More on the blog hacking
(Visited 14804 times)I keep updating this post as I learn more. So if you’re affected, there’s new material at the bottom. I am currently running this full sweep every day, because each day I find something different. But three days ago there were twenty things, yesterday five, and today only one, so maybe I am getting closer.
Latest news 4/25/08: blog seems secure again. But be sure to do the “secret key” thing newly listed at the bottom as well!
So, I mentioned before that I was a victim of a hack. It was a spam injection attack — the one known as the Goro injection attack. But my symptoms were slightly different from some of the ones I have seen on the net, so here’s some war stories even though I suspect the blog is STILL not clean.
First, read these two posts:
- WordPress Spam Injection: ‘Goro’ hacked my blog
- Expunging the wordpress.net.in spam injection hijack
Also read the advice from Jeff Freeman in the last post on this.
OK, in addition to that advice, I also had the following problems:
Can’t get into your admin panel
In the wp_options table, the db_version was set to 0. This prevented me from accessing the admin panel, because it demanded to upgrade the database, but 0 isn’t a valid DB to be upgrading from. The fix: use SQL or PHPMyAdmin to manually set this to the correct version for your blog. For 2.3.3, it’s 6124.
Change your admin password while you’re at it.
Cleaning wp_options
In addition to the advice given there, you can look for the base64 encoded obfuscated code that is rebuilding the exploits in your database. I had already cleaned out the various “rss_9sfnp9735hf097325097” sorts of things in the wp_options table. The SQL for that is on one of the links above and looks like this:
delete from wp_options where option_name like 'rss_%' and option_name not in ('rss_language','rss_use_excerpt','rss_excerpt_length');
However, these entries are being added by code hidden in another option. The Galoppini post suggests looking for blog_headers (which isn’t there in a normal WordPress install). But in my case it was in wordpress_options, inside of wp_options. Who knows what other ways they hide it. But a visual scan will show you — simply put, there shouldn’t be any things in the wp_options table that are giant blocks of numbers and letters.
In my case, even this code was extra-obfuscated — instead of “eval( stuff )” it was actually written backwards. So I suggest doing a search of your full database for “eval” and “lave.”
In my case, there’s maybe still something somewhere adding this block of code into the database, because ten minutes after cleaning out those “rss_” entries, they’re back. Edit: I was wrong: using Search within PHPMyAdmin showed 8 results for “rss_%”. But they were all things that were supposed to be there. But we’ll see what’s up tomorrow.
Second edit: nope, there were more there this morning. So there’s still something putting them in there. That means there’s a PHP file somewhere that’s injecting it — and it could be anywhere. (At this point, I have done not one, not two, but three complete upgrades of WordPress, plus overwriting all the files many times). My next step is going to be grepping all of the files on my host looking for “base64.”
Third update: Turns out that the Dashboard makes option entries of the form “rss_8324hf98hjfsa984hf” and the like. They are cached versions of the feeds on the dashboard. So you may only have the issue if the contents of the field are a giant block of base64 encoded stuff, rather than an actual RSS feed.
Search engine redirection
If search engine results for your site point to somewhere else (in my case it was ezwebdirectory), you should check your .htaccess file. It is in the same place as your index.php file. In my case, there were a whole bunch of redirects in there for every major search engine, and a clean WordPress install didn’t catch this because I normally don’t blow away the .htaccess file.
Harden your plugins folder
Edit: another thing to do: add a blank index.html to your plugins folder. Otherwise, anyone can see what plugins you have by going to http://www.yoursite.com/wp-content/plugins, and try automated attacks against them.
Edit: yet more, I’ll just add onto the bottom of this.
PHP inserted in files
There’s also the stuff that may be inserted into your header.php, footer.php, index.php, and other files. I found a PHP line in several files that didn’t belong as well, right at the top of the file. Affected files:
- wp-includes/media.php
- wp-admin/includes/schema.php
- wp-admin/import/mt.php
- wp-content/themes/default/index.php
- wp-feed.php
And it went in today, so something added it. Best way to find these — look everywhere for dates more recent than your new install.
Fake images with code
There was also a comments_old.jpeg added into the default theme and a couple of “.giff” files buried in various places. They were actually all PHP files. Delete ’em.
Superuser accounts
Check your wp_usermeta table. The tip-off was seeing that the Manage page in the admin area showed 2 administrators for the blog even though there is only one — but only on the front page of the manage users tab. Clicking on the link to list them showed just me. So I went into the database, and I found two extra user ids that had administrator permissions. One of them was a registered user named “WordPress” — the other wasn’t even in the wp_users table. I deleted these rows out of both the wp_usermeta and out of the wp_users table. Be sure to catch all the stuff — you want to identify the user Id, and delete all rows that involve that user id — the wp_capabilities, and the wp_user_level especially.
Secret key
There’s a new layer of security in WP 2.5 that uses a secret key. You can read about it here:
http://boren.nu/archives/2008/04/24/cookie-security-in-wordpress-25/
You should get this set up!
And not done yet…
If I can’t find the offending code, I’m going to be reduced to blowing away everything, pretty much — grabbing a plain XML export of the database, doing a fresh install, and rebuilding themes while going over them with a fine-tooth comb. No fun.
17 Responses to “More on the blog hacking”
Sorry, the comment form is closed at this time.
More on the blog hackingPosted on April 15, 2008 by Raph
Wow, that’s pretty extreme. I’ll be interested to know how it turns out.
Especially a fan of the eval, lave part, lol.
Otherwise, anyone can see what plugins you have by going to http://www.yoursite.com/wp-content/plugins
This can be disabled using .htaccess, but I can’t remember how at the moment. I think it’s Deny All or something, and you should be returning 403 Forbidden. But generally speaking, a live site should never have its directory tree exposed. WordPress should shield that stuff better. =/
And normal people are supposed to deal with these problems exactly how?
The problems with computers amaze me… The average person is bound to encounter a problem once every few months that requires a friendly guru to fix, or an expensive trip to the computer repair store.
Well “normal people” probably shouldn’t be hosting their own blog, there are plenty of sites that will host them for you, and take care of this kind of admin… but where’s the fun in that? 🙂
ouch. I had sim. issues with wordpress but I guess I give up easier than you…I just trashed it all and built my own little custom blog software (very very basic)…besides being less likely to get attacked (because they have no idea about my structures or organization), it gave me the ability to streamline everything down to just the core things I needed/wanted.
If you are going to be playing with wordpress this much anyway, you might as well take the opp. to at least chop out all the extra fluff that’s in there (but that you don’t use in your specific setup)…if nothing else, that step will at least make future debugging easier right?
[…] about Raph · contact « More on the blog hacking […]
Been there, done that, forty hours of cleanup after the attackers got through anyway.
Raph, at this point is there a compelling reason to not just throw WordPress out altogether and go with something like Blosxom? Another few hacking incidents and you will have spent more time patching and sanitizing WordPress than you would have spent auditing 444 lines of cleanly-commented Perl, even including the time it’d take you to learn enough Perl from scratch to do the audit.
1) I despise Perl.
2) The plugins, support, and community for WP.
3) The Blosxom site you linked is illegible. 😉
1. But is it more or less illegible than dozens of base64-encoded entries in your wp_config table? Some people look at trials like yours and say that they need to sanitize the SQL and clean the database. I look at it and wonder why you have a database at all.
2. Preferring PHP over Perl is like preferring Hydrox over Oreo. It’s the same $basic[‘cookie’].
🙂 I just dislike Perl’s syntax a lot. Haven’t used it in years…
When I say the site is illegible, I mean I get little diamonds instead of letters. It’s actually literally illegible. 🙂
I probably DO need to sanitize the DB, actually. 😛
I’d suggest looking around the rest of your httpd user’s home directory and all of the other places it can touch, too. PHP has system(), so anything httpd had permissions on, your attacker could’ve touched.
I think on that Blosxom link, he meant dot com and not dot org.
[…] to valuable instructions from Raph (who was hacked the same way) and meticulous assistance from Jeff Freeman, I’m back up and […]
[…] the recent hack to the blog, and also given the recent news of the decompiled Eve Online client, it seemed like a good time to […]
Hi. I had the same issue. The wp_options code is NOT the main problem. The main problem is one plugin installed that DOESN’T SHOW in your plugins page (that’s because they don’t have a plugin header). I had to remove active_plugins from wp_options and enable the good plugins again to get read of it. Read here: http://wordpress.org/support/topic/169246
[…] RobertGaloppini Linux-by-Example Kakkoi Gordon Dewis Raph […]
[…] those who recall the whole “blog gets hacked” odyssey, and my subsequent request for a plugin that would do security scans, check this […]