Файлы формата PDF используют практически все компании и правительственные учреждения. Нередко для обеспечения аутентичности документа в них применяются цифровые подписи. Группа исследователей из нескольких немецких университетов задалась вопросом, насколько надежно применение цифровой подписи защищает PDF-файлы от изменения его содержимого. Владислав Младенов из Рурского университета в Бохуме поделился находками группы на мероприятии Chaos Communication Congress (36С3).
Если подписанный файл открыть любой программой, созданной специально для просмотра PDF, то она покажет отметку, что файл подписан, укажет, кем именно, и откроет доступ к меню валидации подписи. Исследователи поставили себе задачу: взять подписанный PDF-документ (контракт, счет или какой-нибудь рецепт) и изменить его содержимое так, чтобы подпись оставалась валидной. Теоретически злоумышленники могут использовать такой трюк для того, чтобы подложить кому-нибудь ложную информацию или же добавить в файл вредоносный контент. Ведь на ссылку в документе, присланном и подписанном банком, клиенты с большой вероятностью кликнут не задумываясь.
Для проверки исследователи выбрали 22 популярные программы для просмотра PDF, разработанные для разных платформ, и методично скармливали им результаты своих экспериментов.
Структура PDF-файла
Для начала нужно сказать несколько слов о том, как устроен формат PDF. Файл состоит из четырех основных частей: заголовка (Header), где хранится версия PDF; основной части, где размещается контент, который видит пользователь (body); раздела Xref, представляющего собой каталог, в котором перечислены объекты внутри основного раздела и их местонахождение (он служит для корректного отображения контента); и трейлера (trailer) — раздела, с которого программы для чтения PDF начинают обработку документа. В трейлере находятся два важных параметра, сообщающих программе, с какого элемента следует начинать обработку файла, а также показывающих, где в файле начинается раздел Xref.
В формате реализована функция инкрементного обновления — именно она позволяет, например, выделять часть текста маркером и оставлять комментарии. С технической же точки зрения она добавляет еще три раздела: обновления для основной части, новый каталог Xref и новый трейлер. По сути, это позволяет изменять то, как объекты будут отображаться у пользователя. В том числе — добавлять новый контент. Фактически цифровая подпись — это тоже инкрементальное обновление, которое точно так же добавляет дополнительный элемент и соответствующие ему разделы в файл.
Атака типа «инкрементальное сохранение» (Incremental saving attack, ISA)
Первое, что исследователи попробовали, это просто добавить в файл при помощи текстового редактора дополнительные разделы с еще одним инкрементальным обновлением. По большому счету это даже нельзя назвать атакой — они просто использовали предусмотренную авторами формата функцию. При открытии такого файла обычно выводится сообщение, что цифровая подпись валидна, но документ был изменен. Надо сказать, утверждение не самое однозначное — неопытного пользователя оно вполне может смутить. Что еще хуже, одна из программ для просмотра PDF (LibreOffice) не показала и этого.
Следующим экспериментом стало удаление двух последних разделов (то есть обновление в основной раздел добавляется, а новые Xref и Trailer — нет). Некоторые приложения отказались работать с таким файлом. Две программы для просмотра PDF увидели, что разделов нет, и автоматически достроили их, не оповещая об изменении контента. Еще три без каких-либо возражений проглотили такой формат.
Далее исследователи задумались, а что будет, если цифровую подпись взять и просто-напросто скопировать в свое «ручное» обновление. На этом прокололись еще две программы — Foxit и MasterPDF.
Итого — 11 из 22 приложений для работы с PDF так или иначе оказались уязвимы к несложным манипуляциям с разделом. Причем в случае шести из них у пользователя, открывшего с их помощью документ, не было никаких шансов определить, что он был изменен. В остальных пяти случаях, чтобы увидеть факт манипуляции, пользователь должен был войти в меню и попробовать проверить валидность цифровой подписи, но при открытии файла никаких признаков изменения документа заметить также невозможно.
Атака типа «заворачивание подписи» (Signature wrapping attack, SWA)
Когда документ подписывают, в инкрементальном обновлении добавляются два важных поля: /Contents, где содержится собственно подпись, и /ByteRange, в котором описывается, что именно было подписано. В нем находятся четыре параметра, определяющих начало файла, количество байтов до кода подписи, байт, определяющий, где код подписи кончается, и количество байтов после нее. Дело в том, что цифровая подпись — это последовательность символов, получаемая криптографическими методами из кода PDF-документа. По объективным причинам она не может подписывать сама себя, поэтому область, где хранится подпись, исключается из вычислений.
Исследователи попробовали добавить еще одно поле /ByteRange сразу после подписи. Первые два значения в нем остаются неизменными, меняется только адрес конца кода подписи. В результате в файле появляется дополнительное пространство, в которое можно добавить какие-нибудь вредоносные объекты и описывающий их раздел XRef. По идее, если бы файл читался правильно, то до этого раздела программа бы просто не добралась. Однако 17 из 22 приложений оказались уязвимыми к такой атаке.
Универсальная подделка подписи (Universal signature forgery, USF)
Исследователи решили на всякий случай проверить приложения и при помощи стандартных пентестерских приемов — попробовать заменить значения разных полей на некорректные или просто удалить их. При экспериментах с разделом /contents выяснилось, что если вместо реальной подписи в нем будет значение 0x00, то две программы для просмотра все равно будут успешно валидировать ее.
А что будет, если оставить подпись на месте, но удалить информацию о том, что именно подписано (то есть раздел /ByteRange)? Или поставить в нем вместо реальных значений null? В обоих случаях нашлись приложения, которые валидировали такую подпись.
Итого, четыре программы из 22 имели ошибки в имплементации, которые можно эксплуатировать.
Если посмотреть на сводную таблицу по итогам исследования, то видно, что так или иначе удается обмануть 21 из 22 программ для просмотра PDF. То есть при необходимости почти под каждую из них можно сделать PDF-файл с вредоносным контентом или ложной информацией, но в глазах пользователя он останется подписанным автором.
Забавно, что единственное приложение, не поддавшееся ни на одну из уловок исследователей, это Adobe Reader 9. Проблема в том, что он подвержен RCE-уязвимости, а потому он стоит только у пользователей Linux — просто потому, что это последняя доступная для них версия.
Практические выводы
Какой практический вывод можно сделать из этого? Во-первых, что не стоит слепо доверять цифровой подписи PDF-файла. Если где-то рисуют зеленую галочку, это не значит, что подпись действительно валидна.
Во-вторых, даже подписанный документ может представлять опасность. Так что прежде чем открывать любые файлы, полученные из Интернета, и переходить по ссылкам из них, следует убедиться, что у вас на компьютере стоит надежное защитное решение.