Description:
116Written by: 0x4d5a
A pdf conversion service. What could go wrong?
hax.allesctf.net:3333
Introduction
A website that converts editable content into a pdf, it uses a known tool named tcpdf , since the source code is given lets check its version at TCPDF/tcpdf.php
1 | $ cat pdfcreator/TCPDF/tcpdf.php | head -10 |
The version is 6.2.13 searching online for known vulnerabilities https://www.cvedetails.com/cve/CVE-2018-17057/ :
1 | An issue was discovered in TCPDF before 6.2.22. |
So it’s possible possible to perform an unserialization attack using phar://wrapper wrappers, the deserialization is triggered on functions like file_exists (line 164), getimagesize() (line 171) and file_get_contents() (line 209) in the file pdfcreator/TCPDF/include/tcpdf_images.php:
1 | .... // pdfcreator/TCPDF/include/tcpdf_images.php |
This unserialization only occurs when using phar:// wrappers, but we can’t straightly upload a phar file because of the checks presented in index.php
1 | .... // pdfcreator/index.php |
This checks can be easily bypassed, the first check can easily bypassed by changing filename from exploit.phar to exploit.jpg.
The second check only checks the header we can easily append to our phar file a jpg header before our phar file. The objective is to unserialize a php class that can gives us RCE or a fileread of file flag.php, there is a good class we can use for this:
1 | // pdfcreator/creator.php |
Exploit
We want to trigger functions like __construct or __destruct after object deserialization, __construct is empty so it’s not useful but __destruct is!
It can give us a file_read which is enough for what we need, but for this we need to change tmpfile variable to ./flag.php making the extesion to be diferent from pdf reading the file content instead.
I tried to manually create the phar file but failed miserly, while debugging locally with I was having some troubles passing through the function getimagesize due to some errors on jpg signatures eventually I managed to solve the problem but in the end the function __destruct was not triggering and I ended up giving up.
Eventually I found phpggc which can create for us the fake jpg file with the phar embed on it, we just need to create our own template for this:
1 | $ git clone https://github.com/ambionics/phpggc |
Modifying the chain.php at gadgetchains/Alles/FR/1/:
1 |
|
Generating the payload with phpggc:1
./phpggc Alles/FR1 flag.php -f -pj ../dummy.jpg -o ../exploit.jpg
The option -f uses a technique named fast destructor to make sure the object deserialized triggers __destruct, option -pj is to create a jpeg-phar from sample dummy.jpg(any valid jpg works) the one I used was this one, -o option is to specify the output of the payload to a file location.
After uploading the file make sure you modify the img html tag to use phar:// wrappers:
1 | <img src="phar://./upload/708697c63f7eb369319c6523380bdf7a_6.jpg" width="10" height="10"> |
Finally writing a python script to automate this actions:
1 | import requests |
Running and getting the flag:
1 | $ python webPwn.py |