
PoC para Foxit Reader CVE-2018-14442
PDF es un formato de archivo utilizado para representar documentos. Un PDF se compone de múltiples objetos de datos.
Objetos primitivos simples Entero, Número, Booleano, Nulo
Objetos complejos
| Formato | Nombre |
|---|---|
| [.*] | Array |
| (.*) | Cadena |
| <<.*>> | Diccionario |
| <.*> | Cadena hexadecimal |
| /.* | Nombre |
| stream...endstream | Flujo |
Estos objetos definen cómo se ve un PDF y qué contiene. Las estructuras en un PDF se presentan en 2 tipos de objetos: directos e indirectos. Un objeto indirecto comienza con el número de objeto y el número de generación, seguidos del objeto real. Los objetos indirectos pueden ser referenciados directamente en otros objetos como n m R, donde n y m son los números de objeto y generación respectivamente.
Los objetos diccionario son los componentes básicos del documento. Existen algunos objetos diccionario generales que son necesarios para formar una página o el propio documento. El más importante es el diccionario Root, que define enlaces a todos los demás objetos como Pages, Metadata, Names, etc., cada uno de los cuales puede ser otro objeto.
Los objetos de flujo contienen la mayor parte de los datos binarios, como fuentes, imágenes o datos comprimidos/cifrados.
Un documento PDF puede cifrarse para proteger su contenido del acceso no autorizado. El cifrado se aplica a todas las cadenas y flujos en el archivo PDF del documento, con algunas excepciones como el propio diccionario Encrypt. El cifrado se aplica principalmente a objetos de flujo. No se aplica a otros tipos de objetos como enteros y valores booleanos, que se utilizan principalmente para transmitir información sobre la estructura del documento mas que su contenido.
La información relacionada con el cifrado debe almacenarse en el diccionario de cifrado del documento, que será el valor de la entrada "Encrypt" en el diccionario de trailer del documento.
CPDF_Parser::StartParse establece m_pCryptoHandler para objetos indirectos de un PDF que están cifrados. m_pCryptoHandler debería anularse cuando CPDF_Parser::ReleaseEncryptHandler se completa. En cambio, CPDF_Parser::ReleaseEncryptHandler no elimina la referencia a CryptoHandler en CPDF_Parser y queda colgante.
Más tarde, cuando el analizador comienza a analizar los objetos referenciados en el diccionario Root, se llama a m_pCryptoHandler+8 para descifrar los datos.
Un error similar fue corregido en pdfium en el commit 741c362fb75fd8acd2ed2059c6e3e716a63a7ac8. Ver https://bugs.chromium.org/p/chromium/issues/detail?id=726503
Los PDF permiten incrustar JS en el documento, que puede ejecutarse automáticamente si se ingresa en OpenAction de un diccionario de tipo Catalog. Una vez que tenemos ejecución de JS, podemos pulverizar objetos en el espacio del proceso para llegar a una dirección predecible donde escribiremos nuestra cadena ROP.
Cuando un documento PDF está firmado en Foxit Reader, utiliza plugins\jrsys\x86\jrsysMSCryptoDll.dll del directorio de instalación para leer la información firmada, lo que carga jrsysCryptoDll.dll en una dirección estática de 0x10000000. Este dll importa VirtualAlloc, lo que facilita la ejecución del payload. El exploit adjunto utiliza heap spraying para obtener un diseño de memoria predecible y utiliza una cadena ROP para asignar una página RWX, copiar y ejecutar el payload.
Este exploit fue probado usando Foxit Reader 9.0.1.1049 x86 ejecutándose en MS Windows 7 Enterprise Build 7601 SP1 x86. El exploit requiere que el heap esté en un estado específico; si falla, intente de nuevo. Consulte la demostración en video. Esta vulnerabilidad también está presente en Foxit PDF Reader y Converter para Android.
bitcoins.pdf es el PDF manipulado que realiza la reasignación de la memoria liberada y desencadena el error principal. Si desea reproducir el crash en el depurador, habilite Page Heaps para FoxitReader.exe y abra bitcoins.pdf.
Este crash fue encontrado por Cloudfuzz - Una plataforma de fuzzing desarrollada en Payatu. El análisis y la explotación adicional fueron realizados por Sudhakar