diff --git a/.gitignore b/.gitignore index e039ba9..5e22279 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ settings.env -__pycache__/ \ No newline at end of file +__pycache__/ +oui.txt \ No newline at end of file diff --git a/listener.py b/listener.py index 21f6bd3..7234c6e 100755 --- a/listener.py +++ b/listener.py @@ -29,6 +29,7 @@ include_probes = False # deadpoint_candidates = set() unlinked_candidates = set() bssid_channels = {} +vendor_cache = {} CHANNEL_LIST = [1, 6, 11, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165] # Channels to hop CHANNEL_HOP_INTERVAL = 5 # Seconds per channel @@ -128,13 +129,22 @@ def handle_packet(pkt): if mac not in aps: unlinked_candidates.add(mac) + if dot11.type == 0 and dot11.subtype in [0, 1]: + sa = dot11.addr2.lower() if dot11.addr2 else None + da = dot11.addr1.lower() if dot11.addr1 else None + for mac in (sa, da): + if is_unicast(mac) and mac != target_ap_bssid: + clients[mac] += 1 + if mac not in aps: + unlinked_candidates.add(mac) + if da in aps and is_unicast(sa): + ap_clients[da][sa] += 5 + # Track clients talking to any known AP - if a1 and a2: - for bssid in aps: - if bssid in (a1, a2): - peer = a2 if bssid == a1 else a1 - if is_unicast(peer): - ap_clients[bssid][peer] += 1 + if a1 in aps and is_unicast(a2): + ap_clients[a1][a2] += 1 + elif a2 in aps and is_unicast(a1): + ap_clients[a2][a1] += 1 # === Signal strength tracking === try: @@ -300,7 +310,33 @@ def main(): print(f"[+] Total APsOnChannel: {len(aps)}") print_suspect_aps() + print("\n[+] Vendor Summary (known APs):") + for bssid in sorted(aps): + vendor = get_mac_vendor(bssid) + print(f" {bssid} → {vendor}") + reset_interface(args.monitor_iface) +def get_mac_vendor(mac): + prefix = mac.upper()[0:8].replace(":", "-") + if prefix in vendor_cache: + return vendor_cache[prefix] + try: + if not os.path.exists("oui.txt"): + print("[~] Downloading IEEE OUI list...") + import urllib.request + url = "http://standards-oui.ieee.org/oui/oui.txt" + urllib.request.urlretrieve(url, "oui.txt") + with open("oui.txt", "r", encoding="utf-8", errors="ignore") as f: + for line in f: + if prefix in line: + vendor = line.strip().split("\t")[-1] + vendor_cache[prefix] = vendor + return vendor + except Exception as e: + pass + vendor_cache[prefix] = "Unknown" + return "Unknown" + if __name__ == "__main__": main()