
ペネトレーションテスト、バグ報奨金ハンティング、レッドチーミング用の悪意のあるPDFテストファイルを生成します。PDFビューア、コンバーター、WebアプリケーションにおけるSSRF、XSS、XXE、NTLM資格情報の窃取、およびデータ外部送信をテストします。Burp CollaboratorおよびInteract.shと統合します。

PDFビューア、変換ツール、Webアプリケーションにおけるphone-homeコールバック、SSRF、XSS、XXE、NTLM資格情報の窃取、データ外部送信をテストするための、67個の悪意のあるPDFテストファイルを生成します。Burp Collaborator または Interact.sh と一緒に使用できます。
ペネトレーションテスト、バグバウンティハンティング、レッドチーミングなどに使用されます。さまざまなリンクを含む多数の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デコーダー)は単純な /JS 正規表現スキャナーを無効化するCollab.isDocReadOnly(ファイルシステムプロービング)、app.plugIns(インストール済みプラグインの列挙)、app.viewerVersion(バージョンフィンガープリンティング)-O フラグなしのPDFiDを含む)はオブジェクトを完全に見逃す。参照: PDF仕様 ISO 32000 §7.5.7app.doc.getAnnots()[n].subject で取得してeval。参照: Julia Wolf - PDF Obfuscation using getAnnots()/Info トレーラーフィールド(/Title、/Author)に格納。実行時にJS内の info.Title 経由で取得。参照: corkami PDF tricks/V 値に格納。JS内の getField("name").value で取得。参照: corkami PDF tricks/Names エントリに分割して順次実行。参照: | テストファイル | 関数 | 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フォーム | 自動フォーム送信 |
| test3.pdf | create_malpdf3() | JavaScriptインジェクション | コード実行 | /OpenAction と app.openDoc() | 外部ドキュメントの読み込み |
| test4.pdf | create_malpdf4() | CVE-2019-7089 | XSLTインジェクション | 外部XSLTスタイルシートを含むXFA | UNCパスコールバック |
| test5.pdf | create_malpdf5() | PDF101リサーチ | URIアクション | /URI アクションタイプ | DNSプリフェッチ/HTTPリクエスト |
| test6.pdf | create_malpdf6() | PDF101リサーチ | 起動アクション | 外部URLを含む /Launch | 外部リソースの実行 |
| test7.pdf | create_malpdf7() | PDF101リサーチ | リモートPDF | /GoToR アクション | リモートPDFの読み込み |
| test8.pdf | create_malpdf8() | PDF101リサーチ | フォーム送信 | HTMLフラグ付き /SubmitForm | フォームデータの送信 |
| test9.pdf | create_malpdf9() | PDF101リサーチ | データインポート | /ImportData アクション | 外部データのインポート |
| test10.pdf | create_malpdf10() | CVE-2017-10951 | JavaScript実行 | Foxit this.getURL() コールバック | Foxit Reader経由のネットワークコールバック |
| test11.pdf | create_malpdf11() | EICARテスト | AV検出 | 埋め込まれたEICAR文字列 | アンチウイルステスト |
| test12.pdf | create_malpdf12() | CVE-2014-8453 | FormCalcデータ外部送信 | XFA FormCalc Post() 関数 | クッキー付き同一オリジンデータの外部送信 |
| 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仕様 | GotoE経由のJavaScript | javascript: URI付き /GoToE | PDFが <embed>/<object> で埋め込まれた場合のブラウザXSS |
| test17.pdf | create_malpdf17() | CVE-2014-8452 | XXEインジェクション | XMLData.parse() 外部エンティティ | XML外部エンティティ解決 |
| test18.pdf | create_malpdf18() | PortSwiggerリサーチ | 注釈URIインジェクション | エスケープされていない括弧が重複した /A キー経由でJSアクションを注入 | PDF-Lib/jsPDF出力経由のXSS |
| 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 | Flags 256付き /SubmitForm がPDF全体を送信 | PDF全コンテンツの外部送信 |
| test22.pdf | create_malpdf22() | PortSwiggerリサーチ | JS submitForm() | cSubmitAs: "PDF" 付き this.submitForm() | PDFコンテンツの送信(Acrobat) |
| test23.pdf | create_malpdf23() | PortSwiggerリサーチ | ウィジェットボタンインジェクション | ページ全体を覆う不可視の /Btn ウィジェット、クリック時にJS | コード実行(Chrome/PDFium) |
| test24.pdf | create_malpdf24() | PortSwiggerリサーチ | テキストフィールドSSRF | submitForm() POST付きウィジェット /Tx フィールド | フォームデータ経由のブラインド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インジェクション | Type1フォントの FontMatrix 文字列が c.transform() から脱出 | PDF.jsでの任意JS実行(Firefox < 126) |
| test30.pdf | create_malpdf30() | PDF101リサーチ | 外部XObjectストリーム | 画像XObjectが /FS /URL 経由でリモートURLからデータを取得 | ページレンダリング経由のサイレントコールバック(アクション/JSなし) |
| test31.pdf | create_malpdf31() | PDF101リサーチ | スレッドアクション | リモートFileSpec付き /S /Thread | スレッド参照経由のネットワークコールバック |
| test32.pdf | create_malpdf32() | PDF101リサーチ | 印刷付き起動 | /Win << /O /print >> 付き /Launch がリモート取得を強制 | 印刷操作経由のネットワークコールバック |
| test33_1.pdf | create_malpdf33_1() | PDF101リサーチ | JS: this.submitForm() | Acrobat JSフォーム送信コールバック | Acrobat Reader |
| test33_2.pdf | create_malpdf33_2() | PDF101リサーチ | JS: this.getURL() | Acrobat JS URL取得 | Acrobat Reader |
| test33_3.pdf | create_malpdf33_3() | PDF101リサーチ | JS: app.launchURL() | Acrobat JS URL起動 | Acrobat Reader |
| test33_4.pdf | create_malpdf33_4() | PDF101リサーチ | JS: app.media.getURLData() | Acrobat JSメディア取得 | Acrobat Reader |
| test33_5.pdf | create_malpdf33_5() | PDF101リサーチ | JS: SOAP.connect() | Acrobat JS SOAP接続 | Acrobat Reader |
| test33_6.pdf | create_malpdf33_6() | PDF101リサーチ | JS: SOAP.request() | Acrobat JS SOAPリクエスト | Acrobat Reader |
| test33_7.pdf | create_malpdf33_7() | PDF101リサーチ | JS: this.importDataObject() | Acrobat JSデータインポート | Acrobat Reader |
| test33_8.pdf | create_malpdf33_8() | PDF101リサーチ | JS: app.openDoc() | Acrobat JSドキュメントオープン | 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年4月) | JS: RSS.addFeed() | Acrobat JS RSSフィードコールバック | Acrobat Reader |
| test33_14.pdf | create_malpdf33_14() | Adobe 0-dayブログ(2026年4月) | JS: util.readFileIntoStream() + SOAP.request() | ローカルファイル読み取り+外部送信チェーン(try/catchエラーパスでもコールバック) | Acrobat Reader |
| test33_15.pdf | create_malpdf33_15() | Adobe 0-dayブログ(2026年4月) | フォームフィールドによる段階的JSローダー | /Tx ウィジェットの /V にあるBase64ペイロードを getField() + util.stringFromStream でデコード | Acrobat Reader |
| test34_1.pdf | create_malpdf34_1() | PDF101リサーチ | UNC: XObjectストリーム | UNCパス付き画像XObject | ページレンダリング経由のNTLM窃取 |
| test34_2.pdf | create_malpdf34_2() | PDF101リサーチ | UNC: GoToR | UNC FileSpec付き /GoToR アクション | リモートPDF経由のNTLM窃取 |
| test34_3.pdf | create_malpdf34_3() | PDF101リサーチ | UNC: Thread | UNC FileSpec付き /Thread アクション | スレッド参照経由のNTLM窃取 |
| test34_4.pdf | create_malpdf34_4() | PDF101リサーチ | UNC: URI | UNCパス付き /URI アクション | URIアクション経由のNTLM窃取 |
| test34_5.pdf | create_malpdf34_5() | PDF101リサーチ | UNC: JS submitForm | UNCパス付き this.submitForm() | JSフォーム送信経由のNTLM窃取 |
| test34_6.pdf | create_malpdf34_6() | PDF101リサーチ | UNC: JS getURL | UNCパス付き this.getURL() | JS URL取得経由のNTLM窃取 |
| test34_7.pdf | create_malpdf34_7() | PDF101リサーチ | UNC: JS launchURL | UNCパス付き app.launchURL() | JS起動経由のNTLM窃取 |
| test34_8.pdf | create_malpdf34_8() | PDF101リサーチ | UNC: JS SOAP | UNCパス付き SOAP.connect() | JS SOAP経由のNTLM窃取 |
| test34_9.pdf | create_malpdf34_9() | PDF101リサーチ | UNC: JS openDoc | UNCパス付き app.openDoc() | JSドキュメントオープン経由のNTLM窃取 |
| test35.pdf | create_malpdf35() | PDF101リサーチ | 名前辞書 | /Names /JavaScript カタログレベルの自動実行トリガー | 代替JS実行トリガー |
| test36.pdf | create_malpdf36() | CVE-2016-2175 / CVE-2017-9096 | XMPメタデータ内XXE | /Metadata XMPストリーム内のXXE <!ENTITY> | サーバーサイドコールバック(PDFBox、iText) |
| test37.pdf | create_malpdf37() | CVE-2016-2175 / CVE-2017-9096 | XFAフォームデータ内XXE | /AcroForm /XFA ストリーム内のXXE <!ENTITY> | サーバーサイドコールバック(PDFBox、iText) |
| test38.pdf | create_malpdf38() | CVE-2020-29075 | サイレントDNSトラッキング | /WC、/WS、/DS トリガー付きカタログ /AA | プロンプトなしのDNSコールバック(Acrobat) |
| test39.pdf | create_malpdf39() | CVE-2022-28244 | CSPバイパス | 埋め込みHTML/JS付きRichMedia注釈 | クロスオリジンリクエスト(Acrobat) |
| test40.pdf | create_malpdf40() | CVE-2018-5158 | PostScript計算機インジェクション | 画像XObject内の /FunctionType 4 JSインジェクション | PDF.jsワーカーでのJS実行(Firefox) |
| test41.pdf | create_malpdf41() | CVE-2018-20065 | ユーザージェスチャなしのURI | /S /URI 自動ナビゲーション付き /OpenAction | サイレントナビゲーション(PDFium/Chrome) |
| test42.pdf | create_malpdf42() | CVE-2025-66516 | XFA内XXE OOBパラメータエンティティ | /AcroForm /XFA 内の %xxe; パラメータエンティティがDTD取得を強制 | サーバーサイドブラインドXXE(Tika、Confluence、Jira) |
| test43.pdf | create_malpdf43() | CVE-2025-70401 | 注釈 /T フィールドXSS | テキスト注釈の /T(作成者)フィールド内の `` タグ | XSSコールバック(Apryse WebViewer、Webビューア) |
| test44.pdf | create_malpdf44() | CVE-2024-12426 | LibreOffice URL展開 | vnd.sun.star.expand: 付き /URI が ${HOME} を展開 | 環境変数の外部送信(LibreOffice < 24.8.4) |
| test45.pdf | create_malpdf45() | CVE-2025-59803 | 署名時のOCG JSトリガー | 署名ワークフローで /AA /WP+/DP がOCG経由でJSをトリガー | 署名中のコールバック(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埋め込み | カタログ /AF + /EF EmbeddedFile経由のHTML | 埋め込みHTML経由のコールバック(PDF 2.0対応ビューア) |
| test48.pdf | create_malpdf48() | XFA仕様 | XFA SOAPコールバック | initialize イベント付き <submit method="soap"> | SOAP HTTPリクエスト(Acrobat XFAエンジン) |
%%EOF マーカーの後に新しいオブジェクト/アクションを追加。参照: PDF101 content masking、Didier Stevensunescape() エンコーディング — JSペイロードを eval(unescape("%61%6C%65%72%74...")) でラップ。参照: corkami PDF tricks%PDF- ヘッダーの前にJPEG/HTMLなどのマジックバイトを前置(仕様ではヘッダーが最初の1024バイト以内にあれば許可)。ファイルタイプ検出を混乱させる。参照: corkami、Decalageevent.target.zoomType == "FitPage" やグローバル変数の型チェックで本物のAdobe Readerを検出。参照: corkami PDF tricks