安華金和全面適配國產(chǎn)化操作系統(tǒng)及芯片CPU
數(shù)據(jù)安全治理關(guān)鍵技術(shù)之數(shù)據(jù)庫脫敏技術(shù)詳解
數(shù)據(jù)安全治理之API監(jiān)測系統(tǒng) ,解決API接口安全問題【安華金和】
新一代數(shù)據(jù)庫脫敏技術(shù),為敏感數(shù)據(jù)建立保護盾!
數(shù)據(jù)庫脫敏系統(tǒng)與金融行業(yè)案例解讀
數(shù)據(jù)安全治理建設(shè)思路的著力點——數(shù)據(jù)安全咨詢服務【安華金和】
數(shù)據(jù)庫防火墻功能有哪些?-數(shù)據(jù)安全-安華金和
數(shù)據(jù)安全關(guān)鍵技術(shù)之數(shù)據(jù)庫脫敏技術(shù)詳解【安華金和】
數(shù)據(jù)庫攻擊的目的最終是為要獲取數(shù)據(jù)庫中有價值的數(shù)據(jù),而獲取數(shù)據(jù)最有效的方法就是直接獲取DBA權(quán)限。本文通過Oracle數(shù)據(jù)庫中的一個經(jīng)典漏洞,演示從普通用戶提權(quán)到DBA權(quán)限的過程,DBSec Labs數(shù)據(jù)庫安全實驗室給出針對性的防護建議。
CTXSYS.driload.validate_stmt是一個Oracle的經(jīng)典漏洞。出現(xiàn)在Oracle9i中,從10g開始被修復。這個漏 洞是直接注入形漏洞的代表。漏洞發(fā)生在CTXSYS創(chuàng)建的driload包中的存儲過程validate_stmt中。首先我們通過解壓的方式打開 validate_stmt觀察源碼。
validate_stmt結(jié)構(gòu)如下:
CREATE OR REPLACE PACKAGE BODY DRILOAD IS
PROCEDURE VALIDATE_STMT( SQLSTMT IN VARCHAR2 )
IS
…
…
BEGIN
SRC := DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.PARSE( SRC, SQLSTMT, DBMS_SQL.NATIVE );
RET := DBMS_SQL.EXECUTE_AND_FETCH( SRC );
DBMS_SQL.CLOSE_CURSOR( SRC );
…
…
END VALIDATE_STMT;
在源碼中可以直觀的看到存儲過程中主要使用了DBMS_SQL包中的各種存儲過程和函數(shù)。這說明validate_stmt的漏洞主要是DBMS_SQL的漏洞。
既然問題出在DBMS_SQL上,那么我們就有必要對它的功能和使用場景有一個初步的了解。DBMS_SQL主要被用來解決需要動態(tài)處理數(shù)據(jù)或表結(jié) 構(gòu)的問題。比如對一批表里的數(shù)據(jù)進行處理,或者批量創(chuàng)建表,索引,觸發(fā)器等等,這時就可以通過DBMS_SQL包進行操作。下圖來自O(shè)racle官方揭示 了DBMS_SQL運行時的整體邏輯。
通過對DBMS_SQL包中的存儲過程和函數(shù)的分析得出結(jié)論,在函數(shù)中可以被注入超長參數(shù)的只有DBMS_SQL.PARSE。
在此函數(shù)中的參數(shù)STATEMENT應該是注入的突破點,這是因為此參數(shù)中的VARCHAR2類型可以容納較長的字符串,這使在字符串中嵌入提權(quán)命令成為可能。
筆者構(gòu)造提權(quán)語句如下:
SYS.DBMS_SQL.PARSE( SRC, 'GRANT DBA TO PUBLIC', DBMS_SQL.NATIVE
構(gòu)造出提權(quán)語句,想要通過SYS.DBMS_SQL.PARSE去執(zhí)行,還需要按照DBMS_SQL處理DLL的要求構(gòu)造入侵函數(shù)塊,示例如下:
DECLARE
SRC NUMBER;
RET NUMBER;
BEGIN
SRC := DBMS_SQL.OPEN_CURSOR;
SYS.DBMS_SQL.PARSE( SRC, 'GRANT DBA TO PUBLIC', DBMS_SQL.NATIVE );
RET := DBMS_SQL.EXECUTE_AND_FETCH( SRC );
DBMS_SQL.CLOSE_CURSOR( SRC );
END;
實際攻擊效果如下:
提權(quán)語句的SQL塊在低權(quán)限用戶上執(zhí)行,提權(quán)顯示失敗。究其原因,因為Oracle特別設(shè)置DBMS_SQL.PARSE為AUTHID CURRENT_USER(調(diào)用者權(quán)限)。調(diào)用者權(quán)限決定DBMS_SQL.PARSE在執(zhí)行之前會判斷當前執(zhí)行它的用戶是否具有調(diào)用他的權(quán)限(DBA權(quán) 限)。
但是這里Oracle只是單純的降低了CTXSYS的權(quán)限,并未對DBMS_SQL.PARSE做有效的防護處理。雖然 DBMS_SQL.PARSE被調(diào)用者權(quán)限保護,不能被直接注入。但如果某個DBA賬號建立一個定義者權(quán)限的存儲過程或是函數(shù)(暫且叫這個存儲過程為A) 中調(diào)用了DBMS_SQL.PARSE。并且把A的執(zhí)行權(quán)限賦予PUBLIC。那么低權(quán)限用戶則有機會通過A去調(diào)用DBMS_SQL.PARSE。
以下測試在Oracle 11.2上進行
首先檢查DBA用戶數(shù)量,為最后作為對照組用
在DBA賬號SYS下建立存儲過程A,A中間調(diào)用了DBMS_SQL.PARSE,并把存儲過程A的執(zhí)行權(quán)限賦予PUBLIC。使所有用戶都可以執(zhí)行A。
切到低權(quán)限SCOTT上執(zhí)行SYS.A并把參數(shù)改為提權(quán)語句GRANT DBA TO PUBLIC。
雖然程序報錯但其實已經(jīng)執(zhí)行了提權(quán)命令。切回SYS用戶再次查詢DBA用戶,發(fā)現(xiàn)多了一個DBA用戶PUBLIC。PUBLIC正式通過GRANT DBA TO PUBLIC這個命令獲得提權(quán)的。
至此提權(quán)到DBA成功。
以上Oracle調(diào)用者權(quán)限利用DBMS_SQL漏洞進行DBA提權(quán)的過程中存在四個關(guān)鍵點:
1. DBA用戶創(chuàng)建定義者權(quán)限的函數(shù)或存儲過程。(定義者權(quán)限可使任意用戶可以在調(diào)用函數(shù)或存儲過程的運行時中獲得DBA權(quán)限。)例子中的存儲過程A就是定義 者權(quán)限。低權(quán)限用戶SCOTT在調(diào)用A的運行時中具備了A的創(chuàng)建者SYS具有的DBA權(quán)限。致使DBMS_SQL的調(diào)用者權(quán)限保護機制失效。
2. DBA賬號創(chuàng)建的函數(shù)或存儲過程把執(zhí)行權(quán)限賦予PUBLIC。如果A的執(zhí)行權(quán)限不是PUBLIC,scott根本無法調(diào)用A,也不會出現(xiàn)后面的利用方式。
3. 對輸入?yún)?shù)的限制和防守沒有加強,使得某些非預計參數(shù)的執(zhí)行。
4. 未對用戶身份進行判斷。加強對用戶身份的識別可以在一定程度防止低權(quán)限用戶進行非法提權(quán)操作。
針對數(shù)據(jù)庫漏洞的防護要做到以下幾點:
1.自己不制造漏洞,使用安全性更高的函數(shù)或存儲過程??梢允褂肈BMS_SYS_SQL代替DBMS_SQL。
筆者在實踐中發(fā)現(xiàn)DBMS_SYS_SQL.PARSE_AS_USER這個存儲過程可以代替DBMS_SQL.PARSE這個危險的存儲過程。分
析調(diào)用關(guān)系不難發(fā)現(xiàn)DBMS_SQL.PARSE和DBMS_SYS_SQL.PARSE_AS_USER其實調(diào)用的都是DBMS_SYS_SQL中的
ICD_PARSE。但不同的是調(diào)用的ICD_PARSE有一位參數(shù)不同。
DBMS_SQL.PARSE調(diào)用的是:
ICD_PARSE( C, STATEMENT, LANGUAGE_FLAG MOD PARSE_AS_USER_FLAG, NULL );
而DBMS_SYS_SQL.PARSE_AS_USER調(diào)用的是:
ICD_PARSE( C, STATEMENT, LANGUAGE_FLAG MOD PARSE_AS_USER_FLAG + PARSE_AS_USER_FLAG, USERID );
仔細比較兩者不難發(fā)現(xiàn)最后一位參數(shù)USERID不同。DBMS_SQL.PARSE對應的取的是null,而 DBMS_SYS_SQL.PARSE_AS_USER對應的取的是當前用戶的USERID。通過USERID來判斷當前用戶的權(quán)限是否能解析語句,而并 非是運行時權(quán)限來判斷是否能解析語句。
對比說明,存儲過程Q采用DBMS_SYS_SQL.PARSE_AS_USER,存儲過程P則采用DBMS_SQL.PARSE。存儲過程P和Q 唯一的區(qū)別就是分別采用DBMS_SYS_SQL.PARSE_AS_USER和DBMS_SQL.PARSE來解析SQL語句。
存儲過程P成功實現(xiàn)了DBA提前操作。存儲過程Q采用了DBMS_SYS_SQL.PARSE_AS_USER,成功阻止了低權(quán)限用戶的提權(quán)操作。
2、使用第三方的數(shù)據(jù)庫安全加固產(chǎn)品及解決方案
應對已知數(shù)據(jù)庫安全問題最佳方案是升級數(shù)據(jù)庫,但升級數(shù)據(jù)庫存在很多風險和復雜的準備工作。即便做了升級測試、最小化測試、功能測試、集成測試、性能測試、容量與負載壓力測試等一系列復雜的測試依舊可能導致某些應用或組件出現(xiàn)各種難以預計的問題。
在不對數(shù)據(jù)庫本身進行升級操作的情況下,可以通過虛擬補?。╒patch)技術(shù)來完成對數(shù)據(jù)庫系統(tǒng)漏洞的防護。數(shù)據(jù)庫虛擬補丁技術(shù)一般是集成在數(shù)據(jù) 庫防火墻產(chǎn)品中,能夠有效防止通過數(shù)據(jù)庫本身漏洞對數(shù)據(jù)庫的攻擊行為。有效的解決了生產(chǎn)場景下數(shù)據(jù)庫升級不及時可能給用戶的數(shù)據(jù)庫帶來的潛在威脅。并在無 需對數(shù)據(jù)庫做深度操作的前提下,進行漏洞的修補與防護,以期達到數(shù)據(jù)庫的安全標準要求。