一、注入攻击种类
    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. css制作小三角

    视觉稿中经常有些小三角,如下图.每次用图片做太不方便了,我们看看用css实现的效果(支持ie6,7哦) <style> /*border实现三角*/ /*箭头向上*/ .arrow-top ...

  2. the third assignment of software testing

    没有网的日子不好过,Junit4下不下来,先用androidTestCase实现一个. 遇到了几个bug. 首先是除0问题. public void testDivide(){ result=calc ...

  3. ls -l命令详解

    输入: ls -l 输出: -rwxr-xr-x root root May : b 第一个字段(1个字符):文件类型 - :普通文件 d:目录文件 b:块设备文件(block) c:字符设备文件(c ...

  4. Sql Server 与CLR集成

    .NET编程和SQL Server ——Sql Server 与CLR集成   一.SQL Server 为什么要与CLR集成 1. SQL Server 提供的存储过程.函数等十分有限,经常需要外部 ...

  5. SharePoint 页面Pages和SitePages目录创建不成功解决

    最近项目中要用到Pages及SitePages目录中的一个 可是目录时,不是发现没有Pages就是没SitePages: 分析后才得知Pages目录需要开户SharePoint Server Publ ...

  6. js广告浮动

    一个广告框在指定区域,有定位属性的父级区域内,一直向右向左移动,如果碰到左右边框,反向,如果碰到上下边距,反向,实现在指定框中浮动的效果. <!doctype html> <html ...

  7. 20151216JqueryUI学习笔记---按钮

    按钮(button) , 可以给生硬的原生按钮或者文本提供更多丰富多彩的外观. 它不单单可以设置按钮或文本,还可以设置单选按钮和多选按钮.一. 使用 button 按钮使用 button 按钮 UI ...

  8. MVC中实现部分内容异步加载

    MVC中实现部分内容异步加载 action中定义一个得到结果集的方法 public ActionResult GetItemTree(string title, int itemid, int? pa ...

  9. ios paper for facebook 使用第三方库

    facebook paper使用的第三方库 Facebook Paper使用的第三方库 第三方库名 简介 链接 ACE code editor https://github.com/ajaxorg/a ...

  10. poi 导入/导出 工具类

    package com.holy.util; import java.io.File; import java.io.FileOutputStream; import java.io.IOExcept ...