原理:mysql 在使用 GBK 编码的时候,会认为两个字符为一个汉字,例如%aa%5c 就是一个汉字(前一个 ascii 码大于 128 才能到汉字的范围)。我们在过滤 ’ 的时候,往往利用的思路是将 ‘ 转换为 \’ (转换的函数或者思路会在每一关遇到的时候介绍)。
因此我们在此想办法将 ‘ 前面添加的 \ 除掉,一般有两种思路:
1、%df 吃掉 \ 具体的原因是 urlencode(‘) = %5c%27,我们在%5c%27 前面添加%df,形
成%df%5c%27,而上面提到的 mysql 在 GBK 编码方式的时候会将两个字节当做一个汉字,此时%df%5c 就是一个汉字,%27 则作为一个单独的符号在外面,同时也就达到了我们的目的。
2、将 \’ 中的 \ 过滤掉,例如可以构造 %**%5c%5c%27 的情况,后面的%5c 会被前面的%5c给注释掉。这也是 bypass 的一种方法。

常见的函数在mysql中,用于转义(即在字符串中的符号前加上”\”)的函数有addslashes,mysql_real_escape_string,mysql_escape_string等,还有一种情况是magic_quote_gpc,不过高版本的PHP将去除这个特性。

less-32

id=1’时,被转义为1\’,宽字节注入
image.png
用%df将%5c吃掉,这关用的是replace替换
成功绕过

less-33

同上paylaod

不过用的是addslashes函数
addslashes() 函数返回在预定义字符之前添加反斜杠的字符串。
预定义字符是:

  1. 单引号(')
  2. 双引号(")
  3. 反斜杠(\)

提示:该函数可用于为存储在数据库中的字符串以及数据库查询语句准备字符串。
Addslashes()函数和我们在 32 关实现的功能基本一致的,所以我们依旧可以利用%df 进行绕
过。
Notice:使用 addslashes(),我们需要将 mysql_query 设置为 binary 的方式,才能防御此漏洞。
Mysql_query(“SET
character_set_connection=gbk,character_set_result=gbk,character_set_client=binary”,$conn);

less-34-37

post型注入,不会对我们提交的内容进行编码
将 utf-8 转换为 utf-16 或 utf-32,例如将 ‘ 转为 utf-16 为 �’ 。
搞定闭合符号,联合查询很久,发现始终不行。
采用报错注入�' ``and ``updatexml(1,concat(0x7e,database()),1)#

image.png

less-35

整型注入,无过滤,直接联合查询注入

less-36

?id=0%df' union select 1,database(),3 --+
?id=0�' union select 1,database(),3 --+

用的是mysql_real_escape_string函数

mysql_real_escape_string() 函数转义 SQL 语句中使用的字符串中的特殊字符。
下列字符受影响:

\x00
\n
\r
\
'
"
\x1a

因 mysql 我们并没有设置成 gbk,所以 mysql_real_escape_string()依旧能够被突破。方法
和上述是一样的。
可以利用的‘ 的 utf-16 进行突破的,我们也可以利用%df 进行。

防护问题:
在使用 mysql_real_escape_string()时,如何能够安全的防护这种问题,需要将 mysql 设置为
gbk 即可。
设置代码:
Mysql_set_charset(‘gbk’,’$conn’)

总结:
从上面的几关当中,可以总结一下过滤 ‘ \ 常用的三种方式是直接 replace,
addslashes(),mysql_real_escape_string()。三种方式仅仅依靠一个函数是不能完全防御的,所
以我们在编写代码的时候需要考虑的更加仔细。