ORACLE TNS Listener远程注册投毒(Poison Attack)漏洞

此次有用户正好大规模安全漏洞扫描后,发现此漏洞,该漏洞存在于Oracle DB的所有版本中,当然10g和11g均中招.

1. Vulnerability Description(漏洞描述)

This security alert addresses the security issue CVE-2012-1675, a vulnerability in the TNS listener which hasbeen recently disclosed as "TNS Listener Poison Attack" affecting the Oracle Database Server. This vulnerability may be remotely exploitable without authentication, i.e. it may be exploited over a network without the need for a username and password. A remote user can exploit this vulnerability to impact the confidentiality, integrity and availability of systems that do not have recommended solution applied.

 
 
Oracle 2012年发布的告警,CVE-2012-1675漏洞是Oracle允许攻击者在不提供用户名/密码的情况下,向远程“TNS Listener”组件处理的数据投毒的漏洞。举例:攻击者可以再不需要用户名密码的情况下利用网络中传送的数据消息(包括加密或者非加密的数据),如果结合(CVE-2012-3137漏洞进行密码破解)从而进一步影响甚至控制局域网内的任何一台数据库。
2.针对该漏洞,oracle给出了2种不同环境的解决方法:

http://www.oracle.com/technetwork/topics/security/alert-cve-2012-1675-1608180.html Recommendations for protecting against this vulnerability can be found at: My Oracle Support Note 1340831.1 for Oracle Database deployments that use Oracle Real Application Clusters (RAC). My Oracle Support Note 1453883.1 for Oracle Database deployments that do not use RAC.

举例说明下(非RAC)单实例情况下的修复和测试方式:图2 中的被劫持的数据库的listener.ora加上: SECURE_REGISTER_LISTENER = (TCP) 图2 中的(即黑客想要访问的最终的劫持数据库)做: SQL>alter system set remote_listener='(ADDRESS = (PROTOCOL = TCP)(HOST = database2)(PORT = 1521))' scope = both; $lsnrctl reload   <<<<重启监听

注意:验证环节需要在图2的劫持数据库中的监听日志中,查看是否存在refuse remote_listener访问的信息,如有,即说明加固成功。

同时,还提及了一个在11.2.0.4和12.1中或者在RAC中的新参数配置解决该问题:Valid Node Checking For Registration (VNCR) (文档 ID 1600630.1)

 
 

VALID_NODE_CHECKING_REGISTRATION_listener_name Values: OFF/0 - Disable VNCR ON/1/LOCAL - The default. Enable VNCR. All local machine IPs can register. SUBNET/2 - All machines in the subnet are allowed registration.

#可以指定固定IP或者网段中的服务器

REGISTRATION_INVITED_NODES_listener-name Values are valid IPs, valid hosts, a subnet using CIDR notation (for ip4/6), or wildcard (*) for ipv4. For example: REGISTRATION_INVITED_NODES_Listener=(net-vm1, 127.98.45.209, 127.42.5.*)

Note that when an INVITED list is set, it will automatically include the machine's local IP in the list. There is no need to include it.

REGISTRATION_EXCLUDED_NODES_listener_name - the inverse of INVITED_NODES.

