Project Zero: Cloud Lab (Part 3)

case study

Defenses

last edited 2026-09-02

#VPC Flow Logs Detections

-projectzero-prod-vpc has been created with subnets configured.

-VPC Flow Logs have been enabled and are delivering logs to your S3 security datalake

-Wazuh is configured to ingest VPC Flow Logs from S3

-project-zero-sec-box configured with Wazuh.

#Create Wazuh Detection Rules

I built Wazuh detections around VPC Flow Log telemetry to identify external traffic targeting high value services in the AWS environment. The detections focus on accepted connections to exposed ports such as SSH, RDP, and database services, providing visibility into activity associated with the Open VPC attack scenario.

1.Create SSH Exposure Monitor

Configured a per-query Wazuh monitor to evaluate VPC Flow Log telemetry every minute.
Configured a per-query Wazuh monitor to evaluate VPC Flow Log telemetry every minute.

View Detection Query
sql
{
    "size": 0,
    "query": {
        "bool": {
            "filter": [
                {
                    "term": {
                        "data.aws.action": {
                            "value": "ACCEPT",
                            "boost": 1
                        }
                    }
                },
                {
                    "term": {
                        "data.aws.dstport": {
                            "value": 22,
                            "boost": 1
                        }
                    }
                }
            ],
            "must_not": [
                {
                    "range": {
                        "data.aws.srcaddr": {
                            "from": "10.0.0.0",
                            "to": "10.255.255.255",
                            "include_lower": true,
                            "include_upper": true,
                            "boost": 1
                        }
                    }
                },
                {
                    "range": {
                        "data.aws.srcaddr": {
                            "from": "172.16.0.0",
                            "to": "172.31.255.255",
                            "include_lower": true,
                            "include_upper": true,
                            "boost": 1
                        }
                    }
                },
                {
                    "range": {
                        "data.aws.srcaddr": {
                            "from": "192.168.0.0",
                            "to": "192.168.255.255",
                            "include_lower": true,
                            "include_upper": true,
                            "boost": 1
                        }
                    }
                }
            ],
            "adjust_pure_negative": true,
            "boost": 1
        }
    }
}
Validated the detection query against Wazuh alert data, confirming that accepted external SSH traffic on port 22 was successfully matched.
Validated the detection query against Wazuh alert data, confirming that accepted external SSH traffic on port 22 was successfully matched.
Configured a trigger to generate an alert whenever the monitor detects matching external SSH traffic.
Configured a trigger to generate an alert whenever the monitor detects matching external SSH traffic.

2.Create RDP/VNC Exposure Monitor

I created an additional Wazuh monitor to detect accepted external traffic targeting RDP (3389) and VNC (5900), identifying potentially exposed remote-access services within the VPC.

View Detection Query
sql
{
    "size": 0,
    "query": {
        "bool": {
            "filter": [
                {
                    "term": {
                        "data.aws.action": {
                            "value": "ACCEPT",
                            "boost": 1
                        }
                    }
                },
                {
                    "term": {
                        "data.aws.dstport": {
                            "value": [3389, 5900],
                            "boost": 1
                        }
                    }
                }
            ],
            "must_not": [
                {
                    "range": {
                        "data.aws.srcaddr": {
                            "from": "10.0.0.0",
                            "to": "10.255.255.255",
                            "include_lower": true,
                            "include_upper": true,
                            "boost": 1
                        }
                    }
                },
                {
                    "range": {
                        "data.aws.srcaddr": {
                            "from": "172.16.0.0",
                            "to": "172.31.255.255",
                            "include_lower": true,
                            "include_upper": true,
                            "boost": 1
                        }
                    }
                },
                {
                    "range": {
                        "data.aws.srcaddr": {
                            "from": "192.168.0.0",
                            "to": "192.168.255.255",
                            "include_lower": true,
                            "include_upper": true,
                            "boost": 1
                        }
                    }
                }
            ],
            "adjust_pure_negative": true,
            "boost": 1
        }
    }
}
Created and enabled the RDP/VNC exposure monitor to detect external connections targeting ports 3389 and 5900.
Created and enabled the RDP/VNC exposure monitor to detect external connections targeting ports 3389 and 5900.

3.Default DB Ports

I created an additional Wazuh monitor to detect accepted external traffic targeting common database services, including MySQL (3306), PostgreSQL (5432), and Microsoft SQL Server (1433).

