
pfSense Plus MIM API toolkit b4acd7ca - Alta - Remoto - IDOR - um JWT de controlador é um token de frota
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · pfsense-api-fleet-jwt
Classe: IDOR Alcance: Remoto
pfSense Plus MIM API (Netgate) pin b4acd7ca - github.com/Netgate/pfsense-api
Um Bearer de POST /login é reutilizado para cada device_id inscrito. Os exemplos oficiais copiam esse token para /api/device/pfsense/{device_id}/api para cada id de GET /mim/devices. Os campos de LoginResponse são apenas token, user, version e alerts. As funções LDAP MIM são globais. Não estão vinculadas a um dispositivo. Um login de controlador que consegue listar dispositivos comunica com o firewall B com um token emitido para um usuário que se destinava ao firewall A.
Esta é uma única tenancy de cliente, não um resquício cross-tenant de SaaS. Chamadas não autenticadas permanecem 401. O RBAC do Plus não foi executado. Hub da série: pfsense-api-nexus-mim (este é o resquício 6). O JWT roubado do resquício 9 (amostras verify_ssl=False) é este token de frota.
| ID | ainda sem CVE |
| Classe | IDOR |
| Alcance | Remoto (JWT de controlador autenticado) |
| CWE | CWE-639 |
| CVSS | Alto: 8.1 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N |
| Produto | Netgate/pfsense-api (controlador pfSense Plus Nexus Multi-instance Management OpenAPI + cliente gerado) |
| Afetado | pin b4acd7ca21dbca739a530403a1f62a7440f7726f (2026-05-25). Sem tags. O servidor é exclusivo do Plus (pago). Não é o pacote REST do CE. |
| Autenticação | JWT de controlador de POST /login. Adivinhar o device_id não é necessário se GET /mim/devices for permitido. |
| Licença | GNU Affero GPL v3.0 |
| Lab | apenas 127.0.0.1:19161. Mock em Python do contrato do cliente publicado. Sem imagem Plus. |
Fiz pin de github.com/Netgate/pfsense-api main b4acd7ca21dbca739a530403a1f62a7440f7726f (2026-05-25, Add Snort-3 API definitions). Este não é jaredhendrickson/pfsense-api / pfrest.org.
Um login de controlador que consegue listar dispositivos comunica com cada instância inscrita com o mesmo JWT. CSRF não está em jogo (API Bearer). PHP / shell / export-key em cada máquina é poder de administrador pretendido assim que o proxy aceita o token de frota. O resquício é a ausência de vínculo por dispositivo, não Diagnostics: Command.
| Privilégio | Método / caminho | Comprovado em laboratório ou inferido |
|---|---|---|
Listar todos os device_id inscritos (nome, endereço, estado) | GET /mim/devices com o Bearer de login | Recon (comprovado em laboratório). O mock devolveu tanto site-a como site-b. Sem autenticação é 401. |
| Ler o estado do sistema do firewall A e do firewall B com um único token | GET /api/device/pfsense/{device_id}/api/system | Recon (comprovado em laboratório). device-a=200, device-b=200. Witness apenas em B. |
| Fazer POST do wrapper PHP de diagnósticos em ambos os ids | POST /api/device/pfsense/{device_id}/api/diag/cmd/php | Integridade (laboratório apenas no mock). Ambos 200. Além disso, o RBAC não foi executado, pelo que um role gate em produção não está comprovado. |
Executar PHP / shell / edição de ficheiros em todas as máquinas inscritas se o login incluir console ou system | POST /diag/cmd/php, POST /diag/cmd/shell, GET/POST /diag/editfile, download/upload | Integridade (inferido a partir do OAS + exemplos). Poder de admin pretendido assim que o proxy aceita o token da frota. O pfSense PHP-FPM típico corre como root. |
| Exportar chaves privadas de CA / leaf e PKCS12 em todas as instâncias listadas | GET /system/certificates/{refid}/export-key, GET /system/certauth/{refid}/export-key, GET /system/certificates/{refid}/export-p12 | Recon (inferido). Mesmo JWT, mesmo schema que o leftover 4. Além disso, o RBAC não foi executado. |
| Despejar a conta ACME e as chaves emitidas em todas as instâncias listadas | GET /services/acme e GETs relacionados de conta/certificado | Recon (inferido). Mesmo JWT, schema do leftover 5. |
| Alterar aliases, firewall, interfaces, VPN, serviços em todas as instâncias listadas | mesmo prefixo por dispositivo, restantes 700+ operações | Integridade (inferido). Mesmo JWT, mesmo schema que a instância local. |
| Reboot / halt / restaurar configuração em todas as instâncias listadas | POST /diag/control, POST /diag/backup/restore | Disponibilidade + integridade (inferido). Mesmo proxy. Não exercitado. |
| IDOR de SaaS entre clientes | n/a | Fechado. Uma única tenancy de cliente. A Netgate corre o controller nessa tenancy. |
| Internet-to-:8443 não autenticado | GET /mim/devices sem Bearer | Fechado neste laboratório. 401. Bearer errado também dá 401. |
| Dispositivos offline | as amostras ignoram state != online | Fechado pelas amostras. Não é uma fronteira de autenticação. |
Varredura numérica cega de device_id | GET /api/device/pfsense/1/api/system | Fechado como requisito de adivinhação. Os ids são strings longas (com forma de ED25519). A listagem elimina a adivinhação. |
Requer: um login no controller que tenha permissão para aceder ao proxy do dispositivo. Caminho de rede até ao controller MIM (:8443 em produção, loopback :19161 neste laboratório). Não é sem autenticação. Não é CSRF.
| Superfície | Porquê |
|---|---|
| Listagem / php / shell sem autenticação | Mock 401 sem Bearer e com um Bearer errado. O silêncio da spec sobre securitySchemes não é um 200 do servidor. |
| SaaS entre tenants | Uma única tenancy de cliente. Os clusters de tenancy ainda estavam planeados na página de marketing. |
mim_user / sem grupo Nexus | Documentado como fechado se o gate de login se mantiver. |
Nomes de roles mim_* funcionais | Existem (view, logs, usermgmt, services, firewall, interfaces, devices, system, superuser). São globais, não por device_id. As verificações do Plus em produção não foram executadas (plus-rbac=not-executed). |
| Interpolação JSON do SSH de enrollment | Leftover 1. Pack diferente. |
AutoAddPolicy do enrollment | Leftover 2. Pack diferente. |
| Socket unix do dispositivo sem JWT | Leftover 3. Local, pack diferente. |
| Pacote REST do CE | jaredhendrickson/pfsense-api é um servidor diferente. |
| QinQ / assistente OpenVPN / CARP / limiter / banner IPsec da WebGUI do CE | Já reportado como leftovers do CE. Os nomes de campos neste OAS são os mesmos sinks, não novas CVEs. |
Consola de frota admins / mim_superuser pretendida | Modelo de produto para o proprietário do controller. O leftover é a ACL de objeto em falta para todos os outros. |
Fiz pin de b4acd7ca e li os exemplos oficiais contra o OpenAPI. Todas as amostras que comunicam com firewalls geridos fazem isto: