Skip to content

标题: 关于python-rsa签名伪造漏洞(CVE-2016-1494)的讨论

创建: 2016-06-14 17:14 更新: 链接: https://scz.617.cn/misc/201606141714.txt

这个洞是Filippo Valsorda发现的:

Bleichenbacher'06 signature forgery in python-rsa (CVE-2016-1494) - [2016-01-05] https://blog.filippo.io/bleichenbacher-06-signature-forgery-in-python-rsa/ https://gist.github.com/FiloSottile/9a1832541a7d01237ad6

这种错误实现在校验签名时接受:

s^e mod n="00 01 GARBAGE 00 ASN.1 HASH"

要求GARBAGE中不包含00。

CVE-2016-1494与BB2006的思想是一致的,验证RSA签名时对c^e产生的结果进行了某 种格式解析,而不是简单的memcmp(),在复杂的格式解析过程中留下了安全漏洞。 Bleichenbacher曾经也是贝尔实验室的,后来去了Google。

原文有篇中文直译版:

http://www.freebuf.com/news/92976.html

感觉像是在Google Translate基础上强行翻译的,有很多细节上的错误,不推荐。

相比之下,另有一篇中文意译版还不错,推荐阅读:

CVE-2016-1494 (python-rsa)漏洞详解 - uncleheart [2016-04-12] http://www.freebuf.com/articles/terminal/101200.html http://www.pengyanhao.com/183.html

这篇比较实在,对Filippo Valsorda给出的攻击代码还做了某些改进。作者是对付 BCTF 2016中一道题时折腾这个漏洞的。我是无意中看到作者这篇才引起了对BB2006 及其各种变种的兴趣,感谢uncleheart的分享。

在此就上文内容讨论一下,双引号中内容出自上文:


  1. "在这里我说明一下,原文作者的文章出现了一个错误"

这个地方,Filippo Valsorda没有说错,他说的是BB2006的模板及原理。是那篇中文 直译版没翻译对,仔细看英文原文就能确认。

  1. "我并没有找到一种合适的方法快速求出当e=65537时的根"

如果我没有理解错的话,uncleheart的潜台词是,如果他找到了快速求65537次方根 的办法,CVE-2016-1494还可以对付e=65537。

我想说的是,对形如"00 01 ..."的前缀求e次方根,当e=65537时,n最少1004448位, 现实世界中不可能有这么大的n。n不够大时,"s^e mod n"不等于"s^e",运算从整数 域回到了有限域,BB2006及其变种全部失效。换句话说,现实世界中CVE-2016-1494 永远无法对付e=65537。

实测下面这些参数有解:

n=1024,e=3,md5 n=2048,e=3,md5 n=2048,e=7,md5

n=1024,e=3,sha1 n=2048,e=5,sha1 n=4096,e=7,sha1 n=8192,e=17,sha1 n=8192,e=23,sha1

n=2048,e=3,sha256 n=8192,e=17,sha256

n=2048,e=3,sha384 n=8192,e=13,sha384

n=2048,e=3,sha512 n=8192,e=11,sha512

可以看出,"n=2048,e=3"适用于所有HASH类型。

  1. "待签名信息的二进制最后一位需要为1"

这个限制的数学本质是,对于高次同余方程x^r≡a(mod 2^k):

设r、k均为正整数,a为整数,若r、a均为奇数,则x^r≡a(mod 2^k)恰有一解。

Filippo Valsorda所示办法在e比较大时,效率太低,用数学方式求解高次同余方程 更普适,还能对付a为偶数的情形。


从2006年到2016年,10年间出现了很多BB2006的变种。CVE-2016-1494其实只是下面 这种变种的同型:

Why the exponent 3 error happened - Hal Finney [2006-09-17] http://www.mail-archive.com/[email protected]/msg06693.html

Hal Finney在此揭示了一种错误实现,接受:

x="00 01 00 GARBAGE HASH"

CVE-2016-1494相比之下,变化不大,接受:

x="00 01 GARBAGE 00 ASN.1 HASH",要求GARBAGE中不包含00。

如果抽象一下,它们都接受:

x="apart || gpart || bpart"

其中apart、bpart相对固定,gpart相对任意。因此上述二者的求解算法是相容的。

BB2006及其变种不是教条式的结论,比如什么只能攻击e=3,但也不是天马行空式的, 比如幻想攻击e=65537之流。完全取决于模板x等于什么以及n有多大,x不同n不同, 所能容忍的e的上限就会不同。

比如:

x="00 01 00 GARBAGE HASH" n=4096 hashtype=sha1 e=17

e=17就是此时的上限。"n=4096,e=17,sha1"在现实世界中是存在的,不是幻想或纯理 论上的存在,这种情况下就是安全漏洞。

我还见过有人在问如何攻击e=41,当然他没说模板x是什么,但想必他在现实世界中 碰上了新的BB2006变种。

可以预见,BB2006变种将在相当长的时间段内继续存在于现实世界,且不说蠢才代代 有的问题,要知道战场很多的,不是一处。