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

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

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

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

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2020-13277 — مختبر CVE-2020-13277: ثغرة منطقية في GitLab - وصول غير مصرح به لأي مستخدم إلى المستودعات الخاصة | Kitploit
أدوات/GitHubGitHub/exp-docs/cve-2020-13277
تحليل الثغرات الأمنيةالاستغلالاستغلال تطبيقات الويباختبار الاختراقالتعلم والتعليممختبرات وتدريب عملي
GitHubexp-docs/cve-2020-13277

CVE-2020-13277

مختبر CVE-2020-13277: ثغرة منطقية في GitLab - وصول غير مصرح به لأي مستخدم إلى المستودعات الخاصة

عرض المستودع
283منذ 3 سنواتتمت المراجعة من قبل Kitploit

الأكثر شعبية

عرض الكل →

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

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

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

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

CVE-2020-13277

مختبر CVE-2020-13277: ثغرة منطقية في Gitlab - وصول غير مصرح به لأي مستخدم إلى مستودع خاص


0x10 بيئة المختبر

0x20 بنية الدليل

root@kitploit:~
CVE-2020-13277
├── README.md ............... [此 README 说明]
├── imgs .................... [辅助 README 说明的图片]
├── gitlab .................. [Gitlab 容器的挂载目录]
│   ├── Dockerfile .......... [Gitlab 的 Docker 构建文件]
│   ├── config .............. [Gitlab 配置挂载目录]
│   ├── data ................ [Gitlab 数据挂载目录]
│   ├── logs ................ [Gitlab 日志挂载目录]
│   ├── keys ................ [Gitlab 破解 License 存储目录]
│   └── runner .............. [Runner 容器的挂载目录]
├── license ................. [破解 License 的容器构建目录]
│   ├── Dockerfile .......... [License 的 Docker 构建文件]
│   └── license.rb .......... [生成破解 License 的 Ruby 脚本]
├── docker-compose.yml ...... [Docker 的构建配置]
├── keygen.ps1 .............. [Windows: 一键生成破解 License]
├── keygen.sh ............... [Linux:   一键生成破解 License]
├── run.ps1 ................. [Windows: 一键运行 Gitlab 靶场]
├── run.sh .................. [Linux:   一键运行 Gitlab 靶场]
├── register.ps1 ............ [Windows: 一键注册 Runner]
├── register.sh ............. [Linux:   一键注册 Runner]
├── stop.ps1 ................ [Windows: 一键停止 Gitlab 靶场]
└── stop.sh ................. [Linux:   一键停止 Gitlab 靶场]

0x30 ملاحظات أولية

أساس اختيار إصدار Docker Image للمختبر

يعتمد جوهر هذه الثغرة بشكل أساسي على استخدام Mirror Repository - وظيفة النسخ الاحتياطي لمزامنة المستودعات المتطابقة.

ينقسم اتجاه مزامنة Mirror إلى نوعين:

  • Pull: سحب محتوى Repository المحدد إلى Repository الحالي
  • Push: دفع محتوى Repository الحالي إلى Repository المحدد

تستغل هذه الثغرة اتجاه Pull في Mirror Repository

من الجدير بالذكر أن Gitlab ينقسم إلى نسختين: CE (الإصدار المجتمعي المجاني) و EE (إصدار المؤسسات المدفوع)، وقد صرّح Gitlab رسميًا بأن هذه الثغرة تؤثر في الإصدارات التالية من CE و EE معًا:

  • >=10.6, <12.9.10
  • >=12.10, <12.10.11
  • >=13.0, <13.0.6

لكن هذا لا يعني أن كل Gitlab Docker Image لهذه الإصدارات يمكن استخدامها لبناء المختبر، وذلك للأسباب التالية:

  • إصدار CE من Mirror Repository يدعم اتجاه Push فقط
  • ينقسم إصدار EE إلى أربعة إصدارات: Core وStarter وPremium وUltimate. ومن جدول مقارنة الميزات الرسمي يتضح أن إصدار Core فقط لا يتضمن اتجاه Pull، بينما صور Docker الخاصة بـ Gitlab-EE توفر إصدار Core فقط

