PL/SQL Developer是一个集成开发环境,由Allround Automations公司开发,专门面向Oracle数据库。作为一款第三方工具,早就被广大Oracle开发和运维人员所熟知。相比纯O系的SQL Developer,以及一些其他的第三方软件,在图形操作这块,确实更加友好。

PLSQL Developer,为开发人员提供了丰富的工具,封装了查看执行计划、美化SQL写法、设置日期格式等,很容易地通过点击操作完成,不用记住sqlplus中复杂的命令,

PLSQL Developer几个可能的隐患_Developer

虽然工具方便了,但是屏蔽了细节,一旦不了解,进入盲区,就可能适得其反,产生其他影响。

在这我介绍几个和工具相关的隐患,既然是隐患,就可能碰到,可能不会碰到,但是你知道了这些问题,至少能做出一些提前的应对,或者出现问题时,能快速定位解决问题。

1. 语句自动提交

我们知道,常用的SQL语句,分为DDL和DML两种,DDL是数据定义语言(Data Definition Language),例如create、alter、drop操作,都是DDL语句,官方定义如下,

Data definition language (DDL) statements define, structurally change, and drop schema objects.

For example, DDL statements enable you to:
1.Create, alter, and drop schema objects and other database structures, including the database itself and database users. Most DDL statements start with the keywords CREATE, ALTER, or DROP.
2.Delete all the data in schema objects without removing the structure of these objects (TRUNCATE).
3.Grant and revoke privileges and roles (GRANT, REVOKE).
4.Turn auditing options on and off (AUDIT, NOAUDIT).
5.Add a comment to the data dictionary (COMMENT).

DML是数据控制语言(Data Manipulation Language),例如insert、delete、update操作,都是DML语句,官方定义如下,

Data manipulation language (DML) statements query or manipulate data in existing schema objects. Whereas DDL statements enable you to change the structure of the database, DML statements enable you to query or change the contents. For example, ALTER TABLE changes the structure of a table, whereas INSERT adds one or more rows to the table.

DML statements are the most frequently used SQL statements and enable you to:
1.Retrieve or fetch data from one or more tables or views (SELECT).
2.Add new rows of data into a table or view (INSERT) by specifying a list of column values or using a subquery to select and manipulate existing data.
3.Change column values in existing rows of a table or view (UPDATE).
4.Update or insert rows conditionally into a table or view (MERGE).
5.Remove rows from tables or views (DELETE).
6.View the execution plan for a SQL statement (EXPLAIN PLAN). See "How Oracle Database Processes DML".
7.Lock a table or view, temporarily limiting access by other users (LOCK TABLE).

两者最大区别,就在于提交(commit)操作。DML语句执行完成,需要手动执行commit,或者rollback,才可以结束当前事务,但是,DDL语句执行完成,都会自动执行隐式提交(implicit commit),在Oracle中,这个行为是不能改变的。

这个问题其实会产生一些困扰,假设我要执行如下操作,其中4的执行会进行一些逻辑判断,可能commit,可能rollback回滚1、2和4,针对rollback场景,执行结果不会和你想象的一样,因为1、2、4是DML操作,3是DDL操作,这些语句在同一个事务中执行,3的DDL会隐式提交,此时会将1和2的insert和delete连带提交,当4需要rollback时,只可以回滚4的操作,1和2已经提交,无法再执行回滚,

1. insert into a values (...);
2. delete from a where ...
3. alter table a add ...;
4. update a set ... where ...;

其实这个问题,更多还是程序设计或者工具执行上的问题,你要保证程序中,或者在工具中执行的SQL顺序上,DML和DDL不要有交叉相互影响。

但是在PLSQL Developer中,是可以设置DML语句自动提交的,在"Tools-Preferences-SQL Windows",有个AutoCommit SQL,默认是空,如果勾选,则执行的DML,会自动提交,

PLSQL Developer几个可能的隐患_PLSQL_02

