pfSense Plus MIM API Toolkit b4acd7ca – Hoch – Remote – IDOR – ACB userkey Capability-URL
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · pfsense-api-acb-userkey
Klasse: IDOR Reichweite: Remote
pfSense Plus MIM API (Netgate/pfsense-api b4acd7ca) - Netgate
GET /services/acb und GET /services/acb/bkp nehmen userkey als uneingeschränkten Query-Parameter. Der generierte Python-Client setzt diesen Schlüssel in den Query-String. Die YAML hat keine securitySchemes. Der Besitz des Auto Config Backup-Geräteschlüssels ist die Prüfung. Das ist eine Capability-URL.
Ein gestohlener oder geleakter ACB-userkey listet die gehosteten Backups dieses Geräts auf und ruft einen Revisions-Body ab. Die vollständige Konfiguration steckt in diesen Blobs. Gleiche Klasse wie der CE-ACB-Schlüssel CVE-2024-57273 / SA-25_03, wenn der Schlüssel leakt. Diese CVE war SSH-Banner-Ableitung. Dieser Überrest ist das Query-Param-Geschwister der Plus MIM API. Ich reiche die Banner-Ableitung nicht erneut ein.
Dies ist die öffentliche OpenAPI + generierter Client für pfSense Plus Nexus Multi-instance Management (Controller auf :8443). Es ist nicht das CE REST-Paket (jaredhendrickson/pfsense-api / pfrest.org). Der Server ist Plus-only (kostenpflichtig). Ich habe pfSense Plus nicht ausgeführt.
| ID | noch keine CVE |
| Klasse | IDOR (Capability-URL) |
| Reichweite | Remote |
| CWE | CWE-639 |
| CVSS | Hoch: 7.5 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N, wenn diese GETs userkey ohne Bindung eines JWT an das Gerät honorieren |
| Produkt | Netgate/pfsense-api (pfSense Plus MIM OpenAPI + generierter Client) |
| Betroffen | Pin b4acd7ca21dbca739a530403a1f62a7440f7726f (2026-05-25). Keine Tags. |
| Auth | Spec: keine (securitySchemes fehlen). userkey ist das Query-Geheimnis. Plus JWT/RBAC wurde nicht ausgeführt. |
| Lizenz | GNU Affero GPL v3.0 |
| Lab | nur 127.0.0.1:19171. Kein Plus-Image. |
Serien-Hub: pfsense-api-nexus-mim (dies ist Teil 7).
Erfordert einen gestohlenen oder geleakten ACB-userkey (Spec: "hexidecimal encoded 32-byte random bytes", 64 Hex). Die Spec bindet diesen Schlüssel nicht an ein JWT oder an das Gerät des Aufrufers. GET /services/acb/config der G11-Klasse gibt den Live-userkey zurück. G9-Beispiele setzen verify_ssl=False, sodass ein MITM von :8443 den Schlüssel auf der Leitung sehen kann. Das sind Leak-Pfade. Dieser Überrest ist das, was der Schlüssel kauft, sobald er draußen ist.
| Methode | Sink | Berechtigung |
|---|---|---|
GET /services/acb?userkey=<stolen> | GetACBList (pfapi_openapi.yml). Generiertes get_acb_list.py params["userkey"]. | Lab-proven (mock): listet die gehosteten Backups dieses Geräts auf. Nachweis in backups[].reason. |
GET /services/acb/bkp?userkey=<stolen>&revision= | GetACB -> RetrievedBackup.backup. Generiertes get_acb.py params["userkey"] + params["revision"]. | Lab-proven (mock): ruft den Revisions-Body ab. Nachweis in backup. |
| Derselbe Backup-String auf einem Live-Controller | gehosteter ACB-Blob | Abgeleitet: vollständige config.xml (Benutzer, Schlüssel, Pakete), sobald lesbar. Mock lieferte Klartext-Nachweis-XML. Ich habe nicht mit acb.netgate.com kommuniziert oder einen Live-Blob entschlüsselt. |
GET /services/acb/config | ACBConfigInfo.userkey, ACBConfig.encryption_password | Spec, nicht dieses Lab: Live-Capability-Secret und Entschlüsselungspasswort. G11 secrets-on-GET-Klasse. Nicht ausgeführt. |
| Methode | Sink | Berechtigung |
|---|---|---|
POST /services/acb/restore | RestoreACB Body { timestamp } | Angrenzend geschlossen: Samples senden weiterhin ein JWT. Nicht dieser Überrest. Nicht ausgeführt. |
POST /services/acb/config ersetzt userkey | SaveACBConfig | Angrenzend geschlossen: keine GET-Capability-URL. Nicht ausgeführt. |
GET list / GET bkp löschen nicht. DELETE /services/acb/bkp/{timestamp} ist eine andere Operation. Nicht ausgeführt.
Falscher userkey und fehlender userkey lieferten keinen Nachweis (lab-proven).
Lab-proven vs. abgeleitet: Gestohlener-Schlüssel-Liste und bkp lieferten den Nachweis. Falscher Schlüssel und fehlender Schlüssel nicht. Plus wurde nicht ausgeführt. Live-config.xml-Inhalte und Entschlüsselung sind aus dem öffentlichen Schema abgeleitet (RetrievedBackup.backup ist ein String; encryption_password liegt auf ACBConfig).
Erfordert: Netzwerkpfad zu den MIM-Controller-ACB-GETs, plus einen gestohlenen/geleakten userkey. CVSS 7.5, wenn diese GETs den Query-Key ohne Bindung eines JWT an das Gerät honorieren. Ehrlich: Dieses Pack beweist, dass die öffentliche Spec diesen Vertrag modelliert, auf Loopback.
| Oberfläche | Warum |
|---|---|
| pfSense Plus Controller | nicht ausgeführt. Kein Plus-Image in diesem Pack. |
| CE REST-Paket | anderer Server (jaredhendrickson/pfsense-api / pfrest.org). |
| SSH-Banner-ACB-Schlüsselableitung | CVE-2024-57273 / SA-25_03. Nicht erneut melden. |
POST /services/acb/restore als dieser Fund | Samples senden weiterhin ein JWT. |
Unauth php/shell aus ausgelassenem OAS security | Doku-Überrest. Mock ist kein Server-200-ohne-JWT-Beweis. |
Fehlender userkey | Lab 403, kein Nachweis. |
Falscher userkey | Lab-Liste leer / bkp 403, kein Nachweis. |
Generierte Bibliothek verify_ssl | Standard True. G9 sind die Samples, die es abschalten, nicht der Paketstandard. |
Ich habe Netgate/pfsense-api main b4acd7ca gepinnt (2026-05-25, "Add Snort-3 API definitions"). Zwölf Jagden über Login/JWT, Diagnostik, MIM-Enrollment, Client-TLS, Benutzer/Zertifikate, Pakete, VPN/Firewall, OpenAPI-Security, Device-IDOR, git/firmware/feeds, plus ein Loopback-Mock jeder generierten Operation.
Zuerst die Skip-Liste: CE-WebGUI-Überreste bereits gemeldet (QinQ parent if, OpenVPN-Wizard CRLF, CARP VHID, Limiter-Nummer, IPsec-Login-Banner). Diagnostik-PHP/Shell als beabsichtigte Admin-Befugnis. Das Drittanbieter-CE-REST-Paket. CVE-2024-57273-Banner-Ableitung.