这里是普通文章模块栏目内容页
利用OAM加密缺陷漏洞构造任意用户身份测试

SEC Consult 团队发现了 Oracle Access Manager (OAM) 上的一种有意思的加密格式,本文中,我们将演示如何用这种加密方式的微小特性改变来对实际产品的安全性产生影响。最终,利用这种安全性影响漏洞,可以构造任意身份验证令牌,来假冒任意用户实现对 OAM 功能的恶意破坏。

 利用OAM加密缺陷漏洞构造任意用户身份测试

Oracle Access Manager (OAM) 是甲骨文 Oracle Fusion Middleware 中间件系列的主要部件,它主要用于解决各种 Web 应用环境的身份验证,如其在 Web 服务器应用程序中内置的访问认证组件 Oracle WebGate。当某用户对服务器上的受限资源发起访问请求后,请求会被转发到 OAM 的验证终端。随后,由 OAM 该终端来对用户身份进行验证,验证完成之后,再把请求转发给服务器中相应的 Web 应用。由于所有验证都由 OAM 的一个核心应用来实现,因此,用户只需 OAM 验证一次即可任意访问 OAM 的所有受限资源(单点登录情况下)。

在某研究分析中,我们发现,OAM 的加密格式存在严重漏洞隐患,利用该漏洞,我们能构造绕过 WebGate 的会话令牌,假冒合法用户并访问任意受限资源。此外,我们还能实现用户 cookie 伪造,假冒 OAM 任意合法用户。

涉及漏洞的 Oracle 产品

当前市面普遍在用的两个支持版本 11g 和 12c 都受到该漏洞影响。本文中,我们只对 12c 版本作出测试。通过简单的 Google 搜索可以发现,大量知名企业公司网站都部署有 OAM 产品,其中不乏 Oracle 公司本身,这些还仅只是暴露在互联网上的一部分。

我们于 2017 年底把该漏洞通报给 Oracle 后,漏洞补丁于今年 4 月底才发布。在此,我们希望 OAM 用户能及时更新补丁,以堵塞漏洞。此外,也建议 OAM 管理员分析历史日志记录,识别出前期攻击线索。利用该漏洞的攻击,由于 padding 填充尝试 (javax.crypto.BadPaddingException),会导致大量的解密失败记录。建议受影响用户请及时更新 Oracle 在 4 月发布的关键补丁,详细修复建议,请点此查看我们给出的  修复指南。

漏洞技术分析

以下技术分析需要一定加密解密和 Padding Oracle 技术基础,你可以直接到文章底部观看 Demo 视频。在技术层面来说,在 OAM 身份验证阶段,会发生以下一系列过程:

用户对受限资源发起访问请求

Web 服务器中的 OAM Webgate 组件验证该请求后,再把其转发给 OAM,之后会生成一个在 URL 参数中传递的加密消息 (「encquery」)

用户再根据用户名密码在 OAM 上进行验证

通过成功的登录信息「encreply」,OAM 将用户转向到 Web 服务器上

Web 服务器将用户转向到最初请求的受限资源上,并在 Cookie (「OAMAuthnCookie」) 中生成一个加密验证令牌

用户凭此 Cookie 中的令牌成为合法身份,并具备后续任意验证权限通过

为防篡改,加密消息「encquery」、「encreply」和 OAMAuthnCookie 的值受加密保护,这样,当 OAM 或 WebGate 接收到这些值时,即使来自用户,也能确保其未被篡改。OAM 使用一种单一加密格式来加密所有这些消息,而且 OAM 和 WebGate 共享这种加密方式的密钥。

加密格式

结合之前的分析,可以看出,漏洞原因在于加密格式的实现方式上,创建加密消息的算法在处理键值配对时,使用了共享的密钥,并生成了一个 base64 编码的输出串,该加密格式的目的在于提供完整性和安全性。以下为其工作机制:

输入形式:

salt=<salt> <key>=<value> [...] validate=<base64 hash>

其中,salt 是一个随机生成值,而验证性参数 validate 一组固定的 MD5 哈希;之后,该字符串被使用分组密码方式被加密。

漏洞分析

在分析这种加密格式时,我们首先想到的是,其中所使用的加密算法 (即哈希和 CBC 分组密码) 都是用于确保真实性目的的。可以假设,因为不知晓共享密钥,因此攻击也不可能发生。

有密码基础的人可能会注意到,CBC 加密模式会有脆弱性,比如可以使用 Padding 填充方式对它进行破坏。一种经典的 padding oracle 攻击需要加密输入和 padding oracle 形式的字符填充。Padding oracle 会揭露在解密时,提供的加密字符串是否具有有效的填充。

