2

I have a small web application. Because it is necessary to upload some files I check the file extensions with a whitelist (tgz, jpg, png, pdf, zip, rar, txt, gif, py, c, rb). In addition to that, I hash the filenames with md5 so e.g. when the user uploads the file exploit.php.jpg it is renamed to 526a8f9f3497b5a69bc4523ba0c6aacd.jpg.

There is neither a MIME-Type verification nor a getimagesize() or resize-function, if it is a picture. Because of that it is possible to upload a php-file that is just renamed to exploit.jpg

Although this seems to be very risky and the user also knows, where this file exists on my server (/images/526a8f9f3497b5a69bc4523ba0c6aacd.jpg), I am not able to run this file as a .php.

When I try to open /images/526a8f9f3497b5a69bc4523ba0c6aacd.jpg%00 or /images/526a8f9f3497b5a69bc4523ba0c6aacd.php and so on.. I only get "file not found" (for .php) or "image can not be displayed" (for jpg, gif).

Does anyone know if and how it is possible to exploit that fileupload?

UndercoverDog
  • 612
  • 2
  • 17
zarathustra
  • 121
  • 1
  • 5
  • 2
    py and rb? Do you have an interpreter that would execute these files? – KDEx Nov 18 '14 at 17:35
  • 5
    Have you considered null byte injections? Meaning upload a file called exploit.php%00.jpg? Personally I think you should read the first bytes of the file in order to determine the file header. File extension checking by itself is not sufficient enough in my humble opinion. – Jeroen Nov 18 '14 at 18:34
  • Have a look at how you can determine the file header: http://it.php.net/manual/en/function.finfo-file.php – Jeroen Nov 18 '14 at 18:44
  • @KDEx there is no python or ruby interpreter installed. When I try to open these files, my browser only offers to download these files – zarathustra Nov 18 '14 at 21:52
  • In a vacuum with the correct web server config, this seem sound. I will assume that your file validation code isn't flawed. However it may be possible to chain attacks as stated in other answers, local file include bugs or hosting an indirect attack like a zipped virus, cross site scripting or phishing page may still be possible and can attack users of the website. While your design seems ok, implementation flaws could still lead to code execution. I have seen fileupload validation that calls `/usr/bin/file uploadfilename` for mimetypes and would lead to command injection – wireghoul Jul 16 '21 at 00:07
  • What happens after the files are uploaded? Are they made available (served to the user) via your app at all? (upload malicious file, use your site as a host). Are they processed in some way? (you would need to make sure the software used to process the files is fully robust also, or a vuln. in it could be exploited). Filtering and processing based on filename (metadata) is likely insufficient (IMHO). – Slartibartfast Jul 16 '21 at 01:32
  • It seems fine to me. Assuming the presence of an LFI is a circular argument: will this make my site vulnerable assuming it is already? You can use some defense in depth though: mark `/images/` to be served statically (i.e. don't invoke the PHP interpreter at all for this directory) and see if you can run (or demote) the PHP interpreter under a different user in the same group as the web-server user. Then once uploaded assign the image to the web-server user with 620 permissions (assuming the image only needs to be served). – Margaret Bloom Sep 19 '22 at 15:13

3 Answers3

2

It's possible if you have a LFI in hand. Imagine you have a page like this

http://victimIP&Port/?page=contact.php

http://victimIP&Port/?page=../../../../var/www/payload.jpg <- not found since the filename hash

Then it could be executed like PHP files. In your case

http://victimIP&Port/?page=../../../../var/www/.../images/md5.jpg

You just need to find the LFI vendor for the hashed files.

Alvin Smith
  • 141
  • 3
1

The file upload vulnerability could be exploited in combination with a local file inclusion bug to attack the server side. Or a malicious file (ie: pdf) could be uploaded to attack an end user with administrative privileges for example.

Your approach seems reasonable enough, however the devil is always in the details and you would need someone with security knowledge to take a look at your source code or running application for a more robust assessment.

wireghoul
  • 5,745
  • 2
  • 17
  • 26
0

Don't trust a whitelist, it can be bypassed:

Content-type: image/jpeg; filename=exploit.php

Hashing the files does not protect you if the attacker can access the file direct:

<img src='http://yoursite.net/images/526a8f9f3497b5a69bc4523ba0c6aacd.jpg>

You could create a PHP script to read the file and send the contents to the user, unchanged. This way, the attacker will never reference the file on your server, and whatever server side exploit he could upload would not trigger:

<?php

$filename = getFilenameFromDatabase();
// e.g: $DOCROOT/images/exploit.rb.exe.py.bat.scr.php.jpg
header("Content-type: image/jpeg");
readfile("$filename");
?>

Just make sure to filter the path to the files, otherwise the attacker can get read access of your files.

ThoriumBR
  • 50,648
  • 13
  • 127
  • 142
  • Thank you for your answer. So the only way to use this vulnerability is, when I can manage to include the uploaded file in my php code? I tried `` but nothing happend; only a "failed image" symbol is shown. – zarathustra Nov 19 '14 at 15:20
  • 4
    The whitelist bypass does not apply there. He whitelists the extensions, not MIME types, so your attack will not work. – v6ak Jan 17 '15 at 18:44
  • He didn't post the extension validation code so it may still be vulnerable to bypasses. – wireghoul Jan 28 '15 at 04:59
  • Why OP should not trust a white list, assuming the extension validation is correct (php already has a function for this)? What the `img` is supposed to do besides fetching a public image? – Margaret Bloom Sep 19 '22 at 15:09
  • There are functions to see if a image is a image, but there are certain kinds of files that may behave on distinct ways depending on who is calling them, they are called polyglots. You can have a jpeg file encapsulating a PHAR file, and that single file will be identified as jpeg by image functions, and executed as PHAR by PHP. – ThoriumBR Sep 19 '22 at 15:44