前言:
首先是DVWA環境的搭建:
1.DVWA。
2.PHPSTUDY/WampServer,這里有一個坑,因為他是一體化的,PHP版本必須在5.4以上,否則顯注不能打開。或者自己搭建LAMP環境。
3.抓包軟件BURP以及代理的設置。
具體的步驟可參考:https://www.jb51.net/article/160378.htm
本篇主要記錄DVWA中SQL注入中的顯注部分:
開始之前先了解數字型、字符型和搜索型注入的區別:https://blog.csdn.net/change518/article/details/8116920/或者https://www.cnblogs.com/zztac/p/11355622.html
主要是數字型和字符型的區別:查詢語句中我們輸入的信息被單引號包含起來導致成為一個整體字符串,所以查詢語句會查詢一個為“1 and 1=1”和 “1 and 1=2”的id,這個id當然不會存在了就導致出現錯誤。所以針對字符型注入我們需要對單引號進行匹配,就產生了“' and '1'='1”和“'and '1'='2”這樣的閉合字符型注入的判斷語句。我們輸入這樣的判斷語句就會發現跟數字型注入一樣的返回。
SQL注入常規思路:
1、尋找注入點,可以通過 web 掃描工具實現 2、通過注入點,嘗試獲得關於連接數據庫用戶名、數據庫名稱、連接數據庫用戶權限、操作系統信息、數據庫版本等相關信息。 3、猜解關鍵數據庫表及其重要字段與內容(常見如存放管理員賬戶的表名、字段名等信息) 4、可以通過獲得的用戶信息,尋找后台登錄。 5、利用后台或了解的進一步信息,上傳 webshell 或向數據庫寫入一句話木馬,以進一步提權,直到拿到服務器權限。
手工注入常規思路:
1.判斷是否存在注入,注入是字符型還是數字型
2.猜解 SQL 查詢語句中的字段數 3.確定顯示的字段順序 4.獲取當前數據庫 5.獲取數據庫中的表 6.獲取表中的字段名 7.查詢到賬戶的數據
低級:
網頁源碼:
分析:
由代碼可知,通過REQUEST
方式接受傳遞的參數id,再通過sql語句帶入查詢,並未設置任何過濾,因此可以進行sql注入利用。
常見的測試POC:

幾個常用的函數:
user()返回當前數據庫連接使用的用戶;
database()返回當前數據庫連接使用的數據庫;
version()返回當前數據庫的版本;
1.判斷是否存在注入,注入是字符型還是數字型
當輸入的參數為字符串時,稱為字符型。字符型和數字型最大的一個區別在於,數字型不需要單引號來閉合,而字符串一般需要通過單引號來閉合的。
輸入1,查詢成功:
輸入:1 and 1=1,成功:
輸入:1 and 1=2,成功,可以知道並不是數字型的注入:
輸入:1' and '1'='1 成功:
輸入:1' and '1'='2,失敗,沒有查出東西,說明是字符型的注入:
2.猜解SQL查詢語句中的字段數
輸入1′ order by 2 #,查詢成功:(注意此處的語句,#是注釋后面的單引號,前面的’是閉合SQL的“,一定要記住ORDERBY 后加數字不是字符 )
輸入1′ order by 3 #,查詢失敗:
說明執行SQL查詢的只有兩個字段,就是這里的First name、Surname。
3.確定顯示的字段順序。
輸入1′ union select 1,2 #,查詢成功: #是注釋作用,union是聯合查詢
說明執行的SQL語句為select First name,Surname from 表 where ID=’id’…
4.獲取當前的數據庫

數據庫是DVWA。
5.獲取數據庫中的表
輸入:1' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database() #,查詢成功:
說明數據庫中,有兩個表:guestbook與users。

users表中一個有8個字段,其中包括,user_id,first_name,password。
7.得到數據
輸入:1' union select group_concat(user_id,first_name),group_concat(password) from users #,查詢成功:
可以看到查詢1的內容是id和用戶名,查詢2的內容是password,注意,此處是密文,需要MD5轉換(百度即可):
這樣,我們就拿到了低級手工注入的所有用戶名和密碼。
中級:

Medium級別的代碼利用mysql_real_escape_string函數對特殊符號\x00,\n,\r,,’,”,\x1a進行轉義,同時前端頁面設置了下拉選擇表單,希望以此來控制用戶的輸入。雖然前端使用了下拉選擇菜單,但我們依然可以通過抓包改參數,提交惡意構造的查詢參數。所以就用到了抓包軟件BURPLOADER以及服務器的代理設置。
1.判斷是否存在注入,以及注入的類型。
抓包更改參數為1‘and1=1#報錯:
抓包更改參數為1and1=1 查詢成功:
所以是數字型注入,由於是數字型注入,服務器端的mysql_real_escape_string函數就形同虛設了,因為數字型注入並不需要借助引號。

抓包修改為id=1 order by 3,查詢失敗::
說明執行的SQL查詢語句中只有兩個字段,即這里的First name、Surname。
3.確定顯示字段的順序:
抓包更改參數:1 union select 1,2 查詢成功
4.獲取當前的數據庫名:
抓包修改:id =1 union select 1,database(),查詢成功:
數據庫名為dvwa
5.獲取數據庫當中的表:
抓包修改:id=1 union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()
數據庫中一共存在兩個表,guest和users
6.獲取表中的字段名
抓包修改:id=1 union select 1,group_concat(column_name) from information_schema.columns where table_name='users’,查詢失敗
這是因為‘在這里被轉義成了\',我們可以用16進制繞過:
這樣就得到了字段名。
7.得到數據
抓包修改數據:
同樣,也得到了用戶名和密碼。
高級:
查看源碼
與Medium級別的代碼相比,High級別的只是在SQL查詢語句中添加了LIMIT 1,希望以此控制只輸出一個結果。
雖然添加了LIMIT 1,但是我們可以通過#將其注釋掉。且因為是字符型注入,手工注入的過程與Low級別基本一樣,直接最后一步演示得到數據。