Preview file contents inline — text, CSV, images
()
| 16066 | subprocess.run(['sudo', 'ip', 'link', 'set', restore_secondary, 'up'], |
| 16067 | capture_output=True, timeout=3) |
| 16068 | except Exception: |
| 16069 | pass |
| 16070 | |
| 16071 | ev_thread = _threading.Thread(target=_capture_deauth_frames, daemon=True) |
| 16072 | ev_thread.start() |
| 16073 | |
| 16074 | _time.sleep(4) |
| 16075 | |
| 16076 | # Get results WITH BSSID, SSID, signal, security, frequency, channel |
| 16077 | result = subprocess.run( |
| 16078 | ['nmcli', '-t', '-f', 'BSSID,SSID,SIGNAL,SECURITY,FREQ,CHAN', |
| 16079 | 'dev', 'wifi', 'list', '--rescan', 'no', 'ifname', iface], |
| 16080 | capture_output=True, text=True, timeout=15 |
| 16081 | ) |
| 16082 | |
| 16083 | if result.returncode != 0: |
| 16084 | return jsonify({'success': False, 'error': 'WiFi scan failed', 'findings': []}), 500 |
| 16085 | |
| 16086 | # Get our own connected network for evil twin detection |
| 16087 | link_result = subprocess.run( |
| 16088 | ['iw', 'dev', iface, 'link'], |
| 16089 | capture_output=True, text=True, timeout=5 |
| 16090 | ) |
| 16091 | own_ssid = '' |
| 16092 | own_bssid = '' |
| 16093 | for ln in link_result.stdout.splitlines(): |
| 16094 | ln = ln.strip() |
| 16095 | if ln.startswith('SSID:'): |
| 16096 | own_ssid = ln.split(':', 1)[1].strip() |
| 16097 | elif ln.startswith('Connected to'): |
| 16098 | own_bssid = ln.split(' ')[2].strip().upper() |
| 16099 | |
| 16100 | # Rogue SSID patterns |
| 16101 | _ROGUE_SSID_PATTERNS = [ |
| 16102 | (_re.compile(r'piglet', _re.I), 'Piglet Wardriver', 'high', |
| 16103 | 'Piglet wardriving device AP detected nearby'), |
| 16104 | (_re.compile(r'pineapple|hak5|^pager$|pagerap', _re.I), 'WiFi Pineapple', 'critical', |
| 16105 | 'Hak5 WiFi Pineapple rogue AP detected'), |
| 16106 | (_re.compile(r'pwned|pwnagotchi', _re.I), 'Pwnagotchi', 'high', |
| 16107 | 'Pwnagotchi handshake capture device detected'), |
| 16108 | (_re.compile(r'deauth|dstike|spacehuhn', _re.I), 'Deauther', 'high', |
| 16109 | 'WiFi deauthentication attack device AP detected'), |
| 16110 | (_re.compile(r'marauder', _re.I), 'ESP32 Marauder', 'high', |
| 16111 | 'ESP32 Marauder attack platform AP detected'), |
| 16112 | (_re.compile(r'flipper', _re.I), 'Flipper Zero', 'high', |
| 16113 | 'Flipper Zero WiFi dev board AP detected'), |
| 16114 | (_re.compile(r'^free[_\s-]?wifi$|^free[_\s-]?internet$|^open[_\s-]?guest$', _re.I), |
| 16115 | 'Honeypot AP', 'medium', 'Suspicious open network — possible evil twin honeypot'), |
| 16116 | ] |
| 16117 | |
| 16118 | # Suspicious OUI prefixes (Espressif, Raspberry Pi) acting as APs |
| 16119 | _SUSPICIOUS_AP_OUIS = { |
| 16120 | '24:0A:C4': 'Espressif', '24:6F:28': 'Espressif', '24:62:AB': 'Espressif', |
| 16121 | '30:AE:A4': 'Espressif', '3C:61:05': 'Espressif', '3C:71:BF': 'Espressif', |
| 16122 | '40:F5:20': 'Espressif', '4C:11:AE': 'Espressif', '54:43:B2': 'Espressif', |
| 16123 | '58:BF:25': 'Espressif', '68:67:25': 'Espressif', '7C:9E:BD': 'Espressif', |
| 16124 | '84:0D:8E': 'Espressif', '84:CC:A8': 'Espressif', '8C:AA:B5': 'Espressif', |
| 16125 | '94:3C:C6': 'Espressif', 'A0:20:A6': 'Espressif', 'A4:CF:12': 'Espressif', |
nothing calls this directly
no test coverage detected