
Una prueba de concepto para CVE-2025-64512 mediante un archivo políglota.
En las últimas semanas (en noviembre de 2025), se reveló una vulnerabilidad interesante (CVE-2025-64512) en pdfminer.six, un popular proyecto de Python para procesar archivos PDF, utilizado en particular en pipelines de IA. La vulnerabilidad permite la ejecución remota de código al deserializar datos no confiables mediante pickle.loads(), utilizando un archivo PDF como vector de ataque. Hasta aquí, todo bien: es una vulnerabilidad importante en un paquete de Python popular. Lo que me llamó la atención fue la explotabilidad 👀.
En sistemas tipo Linux, solo se pueden resolver archivos del sistema de archivos. Un atacante tendría que proporcionar el PDF malicioso para su procesamiento y el archivo pickle malicioso tendría que estar presente en el sistema objetivo en una ubicación que el atacante ya conozca, ya que debe especificarse en el propio PDF. En muchos casos, esto será difícil de explotar porque incluso si el atacante proporciona tanto el PDF como el archivo pickle juntos, no habría forma de saber de antemano qué ruta completa al archivo pickle especificar. [...] En general, suele haber menos riesgo en un sistema Linux o similar a Linux.
Entonces, aparentemente, para explotar esta vulnerabilidad en un sistema tipo Linux, el atacante debería:
¿Podemos crear un archivo PDF válido que active la vulnerabilidad sin conocer la ruta del archivo pickle malicioso?
"Válido" significa que pdfminer.six no rechaza el archivo y comienza a procesarlo (porque un archivo PDF es lo que abre un lector de PDF).
La respuesta es Sí, creando una carga útil políglota (una especie de). La idea es crear un archivo que sea a la vez un pickle.gz válido y un archivo PDF válido, de modo que pdf2txt.py pueda comenzar a procesar un archivo PDF y luego apuntar a él para cargar el código pickle en formato GZIP.
A menudo, pero no siempre 🥲, un archivo es un PDF si tiene %PDF- en algún lugar, generalmente en los primeros 1024 bytes (1 - 2). Para pdfminer.six, un archivo PDF válido solo necesita tener un objeto /Root (pdfdocument.py#L752).
Un archivo GZIP tiene bytes iniciales específicos (RFC 1952 - Sec. 2.3.1), pero admite comentarios (FCOMMENT, RFC 1952 - Sec. 2.3.1).
Entonces, este es el diseño del archivo políglota: crear un GZIP válido que contenga la carga útil pickle maliciosa e incrustar un archivo PDF válido en el indicador FCOMMENT del GZIP. Luego, usar este archivo como PDF válido con pdf2txt.py para activar la vulnerabilidad, y usar el mismo archivo para ejecutar el pickle malicioso.
(2025.12.12) EDICIÓN:
La única restricción que tenemos es el nombre de archivo: debe terminar en .pickle.gz (esto está incrustado en el código de .pdfminer.six, cmapdb.py#L235)
Las dos restricciones que tenemos son:
pdfminer.six, cmapdb.py#L235);Me sorprende un poco que este CVE esté tan subestimado, considerando la popularidad de este proyecto (6k ⭐️ en GitHub, pero utilizado por 34k proyectos, según las estadísticas de GitHub) y los casos de uso (herramientas de línea de comandos, flujos de trabajo de IA, pipelines, en resumen, todo el tipo de infraestructura que no quieres actualizar si funciona bien).
Por ejemplo, la herramienta de Microsoft markitdown 0.1.3 (microsoft/markitdown, 84k ⭐️ en GitHub y utilizada por 2k proyectos), instalada antes del 1 de diciembre, es vulnerable a la ejecución arbitraria de código a través de pdfminer.six. El equipo de Microsoft lanzó un parche el 1 de diciembre, 0.1.4, pero no hubo alertas de seguridad, así que no creo que otros equipos de ingeniería hayan priorizado la actualización.
Otros proyectos podrían verse afectados por CVE-2025-64512, y es bastante fácil de explotar.
Una lista (incompleta) de proyectos vulnerables:
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
