
pfSense Plus MIM API toolkit b4acd7ca - متوسط - عن بُعد - صلاحيات متبقية - عينات رسمية verify_ssl=False
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · pfsense-api-example-ssl-verify
الفئة: صلاحية متبقية الوصول: عن بُعد
pfSense Plus MIM API (Netgate/pfsense-api b4acd7ca) - Netgate
يُنشئ Client / AuthenticatedClient المولَّدان القيمة الافتراضية verify_ssl=True ويمررانها إلى httpx. الوثائق تصف بالفعل verify_ssl=False بأنه خطر أمني وتعرض مسار حزمة PEM أولاً. ومع ذلك، لا تزال كل عيّنة Python رسمية وhelper_funcs.py تُنشئها بـ verify_ssl=False. ويضبط example.js القيمة NODE_TLS_REJECT_UNAUTHORIZED=0، فتصبح عملية Node بأكملها تتخطى التحقق. ويضع JSON تسجيل الدخول اسم المستخدم وكلمة المرور بترميز base64. هذا هو عقد OpenAPI، وليس تشفيراً. TLS هو طبقة السرية.
نظير على المسار لـ :8443 يقدّم أي شهادة. ومع ذلك تُرسل العيّنة طلب POST إلى /login. فيلتقط البديل بيانات تسجيل دخول المسؤول بترميز base64 ويصدر JWT. تلك الرمز هي السلسلة: G4 export-key، وG5 ACME dump، وG6 fleet JWT، وG7 ACB userkey، وphp/shell المقصود، وJSON الذي يُدرجه G1 في SSH.
هذا هو الجزء 9 من pfSense Plus MIM API toolkit. اقرأ هذه الثغرة المتبقية أولاً رغم أنها متوسطة الخطورة. فرصة JWT المسروقة هي ما يجعل البقية قابلة للوصول من محطة عمل نسخت example.py.
| المعرّف | لا يوجد CVE بعد |
| الفئة | صلاحية متبقية (التحقق من TLS معطّل في العيّنة) |
| الوصول | عن بُعد (على المسار إلى :8443) |
| CWE | CWE-295 |
| CVSS | متوسط: 6.8 CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:N |
| المنتج | Netgate/pfsense-api (عميل Plus Nexus MIM؛ وليس حزمة CE REST) |
| المتأثر | الفرع العام main b4acd7ca21dbca739a530403a1f62a7440f7726f (2026-05-25) العيّنات الرسمية وhelper_funcs.py |
| المصادقة | يقوم المشغّل بنسخ عيّنة وتشغيلها مقابل المتحكم؛ دون دور متحكم إضافي |
| الترخيص | GNU Affero GPL v3.0 |
| المختبر | 127.0.0.1:19191 فقط. لا يُركّب pfSense Plus. |
AC:H على المسار بين محطة عمل المشغّل ومتحكم MIM. وUI:R هو نسخ/تشغيل العيّنة.
الضحية: محطة عمل المشغّل التي تشغّل عيّنة رسمية أو helper_funcs.py مقابل https://controller:8443. المهاجم: على المسار إلى ذلك HTTPS (شبكة محلية، DHCP خبيث، قفزة VPN مخترقة، ARP). وليس مهاجماً غير مصادق من الإنترنت إلى الجدار الناري.
| الطريقة | الحوض | الصلاحية |
|---|---|---|
تقديم أي شهادة بينما يرسل النموذج POST إلى /login أو /api/login مع verify_ssl=False / NODE_TLS_REJECT_UNAUTHORIZED=0 | httpx verify=False (عينات Python) أو Node TLS reject-unauthorized 0 | السرية (مُثبتة مختبرياً): قراءة JSON تسجيل الدخول. المختبر: التقط البديل base64 admin / lab-controller-secret (captured_b64_admin=yes). فك الترميز هو أمر base64 -d واحد. |
نفس هجوم MITM، 200 LoginResponse | يقبل النموذج أي شهادة | السرية (مُثبتة مختبرياً): سرقة رمز الوصول JWT. المختبر: حصل INJECT على رمز يحمل PFSENSE-API-EXAMPLE-SSL-VERIFY-WITNESS. |
نفس هجوم MITM، Set-Cookie عند تسجيل الدخول | ينسخ النموذج client.get_httpx_client().cookies إلى AuthenticatedClient | السرية (كوكي مُثبت مختبرياً، إعادة تشغيل مُستنتجة): رمز تحديث JWT لمدة 24 ساعة. أعد تشغيل POST /login/refresh مع ذلك الكوكي واسم المستخدم base64 حتى انتهاء صلاحية التحديث. التقط المختبر Set-Cookie: refresh=.... لم يتم تنفيذ التحديث ضد وحدة تحكم حية. |
| إعادة تشغيل Bearer المسروق إلى وحدة التحكم الحقيقية (إذا كان المهاجم قادراً أيضاً على التوجيه إليها) | بالإضافة إلى MIM /api و /api/device/pfsense/{device_id}/api | السلامة (مُستنتجة): مكافئ للمسؤول كمستخدم مسجل الدخول على هذا API. يتضمن المخطط POST /diag/cmd/php، POST /diag/cmd/shell، POST /diag/editfile، POST /diag/backup/restore، POST /diag/control إيقاف/إعادة تشغيل. لم يتم اختبار ذلك هنا. هذا المختبر بديل لوحدة التحكم، وليس Plus. |
| إعادة تشغيل Bearer المسروق كـ leftover 6 (رمز الأسطول) | رمز JWT واحد من POST /login يُعاد استخدامه لكل device_id | السلامة (مُستنتجة): التحدث إلى جدار الحماية B بعد المصادقة كمستخدم مخصص لجدار الحماية A. لا يحتوي LoginResponse على قائمة سماح لكل جهاز. الحزمة: pfsense-api-fleet-jwt. لم يتم تنفيذ Plus RBAC. |
| إعادة تشغيل Bearer المسروق كـ leftover 4 | GET /system/certauth/{refid}/export-key، GET /system/certificates/{refid}/export-key، GET /system/certificates/{refid}/export-p12 | السرية (مُستنتجة): سحب مفاتيح CA والمفاتيح الخاصة للأوراق، PKCS12 موثق بدون حماية بكلمة مرور، ثم انتحال VPN / WebGUI TLS / IPsec. الحزمة: pfsense-api-export-key-get. |
| إعادة تشغيل Bearer المسروق كـ leftover 5 | GET /services/acme | السرية (مُستنتجة): سرقة مفتاح حساب Let's Encrypt ومفاتيح الشهادات الصادرة لكل اسم مضيف يسجله جدار الحماية. الحزمة: pfsense-api-acme-key-dump. |
إعادة تشغيل Bearer المسروق، أو تسريب userkey من نموذج يقوم بـ GET لـ ACB، كـ leftover 7 | GET /services/acb?userkey= و GET /services/acb/bkp?userkey= | السرية (مُستنتجة): سرد وجلب كتل Auto Config Backup (التكوين الكامل). الحزمة: pfsense-api-acb-userkey. |
تشكيل JSON الخاص بـ ControllerSummary نحو leftover 1 | MITM لـ HTTPS مع verify_ssl=False يوفر JSON الذي يقوم example-add-devices.py بتهريب علامات الاقتباس فيه ثم .format إلى SSH | السلامة (مُستنتجة): $() / backticks / أسطر جديدة في حقل وحدة التحكم تُنفذ كـ SSHUSER على كل عنوان في pfsense_addresses. الحزمة: pfsense-api-enroll-json-ssh. |
| حقن الاستجابات نحو العميل | skip-verify يقبل أي شهادة | السلامة (رمز مُثبت مختبرياً، أسطول مُستنتج): صك JWT سيحتفظ به النموذج. المختبر: رمز INJECT مع الشاهد. قوائم الأجهزة المزيفة / تقدم الترقية / نجاح تسجيل الدخول ضد نموذج حي هي نفس البوابة. |
POST /diag/control، POST للبرنامج الثابت، استعادة نسخة احتياطية معطوبة (بعد سرقة Bearer) | سطح المسؤول المقصود بمجرد اختفاء TLS | التوافر (مُستنتج): إيقاف / إعادة تشغيل / صورة معطوبة. نفس Bearer. لم يتم اختباره مختبرياً. |
مُثبت مختبرياً مقابل مُستنتج: فشل مصافحة CONTROL، رمز INJECT، وتسجيل دخول المسؤول base64 الملتقط مُثبتة مختبرياً على 127.0.0.1:19191. إعادة تشغيل ذلك Bearer على وحدة تحكم Plus حية، diag php/shell، G4-G7، تشكيل JSON لـ G1، وصك كوكي التحديث لرموز وصول JWT جديدة مُستنتجة من OpenAPI والعينات.
يتطلب: أن ينسخ المشغّل ويشغّل example.py، وexample-add-devices.py، وexample-upgrade-devices.py، وexample-set-alias.py / example-upgrade-devices-async.py عبر helper_funcs.py، أو example.js. مهاجم على المسار إلى :8443.
سطح مجاور يبقى مغلقاً