
Доказательство концепции для CVE-2025-64512 с использованием полиглот-файла.
За последние недели (в ноябре 2025 года) была раскрыта интересная уязвимость (CVE-2025-64512) в pdfminer.six, популярном Python-проекте для обработки PDF-файлов, который используется, в частности, в AI-пайплайнах. Уязвимость позволяет удалённо выполнять код путём десериализации недоверенных данных через pickle.loads(), используя PDF-файл как вектор атаки. Пока всё хорошо: это важная уязвимость в популярном пакете Python. Моё внимание привлекла её эксплуатабельность 👀.
В системах, подобных Linux, могут быть разрешены только файлы, находящиеся в файловой системе. Злоумышленнику необходимо предоставить вредоносный PDF-файл для обработки, а вредоносный pickle-файл должен присутствовать в целевой системе в месте, которое злоумышленник уже знает, поскольку его нужно указать в самом PDF. Во многих случаях это будет сложно эксплуатировать, потому что даже если злоумышленник предоставляет и PDF, и pickle-файл вместе, нет способа заранее узнать полный путь к pickle-файлу. [...] В целом, на Linux или подобных Linux системах риск обычно ниже.
Итак, для эксплуатации этой уязвимости на системе, подобной Linux, злоумышленнику необходимо:
Можем ли мы создать корректный PDF-файл, который инициирует уязвимость, не зная пути к вредоносному pickle-файлу?
«Корректный» означает, что pdfminer.six не отвергает файл и начинает его обрабатывать (потому что PDF-файл — это то, что открывает программа для просмотра PDF).
Ответ — Да, создав полиглот-пейлоад (своего рода). Идея заключается в том, чтобы создать файл, который одновременно является корректным pickle.gz и корректным PDF-файлом, чтобы pdf2txt.py мог начать обработку PDF-файла, а затем указать на него для загрузки pickle-кода в формате GZIP.
Часто — но не всегда 🥲 — файл является PDF-файлом, если он содержит %PDF- где-то, как правило, в первых 1024 байтах (1 — 2). Для pdfminer.six корректный PDF-файл должен просто иметь объект /Root (pdfdocument.py#L752).
Файл GZIP имеет определённые начальные байты (RFC 1952 — Sec. 2.3.1), но он поддерживает комментарии (FCOMMENT, RFC 1952 — Sec. 2.3.1).
Итак, вот дизайн полиглот-файла: создайте корректный GZIP, содержащий вредоносную pickle-полезную нагрузку, и встройте в него корректный PDF-файл через флаг FCOMMENT в GZIP. Затем используйте этот файл как корректный PDF с помощью pdf2txt.py, чтобы инициировать уязвимость, и используйте тот же файл для выполнения вредоносного pickle.
(2025.12.12) РЕДАКТИРОВАНИЕ:
Единственное ограничение, которое у нас есть, — это имя файла: оно должно заканчиваться на .pickle.gz (это заложено в коде .pdfminer.six, cmapdb.py#L235)
У нас есть два ограничения:
pdfminer.six, cmapdb.py#L235);Я немного удивлён, что этот CVE так недооценён, учитывая популярность этого проекта (6k ⭐️ на GitHub, но используется 34k проектами, согласно статистике GitHub) и сценарии использования (инструменты командной строки, AI-рабочие процессы, пайплайны — в общем, все виды инфраструктуры, которую не хочется обновлять, если она работает исправно).
Например, инструмент Microsoft markitdown 0.1.3 (microsoft/markitdown, 84k ⭐️ на GitHub и используется 2k проектами), установленный до 1 декабря, уязвим к произвольному выполнению кода через pdfminer.six. Команда Microsoft выпустила патч 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
