AWS - S3 Unauthenticated Enum

支持 HackTricks

S3 公共桶

如果任何用户都可以列出桶的内容,则该桶被视为**“公共”,如果桶的内容只能由某些用户列出或写入**,则该桶被视为**“私有”**。

公司可能会错误配置桶权限,使得访问权限要么开放给所有人,要么开放给在任何 AWS 账户中经过身份验证的所有人(即任何人)。请注意,即使存在这样的错误配置,某些操作可能仍无法执行,因为桶可能有自己的访问控制列表(ACL)。

在这里了解 AWS-S3 错误配置: http://flaws.cloud http://flaws2.cloud/

查找 AWS 桶

查找网页是否使用 AWS 存储某些资源的不同方法:

枚举与 OSINT:

  • 使用 wappalyzer 浏览器插件

  • 使用 burp(爬虫网页)或通过手动浏览页面,所有加载的资源将保存在历史记录中。

  • 检查资源在以下域名中:

http://s3.amazonaws.com/[bucket_name]/
http://[bucket_name].s3.amazonaws.com/
  • 检查 CNAMES,如 resources.domain.com 可能有 CNAME bucket.s3.amazonaws.com

  • 检查 https://buckets.grayhatwarfare.com,这是一个已经发现的开放桶的网站。

  • 桶名称桶域名需要相同。

  • flaws.cloudIP 是 52.92.181.107,如果你访问那里,它会重定向到 https://aws.amazon.com/s3/。此外,dig -x 52.92.181.107 返回 s3-website-us-west-2.amazonaws.com

  • 要检查它是否是一个桶,你也可以访问 https://flaws.cloud.s3.amazonaws.com/

暴力破解

你可以通过暴力破解与公司相关的名称来查找桶:

# 生成一个单词列表以创建排列
curl -s https://raw.githubusercontent.com/cujanovic/goaltdns/master/words.txt > /tmp/words-s3.txt.temp
curl -s https://raw.githubusercontent.com/jordanpotti/AWSBucketDump/master/BucketNames.txt >>/tmp/words-s3.txt.temp
cat /tmp/words-s3.txt.temp | sort -u > /tmp/words-s3.txt

# 基于域名和子域名生成单词列表进行测试
## 将这些域名和子域名写入 subdomains.txt
cat subdomains.txt > /tmp/words-hosts-s3.txt
cat subdomains.txt | tr "." "-" >> /tmp/words-hosts-s3.txt
cat subdomains.txt | tr "." "\n" | sort -u >> /tmp/words-hosts-s3.txt

# 创建基于要攻击的域名和子域名列表的排列
goaltdns -l /tmp/words-hosts-s3.txt -w /tmp/words-s3.txt -o /tmp/final-words-s3.txt.temp
## 之前的工具专门用于创建子域名的排列,让我们过滤该列表
### 删除以 "." 结尾的行
cat /tmp/final-words-s3.txt.temp | grep -Ev "\.$" > /tmp/final-words-s3.txt.temp2
### 创建没有 TLD 的列表
cat /tmp/final-words-s3.txt.temp2 | sed -E 's/\.[a-zA-Z0-9]+$//' > /tmp/final-words-s3.txt.temp3
### 创建没有点的列表
cat /tmp/final-words-s3.txt.temp3 | tr -d "." > /tmp/final-words-s3.txt.temp4http://phantom.s3.amazonaws.com/
### 创建没有连字符的列表
cat /tmp/final-words-s3.txt.temp3 | tr "." "-" > /tmp/final-words-s3.txt.temp5

## 生成最终单词列表
cat /tmp/final-words-s3.txt.temp2 /tmp/final-words-s3.txt.temp3 /tmp/final-words-s3.txt.temp4 /tmp/final-words-s3.txt.temp5 | grep -v -- "-\." | awk '{print tolower($0)}' | sort -u > /tmp/final-words-s3.txt

## 调用 s3scanner
s3scanner --threads 100 scan --buckets-file /tmp/final-words-s3.txt  | grep bucket_exists

获取 S3 桶

给定 S3 开放桶,BucketLoot 可以自动搜索有趣的信息

查找区域

