Poison Over Forwarders攻击评估报告
Poison Over Forwarders评估说明
评估脚本获取measure.py源码
1.漏洞说明
来源
[USENIX Security 2020]Poison Over Troubled Forwarders: A Cache Poisoning Attack Targeting DNS Forwarding Devices
基本原理介绍
该漏洞是一种针对DNS转发器的新型缓存投毒攻击。与传统攻击不同,它利用IP分片和由攻击者控制的权威DNS服务器来绕过常见的DNS安全防御机制(如端口随机化、0x20编码等)。
- 强制分片: 攻击者控制一个权威DNS服务器。当有DNS查询请求时,该服务器通过构造一个包含超长CNAME记录链的DNS响应,必须对该响应进行IP分片
- 分片注入: 一个被分片的DNS响应包,只有第一个分片包含UDP和DNS头部信息(如事务ID、端口号等)。攻击者利用这一点,在第一个合法分片到达前,向DNS转发器注入伪造的第二个分片
- 重组缓存: DNS转发器接收到合法的第一个分片和伪造的第二个分片后,会将它们重组。由于伪造的分片篡改了CNAME链的末尾,将其指向了受害者域名(如
victim.com
)和一个恶意IP - 投毒: 如果DNS转发器的实现是“按记录缓存”,它会将这个恶意响应中的每一条记录(包括
victim.com A [恶意IP]
)独立存入缓存,投毒成功
sequenceDiagram participant Attacker participant DNS Forwarder participant Recursive Resolver participant Attacker's Auth Server Attacker->>+DNS Forwarder: 1. Inject Spoofed 2nd Fragment Note over DNS Forwarder: Fragment is held in reassembly buffer Attacker->>DNS Forwarder: 2. Query attacker.com DNS Forwarder->>+Recursive Resolver: 3. Forward query for attacker.com Recursive Resolver->>+Attacker's Auth Server: 4. Resolve attacker.com Attacker's Auth Server-->>-Recursive Resolver: 5. Return OVERSIZED response Note over Recursive Resolver: Response > MTU, must be fragmented Recursive Resolver-->>-DNS Forwarder: 6. Send legitimate 1st Fragment Note over DNS Forwarder: Reassembles: Legitimate 1st + Spoofed 2nd Note over DNS Forwarder: Caches Poisoned Record! (victim.com -> evil.ip)
影响目标
- 设备/软件: 存在漏洞的DNS转发设备。这通常包括家庭路由器、企业网关以及一些配置为转发模式的DNS软件。
- 域名: 任意域名
影响软件版本
- 路由器固件: D-Link, Linksys, ASUS 等部分型号。
- DNS软件: dnsmasq (2.83以前), MS DNS (Windows Server)。
2.漏洞监测工具实现
漏洞监测方法原理
提供的 measure.py
脚本使用无害评估、用于检测DNS转发器是否具备可被利用的先决条件的测量工具。其原理即论文中描述的客户端测量方法,使用该脚本的先决条件是一个定制化的权威服务器,具体参见实验环境中auth
的frag-server
部分实现
- 触发长链: 脚本首先向目标转发器查询一个攻击者域下的随机子域名(如
[uuid].example.com
)。这会触发转发器向上游请求解析,攻击者的权威服务器会返回一个包含超长CNAME链的响应。这个响应的最终A记录是一个特定的Stale IP - 验证缓存: 如果转发器是“按记录缓存”的,它会将CNAME链中的所有记录(包括末尾的
c55.example.com A [Stale IP]
)都存入缓存,脚本稍后直接向转发器查询CNAME链的末尾域名(权威服务器应对末尾域名返回不同IP) - 验证缓存位置: 为了确认响应确实来自转发器的本地缓存(而不是上游服务器),脚本会测量探测缓存时的往返时延(RTT)。如果RTT非常低,则可以高概率地确认响应来自本地缓存
监测是否有害
无,该工具只发送标准的DNS查询请求,不涉及任何分片注入或恶意负载,仅用于测量DNS转发器的缓存行为和性能。
工具输入
无,但是可以直接进行配置FORWARDER_IP = "10.0.0.2" # 转发器或者路由器网关IP
AUTH_SERVER_IP = "10.0.0.3" # 你的权威服务器IP
ATTACKER_DOMAIN = "example.com" # 权威服务器控制域名
CHAIN_LENGTH = 55 # 权威服务器返回CNAME链长度
CHAIN_PREFIX = 'c' # CNAME链子域名前缀
CNAME_CHAIN_EXPECTED_END = f"{CHAIN_PREFIX}{CHAIN_LENGTH}.{ATTACKER_DOMAIN}." # CNAME链最后一个域名
TIMEOUT = 5 # 超时时间
# RTT measurement settings
LOCAL_CACHE_RTT_THRESHOLD = 0.02 # RTT足够低的标准
CACHE_CHECK_ATTEMPTS = 5 # 测试轮数
工具输出
彩色的文本报告,清晰地展示每一步的检测结果([SUCCESS]
, [FAIL]
, [PASS]
),并最后给出明确的结论:[VULNERABLE]
(脆弱) 或 [NOT VULNERABLE]
(不脆弱)。
3.漏洞监测工具使用
环境部署
权威DNS服务器: 一台公网服务器,您需要在此服务器上部署一个DNS服务软件(如 BIND, dnsmasq)
配置要求
- 其对
ATTACKER_DOMAIN
(例如example.com
) 的请求做出如下响应:[uuid].example.com
:- 返回一个
CHAIN_LENGTH
(55) 个CNAME记录的链
例如:[uuid].example.com CNAME c1.example.com.
,c1.example.com. CNAME c2.example.com.
, …,c54.example.com. CNAME c55.example.com.
- 最后一条记录
c55.example.com.
的A记录是一个固定的、您已知的IP地址,脚本将其视为Stale IP。例如1.2.3.4
。
- 返回一个
prefix[uuid].example.com
:- 直接返回一个A记录,但其IP地址必须不同于上面的Stale IP。例如
5.6.7.8
- 直接返回一个A记录,但其IP地址必须不同于上面的Stale IP。例如
注意:measure.py
脚本依赖这种特定的权威服务器逻辑来区分缓存行为。
使用环境配置
- Python版本: Python 3.x
- requirements:
scapy
.pip3 install scapy
使用方法
- 打开
measure.py
文件,修改顶部的配置项:# --- Configuration ---
FORWARDER_IP = "10.0.0.2" # 目标DNS转发器(如你的路由器)的IP地址
AUTH_SERVER_IP = "10.0.0.3" # 你的权威服务器的公网IP
ATTACKER_DOMAIN = "example.com" # 你的权威服务器托管的域名
CHAIN_LENGTH = 55
# ... 其他配置可保持默认 - 在攻击机上,使用root权限运行脚本
sudo python3 measure.py