I have a client that has multiple Wordpress installations, which he didn't keep up to date. As a result, he got hacked. While I try to find how the hackers got in, and fix the problem permanently, I'm trying to create a script to fix them quickly, automatically.
I found this script, which does what I want: http://designpx.com/tutorials/wordpress-security/
It automatically removes the <?php eval(base64_decode("aWY..."); ?>
from every php file, but the regex it's using to do this, removes also <?php get_header(); ?>
if it follows the malicious code.
So, what I want is to change it, so it only removes the malicious code, but not the first line of php code as well. Here's the part of the script that does the replacing:
find $dir -name "*.php" -type f \
|xargs sed -i 's#<?php /\*\*/ eval(base64_decode("aWY.*?>##g' 2>&1
What would I have to change, so it stops at the first ?>
, and not at the second?
Note: I know this is a quick, temporary fix, but it will do until the client makes up his mind about which sites he wants to fix, an which to erase.
Back up everything and scan it with your antivirus. In your server delete all wp files except wp-config.php then go to wordpress.org download the latest version. Extract to your computer and upload.
Check your backup theme files for infections.
Apart from the comments advising a reinstall, the regex question at hand might be greediness. The
.*?
placeholder ought to match the shortest amount of characters, butsed
might have some limitations regarding line length etc. (Not sure.)But for constraining it further you could use
[^>]*
in its place:This will ensure it can't run over a closing
?>
. Thebase64
couldn't possibly contain this anyway.No need for some crazy scripts and whatnot. Hacks on PHP cannot work unless the file is infected. Removing it solved the problem.
And yes, it's possible to do even if you have multiple wordpress installations on the same server (WHY?!).