本文最后更新于:2019 , 六月 9日 星期日, 2:26 下午

简介

正常注入我们是在http请求中构造恶意sql语句发送至服务端进行处理
系统是立即执行并以响应的的形式返回至攻击者的客户端上的

二次注入:是注入点经过函数过滤或防护无法触发漏洞,但是存入数据库中又被还原了,导致数据库中的数据执行时可能出现二次注入漏洞
例如:在一个存在注入又被函数过滤了的数据存入数据库中还原了,同时在其他地方可以引用该数据

实现步骤

  • 在第一次提交中构造可以在下一次检索中执行的恶意语句
  • 提交第二次其他语句检索第一次提交的恶意语句,两个结合达到我们想要执行的结果
  • 在第二次请求响应中返回结果

简易靶场

  • registered.php
<?php
header("content-type:text/html;charset=utf-8");
if(!empty($_POST['submit'])){
    $id = addslashes($_POST['id']);
    $username = addslashes($_POST['username']);
    $password = addslashes($_POST['password']);
    $email = addslashes($_POST['email']);
    $conn = mysql_connect("localhost","root","root");
    mysql_select_db("test",$conn);
    $sql = "INSERT INTO admin(id,admin,password,email) value('$id','$username','$password','$email')";
    $result = mysql_query($sql,$conn) or die('Error:'.mysql_error());
    if($result){
        echo '注册成功';
    }else{
        echo '注册失败';
    }
    mysql_close();
}else{
    echo "Error";
}
?>

<html>
    <head>
        <title>注册</title>
    </head>

    <body>
        <form action="reg.php" method="post">
            id:<input type="text" name="id"><br/>
            username:<input type="text" name="username"><br/>
            password:<input type="password" name="password"><br/>
            email:<input type="text" name="email">
            <input type="submit" name="submit" value="注册">
        </form>
    </body>
</html>
  • serach.php
<?php
if(!empty($_POST['submit'])){
    $id = addslashes($_POST['id']);
    $conn = mysql_connect("localhost","root","root");
    mysql_select_db("test",$conn);
    $sql = "select * from admin where id = '$id'";
    $result = mysql_query($sql,$conn) or die("error:".mysql_error());
    while($row = mysql_fetch_array($result)){
        $username = $row['admin'];
        $sql2 = "select * from admin where admin='$username'";
        $result2 = mysql_query($sql2,$conn) or die("error:".mysql_error());
        while ($row2 = mysql_fetch_array($result2)){
            echo "ID:".$row2['id']."<br />";
            echo "用户名:".$row2['admin']."<br />";
            echo "密码:".$row2['password']."<br />";
            echo "邮箱:".$row2['email']."<br />";
            echo "<hr>";
            echo "第一次插入的恶意语句:".$row['admin']."<br />";
            echo "查询id语句:".$sql."<br />";
            echo "后台查询用户语句:".$sql2;
        }
    }
    mysql_close();
}else{
    echo "Error";
}
?>

<form action="serach.php" method="post">
    搜索id:<input type="text" name="id">
    <input type="submit" value="搜索" name="submit">
</form>

漏洞测试

从以上源码,可以看到最主要的问题是出现在serach.php中第二次sql语句查询

$sql2 = "select * from admin where admin='$username'";

所以这里我们根据这个语句,构造我们恶意插入数据库中的代码

' order by 4 # 正确 
' order by 5 # 错误

之后就可以正常的进行注入或报错注入了

Ps:该靶场的时间盲注有个前提,就是你能猜到admin字段中的值,并把它提前插入到语句中
否则直接构造是直接返回空的,例如:' and if(length(database())=3,0,sleep(10)) #这样是不行的
正确:admin' and if(length(database())=3,0,sleep(10)) #


Web      Web

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!

图片一句话制作
Sql基础注入笔记