
Генерирует вредоносные тестовые PDF-файлы для тестирования на проникновение, баг-баунти и редтиминга. Проверяет SSRF, XSS, XXE, кражу учетных данных NTLM и эксфильтрацию данных в просмотрщиках PDF, конвертерах и веб-приложениях. Интегрируется с Burp Collaborator и Interact.sh.

Создаёт 67 вредоносных PDF-файлов для тестирования phone-home обратных вызовов, SSRF, XSS, XXE, кражи учётных данных NTLM и утечки данных в PDF-просмотрщиках, конвертерах и веб-приложениях. Можно использовать с Burp Collaborator или Interact.sh
Используется для пентеста, охоты за багами и/или red-teaming и т.п. Я создал этот инструмент, потому что мне нужен был инструмент для генерации набора PDF-файлов с различными ссылками. Только для образовательных и профессиональных целей.
pip install -r requirements.txt python3 malicious-pdf.py burp-collaborator-url
Результат будет записан в каталог `output/` как: test1.pdf, test2.pdf, test3.pdf и т. д.
### Параметры```
--output-dir DIR Directory to save generated PDF files (default: output/)
--no-credit Do not embed credit/attribution metadata in generated PDFs
--obfuscate LEVEL Obfuscation level (0-3):
0 = None (default)
1 = PDF name hex encoding + string octal/hex encoding
2 = Level 1 + JS bracket notation + javascript: URI case/whitespace obfuscation
3 = Level 2 + FlateDecode stream compression
Пример с обфускацией:``` python3 malicious-pdf.py https://your-interact-sh-url --obfuscate 2
Максимальная обфускация (уровень 4 оборачивает JS-пейлоады в заглушку-декодер base64, чтобы исходные вызовы API никогда не появлялись в виде литеральных подстрок):```
python3 malicious-pdf.py https://your-interact-sh-url --obfuscate 4
/V, base64-декодер) обходят наивные regex-сканеры /JSCollab.isDocReadOnly (зондирование файловой системы), app.plugIns (перечисление установленных плагинов), app.viewerVersion (определение версии)-O) полностью пропускают объекты. См.: Спецификация PDF ISO 32000 §7.5.7app.doc.getAnnots()[n].subject и выполнять через eval. См.: Julia Wolf — обфускация PDF с помощью getAnnots()/Info (/Title, /Author). Извлекать во время выполнения через info.Title в JS. См.: трюки с PDF от corkami/V полей формы. Извлекать через getField("name").value в JS. См.: | Тестовый файл | Функция | CVE/Ссылка | Вектор атаки | Метод | Воздействие |
|---|
| test1.pdf | create_malpdf() | CVE-2018-4993 | Доступ к внешнему файлу | Действие /GoToE с UNC-путём | Сетевой обратный вызов через файловую систему |
| test1_1.pdf | create_malpdf() | CVE-2018-4993 | Доступ к внешнему файлу | Действие /GoToE с HTTPS-URL | Сетевой обратный вызов через HTTPS |
| test2.pdf | create_malpdf2() | Отправка XFA-формы | Эксфильтрация данных формы | XDP-форма с событием submit | Автоматическая отправка формы |
| test3.pdf | create_malpdf3() | Внедрение JavaScript | Выполнение кода | /OpenAction с app.openDoc() | Загрузка внешнего документа |
| test4.pdf | create_malpdf4() | CVE-2019-7089 | Внедрение XSLT | XFA с внешней XSLT-таблицей стилей | Обратный вызов UNC-пути |
| test5.pdf | create_malpdf5() | Исследование PDF101 | URI-действие | Тип действия /URI | DNS-префетчинг/HTTP-запрос |
| test6.pdf | create_malpdf6() | Исследование PDF101 | Действие Launch | /Launch с внешним URL | Выполнение внешнего ресурса |
| test7.pdf | create_malpdf7() | Исследование PDF101 | Удалённый PDF | Действие /GoToR | Загрузка удалённого PDF |
| test8.pdf | create_malpdf8() | Исследование PDF101 | Отправка формы | /SubmitForm с HTML-флагами | Отправка данных формы |
| test9.pdf | create_malpdf9() | Исследование PDF101 | Импорт данных | Действие /ImportData | Импорт внешних данных |
| test10.pdf | create_malpdf10() | CVE-2017-10951 | Выполнение JavaScript | Обратный вызов Foxit this.getURL() | Сетевой обратный вызов через Foxit Reader |
| test11.pdf | create_malpdf11() | Тест EICAR | Обнаружение антивирусом | Встроенная строка EICAR | Тестирование антивируса |
| test12.pdf | create_malpdf12() | CVE-2014-8453 | Эксфильтрация данных FormCalc | Функция XFA FormCalc Post() | Эксфильтрация данных с cookies в пределах того же источника |
| test13.pdf | create_malpdf13() | Внедрение запроса | Внедрение CRLF-заголовков | Отправка XFA с textEncoding CRLF | Манипуляция HTTP-заголовками |
| test14.svg | create_malpdf14() | Внедрение команд в ImageMagick | Внедрение команд через SVG/MSL | Полиглот SVG-MSL с атрибутом authenticate | Удалённое выполнение кода через ImageMagick |
| test15.pdf | create_malpdf15() | Спецификация PDF | Внедрение заголовков FormCalc | XFA FormCalc Post() с пользовательскими заголовками | Произвольное внедрение HTTP-заголовков |
| test16.pdf | create_malpdf16() | Спецификация PDF | JavaScript через GotoE | /GoToE с URI javascript: | XSS в браузере при встраивании PDF через <embed>/<object> |
| test17.pdf | create_malpdf17() | CVE-2014-8452 | Внедрение XXE | Внешняя сущность XMLData.parse() | Разрешение внешних XML-сущностей |
| test18.pdf | create_malpdf18() | Исследование PortSwigger | Внедрение URI в аннотацию | Неэкранированные скобки внедряют JS-действие через дублирующий ключ /A | XSS через вывод PDF-Lib/jsPDF |
| test19.pdf | create_malpdf19() | Исследование PortSwigger | Автовыполнение PV | Экранная аннотация /AA /PV запускает JS при отображении страницы | Автоматическое выполнение кода (Acrobat) |
| test20.pdf | create_malpdf20() | Исследование PortSwigger | Триггер закрытия PC | Аннотация /AA /PC запускает JS при закрытии страницы | Выполнение кода при закрытии (Acrobat) |
| test21.pdf | create_malpdf21() | Исследование PortSwigger | SubmitForm SubmitPDF | /SubmitForm с флагом 256 отправляет весь PDF | Эксфильтрация полного содержимого PDF |
| test22.pdf | create_malpdf22() | Исследование PortSwigger | JS submitForm() | this.submitForm() с cSubmitAs: "PDF" | Отправка содержимого PDF (Acrobat) |
| test23.pdf | create_malpdf23() | Исследование PortSwigger | Внедрение виджета-кнопки | Невидимый виджет /Btn, перекрывающий страницу, JS по клику | Выполнение кода (Chrome/PDFium) |
| test24.pdf | create_malpdf24() | Исследование PortSwigger | SSRF через текстовое поле | Поле виджета /Tx с POST через submitForm() | Слепой SSRF через данные формы |
| test25.pdf | create_malpdf25() | Исследование PortSwigger | Извлечение содержимого | getPageNthWord() читает весь текст и эксфильтрует его | Эксфильтрация отображаемого текста |
| test26.pdf | create_malpdf26() | Исследование PortSwigger | Триггер наведения мыши | Аннотация /AA /E запускает JS при входе курсора | Выполнение кода при наведении (PDFium) |
| — | — | Удалён | Дубликат test3 (Acrobat OpenAction JS) + test23 (Chrome Widget Btn) | — | |
| test28.pdf | create_malpdf28() | Исследование PortSwigger | Перехват URL | Неэкранированные скобки внедряют новое действие /URI | Перенаправление по клику через PDF-Lib/jsPDF |
| test29.pdf | create_malpdf29() | CVE-2024-4367 | Внедрение FontMatrix | Строка FontMatrix шрифта Type1 выходит за пределы c.transform() | Произвольное выполнение JS в PDF.js (Firefox < 126) |
| test30.pdf | create_malpdf30() | Исследование PDF101 | Внешний поток XObject | Image XObject загружает данные с удалённого URL через /FS /URL | Тихий обратный вызов при рендеринге страницы (без действий/JS) |
| test31.pdf | create_malpdf31() | Исследование PDF101 | Действие Thread | /S /Thread с удалённым FileSpec | Сетевой обратный вызов через ссылку на поток |
| test32.pdf | create_malpdf32() | Исследование PDF101 | Launch с печатью | /Launch с /Win << /O /print >> принудительно выполняет удалённую загрузку | Сетевой обратный вызов через операцию печати |
| test33_1.pdf | create_malpdf33_1() | Исследование PDF101 | JS: this.submitForm() | Обратный вызов отправки формы через JS Acrobat | Acrobat Reader |
| test33_2.pdf | create_malpdf33_2() | Исследование PDF101 | JS: this.getURL() | Получение URL через JS Acrobat | Acrobat Reader |
| test33_3.pdf | create_malpdf33_3() | Исследование PDF101 | JS: app.launchURL() | Запуск URL через JS Acrobat | Acrobat Reader |
| test33_4.pdf | create_malpdf33_4() | Исследование PDF101 | JS: app.media.getURLData() | Получение медиаданных через JS Acrobat | Acrobat Reader |
| test33_5.pdf | create_malpdf33_5() | Исследование PDF101 | JS: SOAP.connect() | SOAP-подключение через JS Acrobat | Acrobat Reader |
| test33_6.pdf | create_malpdf33_6() | Исследование PDF101 | JS: SOAP.request() | SOAP-запрос через JS Acrobat | Acrobat Reader |
| test33_7.pdf | create_malpdf33_7() | Исследование PDF101 | JS: this.importDataObject() | Импорт данных через JS Acrobat | Acrobat Reader |
| test33_8.pdf | create_malpdf33_8() | Исследование PDF101 | JS: app.openDoc() | Открытие документа через JS Acrobat | Acrobat Reader |
| test33_9.pdf | create_malpdf33_9() | Исследование PDF101 | JS: fetch() | Web API-обратный вызов (PDF.js/браузер) | Firefox/PDF.js |
| test33_10.pdf | create_malpdf33_10() | Исследование PDF101 | JS: XMLHttpRequest | Web API-обратный вызов (PDF.js/браузер) | Firefox/PDF.js |
| test33_11.pdf | create_malpdf33_11() | Исследование PDF101 | JS: new Image() | Web API-обратный вызов изображения (PDF.js/браузер) | Firefox/PDF.js |
| test33_12.pdf | create_malpdf33_12() | Исследование PDF101 | JS: WebSocket | Web API-обратный вызов WebSocket (PDF.js/браузер) | Firefox/PDF.js |
| test33_13.pdf | create_malpdf33_13() | Блог Adobe 0-day (апрель 2026) | JS: RSS.addFeed() | Обратный вызов RSS-канала через JS Acrobat | Acrobat Reader |
| test33_14.pdf | create_malpdf33_14() | Блог Adobe 0-day (апрель 2026) | JS: util.readFileIntoStream() + SOAP.request() | Чтение локального файла + цепочка эксфильтрации (путь ошибки try/catch тоже вызывает обратный вызов) | Acrobat Reader |
| test33_15.pdf | create_malpdf33_15() | Блог Adobe 0-day (апрель 2026) | JS-загрузчик с поэтапной загрузкой через поле формы | Base64-нагрузка в виджете /Tx в /V, декодируется через getField() + util.stringFromStream | Acrobat Reader |
| test34_1.pdf | create_malpdf34_1() | Исследование PDF101 | UNC: поток XObject | Image XObject с UNC-путём | Кража NTLM через рендеринг страницы |
| test34_2.pdf | create_malpdf34_2() | Исследование PDF101 | UNC: GoToR | Действие /GoToR с UNC FileSpec | Кража NTLM через удалённый PDF |
| test34_3.pdf | create_malpdf34_3() | Исследование PDF101 | UNC: Thread | Действие /Thread с UNC FileSpec | Кража NTLM через ссылку на поток |
| test34_4.pdf | create_malpdf34_4() | Исследование PDF101 | UNC: URI | Действие /URI с UNC-путём | Кража NTLM через URI-действие |
| test34_5.pdf | create_malpdf34_5() | Исследование PDF101 | UNC: JS submitForm | this.submitForm() с UNC-путём | Кража NTLM через отправку формы JS |
| test34_6.pdf | create_malpdf34_6() | Исследование PDF101 | UNC: JS getURL | this.getURL() с UNC-путём | Кража NTLM через получение URL JS |
| test34_7.pdf | create_malpdf34_7() | Исследование PDF101 | UNC: JS launchURL | app.launchURL() с UNC-путём | Кража NTLM через запуск JS |
| test34_8.pdf | create_malpdf34_8() | Исследование PDF101 | UNC: JS SOAP | SOAP.connect() с UNC-путём | Кража NTLM через JS SOAP |
| test34_9.pdf | create_malpdf34_9() | Исследование PDF101 | UNC: JS openDoc | app.openDoc() с UNC-путём | Кража NTLM через открытие документа JS |
| test35.pdf | create_malpdf35() | Исследование PDF101 | Словарь имён (Names) | Триггер автовыполнения на уровне каталога /Names /JavaScript | Альтернативный триггер выполнения JS |
| test36.pdf | create_malpdf36() | CVE-2016-2175 / CVE-2017-9096 | XXE в метаданных XMP | XXE <!ENTITY> в потоке XMP /Metadata | Серверный обратный вызов (PDFBox, iText) |
| test37.pdf | create_malpdf37() | CVE-2016-2175 / CVE-2017-9096 | XXE в данных формы XFA | XXE <!ENTITY> в потоке /AcroForm /XFA | Серверный обратный вызов (PDFBox, iText) |
| test38.pdf | create_malpdf38() | CVE-2020-29075 | Тихое отслеживание DNS | Каталог /AA с триггерами /WC, /WS, /DS | DNS-обратный вызов без запроса (Acrobat) |
| test39.pdf | create_malpdf39() | CVE-2022-28244 | Обход CSP | Аннотация RichMedia со встроенными HTML/JS | Междоменный запрос (Acrobat) |
| test40.pdf | create_malpdf40() | CVE-2018-5158 | Внедрение PostScript-калькулятора | JS-инъекция через /FunctionType 4 в Image XObject | Выполнение JS в воркере PDF.js (Firefox) |
| test41.pdf | create_malpdf41() | CVE-2018-20065 | URI без жеста пользователя | /OpenAction с автопереходом /S /URI | Тихая навигация (PDFium/Chrome) |
| test42.pdf | create_malpdf42() | CVE-2025-66516 | XXE OOB параметрическая сущность в XFA | Параметрическая сущность %xxe; в /AcroForm /XFA принудительно загружает DTD | Серверный слепой XXE (Tika, Confluence, Jira) |
| test43.pdf | create_malpdf43() | CVE-2025-70401 | XSS в поле /T аннотации | Тег `` в поле /T (автор) текстовой аннотации | XSS-обратный вызов (Apryse WebViewer, веб-просмотрщики) |
| test44.pdf | create_malpdf44() | CVE-2024-12426 | Разворачивание URL в LibreOffice | /URI с vnd.sun.star.expand: разворачивает ${HOME} | Эксфильтрация переменных окружения (LibreOffice < 24.8.4) |
| test45.pdf | create_malpdf45() | CVE-2025-59803 | Триггер JS через OCG при подписании | /AA /WP+/DP запускают JS через OCG в процессе подписания | Обратный вызов во время подписания (Foxit < 2025.2.1) |
| test46.pdf | create_malpdf46() | CVE-2026-25755 | Внедрение объекта jsPDF | Сломанная JS-строка + внедрённое авто-действие /AA /O | Автоматический обратный вызов в любом просмотрщике (jsPDF < 4.2.0) |
| test47.pdf | create_malpdf47() | Спецификация PDF 2.0 | Встраивание HTML через Associated Files | HTML через каталог /AF + /EF EmbeddedFile | Обратный вызов через встроенный HTML (просмотрщики PDF 2.0) |
| test48.pdf | create_malpdf48() | Спецификация XFA | XFA SOAP-обратный вызов | <submit method="soap"> с событием initialize | SOAP HTTP-запрос (движок XFA Acrobat) |
/Names, выполняемым последовательно. См.: трюки с PDF от corkami%%EOF через инкрементальное обновление. См.: маскирование контента PDF101, Didier Stevensunescape() — Оборачивать JS-нагрузку в eval(unescape("%61%6C%65%72%74...")). См.: трюки с PDF от corkami%PDF- (спецификация допускает заголовок в первых 1024 байтах). Сбивает определение типа файла. См.: corkami, Decalageevent.target.zoomType == "FitPage" или проверки типов глобальных переменных перед выполнением нагрузки. См.: трюки с PDF от corkami