SQL二次注入&宽字节注入


SQL二次注入

表现

在二次注入中,一般不会是单纯的二次注入
通常会与报错注入或Bool盲注结合。
比如,在注册页面输入的用户名在登录后才有盲注的回显
这时候我们需要自己编写脚本模拟注册及登录。

无法通过扫描工具或者手工测试出来,二次注入一般在审计代码过程中发现
从前端或黑盒测试无法看到

原理

攻击者构造恶意的数据并存储在数据库后
防御者对语句中的特殊字符进行了转义处理
但在恶意数据插入到数据库时被处理的数据又被还原并存储在数据库中
当程序调用恶意数据并执行SQL查询时就发生了SQL二次注入。
总而言之:
用户输入恶意的数据库查询语句时会被转义,
但在数据库调用读取语句时又被还原导致语句执行。

思路

第一步:构造恶意语句
没有恶意代码怎么能行?先上传含有能被转义的字符的恶意查询语句
第二步:插入恶意数据
传入数据并任他对其中特殊字符进行转义处理,但在保存在数据库时保留了原来的味道
第三步:二次构造语句,引用恶意数据
因为开发者默认存在数据库里的数据都是安全的
所以在进行查询时,直接从数据库中取出九转大肠
结果如下:
只保留了一点原始的味道

注入方法

构造并存入一个恶意语句

由于这种注入太难以被判断及发现,所以本文只作简单说明(其实是因为我太菜了)

在注册等类似能上传并存储数据的页面存入
admin'#

mysql_escape_string()等函数会在特殊字符前加 \ 造成过滤的效果

此时传入时不会执行恶意代码,因为它过滤了。
但是存入的时候没有更改原来的数据。

调用数据库中的恶意语句

既然原来的数据没改,那就再调出来用(相当于执行了恶意代码)。

下面是sqllab靶场的题,二次执行时整个语句变成了这样子
update password=$new where username=admin'#

admin后引号对前面的单引号进行了闭合,#注释掉了后面的语句,就相当于对admin进行了改密

SQL宽字节注入

基本概念

**单字节字符集:**所有的字符都使用一个字节来表示(ASCII 编码0-127)
**多字节字符集:**在多字节字符集中,用多个字节来表示(也有可能一部分用一个字节表示)
**宽字符:**用多个字节来代表的字符称之为宽字符
**字符、字符集:**字符是组成字符集的基本单位
**UTF8:**由于ASCII表示的字符只有128个,因此网络世界的规范是使用UNICODE编码,但是用ASCII表示的字符使用UNICODE并不高效。因此出现了中间格式字符集,被称为通用转换格式,及UTF。
**宽字节:**GB2312、GBK、GB18030、BIG5、Shift_JIS等这些都是常说的宽字节,实际上只有两字节。宽字节带来的安全问题主要是吃ASCII字符(一字节)的现象,即将两个ascii字符误认为是一个宽字节字符。

表现

原理

1、宽字节注入是利用mysql的一个特性:
  PHP中编码为GBK,函数执行添加的是ASCII编码(添加的符号为\)
  MYSQL默认字符集是GBK等宽字节字符集。
2、PHP发送请求到mysql,mysql在使用GBK编码的时候会认为两个字符是一个汉字
3、字符和转义的反斜杠组成了新的汉字,但是组成的新汉字又不是一个正常的汉字,就起到了注掉 \ 的作用

转义函数

addslashes函数:
对单引号(’)、双引号(")、反斜线(\)与x00 (NULL字符)
magic_quotes_gpc函数:
判断解析用户提交的数据,有post、get、cookie数据时增加转义字符“\”
mysql_real_escape_string函数
mysql_escape_string函数

注入方法

方法一:
比如and’的编码是%df’,传参时单引号被加上\变成了 %df'
其中\的十六进制是%5C ,那么现在 %df' =%df%5c%27
如果程序的默认字符集是GBK等宽字节字符集
则MySQL用GBK的编码时,会认为 %df%5c 是一个宽字符,也就是縗

也就是说:%df\' = %df%5c%27=縗'

我们再回想到注入的三要素,有了单引号(闭合)后就好注入了

方法二:
使用汉字绕过。
PHP接收到一个汉字后通过UTF-8编码(三字节),并和\两两配对组成两个汉字,避免了后面引号的转义


评论
  目录