二次注入
原理
二次注入的原理,在第一次进行数据库插入数据的时候,仅仅只是使用了 addslashes 或者是借助get_magic_quotes_gpc 对其中的特殊字符进行了转义,但是 addslashes 有一个特点就是虽然参数在过滤后会添加 “\” 进行转义,但是“\”并不会插入到数据库中,在写入数据库的时候还是保留了原来的数据。
在将数据存入到了数据库中之后,开发者就认为数据是可信的。在下一次进行需要进行查询的时候,直接从数据库中取出了脏数据,没有进行下一步的检验和处理,这样就会造成 SQL 的二次注入。比如在第一次插入数据的时候,数据中带有单引号,直接插入到了数据库中;然后在下一次使用中在拼凑的过程中,就形成了二次注入。
二次注入图解
二次注入原理,主要分成两步:
第一步:插入恶意数据库
第一次进行数据库插入数据的时候,仅仅对其特殊字符进行转义,在写入数据库的时候还保留了原来的数据,但数据的包含恶意内容。
第二步:引用恶意数据库
在将数据存入数据库后,开发者就认为数据是可信的,在下一次需要进行查询的时候,直接从数据中取出恶意数据,没有进行进一步的校验和处理,这样就造成了sql二次注入
举例
新建用户 admin’#,有特殊字符,但写入成功,并能使用该用户登录。
正常修改用户密码时
sql 语句为:update user set password='1234' where username='x' and psssword='xx'
但当用户为 admin’# 时
sql 语句变为:update user set password='1234' where username='admin'#' and xxxxx # 此时井号后的语句都被注释掉了
结果就是会修改掉原有用户 admin 的密码。
二次注入代码分析
mysql_escape_string 函数会将特殊字符进行过滤 如’ 经过转义就成了’ 然后用 insert into 存入在数据库中。
在 login.php 查看源码登录获取用mysql_escape_string 对输入的参数进行转义
转义之后在数据库中查找指定的账号和密码 再传入到 session 里
$
_SESSION[‘username’] 复制给$
username 无任何过滤再带入 UPDATE 语句中造成注入。整个流程就是注册用户,更改密码时会触法注入。可以看到二次注入笔记隐蔽。通常发生在更改,需要二次带入数据时提交的功能里
黑盒环境下进行的二次注入测试
先确定测试的网站是否进行过滤,一般情况下网站都会对输入的参数进行过滤,然后寻找可能会带入恶意数据二次使用的地方。例如:用户注册->修改密码邮箱注册->修改密码 文章添加->文章编辑。找一切存在二次使用的功能点。
二次注入测试 SQL 注入,二次注入多数是字符型注入,所以要注意闭合问题。
现在注册用户 a’ 再分别注册用户 a’ and 1=1# a’ and 1=2# 再来可能触发的地方
密码输入 a123456 提交后可以看到密码被修改成功了
如果是 a’ and 1=2# 怎么修改都不会成功的。
这种情况下可以判断是二次注入。这个注入点传入的参数有长度限制 导致二次注入查询敏感信息,二次注入配合 mysql 报错查询数据均不能成功,只能修改其他账号的密码了 例如 admin 的密码
注册用户 admin’# 登录修改密码 就能修改 admin 的密码
二次编码注入
举例
用户输入 id=1%27,会被 php 转码为 id=1’。
转义代码发现有单引号,转义为 id=1’,无法 SQL 注入。
用户输入 id=1%2527,由于 %25 转码后就是 %,因而会转码为 id=1%27。
转义代码没有发现单引号,故不转义。
但后续 urldecode 等函数,处理 url 时,会将 id=1%27 转码为 id=1’,就可以注入。
注意
如果做白盒测试,要看 urldecode 函数是否在 php 转义方法之后。