Files
Mark-VIII/README.md
T

142 lines
5.6 KiB
Markdown

# 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 '<device-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-<b64>.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_<serverid>`; 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.