长度扩展攻击
Hash 长度扩展攻击:已知明文长度和明文的杂凑值,但明文本身未知,通过构造扩展消息,可以计算出明文连接扩展消息的杂凑值。
引言
在 BaseCTF 第二周遇到的一道题目,题目部分如下:
1 |
|
这里给出了一个96字节的明文,但是内容未知。然后给出这个明文的 MD5
值。然后要求你附加一段文字,文字以 admin
结尾,使得明文加上附加文字的 MD5 能被求出来。这里就设计到了本文介绍的
Hash 长度扩展攻击。
本文在介绍部分就以 MD5 来介绍 Hash 长度扩展攻击,实际上 SHA1,SHA2的算法也都受该攻击的影响,只是影响的方式都大同小异,相信聪明的你举一反三就一定会了。
MD5 算法
该攻击过程是杂凑函数填充过程中由于自身的逻辑导致的,所以在以 MD5 为例子介绍 Hash 长度扩展攻击前,我们来看一下 MD5 算法的具体实现过程。
上图展示了 MD5 算法的过程,我们从上至下、从左至右地看这张图。
填充
MD5 的第一步就是对明文进行填充,使得其长度为512比特的倍数,从而可以切分成长为64字节(等于512比特,下面都用字节来表示了)的分组。那么填充什么呢?
按照 RFC1321 的标准
- 在明文末尾填充
0x80
(1字节) - 在最后一个分组的最后8字节填充明文的长度,注意!!!这里用的比特长度,所以字节要乘以8(8字节)
- 其余部分填充
0x00
来点小练习:
Q1:假如最后一个分组长度为32字节,填充多少
0x00
(仅限0x00
填充部分,下同)?A1:64-32-1-8 = 23字节
Q2:假如最后一个分组长度为56字节,填充多少
0x00
?A2:64-56-1-8 = -1字节?如果填了
0x80
后填不下长度,那么就新开一个分段填充长度,所以是 63 字节。
Q3:假如最后一个分组长度为55字节,填充多少
0x00
?A3:64-55-1-8 = 0字节,刚刚好!
分组计算
这里我不想赘述 MD5 中对每个分组中计算的具体过程,如果好奇可以看 RFC1321 标准,或者其他博客。我们只需要将这段过程记为 \(\textbf{H}_C(\textbf{B_i},\textbf{V})\) ,其中 \(\textbf{B_i}\) 是明文的当前分组,\(\textbf{V}\) 是一个向量,有一个初始值。对所有的分组计算完成后,\(\textbf{V}\) 就是该段明文的 MD5 杂凑值。那么 MD5 计算方法如下:
1 |
|
MD5 长度扩展攻击
下面介绍攻击过程,先看下图:
名词量爆炸,不是吗?捋一下相关的名词:
- 原填充:明文在计算 MD5 过程中的填充
- 扩展消息:你希望添加的消息,但是请注意,这里的扩展消息并不是直接添加在明文后面的
- 伪造消息:等于原填充+扩展消息,这才是直接添加在明文后面的内容
- 扩展填充:将明文+伪造消息变为一个新的明文,为计算新明文的 MD5 而添加的填充
可以看到,扩展填充里面的长度为
明文+(原填充+扩展消息) = 明文+伪造消息
的总长度。
老规律,还是来点例题(你不给例题我知道题怎么做啊)
Q1:明文长为96字节,扩展消息长为5字节,请问扩展填充中有多少
0x00
,长度为多少?A1:首先计算原填充,一看1+23+8=32字节,总消息长为96+32+5=133字节,最后一个分组5字节,填充50个
0x00
,长度为133*8=1064
Q2:明文长为55字节,扩展消息长为120字节,请问扩展填充中有多少
0x00
,长度为多少?A2:首先计算原填充,一看1+0+8=9字节,总消息长为55+9+120=184字节,最后一个分组56字节,填充63个
0x00
,长度为184*8=1472
Q3:明文长为56字节,扩展消息长为0字节,请问扩展填充中有多少
0x00
,长度为多少?A3:首先计算原填充,一看1+63+8=72字节,总消息长度为56+72+0=128字节,最后一个分组为64字节,填充55个
0x00
,长度为128*8=1024
计算结果
相信明白图1和图2后,聪明的你已经知道该怎么计算添加扩展消息后的 MD5 值了吧。如下图:
我们将明文 MD5 值作为向量的初始值 \(\textbf{V}\),然后把
伪造消息+扩展填充
每64字节分成一组 \(\textbf{B_i}\),送到 \(\textbf{H}_C(\textbf{B_i},\textbf{V})\)
中,就得到了扩展后的 MD5 值。
小工具
这里我写了一个小工具来生成你需要的攻击负载以及对应的杂凑值。(但愿它没有问题)