使用盗版/破解版的 PL/SQL 工具存在对数据库注入病毒的风险

推荐大家使用官方提供的免费版本的客户端工具,如 SQL developer :​​http://www.oracle.com/technetwork/developer-tools/sql-developer/downloads/index.html​​​。或开源免费的数据库客户端工具,如 DBeaver 社区版 :​​https://github.com/dbeaver/dbeaver/releases​​

当前是否被注入病毒排查方式如下:

1、检查是否有结果

select OWNER, TRIGGER_NAME, TRIGGER_TYPE, TRIGGERING_EVENT from dba_triggers
where TRIGGER_NAME like '%DBMONITOR%';

2、检查 $ORACLE_HOME/rdbms/admin/prvtsupp.plb 里是否有 create or replace procedure DBMS_SUPPORT_DBMONITORP 的代码

3.检查

select 'DROP TRIGGER '||owner||'."'||TRIGGER_NAME||'";' from dba_triggers 
where TRIGGER_NAME like 'DBMS_%_INTERNAL% '
union all
select 'DROP PROCEDURE '||owner||'."'||a.object_name||'";' from dba_procedures a
where a.object_name like 'DBMS_%_INTERNAL% ';

背景介绍

最近有部分黑客采用各种手段对数据库进行 sql 注入或者直接加密等损坏方式攻击客户的数据库。需要说明的是这里并非黑客用多么高深的手段或者技能攻破 Oracle 数据库或者由于 Oracle Bug 引起的,Oracle 被无辜躺枪。相反,这类攻击完全是使用盗版客户端工具或者客户网络(或者主机)安全有漏洞,入侵主机或者直接使用盗版客户端(部分网上下载的非官方工具已经是被黑客篡改过的)对数据库登录时进行 SQL 注入的方法。

故障描述

于定期巡检期间发现数据库alert日志中有如下错误:

Errors in file /home/oracle/diag/rdbms/ora11/ora11/trace/ora11_ora_181625.trc:
ORA-00604: error occurred at recursive SQL level 1
ORA-20315: 你的数据库已被SQL RUSH Team锁死 发送5个比特币到这个地址 166xk1FXMB2g8JxBVF5T4Aw1Z5JaZ6vrSE (大小写一致) 之后把你的Oracle SID邮寄地址 sqlrush@mail.com 我们将让你知道如何解锁你的数据库 Hi buddy, your database was hacked by SQL RUSH Team, send 5 bitcoin to address 166xk1FXMB2g8JxBVF5T4Aw1Z5JaZ6vrSE (case sensitive), after that send your Oracle SID to mail address sqlrush@mail.com, we will let you know how to unlock your database.
ORA-06512: at "NEUSOFT_RPT.DBMS_CORE_INTERNAL ", line 25
ORA-06512: at line 2

后经核实是由于开发人员使用了带有病毒程序的客户端(PL/SQL Developer)导致如果用户从某些不明来源下载了 PL/SQLDeveloper 工具后(尤其是各种绿色版、破解版),这个工具的安装目录存在一个脚本文件AfterConnect.sql,正常安装这个脚本是空文件,但是被注入的文件,该脚本包含了一系列的 JOB 定义、存储过程和触发器定义。受感染的AfterConnect.sql脚本开头伪装非常正常的代码,后续内容却是加密的恶意代码。

病毒主要对象有:

数据库启动后执行触发器 DBMS_SUPPORT_INTERNAL

DBMS_SUPPORT_INTERNAL 主要的意义是:
1.当数据库创建时间大于1200天之后,开始备份tab$表
2.删除 tab$ 中除掉 owner# 为 0 和 38 的记录(sys,xdb)
3.通过 SYS.DBMS_BACKUP_RESTORE.RESETCFILESECTION 清理掉备份信息(v$controlfile_record_section)
4.然后通过 DBMS_SYSTEM.KSDWRT 在你的 alert 日志中写上2046次的提示信息
Hi buddy, your database was hacked by SQL RUSH Team, send 5 bitcoin to address 166xk1FXMB2g8JxBVF5T4Aw1Z5JaZ6vrSE (case sensitive), after that send your Oracle SID to mail address​​sqlrush@mail.com​​, we will let you know how to unlock your database.
你的数据库已被SQL RUSH Team锁死 发送5个比特币到这个地址 166xk1FXMB2g8JxBVF5T4Aw1Z5JaZ6vrSE (大小写一致) 之后把你的Oracle SID邮寄地址​​sqlrush@mail.com​​我们将让你知道如何解锁你的数据库
5.再抛出一个前台的和4类似的警告信息

数据库登录触发器 DBMS_SYSTEM_INTERNAL

当你的非 SYSTEM,SYSAUX,EXAMPLE 之外的所有表的最小统计信息时间大于 1200 天,而且非 C89239.EXE 程序,就会报出来” 你的数据库已被 SQL RUSH Team 锁死 发送5个比特币到这个地址 166xk1FXMB2g8JxBVF5T4Aw1Z5JaZ6vrSE (大小写一致) 之后把你的Oracle SID邮寄地址​​sqlrush@mail.com​​我们将让你知道如何解锁你的数据库 Hi buddy, your database was hacked by SQL RUSH Team, send 5 bitcoin to address 166xk1FXMB2g8JxBVF5T4Aw1Z5JaZ6vrSE
(case sensitive), after that send your Oracle SID to mail address​​sqlrush@mail.com​​, we will let you know how to unlock your database.”的信息

数据库登录触发器DBMS_CORE_INTERNAL

