order by注入;
sql order by关键字;
sql 中 order by 用于对我们所查询的数据,按照一个列或者多个列进行排序。默认按照升序的方式对查询数据进行排序。如果要以降序进行排序,使用 DESC 关键字。order by是用来写在where之后,给多个字段来排序的一个DQL查询语句,写在最前面的字段,优先级最高。也就说当有字段名1和字段名2时,先以字段名1进行排序,当字段名1的数据值相同时再以字段名2进行排序。
sql order by语法;
select A(列名),B(列名),C(列名) from C(表名) order by A ASC(正序)|DESC(倒序);
解释;查询C表中的A、B、C三列的数据,并按照A列进行排序。
order by 注入是什么;
order by 注入是指其后面的参数是可控的,它不同于我们在 where 后的注入点,无法使用 union 等注入。
判断注入类型;
方法;用rand()可判断注入点类型
原因;数字型order by注入时,语句order by=1 and 1=2,和order by=1 and 1=1 显示的结果一样,所以无法用来判断注入点类型,而rand()在数字型中,每次刷新会显示不同的排序结果。字符型,用?sort=rand(),则不会有效果,排序不会改变。
注入方式;
这里我们假设order by第一个参数可控;
1.order by可以用来判断查询表中的字段数,结合union查询一块使用;
通过修改order by参数值,再依据回显情况来判断具体表中包含的列数。
例如; order by 3——界面显示正常 order by 4——界面显示错误
说明所有查询的数据表中有3个字段名。
判断出列数后,接着使用union select语句进行回显。 2.基于if语句盲注(数字型); 知道列名的前提下; ?order=if(条件,username,password) 条件为true时以username排序 条件为false时以password排序 不知道列名时(通过information_schema结合页面返回情况猜解列名); ?order=if(条件,1,(select id from information_schema.tables)) 如果表达式为true时,则会返回正常的页面。
如果表达式为false时,sql语句会报ERROR 1242 (21000): Subquery returns more than 1 row的错误,导致查询内容为空
3.基于时间的盲注;
/?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秒
4.利用updatexml;
获取数据库版本
order by and(updatexml(1,concat(0x7e,(select version())),0));
获取用户
order by and(updatexml(1,concat(0x7e,(select user())),0));
limit注入;
limit [位置偏移量,]行数 其中,中括号里面的参数是可选参数,位置偏移量是指MySQL查询分析器要从哪一行开始显示,索引值从0开始,即第一条记录位置偏移量是0,第二条记录的位置偏移量是1,依此类推…,第二个参数为“行数”即指示返回的记录条数。
limit注入方法;
limit用法;
格式;limit m,n
其中,m是可选参数,指位置偏移量表示记录查询开始的位置,索引值从0开始,即第一条记录位置偏移量是0,第二条记录的位置偏移量是1,依此类推…,第二个参数为“n”即指示返回的记录条数。
没有order by 可以跟union select 进行查询
有 order by
limit 关键字后面还可跟PROCEDURE和 INTO两个关键字,但是 INTO 后面写入文件需要知道绝对路径以及写入shell的权限,因此利用比较难,因此这里以PROCEDURE为例进行注入 使用 PROCEDURE函数进行注入 ANALYSE支持两个参数,首先尝试一下默认两个参数
mysql> select id from users order by id desc limit 0,1 procedure analyse(1,1);
ERROR 1386 (HY000): Can't use ORDER clause with this procedure
报错,尝试一下对其中一个参数进行注入,这里首先尝试报错注入
mysql> select id from users order by id desc limit 0,1 procedure analyse(extractvalue(rand(),concat(0x3a,version())),1);
ERROR 1105 (HY000): XPATH syntax error: ':5.5.53'
成功爆出 mysql 版本信息,证明如果存在报错回显的话,可以使用报错注入在limit后面进行注入
以及宽字节注入;
1.概念: UT3.F8 由于ASCII表示的字符只有128个,因此网络世界的规范是使用UNICODE编码,但是用ASCII表示的字符使用UNICODE并不高效。因此出现了中间格式字符集,被称为通用转换格式,及UTF(Universal Transformation Format)。
宽字节 GB2312、GBK、GB18030、BIG5、Shift_JIS等这些都是常说的宽字节,实际上只有两字节。宽字节带来的安全问题主要是吃ASCII字符(一字节)的现象,即将两个ascii字符误认为是一个宽字节字符。
2.原理:
1、宽字节注入是利用mysql的一个特性
2、PHP发送请求到mysql,mysql在使用GBK编码(GBK是宽字节,双字节)的时候,会认为两个字符是一个汉字(前一个ascii码要大于128,才到汉字的范围)
3、字符和转义的反斜杠组成了新的汉字,但是组成的新汉字又不是一个正常的汉字,就起到了注掉 \ 的作用
4、可以看出来是字符集不一致造成的宽字节注入
3.涉及函数 addslashes() 函数返回在预定义字符之前添加反斜杠的字符串 mysql_real_escape_string() 函数转义 SQL 语句中使用的字符串中的特殊字符 mysql_escape_string() 转义一个字符串
4.利用: %df、汉字 原理: planA 提交%df的数据会被加入\(编码为%5c),在后面加上后变为%df%5c(繁体汉字運),变成了一个有多个字节的字符,避免了后面引号的转义 planB 使用汉字绕过,一个汉字PHP接收后通过UTF-8编码(三字节),并和\两两配对组成两个汉字,避免了后面引号的转义
|