Skip to content

Commit 2e2918d

Browse files
jonaslejonclaude
andcommitted
Move test matrix into collapsible section
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>
1 parent 5782abc commit 2e2918d

1 file changed

Lines changed: 57 additions & 52 deletions

File tree

README.md

Lines changed: 57 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -34,58 +34,6 @@ Example with obfuscation:
3434
python3 malicious-pdf.py https://your-interact-sh-url --obfuscate 2
3535
```
3636

37-
## Complete Test Matrix
38-
39-
| Test File | Function | CVE/Reference | Attack Vector | Method | Impact |
40-
|-----------|----------|---------------|---------------|---------|---------|
41-
| test1.pdf | `create_malpdf()` | CVE-2018-4993 | External file access | `/GoToE` action with UNC path | Network callback via file system |
42-
| test1_1.pdf | `create_malpdf()` | CVE-2018-4993 | External file access | `/GoToE` action with HTTPS URL | Network callback via HTTPS |
43-
| test2.pdf | `create_malpdf2()` | XFA form submission | Form data exfiltration | XDP form with submit event | Automatic form submission |
44-
| test3.pdf | `create_malpdf3()` | JavaScript injection | Code execution | `/OpenAction` with `app.openDoc()` | External document loading |
45-
| test4.pdf | `create_malpdf4()` | CVE-2019-7089 | XSLT injection | XFA with external XSLT stylesheet | UNC path callback |
46-
| test5.pdf | `create_malpdf5()` | PDF101 research | URI action | `/URI` action type | DNS prefetching/HTTP request |
47-
| test6.pdf | `create_malpdf6()` | PDF101 research | Launch action | `/Launch` with external URL | External resource execution |
48-
| test7.pdf | `create_malpdf7()` | PDF101 research | Remote PDF | `/GoToR` action | Remote PDF loading |
49-
| test8.pdf | `create_malpdf8()` | PDF101 research | Form submission | `/SubmitForm` with HTML flags | Form data submission |
50-
| test9.pdf | `create_malpdf9()` | PDF101 research | Data import | `/ImportData` action | External data import |
51-
| test10.pdf | `create_malpdf10()` | CVE-2017-10951 | JavaScript execution | Foxit `this.getURL()` callback | Network callback via Foxit Reader |
52-
| 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 |
54-
| test13.pdf | `create_malpdf13()` | Request injection | CRLF header injection | XFA submit `textEncoding` CRLF | HTTP header manipulation |
55-
| test14.svg | `create_malpdf14()` | ImageMagick shell injection | Shell injection via SVG/MSL | SVG-MSL polyglot `authenticate` attribute | Remote code execution via ImageMagick |
56-
| test15.pdf | `create_malpdf15()` | PDF specification | FormCalc header injection | XFA FormCalc `Post()` with custom headers | Arbitrary HTTP header injection |
57-
| test16.pdf | `create_malpdf16()` | PDF specification | JavaScript via GotoE | `/GoToE` with `javascript:` URI | Browser XSS when PDF embedded via `<embed>`/`<object>` |
58-
| test17.pdf | `create_malpdf17()` | CVE-2014-8452 | XXE injection | `XMLData.parse()` external entity | XML external entity resolution |
59-
| test18.pdf | `create_malpdf18()` | PortSwigger research | Annotation URI injection | Unescaped parens inject JS action via duplicate `/A` key | XSS via PDF-Lib/jsPDF output |
60-
| test19.pdf | `create_malpdf19()` | PortSwigger research | PV auto-execution | `/AA /PV` Screen annotation fires JS on page visible | Automatic code execution (Acrobat) |
61-
| 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) |
64-
| test23.pdf | `create_malpdf23()` | PortSwigger research | Widget button injection | Invisible `/Btn` widget covering page, JS on click | Code execution (Chrome/PDFium) |
65-
| 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 |
75-
| test33_2.pdf | `create_malpdf33_2()` | PDF101 research | JS: `this.getURL()` | Acrobat JS URL fetch | Acrobat Reader |
76-
| test33_3.pdf | `create_malpdf33_3()` | PDF101 research | JS: `app.launchURL()` | Acrobat JS launch URL | Acrobat Reader |
77-
| test33_4.pdf | `create_malpdf33_4()` | PDF101 research | JS: `app.media.getURLData()` | Acrobat JS media fetch | Acrobat Reader |
78-
| test33_5.pdf | `create_malpdf33_5()` | PDF101 research | JS: `SOAP.connect()` | Acrobat JS SOAP connection | Acrobat Reader |
79-
| test33_6.pdf | `create_malpdf33_6()` | PDF101 research | JS: `SOAP.request()` | Acrobat JS SOAP request | Acrobat Reader |
80-
| 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-
8937
## Purpose
9038
- Test web pages/services accepting PDF files
9139
- Test security products
@@ -159,6 +107,63 @@ PDF.js v5.6.205 blocks all callback vectors. The CVE-2024-4367 FontMatrix inject
159107

160108
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.
161109

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 |
116+
|-----------|----------|---------------|---------------|---------|---------|
117+
| test1.pdf | `create_malpdf()` | CVE-2018-4993 | External file access | `/GoToE` action with UNC path | Network callback via file system |
118+
| test1_1.pdf | `create_malpdf()` | CVE-2018-4993 | External file access | `/GoToE` action with HTTPS URL | Network callback via HTTPS |
119+
| test2.pdf | `create_malpdf2()` | XFA form submission | Form data exfiltration | XDP form with submit event | Automatic form submission |
120+
| test3.pdf | `create_malpdf3()` | JavaScript injection | Code execution | `/OpenAction` with `app.openDoc()` | External document loading |
121+
| test4.pdf | `create_malpdf4()` | CVE-2019-7089 | XSLT injection | XFA with external XSLT stylesheet | UNC path callback |
122+
| test5.pdf | `create_malpdf5()` | PDF101 research | URI action | `/URI` action type | DNS prefetching/HTTP request |
123+
| test6.pdf | `create_malpdf6()` | PDF101 research | Launch action | `/Launch` with external URL | External resource execution |
124+
| test7.pdf | `create_malpdf7()` | PDF101 research | Remote PDF | `/GoToR` action | Remote PDF loading |
125+
| test8.pdf | `create_malpdf8()` | PDF101 research | Form submission | `/SubmitForm` with HTML flags | Form data submission |
126+
| test9.pdf | `create_malpdf9()` | PDF101 research | Data import | `/ImportData` action | External data import |
127+
| test10.pdf | `create_malpdf10()` | CVE-2017-10951 | JavaScript execution | Foxit `this.getURL()` callback | Network callback via Foxit Reader |
128+
| 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 |
130+
| test13.pdf | `create_malpdf13()` | Request injection | CRLF header injection | XFA submit `textEncoding` CRLF | HTTP header manipulation |
131+
| test14.svg | `create_malpdf14()` | ImageMagick shell injection | Shell injection via SVG/MSL | SVG-MSL polyglot `authenticate` attribute | Remote code execution via ImageMagick |
132+
| test15.pdf | `create_malpdf15()` | PDF specification | FormCalc header injection | XFA FormCalc `Post()` with custom headers | Arbitrary HTTP header injection |
133+
| test16.pdf | `create_malpdf16()` | PDF specification | JavaScript via GotoE | `/GoToE` with `javascript:` URI | Browser XSS when PDF embedded via `<embed>`/`<object>` |
134+
| test17.pdf | `create_malpdf17()` | CVE-2014-8452 | XXE injection | `XMLData.parse()` external entity | XML external entity resolution |
135+
| test18.pdf | `create_malpdf18()` | PortSwigger research | Annotation URI injection | Unescaped parens inject JS action via duplicate `/A` key | XSS via PDF-Lib/jsPDF output |
136+
| test19.pdf | `create_malpdf19()` | PortSwigger research | PV auto-execution | `/AA /PV` Screen annotation fires JS on page visible | Automatic code execution (Acrobat) |
137+
| 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) |
140+
| test23.pdf | `create_malpdf23()` | PortSwigger research | Widget button injection | Invisible `/Btn` widget covering page, JS on click | Code execution (Chrome/PDFium) |
141+
| 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 |
151+
| test33_2.pdf | `create_malpdf33_2()` | PDF101 research | JS: `this.getURL()` | Acrobat JS URL fetch | Acrobat Reader |
152+
| test33_3.pdf | `create_malpdf33_3()` | PDF101 research | JS: `app.launchURL()` | Acrobat JS launch URL | Acrobat Reader |
153+
| test33_4.pdf | `create_malpdf33_4()` | PDF101 research | JS: `app.media.getURLData()` | Acrobat JS media fetch | Acrobat Reader |
154+
| test33_5.pdf | `create_malpdf33_5()` | PDF101 research | JS: `SOAP.connect()` | Acrobat JS SOAP connection | Acrobat Reader |
155+
| test33_6.pdf | `create_malpdf33_6()` | PDF101 research | JS: `SOAP.request()` | Acrobat JS SOAP request | Acrobat Reader |
156+
| 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+
162167
## Todo: Obfuscation methods not yet implemented
163168
- **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/)
164169
- **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

Comments
 (0)