下面是一个示例输出: USERNAME OS_USERNAM TERMINAL USERHOST LOGON_TS
--------------- ---------- --------------- --------------- ------------------
ABCD_APP jnelson STJNELSONT40 STJNELSONT40 01/11/06 10:42:19
ABCD_APP jnelson STJNELSONT40 STJNELSONT40 01/11/06 10:42:28
ABCD_APP jnelson STJNELSONT40 STJNELSONT40 01/11/06 10:43:11
PERFSTAT oracle pts/5 stcdwhpd 01/11/06 12:05:26
ARUP jnelson STANANDAT42 STJNELSONT40 01/11/06 14:09:20
ARUP jnelson STANANDAT42 STJNELSONT40 01/11/06 14:23:41
在该输出中,您可以清楚地看到哪个用户曾尝试使用错误口令进行连接。许多尝试可能属于正常的错误,而其他尝试可能需要调查。例如,OS 用户 jnelson 在短时间内从同一客户机以 ABCD_APP 的身份重复尝试登录并失败。紧接着,jnelson 尝试以用户 ARUP 的身份登录。现在,这一点比较可疑。注意,由于大多数攻击均来自企业内部的合法用户,因此任何模式都不值得掩盖。
在相同代码行中,您可以监视使用可能已“猜中”的用户 ID 尝试进行的登录。 select username from dba_audit_trail where returncode = 1017
minus
select username from dba_users;
输出如下: USERNAME
---------------
A
SCOTT
HR
此处,某人尝试以不存在的用户身份(即 SCOTT,您已经审慎地从数据库中删除了该用户)登录。该用户的身份到底如何呢?他是错误地期望连接到开发数据库的无恶意用户,还是试探 SCOTT 是否存在的恶意用户?请再次搜索模式并标识进行此尝试的实际用户。直到您获得满意的解释为止。 可能的影响 打开审计确实会影响性能。但您在该步骤中启用的初级审计对性能的影响可以忽略不计,它的好处远远超过了不利影响。
另一个应仔细考虑的影响是审计跟踪的存储空间。审计跟踪条目存储在 SYSTEM 表空间中,其大小随审计跟踪的扩大而扩大。如果 SYSTEM 表空间已经占满并且没有可供审计记录使用的空间,则所有数据库交互将失败。因此,必须仔细留意可用空间。 操作计划
- 将初始化参数 audit_trail 设置为数据库中的 DB 并重新利用它。
- 对会话启用审计。
- 从审计跟踪中提取信息并根据这些信息分析攻击模式。
3.6 创建和分析对象访问配置文件 背景 只知道用户名和相关属性(如 OS 用户名、他们的连接源自的终端等)是不够的。要正确锁定数据库,还必须知道哪些用户正在访问。您可以通过此信息创建一个对象“访问配置文件” - 凡是不符合该信息的内容均可能表示攻击或入侵,
策略 此处将再次使用审计的强大功能。在上一步中,您启用了用于查看会话详细信息的会话级审计。现在,您必须启用对象访问审计。
例如,您可以选择对非常机密的对象(如存储信用卡卡号的表或通过加密值返回明文信用卡卡号的属性)进行的访问进行审计。
假设您要对访问 ccmaster 拥有的表 credit_cards 的任何用户进行审计。您可以发出以下命令 audit select on ccmaster.credit_cards by access;
随后,任何从该表中进行选择的用户将留下一个审计跟踪。
您可以采用两种方法记录该信息。在第一种方法(如上面的关键字 access 所示)中,每当某个用户从表中进行选择时,审计跟踪中便会出现一个记录。如果同一用户在同一会话中从表中选择两次,则审计跟踪中将出现两个记录。
如果该信息量太大,无法处理,则可以使用另一个方法,即在每个会话中只记录一次: audit select on ccmaster.credit_cards by session;
在该示例中,当用户在会话中从表中进行多次选择时,审计跟踪中将只出现一个记录。
启用审计后,可以分析审计跟踪以了解访问模式。
在每个方法中,审计跟踪均呈现不同的状态。如果会话启用了审计,则每个对象的每个会话中将只显示一个记录。该示例中的 action_name 列将显示 SESSION REC,且操作将记录到 ses_actions 列中。 select username, timestamp, ses_actions
from dba_audit_trail
where obj_name = 'CREDIT_CARDS'
and action_name = 'SESSION REC'
/
输出结果如下: USERNAME TIMESTAMP SES_ACTIONS
------------------------------ --------- -------------------
ARUP 16-JAN-06 ---------S------
当然,您还可以使用其他列,如 os_username、terminal 等。
注意,ses_actions 列显示了一系列的连字符和一个字母“S”。这表示用户 ARUP 执行了某些操作,这些操作记录在审计跟踪的单个记录中。值遵循某个模式,其中的每个位置均表示一个特定操作:
|
位置 |
操作 |
|
1 |
更改 |
|
2 |
审计 |
|
3 |
注释 |
|
4 |
删除 |
|
5 |
授权 |
|
6 |
索引 |
|
7 |
插入 |
|
8 |
锁定 |
|
9 |
重命名 |
|
10 |
选择 |
|
11 |
更新 |
|
12 |
引用 |
|
13 |
执行 |
|
14 |
未使用 |
|
15 |
未使用 |
|
16 |
未使用 |
在以上示例中,ses_actions 显示了以下内容: ---------S------
“S"”位于第 10 个位置,表示用户 ARUP 从表 credit_cards 中进行了选择。但它并未显示用户在此会话中从该表进行选择的频率,这是因为您只对会话而非访问启用了审计。如果用户还在查询中执行了插入和更新操作,则列值将为: ------S--SS-----
注意,第 7 个位置 (Insert)、第 10 个位置 (Select) 和第 11 个位置 (Update) 分别有一个 S。
为什么会显示“S”?启用审计时,可以指定在访问成功或失败时是否记录跟踪。例如,如果只在访问由于某种原因(如权限不足)而失败的情况下记录审计跟踪,可以按如下所示启用审计。 audit select on ccmaster.credit_cards by session whenever not successful;
随后,当用户 ARUP 成功地从表中进行选择时,审计跟踪中将没有记录。如果访问失败,则将有一个记录。这种情况下,ses_actions 列中的字母将为“F”(表示失败)。
同样,如果只想在访问成功时进行审计,请将子句“whenever not successful”替换为“whenever successful”。默认情况下,如果未指定该子句,则将同时记录成功和失败的访问。那么,如果在单个会话中,某些访问成功,而其他访问失败,则将出现什么情况?这种情况下字母将为“B”(表示成功和失败)。
例如,下面演示了对于用户 ARUP(他没有表 credit_cards 的选择权限)而言,字母值如何随时间而更改。
- ARUP 执行命令语句 select * from CCMASTER.CREDIT_CARDS。
- 该语句失败,从而引发 ORA-00942:table or view does not exist。
- 审计跟踪中出现一个记录,且 ses_actions 值为 ---------F------。(注意,“F”位于第 10 个位置,表示失败。)
- ARUP 未与会话断开连接。表 credit_cards 的拥有者 CCMASTER 将 select 权限授予 ARUP。
- ARUP 现在成功地从表中进行选择。
- ses_action 列值现在将更改为 ---------B------。(注意,第 10 位置已从“F”更改为“B”(成功和失败)。)
对该对象进行了一段时间的审计并开发了它的访问配置文件后,可以针对成功尝试关闭审计,并仅针对失败尝试启用审计。表示潜在攻击的通常是失败尝试。只对失败尝试进行审计还将降低审计跟踪的总长度。
如果按访问启用了审计,则可能使用了一个不同的查询,这是因为每个访问将有一个记录。ses_actions 列将不被填充,而 action_name 列将显示实际操作(如 select 或 insert)而非值 SESSION REC。因此,您将使用: col ts format a15
col username format a15
col userhost format a15
col action_name format a10
select to_char(timestamp,a�?mm/dd/yy hh24:mi:ssa�?) ts,
username, userhost, action_name
from dba_audit_trail
where owner = 'CCMASTER'
and obj_name = 'CREDIT_CARDS';
TS USERNAME USERHOST ACTION_NAM
----------------- ---------- --------------- ----------
01/16/06 00:27:44 ARUP stcdwhpd SELECT
01/16/06 11:03:24 ARUP stcdwhpd UPDATE
01/16/06 12:34:00 ARUP stcdwhpd SELECT
注意,每个访问(select、update 等)均有一个记录,这将为您提供更高的粒度来建立访问模式 - 这与会话级审计相反,该审计只显示 ARUP 从表 credit_cards 中执行了选择和更新操作,但未显示操作次数或时间。
既然如此,应使用哪种类型的审计 - 会话级还是访问级?注意,由于访问级审计针对每个访问写入一个记录,因此写入的审计信息数量明显大于每个会话只写入一个记录时的信息数量。如果只尝试确定表的访问用户和访问方式,则应先打开会话级审计。这将使您可以了解用户如何访问每个对象。要跟踪特定用户的错误使用,可以打开访问级的审计。 可能的影响 根据前面的描述,审计不会影响性能。但审计的好处可能远远超过不利影响,尤其是当您巧妙地启用它时。此外,您不必始终打开它;您可以根据需要动态打开或关闭对象审计。
操作计划
- 在不审计所有对象的情况下,标识要审计的主要对象(表、程序包、视图)
- 对这些对象打开会话级审计。
- 一段时间之后(您认为该段时间代表典型的工作周期),分析审计跟踪。等待收集记录的时间通常取决于特定情况。例如,在零售业中,您可能要等待一个月的时间,在这段时间内通常会捕获所有过程,如月终处理、帐目汇总等。
- 开发配置文件后,请跟踪失败尝试。记录用户以及他们尝试访问的对象。
- 关闭会话级审计并只对这些对象打开访问级审计。
- 通过突出显示失败尝试、时间、尝试源自的终端等信息来分析访问模式,并确定尝试失败的原因。如果没有合理的原因,请将该尝试视为潜在的安全漏洞。
3.7 对未来对象启用审计
背景 到现在为止,您已经了解了如何针对特定的机密对象使用审计。您还可能决定对所有对象而非对象子集启用审计 - 您并不知道哪些对象是机密对象,也许它们全部是机密对象。这种情况下,将出现如下问题:不断在数据库中创建对象,并在对象物化时,您必须记住对它们启用审计。
策略 默认审计在此处非常有用。要对任何尚未创建的对象启用审计,请执行以下命令: audit select on default by session;
随后,当您在任何模式中创建表时,将对该表的 select 自动启用审计选项。要检查在数据库中当前设置的默认审计选项,请执行以下语句: SQL> select * from all_def_audit_opts;
ALT AUD COM DEL GRA IND INS LOC REN SEL UPD REF EXE FBK REA
--- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
-/- -/- -/- -/- -/- -/- -/- -/- -/- S/S -/- -/- -/- -/- -/-
注意 SEL 列下有一个值“S/S”。左侧值表示操作成功时的审计选项。此处该值为“S”,表示“会话级”。右侧部分指示操作何时失败,值也显示为“S”(也表示会话级)。由于您未指定应何时执行审计,从而为成功和失败设置了选项 - 因此值为“S/S”。
假设您要在成功时在会话级以及在失败时在访问级对 select 启用默认审计。您将执行下面的语句: SQL> audit select on default by session whenever successful;
Audit succeeded.
SQL> audit select on default by access whenever not successful;
Audit succeeded.
现在,如果您查看默认选项,则将看到以下语句: SQL> select * from all_def_audit_opts;
ALT AUD COM DEL GRA IND INS LOC REN SEL UPD REF EXE FBK REA
--- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
-/- -/- -/- -/- -/- -/- -/- -/- -/- S/A -/- -/- -/- -/- -/-
此处,请注意列 SEL,该列显示“S/A” - 表示在成功时为会话级(“S”,位于“/”的左侧),在失败时为访问级(“A”,“/”的右侧)。
当您要限制成功访问下的审计条目数时,这样的安排将比较常见,因此对成功访问启用会话级审计。但由于您要跟踪出现的每个失败访问,因此对失败启用了访问级审计。
要禁用默认审计,请执行以下语句: noaudit select on default;
稍后,您应签入 all_def_audit_opts 视图以确保实际上关闭了默认审计选项。 可能的影响 在许多审计中,始终存在性能方面的问题,但针对其中包含的信息而言,代价可能比较小。
但其中也存在一个潜在的危险。由于对随后创建的所有对象均启用了默认审计而与创建它们的用户以及从中进行选择的用户无关,因此作为 DBA 的您将无法控制表的审计选项。恶意攻击者可能会利用这种情况,他可以随意创建对象、插入到对象中、从对象中进行选择,并最终删除对象 - 而所有这些操作恰好在表空间级强制使用的份额中发生。
但由于对每个创建的对象均打开了审计,因此审计跟踪中的记录不断增多,并最终填满 AUD$ 表。由于该表位于 SYSTEM 表空间中,因此它最终将被填满并终止数据库,这实际上相当于创建了一个拒绝服务攻击!
尽管这种情况很少出现,但却完全有可能出现。幸运地是,防范方法比较简单:只需密切监视 SYSTEM 表空间。如果空间很快耗尽,请调查一下审计记录的创建为何如此之快。如果看到大量创建或选择的对象,而这些对象并不属于使用审计构建的配置文件,则必须进行调查。
作为一个立杆见影的措施,您可以关闭默认审计,然后关闭对那些填满审计跟踪条目的对象的审计(可以联机执行)。然后,在将其存储到其他表空间中的某个表之后,您应删除审计跟踪中的记录以便将来分析。 操作计划
- 确定执行哪些操作来启用默认审计。
- 确定所需的默认审计级别 - 会话级或访问级。
- 启用默认审计。
3.8 只限制来自特定节点的访问
背景 在许多情况下,只有指定的客户机集将连接到数据库服务器。以下是一个典型的体系结构:
此处,数据库服务器为 findb01 和 hrdb01,且数据库名为 FINDB(财务数据库)和 HRDB(HR 数据库)。HR 部门中的客户机只连接到 HRDB;如果它们需要 FINDB 中的某些数据,则连接到在财务部门的服务器上运行的应用程序并获取数据。同样,财务部门中的应用服务器从不直接连接到 HRDB。
如果财务部门中的客户机 finas01 尝试连接到 HRDB,则将出现什么情况?只要它知道有效的用户 ID 和口令,便可以成功连接。通常,您应保护用户的口令,但有时存在一些使用已知口令的普通用户。例子包括使用不安全口令(如“hrapp”、“password”甚至“abc123”)的应用程序用户。即使实施了口令管理策略(如第 4 阶段所述),口令仍有可能是为人所熟知的。
因此,必须在服务器周围构建一个防护墙,以防计算机授权列表以外的客户机连接到这些服务器。 策略 如何确保只允许来自 HR 部门的客户连接进入数据库 HRDB?方法有两种,即登录触发器和监听器节点验证。
登录触发器。在该方法中,您将创建一个触发器,它在登录时引发,检查 IP 地址,然后当 IP 地址不在允许的计算机列表中时失败。此触发器如下所示: 1 create or replace trigger valid_ip
2 after logon on database
3 begin
4 if sys_context('USERENV','IP_ADDRESS') not in (
5 '100.14.32.9'
6 ) then
7 raise_application_error (-20001,'Login not allowed from this IP');
8 end if;
9* end;
在第 5 行中,您可以设置有效客户机的所有 IP 地址(括在引号中并由逗号分隔)。在此触发器生效后,当 SCOTT 尝试从触发器列表以外的 IP 地址连接时: $ sqlplus scott/tiger@hrdb
ERROR:
ORA-00604:error occurred at recursive SQL level 1
ORA-20001:Login not allowed from this IP
ORA-06512:at line 5
注意错误 ORA-20001:Login not allowed from this IP,该错误置于触发器中。您可以根据需要使此消息具备说明性。还可以使触发器更强大,以收集有用信息(如将类似尝试记录在表中)。
但请注意一个非常重要的问题:由于登录触发器不会对 DBA 用户触发,因此不要在启用 DBA 角色的情况下禁止某人以用户身份登录。该风险并非想象那样恐怖;实际上,您可能需要让 DBA 从任何客户机登录。
监听器节点验证。另一个方法是在监听器本身禁用登录尝试。监听器禁止指向数据库服务器的连接尝试,因此并不需要触发器。要启用节点验证,只需在服务器 hrdb01 上的文件 $ORACLE_HOME/network/admin/sqlnet.ora 中设置以下行。 tcp.validnode_checking = yes
tcp.invited_nodes = (hrdb01, hras01, hras02)
此处,您已经指定了允许连接到监听器的客户机(hras01 和 hras02)。还可以将主机名指定为 IP 地址。将所有节点名称置于由逗号分隔的单个不中断行中(非常重要)。别忘了添加数据库服务器名称 (hrdb01)。
重新启动后,如果客户端尝试从 hras01 或 hras02 以外的计算机登录,则将收到错误 $ sqlplus scott/tiger@hrdb
ERROR:
ORA-12537:TNS:connection closed
这个非常不直观的错误是由在监听器级发生的过滤导致的。当监听器本身终止连接尝试时,您将收到 connection closed 错误。即使用户具有 DBA 角色也会出现该错误,这是因为该尝试尚未到达数据库。
节点验证是一个非常强大的特性。有关该特性的详细信息,请阅读我撰写的 DBAzine 文章“使用 Oracle Net 构建一个简单的防火墙”。
因此,您应选择哪个方法来防止多余的客户端连接?下面我们将介绍一下这两个方法的优点和缺点。
- 节点验证在监听器级进行,因此将禁止所有用户连接 - 即使具有 DBA 角色的用户也不例外。而这可能并不是所需的。例如,如果您在台式机上安装了一个 DBA 工具并且您的台式机启用了 DHCP(每当该台式机连接到网络时将分配一个新的 IP),则无法将 IP 地址置于有效节点列表中;因此,您将无法连接。
- 节点验证需要重新启动监听器。监听器将在短时间内关闭,因此客户端将无法连接。尽管这可能算不上是问题,但您应该注意它。每当更改有效节点列表时,您必须要重新启动监听器。
- 如果要临时禁用节点验证,则应将 tcp.valid_node_checking=no 置于文件 sqlnet.ora 中并重新启动监听器。对于登录触发器而言,您所要做的就是禁用触发器。您可以在需要时重新启用它。
- 在节点验证中,可以将所有允许的客户端置于一行中,但只能置于一个不中断行中。如果该列表太长无法放在一行中,则您将无法使用该方法。而触发器方法几乎没有限制。您也可以使用另一个名为连接管理器的特性来限制长度超过一行的 IP 地址。
- 必须在节点验证中使用特定 IP 地址或主机名 - 不要使用“10.20.%.%”这样的通配符,因为它们表示子网 10.20 中的所有客户端。在触发器方法中,您可以使用通配符也可以使用连接管理器。
- 通过触发器方法,您可以构建一个复杂的跟踪系统,以针对所有尝试(成功或被拒绝)写入某个跟踪表。而节点验证中不存在这样的功能。
- 在触发器方法中,您可以根据 IP 以外的参数(如一天中的某个时间、用户连接等)控制访问。节点验证只读取 IP 地址。
- 注意,节点验证禁止监听器级的尝试;而数据库连接尚未尝试。因此,如果已经针对失败的尝试启用了审计,则它们将不被注册。
- 由于节点验证在监听器级别起作用,因此潜在的恶意攻击者甚至不会进入数据库,从而使拒绝服务攻击变得更困难。这对节点验证而言是一个巨大的好处。
您在考虑以上差别后应确定方法。通常情况下,如果您的目标只是禁止来自 IP 地址的连接,而不使用任何其他功能(如跟踪这些失败的尝试),则节点验证是一个快速、简单的方法。如果需要更复杂的功能,则应查看登录触发器。
如何知道要阻止哪些 IP 地址以及允许哪些 IP 地址?也许此假设太简单;实际上,客户机的列表将很长并很难攻击。在此处使用前面的调查将比较方便。注意,在第 2 阶段,您通过查看监听器日志捕获了用户连接源自的 IP 地址。在该步骤中,您一定已经生成了一个有效的客户端 IP 地址或主机名列表。该列表就是您需要知道的。
可能的影响 可能的影响可能比较严重;如果尚未执行您的操作,则可能阻止合法客户端。
操作计划
- 从第 2 阶段的第 1 步中,获得客户机的有效 IP 地址或主机名的列表。
- 确定要使用的方法 - 基于触发器或节点验证。
- 实施该计划。
- 密切监视几天,最好是整个周期(如一个月或一周),这对您的企业比较适合。
- 通过添加或删除过滤的节点微调该方法。
(编辑:aniston)
|