SQL注入绕过方式
前言
在实际的测试过程中,经常会遇到一些SQL注入,明明判断存在注入点,然而在实际的测试过程中会发现有各种各样的输入过滤器导致SQL注入利用失败。这时我们需要利用一些不常见的特性或者与其它技术结合起来以便发动成功的攻击。本篇文章就来看看常见的过滤方式以及绕过的方式。
判断是否存在SQL注入的方式
1)布尔注入
2)时间注入
3)错误
4)内联
5)union
6)堆叠(stack queries)
常见的过滤方式
1)过滤SQL关键字,比如SELECT,AND,INSERT等
2)特定的单个字符,比如引号标记或连字符
3)空白符
绕过方式
1)使用大小写变种
特性:数据库使用不区分大小写的方式处理SQL关键字
这种特性在基于关键字的检测中,如果没有对大小写进行判断,则可以绕过。

2)使用SQL注释符
特性:在SQL语句中用/**/来进行多行注释。可以用注释符来代替空格连接SQL关键字。
PS:低版本的MySQL中甚至可以在SQL关键字中使用内联注释。
/* */ 在mysql中是多行注释 但是如果里面加了! 那么后面的内容会被执行

select/*foo*/username/*foo*/users
sel/*foo*/ect username,password fr/*foo*/om user (mysql中还可以插入到关键字中)
3)使用编码(URL编码,Unicode编码)
URL编码:使用字符的十六进制ASCII码来替换,并在ASCII码前加上%就是URL编码。
特性:web程序经过一系列处理,可能将经过编码的字符还原成原始字符并带到数据库中执行。
PS:单次编码不行的时候,可以尝试双重编码,因为WEB应用程序有时会多次解码用户输入并在最后解码之前应用其输入过滤器。

4)使用动态查询
特性:许多数据库都允许动态执行SQL查询,只须向执行查询的数据库函数传递一个包含SQL查询的字符串即可。
PS:SQLSERVER中使用exec。exec('select password from tbluser')
oracle中使用EXECUTE IMMEDIATE命令执行一个字符串格式的查询。
这样如果过滤了关键字就可以通过连接字符来进行绕过。
oracle:‘sel'||'ect'ms-sql: 'sel'+'ect'mysql: 'sel' 'ect'
通过还可以使用cha()来构造SQL中的关键字。
SQLSERVER中,可以使用代表字符串的ASCII字符编码的十六进制数字来实例化字符串。如下:
DECLARE @query VARCHAR(100)SELECT @query=0x73656c6563742070617373776f72642066726f6d2074626c55736572exec(@query)

5)使用空字节
特性:原生代码和托管代码分别采用不同的方法来处理空字节。原生代码根据第一个空字节的位置来确认字符串的长度。这种差异导致,原生过滤器如果遇到字符串遇到空字符就会停止处理,导致绕过过滤器。
%00’ union select password form tblusers --
6)使用嵌套
特性:有的过滤器采用的方式是通过去掉SQL关键字。可以退通过嵌套的方式绕过。
selselectect
7)利用截断
特性:有的输入过滤器会将输入截断成最大长度。
有的过滤器将‘变换成’‘来防止SQL注入。这是如果可以截断,那么就可以绕过。
8)非标准入口
特性:有的waf只检查了常规的参数值。我们可以将paylaod放到参数名中。还有http的其它协议,如user-agent。
9)利用二阶注入
特性:输入的时候对字符进行了转换,然后将不安全的字符原样存储在数据库中,下次查询时就会造成SQL注入。
总结
上面这些过滤方式只是一些比较基本的,类似的还有很多,在遇到判断存在注入点而无法利用的时候可以尝试一下绕过。