OpenSSL-CVE-2015-1793漏洞分析

author:360安全卫士

0x00 前言

OpenSSL官方在7月9日发布了编号为 CVE-2015-1793 的交叉证书验证绕过漏洞,其中主要影响了OpenSSL的1.0.1和1.0.2分支。1.0.0和0.9.8分支不受影响。

360安全研究员au2o3t对该漏洞进行了原理上的分析,确认是一个绕过交叉链类型证书验证的高危漏洞,可以让攻击者构造证书来绕过交叉验证,用来形成诸如“中间人”等形式的攻击。

0x01 漏洞基本原理

直接看最简单的利用方法(利用方法包括但不限于此):

攻击者从一公共可信的 CA (C)处签得一证书 X,并以此证书签发另一证书 V(含对X的交叉引用),那么攻击者发出的证书链 V, R (R为任意证书)对信任 C 的用户将是可信的。

显然用户对 V, R 链的验证会返回失败。

对不支持交叉链认证的老版本来说,验证过程将以失败结束。

对支持交叉认证的版本,则将会尝试构建交叉链V, X, C,并继续进行验证。

虽然V, X, C 链能通过可信认证,但会因 X 的用法不包括 CA 而导致验证失败。

但在 openssl-1.0.2c 版本,因在对交叉链的处理中,对最后一个不可信证书位置计数的错误,导致本应对 V, X 记为不可信并验证,错记为了仅对 V 做验证,而没有验证攻击者的证书 X,返回验证成功。

0x02 具体漏洞分析

漏洞代码位于文件:openssl-1.0.2c/crypto/x509/x509_vfy.c

函数:X509_verify_cert()

第 392 行:ctx->last_untrusted–;

对问题函数X509_verify_cert 的简单分析:

( 为方便阅读,仅保留与证书验证强相关的代码,去掉了诸如变量定义、错误处理、资源释放等非主要代码)

问题在于由<1> 处加入颁发者时及<2> 处验证(颁发者)后,证书链计数增加,但 最后一个不可信证书位置计数 并未增加, 而在<4> 处去除过程中 最后一个不可信证书位置计数 额外减少了,导致后面验证过程中少验。

(上述V, X, C 链中应验V, X 但少验了X

代码分析如下

官方的解决方法是在<5> 处重新计算 最后一个不可信证书位置计数 的值为链长:

并去掉<4> 处的 最后一个不可信证书位置计数 自减运算(其实去不去掉都无所谓)。 另一个解决办法可以是在<1> <2> 后,在<3> 处重置 最后一个不可信证书位置计数,加一行:

这样<4> 处不用删除,而逻辑也是合理并前后一致的。

0x03 漏洞验证

笔者修改了部分代码并做了个Poc 。 修改代码:

将代码中X509_verify_cert() 函数加入输出信息如下: 编译,以伪造证书测试,程序输出信息为:

认证成功 将<1> 处注释代码去掉,编译,再以伪造证书测试,程序输出信息为:

认证失败

0x04 安全建议

建议使用受影响版本(OpenSSL 1.0.2b/1.0.2cOpenSSL 1.0.1n/1.0.1o)的 产品或代码升级OpenSSL到最新版本

评论