方法
在Trail of Bits实习期间,我为《测试手册》的新密码学测试章节编写了详细的Wycheproof使用指南。我决定将elliptic库作为该指南的真实案例研究,这使我发现了相关漏洞。
我按照指南为elliptic包编写了Wycheproof测试工具,然后分析了Wycheproof提供的各种失败测试用例所覆盖的源代码,以将其分类为误报或真实发现。在理解这些测试用例失败的原因后,我为每个漏洞编写了概念验证代码。确认是真实发现后,我启动了协调披露流程。
发现
我总共识别出五个漏洞,对应五个CVE。其中三个漏洞是次要的解析问题。我在仓库的公开拉取请求中披露了这些问题,随后申请了CVE ID以跟踪它们。
其中两个问题更为严重。我使用GitHub的安全通告功能私下披露了它们。以下是这些漏洞的一些细节。
CVE-2024-48949: EdDSA签名可塑性
此问题源于缺少越界检查,这在NIST FIPS 186-5标准第7.8.2节“HashEdDSA签名验证”中有规定:
将签名的前半部分解码为点R,后半部分解码为整数s。验证整数s是否在范围0 ≤ s < n内。
在elliptic库中,从未执行检查s是否在范围0 ≤ s < n内,以验证其不超过生成器点的阶n。此漏洞允许攻击者伪造新的有效签名sig’,但仅限于已知的签名和消息对(msg, sig)。
|
|
需要实施以下检查以防止此伪造攻击:
|
|
伪造的签名可能会破坏协议的共识。某些协议会正确地拒绝伪造的签名-消息对为无效,而elliptic库的用户则会接受它们。
CVE-2024-48948: 对前导零哈希的ECDSA签名验证错误
第二个问题涉及ECDSA实现:有效的签名可能无法通过验证检查。
以下是失败的Wycheproof测试用例:
|
|
两个测试用例都因为一个特制的包含四个前导零字节的哈希而失败,该哈希由十六进制字符串"343236343739373234"经SHA-256哈希生成:
|
|
我们将使用secp192r1曲线测试用例来说明签名验证失败的原因。
负责验证椭圆曲线签名的函数位于lib/elliptic/ec/index.js:
|
|
消息在传递到验证函数调用之前必须进行哈希处理,这发生在elliptic库外部。根据FIPS 186-5第6.4.2节“ECDSA签名验证算法”,消息的哈希必须根据椭圆曲线基点的阶n进行调整:
如果 log2(n) ≥ hashlen,则设置 E = H。否则,设置 E 等于 H 的最左侧 log2(n) 位。
为了实现这一点,调用了_truncateToN函数,该函数执行必要的调整。在调用此函数之前,哈希后的消息msg会通过new BN(msg, 16)从十六进制字符串或数组转换为数字对象。
|
|
delta变量计算哈希大小与曲线当前生成器阶n之间的差异。如果msg占用的位数多于n,则按差值进行移位。对于此特定测试用例,我们使用secp192r1(192位)和SHA-256(256位)。哈希应向右移动64位以保留最左侧的192位。
elliptic库中的问题源于new BN(msg, 16)转换会移除前导零,导致哈希变小,占用更少的字节。
|
|
在delta计算期间,msg.byteLength()随后返回28字节而不是32字节。
|
|
这种错误计算导致delta值为32 = (288 - 192) 而不是正确的64 = (328 - 192)。因此,哈希消息没有被正确移位,导致验证失败。如果消息哈希包含足够的前导零(概率为2-32),此问题会导致有效签名被拒绝。
要解决此问题,应在验证函数中添加一个额外的参数以允许解析哈希大小:
|
|
持续测试的重要性
这些漏洞说明了为什么持续测试对于确保广泛使用的密码学工具的安全性和正确性至关重要。特别是,Wycheproof和其他积极维护的密码学测试向量集是确保高质量密码学库的优秀工具。我们建议将这些测试向量(以及任何其他相关的测试向量)包含在您的CI/CD管道中,以便在代码更改时重新运行它们。这将确保您的库现在和将来都能抵御这些特定的密码学问题。
协调披露时间线
对于披露过程,我们使用GitHub集成的安全通告功能私下披露漏洞,并使用报告模板作为报告结构的模板。
2024年7月9日:在针对elliptic库运行Wycheproof时,我们发现失败的测试向量。 2024年7月10日:我们确认ECDSA和EdDSA模块都存在问 题,并编写了概念验证脚本和修复方案。
对于 CVE-2024-48949
2024年7月16日:我们使用GitHub安全通告功能向elliptic库维护者披露了EdDSA签名可塑性问题,并创建了一个包含我们建议修复方案的私有拉取请求。 2024年7月16日:elliptic库维护者确认了EdDSA问题的存在,合并了我们建议的修复方案,并创建了一个新版本,但没有公开披露该问题。 2024年10月10日:我们向MITRE申请了CVE ID。 2024年10月15日:由于自我们私下披露以来已过去90天,此漏洞变为公开。
对于 CVE-2024-48948
2024年7月17日:我们使用GitHub安全通告功能向elliptic库维护者披露了ECDSA签名验证问题,并创建了一个包含我们建议修复方案的私有拉取请求。 2024年7月23日:我们联系请求在ECDSA GitHub通告中添加一名额外的协作者,但未收到回复。 2024年8月5日:我们联系请求确认ECDSA问题,并再次请求在GitHub通告中添加一名额外的协作者。未收到回复。 2024年8月14日:我们再次联系请求确认ECDSA问题,并再次请求在GitHub通告中添加一名额外的协作者。未收到回复。 2024年10月10日:我们向MITRE申请了CVE ID。 2024年10月13日:Wycheproof测试开发者Daniel Bleichenbacher独立发现并披露了与此发现相关的问题#321。 2024年10月15日:由于自我们私下披露以来已过去90天,此漏洞变为公开。