Sunday, April 20, 2008

Wordpress: Blank page when trying to post

Source: Blog.taragana.com
The hacker was able to press a .txt file in the /tmp directory.

The hacker exploited several WordPress vulnerabilities in administrative scripts to gain full access to the website (as permitted to apache user), including the ability to upload & run scripts, delete any file owned by apache user, view the file and directories etc.

This is a full disclosure on the how the site was hacked and how I detected and removed the hack along with few comments on the state of WordPress security. I added a WordPress plugin and made modifications to prevent any such hacking attempts in future using WordPress. This is a must read for WordPress bloggers.

How the site hacking was detected?
The website was normal. However when I tried to publish or even save a post, it simply showed a blank page. The post was never published or even saved. I knew something was wrong.
My first suspect were couple of plugins which contacted external servers after a publish. I disabled them. I also disabled the ping sites as they were sometimes known to cause problems. None of that helped. I progressively disabled all of the plugins. Even with all the plugins disabled, the post wouldn’t publish. I was left with only one option.
I decided to trace WordPress code to find out the cause of error. I started with the file for post submission - post.php. I found something startling with WordPress code which seriously undermines its security, a flawed design choice but more on it later. post.php calls admin.php which calls wp-config.php which in turn calls wp-settings.php. wp-settings is an interesting file. This file isn’t just about settings. It loads tons of files, loads and executes the plugins and more. The problem was, as I originally suspected, in the plugins but which one? The code which loads the plugins in WordPress is:
if ( get_option('active_plugins') ) {
$current_plugins = get_option('active_plugins');
if ( is_array($current_plugins) ) {
foreach ($current_plugins as $plugin) {
if ('’ != $plugin && file_exists(ABSPATH . PLUGINDIR . ‘/’ . $plugin))
include_once(ABSPATH . PLUGINDIR . ‘/’ . $plugin);
}
}
}
The active plugins, as you can see, are loaded directly with include_once. How do I find the plugin which while loading is causing the script to die?I added simple syslog() statements before and after the plugin. However it generated copious output from all the traffic.Remember I was debugging on a heavily trafficked live site. So I added a define in post.php which I was checking before doing a syslog.

The debugging code was:
if ('’ != $plugin && file_exists(ABSPATH . ‘wp-content/plugins/’ . $plugin)) {if(defined(’TG_ADMIN’)) syslog(LOG_ALERT, “Loading $plugin…”);include_once(ABSPATH . ‘wp-content/plugins/’ . $plugin);if(defined(’TG_ADMIN’)) syslog(LOG_ALERT, “Loaded $plugin…”);}

The result was surprising. The first plugin loaded was not even a plugin I knew existed, let alone use it. It was named ro8kbsmawge.txt.

The full path to the plugin
was /../../../../../../../../../../../../../../../../../../tmp/ro8kbsmawge.txt

Effectively the file path was /tmp/ro8kbsmawge.txt. A telltale sign of this hacker is the presence of the file ro8kbsmawge.txt in your tmp directory.

I renamed the file and the problem was solved for now. I could publish posts finally. However my site was still not secure against future attacks. I will detail next at how I secured my site and provide more information on the perpetrator and how the site was hacked in the first place.

Continue reading the article...

Wordpress Exploits

Hello and welcome to Wordpress Exploits.