我猜测之所以有这个功能,可能还是和工具定位有关,就像官网(https://www.allroundautomations.com/)上的广告所说,PLSQL Developer是“real solutions for oracle developers”,这个工具是为了提升Oracle开发人员的工作效率,不是提升Oracle数据库的保障机制,

PLSQL Developer几个可能的隐患_Developer_03

例如开发人员在PLSQL Developer会话中增删改数据,但是忘了或者其他原因没做commit/rollback,再操作其他会话,会看到这个变更未生效,产生混淆。正是为了方便开发人员,PLSQL Developer支持了自动提交,执行这些DML的同时,自动commit,避免了开发人员忘记提交的可能。

但是从运维角度,AutoCommit这种操作是非常危险的。之所以DML语句需要显示提交,从原理层讲,DML会记录redo和undo信息,undo中存储的是修改数据的前镜像,当执行rollback时,可以利用undo数据进行恢复,当执行commit时,Oracle会标记undo,确认持久生效。另一方面,从影响上看,DML需要显示提交,让你有个缓冲,校验所做操作是否和你的预期相同,相当于check,结果正确,执行commit,结果错误,执行rollback。如果设置了AutoCommit,相当于直接提交,此时要回滚,就得手工执行该操作的逆向操作,并不是所有场景都可以很快执行的。

因此从开发角度,AutoCommit会提供些方便,但从运维角度,不建议打开AutoCommit,弊大于利。

2. 退出自动提交

PLSQL Developer另外一个很隐蔽,但确实在某些场景下相当“危险”的功能,就是正常退出时的事务状态,在"Tools-Preferences-Connection",有个Logoff with open transaction,默认是Commit,还支持Rollback、Ask,

PLSQL Developer几个可能的隐患_Developer_04

他的意思是说,当你正常退出PLSQL Developer,如果窗口中,存在尚未提交的事务,Logoff with open transaction=Commit,PLSQL Developer就会帮你自动提交了,从开发者角度,确实提供了方便,我不用记住是不是执行commit,PLSQL Developer帮我做了。但是你想想,某些场景下,这个操作是不是很危险?例如PLSQL Developer连接生产库,你的窗口中,包含一条delete from xxx语句,然后你执行了select想看下这个会话删除的效果,但是因为什么其他的事情,中断了思路,等你回过头来,误认为回滚了,直接关闭软件,PLSQL Developer就会替你执行commit,持久化了delete的操作,此时你可能还未意识到这个。

因此,这个选项Logoff with open transaction强烈建议设置为Rollback,正常关闭软件,就让他自动回滚(其实这正是Oracle默认的行为,退出session,自动回滚),由执行者自行决定事务的提交/回滚状态,不是让工具代替你决定。至少应该设置为Ask,关闭软件时,如果窗口存在未提交事务,弹出窗口,由执行者选择,

PLSQL Developer几个可能的隐患_PLSQL_05

3. 盗版带来的风险

关于Oracle比特币勒索的事情,已经出了很多了,最主要的原因就是用户下载了来源不明的数据库管理工具,指的就是PLSQL Developer。

黑客在PLSQL Developer的AfterConnect.sql文件中加入了勒索代码,然而此文件在官方的软件中为空文件,该勒索病毒就是利用了这个文件注入病毒代 码,在用户连接数据库后立即执行,并在告警日志出现自动任务执行错误,勒索你5个比特币,

ORA-00604: error occurred at recursive SQL level 1
ORA-20315: 你的数据库已被SQL RUSH Team锁死  发送5个比特币到这个地址 166xk1FXMB2g8JxBVF5T4Aw1Z5aZ6vSE (大小写一致)  之后把你的Oracle SID邮寄地址 sqlrush@mail.com我们将让你知道如何解锁你的数据库
Hi buddy, your database was hacked by SQL RUSH Team, send 5 bitcoin to address 166xk1FXMB2g8JxBVF5T4Aw1Z5aZ6vSE (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 “XXX.DBMS_CORE_INTERNAL         ", line 27
ORA-06512: at line 2

在客户端,可能得到这种,

PLSQL Developer几个可能的隐患_PLSQL_06

5个比特币,是多少钱?我不是很懂,于是乎,搜了一下,自行脑补,

PLSQL Developer几个可能的隐患_SQL_07

其实这个问题,和Oracle本身没什么直接关系,就是因为使用了各种绿色版、破解版的盗版PLSQL Developer。

借助PLSQL Developer的AfterConnect.sql脚本,在Oracle中执行了一些特定的JOB、存储过程和触发器,实现勒索机制。而AfterConnect.sql脚本伪装成了login.sql,含有清晰的注释,

PLSQL Developer几个可能的隐患_SQL_08

但是执行的内容,进行了加密,

PLSQL Developer几个可能的隐患_PLSQL_09

可以借助unwrap解密,看到其核心代码,

PLSQL Developer几个可能的隐患_SQL_10

大致的逻辑是,

1.判断数据库建库时间是否大于1200天。

2.隐藏了1200天,就会将sys.tab$的数据导入名为"ORACHK||SYS_GUID前10位"的表中。

3.删除sys.tab$,执行提交。

4.执行检查点事件,强制将脏块,写入数据文件。

5.$ORACLE_HOME/rdbms/admin/dbmsbkrs.sql定义了dbms_backup_restore,存储过程resetCfileSection负责清空控制文件指定记录,

PROCEDURE resetCfileSection(record_type  IN  binary_integer );
  -- This procedure attempts to reset the circular controlfile p.
  --
  -- Input parameters:
  --   record_type
  --     The circular record type whose controlfile p is to be reset.

通过v$controlfile_record_p视图,可以知道14号是备份的数据文件,做的很彻底,

SQL> select rownum-1, type from v$controlfile_record_p;
  ROWNUM-1 TYPE
---------- ----------------------------
     0 DATABASE
     1 CKPT PROGRESS
     2 REDO THREAD
     3 REDO LOG
     4 DATAFILE
     5 FILENAME
     6 TABLESPACE
     7 TEMPORARY FILENAME
     8 RMAN CONFIGURATION
     9 LOG HISTORY
    10 OFFLINE RANGE
    11 ARCHIVED LOG
    12 BACKUP SET
    13 BACKUP PIECE
    14 BACKUP DATAFILE
    15 BACKUP REDOLOG
    16 DATAFILE COPY
    17 BACKUP CORRUPTION
    18 COPY CORRUPTION
    19 DELETED OBJECT
    20 PROXY COPY
    21 BACKUP SPFILE
    22 DATABASE INCARNATION
    23 FLASHBACK LOG
    24 RECOVERY DESTINATION
    25 INSTANCE SPACE RESERVATION
    26 REMOVABLE RECOVERY FILES
    27 RMAN STATUS
    28 THREAD INSTANCE NAME MAPPING
    29 MTTR
    30 DATAFILE HISTORY
    31 STANDBY DATABASE MATRIX
    32 GUARANTEED RESTORE POINT
    33 RESTORE POINT
    34 DATABASE BLOCK CORRUPTION
    35 ACM OPERATION
    36 FOREIGN ARCHIVED LOG

6.dbms_system.ksdwrt会向跟踪日志中写入勒索信息,

1 - Write to trace file.
2 - Write to alertlog.
3 - Write to both.

从以上的信息,至少说明黑客对Oracle还是比较懂的,所谓“流氓会武术”,但“还是能挡住”,最重要的一点,就是避免使用来历不明的软件,除此之外,我们还可以做的,包括不仅限于,

1.使用最小权限的原则,分配用户合适的账号权限,用多少给多少。

2.关注管理工具的登录脚本,存在异常,立即报警,

SQL*Plus: glogin.sql / login.sql
TOAD : toad.ini
PLSQLdeveloper: login.sql / afterconnect.sql

3.开启一定的审计,数据库级的,应用级的,都可以起到一定的告警和监管作用。

4. 异常退出的影响(未确认)

记得很久以前看到某位大佬提到过,大概意思是PLSQL Developer在异常退出的情况下,如果窗口中存在未提交的事务,一般来讲,应该做的是回滚,但是,存在小概率事件会做事务的提交而不是回滚。

实在没找到出处,而且没实验支撑,所以算作未确认,倘若如此,真是很坑的。但归根结底,这个问题,还是对个人行为提出了要求,尤其是对生产系统的操作,通过PLSQL Developer这种工具,执行内容、顺序、时间,其实都是靠个人控制的,因此要对所操作内容谨慎、谨慎、再谨慎。做任何操作前,考虑下这个操作,究竟应该不应该,这就和开车是一样的,开的慢点,就可以避免一些不必要的风险。

To Be Continued ..

对以上这些隐患,各位若是有补充,可以文末留言,目的都是为了让我们尽量避开这些风险,平稳开车,

PLSQL Developer几个可能的隐患_PLSQL_11