بعبارة أخرى، لبناء المختبر باستخدام Docker، لا بد من اختيار إصدار Gitlab-EE وتكسيره (أو يمكن لمن يملك المال شراء License) لتفعيل ميزة Mirror Repository - Pull.

ولكن حتى بعد تكسير Gitlab-EE، سواء كان الإصدار 10.x أو 12.x أو ، عندما يتضمن عنوان URL الخاص بـ Mirror Repository - Pull مسارًا محليًا، ستظهر رسالة الخطأ .

0x40 بناء المختبر

0x41 البناء

  • يجب أن يكون docker و docker-compose مثبتين مسبقًا على المضيف
  • استنساخ هذا المستودع: git clone https://github.com/lyy289065406/CVE-2020-13277
  • توليد زوج مفاتيح التكسير: ./keygen.sh أو ./keygen.ps1
  • بناء وتشغيل Gitlab (تأكد من أن المنفذ 80 غير مشغول): ./run.sh أو ./run.ps1
  • بعد حوالي 5 دقائق يمكن تسجيل الدخول إلى Gitlab من المتصفح: http://127.0.0.1 (عند أول تسجيل دخول يجب إعادة تعيين كلمة مرور حساب المدير root)

0x42 التكسير

عند توليد زوج مفاتيح التكسير سابقًا، تمت كتابة المفتاح العام في خلفية حاوية Gitlab، وما تبقى هو رفع المفتاح الخاص عبر الواجهة الأمامية إلى Gitlab لإتمام التكسير:

  • يتم توليد زوج المفاتيح في دليل ./gitlab/keys/، انسخ محتوى .gitlab-license (المفتاح الخاص)
  • باستخدام مستخدم root افتح الصفحة http://127.0.0.1/admin/license/new
  • اختر Enter license key وألصق المفتاح الخاص، ثم انقر على زر Upload license لإتمام التكسير

بهذا تكون ميزة Mirror Repository - Pull قد تم تفعيلها

0x43 إعدادات الاتصالات الصادرة

  • باستخدام مستخدم root افتح الصفحة http://127.0.0.1/admin/application_settings
  • ابحث عن Outbound requests في أسفل الصفحة وحدد خيار Allow requests to the local network from hooks and services ثم احفظ

بهذا أصبح Mirror Repository - Pull قادرًا على سحب Repository المحلية

0x44 إعداد Runner

  • باستخدام مستخدم root افتح الصفحة http://127.0.0.1/admin/runners
  • ابحث عن registration token وانسخه
  • سجّل Runner: ./register.sh $TOKEN أو ./register.ps1 $TOKEN

بهذا يمكن لجميع المستودعات استخدام هذا Runner لتنفيذ سكربتات CI (Pipeline Jobs)

0x50 التحقق من المختبر

يمكن الرجوع إلى Issue الرسمي أثناء التحقق، لكن عملية التحقق أدناه ستُعدّل بعض الخطوات لتناسب هذا المختبر

0x51 إنشاء حسابات التحقق مسبقًا

باستخدام مستخدم root افتح الصفحة http://127.0.0.1/admin/users لإنشاء 3 حسابات:

  • victim: حساب الضحية
  • attacker1: حساب المهاجم 1
  • attacker2: حساب المهاجم 2

عند إنشاء الحساب لا يمكن تعيين كلمة مرور أولية، إذ يقوم Gitlab افتراضيًا بإرسال كلمة المرور الأولية إلى البريد الإلكتروني المُعيّن. للتسهيل، يمكن إدخال أي بريد إلكتروني، وإنشاء الحساب أولًا، ثم تعديل الحساب فورًا؛ وعندها يمكن استخدام root لتعيين كلمة المرور الأولية لهذا الحساب دون الحاجة إلى البريد الإلكتروني

