使用Oracle DV防范比特币勒索

使用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),识别登录会话使用的模块名称

clip_image002

取模块名并转成大写:UPPER(SYS_CONTEXT(‘USERENV’,’MODULE’)

clip_image004

不做审计

clip_image006

命令行方式是使用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,测试一下是否能正确取到值:

clip_image008

创建规则:

规则名为RULE1,表达式的含义是:客户端模块名不能是PL开头的字符串,或者用户不是SYS和SYSTEM:

clip_image010

等效命令行:

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的关系:

clip_image012

第二步,添加规则,程序模块不能以PL开头,或者用户不是SYS和SYSTEM,这样普通权限用户可以用PL/SQL Developer登录。

clip_image014

第三步,定义违反规则时,显示的错误号和错误信息:

clip_image016

等效命令行:

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中的规则返回结果为真时,允许登录数据库。

clip_image018

等效命令行:

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用户则不可以:

clip_image020

限制特权用户创建对象

我们就以比特币勒索为例,我们要想防范,可以让sys用户不能创建触发器。

创建规则,表达式含义:会话用户不是SYS和SYSTEM

clip_image022

创建规则集RULESET2,里面只有一个规则,就是RULE2:

clip_image024

针对命令“CREATE TRIGGER”创建规则:组合在一起的意思就是,当会话用户不是SYS或SYSTEM时,可以创建触发器,如果用户是SYS和SYSTEM,当尝试创建触发器时,会报错:”sys and system can not create objects”。

clip_image026

限制特权用户创建触发器的效果:

[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的保护作用也就名存实亡了。

Comments are closed.