【23】WEB安全学习----MySQL注入-8(二阶注入)

什么是二阶注入?

简单的来说,就是第一次注入时,开发者进行了编码等限制,无法直接进行注入,但是在数据库中保留了我们注入的语句,程序在其它地方再次调用保存着我们注入的语句时发生了注入,这就是二阶注入,有点类似存储型XSS漏洞的意思。

二阶注入演示

实验环境介绍

text数据库里有张users表,目前里面已有admin和root账户

用户注册页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>用户注册</title>
</head>
<?php
    function check($str){
        $str1=str_replace("'","''",$str);
        $str1=str_replace('"','""',$str1);
        return $str1;
    }
    if(isset($_POST['submit'])){
        $username=check($_POST['username']);
        $passwd=check($_POST['passwd']);
        $email=check($_POST['email']);
        $mysqli=new mysqli();
        $mysqli->connect('localhost','root','root');
        if($mysqli->connect_errno){
            die('数据库连接失败:'.$mysqli->connect_error);
        }
        $mysqli->select_db('text');
        if($mysqli->errno){
            die('打开数据库失败:'.$mysqli->error);
        }
        $mysqli->set_charset('utf-8');
        $sql="SELECT * FROM users WHERE username='{$username}'";
        $sl=$mysqli->query($sql);
        if(!$sl){
            die('SQL语句执行错误:'.$mysqli->error);
        }else if($sl->num_rows>0){
            $sl->free();
            $mysqli->close();
            die('该用户已被注册,请使用其它账户');
        }else {
            $sql="INSERT INTO users VALUES(NULL,'{$username}',md5('{$passwd}'),'{$email}')";
            echo 'SQL执行语句'.$sql.'<hr />';
            $sl=$mysqli->query($sql);
            if(!$sl){
                die('SQL语句执行错误:'.$mysqli->error);
            }else {
                die("恭喜你注册{$username}成功!");
            }
        }
        $sl->free();
        $mysqli->close();
    }
?>
<body>
    <h1>用户注册</h1>
    <form action="" method="post">
        用户名:<input type="text" name="username"><br />
        密码:<input type="password" name="passwd"><br />
        邮箱:<input type="text" name="email"><br />
        <input type="submit" name="submit" value="注册">
    </form>
</body>
</html>

用户密码修改页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>修改用户密码</title>
</head>
<?php
    if(isset($_POST['submit'])){
        $username=$_POST['username'];
        $passwd=$_POST['passwd'];
        $newpasswd=$_POST['newpasswd'];
        $mysqli=new mysqli();
        $mysqli->connect('localhost','root','root');
        if($mysqli->connect_errno){
            die('数据库连接失败:'.$mysqli->connect_error);
        }
        $mysqli->select_db('text');
        if($mysqli->errno){
            die('打开数据库失败:'.$mysqli->error);
        }
        $mysqli->set_charset('utf-8');
        $sql="SELECT * FROM users WHERE username='{$username}' AND passwd=md5('{$passwd}')";
        $sl=$mysqli->query($sql);
        if(!$sl){
            die('SQL语句执行错误:'.$mysqli->error);
        }else if($sl->num_rows==0){
            $sl->free();
            $mysqli->close();
            die('修改密码失败,用户或原密码错误');
        }else {
            $sql="UPDATE users SET passwd=md5('{$newpasswd}') WHERE username='{$username}'";
            $sl=$mysqli->query($sql);
            if(!$sl){
                die('SQL语句执行错误:'.$mysqli->error);
            }else{
                die('修改密码成功!');
            }
        }
        $sl->free();
        $mysqli->close();
    }
?>
<body>
    <h1>用户密码修改</h1>
    <form action="" method="post">
        用户名:<input type="text" name="username"><br />
        原密码:<input type="password" name="passwd"><br />
        新密码:<input type="password" name="newpasswd"><br />
        <input type="submit" name="submit" value="修改">
    </form>
</body>
</html>

二阶注入演示

首先用户注册页面,对用户提交的数据进行了check()函数过滤,对单引号和双引号进行了闭合,故无法闭合SQL语句。

如:id=1' => id=1''

这里很明显,无法直接一阶注入,但用户修改密码页面对这个表中的数据没有过滤或限制就调用了(开发人员相信数据库中数据),那么此时就存在二阶注入。

首先注册一个用户名为:admin'#的用户,经过check函数就变成了admin''#,此时就无法直接注入。

在数据库中,已插入一个用户名为admin'#的用户

然后在用户修改密码界面中,输入admin'#用户和相应的密码

此时,修改密码的SQL为:

UPDATE users SET passwd=md5('123123') WHERE username='admin'#';
=
UPDATE users SET passwd=md5('123123') WHERE username='admin';

此时,查看数据中记录,发现是admin用户的密码被修改了。

猜你喜欢

转载自blog.csdn.net/a15803617402/article/details/82796301
今日推荐