背景
本人安全小白看了很多有关于宽字符注入漏洞的文章,从内心出发,始终没有真正的去完全理解这个漏洞产生的根因,因此小白在这里做个简单的总结,大神饶命绕过哈哈哈。
目的
从简单原理上理解这个漏洞,对学习和工作上有那么一丢丢的帮助。
内容
在讲解这个漏洞之前,我们先拓展下几点知识
- 何为字节?
计量单位,表示数据量多少,是计算机存储容量的计量单位。一个字节占8位。 - 何为字符?
电子计算机或无线电通信中字母、数字、符号的统称,说白了,一个英文字母或其他运算符’A’、‘B’、’$’、’&'就是一个字符。 - 何为编码?
信息格式转换的过程,你要知道编码是一个过程,规定每个“字符”分别用一个字节还是多个字节存储,用哪些字节来存储,说白了就是按照规则对字符进行翻译成对应的二进制,在计算器中运行存储,用户在浏览器进行浏览的时候在对应的编码解析出来用户能看懂的数据。 - 有哪常见编码方式?
ASCII码、Unicode码、中文编码、常用语言的其他编码。 - 何为宽字符?
用多个字节来代表一个字符称之为宽字符 - 何为窄字符?
用一个字节来代表一字个符称之为窄字符
宽字符注入漏洞到底是怎么产生的呢?(文字描述)
首先先想一下既然是宽字符相关的漏洞,肯定是离不开宽字符的这个概念,ASCII码中,一个英文字母(不分大小写)占一个字节的空间,一个中文汉字占两个字节的空间,UTF-8编码中,一个英文字符等于一个字节,一个中文等于三个字节,Unicode编码中,一个英文等于两个字节,一个中文等于两个字节等等,说明了字节与字符在不同的编码方式中字节所占据的空间肯定是不一样的,某种编程语言(例如PHP)默认编码位GBK,默认文件php.ini可查询,mysql默认的编码方式位GBK,用户在提交数据的时候,其实就是使用PHP文件本身的默认编码方式GBK进行编码,接着在向数据库发送请求,而这个请求的本身就类似于就是一个点对点的传统通信方式,涉及到一个Client和一个Server,而实际上对应的是mysql内置的两个变量character_set_client+character_set_connection,所以如果不想出现乱码的情况下这两个内置变量的编码方式一定要设为统一(默认是GBK),当服务器进行处理完后,要进行正确响应客户端,如何达到正确响应客户端呢?就是用到了mysql的内置变量character_set_results设置编码格式位GBK, 此时客户端就被客户端理解了,总结下,从Web应用提供的查询到响应的过程中均使用了GBK编码格式,为了防止数据库注入,使用PHP使用函数addslashes()实现了将特殊符号进行转义掉特殊字符{/ // ’ ‘’ #},但是在进行数据库查询遇到特殊字符比如说**’**的时候,就是触发该函数,理论上可以执行和’把特殊函数给转义掉,但是在BGK编码表里,当用户恶意输入%df%27时,后台数据库查询语句就会变成“%DF%5C%27”,%DF%5C会被当成一个汉字占用两个字节,(函数转义失效),完成绕过, 导致造成数据库注入漏洞。
流程图概述
防御
①在进行部署数据库时设置好编码格式,设置好固定的字符集。 ②在进行使用防止数据库注入时,使用安全的转义函数,防止出现一个字符占用多个字节的情况。(在这里就不列出函数了,因为不同语言不同数据库对应的编码格式及函数都是不一样的,想了解更多可以私发作者) ③可以使用多层转义函数进行对用户数据进行多次自定义编码规则与数据库交互。
|