「網(wǎng)絡(luò)安全」web 漏洞入門之——SQL 注入教程
SQL 注入是最常見、最被人們熟知的 web 漏洞。根據(jù)百科的解釋:所謂SQL注入,就是通過把SQL命令,插入到Web表單提交或輸入域名或頁面請求的查詢字符串,最終達到欺騙服務(wù)器執(zhí)行惡意的SQL命令。

比如某個公司有一個員工管理系統(tǒng),里面存儲員工的許多信息,每個員工只要輸入自己的工號就可查詢自己相關(guān)信息。張三是這個公司的一個開發(fā)人員,他突發(fā)好奇的想輸入李四的工號10001是否可以成功查詢,結(jié)果他失敗了,因為系統(tǒng)有工號和身份的互相校驗。于是他在工號后面加上了一個' OR 'a'='a,沒想到成功返回了數(shù)據(jù),他成功獲取到了他人的許多敏感信息。
這就是 SQL 注入攻擊的典型場景,由于程序員在開發(fā)數(shù)據(jù)庫中,沒有對用戶輸入數(shù)據(jù)進行校驗、轉(zhuǎn)義、限制等處理,導(dǎo)致攻擊者可以通過輸入惡意字符串去獲取數(shù)據(jù)庫中的數(shù)據(jù)。先前的很多影視網(wǎng)站的 VIP 會員密碼就是通過類似的方式泄漏的。
今天我們測試對一個有 SQL 注入漏洞的網(wǎng)站進行攻擊。因為類似的滲透測試過程在沒有經(jīng)過對方允許的情況下,是屬于違法的!所以我們?yōu)榇蠹覝蕚淞藢嶒灜h(huán)境和靶機,你可以拿它當小白鼠,點擊閱讀原文即可體驗。
SQL?注入攻擊步驟
通常來說,SQL 注入攻擊可以分為以下 5 個步驟:

尋找注入點:指找到存在 SQL 注入的參數(shù),SQL 注入大多發(fā)生在 GET 或 POST 請求的參數(shù)中,當然也有可能發(fā)生在其他地方,例如 UserAgent、Cookie 等
判斷注入類型 / 數(shù)據(jù)庫類型:SQL 注入按照不同的分類標準,可以分成不同的種類。
按照參數(shù)類型可分為兩種:數(shù)字型和字符型。
根據(jù)數(shù)據(jù)庫返回的結(jié)果,可分為回顯注入、報錯注入、盲注。
按照注入方法,還可以分為聯(lián)合注入、堆疊注入、寬字節(jié)注入、延時注入等。
猜解數(shù)據(jù)庫名:猜解后臺數(shù)據(jù)庫的庫名
猜解數(shù)據(jù)表名:成功猜解到數(shù)據(jù)庫名稱后,進一步猜解某一個特定數(shù)據(jù)庫中數(shù)據(jù)表的名稱
猜解數(shù)據(jù)字段名:最后是某個特定數(shù)據(jù)庫中特定數(shù)據(jù)表中的字段,因為獲取到字段才能查詢數(shù)據(jù)
使用SQL?注入進行爆庫?
我們先通過一個實驗,讓你更加清楚的理解 SQL 注入攻擊的全過程,然后再針對「如何尋找注入點」和「如何判斷注入類型」這兩部分做詳細的講解。
首先,在終端中執(zhí)行如下命令快速部署實驗環(huán)境:


然后打開桌面上的 Firefox 瀏覽器,訪問以下網(wǎng)址 :


點擊?create/Reset Database
?創(chuàng)建數(shù)據(jù)庫:


稍微等待幾秒后,會自動跳轉(zhuǎn)到登錄界面,默認用戶名為?admin
?密碼為?password
。

為了讓我們更容易理解 SQL 注入的原理,所以先手動將 Security 級別調(diào)整為?low
,注意需要點擊?Submit
?使設(shè)置生效:

第一步:尋找注入點
點擊左側(cè)的?SQL injection
?頁面開始注入:

先輸入 1 ,查看回顯 (URL 中 ID=1,說明 php 頁面通過 get 方法傳遞參數(shù)):

那實際上后臺執(zhí)行了什么樣的 SQL 語句呢?點擊?view source
?查看源代碼:


可以看到,實際執(zhí)行的 SQL 語句是:

在參數(shù)?id
?后面加一個單引號試試:

