Menu

Massive WordPress Hack Seems To Be Underway

A coworker of mine brought this thing to my attention yesterday. As Sucuri reports, there seems to be a massive malware infection that is breaking WordPress sites left and right.

This day at the office was marked by flurry of customer calls complaining their websites were somehow broken. To make things worse – as soon as website is restored from backup, it immediately gets hacked again. So, what is happening?

It turns out to be that this particular WordPress hack attack is a combo, a double-tap if you will, of malware automatically latching itself onto any and every file it can get its hands on, and adding admin users into database as well.

This particular attack is blamed on vulnerability in old version of MailPoet WordPress plugin, which underlines the importance of keeping your plugins up-to-date.

How to get rid of this annoyance?

Really hard, unless you have a backup. As I investigated those incidents, it became obvious that this malware is made in such a way that it will add its program code to as many files as possible. On some of our clients accounts I’ve found thousands of files containing malicious code.

Since some of affected files had common elements (a signature) I used this command to scan for it. Beware – it is quite resource intensive:

But fixing each and every file by hand is truly an unrewarding task. So, having a good backup solution for situation like this is priceless.

Ideally, you would have a recent backup so wiping and restoring all of the files and databases on affected sites would not be an issue. Alternatively, you may restore only files but it is very important that you also remove the admin user that got maliciously inserted into WordPress database.

To fix this WordPress hack:

remove all files from affected account (or, move them to a folder – in case you need something like recent images etc)

wait a couple of minutes so malicious scripts can time out

remove that unusual admin user with really high ID from wp_users table

restore files from backup

update your WordPress, plugins and themes as well

To close the gap between file restore and WP update, you may use .htaccess with Deny from All, except of course your IP address.

order deny,allow
deny from all
allow from 1.2.3.4

Also, restarting the web server after infected files have been removed seems like a good idea, if possible. It can help purge memory from running malicious scripts.

Detecting compromised accounts

After dealing with clients that have noticed the problem, we started wondering how many oblivious ones have been affected by this WordPress hack attack too? And since doing find /home/*/… would be a real no-no during peak hours on shared hosting environment, I’ve created a php script that hunts for possibly hacked sites using a thing we found they all have in common – admin user with really, really high ID.

You can download the script here. Its purpose is to find compromised accounts in shared hosting environment. Please note, it is pretty much beta and assumes that WordPress is installed with table prefix “wp_”, but it can be improved should enough people find it useful.

To run it you need to have MySQL root username and password in text file looking like example below. On cPanel server this file should already exist at /root/.my.cnf:

user=root
password="mysql-root-password-here"

You probably need to be root to run it, and it should be made executable (chmod u+x) beforehand.

Usage example:

./wphunt.php -cnf /root/.my.cnf -host localhost -port 3306

Host and port is optional, run without arguments to get more information on usage.

It will display word ‘Hacked?’ next to WordPress databases containing user ID > 1000000. The ID will also be displayed next to it, however bear in mind that this particular malware may insert more than one admin user into a database. It’s best to take a look using phpMyAdmin or some other database front-end.

To remove such users delete their entries using phpMyAdmin; or simply execute something similar to this for each ID you believe should not be there:

DELETE FROM wp_users WHERE ID=1001001;

Be careful with that one so you don’t end up removing users not related to this WordPress hack though. As a bonus, the script will also display databases indicating if MailPoet plugin has been installed. Since vulnerability in MailPoet has been identified as possible vector of the attack, you can use this information to check if it has been updated to the latest version.

So, how this malware attack works?

This beast turned out to be the most difficult thing for me to decode so far. The level of obfuscation and polymorphism is mind-boggling. After lots of manual work I finally decoded one of the files, and I am quite frustrated that I haven’t been able to determine modus operandi how infection is spread to other files.

I have hoped to find executable RFI stuff, c99 shells etc but the file I have decoded seems only to contain a reporting function which send stuff like user agent, referer, IP address, etc to some websites, and in turn inject returned content into the body of infected page before displaying it. Worth noting is use of its own encryption algorithm to garble data before transmission.

The websites referenced in this decoded piece of malware, used for communication and content injection, were:

54dfa1cb.com
33db9538.com
e5b57288.com
9507c4e8.com

I guess either I missed RFI somewhere, or the attack is composed of several separate scripts with different purposes. Interesting thing, to say at least.

It depends on other factors too, having only suPHP does not guarantee protection from all attacks that may happen in shared hosting environment. For example, if Apache version is old and vulnerable to symlink exploit, it may be possible for attacker from other unrelated hosting account to read your wordpress configuration, get your mysql username and password, and then inject admin user into your website.

Once they know your mysql user and pass, they can do that again and again – so changing mysql password after website was hacked is good idea. You can change wp-config.php file permissions to 0600 to prevent that in the future.

Also, make sure you have updated to latest version of wordpress, plug-ins and themes. If darn thing keeps coming back, attackers may have left backdoor file somewhere on your site (they usually do). Browse directories on your site, perhaps you can spot visually files that are not supposed to be there?

It’s pain in the a** but sometimes only way to be 100% sure is to download your entire website and check all files (wordpress core, plug-ins, themes) versus published versions for differences.