def frame_handler(self, manager, worker_addr, frame_data): """ Inject probe response frames for every probe request frame. """ decoder = RadioTapDecoder() decoder.decode(frame_data) management_frame = decoder.get_protocol(dot11.Dot11ManagementFrame) probe_req_frame = decoder.get_protocol( dot11.Dot11ManagementProbeRequest) if not probe_req_frame: return ssid = probe_req_frame.get_ssid() if not ssid: # Ignore broadcast SSID return station_address = management_frame.get_source_address() print "Station: %s" % ":".join( map(lambda i: "%02X" % i, station_address)) print "SSID: %s" % ssid frame = str() # Radiotap frame += "\x00\x00" # Version frame += "\x0b\x00" # Header Length frame += "\x04\x0c\x00\x00" # Presence Flags frame += "\x6c" # Rate frame += "\x0c" # TX Power frame += "\x01" # Antenna # Management Frame frame += "\x50\x00" # Frame Control frame += "\x31\x01" # Duration frame += "".join(chr(i) for i in station_address) # Destination Address frame += "\x00\xde\xad\xbe\xef\x00" # Source Address frame += "\x00\xde\xad\xbe\xef\x00" # BSSID Address frame += "\x00\x00" # Sequence Control frame += "\x00\x00\x00\x00\x00\x00\x00\x00" # Timestamp frame += "\x64\x00" # Beacon Interval frame += "\x01\x04" # Capabilities frame += "\x00%s%s" % (struct.pack("B", len(ssid)), ssid) # SSID frame += "\x01\x08\x82\x84\x8b\x96\x24\x30\x48\x6c" # Supported Rates frame += "\x03\x01\x0e" # DS parameter set frame += "\xdd\x06\xfa\xfa\xfa\x00\xde\xad" # Vendor Specific workers = manager.get_workers() for worker in workers: if worker.raw_mac_address() == worker_addr: break for iface in worker.interfaces_list(): manager.inject_data_from_worker_interface(worker.raw_mac_address(), iface.name(), frame)
def frame_handler(self, manager, worker_addr, frame_data): """ Inject probe response frames for every probe request frame. """ decoder = RadioTapDecoder() decoder.decode(frame_data) management_frame = decoder.get_protocol(dot11.Dot11ManagementFrame) probe_req_frame = decoder.get_protocol(dot11.Dot11ManagementProbeRequest) if not probe_req_frame: return ssid = probe_req_frame.get_ssid() if not ssid: # Ignore broadcast SSID return station_address = management_frame.get_source_address() print "Station: %s" % ":".join(map(lambda i: "%02X" % i, station_address)) print "SSID: %s" % ssid frame = str() # Radiotap frame += "\x00\x00" # Version frame += "\x0b\x00" # Header Length frame += "\x04\x0c\x00\x00" # Presence Flags frame += "\x6c" # Rate frame += "\x0c" # TX Power frame += "\x01" # Antenna # Management Frame frame += "\x50\x00" # Frame Control frame += "\x31\x01" # Duration frame += "".join(chr(i) for i in station_address) # Destination Address frame += "\x00\xde\xad\xbe\xef\x00" # Source Address frame += "\x00\xde\xad\xbe\xef\x00" # BSSID Address frame += "\x00\x00" # Sequence Control frame += "\x00\x00\x00\x00\x00\x00\x00\x00" # Timestamp frame += "\x64\x00" # Beacon Interval frame += "\x01\x04" # Capabilities frame += "\x00%s%s" % (struct.pack("B", len(ssid)), ssid) # SSID frame += "\x01\x08\x82\x84\x8b\x96\x24\x30\x48\x6c" # Supported Rates frame += "\x03\x01\x0e" # DS parameter set frame += "\xdd\x06\xfa\xfa\xfa\x00\xde\xad" # Vendor Specific workers = manager.get_workers() for worker in workers: if worker.raw_mac_address() == worker_addr: break for iface in worker.interfaces_list(): manager.inject_data_from_worker_interface(worker.raw_mac_address(), iface.name(), frame)
class TestRadioTapDecoder(unittest.TestCase): def setUp(self): self.RadioTapData=b'\x00\x00\x20\x00\x67\x08\x04\x00\x30\x03\x1a\x25\x00\x00\x00\x00\x22\x0c\xd9\xa0\x02\x00\x00\x00\x40\x01\x00\x00\x3c\x14\x24\x11\x08\x02\x00\x00\xff\xff\xff\xff\xff\xff\x06\x03\x7f\x07\xa0\x16\x00\x19\xe3\xd3\x53\x52\x90\x7f\xaa\xaa\x03\x00\x00\x00\x08\x06\x00\x01\x08\x00\x06\x04\x00\x01\x00\x19\xe3\xd3\x53\x52\xa9\xfe\xf7\x00\x00\x00\x00\x00\x00\x00\x43\x08\x0e\x36' self.radiotap_decoder = RadioTapDecoder() self.in0=self.radiotap_decoder.decode(self.RadioTapData) self.in1=self.in0.child() self.in2=self.in1.child() self.in3=self.in2.child() self.in4=self.in3.child() self.in5=self.in4.child() self.in6=self.in5.child() def test_00(self): 'Test RadioTap decoder' if PY2: self.assertEqual(str(self.in0.__class__), "impacket.dot11.RadioTap") else: self.assertEqual(str(self.in0.__class__), "<class 'impacket.dot11.RadioTap'>") def test_01(self): 'Test Dot11 decoder' if PY2: self.assertEqual(str(self.in1.__class__), "impacket.dot11.Dot11") else: self.assertEqual(str(self.in1.__class__), "<class 'impacket.dot11.Dot11'>") def test_02(self): 'Test Dot11DataFrame decoder' if PY2: self.assertEqual(str(self.in2.__class__), "impacket.dot11.Dot11DataFrame") else: self.assertEqual(str(self.in2.__class__), "<class 'impacket.dot11.Dot11DataFrame'>") def test_03(self): 'Test LLC decoder' if PY2: self.assertEqual(str(self.in3.__class__), "impacket.dot11.LLC") else: self.assertEqual(str(self.in3.__class__), "<class 'impacket.dot11.LLC'>") def test_04(self): 'Test SNAP decoder' if PY2: self.assertEqual(str(self.in4.__class__), "impacket.dot11.SNAP") else: self.assertEqual(str(self.in4.__class__), "<class 'impacket.dot11.SNAP'>") # def test_05(self): # 'Test ARP decoder' # self.assertEqual(str(self.in5.__class__), "ImpactPacket.ARP") # def test_05(self): # 'Test Data decoder' # self.assertEqual(str(self.in6.__class__), "ImpactPacket.Data") def test_06(self): 'Test Protocol Finder' p=self.radiotap_decoder.get_protocol(impacket.dot11.RadioTap) if PY2: self.assertEqual(str(p.__class__), "impacket.dot11.RadioTap") else: self.assertEqual(str(p.__class__), "<class 'impacket.dot11.RadioTap'>") p=self.radiotap_decoder.get_protocol(impacket.dot11.Dot11) if PY2: self.assertEqual(str(p.__class__), "impacket.dot11.Dot11") else: self.assertEqual(str(p.__class__), "<class 'impacket.dot11.Dot11'>") p=self.radiotap_decoder.get_protocol(impacket.dot11.Dot11DataFrame) if PY2: self.assertEqual(str(p.__class__), "impacket.dot11.Dot11DataFrame") else: self.assertEqual(str(p.__class__), "<class 'impacket.dot11.Dot11DataFrame'>") p=self.radiotap_decoder.get_protocol(impacket.dot11.LLC) if PY2: self.assertEqual(str(p.__class__), "impacket.dot11.LLC") else: self.assertEqual(str(p.__class__), "<class 'impacket.dot11.LLC'>") p=self.radiotap_decoder.get_protocol(impacket.dot11.SNAP) if PY2: self.assertEqual(str(p.__class__), "impacket.dot11.SNAP") else: self.assertEqual(str(p.__class__), "<class 'impacket.dot11.SNAP'>") #p=self.radiotap_decoder.get_protocol(ImpactPacket.ARP) #self.assertEqual(str(p.__class__), "ImpactPacket.ARP") #p=self.radiotap_decoder.get_protocol(ImpactPacket.Data) #self.assertEqual(str(p.__class__), "ImpactPacket.Data") # When not found, None is returned p=self.radiotap_decoder.get_protocol(impacket.dot11.Dot11WPA) self.assertEqual(p, None)
class WpsScanner(object): def __init__(self, interface, channel=None, timeout=5, output=None, passive=False, mac=None, logfile=None): self.interface = interface self.channel = channel self.timeout = timeout self.output = output self.passive = passive self.mac = mac if is_valid_mac_address(mac) else None self.logfile = logfile # self.aps = {} self.wps_aps = {} self.captured = [] self.probes_sent = [] self._stop = False # self.wps_parser = WPSParser() self.rtDecoder = RadioTapDecoder() # Initialize logger self.logger = logging.getLogger('airlog') self.logger.setLevel(logging.INFO) # Console logging ch = logging.StreamHandler() ch.setLevel(logging.INFO) formatter = coloredlogs.ColoredFormatter( '[%(asctime)s] - %(levelname)s - %(message)s', datefmt='%d.%m.%Y %H:%M:%S') ch.setFormatter(formatter) self.logger.addHandler(ch) # Logging to file if logfile is None: return fh = logging.FileHandler(logfile) fh.setLevel(logging.DEBUG) formatter = logging.Formatter('[%(asctime)s] - %(message)s', datefmt='%d.%m.%Y %H:%M:%S') fh.setFormatter(formatter) self.logger.addHandler(fh) def set_mode(self, mode): if OSX: return self.logger.debug('Enabling %s mode on %s' % (mode, self.interface)) os.system('ifconfig %s down' % self.interface) os.system('iwconfig %s mode %s' % (self.interface, mode)) os.system('ifconfig %s up' % self.interface) def enable_monitor(self): self.set_mode('monitor') # return subprocess.Popen('ifconfig %s down && iw %s set type monitor && ifconfig %s up' % # (self.interface, self.interface, self.interface), shell=True).communicate() def set_channel(self, channel): if LINUX: os.system('iwconfig %s channel %s' % (self.interface, channel)) elif OSX: subprocess.call(['sudo', AIRPORT, '--channel=' + str(channel)]) # os.system('%s %s --channel=%s' % (AIRPORT ,self.interface, channel)) def signal_handler(self, frame, code): # print("Ctrl+C caught. Exiting..") # sys.exit(-1) try: if query_yes_no("\nReally quit?"): self.logger.info( 'Trying to quit correctly. Be patient please...') self._stop = True # self.save() except KeyboardInterrupt: self.logger.warning("Ok ok... Quitting without saving!") sys.exit(1) def get_security(self, pkt): # Check for encrypted networks capability = pkt.sprintf("{Dot11Beacon:%Dot11Beacon.cap%}\ {Dot11ProbeResp:%Dot11ProbeResp.cap%}") p = pkt[Dot11Elt] crypto = set() while isinstance(p, Dot11Elt): if p.ID == 48: crypto.add("WPA2") elif p.ID == 221 and p.info.startswith('\x00P\xf2\x01\x01\x00'): crypto.add("WPA") p = p.payload if not crypto: if 'privacy' in capability: crypto.add("WEP") else: crypto.add("OPEN") return '/'.join(crypto) def handle_beacon(self, pkt): """Process 802.11 Beacon Frame for WPS IE.""" try: rt = self.rtDecoder.get_protocol(dot11.RadioTap) mgt = self.rtDecoder.get_protocol(dot11.Dot11ManagementFrame) beacon = self.rtDecoder.get_protocol(dot11.Dot11ManagementBeacon) bssid = get_addr_from_list(mgt.get_bssid()) essid = str(beacon.get_ssid()) freq = rt.get_channel()[0] channel = frequencies_dict[freq] enc = self.get_security(pkt) vendor = get_vendor(bssid) wps = self.wps_parser.has_wps(beacon.get_vendor_specific()) # Display and save discovered AP if bssid in self.aps: return self.logger.info( "[+] AP found! Channel: %02d ESSID: %s BSSID: %s Encryption: %s Vendor: %s WPS: %s" % (int(channel), essid, bssid, enc, vendor, wps)) self.aps[bssid] = (int(channel), essid, enc, wps) # wi = self.wps_parser.parse_beacon(pkt) print('WPSINFO', wi) # ACTIVE MODE # if wps and not self.passive and bssid not in self.probes_sent: # self.send_probe_req(essid) # # self.send_probe_req_2(essid) # self.probes_sent.append(bssid) except Exception as e: print('Error while parsing beacon') print(str(sys.exc_info())) return None def handle_probe_response(self, pkt): """Process 802.11 Probe Response Frame for WPS IE.""" try: mgt = self.rtDecoder.get_protocol(dot11.Dot11ManagementFrame) probe = self.rtDecoder.get_protocol( dot11.Dot11ManagementProbeResponse) bssid = get_addr_from_list(mgt.get_bssid()) essid = probe.get_ssid() # If null byte in the SSID IE, its cloacked. if essid is None or essid.find("\x00") != -1: essid = "<No ssid>" if bssid in self.aps: return rt = self.rtDecoder.get_protocol(dot11.RadioTap) freq = rt.get_channel()[0] channel = frequencies_dict[freq] vendor = get_vendor(bssid) vendorIEs = probe.get_vendor_specific() wps = self.wps_parser.has_wps(vendorIEs) # print 'checking wps info' if self.wps_parser.has_wps(vendorIEs): hexdump(vendorIEs) # wpsInfo = self.wps_parser.parse_wps(vendorIEs) if wpsInfo: self.wps_aps[bssid] = wpsInfo print("[%s] - [%s]\t%s'\nWPS Information" % (bssid, essid, vendor)) for key, value in wpsInfo.items(): print("[WPSINFO] * %s: %s" % (key, repr(value))) self.wps_parser.parse_probe_response(pkt) enc = self.get_security(pkt) self.aps[bssid] = (channel, essid, enc, wps) self.logger.info( '[+] AP discovered! ProbeResponse channel: %s ESSID: %s Encryption: %s WPS: %s Vendor: %s' % (channel, _green(essid), _colorize_security(enc), _colorize_wps(wps), _green(get_vendor(bssid)))) except Exception: print('Error while parsing probe responsse') print(str(sys.exc_info())) return @property def scan_table(self): x = PrettyTable([ 'Channel', 'BSSID', 'ESSID', 'Security', 'Vendor', 'WPS', 'WPS Info' ]) x.align["ESSID"] = "l" x.align["Vendor"] = "l" for bssid in sorted(self.aps, key=lambda k: self.aps[k][0]): channel, essid, enc, wps = self.aps[bssid] wps_text = '' wpsinfo = self.wps_aps[bssid] if bssid in self.wps_aps else None if wpsinfo: for key, value in wpsinfo.items(): wps_text += " %s: %s" % (key, repr(value)) x.add_row([ channel, bssid, essid, _colorize_security(enc), get_vendor(bssid), _colorize_wps(wps), wps_text ]) return x def pkt_handler(self, pkt): try: self.rtDecoder.decode(str(pkt)) except Exception: self.logger.error('Error while decoding packet..') print(sys.exc_info()) return # Management frames if pkt.type == 0: # Probe response if pkt.subtype == 5: self.handle_probe_response(pkt) # Beacon elif pkt.subtype == 8: self.handle_beacon(pkt) def send_probe_req(self, bssid, essid): """Send a probe request to the specified AP""" src = RandMAC() if self.mac is None else self.mac self.logger.info( '[!] Sending Broadcast Probe Request: SRC=[%s] -> BSSID: %s ESSID: %s' % (src, bssid, essid)) param = Dot11ProbeReq() essid = Dot11Elt(ID='SSID', info=essid) rates = Dot11Elt(ID='Rates', info="\x03\x12\x96\x18\x24\x30\x48\x60") dsset = Dot11Elt(ID='DSset', info='\x01') pkt = RadioTap() / Dot11( type=0, subtype=4, addr1='ff:ff:ff:ff:ff:ff', addr2=src, addr3='ff:ff:ff:ff:ff:ff') / param / essid / rates / dsset try: sendp(pkt, verbose=0) except: return # raise # print("Probing network '%s (%s)'\n" % (bssid, essid)) try: # Build a probe request packet with a SSID and a WPS information element dst = mac2str(bssid) src = mac2str("ff:ff:ff:ff:ff:ff") packet = Dot11(addr1=dst, addr2=src, addr3=dst) / Dot11ProbeReq() packet = packet / Dot11Elt( ID=0, len=len(essid), info=essid) / Dot11Elt( ID=221, len=9, info="%s\x10\x4a\x00\x01\x10" % self.wps_parser.WPS_ID) # Send it! send(packet, verbose=0) # self.probedNets[bssid] = None except Exception, e: print 'Failure sending probe request to', essid, ':', e
class WpsScanner(object): def __init__(self, interface, channel=None, timeout=5, output=None, passive=False, mac=None, logfile=None): self.interface = interface self.channel = channel self.timeout = timeout self.output = output self.passive = passive self.mac = mac if is_valid_mac_address(mac) else None self.logfile = logfile # self.aps = {} self.wps_aps = {} self.captured = [] self.probes_sent = [] self._stop = False # self.wps_parser = WpsParser() self.rtDecoder = RadioTapDecoder() # Initialize logger self.logger = logging.getLogger('airlog') self.logger.setLevel(logging.INFO) # Console logging ch = logging.StreamHandler() ch.setLevel(logging.INFO) formatter = coloredlogs.ColoredFormatter('[%(asctime)s] - %(levelname)s - %(message)s', datefmt='%d.%m.%Y %H:%M:%S') ch.setFormatter(formatter) self.logger.addHandler(ch) # Logging to file if logfile is None: return fh = logging.FileHandler(logfile) fh.setLevel(logging.DEBUG) formatter = logging.Formatter('[%(asctime)s] - %(message)s', datefmt='%d.%m.%Y %H:%M:%S') fh.setFormatter(formatter) self.logger.addHandler(fh) def set_mode(self, mode): if OSX: return self.logger.debug('Enabling %s mode on %s' % (mode, self.interface)) os.system('ifconfig %s down' % self.interface) os.system('iwconfig %s mode %s' % (self.interface, mode)) os.system('ifconfig %s up' % self.interface) def enable_monitor(self): self.set_mode('monitor') # return subprocess.Popen('ifconfig %s down && iw %s set type monitor && ifconfig %s up' % # (self.interface, self.interface, self.interface), shell=True).communicate() def set_channel(self, channel): if LINUX: os.system('iwconfig %s channel %s' % (self.interface, channel)) elif OSX: subprocess.call(['sudo', AIRPORT, '--channel=' + str(channel)]) # os.system('%s %s --channel=%s' % (AIRPORT ,self.interface, channel)) def signal_handler(self, frame, code): # print("Ctrl+C caught. Exiting..") # sys.exit(-1) try: if query_yes_no("\nReally quit?"): self.logger.info('Trying to quit correctly. Be patient please...') self._stop = True # self.save() except KeyboardInterrupt: self.logger.warning("Ok ok... Quitting without saving!") sys.exit(1) def get_security(self, pkt): # Check for encrypted networks capability = pkt.sprintf("{Dot11Beacon:%Dot11Beacon.cap%}\ {Dot11ProbeResp:%Dot11ProbeResp.cap%}") p = pkt[Dot11Elt] crypto = set() while isinstance(p, Dot11Elt): if p.ID == 48: crypto.add("WPA2") elif p.ID == 221 and p.info.startswith('\x00P\xf2\x01\x01\x00'): crypto.add("WPA") p = p.payload if not crypto: if 'privacy' in capability: crypto.add("WEP") else: crypto.add("OPEN") return '/'.join(crypto) def handle_beacon(self, pkt): """Process 802.11 Beacon Frame for WPS IE.""" try: rt = self.rtDecoder.get_protocol(dot11.RadioTap) mgt = self.rtDecoder.get_protocol(dot11.Dot11ManagementFrame) beacon = self.rtDecoder.get_protocol(dot11.Dot11ManagementBeacon) bssid = get_addr_from_list(mgt.get_bssid()) essid = str(beacon.get_ssid()) freq = rt.get_channel()[0] channel = frequencies_dict[freq] enc = self.get_security(pkt) vendor = get_vendor(bssid) wps = self.wps_parser.has_wps(beacon.get_vendor_specific()) # Display and save discovered AP if bssid in self.aps: return self.logger.info("[+] AP found! Channel: %02d ESSID: %s BSSID: %s Encryption: %s Vendor: %s WPS: %s" % (int(channel), essid, bssid, enc, vendor, wps)) self.aps[bssid] = (int(channel), essid, enc, wps) # # wi = self.wps_parser.parse_beacon(pkt) # print('WPSINFO', wi) # ACTIVE MODE # if wps and not self.passive and bssid not in self.probes_sent: # self.send_probe_req(essid) # # self.send_probe_req_2(essid) # self.probes_sent.append(bssid) except Exception as e: print('Error while parsing beacon') print(str(sys.exc_info())) return None def handle_probe_response(self, pkt): """Process 802.11 Probe Response Frame for WPS IE.""" try: mgt = self.rtDecoder.get_protocol(dot11.Dot11ManagementFrame) probe = self.rtDecoder.get_protocol(dot11.Dot11ManagementProbeResponse) bssid = get_addr_from_list(mgt.get_bssid()) essid = probe.get_ssid() # If null byte in the SSID IE, its cloacked. if essid is None or essid.find("\x00") != -1: essid = "<No ssid>" if bssid in self.aps: return rt = self.rtDecoder.get_protocol(dot11.RadioTap) freq = rt.get_channel()[0] channel = frequencies_dict[freq] vendor = get_vendor(bssid) vendorIEs = probe.get_vendor_specific() wps = self.wps_parser.has_wps(vendorIEs) # print 'checking wps info' if self.wps_parser.has_wps(vendorIEs): hexdump(vendorIEs) wpsInfo = self.wps_parser.parse_wps(vendorIEs) if wpsInfo: self.wps_aps[bssid] = wpsInfo print("[%s] - [%s]\t%s'\nWPS Information" % (bssid, essid, vendor)) for key, value in wpsInfo.items(): print("[WPSINFO] * %s: %s" % (key, repr(value))) self.wps_parser.parse_probe_response(pkt) enc = self.get_security(pkt) self.aps[bssid] = (channel, essid, enc, wps) self.logger.info( '[+] AP discovered! ProbeResponse channel: %s ESSID: %s Encryption: %s WPS: %s Vendor: %s' % (channel, _green(essid), _colorize_security(enc), _colorize_wps(wps), _green(get_vendor(bssid)))) except Exception: print('Error while parsing probe responsse') print(str(sys.exc_info())) return @property def scan_table(self): x = PrettyTable(['Channel', 'BSSID', 'ESSID', 'Security', 'Vendor', 'WPS', 'WPS Info']) x.align["ESSID"] = "l" x.align["Vendor"] = "l" for bssid in sorted(self.aps, key=lambda k: self.aps[k][0]): channel, essid, enc, wps= self.aps[bssid] wps_text = '' wpsinfo = self.wps_aps[bssid] if bssid in self.wps_aps else None if wpsinfo: for key, value in wpsinfo.items(): wps_text += " %s: %s" % (key, repr(value)) x.add_row([channel, bssid, essid, _colorize_security(enc), get_vendor(bssid), _colorize_wps(wps), wps_text]) return x def pkt_handler(self, pkt): try: self.rtDecoder.decode(str(pkt)) except Exception: self.logger.error('Error while decoding packet..') print(sys.exc_info()) return # Management frames if pkt.type == 0: # Probe response if pkt.subtype == 5: self.handle_probe_response(pkt) # Beacon elif pkt.subtype == 8: self.handle_beacon(pkt) def send_probe_req(self, bssid, essid): """Send a probe request to the specified AP""" src = RandMAC() if self.mac is None else self.mac self.logger.info('[!] Sending Broadcast Probe Request: SRC=[%s] -> BSSID: %s ESSID: %s' % (src, bssid, essid)) param = Dot11ProbeReq() essid = Dot11Elt(ID='SSID', info=essid) rates = Dot11Elt(ID='Rates', info="\x03\x12\x96\x18\x24\x30\x48\x60") dsset = Dot11Elt(ID='DSset', info='\x01') pkt = RadioTap() / Dot11(type=0, subtype=4, addr1='ff:ff:ff:ff:ff:ff', addr2=src, addr3='ff:ff:ff:ff:ff:ff') / param / essid / rates / dsset try: sendp(pkt, verbose=0) except: return print ("Probing network '%s (%s)'\n" % (bssid, essid)) try: # Build a probe request packet with a SSID and a WPS information element dst = mac2str(bssid) src = mac2str("ff:ff:ff:ff:ff:ff") packet = Dot11(addr1=dst, addr2=src, addr3=dst) / Dot11ProbeReq() packet = packet / Dot11Elt(ID=0, len=len(essid), info=essid) / Dot11Elt(ID=221, len=9, info="%s\x10\x4a\x00\x01\x10" % self.wps_parser.WPS_ID) # Send it! send(packet, verbose=0) # self.probedNets[bssid] = None except Exception, e: print 'Failure sending probe request to', essid, ':', e
class WpsScanner(object): def __init__(self, args): self.args = args self.accessPoints = [] self.interface = args.interface self.macAddress = args.source if isValidMacAddress(args.source) else None self.filename = args.write self.wps_parser = WPSParser() self.oui = OUI() self.captured = [] self.iw = IW(self.args.interface) self.iw.set_monitor() self.ap_dict = {} self.clients_dict = {} self.rtDecoder = RadioTapDecoder() def signal_handler(self, frame, code): print("Ctrl+C caught. Exiting..") exit(-1) def __getAddressFromList(self, bytes_list): "Return a string of a MAC address on a bytes list." return ":".join(map(lambda x: "%02X" % x, bytes_list)) def __getListFromAddress(self, address): "Return a list from a MAC address string." return map(lambda x: int(x, 16), address.split(":")) def _packet_filter(self, pkt): # wlan.fc.type == 0 Management frames # wlan.fc.type == 1 Control frames # wlan.fc.type == 2 Data frames # wlan.fc.type_subtype == 0 Association request # wlan.fc.type_subtype == 1 Association response # wlan.fc.type_subtype == 2 Reassociation request # wlan.fc.type_subtype == 3 Reassociation response # wlan.fc.type_subtype == 4 Probe request # wlan.fc.type_subtype == 5 Probe response # wlan.fc.type_subtype == 8 Beacon return True if pkt.haslayer(Dot11) and pkt.type == 0 else False # return True if pkt.haslayer(Dot11) and pkt.type == 0 and pkt.subtype in [5, 8] else False def _packet_handler(self, pkt): """Process 802.11 Packets.""" data = str(pkt) try: self.rtDecoder.decode(data) beacon = self.rtDecoder.get_protocol(dot11.Dot11ManagementBeacon) probe = self.rtDecoder.get_protocol(dot11.Dot11ManagementProbeResponse) # Process Beacons and inject Probe Requests only when not passive if beacon is not None: self.handle_beacon(data) elif probe is not None: info = self.handle_probe_response(data) if info: bssid, essid = info[0], info[1] vendor, wpsInfo = info[2], info[3] result = "[%s] - [%s]\t%s'\nWPS Information\n" % (bssid, essid, vendor) for key, value in wpsInfo.items(): result += " * %s: %s\n" % (key, repr(value)) result += "-" * 80 + "\n" return result elif pkt.haslayer(Dot11ProbeReq): self.handle_probe_req(pkt) except Exception as e: # print('Error while processing packet') # print(str(exc_info())) return None def handle_beacon(self, pkt): """Process 802.11 Beacon Frame for WPS IE.""" try: self.rtDecoder.decode(pkt) rt = self.rtDecoder.get_protocol(dot11.RadioTap) channel = rt.get_channel()[0] flags= rt.get_flags() tsft = rt.get_tsft() rate = rt.get_rate() management = self.rtDecoder.get_protocol(dot11.Dot11ManagementFrame) beacon = self.rtDecoder.get_protocol(dot11.Dot11ManagementBeacon) bssid = self.__getAddressFromList(management.get_bssid()) essid = str(beacon.get_ssid()) vendor = self.oui.get_vendor(bssid) if bssid not in self.ap_dict: self.ap_dict[bssid] ={'essid':essid, 'channel':channel, 'clients':[],'vendor':vendor} print(Fore.GREEN+'[+] New AP [%s] [%s] at %s vendor:%s TSFT: %s RATE: %s FLAGS: %s' % (bssid, essid, channel, vendor, tsft, rate,flags)) # ACTIVE MODE if self.accessPoints.count(bssid) == 0 and self.wps_parser.has_wps(beacon.get_vendor_specific()): # TODO: add injection self.send_probe_req(essid, bssid,) except Exception as e: # print('Error while parsing beacon') # print(str(exc_info())) return None # Probe requests from clients def handle_probe_req(self, pkt): if pkt.haslayer(Dot11ProbeReq) and '\x00' not in pkt[Dot11ProbeReq].info: essid = pkt[Dot11ProbeReq].info else: essid = 'Hidden SSID' client = pkt[Dot11].addr2 # if client in self.whitelist or essid in self.whitelist: # TODO: add logging # return # New client if client not in self.clients_dict: self.clients_dict[client] = [] print(Fore.GREEN+'[!] New client: %s ' % client) if essid not in self.clients_dict[client]: self.clients_dict[client].append(essid) print(Fore.GREEN+'[+] New ProbeRequest: from %s to %s' % (client, essid)) def handle_probe_response(self, pkt): """Process 802.11 Probe Response Frame for WPS IE.""" try: self.rtDecoder.decode(pkt) mgt = self.rtDecoder.get_protocol(dot11.Dot11ManagementFrame) probe = self.rtDecoder.get_protocol(dot11.Dot11ManagementProbeResponse) bssid = self.__getAddressFromList(mgt.get_bssid()) essid = probe.get_ssid() # If null byte in the SSID IE, its cloacked. if essid.find("\x00") != -1: essid = "<No ssid>" if bssid not in self.ap_dict: self.rtDecoder.decode(pkt) rt = self.rtDecoder.get_protocol(dot11.RadioTap) channel = rt.get_channel()[0] self.ap_dict[bssid] = {'essid':essid, 'channel':channel, 'clients':[],'vendor':self.oui.get_vendor(bssid)} vendorIEs = probe.get_vendor_specific() if self.wps_parser.has_wps(vendorIEs): vendor = self.oui.get_vendor(bssid) wpsInfo = self.wps_parser.parse_wps(vendorIEs) return [bssid, essid, vendor, wpsInfo] except Exception: # print('Error while parsing probe responsse') return None def send_probe_req(self, essid, bssid, src=None): if not self.args.active: return if src is None: src = RandMAC() print('[!] Sending 802.11 Probe Request: SRC=[%s] -> BSSID=[%s]\t(%s)' % (src, bssid, essid)) param = Dot11ProbeReq() essid = Dot11Elt(ID='SSID',info=essid) rates = Dot11Elt(ID='Rates',info="\x03\x12\x96\x18\x24\x30\x48\x60") dsset = Dot11Elt(ID='DSset',info='\x01') pkt = RadioTap()\ /Dot11(type=0, subtype=4, addr1=bssid, addr2=src, addr3=bssid)/param/essid/rates/dsset try: sendp(pkt, verbose=0) except: raise def send_probe_req_2(self, src, ssid): """Return 802.11 Probe Request Frame.""" # Frame Control frameControl = dot11.Dot11() frameControl.set_version(0) frameControl.set_type_n_subtype(dot11.Dot11Types.DOT11_TYPE_MANAGEMENT_SUBTYPE_PROBE_REQUEST) # Frame Control Flags frameControl.set_fromDS(0) frameControl.set_toDS(0) frameControl.set_moreFrag(0) frameControl.set_retry(0) frameControl.set_powerManagement(0) frameControl.set_moreData(0) frameControl.set_protectedFrame(0) frameControl.set_order(0) # Management Frame sequence = randint(0, 4096) broadcast = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff] mngtFrame = dot11.Dot11ManagementFrame() mngtFrame.set_duration(0) mngtFrame.set_destination_address(broadcast) mngtFrame.set_source_address(src) mngtFrame.set_bssid(broadcast) mngtFrame.set_fragment_number(0) mngtFrame.set_sequence_number(sequence) # Probe Request Frame probeRequestFrame = dot11.Dot11ManagementProbeRequest() probeRequestFrame.set_ssid(ssid) probeRequestFrame.set_supported_rates([0x02, 0x04, 0x0b, 0x16]) # How is your daddy? mngtFrame.contains(probeRequestFrame) frameControl.contains(mngtFrame) # return frameControl.get_packet() # src = self.__getListFromAddress(self.args.source) if args.source is not None else self.__getListFromAddress(RandMAC()) # probe = self.__getProbeRequest(src, ssid) return sendp(frameControl.get_packet(), iface=self.args.interface, verbose=0) def start(self, timeout=10): signal.signal(signal.SIGINT, self.signal_handler) print("Press Ctrl+C to stop. Sniffing...") print("-" * 80) while True: for x in [1,6,11,1,3,5,9,13]: print(Fore.YELLOW+"[*] Switching channel to: %i" % x) self.iw.set_channel(x) self.captured.append(sniff(iface=self.interface, prn=self._packet_handler, lfilter=self._packet_filter, store=1, timeout=timeout))
class WpsScanner(object): def __init__(self, args): self.args = args self.accessPoints = [] self.interface = args.interface self.macAddress = args.source if is_valid_mac_address( args.source) else None self.filename = args.write # self.captured = [] self.channel = None self.ap_dict = {} self.clients_dict = {} # self.rtDecoder = RadioTapDecoder() self.wps_parser = WPSParser() def enable_monitor(self): return subprocess.Popen( 'ifconfig %s down && iw %s set type monitor && ifconfig %s up' % (self.interface, self.interface, self.interface), shell=True).communicate() def set_channel(self, channel, width=None): cmd = 'iw %s set channel %s ' % (self.interface, channel) self.channel = channel if width is not None: if width == 20: cmd += 'HT20' elif width == 40: cmd += 'HT40+' elif width == -40: cmd += 'HT40-' return subprocess.Popen(cmd, shell=True).communicate() def signal_handler(self, frame, code): print("Ctrl+C caught. Exiting...") # TODO: add writing to pcap file sys.exit(-1) def __getAddressFromList(self, bytes_list): "Return a string of a MAC address on a bytes list." return ":".join(map(lambda x: "%02X" % x, bytes_list)) def __getListFromAddress(self, address): "Return a list from a MAC address string." return map(lambda x: int(x, 16), address.split(":")) def _packet_filter(self, pkt): # wlan.fc.type == 0 Management frames # wlan.fc.type == 1 Control frames # wlan.fc.type == 2 Data frames # wlan.fc.type_subtype == 0 Association request # wlan.fc.type_subtype == 1 Association response # wlan.fc.type_subtype == 2 Reassociation request # wlan.fc.type_subtype == 3 Reassociation response # wlan.fc.type_subtype == 4 Probe request # wlan.fc.type_subtype == 5 Probe response # wlan.fc.type_subtype == 8 Beacon return True if pkt.haslayer(Dot11) and pkt.type == 0 else False # return True if pkt.haslayer(Dot11) and pkt.type == 0 and pkt.subtype in [5, 8] else False def _packet_handler(self, pkt): """Process 802.11 Packets.""" data = str(pkt) try: self.rtDecoder.decode(data) beacon = self.rtDecoder.get_protocol(dot11.Dot11ManagementBeacon) probe = self.rtDecoder.get_protocol( dot11.Dot11ManagementProbeResponse) # Process Beacons and inject Probe Requests only when not passive if beacon is not None: self.handle_beacon(data) elif probe is not None: info = self.handle_probe_response(data) if info: bssid, essid = info[0], info[1] vendor, wpsInfo = info[2], info[3] result = "[%s] - [%s]\t%s'\nWPS Information\n" % ( bssid, essid, vendor) for key, value in wpsInfo.items(): result += " * %s: %s\n" % (key, repr(value)) result += "-" * 80 + "\n" return result except Exception as e: return None def handle_beacon(self, pkt): """Process 802.11 Beacon Frame for WPS IE.""" try: self.rtDecoder.decode(pkt) rt = self.rtDecoder.get_protocol(dot11.RadioTap) channel = rt.get_channel()[0] flags = rt.get_flags() tsft = rt.get_tsft() rate = rt.get_rate() management = self.rtDecoder.get_protocol( dot11.Dot11ManagementFrame) beacon = self.rtDecoder.get_protocol(dot11.Dot11ManagementBeacon) bssid = self.__getAddressFromList(management.get_bssid()) essid = str(beacon.get_ssid()) vendor = get_vendor(bssid) if bssid not in self.ap_dict: self.ap_dict[bssid] = { 'essid': essid, 'channel': channel, 'clients': [], 'vendor': vendor } print( Fore.GREEN + '[+] New AP [%s] [%s] at %s vendor:%s TSFT: %s RATE: %s FLAGS: %s' % (bssid, essid, channel, vendor, tsft, rate, flags)) # ACTIVE MODE if self.accessPoints.count(bssid) == 0 and self.wps_parser.has_wps( beacon.get_vendor_specific()): # TODO: add injection self.send_probe_req( essid, bssid, ) except Exception as e: # print('Error while parsing beacon') # print(str(exc_info())) return None def handle_probe_response(self, pkt): """Process 802.11 Probe Response Frame for WPS IE.""" try: self.rtDecoder.decode(pkt) mgt = self.rtDecoder.get_protocol(dot11.Dot11ManagementFrame) probe = self.rtDecoder.get_protocol( dot11.Dot11ManagementProbeResponse) bssid = self.__getAddressFromList(mgt.get_bssid()) essid = probe.get_ssid() # If null byte in the SSID IE, its cloacked. if essid.find("\x00") != -1: essid = "<No ssid>" if bssid not in self.ap_dict: self.rtDecoder.decode(pkt) rt = self.rtDecoder.get_protocol(dot11.RadioTap) channel = rt.get_channel()[0] self.ap_dict[bssid] = { 'essid': essid, 'channel': channel, 'clients': [], 'vendor': get_vendor(bssid) } vendorIEs = probe.get_vendor_specific() if self.wps_parser.has_wps(vendorIEs): vendor = get_vendor(bssid) wpsInfo = self.wps_parser.parse_wps(vendorIEs) return [bssid, essid, vendor, wpsInfo] except Exception: # print('Error while parsing probe responsse') return None def send_probe_req(self, essid, bssid, src=None): if not self.args.active: return if src is None: src = RandMAC() print( '[!] Sending 802.11 Probe Request: SRC=[%s] -> BSSID=[%s]\t(%s)' % (src, bssid, essid)) param = Dot11ProbeReq() essid = Dot11Elt(ID='SSID', info=essid) rates = Dot11Elt(ID='Rates', info="\x03\x12\x96\x18\x24\x30\x48\x60") dsset = Dot11Elt(ID='DSset', info='\x01') pkt = RadioTap() \ / Dot11(type=0, subtype=4, addr1=bssid, addr2=src, addr3=bssid) / param / essid / rates / dsset try: sendp(pkt, verbose=0) except: raise def send_probe_req_2(self, src, ssid): """Return 802.11 Probe Request Frame.""" # Frame Control frameControl = dot11.Dot11() frameControl.set_version(0) frameControl.set_type_n_subtype( dot11.Dot11Types.DOT11_TYPE_MANAGEMENT_SUBTYPE_PROBE_REQUEST) # Frame Control Flags frameControl.set_fromDS(0) frameControl.set_toDS(0) frameControl.set_moreFrag(0) frameControl.set_retry(0) frameControl.set_powerManagement(0) frameControl.set_moreData(0) frameControl.set_protectedFrame(0) frameControl.set_order(0) # Management Frame sequence = random.randint(0, 4096) broadcast = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff] mngtFrame = dot11.Dot11ManagementFrame() mngtFrame.set_duration(0) mngtFrame.set_destination_address(broadcast) mngtFrame.set_source_address(src) mngtFrame.set_bssid(broadcast) mngtFrame.set_fragment_number(0) mngtFrame.set_sequence_number(sequence) # Probe Request Frame probeRequestFrame = dot11.Dot11ManagementProbeRequest() probeRequestFrame.set_ssid(ssid) probeRequestFrame.set_supported_rates([0x02, 0x04, 0x0b, 0x16]) # How is your daddy? mngtFrame.contains(probeRequestFrame) frameControl.contains(mngtFrame) # return frameControl.get_packet() # src = self.__getListFromAddress(self.args.source) if args.source is not None else self.__getListFromAddress(RandMAC()) # probe = self.__getProbeRequest(src, ssid) return sendp(frameControl.get_packet(), iface=self.args.interface, verbose=0) def start(self, timeout=10): # Set signal handler signal.signal(signal.SIGINT, self.signal_handler) # Enable monitor if 'mon' not in self.interface: print("Enabling monitor interface on " + self.interface) self.enable_monitor() # Startinf to sniffer print("Press Ctrl+C to stop. Sniffing...") print("-" * 80) while True: for x in [1, 6, 11, 1, 3, 5, 9, 13]: print(Fore.YELLOW + "[*] Switching channel to: %i" % x) self.set_channel(x) self.captured.extend( sniff(iface=self.interface, prn=self._packet_handler, lfilter=self._packet_filter, store=1, timeout=timeout))