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编码等)。

  1. 强制分片: 攻击者控制一个权威DNS服务器。当有DNS查询请求时,该服务器通过构造一个包含超长CNAME记录链的DNS响应,必须对该响应进行IP分片
  2. 分片注入: 一个被分片的DNS响应包,只有第一个分片包含UDP和DNS头部信息(如事务ID、端口号等)。攻击者利用这一点,在第一个合法分片到达前,向DNS转发器注入伪造的第二个分片
  3. 重组缓存: DNS转发器接收到合法的第一个分片和伪造的第二个分片后,会将它们重组。由于伪造的分片篡改了CNAME链的末尾,将其指向了受害者域名(如victim.com)和一个恶意IP
  4. 投毒: 如果DNS转发器的实现是“按记录缓存”,它会将这个恶意响应中的每一条记录(包括 victim.com A [恶意IP])独立存入缓存,投毒成功

影响目标

  • 设备/软件: 存在漏洞的DNS转发设备。这通常包括家庭路由器、企业网关以及一些配置为转发模式的DNS软件。
  • 域名: 任意域名

影响软件版本

  • 路由器固件: D-Link, Linksys, ASUS 等部分型号。
  • DNS软件: dnsmasq (2.83以前), MS DNS (Windows Server)。

2.漏洞监测工具实现

漏洞监测方法原理

提供的 measure.py 脚本使用无害评估、用于检测DNS转发器是否具备可被利用的先决条件的测量工具。其原理即论文中描述的客户端测量方法,使用该脚本的先决条件是一个定制化的权威服务器,具体参见实验环境中authfrag-server部分实现

  1. 触发长链: 脚本首先向目标转发器查询一个攻击者域下的随机子域名(如 [uuid].example.com)。这会触发转发器向上游请求解析,攻击者的权威服务器会返回一个包含超长CNAME链的响应。这个响应的最终A记录是一个特定的Stale IP
  2. 验证缓存: 如果转发器是“按记录缓存”的,它会将CNAME链中的所有记录(包括末尾的 c55.example.com A [Stale IP])都存入缓存,脚本稍后直接向转发器查询CNAME链的末尾域名(权威服务器应对末尾域名返回不同IP
  3. 验证缓存位置: 为了确认响应确实来自转发器的本地缓存(而不是上游服务器),脚本会测量探测缓存时的往返时延(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

注意:measure.py 脚本依赖这种特定的权威服务器逻辑来区分缓存行为。

使用环境配置

  • Python版本: Python 3.x
  • requirements: scapy.
    pip3 install scapy

使用方法

  1. 打开 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
    # ... 其他配置可保持默认
  2. 在攻击机上,使用root权限运行脚本
    sudo python3 measure.py