你可以在 https://docs.aws.amazon.com/general/latest/gr/s3.html 找到 AWS 支持的所有区域。

通过 DNS

你可以通过**dig** 和 nslookup 通过对发现的 IP 进行DNS 请求来获取桶的区域:

dig flaws.cloud
;; ANSWER SECTION:
flaws.cloud.    5    IN    A    52.218.192.11

nslookup 52.218.192.11
Non-authoritative answer:
11.192.218.52.in-addr.arpa name = s3-website-us-west-2.amazonaws.com.

检查解析的域名是否包含“website”。 您可以通过访问以下地址访问静态网站:flaws.cloud.s3-website-us-west-2.amazonaws.com 或者您可以通过访问以下地址访问存储桶:flaws.cloud.s3-us-west-2.amazonaws.com

通过尝试

如果您尝试访问一个存储桶,但在域名中指定了另一个区域(例如存储桶在bucket.s3.amazonaws.com,但您尝试访问bucket.s3-website-us-west-2.amazonaws.com,那么您将被指向正确的位置

枚举存储桶

要测试存储桶的开放性,用户只需在其网页浏览器中输入URL。私有存储桶将响应“访问被拒绝”。公共存储桶将列出前1,000个已存储的对象。

对所有人开放:

私有:

您也可以通过cli检查此内容:

#Use --no-sign-request for check Everyones permissions
#Use --profile <PROFILE_NAME> to indicate the AWS profile(keys) that youwant to use: Check for "Any Authenticated AWS User" permissions
#--recursive if you want list recursivelyls
#Opcionally you can select the region if you now it
aws s3 ls s3://flaws.cloud/ [--no-sign-request] [--profile <PROFILE_NAME>] [ --recursive] [--region us-west-2]

如果存储桶没有域名,在尝试枚举时,只需输入存储桶名称,而不是整个 AWSs3 域名。示例: s3://<BUCKETNAME>

公共 URL 模板

https://{user_provided}.s3.amazonaws.com

从公共桶获取账户ID

可以通过利用新的 S3:ResourceAccount 策略条件键 来确定一个AWS账户。这个条件 基于账户所在的S3桶限制访问(其他基于账户的策略是基于请求主体所在的账户)。 由于策略可以包含 通配符,因此可以 一次找到一个数字 来查找账户号码。

这个工具自动化了这个过程:

# Installation
pipx install s3-account-search
pip install s3-account-search
# With a bucket
s3-account-search arn:aws:iam::123456789012:role/s3_read s3://my-bucket
# With an object
s3-account-search arn:aws:iam::123456789012:role/s3_read s3://my-bucket/path/to/object.ext

这种技术同样适用于 API Gateway URLs、Lambda URLs、Data Exchange 数据集,甚至可以获取标签的值(如果你知道标签键)。你可以在 原始研究 和工具 conditional-love 中找到更多信息,以自动化此利用。

确认一个桶属于 AWS 账户

正如在 这篇博客文章 中解释的那样,如果你有列出桶的权限,可以通过发送类似以下请求来确认桶所属的 accountID:

curl -X GET "[bucketname].amazonaws.com/" \
-H "x-amz-expected-bucket-owner: [correct-account-id]"

<?xml version="1.0" encoding="UTF-8"?>
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">...</ListBucketResult>

如果错误是“访问被拒绝”,这意味着账户 ID 是错误的。

使用电子邮件进行根账户枚举

正如在这篇博客文章中所解释的,可以通过尝试授予电子邮件对 S3 存储桶的权限来检查某个电子邮件地址是否与任何 AWS 账户相关。如果这没有触发错误,这意味着该电子邮件是某个 AWS 账户的根用户:

s3_client.put_bucket_acl(
Bucket=bucket_name,
AccessControlPolicy={
'Grants': [
{
'Grantee': {
'EmailAddress': 'some@emailtotest.com',
'Type': 'AmazonCustomerByEmail',
},
'Permission': 'READ'
},
],
'Owner': {
'DisplayName': 'Whatever',
'ID': 'c3d78ab5093a9ab8a5184de715d409c2ab5a0e2da66f08c2f6cc5c0bdeadbeef'
}
}
)

参考

支持 HackTricks

Last updated