
pfSense Plus MIM API toolkit b4acd7ca - Élevé - À distance - IDOR - un JWT de contrôleur est un jeton de flotte
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · pfsense-api-fleet-jwt
Classe : IDOR Portée : Distante
pfSense Plus MIM API (Netgate) pin b4acd7ca - github.com/Netgate/pfsense-api
Un Bearer POST /login est réutilisé pour chaque device_id enrôlé. Les exemples officiels copient ce jeton sur /api/device/pfsense/{device_id}/api pour chaque id issu de GET /mim/devices. Les champs de LoginResponse sont uniquement token, user, version et alerts. Les rôles LDAP MIM sont globaux. Ils ne sont pas liés à un appareil. Une connexion contrôleur capable de lister les appareils communique avec le pare-feu B à l'aide d'un jeton émis pour un utilisateur destiné au pare-feu A.
Il s'agit d'un seul tenant client, et non d'un résidu SaaS inter-tenant. Les appels non authentifiés restent en 401. Le RBAC Plus n'a pas été exécuté. Hub de la série : pfsense-api-nexus-mim (ceci est le résidu 6). Le JWT volé du résidu 9 (échantillons verify_ssl=False) est ce jeton de flotte.
| ID | pas encore de CVE |
| Classe | IDOR |
| Portée | Distante (JWT contrôleur authentifié) |
| CWE | CWE-639 |
| CVSS | Élevé : 8.1 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N |
| Produit | Netgate/pfsense-api (contrôleur pfSense Plus Nexus Multi-instance Management OpenAPI + client généré) |
| Affecté | pin b4acd7ca21dbca739a530403a1f62a7440f7726f (2026-05-25). Aucun tag. Le serveur est Plus uniquement (payant). Pas le paquet REST CE. |
| Auth | JWT contrôleur issu de POST /login. Deviner device_id n'est pas nécessaire si GET /mim/devices est autorisé. |
| Licence | GNU Affero GPL v3.0 |
| Lab | 127.0.0.1:19161 uniquement. Mock Python du contrat client publié. Pas d'image Plus. |
J'ai épinglé github.com/Netgate/pfsense-api main b4acd7ca21dbca739a530403a1f62a7440f7726f (2026-05-25, Add Snort-3 API definitions). Il ne s'agit pas de jaredhendrickson/pfsense-api / pfrest.org.
Une connexion contrôleur capable de lister les appareils communique avec chaque instance enrôlée à l'aide du même JWT. Le CSRF n'entre pas en jeu (API Bearer). PHP / shell / export-key sur chaque machine est un pouvoir d'administrateur prévu une fois que le proxy accepte le jeton de flotte. Le résidu est l'absence de liaison par appareil, et non Diagnostics: Command.
| Privilège | Méthode / chemin | Prouvé en labo ou déduit |
|---|---|---|
Lister chaque device_id inscrit (nom, adresse, état) | GET /mim/devices avec le Bearer de connexion | Recon (prouvé en labo). Le mock a renvoyé à la fois site-a et site-b. Sans auth, c'est 401. |
| Lire l'état système du pare-feu A et du pare-feu B avec un seul jeton | GET /api/device/pfsense/{device_id}/api/system | Recon (prouvé en labo). device-a=200, device-b=200. Témoin uniquement sur B. |
| POSTer le wrapper PHP de diagnostics sur les deux ids | POST /api/device/pfsense/{device_id}/api/diag/cmd/php | Intégrité (labo sur mock uniquement). Les deux 200. De plus, le RBAC n'a pas été exécuté, donc une barrière de rôle en production n'est pas prouvée. |
Exécuter PHP / shell / édition de fichier sur chaque machine inscrite si la connexion inclut console ou system | POST /diag/cmd/php, POST /diag/cmd/shell, GET/POST /diag/editfile, téléchargement/envoi | Intégrité (déduit de l'OAS + exemples). Pouvoir admin prévu une fois que le proxy accepte le jeton de flotte. Le PHP-FPM typique de pfSense est root. |
| Exporter les clés privées CA / feuille et PKCS12 sur chaque instance listée | GET /system/certificates/{refid}/export-key, GET /system/certauth/{refid}/export-key, GET /system/certificates/{refid}/export-p12 | Recon (déduit). Même JWT, même schéma que le reliquat 4. De plus, le RBAC n'a pas été exécuté. |
| Extraire le compte ACME et les clés émises sur chaque instance listée | GET /services/acme et les GET associés au compte/certificat | Recon (déduit). Même JWT, schéma du reliquat 5. |
| Modifier les alias, le pare-feu, les interfaces, le VPN, les services sur chaque instance listée | même préfixe par appareil, plus de 700 opérations restantes | Intégrité (déduit). Même JWT, même schéma que l'instance locale. |
| Redémarrer / arrêter / restaurer la configuration sur chaque instance listée | POST /diag/control, POST /diag/backup/restore | Disponibilité + intégrité (déduit). Même proxy. Non exercé. |
| IDOR SaaS inter-clients | n/a | Fermé. Un seul tenant client. Netgate exécute le contrôleur dans ce tenant. |
| Internet non authentifié vers :8443 | GET /mim/devices sans Bearer | Fermé dans ce labo. 401. Un mauvais Bearer est aussi 401. |
| Appareils hors ligne | les échantillons ignorent state != online | Fermé par les échantillons. Pas une frontière d'authentification. |
Parcours numérique à l'aveugle de device_id | GET /api/device/pfsense/1/api/system | Fermé comme exigence de devinette. Les ids sont de longues chaînes (en forme d'ED25519). Le listing supprime la devinette. |
Nécessite : une connexion au contrôleur autorisée à accéder au proxy de l'appareil. Chemin réseau vers le contrôleur MIM (:8443 en production, loopback :19161 dans ce labo). Pas sans auth. Pas de CSRF.
| Surface | Pourquoi |
|---|---|
| Listing / php / shell sans auth | Mock 401 sans Bearer et avec un mauvais Bearer. Le silence de la spec sur securitySchemes n'est pas un 200 serveur. |
| SaaS inter-tenant | Un seul tenant client. Des clusters de tenants étaient encore prévus sur la page marketing. |
mim_user / pas de groupe Nexus | Documenté comme fermé si la barrière de connexion tient. |
Noms de rôles mim_* fonctionnels | Ils existent (view, logs, usermgmt, services, firewall, interfaces, devices, system, superuser). Ils sont globaux, pas par device_id. Les vérifications Plus en production n'ont pas été exécutées (plus-rbac=not-executed). |
| Interpolation JSON SSH d'inscription | Reliquat 1. Pack différent. |
AutoAddPolicy d'inscription | Reliquat 2. Pack différent. |
| Socket unix d'appareil sans JWT | Reliquat 3. Local, pack différent. |
| Paquet REST CE | jaredhendrickson/pfsense-api est un serveur différent. |
| Assistant QinQ / OpenVPN WebGUI CE / CARP / limiteur / bannière IPsec | Déjà signalés comme reliquats CE. Les noms de champs dans cet OAS sont les mêmes sinks, pas de nouveaux CVE. |
Console de flotte admins / mim_superuser prévue | Modèle produit pour le propriétaire du contrôleur. Le reliquat est l'ACL d'objet manquante pour tous les autres. |
J'ai épinglé b4acd7ca et lu les exemples officiels par rapport à l'OpenAPI. Chaque échantillon qui parle aux pare-feux gérés fait ceci :