1.什么是二阶注入?
所谓二次注入是指已存储(数据库、文件)的用户输入被读取后再次进入到 SQL 查询语句中导致的注入。
二次注入是sql注入的一种,但是比普通sql注入利用更加困难,利用门槛更高。普通注入数据直接进入到 SQL 查询中,而二次注入则是输入数据经处理后存储,取出后,再次进入到 SQL 查询。
2.二次注入的原理
二次注入的原理,在第一次进行数据库插入数据的时候,仅仅只是使用了 addslashes 或者是借助 get_magic_quotes_gpc 对其中的特殊字符进行了转义,在写入数据库的时候还是保留了原来的数据,但是数据本身还是脏数据。
在将数据存入到了数据库中之后,开发者就认为数据是可信的。在下一次进行需要进行查询的时候,直接从数据库中取出了脏数据,没有进行进一步的检验和处理,这样就会造成SQL的二次注入。比如在第一次插入数据的时候,数据中带有单引号,直接插入到了数据库中;然后在下一次使用中在拼凑的过程中,就形成了二次注入。
3.普通注入与二次注入的区别:
普通注入 (1)在http后面构造语句,是立即直接生效的
(2)一次注入很容易被扫描工具扫描到
二次注入 (1) 先构造语句(有被转义字符的语句)
(2)我们构造的恶意语句存入数据库
(3)第二次构造语句(结合前面已经存入数据库的语句,成功。因为系统没有对已经存入数据库的数据做检查)
(4)二次注入更加难以被发现
4.二次注入的实例
先注册账号密码,admin'#
然后登陆进去会让你修改新的密码:
修改成功
查看源码,发现登陆处的username和password都经过了mysql_real_escape_string函数的转义,直接执行SQL语句会转义’,所以该处无法造成SQL注入。
注册用户的时候用了mysql_escape_string过滤参数:
数据库中还是插入了问题数据admin'#,原因是经过mysql_escape_string转义的数据存入数据库后被还原
我们以admin'#用户登陆,再进行密码修改
发现admin的密码被改变了
现在的密码
5.密码改变的原因:
Username直接从数据库中取出,没有经过转义处理。在更新用户密码的时候其实执行了下面的命令:
“UPDATEusers SET PASSWORD=’22′ where username=’admin’#‘ and password=’$curr_pass’”;
因为我们将问题数据存储到了数据库,而程序再取数据库中的数据的时候没有进行二次判断便直接带入到代码中,从而造成了二次注入;