Skip to content

Intro Lab - Breach in the Cloud

Description

Welcome! We hope that this introductory lab will be enjoyed by red and blue alike. Purple-teaming FTW! It showcases using AWS CloudTrail logs to detect malicious activity, as well as S3 enumeration.

To get started, download the CloudTrail logs in INCIDENT-3252.zip from the 🔎-case-files channel in the Pwned Labs Discord.

Scenario

We've been alerted to a potential security incident. The Huge Logistics security team have provided you with AWS keys of an account that saw unusual activity, as well as AWS CloudTrail logs around the time of the activity. We need your expertise to confirm the breach by analyzing our CloudTrail logs, identifying the compromised AWS service and any data that was exfiltrated.

Lab prerequisites

  • Basic Linux command line knowledge

Learning outcomes

  • Prettifying JSON files for easier analysis
  • Familiarity with the AWS CLI
  • Familiarity with analyzing CloudTrail logs
  • Enumerating S3 buckets
  • Simulating an attacker to validate the path to breach

Difficulty

Beginner

Focus

Blue

Real-world context

Analyzing AWS CloudTrail logs is a standard practice for detecting suspicious activity within an AWS account, while S3 buckets are frequently targeted by attackers due to the valuable data they can contain.

Starting point

Provided AWS keys and case file

 

Access key ID
AKIARSCCN4A3WD4RO4P4

Secret access key
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

 

Submit Flag

 Format: MD5 hash

 

 

Walkthrough

Confirming the Breach by Analyzing CloudTrail Logs

 

To get started, download the CloudTrail logs in INCIDENT-3252.zip from the 🔎-case-files channel in the Pwned Labs Discord.

With the case file downloaded, let's start the investigation.

Note: This guide uses Linux but it's possible to complete the activity using any operating system

 

First unzip the file with unzip. If you need to install it first, run apt install unzip .

 

unzip INCIDENT-3252.zip -d INCIDENT-3252
cd INCIDENT-3252

 

unzipped

 

Opening the file in a text editor such as Nano or Vim reveals that the JSON files aren't prettified, which make them harder to read. To prettify the files we can use jq - a command-line JSON processor for parsing and structuring data. Install it if needed with the command apt install jq . Then issue the command below in the current directory containing the JSON files.

 

for file in *.json; do jq . "$file" > "$file.tmp" && mv "$file.tmp" "$file"; done

 

Opening the file in nano the data is now much easier to read and scan.

 

json

 

We notice that the CloudTrail logs contain the time of creation in the file name and they are ordered by time. The earliest time is T2035 so let's start there. We suspect that the temp-user account is involved, and grep the file with temp-user as the search term.

 

grep -h -A 10 temp-user 107513503799_CloudTrail_us-east-1_20230826T2035Z_PjmwM7E4hZ6897Aq.json

 

        "arn": "arn:aws:iam::107513503799:user/temp-user",
        "accountId": "107513503799",
        "accessKeyId": "AKIARSCCN4A3WD4RO4P4",
        "userName": "temp-user"
      },
      "eventTime": "2023-08-26T20:29:37Z",
      "eventSource": "sts.amazonaws.com",
      "eventName": "GetCallerIdentity",
      "awsRegion": "us-east-1",
      "sourceIPAddress": "84.32.71.19",
      "userAgent": "aws-cli/1.27.74 Python/3.10.6 Linux/5.15.90.1-microsoft-standard-WSL2 botocore/1.29.74",
      "requestParameters": null,
      "responseElements": null,
      "requestID": "3db296ab-c531-4b4a-a468-e1b05ec83246",

 

This reveals that an IAM user named temp-user with the globally unique ARN (Amazon Resource Name) arn:aws:iam::107513503799:user/temp-user from the AWS account 107513503799 issued the CLI command aws sts get-caller-identity on 2023-08-26T20:29:37Z .

The GetCallerIdentity action in AWS is part of the Security Token Service (STS) and allows users to retrieve details about the IAM identity whose credentials are used to make the API request. It can be considered a bit like the whoami command for Windows and Linux. The command returns the globally unique ARN, and, if applicable, the assumed IAM role's ARN. While this is a commonly used command, it is also used by malicious actors to determine the principal (IAM user or role) associated with compromised credentials, as part of gaining situational awareness.

The request originated from the IP address 84.32.71.19 . A check on the IP reveals that the request originated from Turkey. This is not a country where Huge Logistics has a technical presence, and so this could be a potential indicator of compromise (IoC). Let's dig in further.

 

curl ipinfo.io/84.32.71.19

 

ipinfo

 