3.针对上文提到的2个漏洞,有网友也通过组合模拟了截取数据库密码的测试,及以下(攻击部分)转至网络:
CVE-2012-1675漏洞是Oracle允许攻击者在不提供用户名/密码的情况下,向远程“TNS Listener”组件处理的数据投毒的漏洞。攻击者可利用此漏洞将数据库服务器的合法“TNS Listener”组件中的数据转向到攻击者控制的系统,导致控制远程组件的数据库实例,造成组件和合法数据库之间的中间人攻击、会话劫持或拒绝服务攻击。 CVE-2012-3137漏洞是Oracle Database 10g/11g身份验证协议实现中存在一个设计缺陷,攻击者无需认证即可远程获取数据库用户密码哈希相关数据,从而可以离线暴力破解用户密码,进一步控制数据库系统。 我们通过如下的步骤和过程可以实现对Oracle的入侵: (1)利用CVE-2012-1675进行TNS劫持,在监听下利用远程注册,注册同名数据库实例; (2)新登陆的用户,在TNS的负载均衡策略下,有可能流量登录到伪造的监听服务上; (3)该监听服务对用户的登陆过程进行监控,并将相关数据流量转发到真实的数据库上; (4)利用CVE-2012-3137获得通讯过程中的认证相关信息; (5)对认证相关信息进行离线的暴力破解,获得登陆的密码; (6)试用破解的用户名/密码登陆Oracle,完成对Oracle中数据的访问;
画了几个图了解下整个过程:
1.oracle 通过在本地解析网络服务名到目标主机IP地址,服务端口号,目标数据库名,把这些信息发送到oracle服务器端监听程序,最后再由监听程序递送DB。
图(1)
2.如果同时一个 监听下存在有2个同名数据库(见图3,一个local listener,一个remote listener),由于图3中已被注册远程监听到劫持数据库,客户端链接很可能会被分配到劫持者的数据库实例下(图2,第2步),再通过配置劫持者的本地监听把客户端请求指回原数据库(图2,第3步)。
图(2)
通过上图第一步,可以发现已经注册到被劫持数据库上
图(3)
3. 通过CVE-2012-3137进行密码破解
CVE-2012-3137受影响的数据库版本有11.2.0.3,11.2.0.2,11.1.0.7,有使用了SHA-1加密算法的10.2.0.5和10.2.0.4,还有使用了SHA-1的10.2.0.3(运行在z/OS下)版本。 虽然这个漏洞在11.2.0.3中已经解决,但是仅仅数据库客户端和服务器都升级到11.2.0.3并且sqlnet.ora文件中增加SQLNET.ALLOWED_LOGON_VERSION=12才有效。 正如CVE-2012-3137所描述Oracle为了防止第三方通过网络获取登录信息包。而对密码进行了加密处理。本部分只以oracle11.1密码如何破解为例进行说明。 在发起连接之后(oracle牵手完成),客户端和服务器经过协商确定要使用的验证协议。要完成这个任务,客户端首先向数据库发送一个包。包中包含客户端主要信息和所请求的加密方式。数据库确认加密方式有效后,发送一个确认服务包如下图所示: 在通过安全网络服务完成任何所要求的协议之后,数据库用户被O3logon(oracle验证方式) 进行验证,这个协议执行一个序列来向数据库证明客户端拥有密码。为了避免网络第三方截获到密码。首先客户端发送用户名到数据库来表明用户身份。数据库端根据加密协议,其中96位的作为数据库端密钥,20位的作为偏移量,它对每个连接都是不同的。一个典型的数据库端发给客户端的密钥如下: AUTH_SESSKEY.....COCDD89FIGODKWASDF……………………
客户端根据加密算法向服务器端发送96位的客户端密钥和64位的密码密钥。服务器端计算客户端传入的密码密钥。如果计算后密码密文和数据库中存储的16位密码密文一致则验证通过。
根据这个过程可知上面TNS劫持包中取得的加密信息:AUTH_SESSKEY,AUTH_SESSKEY_CLIENT,AUTH_PASSWORD,AUTH_VFR_DATA这四个值是解密的关键。我们把他们按照SHA1,MD5,AES192进行一系列处理。最终通过数据字典碰撞得到密码明文。 下面这段网上公布的一段示例代码,这段代码与笔者的思路不完全相同,但也能大概地说明这个漏洞的攻击过程:   import hashlib     from Crypto.Cipher import AES            def decrypt(session,salt,password):             pass_hash= hashlib.sha1(password+salt)             key =pass_hash.digest() + '\x00\x00\x00\x00'             decryptor= AES.new(key,AES.MODE_CBC)             plain =decryptor.decrypt(session)             returnplain     session_hex ='EA2043CB8B46E3864311C68BDC161F8CA170363C1E6F57F3EBC6435F541A8239B6DBA16EAAB5422553A7598143E78767'          salt_hex = 'A7193E546377EC56639E'           passwords = ['test','password',''oracle','demo']           for password in passwords:             session_id= decrypt(session_hex.decode('hex'),salt_hex.decode('hex'),password)             print'Decrypted session_id for password "%s" is %s' %(password,session_id.encode('hex'))             ifsession_id[40:] == '\x08\x08\x08\x08\x08\x08\x08\x08':                     print'PASSWORD IS "%s"' % password                     break


猜你喜欢

转载自blog.csdn.net/u013310119/article/details/80924362