Part 1 — Uncovering the Vulnerability: How Attackers Can Exploit SSRF via PDF Generation (wkhtmltopdf)

Yash Parab
4 min readMay 30, 2023

--

Hello hackers, I’m excited to share my very first blog on Medium. It’s a thrilling and challenging experience to express my ideas and perspectives in writing, and I can’t wait to see where this journey takes me.

Recon

Initially, I approached the web/mobile application and its API with low expectations due to the limited functionality that only allows users to create a notepad and perform basic actions. However, within a few hours, I found several P2 (XSS) vulnerabilities, which made the scope more interesting than anticipated. As I continued testing, I discovered the application is using (WKHTMLTOPDF — 0.12.6) from a Chrome extension (wappalyzer), The feature that allows users to generate a PDF, which piqued my interest. In past, I read a blog on SSRF using PDF Generation by Nahamsec’s “Owning the cloud through SSRF and PDF generators”.

While exploring the application and its features, I stumbled upon a parameter that enabled me to add items and generate a PDF of them. I proceeded to inject various payloads into the note parameters:

<iframe src=http://evil.com width=300 height=200>
<iframe src=http://169.254.169.254/latest/meta-data width=300 height=200>

However, I had no success, as the iframe was unable to communicate with other domains due to the implemented Content-Security Policy.

As shown in Exhibit 1.1, I have injected the payload in the “noteparameter.

Exhibit 1.1

As shown in Exhibit 1.2, The payload is injected and iFrame is loaded but it was not able to communicate with other domains due to the implemented Content-Security-Policy.

Exhibit 1.2

As shown in Exhibit 1.3, A PDF was generated by clicking on “Export to PDF”.

Exhibit 1.3

As shown in Exhibit 1.4, I opened the PDF and was empty and didn’t load with iFrame in it.

Exhibit 1.4

Note: “I attempted using URI schemas such as file:///, dict:///, ftp:///, and gopher:/// to access internal data and trigger corresponding actions on the server, but unfortunately, — unsuccessful

Let’s Begin the real fun!🎉

Eventually, I figured out where to inject the payload.

I injected the payload into the title, generated the PDF, and suddenly the iframe loaded with localhost in it. — success!

Crafted the payload like this:

<iframe src=http://localhost width=300 height=200>

As shown in Exhibit 2.1, The Payload is injected in the parameter “title” and is reflected in the response.

Exhibit 2.1

As shown in Exhibit 2.2, A PDF was generated by clicking on “Export to PDF”.

Exhibit 2.2

As shown in Exhibit 2.3, we can see that SSRF is being executed, resulting in the loading of PDF with “localhost” in the iFrame.

Exhibit 2.3
                                Part 1: Ends

Hold on to your hats, folks, because this ride’s not over yet.

linkedin.com/parab500
medium.com/parab500
twitter.com/parab500

--

--