哈希长度扩展攻击
原理
在密码学和计算机安全中,长度扩展攻击(Length extension attacks)是指针对某些允许包含额外信息的加密散列函数的攻击手段。 该攻击适用于在消息与密钥的长度已知的情形下,所有采取了 H(key||message)
此类构造的散列函数。MD5和SHA-1等基于Merkle–Damgård构造的算法均对此类攻击显示出脆弱性。
攻击的要点在于:
- 攻击者可以控制message
- 攻击者需要知道key的长度,如不知道可以考虑暴力破解
- 攻击已经知道了包含key的一个消息的hash值
- hash算法使用了Merkle–Damgård construction进行数据的压缩(比如MD5、SHA-1等)并采取
H(key||message)
构造
攻击可以达到的效果在于,如果知道一个原消息哈希值 H(key||M1)
及其 key||M1
长度,对于任意的字符串M2
,攻击者可以计算出 H(pad(key||M1) + M2)
的值,而不需要知道是 key
及 M1
是多少。
以区块为单位操作数据(MD5, SHA1, SHA256的区块长度是512 bits,大多数message的长度不会刚好可以被哈希函数的区块长度整除。这样一来,message就必须被填充(padding)至区块长度的整数倍)。
每个消息块都会和一个输入向量做一个运算,把这个计算结果当成下个消息块的输入向量 ,初始化向量是定义好的,在最后一块的时候,才会将其对应的链接变量转换为hash值。
由已知的MD5值逆向得到对应的链接变量,利用得到的链接变量对填充后的新加的消息进行哈希算法,最后得到hash值。
步骤
MD5操作流程:
用 md5 函数作为例子。 md5 算法在计算的时候会初始化四个寄存器 A、B、C、D
,分别有自己的初始值:
1 | word A: 01 23 45 67 |
md5 算法是以 512bit 为一个块进行迭代计算的,第一个块计算完后,四个寄存器的值就会被更新,如果还存在下一个块,就会在现在四个寄存器里面的数值的基础上继续迭代计算,等全部的块计算完成后,四个寄存器中的十六进制连接起来,就是最终的 MD5 值。换句话说,也就是当第一个块计算完成后,此时四个寄存器中存储的就是第一个块的 MD5 值,接着在这个基础上继续迭代计算下一个块。
如果当前的数据长度不满足对 512bit 求余为 448bit 的时候,需要补至满足这个条件,填充的方法如下:
首先补一个 1(二进制位上的一个 1,不是十进制的 1)
接着在后面补 0(同样是二进制位上的 0),直到满足比特长度对 512 求余为 448 这个条件。
接着补 64bit 的长度,这个长度是在补 1 和 0 以前的长度,如果长度超出了 64bit,那么就取低 64bit。
换句话说:补完的一个块可能是这个样子的:raw_data + '\x80' + '\x00'*n + '\x00\x00\x00\x00\x00\x00\x00\x00'
第一个 raw_data
的部分就是原始的数据,第二个部分 \x80
是一开始补的一个二进制位 1,接着补若干个 \ x00
,直到整个长度达到 56Byte,最后的 8Byte 就是 raw_data
的长度,如果 raw_data
的长度超过了 2^64bit,则取低 64bit。
MD5 算法中的补位的这部分,就是实现长度扩展攻击的关键。
通过长度扩展攻击,我们可以利用 md5 的一些 trick 绕过这个限制。这个问题实际上变成了:如何在不知道 salt/key/secret 的情况下,计算出一个文件名的合法 hash 值。
通过前面对 md5 算法的了解,我们知道,当一个块计算完成后,ABCD 四个寄存器中的值就是刚计算完的 hash 值,如果后面还有数据块,那么会在已有的 ABCD 四个寄存器中的值上进行更新。
那么如果我们将 ABCD 四个寄存器中的值设置为 test.pdf 对应的 hash 值,那么就相当于 MD5 的计算过程中,已经完成了对前一个块的计算,接着向下计算就可以了。
1 |
|
里面的 64 个 A 无所谓是什么,只是为了让 MD5 进行一个块的计算,然后我们将四个寄存器中的值改掉,注意大小端。然后计算附加数据的 MD5。
工具
HashPump:https://github.com/bwall/HashPump
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15$ hashpump -h
HashPump [-h help] [-t test] [-s signature] [-d data] [-a additional] [-k keylength]
HashPump generates strings to exploit signatures vulnerable to the Hash Length Extension Attack.
-h --help Display this message.
-t --test Run tests to verify each algorithm is operating properly.
-s --signature The signature from known message.
-d --data The data from the known message.
-a --additional The information you would like to add to the known message.
-k --keylength The length in bytes of the key being used to sign the original message with.
Version 1.2.0 with CRC32, MD5, SHA1, SHA256 and SHA512 support.
<Developed by bwall(@botnet_hunter)>
$ hashpump -s '6d5f807e23db210bc254a28be2d6759a0f5f5d99' --data 'count=10&lat=37.351&user_id=1&long=-119.827&waffle=eggo' -a '&waffle=liege' -k 14
0e41270260895979317fff3898ab85668953aaa2
count=10&lat=37.351&user_id=1&long=-119.827&waffle=eggo\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02(&waffle=liegehash_extender:https://github.com/iagox86/hash_extender
1
2
3
4
5let secret = "secret"
let data = "data"
let H = md5()
let signature = hash(secret || data) = 6036708eba0d11f6ef52ad44e8b74d5b
let append = "append"1
2
3
4
5$ ./hash_extender --data data --secret 6 --append append --signature 6036708eba0d11f6ef52ad44e8b74d5b --format md5
Type: md5
Secret length: 6
New signature: 6ee582a1669ce442f3719c47430dadee
New string: 64617461800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005000000000000000617070656e64hexpand:https://github.com/amlweems/hexpand
1
2
3
4
5
6
7
8
9
10
11
12
13
14Usage:
hexpand -t type -s signature -l length -m message
hexpand --test
Options:
-t --type the hash algorithm for expansion (md5, sha1, sha256, or sha512
-s --sig the result of the original hash function
-l --length the length of the original message
-m --message the message to be appended
--test runs a set of test cases
$ ./hexpand -t md5 -s cd9fb5c3a20e29b2b2846deaa845c426 -l 55 -m "\nP.S. Tell Eve our secret plan"
Append (hex): 80b8010000000000005c6e502e532e2054656c6c20457665206f75722073656372657420706c616e2e
Signature: 69b0e397b5588c86aa9751b56f2c6943
参考