0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9

避开过滤方法总结
大小写变种
SQL注释
URL编码
动态查询执行
空字节
双关键字绕过
大小写变种
适用于关键字阻塞过滤器不聪明的时候,我们可以变换关键字字符串中字符的大小写来避开过滤,因为数据库使用不区分大小写的方式处理SQL关键字。
select * from sql_test where id = 3 uniON sEleCt * from sql_test where id = 2;
SQL注释
很多开发人员认为,将输入限制为单个就可以限制SQL注入攻击,所以他们往往就只是阻止各种空白符。
常见注释--
, /**/
,#
使用内联注释序列来创建SQL代码段。这些代码段虽然在语法上有些怪异,但实际上却非常有效,能够避开多种输入过滤器。
mysql:
select * from sql_test where id = 3 union /*!select*/ * from sql_test where id like 2;
内联注释不使用空格就可以构造任意复杂的SQL语句。
URL编码
URL编码的最基本表示方式是使用问题字符的十六进制ASCII码来替换它们,并在ASCII码前加%。例如,单引号字符的ASCII码为0x27,其URL编码的表示方式为%27。
or1=1即%6f%72%20%31%3d%31
Test也可以为CHAR(101)+CHAR(97)+CHAR(115)+CHAR(116)。
动态查询执行
许多数据库都允许动态执行SQL查询,只须向执行查询的数据库函数传递一个包含 SQL查询的字符串即可。如果找到了一个有效的SQL注入点,但后来却发现,应用过滤器阻止了想注入的查询,那么可以使用动态执行来避开该过滤器。
想要使用动态执行战胜输入过滤器,关键是使用字符操作函数将过滤器允许的输入转换成一个包含所需查询的字符串。
SQL Server提供了几种运行动态构建的SQL语句的方法。以下是一些选择:
利用char函数拼接
CHAR(83)+CHAR(69)+CHAR(76)+CHAR(69)+CHAR(67)+CHAR(84)
CHAR函数可以接收每个字符的ASCI码
使用 EXEC
EXEC ('SELECT password FROM tblUsers')
使用十六进制实例化
SELECT password FROM tblUsers
可以按照下列方式进行构造并动态执行:
DECLARE @query VARCHAR (100)
SELECT @query = 0x53454c45435420706177373776f72642046524f4d2074626c5573657273
EXEC (@query)
不同的数据库中动态查询执行的实现会有所不同
空字节
通常的输入过滤器都是在应用程序之外的代码实现的。比如入侵检测系统(IDS),这些系统一般是由原生编程语言开发而成,比如C++,为什么空字节能起作用呢,就是因为在原生变成语言中,根据字符串起始位置到第一个出现空字节的位置来确定字符串长度。所以说空字节就有效的终止了字符串。
只需要在过滤器阻止的字符串前面提供一个采用URL编码的空字节即可。
%00 ' union select username,password from users where username='admin' --
双关键字绕过
有些审查过滤器会先从用户输入中剥离特定的字符或表达式,然后再按照常用的方式处理剩下的数据。如果被剥离的表达式中包含两个或多个字符,就不会递归应用过滤器。通常可以通过在禁止的表达式中嵌套自身来战胜过滤器。
例如,如果从输入中剥离了SQL关键词SELECT,就可以使用下列输入战胜过滤器:
SELSELECTECT
参考:
https://blog.csdn.net/wy_97/article/details/78085664
[美]Junstin Clarke. SQL注入攻击与防御[M]. 第二版. 清华大学, 2013.10
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
