首页 技术 正文
技术 2022年11月14日
0 收藏 781 点赞 3,341 浏览 8037 个字

一、注入攻击种类    1. GET注入        输入参数通过URL发送。    2. POST注入        输入参数通过HTTP正文发送    3. COOKIE注入        输入参数通过HTTP cookie发送    4. HTTP Headers注入        通过http提交应用程序时使用的头 二、各种攻击所占比及防范程度    1. 漏洞发现占比                从上图中,可以看到,大部分的http header和http cookie漏洞不能被发现。    2. 漏洞防范占比                从上图中,可以得出,大部分的攻击防范上,在于get和post,而对于cookie和header则很少,因此很容易在这方面失守。 三、注入攻击实验分析    1. 创建实验数据库,分两种类型编码:GBK/UTF8

$createSqlGbk = "CREATE TABLE `user` (`id`  int(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '用户ID' ,`username`  varchar(32) NOT NULL COMMENT '用户名' ,`password`  varchar(32) NOT NULL ,`remark`  text NULL ,PRIMARY KEY (`id`)) DEFAULT CHARACTER SET=gbk";
$createSqlUtf8 = "CREATE TABLE `user` (`id`  int(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '用户ID' ,`username`  varchar(32) NOT NULL COMMENT '用户名' ,`password`  varchar(32) NOT NULL ,`remark`  text NULL ,PRIMARY KEY (`id`)) DEFAULT CHARACTER SET=utf8";

        其中对于多字节编码的数据库,数据在PHP层转义时,GBK存在BUG,因此可以进行测试对比。    2. 初始化数据库

$insertDataSql = "INSERT INTO `user` VALUES ('1', 'test', '123456', null), ('2', 'guest', '888888', null), ('3', 'admin', '888888', null)";

        其中构建一个简单表,放几行简单的数据,用于测试。    3. 构建测试代码