Turning our attention to the next file, a quick look reveals that the temp-user account made an unsuccessful attempt to list the contents of a bucket named emergency-data-recovery .

 

nano 107513503799_CloudTrail_us-east-1_20230826T2040Z_UkDeakooXR09uCBm.json

 

s3_list_denied

 

Investigation of the next file reveals a lot of errors. The errorMessage value reveals that temp-user issued a large number of requests to other AWS services.

 

error

 

Although it is very noisy, malicious actors may look enumerate the permissions granted to their IAM user or role by brute force. There are multiple tools available for brute forcing IAM permissions, such as aws-enumerator and pacu. We find that there are 450 access denied messages generated by temp-user in the next log file.

 

grep errorMessage 107513503799_CloudTrail_us-east-1_20230826T2050Z_iUtQqYPskB20yZqT.json | wc -l
grep errorMessage 107513503799_CloudTrail_us-east-1_20230826T2055Z_W0F5uypAbGttUgSn.json | wc -l

 

enum


Analyzing the next log file and again searching for actions invoked by the user, we see that they were able to assume the role named
AdminRole ! The AssumeRole operation in AWS is part STS. It allows an AWS identity to assume a different privilege context for a limited period, and potentially access other resources that the assuming principal wouldn't normally have access to.

 

grep -A 20 temp-user 107513503799_CloudTrail_us-east-1_20230826T2100Z_APB7fBUnHmiWjHtg.json

 

assume_role_json

 

Examination of the next file reveals that the attacker again invoked the aws sts get-caller-identity command to verify their new execution context.

 

grep -A 20 AdminRole 107513503799_CloudTrail_us-east-1_20230826T2105Z_fpp78PgremAcrW5c.json

 

get_caller_identity_json


Noting their previous interest in the emergency-data-recovery S3 bucket, we find that they re-attempted to list and retrieve the contents.

 

grep eventName 107513503799_CloudTrail_us-east-1_20230826T2120Z_UCUhsJa0zoFY3ZO0.json

 

event_name

 

      "eventTime": "2023-08-26T21:17:10Z",
      "eventSource": "s3.amazonaws.com",
      "eventName": "ListObjects",
      "awsRegion": "us-east-1",
      "sourceIPAddress": "84.32.71.125",
      "userAgent": "[aws-cli/1.27.74 Python/3.10.6 Linux/5.15.90.1-microsoft-standard-WSL2 botocore/1.29.74]",      
      "requestParameters": {
        "list-type": "2",
        "bucketName": "emergency-data-recovery",
        "encoding-type": "url",
        "prefix": "",
        "delimiter": "/",
        "Host": "emergency-data-recovery.s3.amazonaws.com"

 

The file emergency.txt was downloaded!

 

      "eventTime": "2023-08-26T21:17:16Z",
      "eventSource": "s3.amazonaws.com",
      "eventName": "GetObject",
      "awsRegion": "us-east-1",
      "sourceIPAddress": "84.32.71.3",
      "userAgent": "[aws-cli/1.27.74 Python/3.10.6 Linux/5.15.90.1-microsoft-standard-WSL2 botocore/1.29.74]",    
      "requestParameters": {
        "bucketName": "emergency-data-recovery",
        "Host": "emergency-data-recovery.s3.amazonaws.com",
        "key": "emergency.txt"
      },

 

Retracing Steps as an Attacker


Now thinking as an attacker, we want to  to validate the exploitation path and access the compromised data. We use our gained keys and confirm our execution context.

 

aws sts get-caller-identity

 

temp_user

 

Having previously identified the role named AdminRole (we recommend as a follow-up to check out the lab on Unauthenticated AWS IAM Principals Enumeration), the attacker attempted to assume it. We can do this with the command below.

 

aws sts assume-role --role-arn arn:aws:iam::107513503799:role/AdminRole --role-session-name MySession

 

assume_role

 

After setting the keys with aws configure and then issuing the command aws configure set aws_session_token "<SessionToken>" to set the token, we call the command aws sts get-caller-identity and verify our new context.

 

admin_role

 

We can now list the bucket contents and retrieve the files. PWNED!
The flag is in the file emergency.txt .

 

aws s3 ls s3://emergency-data-recovery

 

list_s3

 

aws s3 cp s3://emergency-data-recovery/emergency.txt .
aws s3 cp s3://emergency-data-recovery/message.txt .

 

Further reading

 

https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-log-file-examples.html

https://github.com/nagwww/s3-leaks

Pwned Labs:
Your cloud security training ground

Experience, real-world, byte sized cloud security labs for training cyber warriors. From beginners to pros, our engaging platform allows you to secure your defenses, ignite your career and stay ahead of threats.

Join us at any stage of your journey