
使用Oracle DV防范比特币勒索
作为Oracle DBA,应该都会知道前一阵有人借助PL/SQL Developer的自动执行脚本,破坏Oracle数据库,并勒索比特币的事情。(如果不知道就百度吧)
针对这次的事件,各方专家都陆续给出了原理分析和防范建议,一般都是说不要使用不明来路的PL/SQL Developer,尽量使用原厂提供的工具,我想这个的确能防范问题,不过缺乏强制力。
指望所有能接触数据库的人都自觉遵守制度,是不太现实的。而且,也不排除个别人,借着这次事件,反而了解了技术原理,继续搞出这次事件的变种。
进一步讲,也不见得非要使用PL/SQL Developer自动执行脚本的这种“注入”方式,只要了解了原理,结合比特币的不可追查性,有些内贼完全可以混淆视听,达到自己的目的。
所以,我认为还是必须要有技术手段来积极防范这种情况。
积极防范总比事后补救要好,不过大多数国人总是忘记这一点,这就好比吸烟的人,别人劝他不吸烟不听,得了肺癌,被医生开刀治好了,他绝对会崇拜那个治好他的医生,而对曾经劝他不要吸烟的人,就未必那么印象深刻了,当然,医生能治好他,的确厉害,但是,他本来可以不用挨那“一刀”的。
不说太多题外话,下面我们就看看怎么使用Oracle DV来防范类似这次比特币勒索的威胁。
Oracle Database Vault 的基本原理和简单介绍可以参考我写的这篇文章:《使用技术手段限制DBA的危险操作》http://www.rao-bing.cn/index.php/2017/01/07/database_vault/
本文不是DV全面的介绍,只是针对比特币勒索这种场景,看看怎么防范。
比特币勒索的技术原理有两个关键点,第一是借助篡改过的PL/SQL Developer工具,使DBA毫无知觉地运行了恶意代码。
其次,就是无意中执行了恶意代码的人,必须要有很高的数据库权限,才能创建恶意触发器及存储过程,并破坏系统表。
所以,我们要防范这种危险,主要就是针对这两点,说出来其实也比较简单,第一就是不允许PL/SQL Developer这种能隐式自动执行SQL脚本的工具登录数据库,第二就是限制特权用户,不允许创建触发器,或任何其他类型的存储过程。
最终DV Owner用户的账号应该只掌握在少数1、2个负责安全的人手里,这样就可以避免DBA或开发人员随意绕开DV规则,进而使用特权用户时,不小心“中招”。
而“职责分离”后,DV Owner用户又没有创建系统触发器或存储过程的数据库权限,所以他们也不会“中招”。
我们以12.1.0.2数据库为例,举例说明。(12c后,EM express中又没有DV的管理界面了,11g 的DB Control中有,如果想用web界面配置,必须安装EM12c或EM13c,会比较麻烦,我这里会同时给出web界面配置的方法和使用命令行配置的方法)
限制特权用户使用PL/SQL Developer登录数据库
创建因子(factor),识别登录会话使用的模块名称
取模块名并转成大写:UPPER(SYS_CONTEXT(‘USERENV’,’MODULE’)
不做审计
命令行方式是使用DV owner用户登录数据库,通过调用DV的PL/SQL API,来进行配置,和上面web界面同样效果的语句:
begin DVSYS.DBMS_MACADM.CREATE_FACTOR(factor_name => 'MODULE', factor_type_name => 'Application', description => ' ', rule_set_name => '', get_expr => 'UPPER(SYS_CONTEXT('USERENV ',' MODULE '))', validate_expr => '', identify_by => 1, labeled_by => 0, eval_options => 1, audit_options => 0, fail_options => 1); end;
配置完成后,可以使用安全的PL/SQL Developer,测试一下是否能正确取到值:
创建规则:
规则名为RULE1,表达式的含义是:客户端模块名不能是PL开头的字符串,或者用户不是SYS和SYSTEM:
等效命令行:
begin DVSYS.DBMS_MACADM.CREATE_RULE(rule_name => 'RULE1', rule_expr => 'DVF.F$MODULE NOT LIKE ''PL%'' OR (SYS_CONTEXT(''USERENV'', ''SESSION_USER'') NOT IN (''SYS'',''SYSTEM''))'); end;
创建规则集
第一步,创建一个名字叫RULESET1的规则集,注意赋值选项,全部为“真”等于所有RULE之间是AND的关系:
第二步,添加规则,程序模块不能以PL开头,或者用户不是SYS和SYSTEM,这样普通权限用户可以用PL/SQL Developer登录。
第三步,定义违反规则时,显示的错误号和错误信息:
等效命令行:
begin DECLARE x VARCHAR2(40); static_option BOOLEAN := FALSE; BEGIN x := 'N'; IF x = 'Y' THEN static_option := TRUE; ELSE static_option := FALSE; END IF; DVSYS.DBMS_MACADM.CREATE_RULE_SET(rule_set_name => 'RULESET1', description => ' ', enabled => 'Y', eval_options => 1, audit_options => 1, fail_options => 1, fail_message => '', fail_code => '', handler_options => 0, handler => '', is_static => static_option); END; DVSYS.DBMS_MACADM.ADD_RULE_TO_RULE_SET(rule_set_name => 'RULESET1', rule_name => 'RULE1', rule_order => '1', enabled => 'Y'); end;
定义命令规则
针对connect命令,定义规则,关联的规则集,就是我们上面创建的RULESET1,规则集RULESET1中的规则返回结果为真时,允许登录数据库。
等效命令行:
begin DVSYS.DBMS_MACADM.CREATE_COMMAND_RULE(command => 'CONNECT', rule_set_name => 'RULESET1', object_owner => DBMS_ASSERT.ENQUOTE_NAME('%',FALSE), object_name => '%', enabled => 'Y'); end;
限制特权用户使用PL/SQL Developer登录的效果
如图所示,用户app1可用PL/SQL Developer登录数据库,而使用SYS用户则不可以:
限制特权用户创建对象
我们就以比特币勒索为例,我们要想防范,可以让sys用户不能创建触发器。
创建规则,表达式含义:会话用户不是SYS和SYSTEM
创建规则集RULESET2,里面只有一个规则,就是RULE2:
针对命令“CREATE TRIGGER”创建规则:组合在一起的意思就是,当会话用户不是SYS或SYSTEM时,可以创建触发器,如果用户是SYS和SYSTEM,当尝试创建触发器时,会报错:”sys and system can not create objects”。
限制特权用户创建触发器的效果:
[oracle@oel65vm1 ~]$ sqlplus sys/welcome1 as sysdba SQL*Plus: Release 12.1.0.2.0 Production on Sat Jan 21 12:07:12 2017 Copyright (c) 1982, 2014, Oracle. All rights reserved. Connected to: Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production With the Partitioning, Oracle Label Security, OLAP, Advanced Analytics, Oracle Database Vault and Real Application Testing options SQL> create or replace trigger test_tigger 2 after startup on database 3 begin 4 insert into log_table values(1); 5 commit; 6 end; 7 / after startup on database * ERROR at line 2: ORA-47306: 20003: sys and system can not create objects
普通用户仍然可以创建触发器:
SQL> SQL> connect app1/welcome1 Connected. SQL> SQL> create or replace trigger test_tigger 2 after insert on log_table 3 begin 4 insert into log_table values(999); 5 commit; 6 end; 7 / Trigger created. SQL>
另外,SQL*PLUS也能登录后,自动执行脚本,这就分两种情况,本地和远程,本地相对安全些,远程的就不好讲了,其实也应该禁止远程SQL*PLUS的访问。
其次,对于投产的数据库来讲,特权用户,比如SYS,SYSTEM,基本不会有创建存储过程,触发器等对象的需求,所以限制了这块,对实际工作影响不大,如果实在要创建触发器,可以临时disable对应的命令规则,执行完再enable,这样一来就要有相应的审批确认流程,就可以避免在不知不觉中“中招”。
当然,工具再好,没有制度配合也不行,像DV这种工具,就怕DV Owner账号信息满天飞,谁都可以随意变更DV的权限规则,那就又回到老路上,DV的保护作用也就名存实亡了。