
PoC for Foxit Reader CVE-2018-14442
PDF — это формат файла, используемый для представления документов. PDF состоит из множества объектов данных.
Простые примитивные объекты: Целое число, Число, Булево, Null
Сложные объекты
| Формат | Название |
|---|---|
| [.*] | Массив |
| (.*) | Строка |
| <<.*>> | Словарь |
| <.*> | Шестнадцатеричная строка |
| /.* | Имя |
| stream...endstream | Поток |
Эти объекты определяют внешний вид PDF и его содержимое. Структуры в PDF представлены двумя типами объектов — прямыми и косвенными. Косвенный объект начинается с номера объекта и номера поколения, за которыми следует сам объект. Косвенные объекты могут быть напрямую ссылаться из других объектов в формате n m R, где n и m — номера объекта и поколения соответственно.
Словари являются основными строительными блоками документа. Некоторые общие объекты-словари необходимы для формирования страницы или самого документа. Важнейшим является словарь Root, который определяет ссылки на все остальные Pages, Metadata, Names и т.д., каждый из которых может быть другим объектом.
Объекты-потоки содержат большие объёмы двоичных данных, такие как шрифты, изображения или сжатые/зашифрованные данные.
PDF-документ может быть зашифрован для защиты содержимого от несанкционированного доступа. Шифрование применяется ко всем строкам и потокам в PDF-файле документа, за некоторыми исключениями, такими как сам словарь Encrypt. Шифрование в основном применяется к объектам-потокам. Оно не применяется к другим типам объектов, таким как целые числа и булевы значения, которые в основном используются для передачи информации о структуре документа, а не о его содержимом.
Информация, связанная с шифрованием, должна храниться в словаре шифрования документа, который является значением записи "Encrypt" в словаре трейлера документа.
CPDF_Parser::StartParse устанавливает m_pCryptoHandler для косвенных объектов PDF, которые зашифрованы. m_pCryptoHandler должен быть обнулён после завершения CPDF_Parser::ReleaseEncryptHandler. Вместо этого CPDF_Parser::ReleaseEncryptHandler не удаляет ссылку на CryptoHandler в CPDF_Parser, и она остаётся висячей.
Позже, когда парсер начинает разбор объектов, на которые ссылается словарь Root, вызывается m_pCryptoHandler+8 для расшифровки данных.
Аналогичная ошибка была исправлена в pdfium в коммите 741c362fb75fd8acd2ed2059c6e3e716a63a7ac8. См. https://bugs.chromium.org/p/chromium/issues/detail?id=726503
PDF позволяют встраивать JS в документ, который может быть выполнен автоматически, если он указан в OpenAction словаря типа Catalog. После получения возможности выполнения JS мы можем распылять объекты в адресном пространстве процесса, чтобы получить предсказуемый адрес, куда запишем ROP-цепочку.
Когда PDF-документ подписан в Foxit Reader, для чтения подписанной информации используется plugins\jrsys\x86\jrsysMSCryptoDll.dll из каталога установки, что загружает jrsysCryptoDll.dll по статическому адресу 0x10000000. Эта DLL импортирует VirtualAlloc, что упрощает выполнение полезной нагрузки. Прилагаемый эксплойт использует распыление кучи для получения предсказуемого расположения памяти и использует ROP-цепочку для выделения RWX-страницы, копирования и выполнения полезной нагрузки.
Этот эксплойт был протестирован с Foxit Reader 9.0.1.1049 x86 на MS Windows 7 Enterprise Build 7601 SP1 x86. Эксплойт требует определённого состояния кучи; если эксплойт не срабатывает, повторите попытку. Пожалуйста, обратитесь к видеодемонстрации. Эта уязвимость также присутствует в Foxit PDF Reader and Converter для Android.
bitcoins.pdf — это специально созданный PDF-файл, который выполняет перераспределение освобождённой памяти и вызывает основную ошибку. Если вы хотите воспроизвести сбой в отладчике, включите Page Heaps для FoxitReader.exe и откройте bitcoins.pdf.
Этот сбой был обнаружен Cloudfuzz — платформой для фаззинга, разработанной в Payatu. Дальнейший анализ и эксплуатацию выполнил Sudhakar.