View Detection Query
sql
{
    "size": 0,
    "query": {
        "bool": {
            "filter": [
                {
                    "term": {
                        "data.aws.action": {
                            "value": "ACCEPT",
                            "boost": 1
                        }
                    }
                },
                {
                    "term": {
                        "data.aws.dstport": {
                            "value": [3306,5432,1433],
                            "boost": 1
                        }
                    }
                }
            ],
            "must_not": [
                {
                    "range": {
                        "data.aws.srcaddr": {
                            "from": "10.0.0.0",
                            "to": "10.255.255.255",
                            "include_lower": true,
                            "include_upper": true,
                            "boost": 1
                        }
                    }
                },
                {
                    "range": {
                        "data.aws.srcaddr": {
                            "from": "172.16.0.0",
                            "to": "172.31.255.255",
                            "include_lower": true,
                            "include_upper": true,
                            "boost": 1
                        }
                    }
                },
                {
                    "range": {
                        "data.aws.srcaddr": {
                            "from": "192.168.0.0",
                            "to": "192.168.255.255",
                            "include_lower": true,
                            "include_upper": true,
                            "boost": 1
                        }
                    }
                }
            ],
            "adjust_pure_negative": true,
            "boost": 1
        }
    }
}
Created and enabled the database exposure monitor to detect external connections targeting common database ports.
Created and enabled the database exposure monitor to detect external connections targeting common database ports.

4.Verify SSH Exposure Detection

I deployed an EC2 instance in the monitored ProjectZero VPC with SSH exposed on port 22 and generated an external connection attempt to validate the detection. The resulting VPC Flow Log activity was ingested by Wazuh and successfully triggered the SSH exposure monitor.

Deploy Test EC2 Instance I launched a test EC2 instance in the public subnet using a security group that allowed inbound SSH traffic.

Deployed the test EC2 instance in the monitored VPC using a security group permitting inbound SSH traffic.
Deployed the test EC2 instance in the monitored VPC using a security group permitting inbound SSH traffic.

Identify Public IP I retrieved the instance's public IP address to use as the target for the external connection attempt.

Identified the public IP address assigned to the test EC2 instance.
Identified the public IP address assigned to the test EC2 instance.

Generate SSH Traffic I attempted an external SSH connection to the instance to generate traffic for the detection.

Generated external SSH traffic against the exposed EC2 instance to trigger the detection.
Generated external SSH traffic against the exposed EC2 instance to trigger the detection.

Validate Wazuh Alert The SSH exposure monitor successfully detected the external connection and generated an alert.

Wazuh successfully detected the external SSH connection and generated an alert through the configured SSH exposure monitor.
Wazuh successfully detected the external SSH connection and generated an alert through the configured SSH exposure monitor.
Reviewed the triggered alert details, confirming the SSH exposure monitor matched the expected condition and generated an active Wazuh alert.
Reviewed the triggered alert details, confirming the SSH exposure monitor matched the expected condition and generated an active Wazuh alert.

#AWS Config

I implemented AWS Config monitoring to identify insecure IAM configurations associated with the previously demonstrated privilege escalation scenarios. AWS Config evaluates IAM resources for overly permissive policies, while EventBridge and SNS provide notifications when resources become non-compliant.

1.Configure SNS Compliance Notifications

I created an Amazon SNS topic and email subscription to provide notifications for AWS Config compliance findings.

Created the SNS topic used to deliver AWS Config compliance notifications.
Created the SNS topic used to deliver AWS Config compliance notifications.
Configured an email subscription to receive compliance alerts from the SNS topic.
Configured an email subscription to receive compliance alerts from the SNS topic.

2.Deploy the Insecure IAM Test Environment

I deployed the insecure IAM lab environment through CloudFormation to provide intentionally vulnerable IAM resources that could be evaluated by AWS Config.

Uploaded the CloudFormation template containing the intentionally insecure IAM configuration.
Uploaded the CloudFormation template containing the intentionally insecure IAM configuration.
Configured the CloudFormation stack parameters for the IAM security test environment.
Configured the CloudFormation stack parameters for the IAM security test environment.
Verified successful deployment of the insecure IAM resources used for AWS Config validation.
Verified successful deployment of the insecure IAM resources used for AWS Config validation.

3.Prepare IAM Resources for Compliance Testing

I verified the IAM users deployed through CloudFormation and attached an intentionally overprivileged administrative policy to the vulnerable user. This provides a known insecure configuration that AWS Config can evaluate for compliance.

Verified the IAM users created for the insecure permissions scenario.
Verified the IAM users created for the insecure permissions scenario.
Created an intentionally overprivileged IAM policy granting unrestricted actions and resources ( Action: "*"  and  Resource: "*" ), providing a test case for AWS Config.
Created an intentionally overprivileged IAM policy granting unrestricted actions and resources (Action: "*" and Resource: "*"), providing a test case for AWS Config.

4.Enable AWS Config Monitoring

I configured AWS Config to continuously record IAM policies, users, roles, and groups. Configuration data is delivered to S3, while configuration changes and notifications are sent through the previously configured SNS topic.

