一、注入攻击种类
    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">SQL注入(针对直接等于写法)</a>
<a href="./inject.php?type=utf8&id=2341 or 1 = 1 -- dasf">SQL注入(针对直接等于写法)</a>
        从上面可以很明确的看到,在所传参数中,带有注入性语句。表现结果:
        GBK编码:
        
        UTF8编码:
        
        从中可以看到,两种编码的数据库中,对于 SQL1 的写法是实现了成功注入。
 
<a href="./inject.php?type=gbk&id=2341' or 1 = 1 -- asdf">SQL注入(针对用引号包括写法)</a>
<a href="./inject.php?type=utf8&id=2341' or 1 = 1 -- asdf">SQL注入(针对用引号包括写法)</a>
        从测试的结果中,可以知道,对于两种编码,都实现了对 SQL2 写法的注入攻击。
<a href="./inject.php?type=gbk&isslashes=1&id=2341<?php echo chr(0xbf) . chr(0x27); ?> or 1 = 1 -- asd">SQL注入(针对对特殊字符转义写法)</a>
<a href="./inject.php?type=utf8&isslashes=1&id=2341<?php echo chr(0xbf) . chr(0x27); ?> or 1 = 1 -- asd">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 方式来实现相关的数据库操作逻辑。
    而对于另外几种攻击方式,区别在于传送攻击的方式不同,原理还是一样,所以不再赘叙。
 
附件:
 

附件列表

mysql注入攻击及防范的更多相关文章

  1. [转载] MySQL 注入攻击与防御

    MySQL 注入攻击与防御 2017-04-21 16:19:3454921次阅读0     作者:rootclay 预估稿费:500RMB 投稿方式:发送邮件至linwei#360.cn,或登陆网页 ...

  2. 个人网站对xss跨站脚本攻击(重点是富文本编辑器情况)和sql注入攻击的防范

    昨天本博客受到了xss跨站脚本注入攻击,3分钟攻陷--其实攻击者进攻的手法很简单,没啥技术含量.只能感叹自己之前竟然完全没防范. 这是数据库里留下的一些记录.最后那人弄了一个无限循环弹出框的脚本,估计 ...

  3. SQL注入攻击及防范

    一.什么是SQL注入1.SQL注入的定义     SQL注入(SQL Injection) 利用了程序中的SQL的漏洞,进行攻击的方法. 2.SQL注入举例  1)利用SQL语法错误获取数据库表的结构 ...

  4. mySql 注入攻击

    注入攻击 1.原理: a.只要是带有参数的动态网页且此网页访问了数据库,那么就有可能存在SQL注入; b.字符串拼接和没有判断用户输入是否合法------>导致用户可以玩填字游戏-----> ...

  5. Mysql注入攻击与防御(思维导图笔记)

  6. SQL注入攻击

    SQL注入攻击是黑客对数据库进行攻击的常用手段之一.随着B/S模式应用开发的发展,使用这种模式编写应用程序的程序员也越来越多.但是由于程序员的水平及经验也参差不齐,相当大一部分程序员在编写代码的时候, ...

  7. ASP.NET中的SQL注入攻击与防护

    什么是SQL注入攻击? 它是在执行SQL查询的时候,由于接收了用户的非法参数从而导致,所执行的SQL语义与业务逻辑原本所要查询的语义不相符,从而实现的攻击. 例如我们经常使用的用户登录,通常会出现这样 ...

  8. 【数据库】SQL注入攻击

    背景: 机房收费系统验收的时候,师父提到SQL注入攻击.自己以前看过类似的博客大概知道一些这方面的事情,于是自己动手查了查. 定义: 所谓SQL注入,通过SQL命令插入到Web表单提交或者输入域名或页 ...

  9. SQL注入攻击的种类和防范手段

    观察近来的一些安全事件及其后果,安全专家们已经得到一个结论,这些威胁主要是通过SQL注入造成的.虽然前面有许多文章讨论了SQL注入,但今天所讨论的内容也许可帮助你检查自己的服务器,并采取相应防范措施. ...

随机推荐

  1. iOS之苹果和百度地图的使用

    iOS中使用较多的3款地图,google地图.百度地图.苹果自带地图(高德).其中苹果自带地图在中国使用的是高德的数据.苹果在iOS 6之后放弃了使用谷歌地图,而改用自家的地图.在国内使用的较多的就是 ...

  2. oracle Form Builer:ID_NULL Built-in

    Description                                                                     Returns a BOOLEAN va ...

  3. Magento Block设计分析(深入分析)

    Magento中Block是一个很重要的组件,它在Block中充当非常重要的角色,下面我们来分析一下Magento中Block是怎样设计的,我们应该怎样使用这个重要的角色. 1.Magento Blo ...

  4. Css3炫酷总结使用

    先从CSS3的选择器说起: E F:所有的子孙元素: E>F: E中的子元素: E+F:E元素之后的最近的选择器: E~F:E中所以后面兄弟元素(CSS3 不包括自己本身,前面也不包括) att ...

  5. photoshop 常用快捷键大全

    一.文件新建 CTRL+N打开 CTRL+O 打开为 ALT+CTRL+O关闭 CTRL+W保存 CTRL+S 另存为 CTRL+SHIFT+S另存为网页格式 CTRL+ALT+S打印设置 CTRL+ ...

  6. Android和.net API的数据交互

    一..net API 一般的页面都是.aspx文件,由于.aspx文件都带有HTML的格式,我们传递的都是json格式的数据,所以html页面格式对json格式有影响,故而我们写Web-API都不会采 ...

  7. SQLServer 在Visual Studio的连接方法

    一.Sql Server 在Visual Studio的连接有两种方法: (1)本地计算机连接; [c#] view plaincopy     string s = "Data Sourc ...

  8. php有三种工作模式

    php有三种工作模式. 其中是最常见的是php作为一个模块工作在一个多进程的webserver中, 例如apache webserver. apache会启动一个主进程, 多个子进程(php). 主进 ...

  9. php中实现精确设置session过期时间的方法

    http://www.jb51.net/article/52309.htm 大多数据情况下我们对于session过期时间使用的是默认设置的时间,而对于一些有特殊要求的情况下我们可以设置一下sessio ...

  10. bzoj1131: [POI2008]Sta

    思路:首先先求出以1为根的答案,然后考虑由i转移到i的儿子的答案的变化,显然以son[i]为根的子树的所有结点的深度都会减一,其余的点的深度都会加一,然后就可以直接O(n)求出所有结点的答案,然后取m ...