参考文献:https://www.jianshu.com/p/3fe7904683ac
环境
wampserver2.5-Apache-2.4.9-Mysql-5.6.17-php5.5.12-32b
PS:我只有这个版本的wamp环境可以成功的实现二次注入,在phpstudy的版本中都自带的有转义,若是在插入数据的时候再加上转义那么存到数据库中的脏数据也都被转义了。
sql二次注入原理:
在第一次进行数据库插入数据的时候,仅仅只是使用了 addslashes或 get_magic_quotes_gpc对其中的特殊字符进行了转义,在写入数据库的时候还是保留了原来的数据,但是数据本身还是脏数据。在下一次进行需要进行查询的时候,直接从数据库中取出了脏数据,没有进行进一步的检验和处理,这样就会造成SQL的二次注入。
比如在第一次插入数据的时候,数据中带有单引号,直接插入到了数据库中;然后在下一次使用中在拼凑的过程中,就形成了二次注入
例1
sqli-labs第24关
$username = mysql_real_escape_string($_POST["login_user"]);
$password = mysql_real_escape_string($_POST["login_password"]);
$sql = "SELECT * FROM users WHERE username='$username' and password='$password'";
使用`mysql_real_escape_string`进行转义处理,无法进行SQL注入。
- 注册一个
admin'#
的账号
- 用
admin'#
登陆,并进行密码修改,密码修改为123
可以看到admin
的密码由原来的admin
修改为123
$sql = "UPDATE users SET PASSWORD='$pass' where username='$username' and password='$curr_pass' ";
这是因为上面的数据库更新语句,在用户名为 "admin'#" 时执行的实际是:
$sql = "UPDATE users SET PASSWORD='$pass' where username='admin'#' and password='$curr_pass' ";
例2
一个简单demo
创建数据库
mysql> create database demo;
mysql> use demo;
mysql> create table story(id int(10) NOT NULL AUTO_INCREMENT,title varchar(50) NOT NULL,author varchar(30) NOT NULL,description varchar(300) NOT NULL,content varchar(888) NOT NULL,PRIMARY KEY (id));
- connect.php
<?php
$dbuser ='root';
$dbpass ='xxxx';
$dbname ="demo";
$host = 'localhost';
$dbname1 = "story";
$con1 = mysqli_connect($host,$dbuser,$dbpass,$dbname);
if (mysqli_connect_errno($con1))
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
?>
- inser.php
<?php
include('connect.php');
$title=addslashes($_POST['title']); //addslashes 将预定义字符串转义
echo $title;
$author=addslashes($_POST['author']);
$description=addslashes($_POST['description']);
$content=addslashes($_POST['content']);
$insert="INSERT INTO story(title,author,description,content) VALUES('$title','$author','$description','$content')";
echo $insert;
//mysqli_query("set names utf8"); //设置编码
$result=mysqli_query($con1,$insert);
if($result){
echo "success!!!";
}else{
echo "default!";
}
?>
- connect.php
<!DOCTYPE html>
<html>
<head>
<meta charset="utf8">
<title>啦啦啦啦啦啦</title>
</head>
<body>
<?php
include('connect.php'); //引入数据库配置文件
$id=$_GET['id'];
$select_sql="SELECT * FROM story WHERE id='$id'";
//echo $select_sql;
$select_sql_result=mysqli_query($con1,$select_sql);
while($date=mysqli_fetch_array($select_sql_result)){
echo '书名:'.$date['title'].'</br>';
echo '作者:'.$date['author'].'</br>';
echo '概述:'.$date['description'].'</br>';
echo '正文:'.$date['content'].'</br>';
}
?>
</body>
</html>
解法思路和例1类似。