[wp-hackers] protecting wp-content/plugins ?

Sam Bauers sam at viveka.net.au
Mon Aug 20 15:37:42 GMT 2007


> Omry Yadan wrote:
>
>> covering wp-content and wp-themes will make the life of an  
>> attacker much
>> harder.

But adding a blank index file does nothing to actually protect  
against detection of a known exploitable plugin. It's classic  
security through obscurity.

If an attacker knows the common name for an exploitable plugin file  
and also the common location of the plugin directory, then all they  
have to do is construct the URI and request it.

So if I know of an exploitable plugin whose main file name is "bad- 
plugin.php". Then it is reasonable to assume that on a WordPress  
install at http://www.example.com/blog, if I hit http:// 
www.example.com/blog/wp-content/plugins/bad-plugin.php in curl and  
get a response that isn't a 404, then it's there and I can use  
whatever trick I know to work the exploit.

I can even script it to test a bunch of domains and run the exploit  
automatically.

The best way to protect against this is to test for some known  
WordPress constant at the start of each plugin file, then if it is  
not there you can return a 404 HTTP Response. E.g.:


<?php
... plugin header ...

if ( !defined('ABSPATH') ) {
	$protocol = $_SERVER["SERVER_PROTOCOL"];
	if ( ('HTTP/1.1' != $protocol) && ('HTTP/1.0' != $protocol) )
		$protocol = 'HTTP/1.0';
	
	if ( version_compare( phpversion(), '4.3.0', '>=' ) ) {
		return @header( $protocol . ' 404 Not Found', true, 404 );
	} else {
		return @header( $protocol . ' 404 Not Found' );
	}
	
	exit();
}

... rest of plugin ...
?>


This means direct requests for the file will fail, but when included  
as a plugin, it will continue as normal.

If you wanted to add a bit more cloaking to the file, you could  
include your servers standard 404 page before you exit. E.g.


<?php
... plugin header ...

if (!defined('ABSPATH')) {
	$protocol = $_SERVER["SERVER_PROTOCOL"];
	if ( ('HTTP/1.1' != $protocol) && ('HTTP/1.0' != $protocol) )
		$protocol = 'HTTP/1.0';
	
	if ( version_compare( phpversion(), '4.3.0', '>=' ) ) {
		return @header( $protocol . ' 404 Not Found', true, 404 );
	} else {
		return @header( $protocol . ' 404 Not Found' );
	}
	
	// Your 404 file location may vary
	include '/var/www/localhost/errors/404.html';
	
	exit();
}

... rest of plugin ...
?>


Now if you add to this a well configured .htaccess file, the file  
becomes practically invisible.

I would prefer to see the proper directives added to the rewrite- 
rules generator instead of a bunch of empty index files floating around.


BUT...

The best idea of all is to move the directories out of the web  
accessible directories...

Lets say you have a directory structure like this:


www.example.org
   |
   +-- htdocs
   |      |
   |      +-- blog
   |
   +-- wp-plugins


Firstly, files in wp-plugins have to be executable. Then, you simply  
add the following to the wp-config.php file in htdocs/blog


define('PLUGINDIR', '../../wp-plugins');


That's it. Plugins can then be placed in that directory and available  
as normal to the WordPress install.

I haven't tested either of these solutions, so I'm sorry for any  
mistakes in them, but the basic premises are there.

Sam

--------------------------------------------------------------
  Sam Bauers

  sam at viveka.net.au
--------------------------------------------------------------





More information about the wp-hackers mailing list