<html>
    <head>
        <title>SQL注入攻击与防范</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
        <style>
            body{font-size:12px;margin:20px;}
            h3{font-size:14px;margin:20px 0;}
            a{font-size:12px;margin:10px 20px;}
        </style>
    </head>
    <body>
        <h3>SQL注入攻击(GBK)</h3>
        <a href="./inject.php?type=gbk&id=1">正常取值</a>
        <a href="./inject.php?type=gbk&id=2341 or 1 = 1 -- dasf">SQL注入(针对直接等于写法)</a>
        <a href="./inject.php?type=gbk&id=2341' or 1 = 1 -- asdf">SQL注入(针对用引号包括写法)</a>
        <a href="./inject.php?type=gbk&isslashes=1&id=2341<?php echo chr(0xbf) . chr(0x27); ?> or 1 = 1 -- asd">SQL注入(针对对特殊字符转义写法)</a>
        <h3>SQL注入攻击(UTF8)</h3>
        <a href="./inject.php?type=utf8&id=1">正常取值</a>
        <a href="./inject.php?type=utf8&id=2341 or 1 = 1 -- dasf">SQL注入(针对直接等于写法)</a>
        <a href="./inject.php?type=utf8&id=2341' or 1 = 1 -- asdf">SQL注入(针对用引号包括写法)</a>
        <a href="./inject.php?type=utf8&isslashes=1&id=2341<?php echo chr(0xbf) . chr(0x27); ?> or 1 = 1 -- asd">SQL注入(针对对特殊字符转义写法)</a>
        <div style="width:100%;height:5px;margin:10px 0px;clear:both;background-color:gray;"></div>
        <?php
        if (isset($_GET['type'])) {
            $type = $_GET['type'];
        } else {
            exit();
        }
        echo "<h1 style='font-size:12px;'>CHARSET:: <b style='color:red;font-size:18px;'>" . $type . "</b></h1>";
        // 建立mysql连接
        $c = mysql_connect("localhost", "root", "");
        echo "<h1 style='font-size:14px;color:red;'>SQL注入攻击及防范</h1>";
 
        if (isset($_GET['id'])) {
            if (isset($_GET['isslashes'])) {
                $id = addslashes($_GET['id']);
            } else {
                $id = $_GET['id'];
            }
            // 三种sql写法
            $sql1 = "SELECT * FROM user WHERE id = $id";
            $sql2 = "SELECT * FROM user WHERE id = '{$id}'";
            $sql = "SELECT * FROM user WHERE id = " . intval($id);
        }
        //根据编码不同,选择连接对应编码数据库
        if ($type == 'gbk') {
            mysql_select_db("testInjectionDb_gbk", $c);
            // change our character set
            mysql_query("SET CHARACTER SET 'gbk'", $c);
        } else {
            mysql_select_db("testInjectionDb_utf8", $c);
            // change our character set
            mysql_query("SET CHARACTER SET 'utf8'", $c);
        }
        // 依次执行三种写法的查询
        echo "<div style='font-size:12px;'>++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++</div>";
        echo "<h1 style='font-size:12px;'>被攻击 SQL1::   <b style='color:red;font-size:14px;'>" . $sql1 . "</b></h1>";
        $r1 = mysql_query($sql1, $c);
        if ($r1) {
            echo "<h1 style='font-size:12px;color:green;'>影响数据条数:: <b style='color:red;font-size:18px;'>" . mysql_num_rows($r1) . "</b></h1>";
        } else {
            echo "<h1 style='font-size:12px;color:red;'>语法错误!</h1>";
        }
        echo "<div style='font-size:12px;'>++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++</div>";
        echo "<h1 style='font-size:12px;'>被攻击 SQL2::   <b style='color:red;font-size:14px;'>" . $sql2 . "</b></h1>";
        $r2 = mysql_query($sql2, $c);
        if ($r2) {
            echo "<h1 style='font-size:12px;color:green;'>影响数据条数:: <b style='color:red;font-size:18px;'>" . mysql_num_rows($r2) . "</b></h1>";
        } else {
            echo "<h1 style='font-size:12px;color:red;'>语法错误!</h1>";
        }
        echo "<div style='font-size:12px;'>++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++</div>";
        echo "<h1 style='font-size:12px;'>强制整型较验 SQL::   <b style='color:red;font-size:14px;'>" . $sql . "</b></h1>";
        $r = mysql_query($sql, $c);
        if ($r) {
            echo "<h1 style='font-size:12px;color:green;'>影响数据条数:: <b style='color:red;font-size:18px;'>" . mysql_num_rows($r) . "</b></h1>";
        } else {
            echo "<h1 style='font-size:12px;color:red;'>语法错误!</h1>";
        }
 
        // 建立PDO的连接,万能防注入。
        // 注意:
        // 1. 参数 PDO::ATTR_EMULATE_PREPARES 设置为 false;
        // 2. 你不能让占位符 ? 代替一组值,如:SELECT * FROM blog WHERE userid IN ( ? );
        // 3. 你不能让占位符代替数据表名或列名,如:SELECT * FROM blog ORDER BY ?;
        // 4. 你不能让占位符 ? 代替任何其他SQL语法,如:SELECT EXTRACT( ? FROM datetime_column) AS variable_datetime_element FROM blog;
        echo "<div style='font-size:12px;'>++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++</div>";
        if ($type == 'gbk') {
            $pdo = new PDO("mysql:host=localhost;dbname=testInjectionDb_gbk", "root", "");
        } else {
            $pdo = new PDO("mysql:host=localhost;dbname=testInjectionDb_utf8", "root", "");
        }
        $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);
        $st = $pdo->prepare("SELECT * FROM user WHERE id = ?");
        $st->bindParam(1, $id);
        $c = $st->execute();
        echo "<h1 style='font-size:12px;'>PDO防注入(万能防注入) SQL::   <b style='color:red;font-size:14px;'>" . $st->queryString . "</b></h1>";
        if ($c) {
            $rs = $st->fetchAll();
            echo "<h1 style='font-size:12px;color:green;'>影响数据条数:: <b style='color:red;font-size:18px;'>" . count($rs) . "</b></h1>";
            var_dump($rs);
            $st->debugDumpParams();
        } else {
            echo "<h1 style='font-size:12px;color:red;'>语法错误!</h1>";
        }
        ?>
    </body>