0x52 إنشاء مستودع الضحية مسبقًا

  • سجّل الدخول إلى Gitlab باستخدام حساب victim
  • أنشئ مستودعًا جديدًا New Project:
    • Name: target
    • Visibility Level: Private
  • أنشئ ملف README.md داخل المستودع، واضبط محتواه على mykey is abcxyz

من الواضح أن target هو المستودع الخاص للضحية victim، وهدفنا هو استغلال الثغرة للحصول على محتوى هذا المستودع

0x53 إنشاء مستودع poc للمهاجم

  • سجّل الدخول إلى Gitlab باستخدام حساب attacker1
  • أنشئ مستودعًا جديدًا New Project:
    • Name: poc
    • Visibility Level: Public
  • أنشئ ملف .gitlab-ci.yml داخل المستودع، ومحتواه كالتالي:
root@kitploit:~
image: "ruby:2.6"

rspec:  
  script:  
    - git clone http://gitlab-ci-token:[email protected]/victim/target.git
    - cd target
    - ls -lah .  
    - cat README.md

【الهدف】 في الخطوات التالية، سيتم استخدام بعض الأساليب لجعل victim ينفّذ سكربت CI هذا بصلاحياته دون علمه.

نظرًا لعدم إعداد شهادات في هذا المختبر، يمكن استخدام بروتوكول http فقط؛ و172.168.30.2 هو عنوان IP الذي يخصصه docker-compose.yml لحاوية Gitlab. ولأن سكربت CI هذا سيُنفَّذ في النهاية عبر Runner، وحاوية Runner في هذا المختبر ليست نفس حاوية Gitlab، لذا يجب استخدام عنوان IP الذي يخصصه Docker

0x53 إنشاء مستودع poc المتطابق للمهاجم

  • سجّل الدخول إلى Gitlab باستخدام حساب attacker2
  • أنشئ مجموعة جديدة New Group:
    • Name: test
    • Visibility Level: Public
  • أنشئ داخل مجموعة test مستودعًا فارغًا تمامًا New Project:
    • Name: poc
    • Visibility Level: Public

قم بتكوين المستودع المتطابق من خلال Settings => Repository => Pull from a remote repository:

  • Mirror repository: حدد الخيار
  • Git repository URL: أدخل http://GITLAB/attacker1/poc
  • Password: (اتركه فارغًا، فمستودع Pull بمستوى سرية Public ولا يتطلب كلمة مرور)
  • Trigger pipelines for mirror updates: حدد الخيار (لتشغيل سكربتات CI عند مزامنة المرآة)

بعد نجاح التكوين، يتم كل 30 دقيقة التحقق مما إذا كان المستودع المصدر قد تغيّر، وفي حال وجود تغيير تتم المزامنة القسرية.

Git repository URL يشير إلى مستودع poc الذي تم إنشاؤه سابقًا. والسبب في عدم استخدام 127.0.0.1 هو أن خاصية Pull تمنع سحب المستودعات المحلية، لكن يمكن تجاوز ذلك باستخدام DNS: GITLAB هو اسم المضيف (hostname) الذي يخصصه docker-compose.yml لحاوية Gitlab، ويتم تعيينه افتراضيًا في /etc/hosts. على الرغم من أن المضيف لا يمكنه تحليل GITLAB، إلا أنه داخل الحاوية يُعتبر الوصول إلى http://127.0.0.1/attacker1/poc

0x54 النقل القسري لملكية مستودع poc المتطابق إلى الضحية

  • استمر في استخدام حساب attacker2
  • افتح الصفحة http://127.0.0.1/groups/test/-/group_members لإدارة مستخدمي مجموعة test
  • أضف مستخدم victim إلى المجموعة:
    • Add new member to test: victim
    • Permissions: Owner
    • Expiration date: (اتركه فارغًا، أي دون انتهاء)
  • انقر على صورة الحساب في الزاوية العلوية اليمنى => Setting => Account => Delete account لحذف الحساب الحالي (attacker2)

