
مختبر CVE-2020-13277: ثغرة منطقية في GitLab - وصول غير مصرح به لأي مستخدم إلى المستودعات الخاصة
مختبر CVE-2020-13277: ثغرة منطقية في Gitlab - وصول غير مصرح به لأي مستخدم إلى مستودع خاص
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 靶场]
يعتمد جوهر هذه الثغرة بشكل أساسي على استخدام Mirror Repository - وظيفة النسخ الاحتياطي لمزامنة المستودعات المتطابقة.
ينقسم اتجاه مزامنة Mirror إلى نوعين:
تستغل هذه الثغرة اتجاه 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 لهذه الإصدارات يمكن استخدامها لبناء المختبر، وذلك للأسباب التالية:
بعبارة أخرى، لبناء المختبر باستخدام Docker، لا بد من اختيار إصدار Gitlab-EE وتكسيره (أو يمكن لمن يملك المال شراء License) لتفعيل ميزة Mirror Repository - Pull.
ولكن حتى بعد تكسير Gitlab-EE، سواء كان الإصدار 10.x أو 12.x أو 13.x، عندما يتضمن عنوان URL الخاص بـ Mirror Repository - Pull مسارًا محليًا، ستظهر رسالة الخطأ 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.
في الواقع، من خلال ما سبق يمكن أيضًا إدراك أن شروط استغلال هذه الثغرة قاسية نسبيًا، وبشكل أساسي يصعب على الفقراء أن يتأثروا بهذه الثغرة
./keygen.sh أو ./keygen.ps1./run.sh أو ./run.ps1عند توليد زوج مفاتيح التكسير سابقًا، تمت كتابة المفتاح العام في خلفية حاوية Gitlab، وما تبقى هو رفع المفتاح الخاص عبر الواجهة الأمامية إلى Gitlab لإتمام التكسير:
./gitlab/keys/، انسخ محتوى .gitlab-license (المفتاح الخاص)Enter license key وألصق المفتاح الخاص، ثم انقر على زر Upload license لإتمام التكسيربهذا تكون ميزة Mirror Repository - Pull قد تم تفعيلها

Outbound requests في أسفل الصفحة وحدد خيار Allow requests to the local network from hooks and services ثم احفظبهذا أصبح Mirror Repository - Pull قادرًا على سحب Repository المحلية

./register.sh $TOKEN أو ./register.ps1 $TOKENبهذا يمكن لجميع المستودعات استخدام هذا Runner لتنفيذ سكربتات CI (Pipeline Jobs)

يمكن الرجوع إلى Issue الرسمي أثناء التحقق، لكن عملية التحقق أدناه ستُعدّل بعض الخطوات لتناسب هذا المختبر
باستخدام مستخدم root افتح الصفحة http://127.0.0.1/admin/users لإنشاء 3 حسابات:
victim: حساب الضحيةattacker1: حساب المهاجم 1attacker2: حساب المهاجم 2عند إنشاء الحساب لا يمكن تعيين كلمة مرور أولية، إذ يقوم Gitlab افتراضيًا بإرسال كلمة المرور الأولية إلى البريد الإلكتروني المُعيّن. للتسهيل، يمكن إدخال أي بريد إلكتروني، وإنشاء الحساب أولًا، ثم تعديل الحساب فورًا؛ وعندها يمكن استخدام root لتعيين كلمة المرور الأولية لهذا الحساب دون الحاجة إلى البريد الإلكتروني
