SQL注入编码相关小知识科普(二)

前言

上一篇提到宽字节在SQL注入的相关问题。仔细回想一下整个流程,其实本质是在MySQL中字符编码转换的问题。那么在PHP中进行字符编码转换的相关操作,是不是也会存在这个问题?注意,是PHP中的字符编码转换,在一个程序中难免会使用字符串编码转换,其中iconv函数就是典型。

iconv函数隐患

先将上一篇的源码改改如下:

示例一:

";
$result=mysqli_query($conn,$sql);
@$row = mysqli_fetch_assoc($result);
echo "Your password is:".$row['password']."
"; ?>

上一篇提到使用mysqli_real_escape_stringmysqli_set_charset可以防止宽字节注入的产生。那么在引入了iconv函数之后,这种防御就变得无效了。

image.png

不难看出,在已经设置好编码之后,又进行编码转换,显得有点画蛇添足。

实例二

";
$result=mysqli_query($conn,$sql);
echo mysqli_error($conn);
@$row = mysqli_fetch_assoc($result);
echo "Your password is:".$row['password']."
"; ?>

第二个实例,是将utf-8转换成gbk,由于utf-8编码是占用3个字节而gbk编码是占用两个字节。所以多出的这一字节则是我们的突破口。

image.png

如上图,当我们输入了,则依旧产生了注入。这是由于,utf-8编码为0xE98CA6,而GBK编码则为0xE55c。而之前提过0x5c表示的是转义符\,于是就有了下图的效果,SQL语句中我们加入了一个转义符,从而使单引号逃脱了转义。
image.png

其他编码的问题

从宽字节的问题,可以体会到当编码处理不当可能会造成隐患。但不仅仅只是字符编码会带来此类问题。不少安全类书籍在介绍SQL注入时,都会提到使用base64或者url等一些编码的方式绕过waf和过滤机制。使用编码的绕过前提程序中要有相应的解码机制。这也在白盒审计中提供了一个思路:当单引号无法使用时,则考虑看看程序的编码问题,或者是否在数据传输时使用某种加密,在进入数据库操作时是否进行相应的解密操作

防御

首先得理解各个编码存在的差异,这可能有点困难吧,毕竟编码那么多种。其次就是做到前后端编码一致,如果前端展示使用gbk,后端php和mysql也用gbk。编码统一了,自然不会出现乱码,也就不会使用编码转换,避免了隐患。

最后

在写文章的时候遇到蛮多问题,知识点本身记得朦朦胧胧的,梳理完清晰不少,希望能坚持写下去。

你可能感兴趣的:(SQL注入编码相关小知识科普(二))