-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdnsfrag2tc.py
executable file
·60 lines (52 loc) · 1.37 KB
/
dnsfrag2tc.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#!/usr/bin/env python3
# NFQUEUE function which captures fragmented DNS/UDP/IPv4 response
# and replaces it with TC=1 response
# Requires Python3, Scapy and NetfilterQueue.
# Usage:
# iptables -t raw -A PREROUTING -p udp --sport 53 -j NFQUEUE --queue-num 12345 --queue-bypass
# ./dnsfrag2tc.py 12345
from netfilterqueue import NetfilterQueue
from scapy.all import *
import sys
def process(pkt):
packet = IP(pkt.get_payload())
# is UDP datagram's first fragment?
if packet.flags & 0x1 and packet.frag == 0 and packet.proto == 0x11:
# is source port == 53 (DNS response?)
if packet[UDP].sport == 53:
dnsmsg = bytes(packet[UDP].payload)
if len(dnsmsg) < 12:
return
# is a resnponse ?
if dnsmsg[2] & 0x80 == 0:
pkt.accept()
return
# opcode ?
if dnsmsg[2] & 0x78 != 0:
pkt.accept()
return
# so this is fragmented DNS response.
id = dnsmsg[0] * 256 + dnsmsg[1]
pkt.set_payload(bytes(gentc(packet, id)))
pkt.accept()
return
pkt.accept()
def gentc(packet,id):
ip = IP()
udp = UDP()
ip.src = packet[IP].src
ip.dst = packet[IP].dst
udp.sport = packet[UDP].sport
udp.dport = packet[UDP].dport
dns = DNS(id=id, qr=1, tc=1)
return ip/udp/dns
def main():
nfqueue = NetfilterQueue()
nfqueue.bind(int(sys.argv[1]), process)
try:
nfqueue.run()
except KeyboardInterrupt:
print('')
nfqueue.unbind()
if __name__ == '__main__':
main()