def print_packet(args, bts): """ Print basic information to console. bts -- Bytes retrieved by HackRFBoard return -- True if crc ok, False otherwise """ crc_ok = False try: bts_pkt = bts[:-DEMOD_BYTES_META_LEN] pkt = btle.BTLE(bts_pkt) bts_ch = bts[-DEMOD_BYTES_META_LEN] bts_sig = bts[-DEMOD_BYTES_META_LEN + 1] counter = unpack_I(b"\x00" + bts[-DEMOD_BYTES_META_LEN + 2:-DEMOD_BYTES_META_LEN + 5])[0] upper_layer = pkt.upper_layer crc_ok = pkt.is_crc_ok(crc_init=args.crc_init) print("%-14s CH: %2d sig: %3d/255 (CRC: %-3s, Miss: %7d)" % (upper_layer.__class__.__name__, bts_ch, bts_sig, "OK" if crc_ok else "NOK", counter), end="") if upper_layer.__class__ == btle.AdvInd: vendor = get_vendor_for_mac(upper_layer.adv_addr_s) print(" AdvAddr: %12s %s" % (upper_layer.adv_addr_s, vendor), end="") elif upper_layer.__class__ == btle.ScanRequest: vendor1 = get_vendor_for_mac(upper_layer.scan_addr_s) vendor2 = get_vendor_for_mac(upper_layer.adv_addr_s) print(" ScanAddr: %12s %s AdvAddr: %12s %s" % (upper_layer.scan_addr_s, vendor1, upper_layer.adv_addr_s, vendor2), end="") elif upper_layer.__class__ == btle.ScanResponse: vendor1 = get_vendor_for_mac(upper_layer.adv_addr_s) print(" AdvAddr: %12s %s" % (upper_layer.adv_addr_s, vendor1), end="") elif upper_layer.__class__ == btle.ConnRequest: print(" InitAddr: %12s AdvAddr: %12s AA: %4s CRCinit: %3s" % (upper_layer.init_addr_s, upper_layer.adv_addr_s, upper_layer.access_addr_s, upper_layer.crcinit), end="") print() # TODO: check if AdvAddr is given and compare if upper_layer.__class__ == btle.ConnRequest and args.btle_mode != BTLE_MODE_FIXEDCHANNEL: logger.debug("setting new CRC init") args.crc_init = crc_btle_init_reorder(upper_layer.crcinit_rev_int) print("channel map:") print(upper_layer.get_active_channels()) except Exception as ex: logger.warning("could not parse: %r (corrupted packet)", bts) #print(ex) return crc_ok
def do_aps(self, _): """Show all APs.""" aps = self._logic.aps logger.info("got %d aps: " % len(aps)) for ap in aps: logger.info("%17s %s" % (ap, utils.get_vendor_for_mac(ap[0:8])))
def strategy(radiotap_pkt, channel): try: ieee = radiotap_pkt.body_handler ieee_handler = ieee.body_handler if ieee.subtype == 8 and ieee.type == 0: # add APs if not seen so far mac_ap = ieee_handler.bssid_s if mac_ap not in self._aps_known: logger.debug("adding unknown AP: %s" % mac_ap) aps_new.add(mac_ap) self._aps_known.add(mac_ap) return False except Exception as ex: logger.debug(ex) return False addresses = [] try: addresses.append(ieee_handler.src_s) except: pass try: addresses.append(ieee_handler.dst_s) except: pass #logger.debug("src=%s, dst=%s" % (addresses[0], addresses[1])) found_client = False try: for addr in addresses: # TODO: signal strength? #print("======>") if addr not in clients_identified \ and addr not in self._aps_known\ and not is_special_mac(addr): try: tags = "%r" % self._db_handler.get_client_tags( addr) logger.info( "%s (%s) -> (%r), Sig: %d" % (addr, utils.get_vendor_for_mac(addr[0:8]), tags, unpack_B(radiotap_pkt.flags[3][1])[0])) except KeyError: pass clients_identified.add(addr) found_client = True #print("<======") except AttributeError as ex1: # no src_s present, ignore logger.exception(ex1) pass except Exception as ex2: logger.exception(ex2) return found_client
def is_special_mac(mac_str): """ Check if this is a special MAC adress (not a client address). Every MAC not found in the official OUI database is assumed to be non-client. mac_str -- Uppercase mac string like "AA:BB:CC[:DD:EE:FF]", first 3 MAC-bytes are enough """ return len(utils.get_vendor_for_mac(mac_str[0:8])) == 0
def do_aps(self, arg): """Show all APs.""" print("got %d aps: " % len(FinderShell.aps)) for ap in FinderShell.aps: # print(ap) print("%17s %s" % (ap, utils.get_vendor_for_mac(ap[0:8])))
def harvest(psock, mode, aps=None, known_clients=None, harvest_time_ch=5): """ harvest_time_ch -- time to harvest per channel in seconds return -- set(ap_mac | client_macs) """ found = set() for channel in channels: utils.switch_wlan_channel(psock.iface_name, channel) print("setting channel: %d" % channel) time_start = time.time() clients_seen = {} cnt = 0 # TODO: to be tuned while (time.time() - time_start) < harvest_time_ch: try: try: raw_bytes = psock.recv() except: # assume timeout: switch channel break cnt += 1 drvinfo = radiotap.Radiotap(raw_bytes) if cnt % 1000 == 0: print("packets/s: %d" % (cnt / (time.time() - time_start))) if mode == HARVEST_MODE_AP: beacon = drvinfo[ieee80211.IEEE80211.Beacon] if beacon is None: continue if beacon.bssid_s not in found: logger.info("found AP: %18s %-40s %-10s" % (beacon.bssid_s, utils.get_vendor_for_mac(beacon.bssid_s[0:8]), beacon.params[0].data)) found.add(beacon.bssid_s) elif mode == HARVEST_MODE_CLIENT: dataframe = drvinfo[ieee80211.IEEE80211.Dataframe] if dataframe is None: continue src = dataframe.src_s if src in aps: # not interested in aps continue if src not in found: logger.info("found new client: %s" % src) found.add(src) elif mode == HARVEST_MODE_CLIENT_LIST: try: src = drvinfo[ieee80211.IEEE80211]._body_handler.src_s if src in known_clients: # TODO: signal strength # print(src) found.add(src) except AttributeError as e: pass # print(e) except Exception as e: print(e) for k in found: # os.system("clear") print("%s -> (%r)" % (k, str(known_clients[k]))) else: print("wrong harvest mode") return None except Exception as e: print(e) return found
def strategy(radiotap_pkt, channel): try: # radiotap -> ieee -> [Beacon, data, ACK, ...] ieee80211_pkt = radiotap_pkt.body_handler #logger.debug("checking...") if ieee80211_pkt.subtype == 8 and ieee80211_pkt.type == 0: if ieee80211_pkt.body_handler.bssid_s not in self._aps_known: beacon = ieee80211_pkt.body_handler #logger.debug("skipping beacon") logger.info( "found new AP: %18s %-40s %-10s" % (beacon.bssid_s, utils.get_vendor_for_mac( beacon.bssid_s[0:8]), beacon.params[0].data)) aps_found_new.add(beacon.bssid_s) self._aps_known.add(beacon.bssid_s) self._ap_channels.add(channel) # remain on channel return True return False except Exception as ex: logger.warning("error while harvesting: %r" % ex) return False ieee_handler = ieee80211_pkt.body_handler client_macs = [] # management if ieee80211_pkt.type == 0: # both src/dst could be client client_macs = [ieee_handler.src_s, ieee_handler.dst_s] # control elif ieee80211_pkt.type == 1: try: client_macs.append(ieee_handler.dst_s) except: # TODO: exceptions possible? pass try: client_macs.append(ieee_handler.src_s) except: # dst not always present pass # data elif ieee80211_pkt.type == 2: if ieee80211_pkt.from_ds == 1 and ieee80211_pkt.to_ds == 0: client_macs.append(ieee_handler.dst_s) elif ieee80211_pkt.to_ds == 1 and ieee80211_pkt.from_ds == 0: client_macs.append(ieee_handler.src_s) else: logger.warning( "unknown ieee80211 type: %r (0/1/2 = mgmt/ctrl/data)" % ieee80211_pkt.type) return False found_client = False for addr in client_macs: # not an AP and not yet stored if addr not in self._aps_known and addr not in clients_found: if is_special_mac(addr): logger.debug("special MAC: %s" % addr) continue logger.info("found possible client: %s\t%s" % (addr, utils.get_vendor_for_mac(addr[0:8]))) logger.debug("ieee type was: %d" % ieee80211_pkt.type) clients_found.add(addr) # remain on channel, we found something found_client = True return found_client
def harvest(psock, mode, aps=None, known_clients=None, harvest_time_ch=5): """ harvest_time_ch -- time to harvest per channel in seconds return -- set(ap_mac | client_macs) """ found = set() for channel in channels: utils.switch_wlan_channel(psock.iface_name, channel) print("setting channel: %d" % channel) time_start = time.time() clients_seen = {} cnt = 0 # TODO: to be tuned while (time.time() - time_start) < harvest_time_ch: try: try: raw_bytes = psock.recv() except: # assume timeout: switch channel break cnt += 1 drvinfo = radiotap.Radiotap(raw_bytes) if cnt % 1000 == 0: print("packets/s: %d" % (cnt / (time.time() - time_start))) if mode == HARVEST_MODE_AP: beacon = drvinfo[ieee80211.IEEE80211.Beacon] if beacon is None: continue if beacon.bssid_s not in found: logger.info( "found AP: %18s %-40s %-10s" % (beacon.bssid_s, utils.get_vendor_for_mac( beacon.bssid_s[0:8]), beacon.params[0].data)) found.add(beacon.bssid_s) elif mode == HARVEST_MODE_CLIENT: dataframe = drvinfo[ieee80211.IEEE80211.Dataframe] if dataframe is None: continue src = dataframe.src_s if src in aps: # not interested in aps continue if src not in found: logger.info("found new client: %s" % src) found.add(src) elif mode == HARVEST_MODE_CLIENT_LIST: try: src = drvinfo[ieee80211.IEEE80211]._body_handler.src_s if src in known_clients: # TODO: signal strength # print(src) found.add(src) except AttributeError as e: pass # print(e) except Exception as e: print(e) for k in found: # os.system("clear") print("%s -> (%r)" % (k, str(known_clients[k]))) else: print("wrong harvest mode") return None except Exception as e: print(e) return found