
s3dns v0.2.22
被动DNS服务器,通过解析DNS请求、追踪CNAME链,并在侦察过程中标记潜在的子域名接管,来检测暴露的云存储桶(AWS S3、GCP、Azure)。
S3DNS
s3dns 是一个轻量级DNS服务器,通过解析DNS请求、追踪CNAME并匹配已知的存储桶URL模式,帮助发现云存储桶(AWS S3、Google Cloud Storage和Azure Blob)。
它是渗透测试人员、漏洞赏金猎人和云安全分析师的便捷工具,用于在DNS流量分析中捕获暴露的云存储桶。
如果S3DNS在侦察过程中为您节省了时间,请考虑给它一个⭐️——这有助于其他人找到该项目。
🆕 更新 2026/03/06
- TCP/53支持 — S3DNS现在同时在UDP和TCP端口53上监听。对于在截断的UDP响应后通过TCP重试的客户端,能正确处理,将查询通过TCP转发到上游以获取完整答案。
- 更大的DNS缓冲区 — UDP接收缓冲区从512字节增加到4096字节。客户端的EDNS0选项会原样传递给上游解析器。
- 响应缓存 — 基于TTL的LRU缓存,用于DNS响应,在UDP和TCP路径上共享。减少活跃侦察期间的上游负载和延迟。可通过
CACHE_SIZE配置(默认:1000条,设为0禁用)。 - 速率限制 — 每个客户端IP的请求速率限制,防止滥用。可通过
RATE_LIMIT配置(默认:100req/s,设为0禁用)。 - 子域名劫持检测 — 当域名匹配云存储模式但返回
NXDOMAIN时,S3DNS将其标记为可能的域名劫持。这表示存在一个指向未声明存储桶的悬空DNS记录,攻击者可注册该存储桶。 - IPv6 IP范围检查 — 现在也解析并检查AAAA记录与已知的云存储IP范围。AWS IPv6 S3前缀与IPv4范围一起加载。
- CNAME深度限制 — 递归CNAME链追踪现在有上限(默认:10跳),防止在构造或循环记录上产生无限循环。可通过
max_cname_depth参数配置。
更新 2025/08/19
- 将离线AWS IP范围添加为JSON文件。
- 将离线Azure存储IP范围添加为JSON文件。
- 增加了通过以下方式禁用任一服务的IP范围检查的选项:
AZURE_IP_RANGES=false或AWS_IP_RANGES=false(默认为true)。
- 将
regex_patterns和硬编码模式移到patterns文件夹中作为YAML文件。您可以添加自己的模式。- 正则表达式模式必须以
regex_开头。
- 正则表达式模式必须以
- 增加了更多云提供商:
- IBM Cloud Object Storage
- Oracle Object Storage
- Alibaba OSS
- Backblaze B2
- Linode Object Storage
- Scaleway Object Storage
- Vultr Object Storage
- Cloudflare R2
更新 2025/06/21
- 增加了AWS GovCloud支持。
更新 2025/04/16
- 更新了正则表达式模式。
- 更新了输出以提高可见性(显示CNAME的原始域名、客户端IP和IP范围指示符)。
- 自动从AWS下载IP范围——现在也会检查这些IP!
- 增加了添加自定义IP范围的选项(手动调整类中的模式或IP范围)。
更新 2025/04/14
- 增加了对Google Cloud Storage和Azure Blob Storage存储桶的正则表达式支持。
🚀 功能特性
- 作为DNS服务器运行在端口
53(UDP 和 TCP) - 检测DNS请求中的潜在云存储桶:
- AWS S3(虚拟主机和路径样式,包括GovCloud)
- GCP存储桶
- Azure Blob容器
- DigitalOcean Spaces、Wasabi、IBM COS、Oracle Object Storage、Alibaba OSS、Backblaze B2、Linode、Scaleway、Vultr、Cloudflare R2
- 递归追踪CNAME链(可配置深度限制)以捕获被掩盖的云存储桶链接
- 标记潜在的子域名劫持——返回NXDOMAIN的云存储模式
- 检查解析后的IP(包括A和AAAA记录)是否在已知的AWS S3和Azure存储IP范围内
- TTL感知的响应缓存,减少侦察期间的延迟和上游负载
- 基于IP的速率限制,防止滥用
- 将所有发现记录到控制台和文件
- 容器友好
⚙️ 工作原理
S3DNS在**端口53(UDP和TCP)**监听DNS查询。对于每个请求,它:
- 提取请求的域名
- 检查响应缓存——如果存在有效的缓存答案,立即返回
- 将请求转发到真实的DNS解析器(例如
1.1.1.1)——对UDP客户端使用UDP,对TCP客户端使用TCP - 向客户端返回有效的DNS响应
同时,它:
- 检查云存储桶模式(正则表达式和硬编码主机名匹配)
- 检查解析后的IP是否在已知的AWS S3和Azure存储范围内(IPv4和IPv6)
- 递归追踪CNAME链,直到配置的深度
- 将匹配模式上的NXDOMAIN命中标记为可能的子域名劫持候选
- 将所有发现记录到控制台和
s3dns.log
⚡ 在侦察期间将其用作您的DNS,它将被动地发现您的工具或浏览器解析的每个域名的云存储桶和劫持候选。
🧱 先决条件
您只需要以下之一:
- Python 3.11+
- Docker(可选,但推荐)
🔧 安装
仅当您想使用Python本地运行时需要
克隆仓库
git clone https://github.com/olizimmermann/s3dns.git
cd s3dns
安装依赖
(建议使用虚拟环境)
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
🧪 使用方法
使用Python运行
端口53需要提升权限:
sudo python s3dns.py
如果 sudo 提示找不到模块,请尝试:sudo venv/bin/python s3dns.py
- 如果您自己构建镜像,请确保标签与Docker Hub版本一致:
docker build -t ozimmermann/s3dns:latest .
使用Docker
S3DNS最简便的入门方式。
docker pull ozimmermann/s3dns:latest
docker run --rm -p 53:53/udp -p 53:53/tcp \
-v "./bucket_findings/:/app/buckets/" \
--name "s3dns" \
ozimmermann/s3dns:latest
使用Docker构建并运行
docker build -t ozimmermann/s3dns:latest .
docker run --rm -p 53:53/udp -p 53:53/tcp \
-v "./bucket_findings/:/app/buckets/" \
--name "s3dns" \
ozimmermann/s3dns:latest
发现结果保存在:
- 终端中,和/或
./bucket_findings/目录中
故障排除
当在与分析相同的机器上使用S3DNS时,设置 --network host 标志可能会有所帮助:
docker run --rm -p 53:53/udp -p 53:53/tcp \
-v "./bucket_findings/:/app/buckets/" \
--network host \
--name "s3dns" \
ozimmermann/s3dns:latest
由于端口53需要提升权限,某些用户(例如Mac用户)可能需要 sudo:
sudo docker run --rm -p 53:53/udp -p 53:53/tcp \
-v "./bucket_findings/:/app/buckets/" \
--name "s3dns" \
ozimmermann/s3dns:latest
🌐 在侦察中使用S3DNS
将您的系统或工具的 DNS解析器 设置为您的S3DNS实例。
在浏览或模糊测试目标时,S3DNS会分析每个域名,并告诉您它是否解析到:
- 一个 AWS S3存储桶
- 一个 GCP存储桶
- 一个 Azure Blob容器
- 其他13个受支持的云存储提供商中的任何一个
它会追踪CNAME,因此如果某个域名指向
cdn.example.com,而该域名又指向一个云存储桶,它也会捕获到。它还会标记潜在的子域名劫持——如果某个域名匹配云存储模式但目标不存在(NXDOMAIN),则会高亮显示悬空记录作为可能的劫持候选。
在分析网站时被动使用它,无需主动探测即可发现暴露的存储桶和劫持机会。
⚙️ 配置
您可以通过命令行标志、环境变量或修改 s3dns.py 来调整行为。
每个选项的优先级为:命令行标志 > 环境变量 > 交互提示/默认值。不带标志运行时的行为与之前完全相同。
命令行标志
运行 python s3dns.py -h 查看完整列表:
| 标志 | 等效环境变量 | 描述 |
|---|---|---|
-h, --help | – | 显示帮助并退出 |
--version | – | 显示版本并退出 |
-d, --debug | DEBUG | 启用详细的调试输出 |
-l, --listen IP | LOCAL_DNS_SERVER_IP | 监听的本地接口 |
-u, --upstream IP | REAL_DNS_SERVER_IP | 转发的上游DNS解析器 |
-b, --bucket-file PATH | BUCKET_FILE | 写入发现的存储桶域名的路径 |
--aws-ip-ranges / --no-aws-ip-ranges | AWS_IP_RANGES | 切换AWS S3 IP范围检查 |
--azure-ip-ranges / --no-azure-ip-ranges | AZURE_IP_RANGES | 切换Azure存储IP范围检查 |
--rate-limit N | RATE_LIMIT | 每个客户端IP的最大DNS请求数/秒(0 = 禁用) |
--cache-size N | CACHE_SIZE | 最大缓存DNS响应数(0 = 禁用) |
--max-cname-depth N | – | 追踪的最大CNAME链深度(默认:10) |
示例:
sudo python s3dns.py -l 0.0.0.0 -u 1.1.1.1 --rate-limit 200 --no-azure-ip-ranges
环境变量
| 变量 | 默认值 | 描述 |
|---|---|---|
DEBUG | false | 启用详细的调试输出 |
AWS_IP_RANGES | true | 启用AWS S3 IP范围检查 |
AZURE_IP_RANGES | true | 启用Azure存储IP范围检查 |
REAL_DNS_SERVER_IP | 1.1.1.1 | 转发查询的上游DNS解析器 |
LOCAL_DNS_SERVER_IP | 0.0.0.0 | 监听的本地接口 |
BUCKET_FILE | buckets.txt | 写入发现的存储桶域名的路径 |
RATE_LIMIT | 100 | 每个客户端IP每秒最大DNS请求数(0 = 禁用) |
CACHE_SIZE | 1000 | 最大缓存DNS响应数(0 = 禁用) |
⚠️ 关于Azure IP范围的说明
由于微软并未明确命名其Azure Blob存储IP范围,S3DNS使用所有公开提供的Azure存储IP地址。这可能导致误报。如果遇到问题,请考虑禁用此检查:
AZURE_IP_RANGES=false
添加自定义模式
将YAML文件添加到 patterns/ 目录。以 regex_ 前缀的文件被视为正则表达式模式;其他所有文件被视为子串匹配。
调试模式
Python:
sudo su
export DEBUG=true
python s3dns.py
Docker:
docker run --rm -p 53:53/udp -p 53:53/tcp \
-v "./bucket_findings/:/app/buckets/" \
-e "DEBUG=true" \
--name "s3dns" \
ozimmermann/s3dns:latest
在Docker中设置多个环境变量:
docker run --rm -p 53:53/udp -p 53:53/tcp \
-v "./bucket_findings/:/app/buckets/" \
-e "LOCAL_DNS_SERVER_IP=0.0.0.0" \
-e "REAL_DNS_SERVER_IP=1.1.1.1" \
-e "RATE_LIMIT=200" \
-e "CACHE_SIZE=2000" \
--name "s3dns" \
ozimmermann/s3dns:latest
示例输出

贡献
欢迎贡献——新的云提供商模式、错误修复和改进。请参阅 CONTRIBUTING.md 了解指南。
模式文件位于 patterns/ 目录。添加新提供商的支持只需添加一个YAML条目即可——无需Python。
📄 许可证
MIT许可证——可自由使用、改进和分享。
⚠️ 免责声明
请负责任地使用。仅扫描您拥有或已获得明确许可分析的域名。
未经授权的访问或探测可能违法。