Skip to content

Defender — Objective 1: Download CloudTrail Logs

Setup

You are given access to a "Security" account as an IAM user. That account contains a copy of CloudTrail logs from a successful compromise (the attack from the Attacker track), and has the ability to assume a "security" role into the Target account.

Security account credentials (training environment only): - Account ID: 322079859186 - Username: security - Access Key: <REDACTED_ACCESS_KEY_ID> - Secret Key: <REDACTED_SECRET_KEY>

Two accounts involved:

Account ID Purpose
Security 322079859186 Your analyst account — contains CloudTrail logs, has cross-account access
Target 653711331788 The compromised account — contains the vulnerable resources

This is a realistic setup. Most mature AWS orgs have a dedicated Security or Audit account that's separate from everything else. Logs from all accounts flow into it. Analysts operate from there so compromising the target account doesn't destroy the logs.


What is CloudTrail?

CloudTrail is AWS's audit log service. Every AWS API call made in an account — by a human, a script, a Lambda function, an EC2 instance, anything — gets recorded as a JSON event in CloudTrail.

What a CloudTrail event records: - Who made the call (userIdentity — IAM user, role, service) - What they called (eventNameListBuckets, AssumeRole, GetObject, etc.) - When (eventTime) - From where (sourceIPAddress) - With what tool (userAgentaws-cli, Boto3, Chrome, etc.) - What they asked for (requestParameters) - What they got back (responseElements) - Whether it succeeded or failed (errorCode, errorMessage)

Why it matters for incident response: CloudTrail is the definitive record of what happened. You can reconstruct an entire attack just from the logs — who ran what, when, from which IP, using which credentials.

Log format: Each CloudTrail file is .json.gz — gzipped JSON. Multiple API calls are wrapped in a Records array:

{
  "Records": [
    { "eventTime": "...", "eventName": "ListBuckets", ... },
    { "eventTime": "...", "eventName": "AssumeRole", ... }
  ]
}

Log path pattern:

AWSLogs/<AccountID>/CloudTrail/<region>/<year>/<month>/<day>/<file>.json.gz

For this exercise: AWSLogs/653711331788/CloudTrail/us-east-1/2018/11/28/


Step 1 — Configure the CLI

aws configure --profile security
# AccessKeyId: <REDACTED_ACCESS_KEY_ID>
# SecretAccessKey: <REDACTED_SECRET_KEY>
# region: us-east-1

Verify it works:

aws sts get-caller-identity --profile security

Expected output:

{
    "UserId": "...",
    "Account": "322079859186",
    "Arn": "arn:aws:iam::322079859186:user/security"
}

arn:aws:iam::322079859186:user/security — this is a permanent IAM user (iam:...:user/), not a role. Account ID 322079859186 = Security account. You're in the right place.


Step 2 — List the Buckets

aws s3 ls --profile security

Returns: flaws2-logs — the S3 bucket in the Security account that holds the CloudTrail logs.


Step 3 — Download the Logs

aws s3 sync s3://flaws2-logs . --profile security

aws s3 sync — synchronises a source to a destination. Downloads everything from the bucket that doesn't already exist locally.

Part What it does
aws s3 sync Sync command — copies new/modified files from source to destination
s3://flaws2-logs Source: the S3 bucket
. Destination: current working directory
--profile security Use the security account credentials

sync vs cp: - aws s3 cp — copy a specific file or directory - aws s3 sync — mirror a whole directory tree, only transferring what's missing or changed

Result: Downloads .json.gz files into ./AWSLogs/653711331788/CloudTrail/us-east-1/2018/11/28/

Why is this bucket public? The challenge is designed so you can reference it from Athena (Objective 6) without needing to copy it into your own account first. In real environments, CloudTrail log buckets are private — accessible only to the Security account.