【滲透攻防WEB篇】SQL注入攻擊初級

前言
無論用什麼語言編寫的Web應用,它們都用一個共同點,具備交互性而且多數是數據庫驅動。在網絡中,數據庫驅動的Web應用隨處可見,由此而存在的SQL注入是影響企業運營且最具破壞性的漏洞之一,這裏我想問,咱們真的瞭解SQL注入嗎?看完本篇文章但願能讓你更加深入的認識SQL注入。php


目錄html

第一節 注入攻擊原理及本身編寫注入點
mysql

  • 1.一、什麼是SQL?
  • 1.二、什麼是SQL注入?
  • 1.三、SQL注入是怎麼樣產生的?
  • 1.四、編寫注入點


第二節 尋找及確認SQL注入
sql

    • 2.一、推理測試法
    • 2.二、and大法和or大法
    • 2.三、加法和減法

 

正文
數據庫

  • 第一節 注入攻擊原理及本身編寫注入點


1.一、什麼是SQL?
SQL 是一門 ANSI 的標準計算機語言,用來訪問和操做數據庫系統。SQL 語句用於取回和更新數據庫中的數據。SQL 可與數據庫程序協同工做,好比 MS Access、DB二、Informix、MS SQL Server、Oracle、Sybase 以及其餘數據庫系統。

1.二、什麼是SQL注入?
看起來很複雜,其實很簡單就能解釋,SQL注入就是一種經過操做輸入來修改後臺SQL語句達到代碼執行進行攻擊目的的技術。

1.三、SQL注入是怎麼樣產生的?

構造動態字符串是一種編程技術,它容許開發人員在運行過程當中動態構造SQL語句。開發人員可使用動態SQL來建立通用、靈活的應用。動態SQL語句是在執行過程當中構造的,它根據不一樣的條件產生不一樣的SQL語句。當開發人員在運行過程當中須要根據不一樣的查詢標準來決定提取什麼字段(如SELECT語句),或者根據不一樣的條件來選擇不一樣的查詢表時,動態構造SQL語句會很是有用。

在PHP中動態構造SQL語句字符串:
編程

 

$query = "SELECT * FROM users WHERE username = ".$_GET["ichunqiu"];

 

看上面代碼咱們能夠控制輸入參數ichunqiu,修改所要執行SQL語句,達到攻擊的目的。數組

 

1.四、編寫注入點
爲了照顧一下新人,這裏先介紹一下涉及到的基礎知識:服務器

 

SQL SELECT 語法
SELECT 列名稱 FROM 表名稱
符號 * 取代列的名稱是選取全部列
WHERE 子句
如需有條件地從表中選取數據,可將 WHERE 子句添加到 SELECT 語句。
語法
SELECT 列名稱 FROM 表名稱 WHERE 列 運算符 值

下面的運算符可在 WHERE 子句中使用:網絡

瞭解了以上基礎知識就讓咱們來本身編寫注入點把。函數


第一步:咱們使用if語句來先判斷一下變量是否初始化

 

<?php
if(isset($_GET["ichunqiu"])){
     
}
?>

 

 

第二步:在if語句裏面,咱們鏈接數據庫。在PHP中,這個任務經過 mysql_connect() 函數完成。

mysql_connect(servername,username,password);
servername        可選。規定要鏈接的服務器。默認是 "localhost:3306"。
username        可選。規定登陸所使用的用戶名。默認值是擁有服務器進程的用戶的名稱。
password        可選。規定登陸所用的密碼。默認是 ""。

 

第三步:鏈接成功後,咱們須要選擇一個數據庫。

mysql_select_db(database,connection)
database        必需。規定要選擇的數據庫。
connection        可選。規定 MySQL 鏈接。若是未指定,則使用上一個鏈接。

 

第四步:選擇完數據庫,咱們須要執行一條 MySQL 查詢。

mysql_query(query,connection)
query        必需。規定要發送的 SQL 查詢。註釋:查詢字符串不該以分號結束。
connection        可選。規定 SQL 鏈接標識符。若是未規定,則使用上一個打開的鏈接。

 

第五步:執行完查詢,咱們再對結果進行處理

mysql_fetch_array(data,array_type)
data        可選。規定要使用的數據指針。該數據指針是 mysql_query() 函數產生的結果。
array_type        
可選。規定返回哪一種結果。可能的值:
MYSQL_ASSOC - 關聯數組
MYSQL_NUM - 數字數組
MYSQL_BOTH - 默認。同時產生關聯和數字數組

 

題外話:咱們使用echo將執行的SQL語句輸出,方便咱們查看後臺執行了什麼語句。

echo $querry

 

最終代碼以下:

if(isset($_GET["id"])){
    $con = mysql_connect("127.0.0.1:3306","root","root");
    if (!$con)
    {
        die('Could not connect: ' . mysql_error());
    }
    mysql_select_db("ichunqiu",$con);
    $querry = "select * from users where id = " . $_GET['id'];
    $sql = mysql_query($querry,$con);
    $result = mysql_fetch_array($sql);
 
    echo "<table class='itable' border='1' cellspacing='0' width='300px' height='150'>";
    echo "<tr>";
    echo "<td>id</td>";
    echo "<td>username</td>";
    echo "</tr>";
 
    echo "<tr>";
    echo "<td>".$result['id']."</td>";
    echo "<td>".$result['username']."</td>";
    echo "</tr>";
    echo "</table>";
    mysql_close($con);
    echo $querry;
}
?>

 

