DNS投毒原理与过程

DNS投毒原理与过程
XRDNS投毒原理与过程
要理解 DNS 缓存污染(DNS Cache Poisoning,也叫 DNS 投毒)的实现原理,核心要抓住两个关键点:DNS 协议的 “信任漏洞” 和 缓存服务器的 “存储逻辑” —— 攻击者正是利用了这两个特性,把 “假应答” 伪装成 “真应答”,让缓存服务器 “信以为真” 并保存,进而污染所有依赖该服务器的用户。
1.先了解DNS 缓存服务器的 “正常工作逻辑”
得先知道缓存服务器 “正常情况下怎么接收和存储应答”,这是理解污染的基础:
当用户向缓存服务器(比如运营商的 114.114.114.114)查询某个域名(如baidu.com)时:
- 若缓存服务器本地没有
baidu.com的解析记录(缓存未命中),它会先向 “上级 DNS 服务器”(如.com顶级域服务器)发送DNS 查询请求(比如问:”baidu.com的 IP 是多少?”); - 上级服务器收到请求后,会返回一个DNS 应答包,里面包含
baidu.com→180.101.49.12的真实映射; - 缓存服务器验证这个应答包 “确实是对自己刚才查询的回复” 后,会把这个映射存入本地缓存(通常保留几小时到几天),同时把结果返回给用户;
- 后续再有用户查
baidu.com,缓存服务器直接用缓存的记录回复,不用再向上级服务器请求。
核心:缓存服务器只对 “自己发起的查询所对应的应答” 进行缓存 ——正常情况下,它不会缓存 “没请求过的域名” 的应答。
2.关键漏洞:DNS 协议的 “无身份认证” 和 “弱关联验证”
攻击者能成功投毒,根源是 DNS 协议(尤其是基于 UDP 的传统 DNS)设计时的两个缺陷,这两个缺陷让 “伪造应答” 能通过缓存服务器的验证:
漏洞 1:DNS 应答包 “不验证发送者身份”
DNS 协议默认 “所有发给自己的应答包,都是对之前查询的回复”,**不验证应答包的发送者是不是 “自己请求的那个上级服务器”**。比如:缓存服务器向 A 服务器(1.2.3.4)发送了查询请求,结果收到一个来自 B 服务器(5.6.7.8)的应答包 —— 只要这个应答包的 “内容格式对”,缓存服务器就会默认它是 “A 服务器委托 B 服务器转发的”,不会拒绝。这就像:你给朋友 A 发了一条微信问 “地址是啥”,结果收到一条来自陌生人 B 的微信说 “地址是 XX”,你直接信了,没确认 B 是不是 A 的朋友。
漏洞 2:”查询与应答” 的关联验证太弱
缓存服务器判断 “应答是否对应自己的查询”,只靠两个简单字段:
- 事务 ID(Transaction ID):缓存服务器发送查询时,会生成一个随机的 16 位数字(比如
0x1234)作为事务 ID,放在查询包中;正常应答包会携带相同的事务 ID,证明 “这是对刚才0x1234查询的回复”。 - 查询 ID(QID)与域名匹配:应答包中会包含 “被查询的域名”(如
baidu.com),缓存服务器会检查这个域名是否和自己刚才查询的一致。
但这两个验证点都很容易被突破:
- 16 位事务 ID 只有
2^16=65536种可能,攻击者用计算机暴力枚举,几分钟内就能猜中正确 ID; - 域名匹配只看 “是不是同一个域名”,不看 “应答的 IP 是否合理”(比如缓存服务器查
baidu.com,攻击者给一个baidu.com→1.1.1.1的应答,只要域名对,服务器就会先接收)。
3.DNS 缓存污染的完整实现步骤与过程
结合上面的漏洞,攻击者污染缓存服务器的过程就很清晰了,我们以 “污染运营商的 114.114.114.114 服务器,让它缓存baidu.com→192.168.1.100(攻击者 IP)” 为例:
步骤 1:攻击者 “监听并触发” 缓存服务器的查询
首先,攻击者需要让缓存服务器 “主动发起对baidu.com的查询”—— 因为只有服务器自己发起了查询,才会接收并缓存对应的应答(否则不会管陌生应答)。触发方式很简单:
- 攻击者可以自己先向 114.114.114.114 查询
baidu.com; - 若
baidu.com的缓存已过期,缓存服务器会立刻向上级服务器(如.com服务器)发送查询请求 —— 此时,缓存服务器处于 “等待应答” 的状态,会接收所有事务 ID 匹配的应答包。
步骤 2:攻击者伪造 “假应答包”
攻击者生成一个伪装成 “上级服务器发送的应答包”,包中包含关键信息:
- 事务 ID:暴力枚举或猜测缓存服务器刚才发送查询时用的事务 ID(比如猜中是
0x1234),确保和查询的 ID 一致; - 被查询域名:填写
baidu.com,和缓存服务器的查询域名一致; - 解析结果:把
baidu.com的 IP 改成攻击者的恶意 IP(如192.168.1.100); - TTL(缓存时间):设置一个较长的时间(如 24 小时),让这个假记录在缓存服务器中保留更久,扩大影响。
这个假应答包的 “格式完全符合 DNS 协议规范”,只是内容是假的 —— 就像伪造的身份证,格式对,但信息是假的。
步骤 3:攻击者 “抢先发送” 假应答,让它先到达缓存服务器
这是攻击成功的关键一步:假应答必须比 “上级服务器的真实应答” 先到达缓存服务器。因为缓存服务器在收到 “第一个事务 ID 匹配、域名匹配的应答包” 后,会直接认为这是 “自己等的那个回复”,立刻存入缓存,后续再收到真实应答时,会直接丢弃(”已经有结果了,不用再要了”)。
攻击者怎么做到 “抢先”?
- 攻击者的设备通常离缓存服务器更近(比如和缓存服务器在同一个机房,或用高速网络),网络延迟比远在千里之外的上级服务器低;
- 攻击者可以发送大量假应答包(暴力枚举事务 ID),只要有一个假应答的 ID 和时间对得上,就能抢先被接收。
步骤 4:缓存服务器 “信以为真”,存储假记录并污染用户
缓存服务器收到假应答包后,会做简单验证:
- 事务 ID 和我刚才查询的一致 → 对;
- 被查询域名是
baidu.com,和我刚才查的一致 → 对; - 应答包格式符合 DNS 规范 → 对。
因为 DNS 协议没有更严格的验证(比如验证发送者 IP 是不是上级服务器,或用加密签名),缓存服务器会默认这个假应答是 “上级服务器发来的真实回复”,然后:
- 把
baidu.com→192.168.1.100的假映射存入本地缓存; - 后续所有向 114.114.114.114 查询
baidu.com的用户,都会收到这个假 IP—— 缓存污染成功。
直到缓存中的假记录过期(比如 24 小时后),或管理员手动清除缓存,污染才会消失。
4.本质原因总结
为什么DNS缓存服务器这么好骗?
一句话:**DNS 协议设计时优先考虑 “解析速度”,牺牲了 “安全性”**,导致缓存服务器缺乏有效的 “防伪手段”:
- 不验证应答发送者身份:不知道应答是不是真的来自上级服务器;
- 事务 ID 太容易破解:16 位 ID 的组合太少,攻击者能快速猜中;
- 没有数据完整性校验:不检查应答中的 IP 是否被篡改(比如
baidu.com的 IP 本该是百度的,现在改成攻击者的,服务器无法识别); - 先到先得的接收逻辑:只要第一个应答匹配,就缓存,不等真实应答。
DNS 缓存污染的本质是:攻击者利用 DNS 协议的安全漏洞,伪造 “看似合法的应答包”,抢先发给缓存服务器,让服务器误把假记录当成真记录存入缓存,进而欺骗所有依赖该服务器的用户。
5.有什么防御DNS缓存污染的方法?
针对上述漏洞,其实已经有不少成熟的防御方案,核心是 “补上验证漏洞”:
- 使用 DNSSEC(DNS 安全扩展):给 DNS 应答包加 “数字签名”,缓存服务器会验证签名是否来自可信的上级服务器 —— 假应答没有合法签名,会被拒绝;
- 使用更长的事务 ID:比如用 32 位或 64 位事务 ID,大幅增加攻击者的枚举难度;
- 限制应答发送者 IP:缓存服务器只接收 “自己请求过的上级服务器 IP” 发来的应答,陌生 IP 的应答直接丢弃;
- 使用加密 DNS(DoH/DoT):把 DNS 查询和应答用 HTTPS/TLS 加密传输,攻击者无法伪造或篡改加密后的数据包(比如浏览器默认用 DoH,就能绕过被污染的缓存服务器)。










