一、说明
本篇文章主要说一下Oracle数据库中身份鉴别控制点中a、b、c测评项的相关知识点和理解,以及一些其他的东西。
二、测评项
a)应对登录的用户分配账户和权限;
b)应重命名或删除默认账户,修改默认账户的默认口令;
c)应及时删除或停用多余的、过期的账户,避免共享账户的存在;
三、测评项a
a)应对登录的用户分配账户和权限;
3.1. 要求1
如果从字面意思来看,就是一个废话,用户都登录账户了,自然就存在着账户。
这里的意思是应该是你本来就存在“多个账户”,然后当用户使用时要适当的“分配账户”给用户,而账户再拥有不一样的权限,这样就实现了将权限通过账户分配给用户(自然人)。
所以,该测评项就需要Oracle中存在至少两个账户,且这两个账户的权限不一样。
3.2. 要求2
在测评要求中测评实施如下:
在Oracle中默认用户挺多的,最常用的就是SYS和SYSTEM这两个账户,对于它们以及其他的一些默认账户,实际上没有什么好限制的,如果需要使用,按照实际情况使用就行了。
需要值得关注的是PUBLIC,不过实际上PUBLIC既不是角色也不是用户,但是如果你把某权限赋予给PUBLIC,那么所有的数据库用户都会具有这个权限。
PUBLIC肯定不是用户:
SQL>?select?*from?dba_users?where?username='PUBLIC';
no rows selected
PUBLIC也不会出现在dab_roles表中:
SQL>?select?*from?dba_roles?where?role='PUBLIC';
no rows selected
不过它确实存在于USER$表中:
Oracle官方文档解释如下:
大概就是说Public角色无法删除,手动将其授予给某用户或者从某用户上将其撤销都没有任何意义,由于所有数据库用户都承担PUBLIC角色,因此它不会出现在DBA_ROLES 和 SESSION_ROLES表中。
不管PUBLIC到底是什么,我们知道它属于每一个数据库用户就行了。
默认状态下,PUBLIC会拥有很多的权限,其中和UTL有关的就有不少:
如果你使用某扫描工具扫描,扫描报告里会指出这属于高危漏洞:
所以理论上是最好将这些(UTL_SMTP、UTL_TCP、UTL_HTTP以及UTL_FILE)的相关权限从PUBLIC上撤销掉。
不过最好还是给整改人员提醒下(测评人员基本上不插手整改,顶多做出一些说明),根据实际情况做出整改:
大概就是说由于PUBLIC的权限由所有用户所共有,撤销掉PUBLIC的权限可能会引起严重的级联效应,所以要小心。
为oracle安全加固引发的血案
四、测评项b
b)应重命名或删除默认账户,修改默认账户的默认口令;
对于默认账户如SYS等,可能重命名比较麻烦,所以修改其默认口令应该就可以了。
默认口令如下(没实际验证过,大概率对的,因为网上说的都一样):系统默认ORACLE用户及口令
在Oracle 11G中,增加了个新特性,可以直接查询出使用默认口令的用户:
核心就是这个DBA_USERS_WITH_DEFPWD视图,只有一列,存放的是使用默认口令用户的用户名:
原理我猜就是oracle自己拿着默认口令去对比,发现使用默认口令的用户名就记在这个视图中,反之,不使用默认口令了,就不记入视图中。
所以如果你修改了口令,但是还是用的默认口令(也就是只是更新了口令修改的时间,内容没变),或者你用了新口令,后来又改回默认口令了,不会影响这个视图的效果:
比如我用下面的SQL语句刷新了下DBSNMP的口令修改时间:
alter?user?DBSNMP?identified?by?DBSNMP;
查询DBA_USERS_WITH_DEFPWD,DBSNMP还是在里面的:
网上有关这个视图的解释有点会造成歧义,或者没说清楚,可能会造成DBA_USERS_WITH_DEFPWD是以口令修改时间是否刷新来判断:
五、测评项C
c)应及时删除或停用多余的、过期的账户,避免共享账户的存在;
这大概没有什么需要特别说明的,每个账户是否有自己的用途,这个要通过实际查询账户具备的权限以及访谈来确定。
具体用哪些SQL语句查询出账户拥有哪些权限,放在之后的几个测评项中说。
六、提出的整改建议要符合实际
虽然按照等级保护的工作流程,整改在测评之前,测评机构主要只负责测评,但实际工作中还是会涉及到整改方面的内容,特别是在测评报告中也需要写出整改建议。
那么在提出整改建议的时候,如果写得详细的话(比如直接涉及到参数),那么最好还是要好好考虑,不要犯一些低级错误。
口说无凭,我举几个简单的例子。
6.1. SqlServer的C2跟踪审核
在测评能手中在SqlServer的安全审计控制点中提到了C2跟踪审核,开启之后,几乎会记录数据库的每一个操作。
开启的位置:
会记录数据库的每一个操作,但是不知道为什么,具体到updat语句的时候就比较奇怪了,涉及的sql语句中,具体的值不知道,以变量名代替,比如不知道下面@1和@2到底是什么值:
但是由于每个操作都记录,所以会大量的占用资源,下面的trc就是记录文件,记录文件一天生成一个,以当天的日期为文件名,如果一天之内的记录大小超过200M,就添加序号,生成新的。
我个人电脑上,根本就没有业务,顶多我自己试验一些sql语句,结果记录文件就有这么多,如果真的存在业务的话,我看记录文件直接能占满磁盘空间,性能方面的损耗也不会小。
也就是说,这个选项开启的目的,只能是短期内对sql语句进行核查、检查、审计等,而不能够作为长期对数据库进行审计的手段!
如果照搬测评能手给出这种整改建议的话,画面太美我不敢想象……
这并不是我自己杞人忧天,我在搜索C2跟踪审核的时候居然发现了这样的内容:
大家是不是觉得有点黑色幽默……
6.2. Mysql自带的审计功能
也就是Mysql的general_log选项,开启后好像会记录所有关于mysql的sql语句
你有没有发现Mysql自带的这个审计功能的相关参数太少?只有那么三四个(具体几个我没数,但是很少就是了),和其它的审计插件或者服务器审计功能的相关参数相比是不是少了一些关键的参数。
Mysql自带这个审计功能没有关于记录文件轮询以及文件最大值的限制!
也就是说,你开启general_log选项后,文件只会越来越大,没办法直接进行日志轮询以及文件最大值的设置。
所以同样的,你直接在整改建议中叫被测评机构开启这个选项,虽然可能没C2跟踪审核那么夸张,但是也强不到哪去。
七、SQLServer的空口令查询
注意,不同版本可能效果不一样,请先自行实验。
如果SQLserver没有设置什么口令策略,那么对于数据库用户,是可以设置空口令的。
当然,想要判断某用户是不是空口令,一个最简单的方法就是直接挨个使用空口令去登录。
但是能不能直接从数据库表中查询出空口令呢?
按照一般的思路,我们先设置一个空口令用户,然后去查看其口令字段,然后看看是不是有什么特殊值,比如空字符串、null之类的,这样下次就能直接对比了。
但结果有点奇怪,设置了两个空口令用户,两个的口令字段都有值,而且还不一样:
嗯,其实也没啥奇怪的,有些加密算法可以实现相同的明文生成不一样的密文,一个最简单的例子,你在生成密文的时候挑选一些位数,设定其是无效字符串,然后放一些随机字符进去,不就是一个最简单的方案吗?
当然,实际的算法比我想的肯定复杂多了,而且SQLServer用的应该是哈希算法,不可逆,我也懒得去管它怎么实现的了,解决问题更重要。
在不了解其内部算法的情况下,想要判断出给出的口令的哈希值的原文是不是空字符串,就只能依靠SQLServer自带的函数了,还真被我找到了。
注意看这一段:
也就是PWDCOMPARE这个函数可以将哈希值同某字符串进行对比,判断出哈希值的明文是否等于某字符串。
实际测试是可以的,结果如下:
从这一点扩展的话,如果你想自己判断SQLServer里是否存在弱口令的话,如果使用用扫描工具,你可以自己写一些存储过程什么的来进行判断。
八. 测评项
d)应授予管理用户所需的最小权限,实现管理用户的权限分离;
e)应由授权主体配置访问控制策略,访问控制策略规定主体对客体的访问规则;
f)访问控制的粒度应达到主体为用户级或进程级,客体为文件、数据库表级;
g)应对重要主体和客体设置安全标记,并控制主体对有安全标记信息资源的访问。
九. oracle的权限结构
在数据库权限方面,对方很可能完全不清楚某用户是用来干什么的,或者容易给出错误的判断。
所以实际上,这个控制点下的测评项,依靠用户访谈的得出的结论可靠性极差。
所以,掌握Oracle的基本权限方面的知识,在不依靠用户访谈的情况下,能够判断出某用户的大概用途,从而合情合理的写在结果记录里,是很有必要的。
9.1. 特殊角色、特殊权限
这里就存在一个和其它数据库不大一样的地方,比如SqlServer,我要启动SqlServer,用命令行也好,用图形化界面也好,我只要在windows中把SqlServer的相关服务启动起来就可以了。
但是在oracle这里,却需要使用oracle数据库中的用户去连接它然后启动它。
所以这里就会存在一种特殊的数据库的角色,它可以在数据库没有启动的时候,对数据库执行一些操作,比如启动数据库,也可以关闭数据库。
同时必然的,对于属于这列特殊角色的用户,它的身份验证和权限判定肯定不是依靠数据库中相关字段的对比(因为数据库没启动前,无法查询到表中的数据)。
这里的角色主要包括sysdba和sysoper
那么由于其角色身份的认定信息不是存储在数据库中,而是存储在密码文件中,在linux中,这个文件在$ORACLE_HOME/dbs/目录中,以orapw开头,其内容是加密的:
通过查询这个文件,可以知道哪些用户拥有相关的特殊角色:
这里就能看到,口令文件中仅存在SYS用户,且SYS用户同时拥有sysdba和sysoper角色。
至于具体它拥有的是sysdba还是sysoper角色的情况,要看它每次登录的时候的连接语句是如何写的,如:
sqlplus /?as?sysdba;
连接语句中可以在最后加一个关键词as,即以什么样的角色登录数据库,as后面可以跟三个单词,分别是sysdba、sysoper、normal。
这里有三种情况:
- 不加as关键词、as normal是一个意思,即以数据库内的普通的用户身份登录,这个时候你拥有什么权限,就是看你在数据库内有哪些权限了;
- as sysdba,那么你就是以sysdba这个特殊角色的身份登录数据库;
- as sysoper,那么你就是以sysoper这个特殊角色的身份登录数据库。
注意,同样一个用户如sys用户,使用as sysdba,那么它就具有sysdba的权限,但是如果使用as sysoper,那么它就具有sysoper的权限(相较于sysdba权限大幅下降了)。
9.2. 普通角色、普通权限
权限大概也分成两种,一种是启动数据库、关闭数据库这类权限,一种就是普通的数据库的权限了(如查询、创建表等权限)。
如果说普通数据库的权限的话,以sysdba的身份登录,从普通权限的角度说,因为它是sys用户,则它具备dba角色的权限,以sysoper的身份登录,则它则具备public的权限。
注意,dba角色拥有数据库内的绝大部分的权限(是不是拥有所有权限不清楚,反正就是权限最高的一个角色)
以sysoper的身份登录,使用show user,结果是public
SQL> show user;
User?is?"PUBLIC"
sys和system都拥有dba角色:
9.3. 普通权限的结构
Oracle的权限结构是这样的,某一个权限可以直接授予给某一个角色或用户,某个角色也可以授予给某个角色或用户(被授予的角色或用户就拥有这个角色的所有权限了)。
数据库内,权限分成两种,一种是系统权限,一种是对象权限。
9.4. 普通权限中的系统权限
系统权限就是创建表、创建索引这类权限。
查询某用户或某角色的所拥有的被直接授予的系统权限的语句如下(这里查询的是sys用户):
select?*?from?dba_sys_privs?where?grantee='sys'?ORDER?BY?GRANTEE
grantee:被授权的用户或者角色,如图中的dba
privilege:具体的授予的系统权限
admin_option:即在使用授权语句时,是否使用了with admin option关键词,如果使用,则代表被授予该权限的用户或者角色,可以将被授予的这个权限再次授予给其它的用户或角色
注意,这个表仅代表某一个权限可以直接授予给某一个角色或用户的结果,如将dba角色授予给某用户X,那么在dba_sys_privs表中,仅会存在X用户被直接授予的系统权限行,而并不会存在通过拥有dba继承的权限行。。
Oracle中拥有很多方便使用者查询当前用户信息的视图,通常以user开头,比如可以查询user_sys_privs,他会显示当前用户(sys用户,我使用sys用户登录)所拥有的被直接授予的系统权限
select?*?from?user_sys_privs;
查询某角色或某用户拥有的角色,语句如下(这里查的是sys用户):
select?*?from?dba_role_privs?where?grantee='SYS'??ORDER?BY?GRANTEE
grantee:被授予角色的用户或者角色,如图中的dba
granted_role:具体授予的角色
admin_option:具体意思和dba_sys_privs表的解释差不多,如果为YES,则应该代表授予的角色以及这个角色拥有的权限都可以再授予给其他角色或用户
default_role:代表是否为默认角色,如果是则代表正常,如果不是,则被授予者不默认拥有授予的角色,每次需要显示的开启,具体大家可以百度搜索下
同样,可以查询user_role_privs视图,它会显示当前用户拥有的角色(还存在session_roles视图,其与user_role_privs的区别在下文进行说明):
9.5. 查询某用户拥有的全部系统权限
结合dba_sys_privs、dba_role_privs,查询某个用户拥有的所有的系统权限(包括直接授予、间接授予),语句如下:
SELECT?*
FROM?DBA_SYS_PRIVS
WHERE?GRANTEE =?'SYS'
UNION?ALL
SELECT?*
FROM?DBA_SYS_PRIVS
WHERE?GRANTEE?IN
(SELECT?GRANTED_ROLE?FROM?DBA_ROLE_PRIVS?WHERE?GRANTEE =?'SYS');
你将某角色A赋予给某用户B,同时又直接将某权限a直接赋予给某用户B,如果角色A也拥有a权限的话,那么这里会查出重复的权限。
同样,也可以查询session_privs,它会显示当前用户被激活可使用的所有的系统权限(包括直接授予、间接授予):
select?*?from?session_privs?order?by?privilege;
我对比同时查询dba_sys_privs、dba_role_privs表(然后去重)和查询session_privs视图的结果,对于sys用户,发现不完全一致,后者比前者多了6个权限,但是对于自己创建的普通账户,又是一致的……
所有的系统权限,可以查询system_privilege_map得知:
select?*?from?session_privs?order?by?privilege;
里面的这个PROPERTY字段不清楚是什么意思。
9.6. 常见的系统权限
create session 连接数据库;
create view 建视图;
create procedure 建过程、函数、包;
create cluster 建簇;
create table 建表;
create public synonym 建同义词;
create trigger 建触发器;
其中create session是最基本的权限了,具备该权限才可以连接数据库。
带any关键词的权限,如UPDATE ANY TABLE,顾名思义,这类权限比较重要,授予要谨慎。
另外,还存在一个参数
o7_dictionary_accessibility,当其为false(9i以及之后的版本默认值都是false,之前为true)的时候,此类带有any关键词的权限,对sys用户的Schema是一部分对象是没有效果的,sys用户的Schema里好像存着Oracle数据库的系统表、视图等(可百度oracle数据字典了解详情),如sys.dba_users,具备dba角色的普通用户也无法查询,不过类似于sys.AUD$又
可以查询到,我也不知道具体对哪些sys的对象有限制,哪些没有。
当
o7_dictionary_accessibility为true的时候,sys Schema对于any关键词例外的限制就没有了。
更多内容可以自行搜索
o7_dictionary_accessibility。
9.7. 普通权限中的对象权限
也就是对具体的数据库对象的权限,如对某个表的权限等。
select, update, insert, alter, index, delete, all //all代表前面这6权限
查询某用户拥有的被直接授予的对象权限
select * from dba_tab_privs where grantee='SYS' ORDER BY GRANTEE
至于与dba_tab_privs对应的user_tab_privis,不能理解为当前用户拥有的被直接授予的对象权限
查看Oracle官方文档可以知道,它会将owner, grantor, or grantee为当前user的列都查询出来:
select * from user_tab_privs ORDER BY GRANTEE
查询某用户直接拥有的表
select?*?from?dba_tables?where?owner='SYS';
查询当前用户拥有的表
select?*?from?user_tables;
9.8. 查询某用户拥有的所有对象权限
有三个地方要查:
某用户被直接授予的对象的权限(如某个表的select权限),语句略。
某用户直接拥有的对象(如某个表的所有者为这个用户,则该用户拥有该表的所有权限),语句略。
某用户被授予的角色,从而间接获得某角色拥有的对象权限(角色可以被直接授予某对象的权限,但是角色不能像用户那样成为某对象的所有者),语句如下:
SELECT?*
FROM?DBA_tab_PRIVS
WHERE?GRANTEE =?'SYS'
UNION?ALL
SELECT?*
FROM?DBA_tab_PRIVS
WHERE?GRANTEE?IN
(SELECT?GRANTED_ROLE?FROM?DBA_ROLE_PRIVS?WHERE?GRANTEE =?'SYS');
这里实验了一下public,发现就算把dba角色授予给public,其权限没有半点变化,无法创建表:
当然,所有的用户也确实活得了dba的权限。
这里的session_roles代表当前用户被激活的角色,和user_role_privs有点区别吧,后者代表授予你哪些角色,但是授予了不一定就激活了。
比如default_role为false,或者public这种特殊的存在。
十. 测评项d
d)应授予管理用户所需的最小权限,实现管理用户的权限分离;
这里比较简单了,对于状态为OPEN的用户,按照第3节的方式,把它的所有权限都查出来,就大概可以判断出其作用和是否做到了基本的权限分离了。
数据库系统中主要是业务用户居多,比如某用户只拥有某个数据库的权限,或者某用户只拥有查询权限,大家自己斟酌吧。
十一. 测评项e
e)应由授权主体配置访问控制策略,访问控制策略规定主体对客体的访问规则;
这里其实就是看是否有专门的或者兼职的安全管理员账户吧,能够授予或者撤销用户、角色的权限。
这里说一说授权,前面说过存在with admin option,同时也存在with grant option,决定被授予的权限的用户能否将该权限授予给他人。
网上说得很清楚了,我直接截图了:
另外还有一种很违规的系统权限:GRANT ANY OBJECT PRIVILEGE、GRANT ANY PRIVILEGE、GRANT ANY ROLE
比如GRANT ANY PRIVILEGE,有了这个权限后,你可以授予任何(至少大部分)系统权限给他人,甚至你本身不具备该权限也可以。
嗯,我试了下,还能把自己不具备的权限授予给自己……
十二 . 测评项 f
f)访问控制的粒度应达到主体为用户级或进程级,客体为文件、数据库表级;
至少到数据库表级,其实oracle还能到列的级别,这个自己查询下即可,有就是有,没有就是没有。
十三. 测评项g
g)应对重要主体和客体设置安全标记,并控制主体对有安全标记信息资源的访问。
初级教材上提到了Oracle_Label_Security,这里就不对起做出说明了,因为基本没有哪家测评机构会用这个插件。
碰到这个测评项,99%就是不符合的,如果真有使用该插件的,现场查资料也来得及的。
十四 . 总结
我说到的oracle权限方面的查询肯定不全,大家有想详细了解的可以去看一看oracle的官方文档,其实说得还是很好的:
https://docs.oracle.com/cd/E11882_01/network.112/e36292/guidelines.htm#DBSEG10004