11

Site legit file image_upload.php was used to upload file 89471928047.php.jpg Which was simple file upload form that copy tmp file to same images folder. How they managed to execute it and upload other files trough it. Someone know how this is possible? PHP version was 5.1.6 that being updated exactly hour ago or after by schedule with host to 5.3.8... what a, coincidence?

AstroCB
  • 11,800
  • 20
  • 54
  • 68
JohnA
  • 1,785
  • 7
  • 27
  • 34
  • was it a hack? are you asking how to prevent? What does 89471928047.php.jpg contain? did you try to substitute it with a simple PHP file doing an echo and try to execute to see what happens? – stivlo Nov 06 '11 at 04:56
  • Question is if they able to upload php with .jpg extension how can they execute it from outside maybee is because php was v5.1.6 – JohnA Nov 06 '11 at 05:09
  • 1
    @JohnA This likely has nothing to do with the version of PHP you're running. – Sampson Nov 06 '11 at 05:18

3 Answers3

16

Check your .htaccess file

Using AddType in your .htaccess file, you can add many other extensions from which PHP can be ran. This is generally how .html extensions can be used while still using PHP within themselves. So, yes, it's possible:

AddType application/x-httpd-php .jpg

You can test this if you like.

  1. Create a directory with two files: .htaccess and test.php.jpg
  2. Set content of .htaccess to AddType application-x-httpd-php .jpg
  3. Set content of test.php.jpg to <?php echo 'foo'; ?>
  4. Access test.php.jpg through localhost

If all goes as planned, "foo" will be output to your screen. You could expand upon this to move /tmp files around if you like.

Definitely something you want to be very careful with.

Check exposed calls to include/require

Another way this could have been done is through a call to require() or include() (or any of the _once() methods) where by the hacker was able to load in his badfile.php.jpg file that had been uploaded under the guise of an innocent image:

<?php

  include $_GET["file"];

?>

In the above case (simplified example), the hacker could pass in a path to his .php.jpg file and have its contents loaded in and processed as PHP code.

Other (frightening) ideas

Require, Include, and their related methods aren't the only ways you can process external scripts - unfortunately you can use eval() as well. I would hope that you have none of this going on though. If you did have any scripts on your server that were using any one of the file functions to read the contents of another script, and then eval() to evaluate that content as PHP, this could also provide a gaping security hole in your website.

Community
  • 1
  • 1
Sampson
  • 251,934
  • 70
  • 517
  • 549
  • 1
    i think he's asking how an hacker could do it, NOT how he can do it. besides if you map .jpg all jpg files will be executed by PHP which is hardly a good idea. But maybe, yes he could check if his .htaccess files have been tampered. I think we need more info. (comment reposted due to spelling error). – stivlo Nov 06 '11 at 05:04
  • There was not .htaccess they managed somehow overflow site i think and make it process jpg as php... there was no .htaccess on site at all. – JohnA Nov 06 '11 at 05:07
  • 1
    @stivlo I was merely showing one method by which a hacker could do this. One minor correction, all .jpg files within the directory of the affected .htaccess file would be processed as PHP. Hopefully this helps the OP find the problem. – Sampson Nov 06 '11 at 05:07
  • @JonathanSampson, yes in fact I added *maybe, yes he could check if his .htaccess files have been tampered.* – stivlo Nov 06 '11 at 05:11
  • @stivlo The include was my second idea as well ;) – Sampson Nov 06 '11 at 05:14
  • 1
    @JohnA You should check your site, as stivlo said, for dangerous uses of `include`, `require`, `include_once`, and `require_once` that accept input which could have been tampered with by users. – Sampson Nov 06 '11 at 05:15
  • I removed that from the comment, because as writing, it was growing longer and longer, so in the next few minutes i'm evolving it as an answer. – stivlo Nov 06 '11 at 05:17
  • "AddType" controls the mime type that apache responds with for a given file type. "AddHandler" makes apache use php to handle requests for .php files. – txyoji Apr 20 '15 at 19:31
8

The problem is caused by your server using the default /etc/httpd/conf.d/php.conf:

