【安全面试分享】关于面试中遇到的宽字节注入产生原理以及根本原因详细解析

### 产生原理 在数据库使用了宽字符集而WEB中没考虑这个问题的情况下,在WEB层,由于0XBF27是两个字符,在PHP中比如addslash和magic\_quotes\_gpc开启时,由于会对0x27单引号进行转义,因此0xbf27会变成0xbf5c27,而数据进入数据库中时,由于0XBF5C是一个另外的字符,因此\\转义符号会被前面的bf带着"吃掉",单引号由此逃逸出来可以用来闭合语句。 ### 在哪里编码 由于ASCII表示的字符只有128个,因此网络世界的规范是使用UNICODE编码,但是用ASCII表示的字符使用UNICODE并不高效。因此出现了中间格式字符集,被称为通用转换格式,及UTF(UniversalTransformation Format)。 GB2312、GBK、GB18030、BIG5、Shift\_JIS等这些都是常说的宽字节,实际上只有两字节。宽字节带来的安全问题主要是吃ASCII字符(一字节)的现象。 ### 根本原因 character\_set\_client(客户端的字符集)和character\_set\_connection(连接层的字符集)不同,或转换函数如,iconv、mb\_convert\_encoding使用不当。具体如下 在GBK中,假设MySQL数据库使用了GBK字符集,一个汉字在GBK中用两个字节来表示。一些cms可能会使用addlashes函数来转义特殊字符,如将’变成\\’让单引号失去它原本意义,以抵御SQL注入。这时我构造payload id=1%df’,经过addlashes转义后变成id=1%df\\’,在GBK编码中反斜杠的编码是%5c,这样%df%5c就被MySQL认为是一个汉字,从而’实现逃逸。 ### 解决办法 统一数据库、Web应用、操作系统所使用的字符集,避免解析产生差异,最好都设置为UTF-8。 或对数据进行正确的转义,如mysql\_real\_escape\_string+mysql\_set\_charset的使用。 ### 总结 在面试时学会总结凝练地说,详细解释用于方便自己的理解。

1 个回答

奇安信攻防社区 - 奇安信攻防社区官方账号

感谢师傅的分享,奖励金币已充值,请个人账户查收~