【Sql注入】宽字节 二次注入
本Web安全基础推文系列旨在以平白的语言讲解漏洞原理,文章多数内容为我本人的学习笔记与总结,汇总供大家参考。
目录
1 二次注入
2 二次注入案例 sqli-labs less-24
3 宽字节注入
4 宽字节注入案例 sqli-labs less-32
参考链接
1 二次注入
二次注入是指已存储(数据库、文件)的用户输入被读取后,再次进入到 SQL 查询语句中导致的注入。
过程如下:
- 第一次插入恶意数据:在第一次进行数据库插入数据的时候,使用addslashes 或者是借助 get_magic_quotes_gpc 对其中的特殊字符进行了转义,在后端代码中可能会被转义,但在存入数据库时还是原来的数据,数据中一般带有单引号和#号;
例如,插入1‘#;转义成1\’#。不能注入,但是保存在数据库时变成了原来的1’#。 - 引用恶意数据,篡改正常数据:再次调用时,拼凑到SQL中就形成了二次注入。
利用1’#进行注入,也很好理解,单引号提前闭合,#注释后续语句。
这里利用时要求取出数据时不转义。
二次注入比普通sql注入利用更加困难,利用门槛更高。普通注入数据直接进入到 SQL 查询中,而二次注入则是输入数据经处理后存储,取出后,再次进入到 SQL 查询。
换言之,二次注入需要具备的两个条件:
(1)用户向数据库插入恶意语句(即使后端代码对语句进行了转义,如mysql_escape_string、mysql_real_escape_string转义)
(2)数据库对自己存储的数据非常放心,直接取出恶意数据给用户2 二次注入案例
2.1 以sqli-lab less-24为例
正常来说,无法通过注入来登录admin,因为用户输入会被转义。
我们尝试注册admin ‘#,注册成功;
图片
图片
登录admin’# 转义成admin'#,则登录的是admin’#
更新密码的sql语句为:
1 | UPDATE users SET pw=’$newpw’ where username = ‘$name’ and pw=’oldpw’; |
修改admin’#的密码,由于这里不会被转义,故可以直接利用,这个时候就变成了修改了admin的密码,#后面的语句不执行
于是语句变成:
1 | UPDATE users SET pw=’123456’ where username = ‘admin’#' and pw=’123’; |
于是我们修改admin密码成功
图片
注意到左图admin密码为admin,被修改为123456
2.2 防御
- 通过预编译解决SQL注入。
- 永远不要相信用户的输入!对输入一视同仁,无论输入来自用户还是存储,在进入到 SQL 查询前都对其进行过滤、转义。
3 宽字节注入
宽字节注入是利用mysql的一个特性,mysql在使用GBK编码的时候,会认为两个字符是一个汉字(前一个ascii码要大于128,才到汉字的范围),也就是说一次性会读取两个字节。
简单来说,宽字节注入就是将两个ascii字符误认为是一个宽字节字符。
然而,除了GBK的存在,转义字符\也是可以构成此漏洞的因素。
当ascii码大于127的字符和转义字符\组成宽字节字符,会造成单引号或者双引号逃逸,进而导致sql注入。
产生宽字节注入的原因涉及了编码转换的问题,当我们的mysql使用GBK编码后,同时两个字符的前一个字符ASCII码大于128时,会将两个字符认成一个汉字,那么如果存在过滤我们输入的函数(addslashes()、mysql_real_escape_string()、mysql_escape_string()、Magic_quotes_gpc)会将我们的输入进行转义。
尝试注入,我们举一个简单的例子:
addslashes():该函数的作用是返回在预定义字符之前添加反斜杠的字符串。
4 宽字节注入案例
4.1 以sqli-lab less-32为例
假设我们传入一个参数id为1’查看数据库是否错报:
1 | 127.0.0.1/sqli-labs/Less-32/?id=1' |
那么经过函数过滤后我们的输入拼接到sql语句就会变成:
1 | select * from user where id = '1\'' |
图片
图片
单引号被转义了能正常执行。
图片
1 | 127.0.0.1/sqli-labs/Less-32/?id=-1%df%27union select 1,user(),3--+ |
所以如上,%df’ 变为 %df' 而 %df\组成 %df%5C ,此为運字。而運字刚好使得转义字符失效,单引号成功逃逸,造成提前闭合。
图片
4.2 pikachu靶场wide byte注入
图片
1 | name=kobe1%df' or 1=1# |
5 总结
二次注入关键词为:已存储(数据库、文件)的用户输入被读取后,再次进入到 SQL 查询语句中导致的注入。
宽字节注入关键字为:当ascii码大于127的字符和转义字符\组成宽字节字符,从而造成单引号或者双引号逃逸,进而导致sql注入。
图片