</html>

        以上代码构建了两种编码(gbk/utf8),执行逻辑分四种实现方式,各四种访问方式,其中第一种为正常访问,后三种分别为注入型写法。            4. 四种实现写法

$sql1 = "SELECT * FROM user WHERE id = $id";$sql2 = "SELECT * FROM user WHERE id = '{$id}'";$sql = "SELECT * FROM user WHERE id = " . intval($id);
$st = $pdo->prepare("SELECT * FROM user WHERE id = ?");$st->bindParam(1, $id);$c = $st->execute();

    5. 应对攻击的表现

<a href="./inject.php?type=gbk&id=2341 or 1 = 1 -- dasf" rel="external nofollow" >SQL注入(针对直接等于写法)</a>
<a href="./inject.php?type=utf8&id=2341 or 1 = 1 -- dasf" rel="external nofollow" >SQL注入(针对直接等于写法)</a>

        从上面可以很明确的看到,在所传参数中,带有注入性语句。表现结果:        GBK编码:                UTF8编码:                从中可以看到,两种编码的数据库中,对于 SQL1 的写法是实现了成功注入。 

<a href="./inject.php?type=gbk&id=2341' or 1 = 1 -- asdf" rel="external nofollow" >SQL注入(针对用引号包括写法)</a>
<a href="./inject.php?type=utf8&id=2341' or 1 = 1 -- asdf" rel="external nofollow" >SQL注入(针对用引号包括写法)</a>

        从测试的结果中,可以知道,对于两种编码,都实现了对 SQL2 写法的注入攻击。

<a href="./inject.php?type=gbk&isslashes=1&id=2341<?php echo chr(0xbf) . chr(0x27); ?> or 1 = 1 -- asd" rel="external nofollow" >SQL注入(针对对特殊字符转义写法)</a>
<a href="./inject.php?type=utf8&isslashes=1&id=2341<?php echo chr(0xbf) . chr(0x27); ?> or 1 = 1 -- asd" rel="external nofollow" >SQL注入(针对对特殊字符转义写法)</a>

        其中在链接中输出 chr(0xbf) . chr(0x27) ,主要是为了测试多字节编码的值,经过转义后,对于GBK存在BUG,addslashes处理后,前一个字符会被转义为一个多字节的合法字符,而后面的 chr(0x27) 则自动成了一个单引号,从而实现字符串截断,造成注入。而相对于GBK,UTF8编码的数据库,在编码转义过程中,不存在该问题。        GBK表现(注入成功)                UTF8表现                对于第三种写法,因为 ID 在查询过程中,明确是整型数值,因此,在查询前,强制进行整型校验,所以在这几种攻击方式中,都没能实现注入,因此,对于此种类型的数据查询条件,为了安全,我们可以进行相应的校验,从而保证安全,但对于其他类型的变量,则不太好处理。        综合上面的几种表现,最好的方式是以 PDO 方式来实现数据库的查询逻辑,只需注意以下几点即可:        1. 参数 PDO::ATTR_EMULATE_PREPARES 设置为 false;        2. 你不能让占位符 ? 代替一组值,如:SELECT * FROM blog WHERE userid IN ( ? );        3. 你不能让占位符代替数据表名或列名,如:SELECT * FROM blog ORDER BY ?;        4. 你不能让占位符 ? 代替任何其他SQL语法,如:SELECT EXTRACT( ? FROM datetime_column) AS variable_datetime_element FROM blog; 四、总结    sql注入,可以从多方面来进行防范,在可能的情况下,如果数据库需要存储多字节字符,建议数据库的编码方式尽量采用UTF8;另外,在查询数据库的逻辑实现过程中,我们要加强对于语句编写方面的一些安全意识,如,对于整型数值进行强制性的类型校验等;在解决方案上,建议采用 PDO 方式来实现相关的数据库操作逻辑。    而对于另外几种攻击方式,区别在于传送攻击的方式不同,原理还是一样,所以不再赘叙。 附件:    测试实验文件:http://pan.baidu.com/share/link?shareid=963562568&uk=1090915711 

附件列表

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,076
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,552
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,400
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,176
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,812
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,894