可以看到,返回了數(shù)據(jù)庫報錯信息,說明此處存在 SQL 注入漏洞。
至于為什么能判斷存在 SQL 注入,后文會細講。
第二步:確定注入類型
我們使用最簡單的「聯(lián)合查詢注入」來進行演示。聯(lián)合查詢的語法如下:

union 運算符可以將兩個或兩個以上 select 語句的查詢結(jié)果集合合并成一個結(jié)果集合顯示,即執(zhí)行聯(lián)合查詢。但當使用 union select 的時候,需要保證前后查詢的列數(shù)相同,例如:

Union 前半部分查詢了 A、B 兩個字段,Union 后半部分也只能查詢 C、D 兩個字段,否則就會報錯。但現(xiàn)在有一個問題:我們還不知道 Union 的前半部分查詢的字段數(shù)是多少?這個時候就需要用到?order by
?來查詢字段數(shù)了。在輸入框中輸入?1' order by 1#
,實際執(zhí)行的 SQL 語句就會變成:

這條語句的意思是查詢 users 表中 user_id 為 1 的數(shù)據(jù)并按第一字段排行。輸入?1' order by 1#
?和?1' order by 2#
?時都返回正常:


當輸入?1' order by 3#
?時,返回錯誤:
由此可知,users 表中只有兩個字段,數(shù)據(jù)為兩列。知道字段數(shù)為 2 之后,接下來就可以使用?union select
?聯(lián)合查詢繼續(xù)獲取信息。輸入以下進行查詢:

version()
?獲取當前數(shù)據(jù)庫版本.@@version_compile_os
?獲取當前操作系統(tǒng)。
實際執(zhí)行的 SQL 語句是:


通過上圖返回信息,我們又成功獲取到:
當前數(shù)據(jù)庫版本為 :?
10.5.8-MariaDB-1:10.5.8+maria~focal
當前操作系統(tǒng)為 :?
debian-linux-gnu
第三步:查詢數(shù)據(jù)庫名
查詢數(shù)據(jù)庫名的方法非常簡單,只需要執(zhí)行以下語句進行查詢即可 :

database()
?將會返回當前網(wǎng)站所使用的數(shù)據(jù)庫名字.user()
?將會返回執(zhí)行當前查詢的用戶名.
實際執(zhí)行的 SQL 語句是 :


通過上圖返回信息,我們成功獲取到:
當前網(wǎng)站使用數(shù)據(jù)庫為?
dvwa
當前執(zhí)行查詢用戶名為?
root@localhost
第四步:查詢數(shù)據(jù)庫表名
接下來我們嘗試獲取 dvwa 數(shù)據(jù)庫中的表名。information_schema
?是 mySQL 自帶的一張表,這張數(shù)據(jù)表保存了 MySQL 服務(wù)器所有數(shù)據(jù)庫的信息,如數(shù)據(jù)庫名,數(shù)據(jù)庫的表,表欄的數(shù)據(jù)類型與訪問權(quán)限等。該數(shù)據(jù)庫擁有一個名為 tables 的數(shù)據(jù)表,該表包含兩個字段 table_name 和 table_schema,分別記錄 DBMS 中的存儲的表名和表名所在的數(shù)據(jù)庫。
我們輸入以下語句進行查詢:

實際執(zhí)行的 SQL 語句是:


dvwa 數(shù)據(jù)庫有 2 個數(shù)據(jù)表
表名為 guestbook 和 users
第五步:猜解數(shù)據(jù)庫字段名及爆庫
接下來我們繼續(xù)猜解數(shù)據(jù)庫表中的字段名,因為需要知道字段名,才能查詢數(shù)據(jù)庫中存儲的數(shù)據(jù)。我們輸入以下語句查詢 users 表中的字段信息:


從輸出結(jié)果可知,users 表中有 8 個字段,分別是 user_id,first_name,last_name,user,password,avatar,last_login,failed_login。直接告訴我們,這些字段中最敏感的是?user,password?這兩個字段,所以輸入:1' union select user,password from users#
進行查詢。實際執(zhí)行的 SQL 語句是:


可以看到成功爆出用戶名、密碼,密碼采用 md5 進行加密,可以到?https://www.cmd5.com/
?查詢解密:

總結(jié)
通過實戰(zhàn)的演練,相信大家已經(jīng)理解了通過 SQL 注入來爆破數(shù)據(jù)庫的方法和流程,最后我們再梳理一下比較重要的知識點:
SQL 注入產(chǎn)生的原因
SQL 注入攻擊的分類
SQL 注入爆庫攻擊的 5 個步驟
