
폴리글롯 파일을 이용한 CVE-2025-64512 개념 증명(PoC)
지난 몇 주(2025년 11월) 동안 PDF 파일을 처리하는 인기 있는 Python 프로젝트인 pdfminer.six에서 흥미로운 취약점(CVE-2025-64512)이 공개되었습니다. 특히 AI 파이프라인에서 사용됩니다. 이 취약점은 PDF 파일을 공격 벡터로 활용하여 pickle.loads()를 통해 신뢰할 수 없는 데이터를 역직렬화함으로써 원격 코드 실행을 가능하게 합니다. 여기까지는 좋습니다. 인기 있는 Python 패키지의 중요한 취약점입니다. 제 관심을 끈 것은 악용 가능성이었습니다 👀.
Linux 계열 시스템에서는 파일시스템에 있는 파일만 확인할 수 있습니다. 공격자는 악성 PDF를 처리용으로 제공해야 하며, 악성 pickle 파일은 PDF 자체에 설정해야 하므로 공격자가 이미 알고 있는 대상 시스템의 위치에 존재해야 합니다. 많은 경우 공격자가 PDF와 pickle 파일을 함께 제공하더라도 지정할 pickle 파일의 전체 경로를 미리 알 방법이 없기 때문에 악용하기 어렵습니다. [...] 전반적으로 Linux 또는 Linux 계열 시스템에서는 일반적으로 위험이 더 적습니다.
따라서 Linux 계열 시스템에서 이 취약점을 악용하려면 공격자는 다음을 수행해야 합니다:
악성 pickle 파일의 파일 경로를 모르는 채로 취약점을 트리거하는 유효한 PDF 파일을 만들 수 있을까요?
"유효한"이란 pdfminer.six가 파일을 거부하지 않고 처리를 시작한다는 의미입니다(PDF 파일은 PDF 리더가 여는 파일이기 때문입니다).
대답은 그렇다입니다. 일종의 폴리글롯 페이로드를 만드는 것입니다. 아이디어는 유효한 pickle.gz이자 유효한 PDF 파일인 파일을 만들어 pdf2txt.py가 PDF 파일 처리를 시작한 다음, 해당 파일을 가리켜 GZIP 형식의 pickle 코드를 로드하게 하는 것입니다.
종종 - 항상은 아니지만 🥲 - 파일에 %PDF-가 어딘가 있으면 PDF 파일이며, 일반적으로 처음 1024바이트 안에 있습니다 (1 - ). 의 경우 유효한 PDF 파일에는 객체만 있으면 됩니다 ().
pdfminer.six/RootGZIP 파일에는 특정 초기 바이트가 있지만 (RFC 1952 - Sec. 2.3.1), 주석(FCOMMENT, RFC 1952 - Sec. 2.3.1)을 지원합니다.
따라서 폴리글롯 파일 설계는 다음과 같습니다: 악성 pickle 페이로드를 포함하는 유효한 GZIP을 만들고, GZIP FCOMMENT 플래그에 유효한 PDF 파일을 삽입합니다. 그런 다음 이 파일을 pdf2txt.py로 유효한 PDF로 사용하여 취약점을 트리거하고, 동일한 파일을 사용하여 악성 pickle을 실행합니다.
(2025.12.12) 수정:
우리가 가진 유일한 제약은 파일 이름입니다: .pickle.gz로 끝나야 합니다 (.pdfminer.six 코드에 내장되어 있습니다, cmapdb.py#L235)
우리가 가진 두 가지 제약은 다음과 같습니다:
pdfminer.six 코드에 내장되어 있습니다, cmapdb.py#L235);이 프로젝트의 인기(GitHub에서 6k ⭐️, GitHub 통계에 따르면 34k 프로젝트가 사용)와 사용 사례(명령줄 도구, AI 워크플로, 파이프라인, 요컨대 제대로 작동한다면 업데이트하고 싶지 않은 모든 종류의 인프라)를 고려할 때 이 CVE가 이렇게 과소평가된 것이 조금 놀랍습니다.
예를 들어, 12월 1일 이전에 설치된 Microsoft 도구 markitdown 0.1.3 (microsoft/markitdown, GitHub에서 84k ⭐️, 2k 프로젝트에서 사용)은 pdfminer.six를 통한 임의 코드 실행에 취약합니다. Microsoft 팀은 12월 1일에 0.1.4 패치를 출시했지만 보안 경고는 없었기 때문에 다른 엔지니어링 팀이 업데이트를 우선시하지 않은 것 같습니다.
다른 프로젝트도 CVE-2025-64512의 영향을 받을 수 있으며, 악용이 매우 쉽습니다.
취약한 프로젝트의 (불완전한) 목록:
docker build -t cve-2025-64512-poc .
docker run --rm -it cve-2025-64512-poc
pdf2txt.py payload.pickle.gz
docker build -t cve-2025-64512-poc .
docker run --rm -it cve-2025-64512-poc
markitdown markitdown-payload.pickle.gz -x pdf -o output.md
