SAD DNS攻击评估报告
SAD DNS漏洞评估脚本说明
评估脚本获取measure.py源码
1. 漏洞说明
来源
[CCS ‘20]DNS Cache Poisoning Attack Reloaded: Revolutions with Side Channels
基本原理介绍
该漏洞(又称 SADDNS)是一种利用操作系统内核网络协议栈的边信道,来绕过源端口随机化这一关键防御机制,从而重新实现传统DNS缓存投毒攻击。
传统DNS投毒攻击需要猜测一个32位的组合(16位源端口 + 16位Transaction ID),这在实践中几乎不可能。SADDNS通过一种“分而治之”的策略,将这个难题分解为两个可行的步骤:
利用ICMP边信道猜测源端口:
- 当DNS解析器向外发送一个查询时,它会使用一个随机的UDP源端口(例如 34567)。
- 攻击者为了找到这个端口,会向解析器发送大量伪造源IP的UDP探测包,覆盖一个端口范围(例如 30000-40000)。
- 对于每一个命中关闭端口的探测包,解析器的操作系统(如Linux)会试图回复一个ICMP
Port Unreachable
错误消息。 - 然而,操作系统对ICMP错误消息的生成速率有一个全局速率限制(例如 1000条/秒)。攻击者发送的探测包足以在瞬间耗尽这个限制。
- 核心边信道:如果解析器使用的随机源端口(34567)不在攻击者探测的范围内,那么所有探测包都会触发ICMP响应,耗尽速率限制。此时攻击者用自己的真实IP再发送一个探测包,将收不到ICMP响应。
- 反之,如果源端口(34567)恰好在攻击者探测的范围内,这个探测包会被操作系统接受并递交到上层应用,不会触发ICMP响应。这使得ICMP速率限制的“令牌桶”中会留下一个空额。此时攻击者用真实IP发送探测包,将能收到ICMP响应。
- 通过这个微小的差异,攻击者可以迅速通过二分法等方式定位到解析器使用的确切源端口。
暴力破解Transaction ID:
- 一旦源端口被确定,攻击者只需暴力破解剩余的16位Transaction ID。
- 攻击者向已知的源端口发送大量伪造的DNS响应,每个响应使用不同的Transaction ID。在当前的带宽条件下,发送65536个包是完全可行的。
- 只要其中一个伪造响应的Transaction ID命中,并且早于真实的DNS响应到达,缓存投毒即告成功。
sequenceDiagram participant Client participant Victim Resolver (OS) participant Attacker participant Upstream DNS Client->>+Victim Resolver (OS): 1. Query www.victim.com Victim Resolver (OS)->>+Upstream DNS: 2. Forward query Note over Attacker, Victim Resolver (OS): 攻击者开始探测源端口 Attacker->>Victim Resolver (OS): 3. [Drain] 大量伪源IP的UDP包耗尽ICMP速率限制 Attacker->>Victim Resolver (OS): 4. [Probe] 真实源IP的UDP探测包 Victim Resolver (OS)-->>Attacker: 5. 有/无ICMP响应 <br/> 二分查找推断出源端口 Note over Attacker: 源端口已知 Attacker->>Victim Resolver (OS): 6. [Poison] 大量伪造DNS响应(TXID) <br/> 发往已知的(IP, src_port) Note over Victim Resolver (OS): 缓存投毒成功 Client->>+Victim Resolver (OS): 7. Query www.victim.com again Victim Resolver (OS)-->>-Client: 8. 返回被劫持的恶意IP
影响目标
- 设备/软件: 运行在存在ICMP全局速率限制这一边信道的操作系统上的DNS解析器或转发器。
- 操作系统: Linux (Kernel 3.18及以后、5.10以前版本尤为明显),以及其他实现了类似ICMP速率限制机制的操作系统。
影响软件版本
- 主流的且不使用connect的DNS软件(如Unbound, dnsmasq等),当它们运行在受影响的操作系统上时都可能受到波及,因为漏洞根源在操作系统层面而非DNS软件本身。
2. 漏洞监测工具实现
漏洞监测方法原理
提供的 saddns_measure.py
脚本是一个无害的、用于检测目标服务器操作系统是否存在ICMP速率限制边信道的测量工具。其原理完全基于论文中描述的“耗尽与探测”(Drain and Probe)方法。
基础ICMP响应检查: 脚本首先向目标IP的一个高位UDP端口发送一个探测包。如果目标按预期返回ICMP
Port Unreachable
(type 3, code 3) 消息,证明进行下一步探测的基础条件是存在的。如果目标不响应或被防火墙拦截,则无法利用该边信道。ICMP速率限制边信道探测: 这是脚本的核心。
- 脚本在瞬间向目标IP发送一连串(默认为50个)伪造源IP的UDP包。这些包的目标端口是关闭的,旨在触发ICMP响应并耗尽目标的ICMP全局速率限制“令牌桶”。
- 在发送完耗尽包之后,脚本立即从本机真实IP发送一个UDP探测包到同一个关闭的端口。
- 判断
- 如果探测包没有收到ICMP响应,说明之前的伪造包成功耗尽了目标的ICMP速率限制,导致真实探测包的ICMP响应被丢弃。这证明了侧信道存在,目标是脆弱的。
- 如果探测包仍然收到ICMP响应,说明目标的ICMP速率限制机制不存在或行为与预期不符,无法形成可利用的边信道。
监测是否有害
无。该工具只发送标准的UDP数据包并观察ICMP错误响应。它不包含任何恶意负载,不进行DNS查询,也不执行任何缓存投毒行为。它纯粹用于测量目标操作系统网络协议栈的一种特定行为。
工具输入
脚本通过命令行参数接收目标IP和网络接口。
# 命令行输入 |
工具输出
彩色的文本报告,清晰地展示每个检测步骤的结果 ([PASS]
或 [FAIL]
),并最后给出明确的结论:[VULNERABLE]
(脆弱) 或 [NOT VULNERABLE]
(不脆弱)。
3. 漏洞监测工具使用
环境部署
无需特殊的DNS或网络环境。该工具是一个纯客户端的测量脚本,可以在本地网络(L2)中对任何可达的主机进行评估。
使用环境配置
- Python版本: Python 3.x
- Requirements:
scapy
.pip install scapy
使用方法
- 确保测试机与目标主机在同一个二层网络中,以便获取目标MAC地址。
- 在测试机上,使用root权限运行脚本,并传入目标IP地址和本机网络接口名作为参数。
# 假设你的DNS服务器IP是 192.168.1.1,本机网卡是 ens33
sudo python3 saddns_measure.py 192.168.1.1 ens33
预期输出示例
[INFO] SAD DNS for: 192.168.1.1 on interface ens33 |