原理:
二次注入需要具备的两个条件:
(1) 用户向数据库插入恶意语句 (即使后端代码对语句进行了转义, 如 mysql_escape_string,mysql_real_escape_string 转义)
(2) 数据库对自己存储的数据非常放心, 直接取出恶意数据给用户
举例:
(1) 在 sqli_libs 的第 24 关, 其页面如下所示:
(2) 当我们点击 Forgot your password? 时, 出现提示:
(3) 因此可以尝试在注册页面进行二次注入, 首先, 我们注册一个账号, 名为: admin'# , 密码为: 123456
(4) 注册成功, 尝试登录 admin'# , 然后可以查看一下 phpmyadmin 内存储情况
(5) 而这时的 admin 原密码是 admin, 并且两个账号都存储在数据库内的. 当我们重新修改 admin'# 的密码的时候, 这里修改为: 12345678; 可以发现二次注入的威力所在. admin 的密码被修改为了: 12345678; 而 admin'# 用户的密码并没有发生变化.
(6) 代码审计, 尝试分析源码, 出现问题的页面很显然是注册页面, 与密码修改重置的页面.
注册用户时:
仅对特殊字符进行了转义, 判断输入两次密码是否一致, 然后将用户键入, 将数据插入至数据库.
$sql = "insert into users ( username, password) values(\"$username\", \"$pass\")"
这里直接插入了数据
修改密码时:
- $username= $_SESSION["username"];// 直接取出了数据库的数据
- $sql = "UPDATE users SET PASSWORD='$pass'where username='$username'and password='$curr_pass' ";// 对该用户的密码进行更新
- $sql = "UPDATE users SET PASSWORD='12345678'where username='admin'#
执行成功!
防御:
(1) 对外部提交数据谨慎
(2) 从数据库取数据时, 不能轻易相信查询出的数据, 要做到同样的转义或是甄别
来源: http://www.bubuko.com/infodetail-3116134.html