【الهدف】 لا يوجد في مجموعة test سوى مالكَين اثنين: victim وattacker2. وعند حذف مستخدم attacker2، تنتقل ملكية مجموعة test وجميع المستودعات التابعة لها قسريًا إلى victim. وحاليًا يوجد في مجموعة test مستودع test/poc تتم مزامنته من attacker1/poc، أي أن ذلك يعادل نقل ملكية مستودع test/poc قسريًا إلى مستخدم victim.

0x55 شن الهجوم

دعنا نستعرض الوضع الحالي حتى الآن:

  • أنشأ المهاجم قسريًا وسرًا مستودع test/poc للضحية victim
  • محتوى مستودع test/poc تتم مزامنته من مستودع attacker1/poc (يتم التحقق كل 30 دقيقة من وجود تغييرات تستدعي المزامنة)
  • محتوى مستودع attacker1/poc يتحكم فيه المهاجم، بما في ذلك سكربت CI .gitlab-ci.yml
  • نظرًا لأن مستودع test/poc يمتلك إعداد Trigger pipelines for mirror updates، فسيتم تنفيذ سكربت CI عند كل مزامنة
  • نظرًا لأن Owner لمستودع test/poc هو victim، فسيتم تنفيذ سكربت CI بصلاحيات victim

بالعودة إلى محتوى سكربت CI .gitlab-ci.yml الذي تم تعيينه سابقًا، فإن هذا الـ poc يستخدم صلاحيات victim عبر Runner للوصول إلى بنية دليل المستودع الخاص target وملف README.md:

root@kitploit:~
image: "ruby:2.6"

rspec:  
  script:  
    - git clone http://gitlab-ci-token:[email protected]/victim/target.git
    - cd target
    - ls -lah .  
    - cat README.md

بعد ذلك، يحتاج المهاجم فقط إلى تعديل بعض المحتويات غير المهمة في مستودع attacker1/poc، وفي أسوأ الحالات عليه الانتظار 30 دقيقة فقط، ليتم تنفيذ سكربت CI المحدد بصلاحيات victim.

على الرغم من أن المهاجم لا يملك صلاحية مباشرة للوصول إلى نتائج تنفيذ Pipeline Jobs، إلا أنه يحتاج فقط إلى تعديل وجهة إخراج السكربت، مثل إرسال محتوى المستودع إلى بريد إلكتروني أو خادم FTP محدد، وبذلك يمكنه سرقة كود المستودع.

تنزيل الأداة
13.x
Import url is blocked: Requests to localhost are not allowed

على الرغم من أنه يمكن تكوين عنوان URL محلي بعد ضبط Allow requests to the local network from hooks and services من خلال Admin area => Settings => Network => Outbound requests، إلا أنه عند مزامنة المرآة تظهر رسالة الخطأ 2:Fetching remote upstream failed: fatal: unable to access http://127.0.0.1/xxxx/: The requested URL returned error: 301. بعبارة أخرى، فقط Pull Remote Repository هي المتاحة.

لكن لحسن الحظ، على الرغم من أن الإصدارين 12.x و 13.x صارمان جدًا في طريقة التحقق من عناوين URL المحلية، إلا أن الإصدار 10.x لديه حل: عند تكوين عنوان Pull URL، يكفي تكوين اسم خدمة DNS المحلي لتجاوز هذا الحظر.

مما سبق يتضح أن الخيار النهائي الوحيد هو بناء هذا المختبر باستخدام إصدار Docker Image gitlab-ee:10.6.0-ee.0.

في الواقع، من خلال ما سبق يمكن أيضًا إدراك أن شروط استغلال هذه الثغرة قاسية نسبيًا، وبشكل أساسي يصعب على الفقراء أن يتأثروا بهذه الثغرة