本文從使用瀏覽器與Web應用進行交互這一視角來討論發現SQL注入問題時所涉及的時間延遲技術。
測試應用程序是否存在SQL注入漏洞時,經常發現某一潛在的漏洞難以確認。這可能源於多種原因,但主要是因為Web應用未顯示任何錯誤,因而無法檢索任何數據。
對於這種情況,要想識別漏洞,可以向數據庫注入時間延遲,並檢查服務器的響應是否也已經產生了延遲。時間延遲是一種很強大的技術,Web服務器雖然可以隱藏錯誤或數據,但必須等待數據庫返回結果,因此可用它來確認是否存在SQL注入。該技術尤其適合盲注。
Microsoft SQL Server服務器包含一條向查詢引入延遲的內置命令:WAITFOR DELAY 'hours: minutes:seconds'。例如,向Victim公司的Web服務器發送下列請求,服務器的響應大概要花5秒:
http://www.victim.com/basket.aspx?uid=45;waitfor delay '0:0:5';--
服務器響應中的延遲使我們確信我們正在向后台數據庫注入SQL代碼。
MySQL數據庫沒有與WAITFOR DELAY等價的命令,但它可以使用執行時間很長的函數來引入延遲。BENCHMARK函數是很好的選擇。MySQL的BENCHMARK函數會將一個表達式執行許多次,它通常被用於評價MySQL執行表達式的速度。根據服務器工作負荷和計算資源的不同,數據庫需要的時間也會有所不同。但如果延遲比較明顯,也可使用該技術來識別漏洞。請看下面的例子:
mysql> SELECT BENCHMARK(10000000,ENCODE('hello','mom')); +----------------------------------------------+ | BENCHMARK(10000000,ENCODE('hello','mom')) | +----------------------------------------------+ | 0 | +----------------------------------------------+ 1 row in set (3.65 sec)
執行該查詢花費了3.65秒。如果將這段代碼注入SQL注入漏洞中,那么將延遲服務器的響應。如果想進一步延遲響應,只需增加迭代的次數即可,如下所示:
http://www.victim.com/display.php?id=32; SELECT BENCHMARK(10000000,ENCODE('hello','mom'));--
在Oracle PL/SQL中,可使用下列指令集創建延遲:
BEGIN
DBMS_LOCK.SLEEP(5);
END;
DBMS_LOCK.SLEEP()函數可以讓一個過程休眠很多秒,但使用該函數存在許多限制。首先,不能直接將該函數注入子查詢中,因為Oracle不支持堆疊查詢(stacked query)。其次,只有數據庫管理員才能使用DBMS_LOCK包。
在Oracle PL/SQL中有一種更好的辦法,可以使用下面的指令以內聯方式注入延遲:
http://www.victim.com/display.php?id=32 or 1=dbms_pipe.receive_
message('RDS', 10)
DBMS_PIPE.RECEIVE_MESSAGE函數將為從RDS管道返回的數據等待10秒。默認情況下,允許以public權限執行該包。DBMS_LOCK.SLEEP()與之相反,它是一個可以用在SQL語句中的函數。
在最新版本的PostgreSQL數據庫(8.2及以上版本)中,可以使用pg_sleep函數來引起延遲:
http://www.victim.com/display.php?id=32; SELECT pg_sleep(10);--