103 lines
5.0 KiB
Markdown
103 lines
5.0 KiB
Markdown
# Mark VIII Night Sprint — Attacks, Sync, Harness
|
|
|
|
Date: 2026-08-18
|
|
Status: Approved (user: "Approved, go build")
|
|
|
|
## Problem
|
|
|
|
The Mark VIII web UI (Pager firmware `Pineapple Pager 24.10.1`) is rough and
|
|
desyncs from the device. Interrogation (2026-08-18, live device `172.16.52.1`)
|
|
found:
|
|
|
|
1. **pineapd crash-loop**: 34+ `SIGSEGV`s in logread; stock daemon restarts
|
|
pineapd every ~30s. Root cause: SSID-pool broadcast (68 SSIDs, `disable='0'`)
|
|
segfaults pineapd; `wlan1mon` repeatedly fails to come up
|
|
("That device is not up" / "interface sysfs directory does not exist" every 5s).
|
|
2. **State desync**: `GET /api/pineap/mode` returns `mode: "unknown"` while the
|
|
device is effectively Active; mode is a UI-stored preference, never derived
|
|
from live state.
|
|
3. **Wrong-band AP cards**: `get_ap` reads radio1 (`wlan1wpa`/`wlan1open`)
|
|
whenever those UCI sections exist (even disabled leftovers), so the 2.4GHz
|
|
Evil WPA card silently shows 5GHz state.
|
|
4. **Evil Enterprise is dead code**: `views.pineap_enterprise` exists but has no
|
|
route in `app.js` routes map and no tab.
|
|
5. **Fire-and-forget writes**: UI toasts success without verifying device state.
|
|
6. **Hop hygiene**: radio1-AP feature pauses `wlan1mon` hop and leaves it paused
|
|
with leftover AP sections.
|
|
|
|
## Research findings (verified on device)
|
|
|
|
- Enterprise AP recipe: create `wireless.wlan0ent` (device `radio0`, mode `ap`,
|
|
encryption `wpa2`, key = passphrase), then
|
|
`PUT /api/settings/wifi/set_ap` over unix socket `/tmp/api.sock` with
|
|
`{"configs":[{"interface":"wlan0ent","ssid":...,"enctype":"wpa2",
|
|
"enabled":true,"key":...,"channel":1}]}`. Result: `wlan0ent` AP live with
|
|
`ieee8021x=1`, `wpa=2`, `wpa_key_mgmt=WPA-EAP` (PineAPE internal EAP server).
|
|
Daemon-side hostapd reload is async (poll for iface in `iw dev`).
|
|
- `hcxpcapngtool`, `tcpdump`, `sqlite3`, `aircrack-ng` present on device.
|
|
- MCP Streamable HTTP transport (2025-06-18): single endpoint, POST JSON-RPC,
|
|
respond `application/json` or SSE; Origin validation + auth required.
|
|
- Daemon unix-socket API (`/tmp/api.sock`) carries `/api/pineap/*`; TCP :1471
|
|
carries `/api/settings/*` and `/api/login`.
|
|
|
|
## Design
|
|
|
|
### Phase 1 — Attacks (top-level menu item)
|
|
|
|
New side-menu section **Attacks** with three launchers:
|
|
|
|
- **Evil WPA (PSK)**: SSID, passphrase, enctype (psk2/sae/owe), band+channel
|
|
(2.4 → `wlan0wpa`, 5/6 → `wlan1wpa` via radio1 feature), hidden. Deploy =
|
|
UCI write + hop pause + `wifi reload` + PineAP response engine + karma on +
|
|
handshake logging on. Stop = disable AP + hop resume. Live AP status from
|
|
`iw dev`/UCI (never UI cache), live handshake table (`hostap_handshake`),
|
|
**Export .hc22000** (on-device `hcxpcapngtool`) + hashcat command, per-client
|
|
deauth with band-aware inject interface.
|
|
- **Evil Open**: same shape for `wlan0open` / radio1 open AP.
|
|
- **Evil Enterprise**: SSID, encryption (wpa2/wpa3 enterprise), passphrase.
|
|
Deploy = verified recipe above + PineAPE on + auth-pass capture on. Live cred
|
|
tables (`hostap_basic`, `hostap_chalresp`) with Clear.
|
|
|
|
All three: verification banner ("applied & verified" vs "device state differs"),
|
|
Stop button, and a post-write poll (UCI + `iw dev`) before success toast.
|
|
|
|
### Phase 2 — Stabilize + sync
|
|
|
|
- SSID pool broadcast disabled on deploy of this build; server-side health
|
|
monitor: `_pineap PING` every 15s; two failures → check SIGSEGV growth in
|
|
logread → disable pool, restart pineapd, `ip link set wlan1mon up`.
|
|
- Mode derived from live `enabled` + `collect` + `advertise`; never "unknown"
|
|
when state is readable.
|
|
- `get_ap` returns `radio0` + `radio1` + `enterprise` APs as separate objects.
|
|
- All writes verified by re-read; success only on match.
|
|
- Hop resumed when no radio1 AP active; leftover radio1 sections reported.
|
|
|
|
### Phase 3 — Local Harness (MCP)
|
|
|
|
- `POST /mcp` on server.py: Streamable HTTP MCP server (JSON-RPC 2.0, pure
|
|
socket, no deps), auth via session cookie/Bearer + Origin validation.
|
|
- Tools: `recon.query`, `attack.deploy_evil_wpa` / `deploy_evil_open` /
|
|
`deploy_evil_enterprise` / `stop_attack`, `attack.deauth`,
|
|
`attack.capture`, `loot.handshakes`, `loot.export_hc22000`,
|
|
`loot.enterprise_creds`, `device.state`, `pineap.set_filter`,
|
|
`pineap.kick_client`.
|
|
- Resources: recon DB tables (ssid, wifi_device, handshake, hostap_handshake,
|
|
hostap_basic, hostap_chalresp), handshake files, loot listing, and the
|
|
opencode skills (pineapple-control, wifi-deauth, aircrack-suite) as
|
|
markdown resources.
|
|
- Prompts: attack playbooks (evil-wpa, evil-enterprise, recon).
|
|
- **Harness UI page**: endpoint + client config snippets (opencode/Claude/
|
|
Cursor), capability explorer, "prompt for pi.dev" generator, live state
|
|
snapshot.
|
|
- Optional stdio wrapper `scripts/harness_stdio.py` for stdio-only agents.
|
|
|
|
## Constraints
|
|
|
|
- Authorized target: `<authorized-test-ssid>` only (intermittent). Non-client
|
|
environment; no deauth blasts; verify on-wire via monitor capture when needed.
|
|
- SSID pool stays disabled (stock bug; re-enabling re-crashes pineapd).
|
|
|
|
## Out of scope
|
|
|
|
`1471` takeover, Cloud C2, campaigns, physical display mirroring.
|