简单地说,分组加密需要填充才能加密任意长度的消息。而且,分组加密只能处理固定大小信息 (如 16 字节)。如果我们想要加密如 25 字节长的消息,我们将加密前 16 字节,然后留下 9 字节。由于分组加密不能处理 9 字节的输入,我们则需要附加 7 个填充字节。实现的典型方法是添加填充字节,其中每个字节包含填充字节的数量 (如 PKCS#7 填充中定义的)。例如在这种情况下添加的长度为 7 字节,则每个字节值为 7 或 0×7。当恰好不需要填充时,将追加完整的填充块,此时为填充块为 16 字节,每个字节包含值 16。

#p#分页标题#e#

Padding oracle attack 攻击在此不是本文的重点,我们只需要找到一种方法来确定在解密时,加密字符串是否具有适当的 padding 填充。

 利用OAM加密缺陷漏洞构造任意用户身份测试

要确定 Padding oracle attack 攻击是否可行,我们需要观察系统对消除填充的不同反应,如对无法正确消除填充的消息,和可以正确消除填充但随后未通过检查消息(如消除填充文本不能被正确解析时)。当我们之前提到的 encquery 参数尝试这两种测试用例时,OAM 两次都以「系统错误」响应,因此我们不能清楚地区分出这两种情况。当这种情况下,OAM 会显示「系统错误」,因此,为了区分正确填充的消息和错误填充的消息,其中一种方法就是,使我们在攻击中使用的所有正确填充的消息看起来完全合法。很显然,当 OAM 遇到有效消息时,它就不会报错,反之,如果系统消除填充失败,我们也会看到错误消息。

构造 Padding Oracle 攻击

事实证明,OAM 会忽略掉任何附加到解密消息的中的垃圾字符,如一些空格,我们可以尝试创建一个在末尾带有空格字符的有效消息。然后,我们再添加进入测试填充有效性的块。

具有有效填充的解密消息如下所示:

<valid message> <decryption of tested blocks>07070707070707 

这里,OAM 会首先检查填充,然后解析有效消息,忽略掉消息的其余部分。

具有无效填充的解密消息如下所示:

<valid message> <decryption of tested blocks>8BA09FB1ABC543

OAM 会检查填充有效性,并抛出系统错误。

Space: The Final Frontier 一切与空格符有关。

那么,如何用暴力破解的方式来确定有效消息后面跟的是空格符呢?

首先,我们要创建一个长度可被分组长度单位整除的有效消息,在此,需要找到一种影响明文的方法,使其生成的密文满足该标准。事实证明,加密请求 encquery 中包含了用户请求的最初受保护的 URL 链接,我们能捕获这种由不同长度 URL 下的 encquery 值:

?

?a

?aa

?aaa

一旦 encquery 的长度增加了 16 字节,我们就知道加密消息的长度可被 16 整除,且最后一个分组块由填充字节组成:

|---------------|---------------|

< valid msg>PPPP

< valid msg >PPP

< valid msg  >PP

< valid msg   >P

< valid msg    >PPPPPPPPPPPPPPPP

这样,我们可以把最后一个分组块丢弃,并继续使用不包含填充的加密字符串,然后,我们确保下面的分组块在第一个位置中包含空格字符。

我们可以创建一个不包含 padding 填充的有效加密消息,但我们选择的分组块以及原始消息的最后两个块要保持填充有效。在不有意影响解密后的结果文本,我们可以任意选择加密消息中的分组块。但是,我们可以继续尝试随机加密块,直到明文块符合我们的需要。

|---------------|---------------|---------------|---------------|

< valid msg    >< brute force  >< last 2 blocks of orig. msg   >

如果解密的有效消息后面没有空格符,则该消息无效,并显示「系统错误」。我们将继续使用随机分组块构造消息,直到最终被 OAM 接受。然后我们发现,我们选择的解密分组块偶然地在第一个字节中包含了一个空格符:

|---------------|---------------|---------------|---------------|

< valid msg    > <random data  >< last 2 blocks of orig. msg   >

在此步骤之后,攻击就变得很简单了:我们只需使用我们构建的消息,作为要测试有效填充的分组块的前缀。如果填充不正确,则系统消除填充步骤将失效,从而导致系统错误消息。如果填充正确,OAM 将正确地接收填充消息,开始解析有效消息,并且系统不报错

|---------------|---------------|---------------|---------------|---------------|---------------|

< valid msg    > <random block >< last 2 blocks of orig. msg   >< some text        ><pad valid?>

组合攻击 #p#分页标题#e#

Padding oracle 允许我们解密任意消息,由于所有加密消息 ( encquery、enceply、oamauthnokoie ) 都使用相同的密钥加密,因此我们可以解密这些消息中的任何一个。

这里很少有人知晓,Padding Oracle 攻击也可以用于加密消息,因此,如果我们构造一个有效的身份验证 cookie 并用我们的 Padding Oracle 攻击对其进行加密,我们就可以将它作为合法消息传递给 Web 服务器。事实上,攻击就这样就毫无意识地产生了,因为加密字符串中的 validate 值是一个简单的散列,而不是 HMAC 算法产生的,所以我们可以不需任何密钥简单地对它进行计算破解。目前,我们已经开发出了该漏洞的攻击利用脚本,但出于安全考虑,暂不公开发布。

DEMO

以下视频中,我们演示了利用该漏洞,在受限资源和应用中,攻击者可以假冒包括 admin 在内的任意用户。 

收藏
0
有帮助
0
没帮助
0