这里比较明显,把表名不含 $,不含 ORACHK,不是 cluster 的表放到一个游标里面,然后取非 SYSTEM,SYSAUX,EXAMPLE之外的表空间的表的最小统计信息收集时间和当前时间比较如果大于 1200天 就执行 truncate table 操作,操作完成之后判断如果登录程序不为 C89239.EXE,则报出来异常,” 你的数据库已被SQL RUSH Team锁死 发送5个比特币到这个地址 166xk1FXMB2g8JxBVF5T4Aw1Z5JaZ6vrSE (大小写一致) 之后把你的Oracle SID邮寄地址​​sqlrush@mail.com​​我们将让你知道如何解锁你的数据库 Hi buddy, your database was hacked by SQL RUSH Team, send 5 bitcoin to address 166xk1FXMB2g8JxBVF5T4Aw1Z5JaZ6vrSE
(case sensitive), after that send your Oracle SID to mail address​​sqlrush@mail.com​​, we will let you know how to unlock your database.”。

由于之前做了权限收缩收回了DBA角色与大多数权限,导致病毒程序权限不足,无法创建JOB,触发器编译失败,导致部分病毒程序无法执行,未造成重大影响。

解决方案

第一 :被攻击的数据库用户中没有重要的业务对象时

1.这段代码的运行都是通过job来操作的,高版本默认的job_queue_processes已经是1000了,所以当时通过操作系统看到后台有700多个job进程在跑这段代码。
通过把job_queue_processes设置为0,重启实例它这段脚本就跑不起来了。只有没有跑这段代码,存储过程等对象才能删除。

2.从操作系统登录到数据库(sys 用户),找出非法的存储过程,job 定义,触发器,把它们都 drop 就可以,当时由于这个客户在受攻击的数据库用户下面没有业务对象,把这个用户drop,重建就可以了。上述的整个处理过程没有数据丢失,之所以耗时这么长是因为客户担心丢失先做一次备份。

如果 SELECT NVL(TO_CHAR(SYSDATE-MIN(LAST_ANALYZED)),0) FROM ALL_TABLES WHERE TABLESPACE_NAME NOT IN (‘SYSTEM’,'SYSAUX’,'EXAMPLE’); 小于1200,查询下列语句,然后删除掉(正常库查询为空)

select 'DROP TRIGGER '||owner||'."'||TRIGGER_NAME||'";' from dba_triggers where
TRIGGER_NAME like 'DBMS_%_INTERNAL% '
union all
select 'DROP PROCEDURE '||owner||'."'||a.object_name||'";' from dba_procedures a
where a.object_name like 'DBMS_%_INTERNAL% ';

如果SYSDATE-MIN(LAST_ANALYZED)大于1200, SYSDATE-CREATED大于1200天未重启,或者SYSDATE-CREATED小于1200;就是tab$还未被清理,但是表被truncate,这样情况可以通过oracle原厂dul工具恢复;

如果SYSDATE-CREATED大于1200天,而且数据库重启过,但是SYSDATE-MIN(LAST_ANALYZED)小于1200天,那可以直接通过把ORACHK’||SUBSTR(SYS_GUID,10)中备份信息插入到$tab中;

SYSDATE-CREATED大于1200天,而且数据库重启过,但是SYSDATE-MIN(LAST_ANALYZED)大于1200天,Oracle 原厂dul之类工具结合ORACHK’||SUBSTR(SYS_GUID,10)备份表中数据进行恢复;

第二 :当被攻击的数据库用户中有重要业务对象时:

1. 如果是对文件加密,根据具体客户情况,可以考虑比对正常文件(没有被攻击的数据库的文件)和有问题文件比对,找到端倪后,拼接等等思路

2. 根据实际情况,如果上面的“1.”不可行,那么考虑停止黑客的异常job,过程,触发器等等(可以采用倒推等方式或者直接查询DBA_OBJECTS中的LAST_DDL时间),根据实际情况,如果有必要的话,还可以根据报错时间点进行logminer来进行检查和确认损坏过程,并找到黑客备份的系统表,进行还原(请在Oracle Support或者专业DBA指导下完成)。

3. 如果上述的“1.”和“2.”都不可行,那么可以考虑使用各种可以进行逻辑挖掘的工具挖出数据。
.
当然根据不同的黑客入侵方式,可能还有其他解决方法,这里要重点讨论的是我们如何防患于未然:
1,请使用正版工具或者使用Oracle官方推荐的免费SQL客户端工具:
​​​http://www.oracle.com/technetwork/developer-tools/sql-developer/downloads/index.html​​ 上面地址是官网正版下载地址,功能非常强大,完美支持12c和以前的数据库版本,并且免费。

2,如果发现类似问题,尽量保护现场,并根据报错信息的时间点,追查原因

3,重要数据库一定要备份,如果配置了ADG,备库建议开闪回,如此,很多问题处理上就简单多了。

4,对于数据库用户的dba等高级权限应该有效管理

5.请注意,有些黑客会设置一个潜伏期,例如上面的例子,该攻击的效果存在1200天的潜伏期:
黑客代码中有类似下面的判断条件:IF (DATE1>=1200) THEN
因此,建议客户检查数据库的异常对象,如果发现异常对象,建议直接删除相关恶意注入的数据库对象(procedure,job,trigger等等)

预防策略

1)数据库里面查询异常对象,并及时清理。

2)建议业务用户尽量限制dba 权限

3)检查相关登陆工具的自动运行脚本 清理掉有风险脚本
sqlplus中的glogin.sql/login.sql
toad中的toad.ini
plsql dev中的login.sql/afterconnect.sql

4)建议从官方下载工具,不要使用绿色版/破解版等