Gravitational plate of three masses and a slashed discABC0Static engraved plate. Three-dimensional view is unavailable or reduced motion is requested.

← back to fieldarticle

articleDec 31, 2021

Cloud Vulnerability Lab 6 (CloudGoat: EC2 SSRF)

CloudGoat EC2 SSRF path: Solus reads Lambda env keys for Wrex, SSRF hits IMDS, S3 yields Shepard admin creds, then invoke the target Lambda.

Cloud vulnerability analysis 6

[Scenario 5]: EC2 SSRF

Size: Medium
Difficulty: Moderate
Command: $ ./cloudgoat.py create ec2_ssrf

Scenario overview

Resources

  • VPC (EC2)
  • Lambda function
  • One S3 bucket

Vulnerabilities

  • Solus IAM user
  • Read-only Lambda permissions
  • Wrex access keys hard-coded in Lambda environment variables
  • Hard-coded sensitive data
  • Web app SSRF that reaches the AWS metadata API for another set of credentials
  • Admin credentials stored in an S3 bucket

Goal

  • Invoke cg-lambda-/cloud goat id/.
  • Start as Solus, discover Lambda read access, and get steered toward an EC2 instance running an SSRF-prone web app.
  • Abuse the app, pull keys from the EC2 metadata service, then obtain the credential that can invoke the Lambda and finish the scenario.

Exploit flow

31.png
31.png

Lab setup

Scenario path

  1. With the Solus IAM account, map the environment and find Lambda functions listed for the account.
  2. Inside a Lambda function, recover AWS access keys that belong to IAM user Wrex.
  3. Acting as Wrex, find an EC2 instance running a web app vulnerable to SSRF.
  4. Trigger SSRF through the url query parameter on a GET request and steal AWS keys from the EC2 metadata service.
  5. With the EC2 role keys, find a private S3 bucket that holds higher-privilege Shepard credentials.
  6. As Shepard with full privilege, invoke the original Lambda and complete the scenario.
IAM : Solus (Read Only Key Access)
 
Lambda function list -> Secret key
 
Wrex <-

Exploit walkthrough

Read Solus's read-only key material

  • While reviewing the lab, start.txt handed over AWS credentials in read-only form.
  • I enumerated IAM with those credentials to see which AWS actions were actually available.

  • The listing showed a Lambda vector worth chasing.

Inspect Lambda environment variables

  • Through Pacu, calling into the cg-lambda-id Lambda surfaced env values EC2_ACCESS_KEY_ID and SECRET_KEY_ID.
[+] Secret (ENV): EC2_ACCESS_KEY_ID= <ACCESS_KEY>
[+] Secret (ENV): EC2_SECRET_KEY_ID= <ACCESS_SECRET_KEY>
  • The target Lambda exists in the account, and hard-coded env vars mean real AWS security credentials are sitting there.

  • Solus lacks lambda:InvokeFunction, so a direct invoke fails.

List and analyze Lambda further

  • With the leaked Lambda env credentials, Pacu's run aws__enum_account showed they belong to IAM user wrex.
  • From Wrex I listed which services that identity can touch.

  • Wrex had more services than expected. Next check: running EC2 instances.

  • I pulled EC2 inventory across regions, then used AWS query filters to cut the noise.

  • Instance state and attached services were visible, but outside the known instance it was still hard to pin down the exact service.

Find the web service on EC2

  • To get a clearer picture I started looking at which instance was actually serving something.

  • The security group attached to the instance showed a web service in play.

  • I grabbed the public IP to reach the host.

  • Port 80 was serving a web app. A Node.js error said the URL parameter was null rather than a string, so I fed it a string value next.

SSRF and IMDS credential theft

  • To test SSRF I passed a link address and watched the response.

  • The response leaked instance environment details.
  • The app is SSRF-vulnerable and runs on EC2, so IMDSv1 can hand over the instance role credentials.

cg-ec2-role-ec2_ssrf_cgid84kpkl3ssy
  • That yields the security-credential path.

{ "Code" : "Success",
"LastUpdated" : "2021-08-13T12:26:30Z",
"Type" : "AWS-HMAC",
"AccessKeyId" : "<ACCESS_KEY>",
"SecretAccessKey" : "<ACCESS_SECRET_KEY>",
"Token" : "<ACCESS_SESSION_KEY>",
"Expiration" : "2021-08-13T18:44:43Z" }
  • Role credentials work like other IAM credentials, with one catch: a short-lived session token. I added a new AWS CLI profile that includes the token.

  • Enumerating with the stolen role credentials showed s3.list_buckets works.

Pull S3 data, extract credentials, invoke Lambda

  • With S3 available I downloaded bucket contents through Pacu.

  • The download contained another AWS credential set. Same playbook: new profile.

  • get-caller-identity showed which user the keys belong to.

  • The principal was shepard. Next I mapped attached policies.

  • Permissions on shepard-ec2_ssrf_cgid84kpkl3ssy set the next move.

  • As expected, Shepard had admin on the account. With those credentials I invoked cg-lambda-ec2_ssrf_cgid84kpkl3ssy.

related

  1. Dec 31, 2021/articleCloud Service Vulnerability Lab 4 (CloudGoat: Cloud Breach S3)
  2. Dec 31, 2021/articleCloud service vulnerability analysis 5 (CloudGoat: IAM privilege escalation by attachment)
  3. Dec 31, 2021/archiveCloud service vulnerability analysis 1: CloudGoat lab setup

graphfeed