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

作者:戈丫汝
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!

 

          

 

 

 

 

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM