二次注入的复现

0x00.前言

  最近了解到二次注入,于是参考强网杯的"three hit",本地搭建了二次注入的环境来复现理解二次注入的形成

0x01.搭建环境

  搭建一个web环境,功能有注册、登录、登录后显示同年龄的人

  

  以下给出源码,由于只是为了达到复现二次注入产生的效果来理解二次注入,故在功能和界面上代码写得比较粗糙,望见谅

  conn.php源码:

1 <?php
2     $con = mysqli_connect('localhost','root','root','test');
3     if(!$con){
4         die('Cound not connect:'.mysqli_connect_error());
5     }
6 ?>

  register.php源码:

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <title>注册</title>
 5     <meta charset="utf-8">
 6 </head>
 7 <body>
 8 <h2 align="center">注册</h2>
 9 <form action="" method="POST">
10     用户名: <input type="text" name="name"><br>
11     年龄: <input type="text" name="age"><br>
12     密码: <input type="text" name="pwd"><br>
13     <input type="submit" name="submit" value="提交">
14 </form>
15 <?php
16     require('conn.php');
17     if(isset($_POST['submit'])){
18         $user = addslashes(@$_POST['name']);  //addslashes过滤掉单引号等防注入
19         $age = addslashes(@$_POST['age']);
20         $pwd = addslashes(@$_POST['pwd']);
21         $sql = "INSERT INTO user(name,pwd,age) VALUES('".$user."','".$pwd."','".$age."')";
22         if($res = mysqli_query($con,$sql)){
23             echo "注册成功<br>用户名:$user<br>年龄:$age<br><a href='login.php'>去登录</a>";
24         }else{
25             echo "注册失败";
26         }
27     }
28 ?>
29 </body>
30 </html>

  login.php源码:

 1 <?php
 2 session_start();
 3 ?>
 4 
 5 <!DOCTYPE html>
 6 <html>
 7 <head>
 8     <title>登录</title>
 9     <meta charset="utf-8">
10 </head>
11 <body>
12 <h2 align="center">登录</h2>
13 <form action="" method="POST">
14     用户名: <input type="text" name="name"><br>
15     密码: <input type="text" name="pwd"><br>
16     <input type="submit" name="submit" value="登录">
17 </form>
18 <h2>已注册用户:</h2><hr>
19 <?php
20     require("conn.php");
21     $sql = "SELECT * FROM user";
22     // 列出已注册用户
23     if($res = mysqli_query($con,$sql)){
24         while($row = mysqli_fetch_assoc($res)){
25             echo "用户名:".$row['name']."<br>年龄:".$row['age']."<br>";
26         }
27     }
28 ?>
29 <hr>
30 <?php
31     if(isset($_POST['submit'])){
32         $name = @$_POST['name'];
33         $pwd = @$_POST['pwd'];
34         $sql = "SELECT * FROM user WHERE name='".$name."' and pwd='".$pwd."'";
35         // 登录
36         if($res = mysqli_query($con,$sql)){
37             if(mysqli_num_rows($res)>0){
38                 $_SESSION['user'] = $name;
39                 header("Refresh:0;url=index.php");
40             }else{
41                 echo '登录失败';
42             }
43         }
44     }
45 ?>
46 </body>
47 </html>

  index.php源码:

 1 <?php
 2     session_start();
 3     if(!isset($_SESSION['user'])){
 4         header("Refresh:0;url=login.php");
 5     }
 6 ?>
 7 <!DOCTYPE html>
 8 <html>
 9 <head>
10     <title>首页</title>
11     <meta charset="utf-8">
12 </head>
13 <body>
14 <?php
15     require('conn.php');
16     //显示当前用户信息
17     $sql = "SELECT * FROM user WHERE name='".@$_SESSION['user']."'";
18     if($res = mysqli_query($con,$sql)){
19         while($row = mysqli_fetch_assoc($res)){
20             $current_name = $row['name'];
21             $current_age = $row['age'];
22             echo '当前用户:'.$current_name.'<br>年龄:'.$current_age;
23         }
24     }
25     echo "<br><br>";
26     //显示同龄用户
27     $sql = "SELECT * FROM user WHERE age='".$current_age."' LIMIT 1";// $current_age从数据库取出未经过滤直接拼接SQL语句,从而产生二次注入
28     if($res = mysqli_query($con,$sql)){
29         while($row = mysqli_fetch_assoc($res)){
30             echo '与'.$current_name.'<br>同年龄为'.$current_age.'的有<br>'.$row['name']."<br>";
31         }
32     }
33 
34     echo "<br><br><a href='register.php'>去注册</a>"
35 ?>
36 </body>
37 </html>

0x03.复现

  先注册一个用户test1,年龄为1

  

  登录后,可以看到正常的效果

  

  接下来,注册一个用户user1,年龄为1' and 1=2 #

  

  这里可以看到,单引号前是被加了的,产生不了注入

  

  接着在login.php可以看到,从数据库取出的年龄是有单引号并且最后有个#注释符的,是被污染的危险数据

    

  登录之后,可以看到,原本该显示同年龄的人的地方并没有显示,说明报错了,and 1=2被拼接进了SQL语句

  接下来就是常规的SQL注入了

  接着注册年龄为【1' order by 1 #】...【1' order by 4#】、【1' union select 1,2,3#】、【1' union select user(),2,3#】...

  1' order by 1#】

   

    1' order by 4#】

  

  【1' union select 1,2,3#】

  

  【1' union select user(),2,3#】

  

0x04.总结

  二次注入可以理解为先将恶意数据插入到数据库,之后服务器从数据库取出恶意数据,未经过滤就直接拼接SQL语句进行查询而导致的漏洞

  因为精心构造的恶意数据在中间折转了一次,故名为二次注入

原文地址:https://www.cnblogs.com/hun-ya/p/9314398.html