
pfSense Plus MIM API Toolkit b4acd7ca – Hoch – Lokal – Verbleibendes Privileg – Unix-Socket-Registrierung ohne JWT
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · pfsense-api-unix-sock-noauth
Klasse: Privilegien-Überrest Reichweite: Lokal
pfSense Plus MIM API b4acd7ca - Netgate
github.com/Netgate/pfsense-api ist die öffentliche OpenAPI plus generiertes Python für pfSense Plus Nexus Multi-instance Management. Es ist nicht das CE-REST-Paket. Das offizielle Enroll-Beispiel meldet sich per HTTPS :8443 mit einem Bearer-JWT an und überträgt dann per SSH ein POSIX-Skript auf jede Firewall. Dieses Skript kommuniziert mit /var/run/pfnet-controller.sock ohne Authorization.
curl --unix-socket /var/run/pfnet-controller.sock -H "Content-Type: application/json" -d "{controller JSON}" http://unix/api/mim/controllers
curl --unix-socket /var/run/pfnet-controller.sock http://unix/api/mim/device/identity
Veraltete Fallbacks /api/system/controller und /api/system/mim/devid sind identisch: kein Bearer. HTTPS-Login stellt weiterhin ein JWT aus. Dieses Token wird nicht auf den On-Device-Sock angewendet. Dies ist eine separate Vertrauensgrenze von :8443 plus mim_*-Gruppen.
Teil 3 der Nexus MIM-Serie. Nachdem G1 / G2 auf der Box landen, ist dieser Sock die lokale Ebene.
Ein lokaler Prozess, der connect(2) auf den Sock ausführen kann, kann einen Controller enrollen und die Geräteidentität ohne JWT auslesen. Plus wurde nicht ausgeführt. Die tatsächliche Sock-DAC ist unbekannt.
| ID | noch keine CVE |
| Klasse | Privilegien-Überrest |
| Reichweite | Lokal (connect(2) auf /var/run/pfnet-controller.sock) |
| CWE | CWE-306 |
| CVSS | Hoch: 7.8 CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H, wenn der Sock-Modus einer anderen lokalen UID das Verbinden erlaubt. Ehrlich: DAC unbekannt, Plus nicht ausgeführt. |
| Produkt | Netgate/pfsense-api (Plus Nexus MIM-Toolkit) |
| Betroffen | öffentliches main b4acd7ca21dbca739a530403a1f62a7440f7726f (2026-05-25) |
| Auth | keine bei den offiziellen Unix-Socket-Enroll-Curls |
| Lizenz | GNU Affero GPL v3.0 |
| Lab | nur 127.0.0.1:19121. Unix-HTTP-Mock. Kein Plus-Image. |
Akteur ist jeder Prozess auf dem pfSense-Gerät, der connect(2) auf /var/run/pfnet-controller.sock ausführen kann. Kein entferntes TCP durch dieses Beispiel (nur curl --unix-socket). HTTPS :8443 JWT und mim_*-Gruppen gelten nicht für diesen fd.
| Methode | Sink | Privileg |
|---|---|---|
Offizieller device_script POST ohne Authorization | POST http://unix/api/mim/controllers | Integrität: Mock akzeptierte Enroll-JSON. Hit-Log authorization_present=false. |
Offizieller device_script GET ohne Authorization | GET http://unix/api/mim/device/identity | Recon: Mock gab DeviceIdentity-förmiges JSON zurück, einschließlich PFSENSE-API-UNIX-SOCK-NOAUTH-WITNESS. |
Derselbe GET mit Authorization: Bearer lab-jwt | derselbe Identity-Pfad | Lab-Kontrolle: 401, Witness nicht im Body. Unterscheidet vorhanden vs. abwesend. Kein Plus-Ergebnis. |
Dies sind dieselben OpenAPI-Operationen, die das offizielle Beispiel und das mim-Tag auf dem Gerät platzieren. Nur als Protokoll nachgewiesen, nicht als Plus-200.
| Methode | Sink | Privileg |
|---|---|---|
POST /mim/controllers (Fallback POST /api/system/controller) mit Angreifer-ControllerIdentity (key, vpn_pubkey, vpn_listenaddr, vpn_netkey, cert) | SetController | Integrität: einen feindlichen Controller enrollen. Spec: Gerät „wird weiterhin alle 10 Sekunden eine Verbindungsanfrage senden“ (Netgard VPN zum Angreifer). |
GET /mim/device/identity (Fallback GET /api/system/mim/devid) | GetDeviceIdentity | Recon: Geräte-Noise/VPN-Public-Keys, address, controller_add-Curl-Text. |
GET /mim/controllers | GetControllers | Recon: Controller auflisten plus Geräteinfo (ControllerInfo.noise_secret, Keys). |
GET /mim/controllers/id/{key} | GetMIMController | Recon: ein Controller-Datensatz. |
DELETE /mim/controllers/id/{key} | DeleteMIMController | Integrität / Verfügbarkeit: den echten Controller unenrollen (Key hex oder base64-URL). |
POST /mim/device/pubkey mit Angreifer-privkey / pubkey | SetDevicePublicKey (DevicePublicKeyOption enthält privkey) | Integrität: die ED25519-Identität des Geräts ersetzen. Der Controller-Handshake vertraut dann dem Angreifer-Key. |
Gewährt nicht von sich aus eine Host-Root-Shell. Gewährt die MIM-Ebene: wem das Gerät als Controller vertraut, und den Noise-Private-Key des Geräts, wenn der Pubkey-POST beachtet wird.
Erfordert: lokales connect(2) zu /var/run/pfnet-controller.sock. DAC (Modus, Eigentümer, Gruppe, SO_PEERCRED) ist nicht im öffentlichen Client-Baum. Wenn der Daemon 0600 root bindet, ist dies bereits-root lokal (confused deputy für einen Helper, ein Paket oder eine Escape, die /var/run sehen kann). Wenn der Sock für eine andere uid erreichbar ist, CVSS 7.8 wie bewertet.
/mim/controllers auf Nexus HTTPS :8443. Dieser Port ist als User Manager JWT dokumentiert. Dieser Rest ist der unix fd.POST /login gibt weiterhin ein Bearer JWT aus. AuthenticatedClient sendet es weiterhin an CONTROLLER_URL+"/api".verify_ssl=True. Pfadparameter prozentkodieren ../.security: MISSING bei allen 755 Ops ist eine Schema-Lücke, kein bewiesener unauth HTTPS-Skip.Gleicher Pin, remote enrollment plane: pfsense-api-enroll-json-ssh und pfsense-api-enroll-autoadd. Serienkarte: pfsense-api-nexus-mim.
Ich habe Netgate/pfsense-api b4acd7ca21dbca739a530403a1f62a7440f7726f gepinnt und die offizielle Enrollment-Schleife gelesen: login, GET /mim/controller/identity, stringify, SSH exec von unix-socket POST/GET, POST /mim/devices. HTTPS verwendet AuthenticatedClient(token=...). Die Sock-Curls nicht.
Irrwege: fehlende securitySchemes als unauth HTTPS behandeln (login fehlt es auch; Beispiele immer Bearer zuerst). Annehmen, der Sock sei world-writable (Modus ist nicht in diesem Repo). Ein Plus 200 behaupten. Der hier bewiesene Rest ist das veröffentlichte Enroll-Protokoll.