
pfSense Plus MIM API toolkit b4acd7ca - High - Remote - IDOR - एक controller JWT एक fleet token है
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · pfsense-api-fleet-jwt
Class: IDOR Reach: Remote
pfSense Plus MIM API (Netgate) pin b4acd7ca - github.com/Netgate/pfsense-api
एक POST /login Bearer को हर enrolled device_id के लिए दोबारा इस्तेमाल किया जाता है। आधिकारिक उदाहरण उस टोकन को GET /mim/devices से प्राप्त हर id के लिए /api/device/pfsense/{device_id}/api पर कॉपी करते हैं। LoginResponse फ़ील्ड केवल token, user, version, और alerts हैं। LDAP MIM roles वैश्विक हैं। वे किसी डिवाइस से बंधे नहीं हैं। एक controller login जो डिवाइसों की सूची बना सकता है, firewall B से ऐसे टोकन के साथ बात करता है जो उस उपयोगकर्ता के लिए जारी किया गया था जो firewall A के लिए था।
यह एक ग्राहक tenancy है, SaaS cross-tenant अवशेष नहीं। Unauthenticated कॉल 401 ही रहती हैं। Plus RBAC निष्पादित नहीं हुआ। Series hub: pfsense-api-nexus-mim (यह अवशेष 6 है)। अवशेष 9 (verify_ssl=False नमूने) से चुराया गया JWT यही fleet token है।
| ID | अभी कोई CVE नहीं |
| Class | IDOR |
| Reach | Remote (authenticated controller JWT) |
| CWE | CWE-639 |
| CVSS | High: 8.1 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N |
| Product | Netgate/pfsense-api (pfSense Plus Nexus Multi-instance Management controller OpenAPI + generated client) |
| Affected | pin b4acd7ca21dbca739a530403a1f62a7440f7726f (2026-05-25)। कोई टैग नहीं। सर्वर Plus-only (सशुल्क) है। CE REST पैकेज नहीं। |
| Auth | POST /login से controller JWT। यदि GET /mim/devices की अनुमति है तो device_id का अनुमान लगाना आवश्यक नहीं। |
| License | GNU Affero GPL v3.0 |
| Lab | केवल 127.0.0.1:19161। प्रकाशित client contract का Python mock। कोई Plus image नहीं। |
मैंने github.com/Netgate/pfsense-api main b4acd7ca21dbca739a530403a1f62a7440f7726f (2026-05-25, Add Snort-3 API definitions) pin किया। यह jaredhendrickson/pfsense-api / pfrest.org नहीं है।
एक controller login जो डिवाइसों की सूची बना सकता है, वह उसी JWT के साथ हर enrolled instance से बात करता है। CSRF यहाँ लागू नहीं है (Bearer API)। हर बॉक्स पर PHP / shell / export-key इच्छित admin शक्ति है जैसे ही proxy fleet token स्वीकार करता है। अवशेष प्रति-डिवाइस bind की कमी है, Diagnostics: Command नहीं।
| विशेषाधिकार | विधि / पथ | प्रयोगशाला-प्रमाणित या अनुमानित |
|---|---|---|
प्रत्येक नामांकित device_id की सूची बनाएं (नाम, पता, स्थिति) | लॉगिन Bearer के साथ GET /mim/devices | Recon (प्रयोगशाला-प्रमाणित)। Mock ने site-a और site-b दोनों लौटाए। Unauth 401 है। |
| एक टोकन से firewall A और firewall B की सिस्टम स्थिति पढ़ें | GET /api/device/pfsense/{device_id}/api/system | Recon (प्रयोगशाला-प्रमाणित)। device-a=200, device-b=200। Witness केवल B पर। |
| दोनों ids पर diagnostics PHP wrapper POST करें | POST /api/device/pfsense/{device_id}/api/diag/cmd/php | Integrity (केवल mock पर प्रयोगशाला)। दोनों 200। साथ ही RBAC निष्पादित नहीं हुआ, इसलिए लाइव role gate अप्रमाणित है। |
यदि लॉगिन में console या system शामिल है तो प्रत्येक नामांकित बॉक्स पर PHP / shell / फ़ाइल संपादन चलाएं | POST /diag/cmd/php, POST /diag/cmd/shell, GET/POST /diag/editfile, download/upload | Integrity (OAS + उदाहरणों से अनुमानित)। एक बार proxy फ्लीट टोकन स्वीकार कर ले तो इच्छित admin शक्ति। सामान्य pfSense PHP-FPM root है। |
| प्रत्येक सूचीबद्ध इंस्टेंस पर CA / leaf निजी कुंजियाँ और PKCS12 निर्यात करें | GET /system/certificates/{refid}/export-key, GET /system/certauth/{refid}/export-key, GET /system/certificates/{refid}/export-p12 | Recon (अनुमानित)। वही JWT, वही schema जो leftover 4 का है। साथ ही RBAC निष्पादित नहीं हुआ। |
| प्रत्येक सूचीबद्ध इंस्टेंस पर ACME account और जारी कुंजियाँ डंप करें | GET /services/acme और संबंधित account/cert GETs | Recon (अनुमानित)। वही JWT, leftover 5 schema। |
| प्रत्येक सूचीबद्ध इंस्टेंस पर aliases, firewall, interfaces, VPN, services बदलें | वही per-device prefix, शेष 700+ ops | Integrity (अनुमानित)। वही JWT, वही schema जो स्थानीय इंस्टेंस का है। |
| प्रत्येक सूचीबद्ध इंस्टेंस पर reboot / halt / config restore करें | POST /diag/control, POST /diag/backup/restore | Availability + integrity (अनुमानित)। वही proxy। अभ्यास नहीं किया गया। |
| क्रॉस-कस्टमर SaaS IDOR | n/a | बंद। एक ग्राहक tenancy। Netgate उस tenancy में controller चलाता है। |
| अनधिकृत Internet-to-:8443 | Bearer के बिना GET /mim/devices | इस प्रयोगशाला में बंद। 401। गलत Bearer भी 401 है। |
| ऑफ़लाइन डिवाइस | samples state != online छोड़ देते हैं | samples द्वारा बंद। यह auth सीमा नहीं है। |
device_id का ब्लाइंड न्यूमेरिक वॉक | GET /api/device/pfsense/1/api/system | अनुमान की आवश्यकता के रूप में बंद। Ids लंबे स्ट्रिंग्स हैं (ED25519-आकार के)। लिस्टिंग अनुमान को हटा देती है। |
आवश्यक: एक controller लॉगिन जिसे device proxy पर अनुमति है। MIM controller तक नेटवर्क पथ (उत्पाद में :8443, इस प्रयोगशाला में loopback :19161)। unauth नहीं। CSRF नहीं।
| सतह | क्यों |
|---|---|
| Unauth listing / php / shell | Bearer के बिना और गलत Bearer के साथ Mock 401। securitySchemes पर spec का मौन server 200 नहीं है। |
| SaaS क्रॉस-टेनेंट | एक ग्राहक tenancy। Tenancy clusters अभी भी मार्केटिंग पेज पर नियोजित थे। |
mim_user / no Nexus group | यदि लॉगिन गेट टिकता है तो बंद के रूप में प्रलेखित। |
कार्यात्मक mim_* role नाम | वे मौजूद हैं (view, logs, usermgmt, services, firewall, interfaces, devices, system, superuser)। वे वैश्विक हैं, प्रति device_id नहीं। लाइव Plus जाँच निष्पादित नहीं की गईं (plus-rbac=not-executed)। |
| Enrollment SSH JSON interpolation | Leftover 1। भिन्न pack। |
Enrollment AutoAddPolicy | Leftover 2। भिन्न pack। |
| JWT के बिना Device unix socket | Leftover 3। स्थानीय, भिन्न pack। |
| CE REST package | jaredhendrickson/pfsense-api एक भिन्न सर्वर है। |
| CE WebGUI QinQ / OpenVPN wizard / CARP / limiter / IPsec banner | पहले ही CE leftovers के रूप में मेल किया गया। इस OAS में फ़ील्ड नाम वही sinks हैं, नए CVEs नहीं। |
इच्छित admins / mim_superuser फ्लीट कंसोल | controller owner के लिए उत्पाद मॉडल। leftover बाकी सभी के लिए अनुपस्थित object ACL है। |
मैंने b4acd7ca pin किया और OpenAPI के विरुद्ध आधिकारिक उदाहरण पढ़े। प्रत्येक नमूना जो managed firewalls से बात करता है, यह करता है:
devApi = AuthenticatedClient(
base_url=CONTROLLER_URL+"/api/device/pfsense/{}/api".format(device.device_id),
verify_ssl=False,
headers={"Content-Type": "application/json"},
cookies=cookies,
token=token,
)