二次排序注入思路:
黑客通过构造数据的形式,在浏览器或者其他软件中提交HTTP数据报文请求到服务端进行处理,提交的数据报文请求中可能包含了黑客构造的SQL语句或者命令。
服务端应用程序会将黑客提交的数据信息进行存储,通常是保存在数据库中,保存的数据信息的主要作用是为应用程序执行其他功能提供原始输入数据并对客户端请求做出响应。
黑客向服务端发送第二个与第一次不相同的请求数据信息。
服务端接收到黑客提交的第二个请求信息后,为了处理该请求,服务端会查询数据库中已经存储的数据信息并处理,从而导致黑客在第一次请求中构造的SQL语句或者命令在服务端环境中执行。
服务端返回执行的处理结果数据信息,黑客可以通过返回的结果数据信息判断二次注入漏洞利用是否成功。
sql注入绕开过滤(lesson25)
一般有以下思路
1. 大小写变形 :
如:Or,OR,oR
2. 改变编码:
如:通过hex,urlencode、url等编码
Eg:果or被过滤时,我们可以采用url编码(其相当于把ascii编码的0x给替换成%,比如o的ascii为0x6f,url编码就是%6f),这个时候我们可以试试%6fr,即把o换成url编码,也可以全换,也可以大小写的换,如果没被过滤就成功了,(如果%被过滤了的话…)
注:这个可以积极的去使用,比如测试时and被注释,使用&&替换也失败,这个时候不妨试试%26%26(&的url编码)
3. 添加注释:
如:/or/(不止应对字母被注释)
Eg:某个过滤器能够过滤的字符如下——“select ”、”from ”、”limit ”等,注意这些字符最后面都有一个空格,这个时候我们就能通过内联注释来绕过这个过滤器,如:
SELECT/**/username,password/**/FROM/**/users
注:这个注释甚至可以穿插在关键字当中,例如被过滤了or,我们可以把order by改成o/**/rder by,参考的资料上是这么说(滑稽
4. 利用符号
如:and=&& or=||
Eg:
‘ || updatexml(1,concat(0x7e,(select database()),0x7e),1)--+
5.往字符里面插入被过滤的字符
如or被过滤了,我们可以往里面加or,即注入:oorr,这个时候里面的or就被删去了,剩下的组成新字符,也就是or,是个很好用的绕过方法,像这种类似的还有很多
数字被注释(1、2等)
6.使用浮点数:
如:1.0、2.0
符号被注释(>、<等)
7.利用函数来替代
如盲注时经常用到比较,这时候要是比较符号被注释了不能用平常的方法了,所以需要用某些函数如greatest()【greatest(n1,n2,n3,...)函数返回输入参数(n1,n2,n3,...)的最大值】、least()等,比如语句:select * from users where id=1 and ascii(substr(database(),0,1))>64就可以替换成select * from users where id=1 and greatest(ascii(substr(database(),0,1)),64)=64
注:当or被注释时,像order by这种含有相关字符的语句也同样无法使用,这个时候如果改变大小写也无用时,可以使用上述的内联注释/**/,或者用别的编码形式,如果不行的话,那就只能放弃使用order by,可以尝试使用group by语句等
宽字节注入
原理:
1、我们都知道,在防御SQL注入的时候,大多说都是使用的过滤特殊字符,或者使用函数将特殊字符转化为实体,就是说在字符转义,添加‘\’。这里第一条就是有这个机制。
2、设置宽字节字符集,这里为GBK字符集,GBK字符集占用两个字节。关键就在于这个设置字符集。通常有很多方法可以设置,例如:
mysql_query,如mysql_query("SET NAMES 'gbk'", conn)。
mysql_set_charset,如mysql_set_charset("gbk",$conn)。
实现过程:当我们测试的时候,输入“%df‘”,这个时候如果php函数是使用的addslashes()的时候,会在冒号的前面加上’\’。也就变成了%df\’ 。对应的编码是%df%5c’.这时候网站字符集是GBK,MYSQL使用的编码也是GBK的话,就会认为%df\是一个汉“運’”,这样的话,单引号前面的\就不起作用了,从而转义失败,导致报错
涉及到的一些概念
字符、字符集与字符序
字符(character)是组成字符集(character set)的基本单位。对字符赋予一个数值(encoding)来确定这个字符在该字符集中的位置。
字符序(collation)指同一字符集内字符间的比较规则。
UTF8
由于ASCII表示的字符只有128个,因此网络世界的规范是使用UNICODE编码,但是用ASCII表示的字符使用UNICODE并不高效。因此出现了中间格式字符集,被称为通用转换格式,及UTF(Universal Transformation Format)。
宽字节
GB2312、GBK、GB18030、BIG5、Shift_JIS等这些都是常说的宽字节,实际上只有两字节。宽字节带来的安全问题主要是吃ASCII字符(一字节)的现象。
MYSQL的字符集转换过程
- MySQL Server收到请求时将请求数据从character_set_client转换为character_set_connection;
- 进行内部操作前将请求数据从character_set_connection转换为内部操作字符集,其确定方法如下:
- 使用每个数据字段的CHARACTER SET设定值;
- 若上述值不存在,则使用对应数据表的DEFAULT CHARACTER SET设定值(MySQL扩展,非SQL标准);
- 若上述值不存在,则使用对应数据库的DEFAULT CHARACTER SET设定值;
- 若上述值不存在,则使用character_set_server设定值。
将操作结果从内部操作字符集转换为character_set_results。
注:宽字节注入发生的位置就是PHP发送请求到MYSQL时字符集使用character_set_client设置值进行了一次编码。
附:
宽字节注入详解:
https://www.cnblogs.com/lcamry/articles/5625276.html
https://blog.csdn.net/helloc0de/article/details/76180190
Stacked injection--堆叠注入--堆查询注入
- Stacked injections:堆叠注入。从名词的含义就可以看到应该是一堆sql语句(多条)一起执行。而在真实的运用中也是这样的,我们知道在mysql中,主要是命令行中,每一条语句结尾加 ; 表示语句结束。这样我们就想到了是不是可以多句一起使用。这个叫做stacked injection。
原理:
在SQL中,分号(;)是用来表示一条sql语句的结束。试想一下我们在 ; 结束一个sql语句后继续构造下一条语句,会不会一起执行?因此这个想法也就造就了堆叠注入。而union injection(联合注入)也是将两条语句合并在一起,两者之间有什么区别么?区别就在于union 或者union all执行的语句类型是有限的,可以用来执行查询语句,而堆叠注入可以执行的是任意的语句。例如以下这个例子。用户输入:1; DELETE FROM products服务器端生成的sql语句为:(因未对输入的参数进行过滤)Select * from products where productid=1;DELETE FROM products当执行查询后,第一条显示查询信息,第二条则将整个表进行删除。
Eg:
当执行查询后,第一条显示查询信息,第二条则将整个表进行删除。
局限性
堆叠注入的局限性在于并不是每一个环境下都可以执行,可能受到API或者数据库引擎不支持的限制,当然了权限不足也可以解释为什么攻击者无法修改数据或者调用一些程序。
附:
关于堆叠注入的更多内容:
https://www.bbsmax.com/A/kvJ3Eq9Xdg/
http://www.sqlinjection.net/stacked-queries/