CVE-2022-21449漏洞分析

admin 2025年2月15日23:24:25评论18 views字数 3563阅读11分52秒阅读模式

前言

Oracle于今年4月19日披露出了一个java的加密算法漏洞,简单来说效果就是绕过ECDSA 签名算法,也就说是这个名白签了。该漏洞允许攻击者随意伪造相关SSL证书或SSL握手包,影响到Java 15、Java 16、Java 17、Java 18等版本,更新到最新版本就可以修复。

环境搭建

首先需要安排一个带有漏洞的java版本环境,这里就不得不吐槽一下Oracle官网,我来来回回找了好久才找到下载历史版本的地方,链接如下。https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html

这里我下载的是17.0.2版本的jdk。

漏洞验证

我在漏洞发现者Neil Madden给的poc上小改一下,验证是否存在漏洞。代码如下:

package com.company;
import java.security.*;
public class Main {
    public static void main(String[] args) {
        String crypto_type[]=new String[]{"NONEwithECDSAinP1363Format","SHA1withECDSAinP1363Format","SHA224withECDSAinP1363Format","SHA256withECDSAinP1363Format","SHA384withECDSAinP1363Format","SHA512withECDSAinP1363Format","SHA3-224withECDSAinP1363Format","SHA3-256withECDSAinP1363Format","SHA3-384withECDSAinP1363Format","SHA3-512withECDSAinP1363Format"};
        byte[] blankSignature = new byte[64];
        for(int i=0;i<=9;i++) {
            try {
                Signature sig = Signature.getInstance(crypto_type[i]);
                KeyPair keys = KeyPairGenerator.getInstance("EC").generateKeyPair();
                sig.initVerify(keys.getPublic());
                sig.update("Hello, World".getBytes());
                Boolean s = sig.verify(blankSignature);
                System.out.println(crypto_type[i]+"have vul ? :"+s);
            } catch (Exception e) {
                System.out.println(e);
            }
        }

    }
}

CVE-2022-21449漏洞分析

使用ECDSA签名的均存在问题(底层使用的是同一个方法)。

漏洞分析

通过调试进入java库,找到具体验证签名的代码。

CVE-2022-21449漏洞分析

首先把我们的签名数据切割成了两块,装在数组r和s中。而后将数组中的数据颠倒一下。接着进行转换到IntegerModuloP类型的ri、si变量中。

int lengthE = Math.min(length, digest.length);
byte[] E = new byte[lengthE];
System.arraycopy(digest, 0, E, 0, lengthE);
ArrayUtil.reverse(E);
IntegerModuloP e = orderField.getElement(E);

随后对参数digest 进行拷贝颠倒放入IntegerModuloP类型 变量e中。

int lengthE = Math.min(length, digest.length);
byte[] E = new byte[lengthE];
System.arraycopy(digest, 0, E, 0, lengthE);
ArrayUtil.reverse(E);
IntegerModuloP e = orderField.getElement(E);

而后对si求倒数sInv,求u1、u2的值

u1 = e * sInv
u2 = ri * sInv

java中的实现如下

IntegerModuloP sInv = si.multiplicativeInverse();
ImmutableIntegerModuloP u1 = e.multiply(sInv);
ImmutableIntegerModuloP u2 = ri.multiply(sInv);

到这里问题显现出来了,很明显slnv的值为0最后求出的u1、u2的值也是0。而后根据传入的参数pp算出AffinePoint 类型的变量pub

AffinePoint pub = new AffinePoint(field.getElement(pp.getAffineX()),field.getElement(pp.getAffineY()));

根据u1、u2求出两个值temp1、temp2

byte[] temp1 = new byte[length];
b2a(u1, orderField, temp1);

byte[] temp2 = new byte[length];
b2a(u2, orderField, temp2);

temp1=0,temp2=0 而后算出MutablePoint类型的值p1、p2

MutablePoint p1 = ecOps.multiply(basePoint, temp1);
MutablePoint p2 = ecOps.multiply(pub, temp2);

根据函数名,猜测也是一个乘法的过程。最后使用p1、ri进行运算,判断结果值是否为0。

ecOps.setSum(p1, p2.asAffine());
IntegerModuloP result = p1.asAffine().getX();
result = result.additiveInverse().add(ri);//result=0,ri=0
b2a(result, orderField, temp1);
return ECOperations.allZero(temp1);

当temp1全为0时满足判断条件返回真,也就是签名校验成功。

想要进一步理解其中的理念需要简单理解一下ECDSA签名算法。

ECDSA签名算法

ECDSA工作在加密信息的哈希上面,而不是信息本身。哈希函数的选择由用户自己确定,显然,为了确保安全性,还是需要采用密码级安全的哈希函数。加密信息的哈希需要进行截取以确保哈希的字节长度与子群的阶n相等,被截取的哈希是一个正整数,通常用z来表示。

签名过程如下:

CVE-2022-21449漏洞分析

验证签名过程如下:

为了对数字签名进行验证,我需要公钥HA,截取后的哈希z,当然,也需要签名对(r,s),主要分以下三步:

CVE-2022-21449漏洞分析

如果r ≡ xp (mod n)则签名是有效的。

仔细观察签名验证过程可知,如果s为0则u1、u2为0,进而P为0,而如果r也为0,则等式两边均为0,满足相等条件。

在实际应用中,我们将签名均置为0即可绕过签名,使其在任何时候均能通过验证。

该漏洞在于没有验证签名的s、r值是否为0,签名过程不会产生r=0,s=0的签名,但在验证过程中签名的值是可被人为修改的,开发者应该考虑到对签名的验证。

结语

java15以上的高版本实际上应用的比较少,感觉用在实战的机会不多。本人的密码水平一般,有什么错误欢迎师傅们指出。

pcat给我说过,在签名算法这方面,可以关注更为健壮的Edwards-Curve Digital Signature Algorithm (EdDSA) ,该算法实现了一种 RFC8032 标准化方案。

参考文献

  1. https://neilmadden.blog/2022/04/19/psychic-signatures-in-java/
  2. https://zhuanlan.zhihu.com/p/107599962

原文始发于微信公众号(BeFun安全实验室):CVE-2022-21449漏洞分析

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年2月15日23:24:25
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   CVE-2022-21449漏洞分析https://cn-sec.com/archives/1066005.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息