二次注入的复现

0x00.前言

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

0x01.搭建环境

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

  

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

  conn.php源码:web

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源码:sql

 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,年龄为1session

  

  登陆后,能够看到正常的效果fetch

  

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

  

  这里能够看到,单引号前是被加了\的,产生不了注入

  

  接着在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语句进行查询而致使的漏洞

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

相关文章
相关标签/搜索