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:
find /home/insert-user-here/public_html -regextype posix-egrep -type f -iregex ".*\.php" -print0 | xargs -0 grep -li "x2f.50.x2e.52"
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 18.104.22.168
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:
You probably need to be root to run it, and it should be made executable (chmod u+x) beforehand.
./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.