13-二次注入
二次注入是指已存储(数据库、文件)的用户输入被读取后再次进入到 SQL 查询语句中导致的注入。
原理解析:
二次注入的原理,在第一次进行数据库插入数据的时候,仅仅只是使用了 addslashes 或者是借助 get_magic_quotes_gpc 对其中的特殊字符进行了转义,在写入数据库的时候还是保留了原来的数据,但是数据本身还是脏数据。
在将数据存入到了数据库中之后,开发者就认为数据是可信的。在下一次进行需要进行查询的时候,直接从数据库中取出了脏数据,没有进行进一步的检验和处理,这样就会造成SQL的二次注入。比如在第一次插入数据的时候,数据中带有单引号,直接插入到了数据库中;然后在下一次使用中在拼凑的过程中,就形成了二次注入。
打开如下:
分析代码:
index.php:
if(!empty($_POST['email'])){
if($_POST['sub']){
$username=addslashes($_POST['username']);
$password=addslashes($_POST['password']);
$email=addslashes($_POST['email']);
$sql="INSERT INTO `sqli` (`username` ,`password` ,`email`) VALUES ('$username', '$password', '$email');";
$row = mysql_query($sql);
if($row){
echo "<script>alert('注册成功')</script>";
}else{
echo "<script>alert('注册失败')</script>";
}
}
}else{
echo "<center>请注册输入信息</center>";
}
?>
addslashes
函数对 '
,"
,\
,nul
进行转义,但这里到数据库里会被还原,就是说把脏数据给带到数据库中了,再来看第二个文件
rest.php:
<?php
if($_POST['sub']){
$email=addslashes($_POST['email']);
$sql="select * from sqli where email='{$email}'";
$row=mysql_query($sql);
if($row){
$rows = mysql_fetch_array($row);
$username=$rows['username'];
$sql2="select * from sqli where username='$username'";
$row=mysql_query($sql2) or die(mysql_error());
$rows = mysql_fetch_array($row);
if($rows){
echo "<center><h4>您的用户名是 ".$rows['username']."</h4><br>";
echo "<center><h4>您的密码是 ".$rows['password']."</h4><br>";
}else{
echo "<script>alert('邮箱不存在')</script>";
}
}
}
?>
addslashes
函数处理 emai 参数,带入到 sql 查询然后判断是否成功
成功就进一步查询,mysql_fetch_array
函数从结果集中读取一行数据
从数据中拿到 username 查询SQL,如果成功就再通过 mysql_fetch_array
函数读取 password ,再执行SQL
注册用户功能点可以插入一条脏数据,邮箱找回功能点会查询之前注册用户时候的脏数据,就会造成 SQL 注入,看到有 mysql_error
函数,可以进行报错注入
构造注入语句:
先在用户注册页面构造
用户名:test' or updatexml(1,concat(0x7e,(select database()),0x7e),1)#
密码:123456
邮箱:test
注册成功后,再去找回密码页面
注入成功