freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

等保测评2.0:Oracle身份鉴别(上)
2020-04-29 15:00:46

一、说明

本篇文章主要说一下Oracle数据库中身份验证控制点中关于身份鉴别的知识点,由于这个地方比较“复杂”,所以这篇文章就不写测评项方面的东西了,放在下篇文章中。

在oracle的身份验证这方面,网上的文章很多,但是真假难辨,而且没有把逻辑说清楚,所以如果不经过自己的测试往往会得到错误的结论或者半对半错的结论。

二、oracle的特性

先说一下我使用的oracle的版本,是11g,装在redhat-7中。

三、启动数据库

启动监听,就是在操作系统中执行lsnrctl start命令,这样才能远程连接oracle数据库(不启动监听的话,就只能在本地进行访问了,也就是装有这个数据库的服务器上)。

对于oracle,启动数据库,需要先在本地对数据库进行连接,此时会显示:
Connected to an idle instance.

然后再执行startup:

如果你不启动数据库,连接上去后是执行不了什么查询、更改操作的:

四、特殊的角色

所以这里就存在一个和其它数据库不大一样的地方,比如SqlServer,我要启动SqlServer,用命令行也好,用图形化界面也好,我只要在windows中把SqlServer的相关服务启动起来就可以了。

但是在oracle这里,却需要使用oracle数据库中的用户去连接它然后启动它。

所以这里就会存在一种特殊的数据库的角色,它可以在数据库没有启动的时候,对数据库执行一些操作,比如启动数据库,也可以关闭数据库。

同时必然的,对于属于这列特殊角色的用户,它的身份验证和权限判定肯定不是依靠数据库中相关字段的对比(因为数据库没启动前,无法查询到表中的数据)。

在oracle中,有两种这样的角色,分别是sysdba和sysoper,都具备数据库的启动和关闭权限,这两个角色的权限应该是固定不能更改的,其权限如下:

五、密码文件验证

所以,为了实现对拥有特殊角色如sysdba的用户的口令验证和权限判定,就出现了密码文件。

密码文件中储存了特殊用户的口令和一些权限字段,在linux中,这个文件在$ORACLE_HOME/dbs/目录中,以orapw开头,其内容是加密的:

查看里面的内容,需要启动数据库后查看V$PWFILE_USERS视图:

这里就能看到,口令文件中仅存在SYS用户,且SYS用户同时拥有sysdba和sysoper角色。

在oracle中,有一个参数可以对密码文件进行控制:remote_login_passwordfile

它有三个值,分别是:EXCLUSIVE、NONE、SHARED

EXCLUSIVE:对于这种特殊用户,使用密码文件来进行验证,另外这也是独占模式,可以将sysdba权限给非sys用户。

NONE:忽视任何密码文件,不使用密码文件对特殊用户验证

SHARED:对于这种特殊用户,使用密码文件来进行验证,另外这是共享模式,可以被一台服务器上的多个数据库或者RAC集群数据库共享,也无法将sysdba权限给非sys用户。

这里说明一点,选择NONE的时候,不使用密码文件对特殊用户进行验证,这里还存在另外一种验证方式——操作系统验证方式。

六、操作系统验证之特殊用户

比如在linux上,当你登录了操作系统的某些用户后,可以直接绕过数据库的验证,登录数据库的特殊用户SYS。

比如上面的说到启动数据库时,使用的连接语句是空用户名、空密码,用的就是操作系统认证方式:sqlplus / as sysdba;

这里进行的验证,本质上是判定你所使用的操作系统用户是否属于操作系统中的数据库用户组。

在windows以及linux中,安装oracle时,oracle默认就会在操作系统中建立相关的用户组,属于这个用户组的用户,就能使用操作系统验证方式来连接数据库。

在windows中,这个组默认是ora_dba,linux中,这个组默认是oinstall。(注意,由于oracle版本的不同,以及安装时组名称的设置,不一定都是这个名字和仅仅一个用户组)。

使用操作系统验证时,对于属于数据库用户组的用户而言,无论输入的数据库用户的用户名和密码是什么,甚至是空的,只要你后面加了as sysdba,最后都会以sys用户的身份登录数据库。

