AWS Account ID Reconnaissance

当获得一个AWS Account ID之后我们可能会对这个ID去做一些信息收集,而该账户的 IAM User/Role 是会被考虑的一个信息。下面就记一下如何通过一个 Account ID 收集该账户的 IAM User/Role。

使用角色信任策略

假设我们现在拿到了一个账户ID为427648302155,我现在想知道这个账户下有哪些User和Role。

首先,我们在自己的AWS账户里随便新建一个角色,并将信任策略配置为

{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Sid": "Statement1",
			"Effect": "Deny",
			"Principal": {
			    "AWS": "*"
			},
			"Action": "sts:AssumeRole"
		}
	]
}

创建好之后我们点击进入角色,编辑信任策略
image.png

修改 Principal -> AWS 为427648302155下的一个 User/Role,比如arn:aws:iam::427648302155:user/admin。然后我们更新策略,出现报错
image.png

这个ID是 Pwnedlabs实验 Identify the AWS Account ID from a Public S3 Bucket 中的ID,它存在一个用户是 s3user。现在我们修改AWSarn:aws:iam::427648302155:user/s3user,发现策略成功更新。
image.png

通过这种方式我们就能枚举一个账户下它的 IAM User/Role,如果目标的某个角色信任策略配置错误,比如

{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Sid": "Statement1",
			"Effect": "Allow",
			"Principal": {
			    "AWS": "*"
			},
			"Action": "sts:AssumeRole"
		}
	]
}

那我们就可以扮演该角色,以获取目标的更多信息。云渗透工具pacu的iam__enum_roles模块就是用这种方式实现的。在使用时我们将--role-name配置为当前账户中一个可用角色,--account-id设置为要枚举的目标ID,工具便会用自己的字典对该目标进行枚举

run iam__enum_users --role-name IAMEnum --account-id 104506445608
image.png

使用S3/Lambda访问策略

这两种方法和上面的也是大同小异,都是根据将一个IAM主体付给S3/Lambda策略上时的报错信息进行判断的。这里就不再赘述,详见实验:https://pwnedlabs.io/labs/unauthenticated-aws-iam-principals-enumeration

S3

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "IAM Enum",
      "Effect": "Deny",
      "Principal": {
        "AWS": "arn:aws:iam::104506445608:role/batch"
      },
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::iam-enum/*"
    }
  ]
}

image.png
image.png

Lambda

aws lambda add-permission --function-name IAMEnum --action lambda:GetFunction --statement-id IAMEnum --principal "arn:aws:iam::104506445608:role/admin"
aws lambda add-permission --function-name IAMEnum --action lambda:GetFunction --statement-id IAMEnum --principal "arn:aws:iam::104506445608:role/batch"

获取公开S3的 AWS Account ID

实验环境:Identify the AWS Account ID from a Public S3 Bucket

主要说下这个原理。在题目给的网页中我们可以看到它使用的S3名称:mega-big-tech
image.png

是一个公开的S3,可以直接访问查看
image.png

使用的方法参考:Finding the Account ID of any public S3 bucket

下面讲下这个原理,首先我们创建一个角色,权限使用AWS托管策略里面的AmazonS3ReadOnlyAccess
image.png

扮演这个角色我们是可以列出这个S3的内容的
image.png

清空SessionTokenaws configure set aws_session_token "",切换到原来的用户。说一下这个穷举的原理。在执行sts:Assumerole的时候,可以指定--policy参数来指定一个附加的权限策略,这个策略将与你要扮演的角色的权限策略结合(取交集),最终确定你在该角色下的实际权限。

根据这个利用脚本:s3-account-search,它附加的策略--policy

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowResourceAccount",
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": "*",
            "Condition": {
                "StringLike": {"s3:ResourceAccount": [f"{digits}*"]},
            },
        },
    ],
}

其中Condition元素允许你指定策略生效的条件,而在 Condition 元素中可以使用条件运算符来将策略中的条件键和值与请求上下文中的值进行匹配。其中的StringLike可以做通配符匹配(参考:IAM JSON 策略元素:条件运算符),依次来爆破出s3:ResourceAccount,也就是该S3资源的Account-ID

下面做个测试。"s3:ResourceAccount":"0*"也就是Account-ID是0开头

aws sts assume-role --role-arn arn:aws:iam::<Account-ID>:role/s3reader --role-session-name skky --policy '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"s3:*","Resource":"*","Condition":{"StringLike":{"s3:ResourceAccount":"0*"}}}]}' 

这时无法列出S3内容,说明该S3的Account-ID不是0开头的
image.png

而修改为"s3:ResourceAccount":"1*"可以访问
image.png

利用这个方式我们就可以枚举出该S3的Account-ID,这里直接使用脚本进行枚举https://github.com/WeAreCloudar/s3-account-search/blob/main/s3_account_search/cli.py
image.png

参考链接

Assume the Worst: Enumerating AWS Roles through ‘AssumeRole’
Using AWS Account ID’s for IAM User Enumeration
Unauthenticated AWS Role Enumeration (IAM Revisited)