S3 公共桶
如果任何用户都可以列出 桶的内容,则该桶被视为**“公共”,如果桶的内容 只能由某些用户列出或写入**,则被视为**“私有”**。
公司可能会错误配置桶权限 ,使得访问权限要么开放给所有人,要么开放给在任何 AWS 账户中经过身份验证的所有人(即任何人)。请注意,即使存在这样的错误配置,某些操作可能仍无法执行,因为桶可能有自己的访问控制列表(ACL)。
在这里了解 AWS-S3 错误配置: http://flaws.cloud 和 http://flaws2.cloud/
查找 AWS 桶
查找网页是否使用 AWS 存储某些资源的不同方法:
枚举与 OSINT:
使用 burp(爬虫 网页)或通过手动浏览页面,所有加载的资源 将保存在历史记录中。
Copy http://s3.amazonaws.com/[bucket_name]/
http://[bucket_name].s3.amazonaws.com/
检查 CNAMES ,如 resources.domain.com
可能有 CNAME bucket.s3.amazonaws.com
flaws.cloud 的 IP 是 52.92.181.107,如果你访问那里,它会重定向到 https://aws.amazon.com/s3/ 。此外,dig -x 52.92.181.107
返回 s3-website-us-west-2.amazonaws.com
。
暴力破解
你可以通过暴力破解与公司相关的名称 来查找桶:
Copy # 生成一个单词列表以创建排列
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 请求 来获取桶的区域:
Copy 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检查此内容:
Copy #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 模板
Copy https://{user_provided}.s3.amazonaws.com
从公共桶获取账户ID
可以通过利用新的 S3:ResourceAccount
策略条件键 来确定一个AWS账户。这个条件 基于账户所在的S3桶限制访问 (其他基于账户的策略是基于请求主体所在的账户)。
由于策略可以包含 通配符 ,因此可以 一次找到一个数字 来查找账户号码。
这个工具自动化了这个过程:
Copy # 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:
Copy 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账户的根用户:
Copy s3_client . put_bucket_acl (
Bucket = bucket_name,
AccessControlPolicy = {
'Grants' : [
{
'Grantee' : {
'EmailAddress' : 'some@emailtotest.com' ,
'Type' : 'AmazonCustomerByEmail' ,
},
'Permission' : 'READ'
},
],
'Owner' : {
'DisplayName' : 'Whatever' ,
'ID' : 'c3d78ab5093a9ab8a5184de715d409c2ab5a0e2da66f08c2f6cc5c0bdeadbeef'
}
}
)
参考文献