在oracle中,连接语句中as后面可以跟三个单词,分别是sysdba、sysoper、normal。

sysdba、sysoper的意思就是以这两种特殊角色的身份登录数据库,以sysdba身份登录后,实际上就是以sys用户的身份登录:

以sysoper的身份登录,实际上是以public用户(角色)的身份登录,而如果后面不写加上as或者使用as normal,那么就是以数据库内的普通的用户身份登录,这个时候你使用什么用户名登录,就使用的什么用户的身份。

对于操作系统认证,在sqlnet.ora文件中,可以通过SQLNET.AUTHENTICATION_SERVICES参数来配置:

这里就有点麻烦了,网上的说法一大堆,而且还有互相矛盾的,这里我仅给出我在linux下的实验结果(windows和linux好像不大一样,大家有空自己测试下)

当SQLNET.AUTHENTICATION_SERVICES参数被注释掉或者不存在时:操作系统中数据库用户组的用户可以使用操作系统验证方式以特殊角色的身份登录。

当SQLNET.AUTHENTICATION_SERVICES参数的值是all:操作系统中数据库用户组的用户可以使用操作系统认证方式以特殊角色的身份登录。

当SQLNET.AUTHENTICATION_SERVICES参数的值是none的时候:操作系统中数据库用户组的用户不可以使用操作系统认证方式以特殊角色的身份登录。

当SQLNET.AUTHENTICATION_SERVICES参数的值是nts或者其它的乱七八糟的值的时候(因为nts这个值不是给linux系统用的,所以设置这个值和你设置一个无意义的值是一样的):操作系统数据库用户组的用户不可以使用操作系统认证方式以特殊角色的身份登录。

注意,在参数外面加括号也可以,比如(all)和all是一回事,不过网上还有说(nts,none)这种参数使用方式的,这种写法反正在linux上应该归于“其它的乱七八糟的值”,windows上我就不知道了。

七、操作系统验证之普通用户

操作系统验证也可以作用于数据库中的普通用户,这个是否开启也是由SQLNET.AUTHENTICATION_SERVICES和remote_os_authent参数共同进行控制,这里先说一说是怎么一个验证方法。

在oracle中,有一个os_authent_prefix参数,其默认值是ops$

这个时候,如果数据库内存在一个名为ops$cv的账户,而操作系统也有一个名为cv的账户,那么登录cv后,可以以空用户名、空密码的方式以普通用户(normal)的身份登录ops$cv账户,这里很容易看出来,os_authent_prefix的意思就是用来设置前缀的。

这里我们来实际操作下,首先先创建一个ops$cv账户(注意这里的语句和一般的创建语句稍微有些不同):

create user ops$cv identified externally;

这个时候,这个用户的密码信息是这样的(不过在11g中,密码信息页不存在DBA_USERS表中):

在11g中,普通用户的密码应该是存在USER$表中的PASSWORD中:

ops$cv账户在USER$表中的PASSWORD字段的值是:EXTERNAL,所以,实际上对于这种账户,你没办法用用户名、密码的方式登录上去的。

然后,赋予ops$cv账户简单的权限:

grant create session to ops$cv;

我的虚拟机中存在一个cv账户,为了方便使用sqlplus,在cv账户的~/.bash_profile中设置相关的环境变量:

这个时候,直接用空用户名、空密码的方式以普通用户的方式登录:

这里说一下控制规则:

在remote_os_authent为默认值也就是False的时候,是否启用普通用户的操作系统验证,由SQLNET.AUTHENTICATION_SERVICES参数来控制,而控制的规则,和对于特殊用户的操作系统验证的控制规则是一样的,这里就不重复说明了。

当remote_os_authent的值为True的时候,就和SQLNET.AUTHENTICATION_SERVICES参数没关系了,无论SQLNET.AUTHENTICATION_SERVICES参数设置什么值,普通用户的操作系统验证方式都是开启的。

八、作系统验证之普通用户之远程连接

这种普通用户的操作系统验证,也可以在客户端进行,由remote_os_authent参数进行控制,其默认值是False:

验证规则和本地其实是一样的,只不过这里用来验证的操作系统用户名由本地的变成了客户端的。

