pfSense Plus MIM API टूलकिट b4acd7ca - उच्च - रिमोट - विशेषाधिकार शेष - GET /services/acme कुंजियाँ डंप करता है
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · pfsense-api-acme-key-dump
Class: Privilege leftover Reach: Remote
pfSense Plus Nexus Multi-instance Management OpenAPI toolkit b4acd7ca - Netgate
GET /services/acme (GetACMEConfig) ACMEConfig लौटाता है जिसमें कोई write-only या redacted flag नहीं होता। 200 schema में ACME account private key, हर issued leaf private key, कोई भी custom leaf key, और validation के लिए उपयोग किए गए DNS-provider tokens शामिल हैं। Cert manager के पास कम से कम एक समर्पित GET .../export-key तो है। ACME के पास कोई नहीं है। Config GET ही dump है।
एक controller session जो इस path को GET कर सकता है, firewall द्वारा enroll किए गए हर hostname key की प्रति बना लेता है, साथ ही उन नामों पर नियंत्रण साबित करने वाले DNS credentials भी।
यह tree public OpenAPI के साथ एक generated Python client है। यह CE REST package नहीं है। MIM controller केवल Plus-only है और GitHub repo में नहीं है। मैंने किसी live controller से बात नहीं की। plus-not-executed=1.
| ID | अभी तक कोई CVE नहीं |
| Class | Privilege leftover (config GET पर secret dump) |
| Reach | Remote (authenticated MIM controller; unauth सिद्ध नहीं) |
| CWE | CWE-200 |
| CVSS | High: 6.5 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N यदि कोई services-read role body प्राप्त करता है। यदि केवल superuser इसे GET कर सकता है, तो भी dump config listing के लिए गलत आकार का है। |
| Product | Netgate/pfsense-api OpenAPI for pfSense Plus Nexus MIM |
| Affected | public main b4acd7ca21dbca739a530403a1f62a7440f7726f (2026-05-25, Add Snort-3 API definitions)। कोई tags नहीं। |
| Auth | POST /login से Controller JWT। Examples Bearer भेजते हैं। Spec में कोई securitySchemes नहीं है। |
| License | GNU Affero GPL v3.0 |
| Lab | केवल 127.0.0.1:19151। कोई Plus image नहीं। |
Series hub: pfSense Plus MIM leftovers। यह part 5 है। G9 stolen JWT (samples verify_ssl=False सेट करते हैं) और G6 fleet token (एक login Bearer हर device_id के लिए दोबारा उपयोग किया जाता है) के साथ chain होता है। Sibling dump: G4 cert-manager export-key।
इसके लिए एक controller session चाहिए जो GET /services/acme कर सके। Docs इसे mim_services_read / mim_services / mim_superuser से map करते हैं। Spec उन roles को path से नहीं जोड़ता। Plus RBAC निष्पादित नहीं किया गया।
G9 से चुराया गया JWT (official samples का MITM) या G6 से helpdesk fleet token इस GET को हर enrolled box पर लक्षित करने के लिए पर्याप्त है। वह chain अनुमानित है। यह leftover GET body है।
| Method | Sink | Privilege |
|---|---|---|
GET /services/acme | ACMEConfig.account_keys[].account_key (format: byte) | प्रकाशित spec और mock पर Lab-proven: 200 schema में account_key शामिल है; mock body PFSENSE-API-ACME-KEY-DUMP-WITNESS को round-trip करता है। Plus पर Inferred: Let's Encrypt (या अन्य ACME) account private key की copy बनाएँ। ACME account से off-box बात करें। |
| Same GET | certs[].issued_cert.privateKey (format: byte) | Lab-proven spec+mock। Plus पर Inferred: firewall द्वारा enroll किए गए प्रत्येक issued leaf private key की copy बनाएँ। उन नामों के लिए off-box TLS impersonation। |
| Same GET | certs[].custom_key (format: byte) | Lab-proven spec+mock। Plus पर Inferred: जब key_type=custom हो तो custom leaf key की copy बनाएँ। |
| Same GET | certs[].domain_list[].config.credentials (additionalProperties: string) | Lab-proven spec+mock। Plus पर Inferred: DNS validation secrets (Cloudflare tokens, AWS keys, RFC2136 secrets) की copy बनाएँ। ये नामों पर नियंत्रण सिद्ध करते हैं। |
| Same GET | account emails, custom server URLs, action_list.command | Lab-proven कि fields schema पर मौजूद हैं। Hook execution एक modify path है, यह GET नहीं। |
GET द्वारा स्वयं कोई नहीं। चुराई गई keys और DNS tokens का बाद में उपयोग off-box है (rogue cert जारी करना, ACME account से बात करना, DNS बदलना)। Not exercised।
कोई नहीं। Config listing certificates को revoke या rewrite नहीं करती।
Requires: authenticated MIM controller access जिसे ACME tag GET करने की अनुमति हो। Not proven unauth। इस op के लिए generated _get_kwargs कोई Authorization नहीं जोड़ता; examples अभी भी login करते हैं और Bearer भेजते हैं।
| Surface | Why |
|---|---|
| Live pfSense Plus / Nexus controller | Not executed। plus-not-executed=1। |
| Unauthenticated Internet-to-8443 | Examples के लिए POST /login आवश्यक है। Missing OAS security एक spec gap है, server 200-without-JWT proof नहीं। |
POST /services/acme/cert/{name}/issue और .../renew | Intended services-modify। |
POST /services/acme/genprivatekey | नई account key का intended generate-and-return। यह leftover नहीं। |
POST /diag/cmd/php / POST /diag/cmd/shell | Intended admin console। Separate surface। Vendor Diagnostics: Command को intended मानता है (CVE-2025-69691 disputed)। |
GET /system/certificates/{refid}/export-key | Separate leftover: cert manager पर dedicated key export। ACME में कोई equivalent export op नहीं है। |
GET /services/acme/validmethods | Method catalog। कोई keys नहीं। |
CE jaredhendrickson/pfsense-api | Different product। |
CE 2.9.0-DEVELOPMENT wave के बाद मैंने public Netgate/pfsense-api b4acd7ca को pin किया। यह tree OpenAPI 3.0.3 (pfapi_openapi.yml, 486 paths, 755 ops) के साथ-साथ :8443 पर Plus MIM controller के लिए generated Python client है। कोई tags नहीं। जिस दिन मैंने clone किया उस दिन latest public commit 2026-05-25, "Add Snort-3 API definitions." था।
login/JWT, diagnostics, MIM enrollment, client TLS, users/certs, packages, VPN/firewall, OpenAPI security, device IDOR, git/firmware/feeds, तथा प्रत्येक generated operation के loopback mock पर बारह hunts।
पहले skip list: पाँच CE leftovers जो पहले ही mail किए जा चुके हैं (QinQ parent-if, OpenVPN wizard CRLF, CARP VHID, limiter number, IPsec login banner)। Third-party CE REST package। Diagnostics PHP/shell as unpublished RCE। Missing securitySchemes as proven unauth। POST /system/firmware में कोई URL नहीं है। Ping/DNS/traceroute diagnostic हैं।
मैंने GET /services/acme पढ़ा। 200 $ref ACMEConfig है। properties में चलने पर key fields पर format: byte के साथ account_key, privateKey, custom_key, और credentials मिलते हैं। generated client get_acme_config.py GET /services/acme को call करता है और ACMEConfig को parse करता है।
Wrong turns: POST /services/acme/genprivatekey को leftover मानना (वह mint feature है); missing securitySchemes को proven unauth मानना (examples अभी भी Bearer भेजते हैं); यह दावा करना कि non-superuser role वास्तव में Plus पर keys प्राप्त करता है।
Theatre: एक live Plus box। Oracle प्रकाशित schema के साथ-साथ एक loopback mock 200 है।