# Mark VIII A Mark VII-style web management UI that runs **on the WiFi Pineapple Pager** at `http://172.16.52.1:8080/`. Packaged as a native Pager payload. Features: Dashboard (live), PineAP (settings, SSID pool, filters, clients/kick), Recon (scans from `recon.db`), Handshakes/Loot, Payloads (embedded stock Pager Portal), Logs, Settings (hostname/NTP/password/prefs), and a bottom-docked xterm terminal. - Rogue AP on the second radio (5GHz / 6GHz Wi-Fi 6E): Open AP and Evil WPA (WPA2-PSK/WPA3-SAE/WPA3-OWE) on `radio1`, band-aware channel pickers, 6GHz requires WPA3. While a radio1 AP is enabled the stock monitor-hopping (`wlan1mon`) is paused and resumed on disable; 2.4GHz PineAP is untouched. ## Requirements - WiFi Pineapple Pager, firmware `Pineapple Pager 24.10.1` - `python3` on the device (present on current firmware) - Python 3.11 on the development machine ## Install (sideload) macOS/Linux: ```bash # Recommended: key authentication ./scripts/deploy.sh --ssh-key "$HOME/.ssh/pager_key" # Password authentication requires sshpass brew install hudochenkov/sshpass/sshpass ./scripts/deploy.sh --password '' ``` Windows: ```powershell # deploy.ps1 needs either an SSH key or sshpass for password auth: & .\scripts\deploy.ps1 -SshKey "$HOME\.ssh\pager_key" # or set up a key and add it: ssh-copy-id root@172.16.52.1 ``` The deployment scripts build `build/pager-webui/payload-.zip`, upload it, extract it to `/root/payloads/user/remote_access/pager-webui/`, and refresh the portal index. Then on the Pager menu, run **Mark VIII**: - **Yes** to "Run as background service?" -> procd service (respawns on crash, boot-persistent via rc.d symlinks). - **No** -> foreground mode; press **B** to stop. - Re-run the payload while running to **Stop** the service. - `PAYLOAD_GET_CONFIG pager_webui auto_mode/run_mode` skip the prompt. Browse `http://172.16.52.1:8080/` and log in with the device password. ## Uninstall / recovery Re-run the payload and confirm "Stop service?" (stops, disables, removes the init script), then delete the payload directory via the portal or: `rm -rf /root/payloads/user/remote_access/pager-webui`. No stock files are modified. After a **firmware upgrade** (which wipes the overlay), reinstall and run the payload to re-enable it—the same caveat as Nautilus. ## Local dev loop ```powershell .\scripts\deploy.ps1 -SshKey "$HOME\.ssh\pager_key" # deploy backend once .\scripts\dev.ps1 -Tunnel # local SPA + API proxy # open http://127.0.0.1:8000 ``` `dev.ps1` serves `www/` locally, proxies `/api/*` to the Pager, and points the terminal at the Pager's daemon WS (`-Tunnel` opens the `:1471` SSH tunnel). The live WebSocket falls back to 5s polling through the dev proxy. ## API tests Python unit tests (stdlib `unittest`, runnable on Windows with mocks). Run each module in its own process—the tests monkeypatch module-level helpers and do not restore them, so a single `discover` process leaks state between files: ```powershell $py = "$env:LOCALAPPDATA\Programs\Python\Python311\python.exe" Get-ChildItem tests\test_*.py | ForEach-Object { $mod = "tests." + [IO.Path]::GetFileNameWithoutExtension($_.Name) & $py -m unittest $mod -v } ``` On-device smoke tests cover every page, background vs foreground, terminal I/O, and reboot persistence. ## Architecture - `server.py` — Mark VIII's pure-socket HTTP + JSON API + minimal RFC6455 WS on `0.0.0.0:8080`, written to run on the device's `python3-light` (no `urllib`/`http.server`/`sqlite3` stdlib modules there); talks to the Hak5 daemon (`127.0.0.1:1471`) over a raw-socket HTTP client, `hak5cmd`, `uci`, `iwinfo`, and `recon.db` read-only (via the `sqlite3` CLI). - `www/` — vanilla JS SPA (no build step) + bundled xterm.js. - `payload.sh` + `pagerwebui.init` — Nautilus-style installer / procd service. ## Stability notes (Pager 24.10.1) pineapd crash sources found and fixed on this firmware (verified on-device, zero crashes over sustained watches): 1. **SSID-pool broadcast** — segfaults pineapd (~15s cadence). Kept disabled. 2. **wlan2mon** — a 6GHz monitor this hardware never creates; hopping the missing iface segfaults pineapd. Disabled. 3. **Large refilled pool** — the pool list itself crashes pineapd even with broadcast disabled. The health monitor clears it (collect refills). 4. **wlan1mon fast-hopping 6GHz** — stalls pineapd's command socket; the stock daemon's watchdog then SIGTERMs pineapd every ~30s. Bands pinned to 5GHz (2.4GHz only on wlan0mon). 5. **Socket collisions** — actively pinging pineapd from a health monitor collides with the stock daemon's own socket writes. The monitor now checks `pidof` only. `GET /api/health` reports pineapd/monitor state; the top bar shows a PINEAP OK / POOL OFF / PINEAPD DOWN chip. ## Security notes - Auth via device password validated against the daemon; HttpOnly session cookie `AUTH_`; all state-changing endpoints gated. - Commands run with argument lists (no shell interpolation). - Binds `0.0.0.0:8080` — same exposure class as the stock `:1471`/`:7681`. - Same-origin validation protects browser writes and WebSocket upgrades; the daemon token is stored in a root-only temporary session file. ## Out of scope (v1) `:1471` takeover, Mark VII-only features (Campaigns/Modules/Cloud C2/EAP), physical-display mirroring, and a PR to `hak5/wifipineapplepager-payloads` (packaging is drop-in ready for that PR). ## License Mark VIII source code is available under the MIT License. See `LICENSE` and `THIRD_PARTY_NOTICES.md` for bundled-component and trademark notices.