首页 > 数字化转型 > ERP > 这是安全性和合规性项目的第 2 阶段
这是安全性和合规性项目的第 2 阶段。 看看如何在 5 个工作日内保护您的基础架构。
尽管“安全保护项目”的第 1 阶段仅持续了 24 小时,但在该阶段您已完成了很多操作。 现在将进入第 2 阶段,持续时间大约为一周。 在本阶段,您将接着上一阶段执行的操作继续执行操作,并取得一些新的进展。与以前一样,您将采取一些简单但却高效的操作来保护数据库。
您可能会问,为什么本阶段要持续一周的时间呢?
下面我们就开始吧!
这一部分涉及:
· 2.1 删除 utl_file_dir
· 2.2 限制 OS 验证
· 2.3 禁用远程 OS 验证
· 2.4 使用产品配置文件保护 SQL*Plus
· 2.5 控制 SQL*Plus
· 2.6 包装机密代码
· 2.7 将间接授权转换为直接授权
· 2.8 限制表空间限额
· 2.9 监控监听器日志以获知尝试的非法侵入
· 2.10 审计和分析用户访问
2.1 删除 utl_file_dir
背景
Oracle 支持通过 SQL 和/或 PL/SQL 从数据库中操作 OS 文件,而不必访问主机操作系统。 此功能由内置的 PL/SQL 程序包 utl_file 提供。 例如,下面的代码打开目录 /tmp 中一个名为 myfile.txt 的文件并向其中写入行“Some Text”:
1 declare
2 l_filename utl_file.file_type;
3 begin
4 l_filename := utl_file.fopen ('/tmp','myfile.txt','W');
5 utl_file.put_line (l_filename, 'Some Text', TRUE);
6 utl_file.fclose(l_filename);
7 end;
如果文件 myfile.txt 不存在,则此代码将创建 myfile.txt。 但要使此代码正常运行,您必须通过以下初始化参数将 /tmp 声明为一个可以由 utl_file 程序包打开的目录:
utl_file_dir = '/tmp'
然后重新启动数据库。
只要该目录由 Oracle 软件拥有者拥有,使用此参数表示用户可以在目录 /tmp 中创建文件,也可以覆盖其中的任何文件。那么,设置该参数有错么?
没有,但大多数系统不会将此参数设置为 /tmp。 相反,为了使开发人员或用户可以操作文件,而事先并不知道创建文件的位置,该设置通常为“*”,如下所示:
utl_file_dir = '*'
这意味着只要 Oracle 软件拥有者拥有文件(甚至是 Oracle 数据文件)的读取或写入权限,用户便可以打开文件。从理论上来讲,这将使恶意攻击者可以写入一个故意破坏数据文件的程序。 如果该文件恰好用于 SYSTEM 表空间,则整个数据库将崩溃。(当然,您可以从备份恢复它,但损害已经在所难免。) 更糟糕的是,恶意攻击者可能会破坏存档的日志文件,从而导致无法通过此存档日志进行恢复。 恶意攻击者甚至还可以使用 utl_file.fremove 提供的程序包删除文件。
因此,将 utl_file_dir 设置为“*”并不可取。
策略在 Oracle9i 数据库和更高版本中,无需使用 utl_file_dir - 程序将使用 directory 对象指定位置,而非绝对目录。因此,在以上示例中(在该示例中,该应用程序需要打开 /tmp 目录中的文件 myfile.txt),该应用程序可以通过以下代码执行此操作:
1 declare
2 l_filename utl_file.file_type;
3 begin
4 l_filename := utl_file.fopen ('TMP_DIR','myfile.txt','W');
5 utl_file.put_line (l_filename, 'Some Text', TRUE);
6 utl_file.fclose(l_filename);
7 end;
目录对象 TMP_DIR 必须已在前面通过以下命令创建:
create directory TMP_DIR as '/tmp';
该命令(即 create directory)只提供一次。 随后,任何具有该目录访问权限的用户均可以从中创建或读取文件。
您可以通过精细的方式授予此目录对象。例如,假设您为警报日志所在的目录创建了一个目录对象,并创建了一个读取和操作此警报日志的应用程序。 您可以将该目录的读取权限授予 SCOTT,而将写入权限授予 DBA ananda。
因此,请从数据库参数中删除 utl_file_dir 并使用目录对象替换此代码。
随后,您还应删除 PUBLIC 以及任何其他用户所拥有的 create directory 系统权限。
可能的影响可能的影响取决于 utl_file 程序包用于操作外部文件的频次。 如果从未使用此程序包,则可以立即删除它。如果将要使用它,则首先需要进行规划。
操作计划
1. 浏览此代码可以看到以下字符串: utl_file.fopen。
2. 收集第一个参数中的所有名称。 例如,当您看到 utl_file.fopen('/tmp'、'myfile.txt'、'W')时,请记录值“/tmp”。 浏览所有文件以获得所有目录位置。 可能有 10 个文件使用“/tmp”,有 5 个文件使用“/ftpdata”等等。
3. 以用户 SYS 的身份分别为这些目录创建一个目录对象,例如:
create directory TMPDIR for '/tmp';
4. 将这些目录授予访问它们的用户,例如:
grant read on directory TMPDIR to SCOTT;
5. 从代码中删除目录名,并使用目录对象名称替换它。 例如,行:
utl_file.fopen ('/tmp','myfile.txt','W')
将变为
utl_file.fopen ('TMPDIR','myfile.txt','W')
6. 重新编译程序。
7. 删除 PUBLIC 以及除 DBA 以外的所有用户所拥有的 create any directory 系统权限。
revoke create any directory from public;
2.2 限制 OS 验证
背景可以通过不同的方式(最常见的方式是通过数据库验证)验证 Oracle 用户。 使用 create user ananda identified by abc123 命令行创建用户后,该用户登录数据库的唯一方法就是传递它的用户 ID 和口令。
一种替带方法是操作系统验证,该方法使用以下命令行创建用户:
create user ops$ananda identified externally;
如果主机操作系统有一个名为“ananda”的用户 ID,则 Oracle 将不再检查它的证书。 它只假设该主机一定已经执行了它的验证,从而允许用户登录数据库而不必进行任何进一步的检查。
这正是问题的所在。 如果主机操作系统的验证机制比较强大,则它可能是安全的;但在某些脆弱的 OS 中,可以用户身份通过破解口令或不输入口令来进行登录:
sqlplus /
注意,以上命令缺少用户 ID 和口令 - 字符串“/”指示数据库接受用户 ID ananda 到数据库帐户 ops$ananda 的连接。
此类验证通常用于 shell 脚本,因此您不必在脚本中嵌入口令,而只需使用 sqlplus / 调用它。由于不存在口令,因此该方法不但方便而且在某种程度上比较安全。 但请注意以下情形: 在安全性薄弱的 OS 中,某人可以创建一个名为 ananda 的帐户,然后使用它登录到帐户 ops$ananda。
该帐户一定为 ops$ 么? 不一定;您可以通过设置初始化参数更改它。 在以下示例中,我已将它设置为 osauthent$。
os_authent_prefix = 'osauthent$'
可以使用以下查询找到这些用户:
SQL> select username, password from dba_users
2 where password = 'EXTERNAL'
3 /
USERNAME PASSWORD
------------------------------ ------------------------------
OPS$ANANDA EXTERNAL
OPS$ORACLE EXTERNAL
按如上所示设置初始化参数时,帐户 ops$ananda 将不起作用;相反,您需要将这些帐户(OS 验证的帐户)创建为 osauthent$ananda。 有趣的是,您还可以将它设置为 ""(空)。 这时,OS 用户 ananda 将映射到 Oracle 用户 ananda。您甚至还可以为此帐户设置口令:
alter user ops$ananda identified by oracle;
这种情况下,用户可以通过以下两种方法登录数据库:
sqlplus /
sqlplus ops$ananda/oracle
那么,这样做有什么不妥么? 先来看一看下面的情形。假设参数 os_authent_prefix 设置为 ""(空)。 在安全性薄弱的 OS 中,某人可以创建一个名为 SYSTEM 的用户并使用以下命令登录
sqlplus /
这将把该用户记录为 Oracle 用户 SYSTEM! 登录后,该用户可以执行所需的任何操作 - 创建用户、删除数据文件、查看机密数据以及大量其他操作。 看似方便的事情突然间成了一个大麻烦。
策略您可以看到,此问题只会在所出现的情况的某些组合中发生。 其中之一是 OS_AUTHENT_PREFIX 不为空,另一个是为 OS 验证的帐户设置口令。 因此,第一个需要检查的对象就是 OS 验证前缀。
SQL> select value
2 from v$parameter
3 where name = 'os_authent_prefix';
VALUE
-----------------------
ops$
如果以上查询返回空,则应制订规划来更改它。实际值并不重要,但您必须包含某个非字母字符。 这样,OS 验证的用户名将始终不会匹配实际用户。
其次,您需要确保 OS 验证的帐户应完全按照 OS 所采用的方式得到验证,并从不包含口令。例如,如果 OS_AUTHENT_PREFIX 设置为 OPS$,则您将使用以下查询查明是否设置了口令:
SQL> select username, password from dba_users
2 where username like 'OPS$%';
USERNAME PASSWORD
------------------------------ ------------------------------
OPS$ORACLE 17C96FEC14DC431F
OPS$ANANDA EXTERNAL
该查询表明用户 OPS$ORACLE 无法通过 OS 验证路由或口令路由登录。 这正是您希望避免的情况;应只存在一种验证方法。要更改 OPS$ORACLE 的验证模式,应使用:
alter user OPS$ORACLE identified externally;
该命令将 PASSWORD 列更改为 EXTERNAL。
可能的影响根据这些帐户的使用情况,这些更改的影响可能会比较广泛。 如果您拥有此类帐户的任何一个,请浏览程序以便了解如何轻松地更改它们。
操作计划
查明哪些程序正在使用 OPS$ 帐户。如果没有,则 | ||
| 检查初始化参数 os_authent_prefix如果它为空,则 | |
|
| 将它更改为 OPS$(需要重新启动数据库) |
| 检查 OPS$ 帐户的口令如果不为 EXTERNAL,则 | |
|
| 将其更改为 EXTERNAL |
如果找到一些这样的程序,则 | ||
| 检查它们是否还将该帐户用作口令(例如,OPS$ORACLE/mypass)。如果使用了口令,则删除它 - 例如,行 sqlplus OPS$ORACLE/mypass 应变为 sqlplus /。 | |
2.3 禁用远程 OS 验证
背景远程 OS 验证是一个相似的过程。 在 OS 验证中,您可以创建在本地操作系统中进行验证的用户。例如,如果 UNIX 服务器上有一个名为 ananda 的用户,而同一服务器上运行的数据库中有一个名为 OPS$ANANDA 的用户,则用户 ananda 只需发出以下命令即可登录到该数据库:
sqlplus /
该方法适用于本地用户 - 数据库运行所在的同一服务器上的用户。 但当远程服务器的用户尝试连接到此数据库时,情况将如何? 例如,假设有两个服务器 - node1 和 node2,且数据库在 node1 服务器上运行。 该数据库有一个在外部标识的用户 OPS$ANANDA。服务器 node2(而非 node1)上有一个用户 ananda。 当服务器 node2 上的用户 ananda 通过发出以下命令尝试连接到 node1 上的数据库时:
sqlplus /@node1
他能否连接成功?
答案取决于数据库初始化参数 remote_os_authent 的设置。 如果该参数设置为 TRUE,则此连接尝试将取得成功;如果为 FALSE,则不允许来自远程服务器的 OS 验证连接。 默认值为 FALSE。
为什么? 理由很充分: 在您的数据库服务器上,您可能拥有很高的安全性,因此 OS 验证的用户可能并不算是问题。 而客户端计算机则不然。 根据 OS 的不同,恶意攻击者能够在远程服务器上创建一个名为 ananda 的帐户,当该帐户连接到数据库服务器时,它可以在无需口令情况下连接到 ops$ananda。 由于您无法轻松地控制客户机,因此该功能将为您带来一个不小的漏洞。
策略此处的任务很简单。 检查该参数是否设置为 TRUE。 如果为 true,则将其更改为 FALSE,然后重新启动数据库。
可能的影响在许多数据库中,该参数可能已经设置为 FALSE。 但如果它设置为 TRUE,且某些客户机以 OS 验证的用户身份连接,则这些帐户将不起作用。您可以在进行此更改之前找到它们:
select username, machine, osuser, terminal
from v$session
where username like 'OPS$%'
/
输出可能显示类似如下的内容:
USERNAME MACHINE OSUSER TERMINAL
------------- -------------------- ------------ -----------
OPS$ANANDA PRONTANANDAT42 ananda ANANDAT42
此处我们看到,用户 ananda 已经以远程 OS 验证的用户身份从计算机 PRONTANANDAT42 登录。 此处请注意,ananda 是计算机 PRONTANANDAT42(而非数据库运行所在的服务器)中的用户。
操作计划
1. 如果某些用户使用远程验证连接,则删除他们的无口令功能。
2. 在初始化参数文件中,将 remote_os_authent 更改为 FALSE,然后重新启动数据库。
2.4 使用产品配置文件保护 SQL*Plus
背景使用 SQL*Plus 时,您可能注意到,您可以发出 host 命令转到 *nix 提示符,或发出 run 命令执行某个脚本。一个很少使用但却有可能造成致命破坏的攻击便源自此功能。 您可能编写了某个从 shell 中调用的 SQL*Plus 脚本,如下所示:
sqlplus someuser/somepass@remotedb @myscript.sql
此处的 myscript.sql 是一个先执行然后退出的 SQL*Plus 脚本文件。在该文件执行过程中,用户可以按 Control-C(或特定 OS 的 break 键序列)中断程序流。 这种情况下,用户将获得 SQL*Plus 提示符(以 someuser 的身份连接)。 在此阶段,用户几乎可以执行从 SQL*Plus 提示符中所能执行的所有操作,并因此而造成某种程度的破坏。
这是一个应立即修复的安全漏洞。
策略修复方法很简单: 您所要做的就是在运行命令之前,将这些命令限制到一个由 SQL*Plus 引用的“特殊位置”。 此特殊位置是 SYSTEM 模式中一个名为 SQLPLUS_PRODUCT_PROFILE 的表。 如果该表不存在,则您在每次启动 SQL*Plus 时将获得一个类似“Product User Profile Not Loaded”这样的警告。
SQL> select * from system.SQLPLUS_PRODUCT_PROFILE
2 /
no rows selected
SQL> insert into system.SQLPLUS_PRODUCT_PROFILE
2 values ('SQL*Plus','%','HOST',null,null,'DISABLED',null,null)
3 /
1 row created.
SQL> commit;
Commit complete.
现在,当您启动 SQL*Plus 并输入 host 命令(或它的等价形式“!”)时,您将收到以下错误:
SQL> host;
SP2-0544: Command "host" disabled in Product User Profile
如果要对某个用户禁用此功能,只需使用要限制的用户名替换上面的 insert 命令中的“%”(表示所有用户)。 例如,如果只希望对用户 SCOTT 禁用此功能,请使用以下语句:
SQL> insert into system.SQLPLUS_PRODUCT_PROFILE
2 values ('SQL*Plus','SCOTT','HOST',null,null,'DISABLED',null,null)
3 /
还可以在用户名中使用通配府 - 例如,使用 APP% 表示所有以 APP 开头的用户(APPUSER1、APPUSER2)。
该方法也适用于其他命令(及其缩写或简写形式):
accept edit repheader
append execute run
archive log exit save
attribute quit set
break get show
btitle help shutdown
change host spool
clear input start
column list startup
compute password store
connect pause timing
copy print ttitle
define prompt undefine
del recover variable
describe remark whenever oserror
disconnect repfooter whenever sqlerror
除了 SQL*Plus 以外,该方法还适用于 SQL 命令。 例如,如果要禁用 lock 命令,则需要插入:
insert into system.SQLPLUS_PRODUCT_PROFILE
values ('SQL*Plus','%','LOCK',null,null,'DISABLED',null,null)
/
注意,SQL 命令 lock 已被禁用,此外我们还在上面使用了“SQL*Plus”关键字。
可以禁用的 SQL 命令如下:
alter drop revoke
analyze explain rollback
associate flashback savepoint
audit grant select
call insert set constraints
comment lock set role
commit merge set transaction
create noaudit truncate
delete purge update
disassociate rename validate
可能的影响开始前,请注意一个重要问题: 该方法适用于在服务器本身中运行的 SQL*Plus, 而不会影响在其他位置运行(如在客户端中运行)的 SQL*Plus。
该操作需要仔细的规划。 如果 shell 脚本依赖于 SQL*Plus 中的 host 命令,则禁用它们将会明显停止这些作业。 一个非常典型的例子就是旧式的 host backup 命令。 一个典型的 SQL 脚本可能如下所示:
alter tablespace xyz begin backup;
host cp /fs1/xyz.dbf /backup/xyz.dbf
alter tablespace xyz end backup;
等等(适用于所有表空间)。 该脚本将注定失败 - 除非以 SYS 用户的身份运行它,这时命令禁用将不起作用。
操作计划当所有这些命令使用的可能性最小时,从 SQL*Plus 中禁用它们。
2.5 控制 SQL*Plus
背景根据 SQL*Plus 脚本用法的不同,您可能会也可能不会受到前面描述的威胁。 无论在哪种情况下,采取预防性措施降低威胁级别都是很有好处的。方法之一是按照前面所述在产品配置文件中禁用命令,而自从 Oracle9i 数据库推出后,一个更简单的可用方法是使用 SQL*Plus 限制。 在该方法中,您必须使用一个新参数 restrict 调用 SQL*Plus。 限制分多个不同的级别。 级别 1 只禁用 host 和 edit 命令。
sqlplus a
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/178357/viewspace-910002/ ,如需转载,请注明出处,否则将追究法律责任。