0x0 原理
针对场景:
存在另一处操作直接调用输入数据而不做其他处理
关键:【寻找另一处引用这个数据的操作】如果另一处操作直接将1’作为变量带进自身的sql语句中,且未做如转义等处理,那1’的单引号便会发生作用,起到sql注入的效果
0x11 演示
以sqlilabs 24关为例
先点击forget your pass?出来如下页面,看来是提示我们通过注入修改密码
注册一个新用户,用户名admin4‘#,密码4444
注册成功
这时候看数据库,提前留意下admin4的密码
以刚注册的用户登陆
修改密码为4111
再看回数据库
会发现被修改密码的是admin4,而不是我们登陆的admin4’#,这就是二次注入
0x12解析
以24关的代码为例
回忆我们刚刚的操作,注册admin4’#,修改admin4’#密码,发现admin4的密码被修改
重点在admin4’#的修改密码操作
对应代码在pass_change.php
可以看到,执行的sql语句为
$sql= ”UPDATE users SET PASSWORD = ‘$pass’ where username = ‘$username’ and password = ‘$curr_pass’ ”;
当我们以admin4’#的用户修改原密码4444为新密码4111时,执行的对应sql语句就为
$sql= ”UPDATE users SET PASSWORD = ‘4111’ where username = ‘admin4’#’ and password = ‘4444’”;
这条语句实际执行时产生的效果相当于
$sql= ”UPDATE users SET PASSWORD = ‘4111’ where username = ‘admin4’;
也就是修改用户admin4的密码为4111,也就造成了二次注入
0x2 防御
24关其实在注册,登陆,修改密码的数据带入sql语句前都用了mysql_real_escape_string对特殊字符进行转义,但修改密码中, sql语句中的$username是直接通过$_SESSION["username"]从数据库中提取的,这个变量并未进行处理就被带入sql语句中执行了,进而导致单引号发挥作用,造成注入。
防止二次注入,要么禁止输入数据库的变量中存在非法字符,如果必须要有字符,在数据出库后,也要做好处理
数据的输入输出都要有处理