Exploitation

All techniques assume user-controlled HTML is fed into the PDF generator.

1) JavaScript Code Execution (Server-Side XSS)

Test HTML rendering, then JavaScript execution:

<b>bold-test</b>
<script>document.write('XSS-OK')</script>

Leak server file path via window.location:

<script>document.write(window.location)</script>

Outputs often show file:///.../tmp_wkhtmlto_pdf_XXXX.html revealing server paths.

2) Server-Side Request Forgery (SSRF)

Force outbound requests by loading external resources:

<img src="http://<your-oast-domain>/ssrf-img"/>
<link rel="stylesheet" href="http://<your-oast-domain>/ssrf-css">
<iframe src="http://<your-oast-domain>/ssrf-iframe"></iframe>

If iframe responses render in the PDF (non-blind SSRF), you can read internal endpoints:

<iframe src="http://127.0.0.1:8080/api/users" width="800" height="500"></iframe>

3) Local File Inclusion (LFI)

With JavaScript

Without JavaScript

Direct tags (may be blocked):

Redirect-based LFI (if file:// blocked but redirects followed):

Server-side redirector.php:

Payload:

4) Annotations / Attachments

Leverage library-specific features to attach local files.

  • mPDF (older versions or enabled setting):

  • PD4ML:

Consult documentation for the target library and version (see metadata identification).

Notes

  • Always sanitize and encode when testing in real apps; proof in controlled labs.

  • Outbound network, file://, and JS execution are all configuration-dependent.

  • For large/binary file exfil via JS, prefer base64 with line wrapping.

Question 1 (lab walkthrough)

Goal: access an internal web app and exfiltrate the flag via PDF generator.

  1. Add a new note; test HTML injection using <b>test</b>.

  2. Only the Note body renders HTML β†’ injection confirmed.

  3. Enumerate internal ports (Apache) via LFI using JS:

  • Discover internal app on port 8000.

  1. Interact with internal app (non-blind SSRF via iframe):

  • Endpoints list shows /users.

  1. Probe /users to find key locations:

  • admin key path: /users/adminkey.txt.

  1. Exfiltrate key via Server-Side XSS + file:// read:

Answer: {hidden}

Obtain the flag (skills assessment)

  1. Visit root page, note PDF invoice generation and hint about an internal orders app.

  2. Test fields for server-side execution:

    • Comment sanitized; try title via Burp.

  • JS probe (in title):

  1. Enumerate internal ports via Apache config (in title field):

  1. SSRF to internal web app (port 8000) using iframe (in title):

  • The internal app exposes endpoints and an XML-backed / with q GET param.

  1. Exfiltrate flag via XPath injection (iframe in title):

  • Using contains on substring:

  • Alternative substring:

  • Or position-based selection:

Answer: {hidden}

Last updated