MySQL數據庫實驗環境配置:
代碼層工做已經作好,可是在數據庫裏面,咱們尚未ichunqiu這個數據庫啊,接下來我就帶你們一步步建立數據庫,建立表,建立列,插入數據。

 

第一步:建立數據庫

 
 
第二步:建立表users和列id,username,password
 
 
第三步:咱們插入幾條數據
 
 
一樣的道理,你們多插幾條數據。到此咱們整個任務就完成了。

 

  • 第二節 尋找及確認SQL注入


2.一、推理測試法
尋找SQL注入漏洞有一種很簡單的方法,就是經過發送特殊的數據來觸發異常。


首先咱們須要瞭解數據是經過什麼方式進行輸入,這裏我總結了三個:

  • GET請求:該請求在URL中發送參數。
  • POST請求:數據被包含在請求體中。
  • 其餘注入型數據:HTTP請求的其餘內容也可能會觸發SQL注入漏洞。


瞭解完數據的輸入方式,咱們接下來再學習數據庫錯誤。這裏咱們以MySQL爲例,其它的請你們自行學習咯。
咱們如今參數後面加個單引號,以下圖:

 

 

sql語句最終變爲

select * from users where id = 1'

 

執行失敗,因此mysql_query()函數會返回一個布爾值,在下行代碼中mysql_fetch_array($sql)將執行失敗,而且PHP會顯示一條警告信息,告訴咱們mysql_fetch_array()的第一個參數必須是個資源,而代碼在實際運行中,給出的參數值倒是一個布爾值。
咱們修改代碼在

 

$sql = mysql_query($querry,$con);下一行加上
var_dump($sql);

 

 

能夠發現:

爲了更好的瞭解MySQL錯誤,咱們在

$sql = mysql_query($querry,$con);

加上

if(!$sql)
    {
        die('<p>error:'.mysql_error().'</p>');
    }

這樣當應用捕獲到數據庫錯誤且SQL查詢失敗時,就會返回錯誤信息:(咱們在參數中添加單引號返回的錯誤信息)

error:You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''' at line 1

而後藉助這些錯誤,咱們這能夠推斷應該存在SQL注入。還有其餘數據庫錯誤信息,以及MySQL其餘錯誤信息,因爲篇幅問題就不一一講解了。



2.二、and大法和or大法
頁面不返回任何錯誤信息,咱們就能夠藉助本方法來推斷了,首先咱們在參數後面加上 and 1=1和and 1=2看看有什麼不一樣

 

能夠發現and 1=1 返回了數據,而and 1=2沒有,這是因爲1=1是一個爲真的條件,前面的結果是true,true and true 因此沒有任何問題,第二個 1=2 是個假條件, true and false仍是false,因此並無數據返回。


好,講完and,咱們自來看看 or ,or就是或者,兩個都爲假,纔會爲假。咱們先把id改成5,能夠發現id=5是沒有數據的。

能夠發現咱們加上or 1=1就成功返回了數據,這是由於1=1爲真,無論前面是否是假,數據都會返回,這樣就把表裏面數據所有返回,咱們沒看見,是由於代碼中並無迭代輸出。這樣,咱們來修改一下代碼。

 

echo "<table class='itable' border='1' cellspacing='0' width='300px' height='150'>";
        echo "<tr>";
        echo "<td>id</td>";
        echo "<td>username</td>";
        echo "</tr>";
        //遍歷查詢結果
        while ($result = mysql_fetch_array($sql)) {
        echo "<tr>";
        echo "<td>" . $result[0] . "</td>";
        echo "<td>" . $result[1] . "</td>";
        echo "</tr>";
    }

 

而後你就能夠發現:

 

2.三、加法和減法
這裏咱們須要區分一下數字型和字符串型:

  • 數字型:不須要使用單引號來表示
  • 其餘類型:使用單引號來表示

綜合上述,咱們能夠發現咱們的例子是數字型的,這樣咱們就可使用加法和減法來判斷了。


加法,咱們在參數輸入1+1,看看返回的數據是否是id等於2的結果,這裏注意一下+號在SQL語句是有特效含義的,因此咱們要對其進行url編碼,最後也就是%2b。

 

 

減法是一樣的道理,不過咱們不須要對-號進行url編碼了。

結束語
感謝你們的支持吧,在此我也總結一下前面本身的不足,因爲篇幅很長,寬度是到位了,可是並無深刻,也不算詳細,因此本篇教程分爲了三級即初級、中級、高級。六節來寫,既要深度也要寬度,固然我也不是技術大牛,如文中有錯誤請指出,我會加以改正,謝謝。

 

文章首鏈:http://bbs.ichunqiu.com/thread-9518-1-1.html


感謝您的閱讀,若是您學到了,請點贊(碼字不易)!


歡迎熱心園友補充!

做者:zusheng


系列文章預告及導航

滲透攻防Web篇-SQL注入攻擊中級(狀態:更新中)

  • 第三節 利用SQL注入
  • 第四節 SQL盲注利用


滲透攻防Web篇-SQL注入攻擊高級(狀態:更新中)

    • 第五節 避開過濾方法總結
    • 第六節 探討SQL注入防護技巧
相關文章
相關標籤/搜索