SSRF to Local File read through HTML Injection in PDF file
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)
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!!
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>
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>
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!!