1. 什么是二次注入
二次注入可以理解为,攻击者构造的恶意数据存储在数据库后,恶意数据被读取并进入到SQL查询语句所导致的注入。防御者可能在用户输入恶意数据时对其中的特殊字符进行了转义处理,但在恶意数据插入到数据库时被处理的数据又被还原并存储在数据库中,当Web程序调用存储在数据库中的恶意数据并执行SQL查询时,就发生了SQL二次注入。
2. 二次注入的原理
二次注入的原理,在第一次进行数据库插入数据的时候,仅仅只是使用了 addslashes 或者是借助get_magic_quotes_gpc 对其中的特殊字符进行了转义,在写入数据库的时候还是保留了原来的数据,但是数据本身还是脏数据。
在将数据存入到了数据库中之后,开发者就认为数据是可信的。在下一次进行需要进行查询的时候,直接从数据库中取出了脏数据,没有进行进一步的检验和处理,这样就会造成SOL的二次注入。比如在第一次插入数据的时候,数据中带有单引号,直接插入到了数据库中,然后在下一次使用中在拼凑的过程中,就形成了二次注入。
3. 二次注入的过程
(1)先构造语句
(此语句含有被转义字符的语句,如mysql_escape_string、mysql_real_escape_string 转义)
(2)将我们构造的恶意语句存入数据库(被转义的语句)
(3)第二次构造语句
(结合前面已被存入数据库的语句构造。因为系统没有对已存入的数据做检查,成功注入)
4.实例
首先先查询下初始的users表
在网站进行注册,用户名为admin'#,密码123456
再查看下现在的users表
接着输入新的用户名和密码进行登录
此时弹出是否更改密码,点击更改,改为123
查看此时的users表,admin’#的密码并未被更改,被更改的是admin后的密码
原语句
UPDATE users SET PASSWORD='$pass' where username='$username' and password='$curr_pass'
插入 payload 后的语句
UPDATE users SET PASSWORD='$pass' where username='admin'#' and password='$curr_pass'
此时 'admin' 后的语句被注释
真正的生效的语句
UPDATE users SET PASSWORD='$pass' where username='admin'
从而达到了修改用户 admin 密码的目的