rpm -ql php-5.1.6-39.el5_8
/etc/httpd/conf.d/php.conf
/usr/lib64/httpd/modules/libphp5-zts.so
/usr/lib64/httpd/modules/libphp5.so
/var/lib/php/session
/var/www/icons/php.gif

The content of /etc/httpd/conf.d/php.conf is:

#
# PHP is an HTML-embedded scripting language which attempts to make it
# easy for developers to write dynamically generated webpages.
#
<IfModule prefork.c>
  LoadModule php5_module modules/libphp5.so
</IfModule>
<IfModule worker.c>
  # Use of the "ZTS" build with worker is experimental, and no shared
  # modules are supported.
  LoadModule php5_module modules/libphp5-zts.so
</IfModule>

#
# Cause the PHP interpreter to handle files with a .php extension.
#
AddHandler php5-script .php
AddType text/html .php

Please note the last line AddHandler php5-script .php . This is causing that problem and needs to be replaced with a more secure configuration

You can read more about it and how to apply a fix here ( see last reply):

http://core.trac.wordpress.org/ticket/11122

also see this:

https://bugzilla.redhat.com/show_bug.cgi?id=885839

ion daniel
  • 81
  • 1
  • 3
  • Why `AddHandler php5-script .php` could be exploited to handle a .php.jpg file? The simple fact that the file extension has .php in the middle can cause it to be handled by PHP interpreter? – kaneda Mar 25 '14 at 15:57
  • 1
    @kaneda yes the interpreter parse only for .php and ignore anything after. For example you can use blabla.php.blabla and it will still interpret it as php script. – ion daniel Jun 20 '14 at 09:14
  • @kaneda It's a feature of mod_mime which will match the .php anywhere in the file name. http://httpd.apache.org/docs/2.2/mod/mod_mime.html#multipleext – txyoji Apr 20 '15 at 19:26
8

Your image_upload.php is insecure, check the following:

  1. does it allow only image extensions? Otherwise it would be possible to upload directly a PHP file. (I think you're covered on this one, but double check).
  2. does it check that the uploaded file is indeed an image? Here the answer is no, it doesn't check the contents. Add this check! With this single step you'd close the initial breach.

To check if it's an image you can run getimagesize on the file, it will return FALSE if it's not an image.

How is it possible to execute that file? First, how do you know it has been executed? Did you see side effects?

  1. One way is that they could have tampered other files
  2. A second way, perhaps more probable is that they used unsanitized inputs from your scripts to either include or eval the code. In this case you can find proof only by looking at the logs.

How to look at the logs?

Check the date and time of the uploaded file and start to look around there for suspicious activity (look at strange url parameters). Once you've find one or more IP address, doing evil things, grep the log for that (those) IPs, to see the whole story.

Another important info to know is, did you write the site or use a CMS or similar and in this case what is it and what version? You've to check published vulnerabilities and upgrade in case.

stivlo
  • 77,013
  • 31
  • 135
  • 193
  • Embedded comments in JPG files can still get around the getimagesize() check. It will eval as a legit JPG but still contain code. – jharrell Sep 24 '14 at 00:57
  • using getimagesize() to determine whether its image or not is really a bad idea because one can easily embed dangerous code in a good looking image. Check this link that shows how php scripts can be embedded in an image. http://php.webtutor.pl/en/2011/05/13/php-code-injection-a-simple-virus-written-in-php-and-carried-in-a-jpeg-image/ – Bikal Basnet Dec 27 '14 at 19:17
  • @BikalBasnet as explained in the article you linked the code inside an image can be executed because of the improper use of require to display an image, not because of getimagesize. – stivlo Dec 27 '14 at 20:07
  • @stivlo You are right that this is exploited while using require/include etc but lets say that that you have a page called index.php which loads the page from value passed in a the parameter by using require($_GET['page']) eg: index.php?page=page/aboutus.php. In this case what if someone uploaded the bad image in upload/bad.jpg and requested the server to run index.php?page=upload/bad.jpg. This time pretty bad stuff can happen. can't it? – Bikal Basnet Dec 27 '14 at 22:02
  • You shouldn't have a require like that in the first place, the fault is there. However if you don't check with getimagesize() a plain php script with jpg extension would be accepted, which is even worse than not checking. So what do you suggest to check more? – stivlo Dec 27 '14 at 22:10