pfSense Plus MIM API toolkit b4acd7ca - Alta - Remoto - IDOR - URL di capacità userkey ACB
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · pfsense-api-acb-userkey
Classe: IDOR Portata: Remota
pfSense Plus MIM API (Netgate/pfsense-api b4acd7ca) - Netgate
GET /services/acb e GET /services/acb/bkp accettano userkey come parametro di query non vincolato. Il client Python generato inserisce quella chiave nella query string. Lo YAML non ha securitySchemes. Il possesso della chiave del dispositivo Auto Config Backup è il controllo. Si tratta di una capability URL.
Una userkey ACB rubata o trapelata elenca i backup ospitati di quel dispositivo e recupera il corpo di una revisione. La configurazione completa risiede in quei blob. Stessa classe della chiave ACB CE CVE-2024-57273 / SA-25_03 se la chiave trapela. Quel CVE riguardava la derivazione dal banner SSH. Questo residuo è il fratello query-param della Plus MIM API. Non sto ri-segnalando la derivazione dal banner.
Questo è l'OpenAPI pubblico + client generato per pfSense Plus Nexus Multi-instance Management (controller su :8443). Non è il pacchetto REST CE (jaredhendrickson/pfsense-api / pfrest.org). Il server è solo Plus (a pagamento). Non ho eseguito pfSense Plus.
| ID | nessun CVE al momento |
| Classe | IDOR (capability URL) |
| Portata | Remota |
| CWE | CWE-639 |
| CVSS | Alto: 7.5 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N se quelle GET onorano userkey senza vincolare un JWT al dispositivo |
| Prodotto | Netgate/pfsense-api (pfSense Plus MIM OpenAPI + client generato) |
| Affetto | pin b4acd7ca21dbca739a530403a1f62a7440f7726f (2026-05-25). Nessun tag. |
| Auth | Spec: nessuna (securitySchemes assente). userkey è il segreto di query. Plus JWT/RBAC non è stato eseguito. |
| Licenza | GNU Affero GPL v3.0 |
| Lab | solo 127.0.0.1:19171. Nessuna immagine Plus. |
Hub della serie: pfsense-api-nexus-mim (questa è la parte 7).
Richiede una userkey ACB rubata o trapelata (spec: "hexidecimal encoded 32-byte random bytes", 64 hex). La spec non vincola quella chiave a un JWT o al dispositivo del chiamante. GET /services/acb/config di classe G11 restituisce la userkey attiva. I campioni G9 impostano verify_ssl=False, quindi un MITM di :8443 può vedere la chiave sul filo. Questi sono percorsi di fuga. Questo residuo è ciò che la chiave permette di ottenere una volta che è fuori.
| Metodo | Sink | Privilegio |
|---|---|---|
GET /services/acb?userkey=<stolen> | GetACBList (pfapi_openapi.yml). Generato get_acb_list.py params["userkey"]. | Dimostrato in laboratorio (mock): elenca i backup ospitati di quel dispositivo. Witness in backups[].reason. |
GET /services/acb/bkp?userkey=<stolen>&revision= | GetACB -> RetrievedBackup.backup. Generato get_acb.py params["userkey"] + params["revision"]. | Dimostrato in laboratorio (mock): recupera il corpo della revisione. Witness in backup. |
| Stessa stringa di backup su un controller live | blob ACB ospitato | Inferito: config.xml completo (utenti, chiavi, pacchetti) una volta leggibile. Il mock ha restituito un witness XML in chiaro. Non ho contattato acb.netgate.com né decifrato un blob live. |
GET /services/acb/config | ACBConfigInfo.userkey, ACBConfig.encryption_password | Spec, non questo laboratorio: segreto di capability live e password di decifratura. Classe G11 secrets-on-GET. Non esercitato. |
| Metodo | Sink | Privilegio |
|---|---|---|
POST /services/acb/restore | RestoreACB body { timestamp } | Adiacente chiuso: i campioni inviano ancora un JWT. Non questo residuo. Non eseguito. |
POST /services/acb/config sostituisce userkey | SaveACBConfig | Adiacente chiuso: non è un URL di capability GET. Non eseguito. |
GET list / GET bkp non eliminano. DELETE /services/acb/bkp/{timestamp} è un'operazione diversa. Non esercitata.
userkey errata e userkey mancante non hanno restituito witness (dimostrato in laboratorio).
Dimostrato in laboratorio vs inferito: list e bkp con chiave rubata hanno restituito il witness. Chiave errata e chiave mancante no. Plus non è stato eseguito. I contenuti di config.xml live e la decifratura sono inferiti dallo schema pubblico (RetrievedBackup.backup è una stringa; encryption_password risiede su ACBConfig).
Richiede: percorso di rete verso le GET ACB del controller MIM, più una userkey rubata/trapelata. CVSS 7.5 se quelle GET onorano la chiave di query senza vincolare un JWT al dispositivo. Onestamente: questo pack dimostra che la spec pubblica modella quel contratto, su loopback.
| Superficie | Perché |
|---|---|
| Controller pfSense Plus | non eseguito. Nessuna immagine Plus in questo pack. |
| Pacchetto CE REST | server diverso (jaredhendrickson/pfsense-api / pfrest.org). |
| Derivazione della chiave ACB dal banner SSH | CVE-2024-57273 / SA-25_03. Non ri-segnalare. |
POST /services/acb/restore come questa scoperta | i campioni inviano ancora un JWT. |
php/shell non autenticato da security OAS omesso | residuo della documentazione. Il mock non è una prova di server 200-senza-JWT. |
userkey mancante | laboratorio 403, nessun witness. |
userkey errata | laboratorio list vuota / bkp 403, nessun witness. |
verify_ssl della libreria generata | default True. G9 sono i campioni che lo disattivano, non il default del pacchetto. |
Ho fissato Netgate/pfsense-api main b4acd7ca (2026-05-25, "Add Snort-3 API definitions"). Dodici ricerche su login/JWT, diagnostica, enrollment MIM, TLS client, utenti/certificati, pacchetti, VPN/firewall, sicurezza OpenAPI, IDOR dispositivo, git/firmware/feeds, più un mock loopback di ogni operazione generata.
Prima la skip list: residui CE WebGUI già segnalati (QinQ parent if, OpenVPN wizard CRLF, CARP VHID, limiter number, IPsec login banner). Diagnostica PHP/shell come potere admin previsto. Il pacchetto CE REST di terze parti. Derivazione dal banner CVE-2024-57273.