sqli-二次注入

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 =4111where username = ‘admin4’#’ and password =4444’”;

这条语句实际执行时产生的效果相当于

$sql=UPDATE users SET PASSWORD =4111where username = ‘admin4’;

也就是修改用户admin4的密码为4111,也就造成了二次注入

0x2 防御

24关其实在注册,登陆,修改密码的数据带入sql语句前都用了mysql_real_escape_string对特殊字符进行转义,但修改密码中, sql语句中的$username是直接通过$_SESSION["username"]从数据库中提取的,这个变量并未进行处理就被带入sql语句中执行了,进而导致单引号发挥作用,造成注入。

防止二次注入,要么禁止输入数据库的变量中存在非法字符,如果必须要有字符,在数据出库后,也要做好处理

数据的输入输出都要有处理

 

原文地址:https://www.cnblogs.com/Rain99-/p/10595073.html