hak5cmd on this firmware has no CLIENT_KICK command and PINEAPPLE_DEAUTH_CLIENT requires (bssid, target, channel) — the UI kick/deauth buttons and the MCP pineap.kick_client tool previously passed only the client MAC, which printed usage and silently did nothing. - _deauth_target/_deauth_client_via_iface resolve the client's association interface via iwinfo (Access Point + Channel), pick the band-aware inject interface, and issue DEAUTH_CLIENT <bssid> <mac> <channel> - h_client_kick: deny-filter (persistent) + immediate deauth with rc checks - h_deauth_client: deauth with the full form; 502 with detail when the client is not associated - MCP pineap.kick_client: resolves the client first (no side effects on failure), then deny-filter + deauth; verified on device (clean error for unassociated clients, filter list restored) - tests updated for the new command chain
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 python3on the device (present on current firmware)- Python 3.11 on the development machine
Install (sideload)
macOS/Linux:
# 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:
# 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_modeskip 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
.\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:
$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 on0.0.0.0:8080, written to run on the device'spython3-light(nourllib/http.server/sqlite3stdlib modules there); talks to the Hak5 daemon (127.0.0.1:1471) over a raw-socket HTTP client,hak5cmd,uci,iwinfo, andrecon.dbread-only (via thesqlite3CLI).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):
- SSID-pool broadcast — segfaults pineapd (~15s cadence). Kept disabled.
- wlan2mon — a 6GHz monitor this hardware never creates; hopping the missing iface segfaults pineapd. Disabled.
- Large refilled pool — the pool list itself crashes pineapd even with broadcast disabled. The health monitor clears it (collect refills).
- 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).
- Socket collisions — actively pinging pineapd from a health monitor
collides with the stock daemon's own socket writes. The monitor now
checks
pidofonly.
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.