You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The test matrix grew to 47 rows. Wrap it in a <details> block so
the README stays scannable — Usage, Purpose, Credits, and Test
Results are now visible without scrolling past the full table.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
| test11.pdf |`create_malpdf11()`| EICAR test | AV detection | Embedded EICAR string | Anti-virus testing |
53
-
| test12.pdf |`create_malpdf12()`|CVE-2014-8453 | FormCalc data exfiltration | XFA FormCalc `Post()` function | Same-origin data exfiltration with cookies |
| test16.pdf |`create_malpdf16()`| PDF specification | JavaScript via GotoE |`/GoToE` with `javascript:` URI | Browser XSS when PDF embedded via `<embed>`/`<object>`|
| test20.pdf |`create_malpdf20()`| PortSwigger research | PC close trigger |`/AA /PC` annotation fires JS on page close | Code execution on close (Acrobat) |
62
-
| test21.pdf |`create_malpdf21()`| PortSwigger research | SubmitForm SubmitPDF |`/SubmitForm` with Flags 256 sends entire PDF | Full PDF content exfiltration |
63
-
| test22.pdf |`create_malpdf22()`| PortSwigger research | JS submitForm() |`this.submitForm()` with `cSubmitAs: "PDF"`| PDF content submission (Acrobat) |
| test24.pdf |`create_malpdf24()`| PortSwigger research | Text field SSRF | Widget `/Tx` field with `submitForm()` POST | Blind SSRF via form data |
66
-
| test25.pdf |`create_malpdf25()`| PortSwigger research | Content extraction |`getPageNthWord()` reads all text and exfiltrates | Rendered text exfiltration |
67
-
| test26.pdf |`create_malpdf26()`| PortSwigger research | Mouseover trigger |`/AA /E` annotation fires JS on mouse enter | Code execution on hover (PDFium) |
68
-
| test27.pdf |`create_malpdf27()`| PortSwigger research | Hybrid payload | JS OpenAction + Widget button in single PDF | Targets both Acrobat and Chrome |
69
-
| test28.pdf |`create_malpdf28()`| PortSwigger research | URL hijacking | Unescaped parens inject new `/URI` action | Click redirection via PDF-Lib/jsPDF |
70
-
| test29.pdf |`create_malpdf29()`|CVE-2024-4367 | FontMatrix injection | Type1 font `FontMatrix` string breaks out of `c.transform()`| Arbitrary JS execution in PDF.js (Firefox < 126) |
71
-
| test30.pdf |`create_malpdf30()`| PDF101 research | External XObject stream | Image XObject fetches data from remote URL via `/FS /URL`| Silent callback via page rendering (no actions/JS) |
72
-
| test31.pdf |`create_malpdf31()`| PDF101 research | Thread action |`/S /Thread` with remote FileSpec | Network callback via thread reference |
73
-
| test32.pdf |`create_malpdf32()`| PDF101 research | Launch with print |`/Launch` with `/Win << /O /print >>` forces remote fetch | Network callback via print operation |
74
-
| test33_1.pdf |`create_malpdf33_1()`| PDF101 research | JS: `this.submitForm()`| Acrobat JS form submission callback | Acrobat Reader |
| test33_7.pdf |`create_malpdf33_7()`| PDF101 research | JS: `this.importDataObject()`| Acrobat JS data import | Acrobat Reader |
81
-
| test33_8.pdf |`create_malpdf33_8()`| PDF101 research | JS: `app.openDoc()`| Acrobat JS open document | Acrobat Reader |
82
-
| test33_9.pdf |`create_malpdf33_9()`| PDF101 research | JS: `fetch()`| Web API callback (PDF.js/browser) | Firefox/PDF.js |
83
-
| test33_10.pdf |`create_malpdf33_10()`| PDF101 research | JS: `XMLHttpRequest`| Web API callback (PDF.js/browser) | Firefox/PDF.js |
84
-
| test33_11.pdf |`create_malpdf33_11()`| PDF101 research | JS: `new Image()`| Web API image callback (PDF.js/browser) | Firefox/PDF.js |
85
-
| test33_12.pdf |`create_malpdf33_12()`| PDF101 research | JS: `WebSocket`| Web API WebSocket callback (PDF.js/browser) | Firefox/PDF.js |
86
-
| test34.pdf |`create_malpdf34()`| PDF101 research | UNC multi-vector | NTLM theft via XObject, GoToR, Thread, URI, JS (8 methods) | Credential theft via SMB |
87
-
| test35.pdf |`create_malpdf35()`| PDF101 research | Names dictionary |`/Names /JavaScript` catalog-level auto-execute trigger | Alternative JS execution trigger |
88
-
89
37
## Purpose
90
38
- Test web pages/services accepting PDF files
91
39
- Test security products
@@ -159,6 +107,63 @@ PDF.js v5.6.205 blocks all callback vectors. The CVE-2024-4367 FontMatrix inject
159
107
160
108
All obfuscation levels produce callbacks on both viewers. The obfuscation only changes the PDF structural layer (name tokens, string encoding, stream compression) without affecting the actual exploit payloads.
161
109
110
+
## Complete Test Matrix
111
+
112
+
<details>
113
+
<summary>Click to expand all 47 test cases</summary>
114
+
115
+
| Test File | Function | CVE/Reference | Attack Vector | Method | Impact |
| test11.pdf |`create_malpdf11()`| EICAR test | AV detection | Embedded EICAR string | Anti-virus testing |
129
+
| test12.pdf |`create_malpdf12()`|CVE-2014-8453 | FormCalc data exfiltration | XFA FormCalc `Post()` function | Same-origin data exfiltration with cookies |
| test16.pdf |`create_malpdf16()`| PDF specification | JavaScript via GotoE |`/GoToE` with `javascript:` URI | Browser XSS when PDF embedded via `<embed>`/`<object>`|
| test20.pdf |`create_malpdf20()`| PortSwigger research | PC close trigger |`/AA /PC` annotation fires JS on page close | Code execution on close (Acrobat) |
138
+
| test21.pdf |`create_malpdf21()`| PortSwigger research | SubmitForm SubmitPDF |`/SubmitForm` with Flags 256 sends entire PDF | Full PDF content exfiltration |
139
+
| test22.pdf |`create_malpdf22()`| PortSwigger research | JS submitForm() |`this.submitForm()` with `cSubmitAs: "PDF"`| PDF content submission (Acrobat) |
| test24.pdf |`create_malpdf24()`| PortSwigger research | Text field SSRF | Widget `/Tx` field with `submitForm()` POST | Blind SSRF via form data |
142
+
| test25.pdf |`create_malpdf25()`| PortSwigger research | Content extraction |`getPageNthWord()` reads all text and exfiltrates | Rendered text exfiltration |
143
+
| test26.pdf |`create_malpdf26()`| PortSwigger research | Mouseover trigger |`/AA /E` annotation fires JS on mouse enter | Code execution on hover (PDFium) |
144
+
| test27.pdf |`create_malpdf27()`| PortSwigger research | Hybrid payload | JS OpenAction + Widget button in single PDF | Targets both Acrobat and Chrome |
145
+
| test28.pdf |`create_malpdf28()`| PortSwigger research | URL hijacking | Unescaped parens inject new `/URI` action | Click redirection via PDF-Lib/jsPDF |
146
+
| test29.pdf |`create_malpdf29()`|CVE-2024-4367 | FontMatrix injection | Type1 font `FontMatrix` string breaks out of `c.transform()`| Arbitrary JS execution in PDF.js (Firefox < 126) |
147
+
| test30.pdf |`create_malpdf30()`| PDF101 research | External XObject stream | Image XObject fetches data from remote URL via `/FS /URL`| Silent callback via page rendering (no actions/JS) |
148
+
| test31.pdf |`create_malpdf31()`| PDF101 research | Thread action |`/S /Thread` with remote FileSpec | Network callback via thread reference |
149
+
| test32.pdf |`create_malpdf32()`| PDF101 research | Launch with print |`/Launch` with `/Win << /O /print >>` forces remote fetch | Network callback via print operation |
150
+
| test33_1.pdf |`create_malpdf33_1()`| PDF101 research | JS: `this.submitForm()`| Acrobat JS form submission callback | Acrobat Reader |
| test33_7.pdf |`create_malpdf33_7()`| PDF101 research | JS: `this.importDataObject()`| Acrobat JS data import | Acrobat Reader |
157
+
| test33_8.pdf |`create_malpdf33_8()`| PDF101 research | JS: `app.openDoc()`| Acrobat JS open document | Acrobat Reader |
158
+
| test33_9.pdf |`create_malpdf33_9()`| PDF101 research | JS: `fetch()`| Web API callback (PDF.js/browser) | Firefox/PDF.js |
159
+
| test33_10.pdf |`create_malpdf33_10()`| PDF101 research | JS: `XMLHttpRequest`| Web API callback (PDF.js/browser) | Firefox/PDF.js |
160
+
| test33_11.pdf |`create_malpdf33_11()`| PDF101 research | JS: `new Image()`| Web API image callback (PDF.js/browser) | Firefox/PDF.js |
161
+
| test33_12.pdf |`create_malpdf33_12()`| PDF101 research | JS: `WebSocket`| Web API WebSocket callback (PDF.js/browser) | Firefox/PDF.js |
162
+
| test34.pdf |`create_malpdf34()`| PDF101 research | UNC multi-vector | NTLM theft via XObject, GoToR, Thread, URI, JS (8 methods) | Credential theft via SMB |
163
+
| test35.pdf |`create_malpdf35()`| PDF101 research | Names dictionary |`/Names /JavaScript` catalog-level auto-execute trigger | Alternative JS execution trigger |
164
+
165
+
</details>
166
+
162
167
## Todo: Obfuscation methods not yet implemented
163
168
-**Empty-password PDF encryption** — Encrypt all strings/streams with empty user password. Document opens without prompting but static analysis tools cannot read content. Biggest gap in current obfuscation. Ref: [Didier Stevens](https://blog.didierstevens.com/category/pdf/), [How secure is PDF encryption?](https://www.decalage.info/hugo/file_formats_security/pdf/)
164
169
-**Object streams (ObjStm)** — Hide PDF objects inside compressed stream containers. Simple parsers (including PDFiD without `-O` flag) miss objects entirely. Ref: [PDF spec ISO 32000 §7.5.7](https://www.iso.org/standard/63534.html)
0 commit comments