先将remote_os_authent设置为true,注意,对于这些参数的设置,需要重启数据库后才能生效:

我的客户端的操作系统账户的用户名是cx,所以和上面一样,创建相关的数据库用户并赋予权限:

这里用空用户名、空密码,以normal的身份登录:

这里注意下,是否开启远程的操作系统普通用户验证,是由remote_os_authent单独控制,和SQLNET.AUTHENTICATION_SERVICES参数没啥关系,remote_os_authent是True,就开启,是False,就关闭。

九、总结一之互不干扰

从上面的说明可以看出,实际上有3个参数:

remote_login_passwordfile、SQLNET.AUTHENTICATION_SERVICES、remote_os_authent

不知道为何,在网上,莫名其妙的把SQLNET.AUTHENTICATION_SERVICES和remote_login_passwordfile联系了在一起,实际上remote_login_passwordfile和SQLNET.AUTHENTICATION_SERVICES是互不干扰的,不存在什么SQLNET.AUTHENTICATION_SERVICES的值是none的时候,密码文件验证就不能用了。

它们是这样的关系:

remote_login_passwordfile决定是否启用密码文件验证,而SQLNET.AUTHENTICATION_SERVICES、remote_os_authent决定是否启用操作系统的验证方式。

这remote_login_passwordfile和SQLNET.AUTHENTICATION_SERVICES、remote_os_authent是互不干扰的,remote_login_passwordfile不会影响到操作系统验证的开启与否,SQLNET.AUTHENTICATION_SERVICES、remote_os_authent也不会影响到密码文件的验证开启与否。

开启密码文件验证后,无论操作系统的哪一个用户,都可以使用sqlplus 用户名/密码 as sysdba的方式登录数据库。

开启操作系统的验证方式后,是否可以以特殊用户的身份登录数据库,看的是你使用的操作系统用户是否属于数据库的用户组。

remote_os_authent为默认值的前提下,对于特殊用户的登录,有:

remote_login_passwordfile不为none的时候,如果数据库未启动,那么无法远程连接数据库,不存在可以在数据库未启动时远程通过密码文件验证的方式以特殊角色的身份登录数据库然后启动,至少我自己测试时是不行的,登不上去。这个时候,可以在本地通过类似于sqlplus 用户名/密码 as sysdba的方式以特殊角色的身份登录数据库(密码文件认证)。

不过,虽然未启动时不可以,启动了数据库之后,就可以通过密码文件认证的方式远程以sysdba的身份登录数据库了。

同样的,如果remote_login_passwordfile为none,那么不仅本地不可以使用密码文件验证的方式以特殊角色的身份登录数据库,远程也不可以。

所以这个参数为none时,就使得远程连接的时候,不能以sysdba、sysoper的身份登录数据库,只能够以normal的身份远程登录数据库。

当通过设置SQLNET.AUTHENTICATION_SERVICES的值无法使用操作系统验证方式时,虽然无法使用操作系统验证,但如果此时remote_login_passwordfile不为none,任何一个操作系统用户在本地,都还是可以使用密码文件验证的方式以特殊角色的身份登录数据库,只不过非数据库用户组的用户需要配置下环境变量方便使用sqlplus而已。而且同时,远程以特殊角色的身份连接数据库,也是可以的(两个参数互不干扰)。

当通过设置SQLNET.AUTHENTICATION_SERVICES的值可以使用操作系统验证方式时,非数据库用户组的用户,使用sqlplus也无法使用操作系统验证方式的方式以特殊角色身份登录数据库。此时如果remote_login_passwordfile不为none,那么对于数据库用户组的用户,似乎就同时存在密码文件验证和操作系统验证,但实际上,应该使用的是操作系统验证,因为随便输入什么用户名、密码,连接语句中加上as sysdba,都能以sysdba的身份登录。

无论是密码文件认证还是操作系统认证,说来说去,影响到的都是以特殊角色身份登录数据库是否能成功,如果使用用户名、口令,并且以normal身份登录数据库,则不受到这两个参数的影响,只要数据库启动后,本地或者远程以normal身份登录数据库都是可以的,这个时候,使用的就是数据库中的用户名、口令的字段的验证了。

