用户登录页面--SQL注入

web网站攻击方式多种多样,sql注入是经常使用的攻击方向。攻击者把SQL命令插入到Web表单的输入域或页面请求的字符串,欺骗服务器执行恶意的SQL命令 SQL注入不是Web或数据库服务器中的缺陷,而是由于编程实践较差且缺乏经验而导致的。

动态拼接的SQL指令最易受攻击。

如登录时使用的SQL指令:

$query = 'SELECT * from Users WHERE login = ' $username ' AND password = ' $password'

攻击者主要利用了mysql的注释指令:# 或者 --

 

攻击者在帐户文本框中输入 aaa' or 1=1 #, 即可骗过服务器,成功登录

详情情况看下面的代码:

数据库

 

连接数据库的conn.php

<?php
$mysqli = new mysqli('localhost','root','root','demo');
if($mysqli->connect_errno){
    printf("连接数据库失败: %s\n", $mysqli->connect_error);
    exit();
}

$mysqli->query('set names utf8');

 用户登录 login.php

<?php
if(empty($_POST)){
    session_start();
    unset($_SESSION);
    session_destroy();
    header('location:login.html');
    exit();
}

require_once 'conn.php';

$username = $_POST['username'];
$password = $_POST['password'];
$password = md5(md5($password));

//错误的sql语句
$sql = "select username from users where username='{$username}' and password='{$password}'";


$result = $mysqli->query($sql);
if($result === false) {
    die($mysqli->error);
}

if($arr = $result->fetch_array()){
    session_start();
    $_SESSION['username'] = $username;
    header('location:index.php');
}else{
    $msg = '用户名或密码输入错误,重新输入';
    $wait = 3;
    $url = 'login.html';
    require_once 'jump.php';
    exit();
}

页面跳转 jump.php

<!doctype html>
<html lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no"/>
    <title>跳转提示</title>
    <style type="text/css">
        *{ padding: 0; margin: 0; }
        body{ background: #fff; font-family: "Microsoft Yahei","Helvetica Neue",Helvetica,Arial,sans-serif; color: #333; font-size: 16px; }
        .system-message{ padding: 24px 48px; }
        .system-message h1{ font-size: 100px; font-weight: normal; line-height: 120px; margin-bottom: 12px; }
        .system-message .jump{ padding-top: 10px; }
        .system-message .jump a{ color: #333; }
        .system-message .success,.system-message .error{ line-height: 1.8em; font-size: 36px; }
        .system-message .detail{ font-size: 12px; line-height: 20px; margin-top: 12px; display: none; }
    </style>
</head>
<body>
<div class="system-message">
    <?php switch ($code) {?>
<?php case 1:?>
            <h1>:)</h1>
            <p class="success"><?php echo(strip_tags($msg));?></p>
            <?php break;?>
        <?php case 0:?>
            <h1>:(</h1>
            <p class="error"><?php echo(strip_tags($msg));?></p>
            <?php break;?>
        <?php } ?>
    <p class="detail"></p>
    <p class="jump">
        页面自动 <a id="href" href="<?php echo($url);?>">跳转</a> 等待时间: <b id="wait"><?php echo($wait);?></b>
    </p>
</div>
<script type="text/javascript">
    (function(){
        var wait = document.getElementById('wait'),
            href = document.getElementById('href').href;
        var interval = setInterval(function(){
            var time = --wait.innerHTML;
            if(time <= 0) {
                location.href = href;
                clearInterval(interval);
            };
        }, 1000);
    })();
</script>
</body>
</html>

 

前端登录页面:login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户登录</title>
    <link rel="stylesheet" href="static/bootstrap-3.3.7-dist/css/bootstrap.css">
    <style>
        body {
            background-color: #cecece;
        }

        .login-form {
            background-color: #fff;
            height: 500px;
            padding: 20px;
            border-radius: 1em;
            margin: 50vh auto 0;
            transform: translateY(-50%);

            -moz-box-shadow: 2px 2px 5px #333333;
            -webkit-box-shadow: 2px 2px 5px #333333;
            box-shadow: 2px 2px 5px #333333;
        }

        .login-form header {
            font-size: 36px;
            font-weight: bolder;
            text-align: center;
            margin-bottom: 30px;
        }
        .login-form .btn-row{
            margin-top: 30px;
        }
    </style>

</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-md-10 col-md-offset-1">
            <form class="login-form" action="login.php" method="post">
                <header>用户登录</header>
                <div class="form-group">
                    <label for="username">用户名</label>
                    <input type="text" class="form-control" id="username" name="username" placeholder="输入用户名">
                </div>
                <div class="form-group">
                    <label for="password">密码</label>
                    <input type="text" class="form-control" id="password" name="password" placeholder="输入密码">
                </div>
                <div class="form-group btn-row">
                    <button type="submit" class="btn btn-primary btn-block">登录</button>
                </div>
                <p class="text-primary">本案例演示sql注入</p>
                <p>sql注入1:利用mysql 注释,用户名输入aaa' or 1=1 #, 密码随意输入</p>
            </form>
        </div>
    </div>
</div>


<script src="static/jquery-1.11.3.min.js"></script>
<script src="static/bootstrap-3.3.7-dist/js/bootstrap.js"></script>
</body>
</html>

 

登录成功后进入首页:index.php

<?php
session_start();
if(empty($_SESSION['username'])){
    $msg = '没有权限,请先登录';
    $wait = 3;
    $url = 'login.html';
    require_once 'jump.php';
    exit();
}
?>
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<p>欢迎:<?php echo $_SESSION['username']; ?></p>
<p><a href="logout.php">注销</a> </p>
</body>
</html>

 

注销 logout.php

<?php
session_start();
unset($_SESSION);
session_destroy();
header('location:login.html');
exit();

最后实现的效果是:

 

攻击者利用程序上的漏洞,轻而易举登录成功。

 

使用sql 指令的参数化可防范SQL注入

正确的login.php代码如下 :

 

<?php
if(empty($_POST)){
    session_start();
    unset($_SESSION);
    session_destroy();
    header('location:login.html');
    exit();
}

require_once 'conn.php';

$username = $_POST['username'];
$password = $_POST['password'];
$password = md5(md5($password));

//正确的sql
$sql = "select username from users where username=? and password=?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('ss',$username,$password);
$stmt->execute();
if($stmt->affected_rows){
    $result = $stmt->get_result();
    if ($arr = $result->fetch_array()) {
        session_start();
        $_SESSION['username'] = $username;
        header('location:index.php');
    } else {
        $msg = '用户名或密码输入错误,重新输入';
        $wait = 3;
        $url = 'login.html';
        require_once 'jump.php';
        exit();
    }
}

如果同样输入:aaa' or 1=1 #

得到的结果是:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李 书 明

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值