feat: merge attacks into PineAP menu; auto channel; recon fixes; richer reports
- Rail: Attacks tab removed; PineAP becomes a grouped menu (Evil WPA / Evil Open / Evil Enterprise / Impersonation / Clients / Filtering); old #/attacks* hashes redirect to their PineAP equivalents. - PineAP tabs gain Evil Enterprise; stock Open AP / Evil WPA / Enterprise pages replaced by the verified one-click launchers (status, capture, export, deauth, playbooks). - Channel selects gain an Auto option: deploy resolves the target SSID's last-seen channel from recon.db (verified unit-tested end to end). - Harness: pi.dev prompt section removed; Copy Token inline; robot icon. - Recon: compare checkboxes no longer hide the AP list (multi-select stays visible, rows highlighted, clients table no longer suppressed); Previous Scans buttons moved above the dropdown with a Delete All; encryption chips + buckets now distinguish WPA2/WPA3 PSK vs Enterprise (AKM suites decoded from recon bitfield bits 32-47); scan JSON carries GPS when a fix exists; Reports tab shows a GPS column. - fix: restore top-level EVIL_ENC definition lost in the repo (deployed build had it; repo would have thrown at init).
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import os
|
||||
import shutil
|
||||
import sqlite3
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
@@ -133,6 +134,54 @@ class AttacksDeployTest(unittest.TestCase):
|
||||
self.assertEqual(payload['iface'], 'wlan1wpa')
|
||||
self.assertEqual(payload['band'], server.BAND_5G)
|
||||
|
||||
def test_deploy_wpa_auto_channel_defaults_to_1_without_recon(self):
|
||||
status, payload = server.h_attacks_deploy(ctx({
|
||||
'kind': 'wpa', 'ssid': 'UnknownNet', 'passphrase': 'secretpass1',
|
||||
'enctype': 'psk2', 'hidden': False}))
|
||||
self.assertEqual(status, 200)
|
||||
self.assertTrue(payload['auto'])
|
||||
self.assertEqual(payload['channel'], 1)
|
||||
self.assertEqual(payload['band'], server.BAND_2G)
|
||||
cfg = [s for s in self.f.sock if s[0] == 'PUT' and s[1] == '/api/settings/wifi/set_ap'][0][2]
|
||||
self.assertEqual(cfg['configs'][0]['channel'], 1)
|
||||
|
||||
def test_deploy_wpa_auto_channel_uses_recon_target_channel(self):
|
||||
db = self._make_recon_db()
|
||||
old = server.RECON_DB
|
||||
server.RECON_DB = db
|
||||
try:
|
||||
status, payload = server.h_attacks_deploy(ctx({
|
||||
'kind': 'wpa', 'ssid': 'Anderson-5', 'passphrase': 'secretpass1',
|
||||
'enctype': 'psk2', 'hidden': False}))
|
||||
finally:
|
||||
server.RECON_DB = old
|
||||
os.unlink(db)
|
||||
self.assertEqual(status, 200)
|
||||
self.assertEqual(payload['channel'], 149)
|
||||
self.assertEqual(payload['band'], server.BAND_5G)
|
||||
self.assertEqual(self.f.state['wireless.radio1.channel'], '149')
|
||||
|
||||
def _make_recon_db(self):
|
||||
fd, db = tempfile.mkstemp(suffix='.db')
|
||||
os.close(fd)
|
||||
conn = sqlite3.connect(db)
|
||||
conn.executescript(
|
||||
'CREATE TABLE scan(id INTEGER PRIMARY KEY AUTOINCREMENT, uuid TEXT,'
|
||||
' time INT, name TEXT);'
|
||||
'CREATE TABLE wifi_device(hash INT PRIMARY KEY, scan INT, mac TEXT,'
|
||||
' time INT, signal INT, freq INT, packets INT);'
|
||||
'CREATE TABLE ssid(hash INT PRIMARY KEY, wifi_device INT, scan INT,'
|
||||
' type INT, bssid TEXT, ssid BLOB, hidden INT, time INT, signal INT,'
|
||||
' freq INT, channel INT, encryption INT);')
|
||||
conn.execute("INSERT INTO scan (uuid, time, name) VALUES ('u1', 1, 'pager')")
|
||||
conn.execute("INSERT INTO ssid (hash, wifi_device, scan, type, bssid, ssid, hidden,"
|
||||
" time, signal, freq, channel, encryption) VALUES"
|
||||
" (10, 1, 1, 8, 'C89E43648080', X'416E646572736F6E2D35', 0,"
|
||||
" 1786466532, -76, 5745, 149, 0x400400108)")
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return db
|
||||
|
||||
def test_deploy_open_2g4_includes_bssid_and_country(self):
|
||||
status, payload = server.h_attacks_deploy(ctx({
|
||||
'kind': 'open', 'ssid': 'Guest', 'hidden': False,
|
||||
|
||||
+8
-4
@@ -76,8 +76,13 @@ class DecodersTest(unittest.TestCase):
|
||||
self.assertEqual(server.decode_encryption(0x04), 'WPA')
|
||||
self.assertEqual(server.decode_encryption(0x08), 'WPA2')
|
||||
self.assertEqual(server.decode_encryption(0x04 | 0x08), 'WPA2 WPA')
|
||||
self.assertEqual(server.decode_encryption(0x400400108), 'WPA3 WPA2')
|
||||
self.assertEqual(server.decode_encryption(0x20050004C), 'WPA2 WPA')
|
||||
self.assertEqual(server.decode_encryption(0x400400108), 'WPA3 WPA2 PSK')
|
||||
self.assertEqual(server.decode_encryption(0x400400108 | (1 << 33)), 'WPA3 WPA2 Enterprise')
|
||||
self.assertEqual(server.decode_encryption(0x400400108 | (1 << 40)), 'WPA3 WPA2 SAE')
|
||||
self.assertEqual(server.decode_encryption(0x400400108 | (1 << 33) | (1 << 40)), 'WPA3 WPA2 Enterprise')
|
||||
self.assertEqual(server.decode_encryption(0x400400108 | (1 << 45)), 'WPA3 WPA2 OWE')
|
||||
self.assertEqual(server.decode_encryption(0x400400110), 'WPA3 PSK')
|
||||
self.assertEqual(server.decode_encryption(0x20050004C), 'WPA2 WPA Enterprise')
|
||||
|
||||
|
||||
class ReconDataTest(unittest.TestCase):
|
||||
@@ -111,7 +116,7 @@ class ReconDataTest(unittest.TestCase):
|
||||
self.assertEqual(a['ssid'], 'Anderson-5')
|
||||
self.assertEqual(a['channel'], 149)
|
||||
self.assertEqual(a['signal'], -76)
|
||||
self.assertEqual(a['encryption'], 'WPA3 WPA2')
|
||||
self.assertEqual(a['encryption'], 'WPA3 WPA2 PSK')
|
||||
self.assertFalse(a['hidden'])
|
||||
hidden = aps['50:6F:9A:01:00:00']
|
||||
self.assertTrue(hidden['hidden'])
|
||||
@@ -1193,4 +1198,3 @@ class ReconRoutesTest(unittest.TestCase):
|
||||
method = 'GET' if path.endswith(('status', 'scans', 'events')) else 'POST'
|
||||
h, args = server.ROUTER.dispatch(method, path)
|
||||
self.assertIsNotNone(h, path)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user