某客户核心业务系统中招ORACLE数据库勒索病毒。 告警日志出现自动任务执行错误,对象被锁,并出现“你的数据库已被SQL RUSH Team锁死 发送5个比特币到这个地址166xk1FXMB2g8JxBVF5T4Aw1Z5aZ6vSE (大小写一致) 之后把你的Oracle SID邮寄地址 [email protected]我们将让你知道如何解锁你的数据库”的信息(别发,数据丢失他们找不回来,病毒程序云和恩墨可以处理)。当时的告警日志如下:
修改job参数,防止病毒程序自启
alter system set job_queue_processes=0;
杀掉job进程,停止正在运行的病毒程序自动任务
ps -ef |grep j0|grep -v grep|awk '{print $2}'|xargs kill -9
禁用数据库监听自启动,关闭监听,防止携带病毒的客户端再次连接
srvctl disable listener
srvctl disable scan_listener
srvctl stop listener
srvctl stop scan_listener
杀LOCAL=NO的会话
ps -ef|grep LOCAL=NO|grep -v grep|awk '{print $2}'|xargs kill -9
查找病毒程序
select owner,object_name from dba_objects where object_name like '%FUN9%'
select owner,created,object_name,OBJECT_TYPE from dba_objects where object_name like '%DBMS_CORE%';
select owner,created,object_name,OBJECT_TYPE from dba_objects where object_name like '%DBMS_SYSTEM_INTERNAL%’;
select owner,created,object_name,OBJECT_TYPE from dba_objects where object_name like '%DBMS_SUPPORT%';
OWNER CREATED OBJECT_NAME OBJECT_TYPE
-------------------- ------------------- ------------------------------ -------------------
APPUSER01 2019-05-24 10:58:06 DBMS_CORE_INTERNAL PROCEDURE
APPUSER01 2019-05-24 10:58:06 DBMS_SYSTEM_INTERNAL TRIGGER
APPUSER01 2019-05-24 10:58:05 DBMS_SUPPORT_INTERNAL PROCEDURE
APPUSER01 2019-05-24 10:58:06 DBMS_SYSTEM_INTERNAL PROCEDURE
APPUSER01 2019-05-24 10:58:06 DBMS_STANDARD_FUN9 PROCEDURE
删除病毒程序的存储过程、触发器
--一般会跟9个空格,最好是通过sql拼凑drop语句
SQL> drop PROCEDURE APPUSER01."DBMS_CORE_INTERNAL ";
Procedure dropped.
SQL> drop PROCEDURE "APPUSER01"."DBMS_SYSTEM_INTERNAL ";
Procedure dropped.
SQL> drop PROCEDURE "APPUSER01"."DBMS_SUPPORT_INTERNAL ";
Procedure dropped.
SQL> drop TRIGGER "APPUSER01"."DBMS_SYSTEM_INTERNAL ";
Procedure dropped.
SQL> drop PROCEDURE "APPUSER01"."DBMS_STANDARD_FUN9";
Procedure dropped.
在启动数据库前,需要将出入病毒的连接IP查找出来加入黑名单,以防再次发生病毒注入。通过监听日志查找问题时间段的PLSQL连接
[oracle@host01 trace]$ fgrep "24-MAY-2019 10:5" dd1.log |fgrep "establish" | fgrep "plsql"
24-MAY-2019 10:50:05 * (CONNECT_DATA=(SERVICE_NAME=service1)(CID=(PROGRAM=C:\PLSQL Developer\plsqldev.exe)(HOST=host1)(USER=user1))) * (ADDRESS=(PROTOCOL=tcp)(HOST=10.xx.xx.xx)(PORT=xxx)) * establish * epmjc * 0
24-MAY-2019 10:51:01 * (CONNECT_DATA=(SERVICE_NAME= service1)(CID=(PROGRAM=C:\Program Files\PLSQL Developer\plsqldev.exe)(HOST=host1)(USER=user1))) * (ADDRESS=(PROTOCOL=tcp)(HOST=10.xx.xx.xxx)(PORT=xx)) * establish * epmjc * 0
…
查找所有节点的监听日志,发现疑似携带病毒的机器IP有5个,并同时检查下面ip对应机器上的三方程序是否有异常。
检查这些机器是否携带病毒需要时间,为了及时恢复应用,将上述5个ip全部加入数据库黑名单,sqlnet.ora添加配置示例如下
TCP.VALIDNODE_CHECKING=YES
tcp.excluded_nodes=(xxx.xx.xx.xx,xx.xx.xx.xx)
启动监听,检查数据库(注意:因为还有job没有删除,job_queue_processes仍然为0),联系应用验证数据一致性和可用性。
APPUSER01用户下的表丢失数据,通过数据库历史视图查找数据库truncate操作
SQL> select * from dba_hist_sqltext where upper(SQL_TEXT) like '%TRUNCATE TABLE%';
DBID SQL_ID SQL_TEXT COMMAND_TYPE
---------- -------------------------- -------------------------------------------------------------------------------- ------------
2584110390 b1undrf93t007 DECLARE job BINARY_INTEGER := 1; broken BOOLEAN := TRUE; next_date DATE := SYSDA 47
2584110390 48v643w2mr5ax DECLARE job BINARY_INTEGER := 1; broken BOOLEAN := TRUE; next_date DATE := SYSDA 47
2584110390 9up4qgk4udmq3 DECLARE job BINARY_INTEGER := 1; broken BOOLEAN := TRUE; next_date DATE := SYSDA 47
…
108 rows selected.
从上面的历史sql视图反应,数据库在注入病毒后,于2019年5月24日11:02分钟左右病毒程序truncate了约108张表。(小广告:数据库中病毒或者数据丢失,可以联系云和恩墨团队进行专业处理)
检查病毒相关job
select count(*) from dba_jobs where schema_user='APPUSER01' and what like '%truncate%';
count出来大概有4kw行,system表空间都要撑满了
逐条删除job需要花很多时间,可以使用并行来跑
begin
for i in (select job from dba_jobs
where schema_user='APPUSER01' and what like '%truncate%' and mod(job,4)=0 )
loop
dbms_ijob.remove(i.job);
end loop;
end;
/
大概跑了20+小时,干掉了这些病毒程序的job。
Remove操作有点类似delete,基表job$的段空间是没有收缩的,水位线仍然是4kw的时候那么高。虽然查询dba_jobs很慢,但是出于安全考虑没有降低基表的水位线,但是实测trunc是没有问题的,可以备份jobs,然后trunc job$,再创建job应该就没问题。注意:不要使用move,move会使job$上的索引失效,而且基本无法创建索引,也无法创建job。
我们检查了可疑IP中的4个,发现PLSQL中的AfterConnect.sql和login.sql都没有异常。其中afterconnect.sql的大小应该是0字节,login.sql打开后只有一句注释“- -Autostart Command Window script ”。如果这两个文件里有其他内容,应该怀疑是病毒。
但最后一个IP,没有在本地,通过360扫描出了病毒程序
在2019年5月24日10:58:05该机器通过携带病毒的PLSQL连接到数据库的APPUSER01用户,导致了该数据库被注入勒索病毒,2019年5月24日11:02该病毒程序删除了APPUSER01下的部分数据,2019年5月27日11:15病毒程序阻止了数据库会话登陆,抛出勒索比特币告警信息,从而导致此次业务长时间中断和数据丢失。
ORACLE比特币勒索病毒可以追溯到2016年,国内很多用户的Oracle 数据库中病毒。时隔3年,勒索病毒似乎卷土重来。
本次故障直接造成业务长时间无法连接数据库,造成数据永久丢失,原因就是不安全的PLSQL连接到了核心库。
几乎绝大多数客户端工具,在访问数据库时,都可以通过脚本进行一定的功能定义,而这些脚本往往就是安全问题的漏洞之一,来历不明的工具是数据库管理大忌。通过此次数据库勒索病毒事件可以看出,数据库安全的重要性,不要抱着“不会发生在我身上”的想法管理数据库,一切都是命运的安排。
为了防止勒索病毒不再发生,提高数据安全性,建议如下:
1.严格管理权限。回收所有业务用户的dba权限,在保障数据安全和应用可用的前提下,提供用户最小权限。
2.排查三方工具。大范围排查是否还可能有不明来源的第三方工具连接数据库,必须从官方渠道获取客户端连接工具。以下列出了常见客户端工具的脚本位置,需要引起注意
SQL*Plus: glogin.sql / login.sql
TOAD : toad.ini
PLSQLdeveloper: login.sql / afterconnect.sql
3.通过官方渠道下载补丁包。补丁包中也可能包含病毒程序,下载官方补丁包是基本规范操作。
4.设置白名单。限制IP登录,非白名单中的IP不允许登录数据库,提高数据的安全性。
5.日常巡检。把病毒扫描脚本加入日常巡检中,早发现早处理。(小广告,恩墨白求恩产品可以检查出数据库是否带病毒,免费!(https://bethune.enmotech.com)
6.开启数据库审计。数据库审计在跟踪用户操作上更加全面,审计会捕获用户登录数据库及登录后的各项操作