注意,这里对于数据库的普通用户,如果使用用户名对比的操作系统验证方式,比如上面说到的ops$cv、ops$cx账户,还是受到SQLNET.AUTHENTICATION_SERVICES、remote_os_authent参数的控制的。

十、总结二之操作系统认证

在remote_os_authent为默认值也就是False的时候:

是否启用数据库的普通用户、特殊用户的本地操作系统验证,由SQLNET.AUTHENTICATION_SERVICES参数来控制,这里数据库中普通用户本地操作系统验证的规则,和对于特殊用户的操作系统验证的控制规则是一样的,这里就不重复说明了。

此时,远程客户端的操作系统验证方式是关闭的,和SQLNET.AUTHENTICATION_SERVICES参数无关。

当remote_os_authent的值为True的时候:

数据库中普通用户的本地操作系统验证的控制,就和SQLNET.AUTHENTICATION_SERVICES参数没关系了,无论SQLNET.AUTHENTICATION_SERVICES参数设置什么值,普通用户的操作系统验证方式都是开启的。

但是,这个时候,特殊用户的本地操作系统验证还是由SQLNET.AUTHENTICATION_SERVICES参数控制,与remote_os_authent没啥关系。

同时,远程客户端的操作系统验证方式是开启的,也和SQLNET.AUTHENTICATION_SERVICES参数没关系。

十一、总结三——测试

想自行测试的话,有一些注意项,不注意的话会得出错误的结论:

SQLNET.AUTHENTICATION_SERVICES是实时改变的,意思就是改变了SQLNET.AUTHENTICATION_SERVICES的值,不用重启数据库。

remote_os_authent、remote_login_passwordfile则不然,改变了它们的值,需要关闭数据库,然后再启动数据库,才会加载新的值。

SQLNET.AUTHENTICATION_SERVICES对格式要求好像挺严格,比如在参数前面加一个空格,应该就相当于注释掉它了:

所以图中虽然参数是none,但实际仍然可以使用操作系统验证登录特殊用户。

远程登录测试的时候,如果使用PLSQL,注意,每次测试要把登录框关掉,重新打开。

比如关闭密码文件验证的时候,你测试是否能远程登录特殊用户:

当然登录不上,之后你在服务器端设置remote_login_passwordfile参数开启密码文件验证后,重新打开个登录框进行登录是可以登录上的。但如果还是用这个登录框,好像还是登录不上去,这样就会得到错误的结论。我也不是很了解PLSQL连接的细节,大家自己注意吧。

十二、往期文章的错误和扩充

发现以前文章的错误或者有什么扩充,但是由于内容的问题,不足以写成新的文章,所以就放在这里了:

等保测评2.0:Windows身份鉴别有这么一段话:

所以一般的,本地登录超时,仅查看“屏幕保护程序”就可以了。
注意,如果在“屏幕保护程序”处设置了超时,那么对于远程登录而言(无论使用远程桌面还是其他远程管理软件),应该也会具备效果。
即,你在设置了“屏幕保护程序”后(如15分钟),当你通过远程桌面登录到服务器时,在你没有设置远程登录超时的情况下,超过15分钟没有动作,服务器就会开始运行“屏幕保护程序”了,也就是超时退出了(虽然你的网络连接并没有断开)。

这里其实也没说错,但是没说全。

经过群中QQ群员的测试和提醒:“屏幕保护程序”对于本地登录有效,远程登录也有效的,只不过这个设置是用户设置而不是全局设置。

举个例子,你登录administrator用户时,设置了“屏幕保护程序”,但这个设置仅对administrator用户有效,对其他用户没有用,每个用户都有自己的设置数据。

所以如果设置“屏幕保护程序”的话,应该是每个用户都要设置一遍。

等保测评主机安全:CentOS密码修改周期与登录失败处理中,关于本地图形化界面登录时调用的pam文件,我写错了:

这里是评论区的孔明梅林123提醒我的,他还问了个新问题,我就直接截图了:

*本文作者:起于凡而非于凡,转载请注明来自FreeBuf.COM

# oracle # 数据库 # 身份鉴别
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者