最新消息:

cmseasy绕过补丁SQL注入一枚

PHP代码审计 admin 2050浏览 0评论

转自:http://0day5.com/archives/1729

在lib\plugins\pay\alipay.php中。上次提了这个文件的洞:http://www.jinglingshu.wiki/?p=7683。

看了看官网发的补丁。

foreach($_POST as $key =>$data) {
if(preg_match('/(=|<|>)/', $data){
 return false;
 }
就是过滤了几个运算符。 但是因为语句是 where xxx。一般的注入的话 需要where id=xxx 来注入 但是这里过滤了这些。 没想出什么办法突破。但是在这文件 还有一个函数。
    function respond() {
        if (!empty($_POST)) {
            foreach($_POST as $key =>$data) {
                if(preg_match('/(=|<|>|\')/', $data)){
                    return false;
                }
                $_GET[$key] = $data;
            }
        }
        $payment  = pay::get_payment($_GET['code']);
        $seller_email = rawurldecode($_GET['seller_email']);
        $order_sn = str_replace($_GET['subject'],'',$_GET['out_trade_no']);
        $order_sn = trim($order_sn);
        if (!pay::check_money($order_sn,$_GET['total_fee'])) {
            return false;
        }
        if($_GET['trade_status'] == "WAIT_SELLER_SEND_GOODS"||$_GET['trade_status'] == "TRADE_FINISHED" || $_GET['trade_status'] == "TRADE_SUCCESS") {
            pay::changeorders($order_sn,$_GET);
            return true;
        }else {
            return false;
        }
    }

上次是看的changeorders函数现在 反正我是没办法利用了。那现在来看看check_money:

    public static function check_money($id,$money) {
        
        $where=array();
        $where['id']=$id;
        $orders=orders::getInstance()->getrow($where);
        $archive=archive::getInstance()->getrow($orders['aid']);
        
        $prices = getPrices($archive['attr2']);
        $archive['attr2'] = $prices['price'];
        
        $where=array();
        $where['pay_code']=$_GET['code'];
        $pay=pay::getInstance()->getrows($where);
        $logisticsid = substr($_GET['subject'],15,1);
        $where=array();
        $where['id'] = $logisticsid;
        $logistics=logistics::getInstance()->getrows($where);
        if($logistics[0]['cashondelivery']) {
            $logistics[0]['price'] = 0.00;
        }else {
            if($logistics[0]['insure']) {
                $logistics[0]['price'] = $logistics[0]['price'] +($archive['attr2'] * $orders['pnums'])*($logistics[0]['insureproportion']/100);
            }
        }
        $pay[0]['pay_fee'] = $pay[0]['pay_fee']/100;
        $total = $archive['attr2'] * $orders['pnums'] +$logistics[0]['price'] +($archive['attr2'] * $orders['pnums'] * $pay[0]['pay_fee']);
        $amount = $total;
        if($money == $amount) {
            return true;
        }else {
            return false;
        }
    }
可以看到是把order_sn 带入了getrow; 再继续这里来把语句输出一下看看。
function getrow($condition,$order='1 desc',$cols='*') {
        $this->condition($condition);
        return $this->rec_select_one($condition,'*',$order);
    }
    function sql_select($tbname,$where="",$limit=0,$fields="*",$order='') {
        $sql="SELECT ".$fields." FROM `".$tbname."` ".($where ?" WHERE ".$where : "")." ORDER BY ".$order.($limit ?" limit ".$limit : "");
        //echo $sql."<br>";
        return $sql;
    }
SELECT * FROM `cmseasy_p_orders` WHERE `id`=’123aaaa’
被单引号了。 但是又全局转义 怎么办呢?
看 $order_sn = str_replace($_GET[‘subject’],”,$_GET[‘out_trade_no’]);
$order_sn = trim($order_sn);
这里跟ecshop 那个洞挺像。
在这里 有一个replace 是xx把清空 但是这个xxx是我们可控的。
总所周知 %00 转义后会变成\0 然后%00′ 就是\0\’
这里 如果我们把0清空 的话 就成了\\’ 单引号成功出来。
测试测试。
20140608121826922
执行的语句有点多。。 直接全部输出来了。
是成功的哦。
修复方案:
继续过滤。

转载请注明:jinglingshu的博客 » cmseasy绕过补丁SQL注入一枚

发表我的评论
取消评论

表情

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

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