# Mark-VIII PineAP Attack Validation — Round 2 (post-fix), 2026-08-23 Full live re-validation of every PineAP attack type exposed by Mark VIII, executed after the fix round in commit `d23ea56`. All attacks were run against authorized, in-scope networks only. ## Environment | Role | Host | Identity | |---|---|---| | Attack platform | WiFi Pineapple Pager 24.10.1, `root@172.16.52.1`, Mark VIII `:8080` | radio0 MAC base `00:13:37:ae:e0:50`, radio1 `00:13:37:ae:8e:7c` | | Victim client | Kali Linux, `bzuccaro@192.168.1.103`, wlan0 `a0:a4:c5:93:f8:05` | NetworkManager + standalone wpa_supplicant | | In-scope targets | `Znet` (WPA2/WPA3-SAE-mixed, 5GHz ch36/44/48/…; PSK provided) and `Znet-Open` (open, 2.4GHz ch6 `B6:8B:A9:17:2A:6E`, ch11 `B6:8B:A9:17:47:33`) | recon.db fresh scans confirmed both | Pre-flight: `/api/health` env `pass` (pineapd alive, both monitors up, recon readable). ## Results summary | # | Attack / capability | Endpoint(s) | Result | Proof captured | |---|---|---|---|---| | 1 | Recon | recon.db / scan history | **PASS** | Both SSIDs present with fresh timestamps, correct BSSIDs/channels/crypto | | 2 | Evil Open twin + Evil Portal credential capture | `POST /api/attacks/deploy kind=open` + portals API | **PASS** | Victim associated to spoofed-BSSID twin (`172.16.52.123`); DNS hijack resolved arbitrary domain → `172.16.52.1`; portal served on :80; POSTed creds recorded with MAC/hostname/IP (`evidence/r2_t1_portal_captures.json`) | | 3 | Karma association | (implicit) | **PASS** | Real third-party client `48:e1:e9:4d:98:8a` associated to Znet-Open twin unprompted; later handshakes from `68:9e:19:d1:6e:e1` / `e6:75:7f:45:fd:57` on the WPA twin across multiple probed SSIDs | | 4 | Filters auto-config post-deploy | `GET /api/pineap/filters/{ssid,client}` | **PASS** (BUG 2 fix verified) | After deploy both filters read `deny` + empty with no manual help — twins accept clients unaided | | 5 | Single deauth via API | `POST /api/attacks/deauth` | **PASS** (BUG 1 fix verified) | `ok:true, inject:wlan0mon`; pcap holds **556 deauth frames** incl. directed SA=twin-BSSID → DA=victim (`evidence/r2_t2_deauth.cap`); victim dropped (NM re-associated sub-second) | | 6 | Client kick | `POST /api/pineap/clients/kick` | **PASS** | Deny filter added for victim MAC; victim flapped DISCONNECTED/CONNECTED and could not hold association until filter cleared | | 7 | Evil WPA twin 5GHz + handshake capture | `deploy kind=wpa` + `attacks/capture` | **PASS** | Twin live ch44 (`02:13:37:ae:8e:7c`); full EAPOL 4-way from victim captured on pinned `wlan1mon`; export produced 18-row `.hc22000` incl. victim AND real-client handshakes | | 8 | hc22000 export → crack | `GET /api/attacks/export/hc22000` + hashcat -m 22000 (Kali) | **PASS** | PSK recovered for victim (`021337ae8e7c:a0a4c593f805:Znet`) and real client (`…:e6757f45fd57:Znet`) = exact known PSK (`evidence/r2_t4_cracked.txt`) | | 9 | Bulk deauth | `POST /api/attacks/deauth/bulk` | **PASS** | 3-target batch: 2 valid sent (`sent:2`), malformed target rejected per-index without aborting batch; victim dropped on-air | | 10 | Evil Enterprise PEAP/MSCHAPv2 | `deploy kind=enterprise` | **PARTIAL** | AP verified + ctrl-linked + runtime-bridged; client associates; TLS tunnel up; server issues inner MSCHAPv2 success for `victim@znet.local`. BUT wpa_supplicant rejects the karma wpad's success request ("Invalid authenticator response") so no full CONNECTED; `hostap_basic`/`hostap_chalresp` remain empty (known firmware residual). See §T6 | | 11 | Post-suite hygiene | — | **PASS** | All attacks stopped, zero leftover APs/tcpdump/watchdog churn, health env `pass`, victim restored to real `Znet` (`18:e8:29:b5:a4:2c`) | ## New defects found this round ### D1 — MEDIUM: portal download endpoint crashes on device `h_portal_download` (`server.py:5395`) imports `zipfile`, which python3-light does not ship (the import endpoint was converted to struct+zlib in d23ea56 but download was missed): `GET /api/portals//download` → `{"error": "No module named 'urllib'"}`. Fix: reuse the minimal ZIP writer approach or stream raw files. ### D2 — MEDIUM: deploy-time auto-capture produces an empty pcap The 5GHz WPA deploy reported `"capture": true` but the auto-started `wlan1mon` capture died during AP bring-up (file stayed at the 24-byte header; no tcpdump process left). A capture started *after* the AP is up works fine (frames flow, monitor inherits phy channel context). Fix: arm the auto-capture after hostapd verify-loop completes, and/or have `_capture_state` detect-and-restart the dead pid (ISSUE 7 stale logic exists but did not fire here). Also: `h_attacks_capture` silently ignores a `channel` body param — either honor it or reject it. ### D3 — LOW/cosmetic: `GET /api/attacks/capture` with no active capture returns 404 `{"error":"not found"}` instead of `{running:false,...}` — UI-hostile shape. ## T6 detail (Enterprise PARTIAL) Repro: deploy `kind=enterprise ssid=Znet enctype=wpa2 channel=44 passphrase=VictimPass123!` → `verified:true, ctrl_linked:true`. Victim (standalone wpa_supplicant, MAC randomization off): - Association OK; outer PEAP TLS tunnel completes (`CTRL-EVENT-EAP-PROPOSED-METHOD method=25`) - Inner MSCHAPv2 exchange runs; client logs `EAP-MSCHAPV2: Received success` — i.e. the standalone hostapd accepted the inner credentials (BUG 3 eap_users grammar fix works) - But every attempt then logs `EAP-MSCHAPV2: Invalid authenticator response in success request` → supplicant refuses, disconnects, retries forever. Same result with matched and mismatched passwords (server auto-accepts but its AuthResp never verifies) — consistent with the karma- patched wpad issuing success without computing it from the stored secret. - TTLS/PAP could not be differentiated this round (client-side sed failure meant PEAP ran; association-level flapping prevented a clean second attempt). - `hostap_basic` / `hostap_chalresp`: still empty (documented firmware residual — pineapd does not forward from foreign hostapd instances). Enterprise client list DOES record associations. Net: enterprise twin captures inner-auth material server-side only as far as hostapd's own logs; portable credential loot remains impossible on 24.10.1 without a Hak5 pineapd change. ## Evidence index (`evidence/r2_*`) | File | Content | |---|---| | `r2_t1_portal_captures.json` | Captured portal credentials (user/pass, victim MAC/hostname/IP) | | `r2_t2_deauth.cap` | wlan0mon pcap, 556 deauth frames (directed at victim) | | `r2_t2_deauth.json`, `r2_t2_kick.json` | API responses proving deauth/kick ok:true | | `r2_t3_deploy_wpa.json` | WPA twin deploy response (`capture:true`, `verified:true`) | | `r2_t3_hc_export.json`, `r2_handshakes.hc22000` | Exported 18 handshake hashes | | `r2_t4_cracked.txt` | hashcat --show output recovering the true PSK (victim + real client) | | `r2_t5_bulk.json` | Bulk deauth batch results (2 sent / 1 rejected) | | `r2_t6_deploy_ent.json` | Enterprise deploy response | Copies of key artifacts also live on-device (`/root/loot/**`) and on Kali (`/tmp/r2.hc22000`, removed wordlist).