zoukankan      html  css  js  c++  java
  • sql注入学习笔记,什么是sql注入,如何预防sql注入,如何寻找sql注入漏洞,如何注入sql攻击 (原)

    (整篇文章废话很多,但其实是为了新手能更好的了解这个sql注入是什么,需要学习的是文章最后关于如何预防sql注入)

    (整篇文章废话很多,但其实是为了新手能更好的了解这个sql注入是什么,需要学习的是文章最后关于如何预防sql注入

    (整篇文章废话很多,但其实是为了新手能更好的了解这个sql注入是什么,需要学习的是文章最后关于如何预防sql注入

        重要的事情说三遍  ^-^

    一.什么是SQL注入

    • 如何理解sql注入?

        sql注入是一种将sql代码添加到输入参数中,传递到sql服务器解析并执行的一种攻击手法

        示例:

           本地一段代码为get获取id值,输出实际执行sql以及查询id对应内容。

           当id值传为1时,执行结果如下:

          

                            这是正常请求情况,而当我们往id传的参数中注入sql代码时,便可以根据自己需求查询自己想要获取的内容,例如:

           

                          id值传参数为  -1 OR 1=1 ,此时执行代码中id值带入了我们传参数的sql代码,  1=1 为真,OR 1=1便会查出表中所有的内容。            达到攻击目的。

                           所以sql注入攻击就是输入参数未经过滤,直接拼接到sql语句中,解析执行,达到预想之外的行为。

    • sql注入是如何产生的?

          1.web开发人员无法保证所有的输入都已经过滤

          2.攻击者利用发送给sql服务器的输入数据构造可执行代码

          3.数据库未作相应的安全配置(对web应用设置特定的数据库账号,而不使用root或管理员账号,特定数据库账号给予一些简单操作的权限,回收一些类似drop的操作权限)

    二.如何寻找SQL注入漏洞

    • 如何寻找sql注入漏洞?

       (借助逻辑推理)

       1.识别web应用中所有输入点

           web应用中的输入包含三点:get,post,http头信息

       2.了解哪些类型请求会触发异常

           <1>比如get信息请求,获取文章id返回文章内容,当在get传递的id参数值后加“"”双引号,请求结果就会出现数据库异常错误.

            

                          <2>post请求示例,提交文章标题和文章内容,添加入库,正常情况是:

                                    

                                   提交入库的sql如下:

                                   

                                   但是当我们把标题输入为   标题"  ,提交后便会触发sql异常:

                                   

       3.检测服务器响应中的异常

    三.如何进行SQL注入攻击 

       (这里介绍两种主要的sql注入攻击)

    • 数字注入

       sql中where条件的参数值为数字的语句进行修改攻击。

       也就是上面提到的  id = -1 OR 1=1

    • 字符串注入

       以一个用户登陆为例:

             

                                  

               <1.>以sql中的注释符号‘#’来实现攻击:

                          我们只需要知道数据库中的某一个用户的用户名,比如peter,在表单输入时,在用户名列输入  “peter'#”,密码随意输入,点击登陆后便会显示登陆成功,输出的sql语句为:

                                 

                                

                                如上,用户名拼接“ ‘# ”说明:( ’ 单引号用来闭合用户名的输入,#井号用来注释掉后面的查询条件)

              <2.>以注释符号‘ -- ’来实现攻击:

                               还是一样只需要知道数据库中的某一个用户的用户名,比如peter,在表单输入时,在用户名列输入  “peter'-- ” (双中横线后还有空格),密码随意输入,点击登陆后便会显示登陆成功,输出的sql语句为:

                               

                              

                                跟上面的#号攻击一样,sql语句执行都会跳过密码验证,在不需要知道密码的情况下就可以实现登陆。

     四.如何预防SQL注入(分三种方法讲解)

    • 严格检查输入变量的类型和格式

           1.对数字类型的参数id的强校验(empty()为空验证和is_numeric()进行数字验证)

                        

                    2.对字符串类型的参数的校验 (正则校验

           例如上面提到的登陆系统的用户名的校验,比如校验规则为 六位数字以上的字母或者数字,可以用preg_match("/^[a-zA-Z0-9]{6,}$/")

          

    • 过滤和转义特殊字符  

                            一.  用php函数addslashes()进行转义(addslashes函数使用方法详解点这里):

             一般是对这些特殊字符进行转义:         

               1.单引号(')   2.双引号(")  3.反斜杠() 4. NULL

                                    

                           二. 用mysqli的php扩展中的函数 mysqli_real_escape_string()

                                  

                           :这两种方法只做简单介绍用,但其实现在的黑客已经可以轻而易举的绕过这些函数,包括一些字符串替换 str_replace() 等,表着急,继续往下看,下面介绍的第三种防sql注入的方法还是比较实在,如果需要还是直接用下面的方法吧~

    • 利用预编译机制(mysqli 和 pdo)

       一. DML语句预编译(mysqli示例和pdo示例)

         使用mysqli需要开启扩展详细教程点我

          (使用pdo需要开启扩展详细教程点我)

        mysqli预编译示例                                             

       <?php
         
            $mysqli = new mysqli("localhost","root","root","dbname");
            $mysqli->query("set names utf8");
            $sql = 'insert into user(id,name,age,email) values (?,?,?,?)';
            $mysqli_stmt = $mysqli->prepare($sql);
         
         
            $id = 2;
            $name = 'kung';
            $age = 28;
            $email = 'ohdas@163.com';
            
            $mysqli_stmt->bind_param('isis',$id,$name,$age,$email);
         
            $res = $mysqli_stmt->execute();
         
            if(!$res){
                echo 'error'.$mysqli_stmt->error;
                exit;
            }else{
                echo 'ok';
            }
         
            $id = 3;
            $name = 'xiaoyu';
            $age = 28;
            $email = 'kung-yu@163.com';
         
            $mysqli_stmt->bind_param('isis',$id,$name,$age,$email);
            $res = $mysqli_stmt->execute();
         
            if(!$res){
                echo 'error'.$mysqli_stmt->error;
                exit;
            }else{
                echo 'ok';
            }
        ?>

         PDO预编译示例 

    <?php
        $dns = 'mysql:dbname=dbname;host=127.0.0.1';
        $user = 'root';
        $password = 'root';
    try{    
        $pdo = new PDO($dns,$user,$password);
    } catch(PDOException $e){
        echo $e->getMessage();
    }
        $pdo->query("set names utf8");
        
        $sql = 'inser into user values(:id,:name,:age,:email)';
        $pdo_stmt = $pdo->prepare($sql);
        
        $id = 2;
        $name = 'kung';
        $age = 27;
        $email = 'ohdas@163.com';
     
        $pdo_stmt->bindParam(':id',$id);
        $pdo_stmt->bindParam(':name',$name);
        $pdo_stmt->bindParam(':age',$age);
        $pdo_stmt->bindParam(':email',$email);
        $pdo_stmt->execute();
    ?>

              . DQL语句预编译(mysqli示例)

    <?php
        $mysqli = new mysqli("localhost","root","root","dbname");
        $mysqli->query("set names utf8");
        $sql = " select id,name from user where id > ?";
        $mysqli_stmt = $mysqli->prepare($sql);
        
        $id = 1;
        $mysqli_stmt->bind_param('i',$id);
        $mysqli_stmt->bind_result($id,$name);
        $mysqli_stmt->execute();
        
        while($mysqli_stmt->fetch()){
            echo $id.'--'.$name;
        }
     
        $mysqli_stmt->close();
        $mysqli->close();
    ?>

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    整篇文章内容是看慕课网视频写的笔记:   链接戳我

    最后预编译的代码示例摘自:  https://blog.csdn.net/kissxia/article/details/46623097

    作者:戈丫汝
    版权声明:本文为博主原创文章,转载请附上博文链接!

              

      

  • 相关阅读:
    C#中|(位或)和||(逻辑或)
    VS快捷键(转)
    C# 3.0 新特性 学习(二):匿名类型、扩展方法
    Highcharts 如何添加基准线
    怎样用Diskpart进行分区
    命名空间别名限定符 (::)
    NDK下 将Platinum SDK 编译成so库 (android upnp)
    在native线程利用JNI 反射自定义类
    GithubClient(ANDROID)开源之旅(一) 初探GitHub
    基于Platinum库的DMR实现(android)
  • 原文地址:https://www.cnblogs.com/gyrgyr/p/9876569.html
Copyright © 2011-2022 走看看