PDFiD: возможности, ограничения и безопасное применение для анализа PDF
PDFiD — не просмотрщик и не редактор PDF, а компактный Python-скрипт Didier Stevens для первичного статического триажа документов. Он не пытается полноценно разобрать структуру файла: вместо этого быстро считает характерные PDF-имена и служебные маркеры, по которым аналитик решает, требуется ли более глубокая проверка. Такой подход особенно полезен перед открытием неизвестного вложения, при сортировке коллекции образцов и в учебной лаборатории по анализу вредоносных документов. Актуальная официальная версия на дату подготовки обзора — 0.2.10; она выпущена в марте 2025 года и остаётся последней найденной версией в официальном репозитории и на странице автора.
| Параметр | Состояние |
|---|---|
| Официальное название | PDFiD, файл pdfid.py |
| Разработчик | Didier Stevens |
| Назначение | Первичный статический анализ и триаж PDF по ключевым признакам |
| Актуальная версия | 0.2.10, март 2025 года |
| Тип | Консольный Python-скрипт, без графического интерфейса |
| Платформы | Системы с совместимым Python; отдельной официальной матрицы ОС нет |
| Лицензирование | Исходный код помещён автором в public domain; платной редакции нет |
| Основной ввод | PDF, ZIP-архив с образцом, URL, список файлов, каталог |
| Основной вывод | Текст в консоли или журнале; CSV для сценариев с плагинами |
| Облачная обработка | Не требуется; локальные файлы анализируются локально |
Скачать PDFid
Новейшая версия для Виндовс, macOS и Линукс. Удобный редактор PDF под российские реалии.
Для оригинальной PDFiD безопаснее ориентироваться на два источника самого автора: страницу PDF Tools в блоге Didier Stevens и репозиторий DidierStevensSuite. На странице PDF Tools опубликован архив pdfid_v0_2_10.zip, а рядом указан контрольный SHA-256 A677336B1CF51386E35DBDED8FDB79F27368FD5D5ECC3FC5C8DA020A029CB6B6. В репозитории лежит актуальный исходный файл pdfid.py с тем же номером версии 0.2.10 и датой исходника 5 марта 2025 года. Такой способ получения позволяет одновременно проверить происхождение файла и сверить, что загружена именно оригинальная реализация.
Следует различать официальную PDFiD и пакет с похожим названием в PyPI. Проект pdfid на PyPI прямо описывает себя как клон инструмента Didier Stevens, адаптированный другими сопровождающими для публикации как Python-библиотеки. У него собственная нумерация выпусков, другая лицензия и иные сопровождающие. Установка команды pip install pdfid поэтому не равнозначна загрузке актуального pdfid.py от Didier Stevens. Для обзора и команд далее подразумевается оригинальная PDFiD.
Что такое PDFid
Официальное написание продукта — PDFiD. Это небольшой инструмент статического анализа PDF, появившийся у Didier Stevens в 2009 году. Его задача — не доказать, что документ вредоносный, а дать первичную картину: есть ли в файле JavaScript, автоматические действия, запуск внешнего содержимого, вложенные файлы, формы, шифрование, объектные потоки и другие признаки, которые меняют приоритет дальнейшего исследования. Автор отдельно подчёркивал роль PDFiD как инструмента triage, а не антивирусного детектора.
Принцип работы намеренно проще полноценного PDF-парсера. Скрипт проходит по содержимому, распознаёт PDF-заголовок, считает набор ключевых слов и показывает число найденных вхождений. Он также умеет учитывать имена, обфусцированные шестнадцатеричными кодами вида #xx. Это полезно против простого сокрытия опасных имён, однако сам подход по-прежнему не превращает PDFiD в интерпретатор структуры документа.
На 12 сентября 2026 года версия 0.2.10 остаётся актуальной в официальных источниках. Это не снятый с поддержки продукт: релиз 0.2.10 был опубликован как исправление ошибки, а в январском обзоре материалов автора за 2025 год обновление PDFiD по-прежнему перечислено среди выпущенного ПО. При этом темп развития осторожный: инструмент зрелый, интерфейс командной строки меняется редко, а крупные функции чаще вынесены в соседние инструменты и плагины.
Основные функции PDFid
Подсчёт структурных и потенциально опасных ключевых слов
Базовый запуск показывает PDF-заголовок и счётчики obj, endobj, stream, endstream, xref, trailer и startxref, а также набор PDF-имён. В текущем исходнике среди стандартных имён присутствуют /Page, /Encrypt, /ObjStm, /JS, /JavaScript, /AA, /OpenAction, /AcroForm, /JBIG2Decode, /RichMedia, /Launch, /EmbeddedFile и /XFA. Отдельно учитывается аномалия /Colors с чрезмерно большим числовым значением, исторически связанная с CVE-2009-3459.
Смысл счётчиков контекстный. Наличие /JS или /JavaScript говорит о присутствии JavaScript-обозначений, /OpenAction и /AA — об автоматических или дополнительных действиях, /Launch — о механизме запуска, /EmbeddedFile — о вложенном файле, /AcroForm и /XFA — о формах, /Encrypt — о шифровании, /ObjStm — об объектных потоках. Ни один отдельный ненулевой счётчик не является доказательством заражения. Например, интерактивная форма может быть полностью легитимной, а короткое имя /JS способно случайно встретиться внутри потока.
Распознавание обфускации имён
PDF допускает шестнадцатеричное кодирование символов внутри name-объектов. PDFiD декодирует такие последовательности при подсчёте и показывает дополнительное число обфусцированных вхождений в скобках. Для первичного анализа это важно: простая замена буквы в /JavaScript на код #xx не должна скрыть имя от счётчика. Отдельный plugin_nameobfuscation превращает сам факт такой маскировки в оценку, пригодную для пакетного triage.
Дополнительные данные: даты, энтропия и конец файла
Опция -e включает расширенный сбор данных. Скрипт ищет строки PDF-дат, рассчитывает энтропию для всего файла, отдельно для байтов внутри и вне потоков, считает маркеры %%EOF и число символов после последнего %%EOF. Эти признаки полезны как ориентир: необычное количество хвостовых данных, несколько завершений файла или резкое различие энтропии между потоками и остальным содержимым могут стать поводом перейти к объектному анализу. PDFiD не объясняет причину автоматически и не заменяет разбор конкретных объектов.
Пакетная обработка и фильтрация результатов
Скрипт принимает один или несколько файлов, шаблоны имён и файл-список через синтаксис @file. Опция —recursedir рекурсивно разворачивает каталоги и шаблоны, а -s запускает сканирование указанного каталога через встроенную рекурсивную функцию. В режиме scan вывод дополнительно записывается в PDFiD.log, если не переопределён другой файл через -o. Опция -n скрывает нулевые счётчики и делает большие отчёты короче.
Механизм -S позволяет вывести только объекты, удовлетворяющие Python-выражению отбора по данным PDFiD. Это мощный, но технический режим: выражение вычисляется через eval. Поэтому строку для -S нельзя бездумно копировать из недоверенного источника. То же правило относится к плагинам: PDFiD загружает их как Python-код, следовательно сторонний плагин обладает возможностями обычного локального скрипта.
Плагины triage
Официальный plugin_triage.py присваивает образцу упрощённый балл. Наличие одного из ряда признаков, включая /JS, /JavaScript, /AA, /OpenAction, /AcroForm, /JBIG2Decode, /RichMedia, /Launch, /EmbeddedFile, /XFA или аномалию /Colors, приводит к максимальной оценке 1.0 и рекомендации дальнейшего анализа. /ObjStm даёт 0.75, /URI — 0.6, а несоответствие obj/endobj или stream/endstream — 0.5. Этот балл предназначен для сортировки очереди, а не для вердикта «вредоносный/безопасный».
plugin_embeddedfile ориентирован на вложения, а plugin_nameobfuscation — на скрытые имена. Плагины можно перечислять через запятую или передавать списком. При работе с плагинами доступен CSV-вывод; параметр -m задаёт минимальный балл, который попадёт в результат. Такой режим удобен для большого набора вложений, когда аналитик хочет сначала отобрать файлы с наиболее заметными признаками.
Работа с ZIP и удалённым вводом
PDFiD умеет читать ZIP-файл как контейнер образца и открывает первый элемент архива с паролем infected — распространённой практикой обмена вредоносными образцами. Начиная с 0.2.9 код пытается использовать pyzipper, если модуль установлен, что расширяет совместимость с современными ZIP-вариантами. Кроме локального пути можно передать HTTP- или HTTPS-адрес: содержимое будет запрошено самим скриптом. Для изолированной лаборатории удалённый режим следует использовать осознанно, поскольку он создаёт сетевое соединение с указанным сервером.
Режим disarm
Опция -d создаёт новый файл с суффиксом .disarmed перед исходным расширением. При проходе по содержимому PDFiD меняет регистр букв в ряде опасных PDF-имён, включая /JS, /JavaScript, /AA, /OpenAction, /JBIG2Decode, /RichMedia и /Launch. Поскольку PDF-имена чувствительны к регистру, такое изменение мешает обработчику распознать эти имена в обычном виде. Исходный файл при этом не перезаписывается.
Disarm нельзя считать универсальной очисткой PDF. В список замены не входят все возможные активные или нежелательные конструкции, а сам PDFiD не делает полного семантического анализа. Полученная копия полезна для лабораторной работы или снижения риска отдельных механизмов, но не превращается автоматически в доверенный документ.
Паспорт обратимости операций
| Операция | Что меняется | Как вернуться |
|---|---|---|
| Обычный анализ | Исходный PDF только читается | Ничего восстанавливать не нужно |
| -e, -a, -n | Меняется только объём отчёта | Повторить запуск с другими опциями |
| -o или -s | Создаётся или дополняется файл журнала | Удалить журнал; PDF не изменён |
| Плагин | Сам PDF не меняется, но исполняется Python-код плагина | Удалить плагин и повторить анализ доверенным набором |
| -d | Создаётся отдельная изменённая копия .disarmed.pdf | Сохранить и использовать оригинал как эталон |
Интерфейс и удобство использования
У PDFiD нет окон, панели инструментов и встроенного просмотрщика. Рабочая зона — терминал. Базовый сценарий укладывается в одну команду: python pdfid.py document.pdf. Вывод компактный и хорошо читается построчно: слева имя признака, справа число вхождений. Для специалиста такой формат быстрее графического интерфейса, особенно при автоматизации. Для пользователя, привыкшего к кликам и визуальному просмотру страниц, порог входа заметно выше.
Логика навигации строится вокруг небольшого набора ключей командной строки. -e добавляет расширенную статистику, -a показывает все встреченные PDF-имена, -n убирает нулевые строки, -p подключает плагины, -c включает CSV в плагинных сценариях, -o задаёт журнал, -s и —recursedir отвечают за каталоги. Справка встроена в optparse, поэтому перечень действующих параметров можно получить непосредственно из используемой версии скрипта.
Поддерживаемые форматы и совместимость
Целевой формат PDFiD — PDF. Скрипт ищет заголовок %PDF в первых 1024 байтах и затем анализирует поток байтов. При необходимости -f принуждает анализ даже без корректного PDF-заголовка. Эта возможность предназначена для повреждённых, вложенных или намеренно искажённых образцов, но результат в таком режиме требует ещё более осторожной интерпретации.
В качестве транспортного контейнера поддерживается ZIP: анализируется первый файл внутри архива, для защищённого образца применяется пароль infected. Это не означает поддержку ZIP как самостоятельного документного формата. Аналогично URL — не формат экспорта, а способ получить входные данные. Через стандартный ввод PDFiD также может принимать поток; если файл не задан, скрипт читает stdin. В этом режиме опции disarm и scan автоматически отключаются.
PDFiD не открывает DOCX, ODT, EPUB, изображения или DjVu как документы и не предназначена для конвертации. Если задача состоит в чтении разных форматов, ближе по назначению будут универсальные просмотрщики: например, Okular или Sumatra PDF. Их совместимость с форматами шире, но они не заменяют статический security-triage.
По выводу также важно не ожидать лишнего. Стандартный CLI печатает человекочитаемый текст, может дописывать его в журнал и формировать CSV при использовании плагинов. В исходнике присутствует функция преобразования результата в JSON, но отдельного CLI-параметра для JSON в текущем Main нет. Поэтому автоматизацию лучше строить либо вокруг текстового/CSV-вывода, либо импортировать код осознанно, не приписывая командной строке несуществующий режим.
Производительность и стабильность
Архитектурно PDFiD лёгкая: для обычного файла она читает данные последовательно и поддерживает небольшие счётчики, а не загружает полную объектную модель PDF в память. Дополнительная энтропия использует фиксированные массивы из 256 счётчиков. Поэтому память обычно растёт значительно медленнее размера документа, чем у инструментов, которые строят подробное дерево всех объектов.
Обратная сторона простоты — побайтовый Python-цикл. В исходнике каждый байт проходит через логику распознавания токенов, а при -e дополнительно обновляются энтропия, даты и EOF-статистика. Время работы закономерно растёт вместе с размером файла, а встроенного многопоточного анализа нескольких документов нет. Для очень крупных коллекций разумно сначала сузить набор файлов по расширению и размеру, а параллелизм организовывать внешними средствами, если это допустимо в лаборатории.
Известное ограничение принципиальнее обычных багов: PDFiD не знает объектной структуры так же глубоко, как парсер. Didier Stevens отдельно показывал ложные срабатывания /JS и /AA в больших файлах, когда короткая последовательность байтов случайно встречалась внутри потока. Поэтому для спорного счётчика нужен второй этап — поиск и декодирование соответствующего объекта другим инструментом.
Лицензирование и версии
В заголовке актуального pdfid.py указано, что исходный код помещён Didier Stevens в public domain и не защищается его авторским правом. Платной редакции PDFiD, подписки, пробного срока или ограничения бесплатного режима у оригинального скрипта нет. Для запуска не требуется аккаунт, онлайн-активация или лицензионный сервер.
Нумерация оригинального проекта дошла до 0.2.10. Важно не переносить сюда версии 1.x из PyPI: это другой пакет-клон, созданный для использования как библиотека и сопровождаемый не Didier Stevens. Совпадение имени может привести к неверным инструкциям по установке, лицензии и API. Если в рабочем окружении уже установлен пакет pdfid через pip, перед автоматизацией нужно определить, какой именно код импортируется и соответствует ли он ожидаемой реализации.
Хронология развития и поддержки
| Период | Подтверждённое изменение | Практическое значение |
|---|---|---|
| 2009 | Начало PDFiD, scan, XML-основа результата, даты, энтропия, disarm | Сформирована модель быстрого triage без полного парсинга |
| 2011–2013 | Python 3, /EmbeddedFile, URL и ZIP, /XFA, плагины и отбор | Инструмент стал пригоден для современных лабораторий и пакетной работы |
| 2014–2017 | CSV для плагинов, plugin options, pdfid.ini, -n | Упростились автоматизация и локальные правила |
| 2018–2020 | Исправления энтропии и EOF, обработка имён файлов, путь плагинов, аргумент data | Улучшена устойчивость в нетипичных сценариях и при встраивании |
| 2024 | Поддержка pyzipper | Лучше работа с современными защищёнными ZIP-образцами |
| 2025 | Версия 0.2.10 с исправлением ошибки | Текущая официальная версия на дату обзора |
Системные требования
Python и операционная система
Официальный исходник — Python-скрипт. В коде сохранены ветви совместимости и для Python 2, и для Python 3, однако Python 2 давно не поддерживается своей экосистемой; для новой рабочей среды рационально использовать актуальный поддерживаемый Python 3. Автор не публикует жёсткую таблицу минимальных версий Windows, macOS или Linux для PDFiD 0.2.10. Сам скрипт использует кросс-платформенные модули стандартной библиотеки, поэтому практическое требование — совместимый интерпретатор и доступ к анализируемым файлам.
Зависимости
Для обычного анализа используются модули стандартной библиотеки Python: работа с файлами, регулярными выражениями, XML DOM, JSON, glob, configparser и urllib. Импорт pyzipper опционален: если модуль отсутствует, PDFiD использует стандартный zipfile. Для AES-защищённых ZIP-архивов pyzipper может быть необходим, тогда как незашифрованные и поддерживаемые стандартной библиотекой архивы не требуют отдельного пакета.
Права и сеть
Локальный анализ требует права чтения исходника; -o и -s требуют права записи журнала, а -d — права создать соседний .disarmed-файл. Сеть не нужна, пока пользователь не передаёт URL. При анализе URL скрипт самостоятельно выполняет исходящий запрос с тайм-аутом, поэтому в изолированной среде этот режим может быть запрещён политикой и обычно не нужен для уже загруженного образца.
Карта критических зависимостей
| Зависимость | Нужна всегда | Что произойдёт при отсутствии |
|---|---|---|
| Python | Да для исходного скрипта | pdfid.py не запустится |
| Интернет | Нет | Локальный анализ продолжит работать; URL-ввод недоступен |
| pyzipper | Нет | Используется стандартный zipfile; часть современных защищённых ZIP может не открыться |
| Плагины | Нет | Базовые счётчики работают, но нет их оценок и инструкций |
| pdfid.ini | Нет | Используется встроенный список ключевых слов |
| Аккаунт или лиценз-сервер | Нет | На запуск не влияют, так как оригинальная PDFiD их не использует |
Преимущества и недостатки PDFid
Плюсы и минусы
• Очень узкая и понятная задача. Инструмент быстро показывает ключевые признаки без визуального открытия документа.
• Локальная работа. Для обычного файла не нужны аккаунт, облако или загрузка документа на чужой сервер.
• Низкий порог автоматизации. Один скрипт, текстовый вывод, журнал, шаблоны файлов, каталоги и плагины хорошо сочетаются с командными сценариями.
• Устойчивость к простой обфускации имён. Hex-кодирование PDF name-объектов учитывается в счётчиках.
• Расширенный triage без полного парсинга. Энтропия, даты и EOF-статистика помогают решить, что проверять дальше.
• Открытое распространение. Оригинальный код помещён автором в public domain и не ограничен платными редакциями.
• Сохранение оригинала при disarm. Модифицированная копия создаётся отдельно.
Минусы
• Нет полного понимания PDF-объектов. Сам автор демонстрировал ложные срабатывания коротких имён внутри потоков.
• Нет графического интерфейса и просмотра страниц. Пользователь должен работать в терминале и понимать семантику признаков.
• Нет готового вердикта. Ненулевой счётчик не равен заражению, нулевые счётчики не гарантируют безопасность.
• Disarm ограничен конкретным набором имён. Это не полноценный санитайзер и не замена безопасной изоляции.
• Плагины и -S требуют дисциплины доверия. Плагины исполняются как Python-код, а выражения отбора вычисляются через eval.
• Нет встроенного параллелизма. Большие коллекции приходится масштабировать внешними средствами.
• Сходное имя PyPI-пакета создаёт риск путаницы. Можно случайно установить не оригинальную реализацию.
Сравнение с аналогами
| Инструмент | Основная роль | Глубина анализа PDF | Удобство для массового triage | Когда выбирать |
|---|---|---|---|---|
| PDFiD | Подсчёт признаков и первичная сортировка | Низкая: без полной объектной модели | Высокое | Быстро решить, какие файлы исследовать глубже |
| pdf-parser.py | Разбор и поиск PDF-объектов | Высокая для структурного анализа | Среднее | Проверить, где именно расположен подозрительный объект или поток |
| peepdf | Исследование вредоносных PDF | Высокая, включая объекты, фильтры и версии документа | Среднее | Нужна интерактивная и более глубокая forensic-работа |
| qpdf | Проверка и преобразование структуры PDF | Высокая структурная, включая JSON-представление | Среднее | Нужны проверка, нормализация или программный доступ к объектам |
| Sumatra PDF | Просмотр документов | Не security-triage | Не предназначен | Нужно безопасно и быстро читать поддерживаемые форматы, а не анализировать признаки |
Ближайший компаньон PDFiD — pdf-parser.py того же автора. Если PDFiD сообщает /JavaScript или /EmbeddedFile, pdf-parser.py помогает найти соответствующие объекты, исследовать потоки и проверить, не является ли счётчик случайным совпадением. Эти инструменты лучше рассматривать как два этапа одной цепочки, а не как взаимоисключающие продукты.
peepdf ориентирован на более насыщенный анализ вредоносных PDF: он разбирает объекты, версии документа, объектные потоки, шифрование и распространённые фильтры. За более глубокую модель приходится платить сложностью. PDFiD выигрывает там, где нужен короткий отчёт по сотне файлов, а не интерактивное исследование одного образца.
qpdf — другой класс утилиты. Она умеет проверять и преобразовывать структуру PDF, а современные версии способны выдавать полное JSON-представление объектов. qpdf полезна для структурной диагностики и нормализации, но не предлагает встроенную «таблицу подозрительных ключей» PDFiD. Для обычного редактирования вместо обоих инструментов логичнее использовать специализированный редактор, например PDF-XChange Editor.
Sumatra PDF находится ещё дальше от PDFiD по назначению. Это просмотрщик PDF и ряда других форматов, а не средство malware-triage. Сравнение корректно только как выбор этапа: PDFiD — перед открытием сомнительного файла и для аналитики, Sumatra PDF — для чтения уже принятого к просмотру документа. Один инструмент не является функциональной заменой другого.
Инструкция по установке
Установка из официального архива
1. Откройте официальную страницу PDF Tools Didier Stevens и выберите архив актуальной версии PDFiD. На дату обзора это pdfid_v0_2_10.zip.
2. До распаковки сверяйте контрольную сумму с опубликованным автором SHA-256: A677336B1CF51386E35DBDED8FDB79F27368FD5D5ECC3FC5C8DA020A029CB6B6.
3. Распакуйте архив в отдельный каталог инструментов. Не смешивайте его с каталогом недоверенных образцов, чтобы случайно не загрузить посторонний файл-плагин.
4. Убедитесь, что в системе доступен поддерживаемый Python 3. Команда python —version или python3 —version должна возвращать версию интерпретатора.
5. Проверьте сам PDFiD: python pdfid.py —version. Ожидаемый номер для текущего файла — 0.2.10.
6. Выполните тест справки: python pdfid.py —help. Это подтверждает, что optparse и стандартные модули доступны.
Если вместо архива используется официальный репозиторий DidierStevensSuite, сохраняйте pdfid.py и нужные плагины из того же дерева. Не подменяйте этот шаг установкой одноимённого PyPI-пакета, если требуется именно оригинальный код.
Первый запуск
Поместите тестовый PDF в отдельный рабочий каталог и запустите python pdfid.py document.pdf. Нормальный результат начинается с строки PDFiD 0.2.10, имени файла и PDF Header. Затем идут счётчики. Если вывод говорит Not a PDF document, сначала проверьте путь и тип файла; -f применяйте только когда сознательно анализируете повреждённый или замаскированный образец.
Для расширенного отчёта используйте python pdfid.py -e document.pdf. Для официального triage-плагина команда имеет вид python pdfid.py -p plugin_triage document.pdf. Если плагин лежит рядом со скриптом, загрузчик умеет искать его в каталоге PDFiD. Не используйте случайно найденные плагины: загрузка выполняет их Python-код.
Безопасное удаление
Сам pdfid.py не содержит инсталлятора, службы или механизма активации. Если инструмент использовался как распакованный скрипт, для удаления достаточно стереть его рабочий каталог и созданные журналы. Не удаляйте системный Python или pyzipper автоматически: они могли быть нужны другим программам. Каталог с анализируемыми образцами следует обрабатывать отдельно в соответствии с правилами хранения вредоносных файлов.
Практические кейсы
Кейс 1. Первичный triage неизвестного вложения
Цель: понять, есть ли у PDF признаки, требующие глубокого анализа до открытия в просмотрщике. Подготовка: сохранить файл в изолированном рабочем каталоге, не открывать его двойным щелчком. Шаги: выполнить python pdfid.py sample.pdf и отметить ненулевые /JS, /JavaScript, /AA, /OpenAction, /Launch, /EmbeddedFile, /AcroForm, /XFA, /ObjStm и /Encrypt. Затем при необходимости повторить с -e. Проверка: результат должен содержать распознанный PDF Header и непротиворечивые служебные счётчики. Ограничение: даже все нули не доказывают безопасность; PDFiD ищет ограниченный набор признаков.
Кейс 2. Отбор подозрительных файлов из каталога
Цель: сократить очередь из множества PDF. Подготовка: хранить официальные plugin_triage.py и pdfid.py в доверенном каталоге, а образцы — отдельно. Шаги: запустить рекурсивный анализ каталога с плагином и при необходимости CSV: python pdfid.py —recursedir -p plugin_triage -c «samples/*.pdf». Для отсечения низких оценок можно добавить -m с выбранным порогом. Проверка: в CSV должны быть имя файла, имя плагина и score. Ограничение: score — приоритет triage, а не вероятность заражения; файл с нулём может потребовать анализа по внешнему контексту.
Кейс 3. Проверка ложного срабатывания короткого имени
Цель: не принять случайное /JS или /AA за активный код. Подготовка: зафиксировать исходный отчёт PDFiD и подготовить полноценный PDF-парсер. Шаги: сначала повторить PDFiD с -e и -a, чтобы получить больше контекста, затем использовать pdf-parser.py для поиска имени в объектах и отдельно внутри потоков. Проверка: если совпадение существует только как байты внутри изображения или другого потока и не является PDF-name в словаре объекта, исходный счётчик PDFiD не следует трактовать как активную функцию. Ограничение: окончательное заключение требует понимания структуры конкретного файла.
Кейс 4. Анализ хвостовых данных и нескольких EOF
Цель: обнаружить необычную структуру сохранений или данные после логического конца PDF. Подготовка: работать с копией файла и включить расширенную статистику. Шаги: выполнить python pdfid.py -e sample.pdf, сравнить число %%EOF и After last %%EOF, посмотреть энтропию внутри и вне потоков. Проверка: зафиксировать значения и сопоставить их с более глубоким разбором xref/trailer или инкрементальных обновлений. Ограничение: несколько %%EOF сами по себе не означают вредоносность; PDF допускает инкрементальные обновления.
Кейс 5. Создание disarmed-копии для лаборатории
Цель: получить отдельную копию, в которой PDFiD переименует ряд активных имён. Подготовка: сохранить оригинал неизменным и убедиться, что в каталоге достаточно места для второго файла. Шаги: выполнить python pdfid.py -d sample.pdf. Скрипт создаст sample.disarmed.pdf и выведет заменяемые имена. Затем проанализировать обе версии обычным PDFiD и сравнить счётчики. Проверка: исходный файл должен остаться на месте, а новая копия иметь отдельное имя. Ограничение: не считать disarmed-копию полностью очищенной и не использовать её как доказательство безопасности.
Навигатор по сбоям
| Симптом | Проверка | Вероятная причина | Безопасное действие |
|---|---|---|---|
| Not a PDF document | Путь, расширение, первые байты | Не-PDF, повреждённый или замаскированный файл | Не включать -f автоматически; сначала установить тип файла |
| Error opening file | Существование и права | Неверный путь, блокировка, ZIP не поддержан | Исправить путь; для защищённого ZIP проверить pyzipper |
| Плагин не загружается | Имя и расположение .py | Файл отсутствует или содержит ошибку | Взять официальный плагин из того же репозитория |
| Слишком много /JS или /AA | Размер файла и поиск внутри потоков | Возможны случайные совпадения | Проверить объектным парсером, не делать вывод по одному счётчику |
| Нет расширенной статистики | Наличие -e | Запущен базовый режим | Повторить с -e |
| CSV пуст или короток | Плагин, -m, входные файлы | Порог отфильтровал результаты | Снизить порог только для диагностики и повторить |
Контроль перед сохранением и передачей
• Хранить исходный PDF отдельно от disarmed-копии и журналов.
• Не переименовывать результат так, чтобы его можно было спутать с оригиналом.
• Записывать версию PDFiD и использованные параметры, особенно -e, -a, -f и плагины.
• Если применялся pdfid.ini, сохранять его вместе с методикой: добавленные ключевые слова меняют отчёт.
• Для плагинного результата фиксировать точное имя плагина и его происхождение.
• Не передавать score как «процент вредоносности»; описывать его как приоритет triage.
• При спорном признаке прикладывать подтверждение из объектного анализа, а не только счётчик PDFiD.
• Перед публикацией образца удалять чувствительные данные только отдельным специализированным процессом; PDFiD не является средством редактирования или редактирования персональных данных.
Часто задаваемые вопросы
PDFiD может определить, что PDF заражён?
Нет. Она показывает структурные признаки и может вместе с официальным triage-плагином присвоить приоритет анализа. Ненулевой /JavaScript, /OpenAction или другой счётчик — причина посмотреть файл глубже, а не готовый антивирусный вердикт. Автор специально позиционировал PDFiD как triage-инструмент.
Безопасно ли запускать PDFiD на неизвестном PDF?
PDFiD не рендерит страницы и не исполняет встроенный PDF JavaScript как просмотрщик. Она читает байты и считает токены, что существенно уменьшает поверхность взаимодействия с активным содержимым. Однако сам Python, сторонние плагины, файловая система и окружение остаются обычным программным контекстом. Для заведомо вредоносных образцов всё равно применяют изоляцию, минимальные права и доверенные плагины.
Нужен ли интернет?
Нет для локального файла. Интернет требуется только если в качестве входа передан сетевой URL или если пользователь сам загружает обновления. Аккаунта, облачного кабинета и лицензионной проверки у оригинальной PDFiD нет.
Почему PDFiD показывает JavaScript, а pdf-parser.py ничего не находит в словарях?
Потому что PDFiD не является полноценным парсером и сканирует байтовое содержимое. Короткая строка вроде /JS может случайно оказаться внутри сжатого или бинарного потока. Didier Stevens отдельно документировал такие ложные срабатывания. В спорном случае ищут совпадение внутри потоков и проверяют, является ли оно реальным PDF-name объекта.
Можно ли добавить собственный подозрительный ключ?
Да. PDFiD читает дополнительные ключевые слова из секции keywords файла pdfid.ini рядом со скриптом. Это удобно для корпоративных правил, но конфигурацию нужно версионировать вместе с процессом анализа: без неё коллега не воспроизведёт тот же набор счётчиков.
Чем PDFiD отличается от обычного PDF-редактора?
Редактор работает с содержимым страниц, аннотациями, формами, текстом и экспортом. PDFiD анализирует технические маркеры и не предназначена для правки текста или компоновки. Если нужна полноценная редактура, лучше выбрать отдельный продукт, например Master PDF Editor; PDFiD может использоваться до открытия сомнительного исходника.
Вывод
PDFiD остаётся полезным специализированным инструментом для тех, кому нужен быстрый первый взгляд на неизвестный PDF без запуска полноценного просмотрщика. Она особенно подходит аналитикам SOC, исследователям вредоносных документов, преподавателям цифровой криминалистики и администраторам, которым нужно сортировать большие наборы вложений по техническим признакам. Сильные стороны — компактность, локальная обработка, public-domain код, работа с обфусцированными именами, расширенная статистика и официальный механизм плагинов.
При этом PDFiD не следует выбирать как единственный инструмент анализа. Она не строит полную объектную модель, допускает ложные срабатывания внутри потоков и не доказывает безопасность при нулевых счётчиках. Для подтверждения подозрительного элемента нужен pdf-parser.py, peepdf, qpdf или другой структурный инструмент; для чтения — Sumatra PDF или иной просмотрщик; для правки — отдельный редактор. Наиболее разумная роль PDFiD — быстрый фильтр перед более дорогим и глубоким этапом исследования.