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