Configured AWS Config to continuously record IAM resources for compliance evaluation.
Configured AWS Config to continuously record IAM resources for compliance evaluation.
Configured the AWS Config delivery channel with S3 storage and SNS notifications for configuration changes.
Configured the AWS Config delivery channel with S3 storage and SNS notifications for configuration changes.

5.Configure IAM Compliance Rules

I added AWS Config managed rules to identify overly permissive IAM policies, including policies that grant administrative access or unrestricted access to AWS services.

Configured  iam-policy-no-statements-with-admin-access  to detect IAM policies that grant unrestricted administrative permissions.
Configured iam-policy-no-statements-with-admin-access to detect IAM policies that grant unrestricted administrative permissions.
Configured  iam-policy-no-statements-with-full-access  to detect IAM policies that grant unrestricted access to AWS services.
Configured iam-policy-no-statements-with-full-access to detect IAM policies that grant unrestricted access to AWS services.

6.Configure EventBridge Compliance Notifications

I configured Amazon EventBridge to monitor AWS Config compliance changes and forward NON_COMPLIANT findings from the IAM security rules to the SNS notification topic.

Created the  config-compliance-to-sns  EventBridge rule to monitor AWS Config compliance events.
Created the config-compliance-to-sns EventBridge rule to monitor AWS Config compliance events.

EventBridge Event Pattern:

c
{
  "source": ["aws.config"],
  "detail-type": ["Config Rules Compliance Change"],
  "detail": {
    "configRuleName": ["iam-policy-no-statements-with-admin-access", "iam-policy-no-statements-with-full-access"],
    "newEvaluationResult": {
      "complianceType": ["NON_COMPLIANT"]
    }
  }
}
Configured the event pattern to match  NON_COMPLIANT  findings from the administrative and full-access IAM policy rules.
Configured the event pattern to match NON_COMPLIANT findings from the administrative and full-access IAM policy rules.
Configured the  aws-config-compliance-alert  SNS topic as the target for matched compliance events.
Configured the aws-config-compliance-alert SNS topic as the target for matched compliance events.
Verified the EventBridge rule configuration, including the AWS Config compliance event pattern and SNS notification target.
Verified the EventBridge rule configuration, including the AWS Config compliance event pattern and SNS notification target.

Configured EventBridge to route AWS Config non-compliance events to the SNS notification topic, completing the compliance monitoring and alerting pipeline.


#AWS Secrets (Secure Secret Storage)

I implemented AWS Secrets Manager to securely store application secrets and eliminate the hardcoded credential exposure demonstrated in the previous attack scenario. Access to the secret was granted through an EC2 IAM role, allowing the instance to retrieve the secret at runtime without storing AWS credentials or sensitive values in application configuration.

1.Store Application Secret

I created a secret in AWS Secrets Manager using the default AWS-managed KMS encryption key, providing centralized encrypted storage for application credentials.

Stored the application secret in AWS Secrets Manager using the  aws/secretsmanager  encryption key.
Stored the application secret in AWS Secrets Manager using the aws/secretsmanager encryption key.

2.Create IAM Role for Secret Access

I created an EC2 IAM role with read-only Secrets Manager permissions, allowing the workload to retrieve secrets without requiring hardcoded AWS access keys.

Configured EC2 as the trusted service for the secrets-reader IAM role.
Configured EC2 as the trusted service for the secrets-reader IAM role.
Granted the EC2 role read-only access to AWS Secrets Manager.
Granted the EC2 role read-only access to AWS Secrets Manager.
Created the  projectzero-app-secrets-reader  IAM role for runtime secret retrieval.
Created the projectzero-app-secrets-reader IAM role for runtime secret retrieval.

3.Attach IAM Role and Retrieve Secret

I attached the secrets-reader IAM role to the EC2 instance and validated access by retrieving the stored secret through the AWS CLI from the instance.

Attached the  projectzero-app-secrets-reader  role to the EC2 instance.
Attached the projectzero-app-secrets-reader role to the EC2 instance.
Selected the  projectzero-app-secrets-reader  IAM role for the EC2 instance.
Selected the projectzero-app-secrets-reader IAM role for the EC2 instance.

aws secretsmanager get-secret-value --secret-id projectzero-app/production --region eu-north-1

Successfully retrieved the secret from AWS Secrets Manager using the EC2 instance profile, validating role-based access without hardcoded AWS credentials.
Successfully retrieved the secret from AWS Secrets Manager using the EC2 instance profile, validating role-based access without hardcoded AWS credentials.

#Why This Matters

These defenses demonstrate a layered approach to AWS security by combining network based detection, configuration compliance monitoring, and secure secrets management to detect and reduce the attack paths demonstrated earlier in the project.