我正在尝试使用NFQUEUE和Scapy将任何UDP DNS请求转换为TCP DNS请求,然后使用基于TCP DNS共振的精心制作的UDP数据包响应UDP DNS请求。这是我到目前为止写的脚本:
#! /usr/bin/env python2.7
from scapy.all import *
from netfilterqueue import NetfilterQueue
import os
import dns.resolver
myResolver = dns.resolver.Resolver()
def resolv_dns(payload):
udp_query_pkt = IP(payload.get_payload())
domain = udp_query_pkt[DNS].qd.qname
ip_addrs = myResolver.query(domain, "A", tcp=True)
if not udp_query_pkt.haslayer(DNSQR):
payload.set_verdict(nfqueue.NF_ACCEPT)
else:
if domain in udp_query_pkt[DNS].qd.qname:
print str(ip_addrs[0])
udp_resp_pkt = IP(dst=udp_query_pkt[IP].src, src=udp_query_pkt[IP].dst)/\
UDP(dport=udp_query_pkt[UDP].sport, sport=udp_query_pkt[UDP].dport)/\
DNS(id=udp_query_pkt[DNS].id, qr=1, aa=1, qd=udp_query_pkt[DNS].qd,\
an=DNSRR(rrname=udp_query_pkt[DNS].qd.qname, ttl=10, rdata=str(ip_addrs[0])))
send(udp_resp_pkt)
payload.drop()
nfqueue = NetfilterQueue()
nfqueue.bind(1, resolv_dns)
try:
os.system("iptables -A OUTPUT -p udp --dport 53 -j NFQUEUE --queue-num 1")
print "[*] waiting for data"
nfqueue.run()
except KeyboardInterrupt:
os.system("iptables -D OUTPUT -p udp --dport 53 -j NFQUEUE --queue-num 1")
pass
脚本的问题是它不起作用!
实际上我可以在wireshark中看到相应的DNS数据包,看起来没问题:
但我无法打开任何网站!实际上UDP DNS请求超时了:
ebrahim@ebrahim:~$ dig www.xyw.com
; <<>> DiG 9.10.3-P4-Ubuntu <<>> www.xyw.com
;; global options: +cmd
;; connection timed out; no servers could be reached
怎么了?
更新
在@Pierre的回答之后,我更改了IPTable规则,将收到的UDP DNS响应发送到NFQUEUE(而不是发送DNS查询)然后我修改了resolv_dns
函数如下(替换UDP中的IP地址)使用TCP DNS查询收到的新IP地址的DNS响应:
def resolv_dns(packet):
pkt = IP(packet.get_payload())
domain = pkt[DNS].qd.qname
ip_addrs = myResolver.query(domain, "A", tcp=True)
pkt[DNS].an.rdata = str(ip_addrs[0])
packet.set_payload(str(pkt))
packet.accept()
但它仍然不起作用!
答案 0 :(得分:1)
如果您的盒子是路由器拦截转发的数据包,您的脚本可能会有效。但由于您使用的是OUTPUT
链,我认为截获的数据包来自本地主机。在这种情况下,我认为原始客户永远不会得到您的伪造答案。
在我看来,你最好的选择是
127.0.0.1:5300
,它将读取DNS查询(您仍然可以使用Scapy,使用DNS(data_from_client)
执行此操作),解决它(使用TCP,如你的脚本确实如此),并发送响应(同样,你可以从你的脚本发送使用DNS()
调用创建的数据。)iptables
,但不是拦截NFQUEUE
目标的传出数据包,只需DNAT
将它们发送到您的服务器(类似iptables -t nat -A OUTPUT -p udp --dport 53 -j DNAT --to 127.0.0.1:5300
)。 更新:我不知道为什么你坚持使用NFQUEUE
而不是使用DNAT
的简单UDP服务器(让你的IP堆栈和netfilter完成这项工作) ,因为这可能是你想做的最好的方式,但你可能有充分的理由。请注意,根据您提出的第二个解决方案,您必须从DNS服务器获得响应才能使您的脚本正常工作(因此您必须拥有可用且可访问的UDP DNS解析器)。
在第二次尝试中,您修改UDP数据,因此您必须再次计算IP&amp; UDP校验和和长度字段(使用服务器+ DNAT
解决方案,您的内核将完成该工作)。您可以使用del pkt[IP].chksum, pkt[IP].len, pkt[UDP].chksum, pkt[UDP].len
执行此操作(Scapy将为您计算正确的值)。