2.9 绕过
在CTF中,关于SQL注入的题目一般都会涉及绕过。所以,掌握花式的绕过技术是必不可少的。我们需要熟悉数据库的各种特性,并利用开阔的思维来对SQL注入的防护措施进行绕过操作。
SQL注入的题目中一般都有绕过这样的类型,常见的绕过方式有以下几个分类。
1.过滤关键字
即过滤如select、or、from等的关键字。有些题目在过滤时没有进行递归过滤,而且刚好将关键字替换为空。这时候,我们可以使用穿插关键字的方法进行绕过操作,如:
select -- selselectect or -- oorr union -- uniunionon ...
也可以通过大小写转换来进行绕过,如:
select -- SelECt or -- oR union -- uNIoN ...
有时候,过滤函数是通过十六进制进行过滤的。我们可以对关键字的个别字母进行替换,如:
select -- selec\x74 or -- o\x72 union -- unio\x6e ...
有时还可以通过双重URL编码进行绕过操作,如:
form -- %25%36%36%25%36%66%25%37%32%25%36%64 or -- %25%36%66%25%37%32 union -- %25%37%35%25%36%39%25%36%65%25%36%66%25%36%65 ...
在CTF题目中,我们通常需要根据一些提示信息及题目的变化来选择绕过方法。
2.过滤空格
在一些题目中,我们发现出题人并没有对关键字进行过滤,反而对空格进行了过滤,这时候就需要用到下面这几种绕过方法。
1)通过注释绕过,一般的注释符有如下几个:
·#
·--
·//
·/**/
·;%00
这时候,我们就可以通过这些注释符来绕过空格符,比如:
select/**/username/**/from/**/user
2)通过URL编码绕过,我们知道空格的编码是%20,所以可以通过二次URL编码进行绕过:
%20 -- %2520
3)通过空白字符绕过,下面列举了数据库中一些常见的可以用来绕过空格过滤的空白字符(十六进制):
SQLite3 -- 0A,0D,0C,09,20 MySQL5 -- 09,0A,0B,0C,0D,A0,20 PosgresSQL -- 0A,0D,0C,09,20 Oracle 11g -- 00,0A,0D,0C,09,20 MSSQL -- 01,02,03,04,05,06,07,08,09,0A,0B,0C,0D, 0E,0F,10,11,12,13,14,15,16, 17,18,19,1A,1B,1C,1D,1E,1F,20
如图2-4所示的操作为利用换行符来替代空格的例子。
4)通过特殊符号(如反引号、加号等),利用反引号绕过空格的语句如下:
...select`user`,`password`from...
如图2-5所示的是使用反引号对空格进行绕过的示例。这样就能获取全部的username和password。
在不同的场景下,加号、减号、感叹号也会有同样的效果,这里不一一进行举例说明了,读者可以自行测试。
5)科学计数法绕过,语句如下:
SELECT user,password from users where user_id=0e1union select 1,2
图2-4 空白字符(换行符)绕过空格过滤的示例
图2-5 使用反引号绕过空格过滤的示例
结果如图2-6所示,同样可以达到绕过的效果。
图2-6 使用科学计数法进行绕过
3.过滤单引号
绕过单引号过滤遇到题目最多的是魔术引号,也就是PHP配置文件php.ini中的magic_quote_gpc。
当PHP版本号小于5.4时(PHP5.3废弃魔术引号,PHP5.4移除),如果我们遇到的是GB2312、GBK等宽字节编码(不是网页的编码),可以在注入点增加%df尝试进行宽字节注入(如%df%27)。原理在于PHP发送请求到MySQL时字符集使用character_set_client设置值进行了一次编码,从而绕过了对单引号的过滤。
这种绕过方式现在已不多见,基本上也不会出现在未来的CTF比赛中。
4.绕过相等过滤
根据“猪猪侠”的微博:MySQL中存在utf8_unicode_ci和utf8_general_ci两种编码格式。utf8_general_ci不仅不区分大小写,而且Ä=A,Ö=O,Ü=U这三种等式都成立。对于utf8_general_ci等式ß=s是成立的,但是,对于utf8_unicode_ci,等式ß=ss才是成立的。
这种绕过方式曾在2016年HITCON的BabyTrick题目中作为一个绕过的考点出现过。