一步一步学习 Web 安全 3.1 宽字节注入

原理

宽窄字节
字符大小为一个字节(英文默认一个字节)称为窄字节,为两个字节(汉字默认两个字节)的称为宽字节,比如:GB2312、GBK、GB18030、BIG5、Shift_JIS 等。

宽字节注入
直接举例:我们在注入时如果后台做了防御,输入的符号被转义,比如:?id=1' union select 1,2,3 --+,『1'』 被转义成『1\'』,这时这条语句是无法进行注入的,整条语句被看做了是字符串,这时候我们就要想办法把『 \ 』干掉,删肯定是删不掉的,但是可以把它变成不是『 \ 』,它就失去了转义的作用,这条注入也可以正常执行。

如何变成不是『 \ 』,就是今天要说的宽字节,『 \ 』的编码是:%5c,而当 MySQL 使用 GBK 编码时,会把两个字符认作一个汉字,编码:%df%5c,就是一个汉字『運』,所以我们可以把注入语句弄成:?id=運' union,就消灭掉了『 \ 』。

也就是说 GBK 编码处理编码的过程中存在问题,可以通过在注入点加上『%df』构造数据绕过转义防御,然后按照正常注入流程开始即可。

练习

sqli-labs 的 less-32
判断列数:
?id=1%df' order by 3 --+,改成 4 报错,可见正确注入了,且得到列数为 3,剩下的语句就不多说了,和之前的注入都一样,只是多个 『%df』

宽字节注入如何发现

如果是黑盒测试,那就只能在注入点输入『%df』进行测试了。

如果是白盒测试:

  • 查看 MySQL 编码是否为 GBK
  • 是否使用了 preg_replace 把单引号替换成了 『\'』
  • 是否使用了 addslashes 进行转义
  • 是否使用了 mysql_real_escape_string 进行转义

防御

知道如何发现,防御就很简单了

  • 使用 utf-8
  • 使用 mysql_real_escape_string 时,需要配合 mysql_set_charset('gbk', $conn)
  • 设置参数:character_set_client = binary,使用二进制进行数据库的连接

你可能感兴趣的:(一步一步学习 Web 安全 3.1 宽字节注入)