Hash Attack
常见的Hash函数的攻击方法主要有
暴力攻击:不依赖于任何算法细节,仅与Hash值长度有关;
生日攻击法(Birthday Attack):没有利用Hash函数的结构和任何代数弱性质,只依赖于消息摘要的长度,即Hash值的长度。
中点交会攻击法(Meet-In-The-Middle):是生日攻击的一种变形,不比较Hash值,而是比较中间变量。这种攻击主要适用于攻击具有分组链结构的Hash方案。
密码分析:依赖于具体算法的设计缺点。
暴力攻击
HashCat 工具 可以说是目前最好的基于 CPU 和 GPU 破解 Hash 的软件,相关链接如下
哈希长度拓展攻击(hash length extension attacks)
介绍
基本定义如下,源自维基百科。
哈希长度扩展攻击(Hash Length Extension Attacks)是指针对某些允许包含额外信息的加密散列函数的攻击手段。该攻击适用于在消息与密钥的长度已知的情形下,所有采取了 H(key ∥ message) 此类构造的散列函数。MD5和SHA-1 等基于 Merkle–Damgård 构造的算法均对此类攻击显示出脆弱性。
这类哈希函数有以下特点
消息填充方式都比较类似,首先在消息后面添加一个1,然后填充若干个0,直至总长度与 448 同余,最后在其后附上64位的消息长度(填充前)。
每一块得到的链接变量都会被作为下一次执行hash函数的初始向量IV。在最后一块的时候,才会将其对应的链接变量转换为hash值。
一般攻击时应满足如下条件
我们已知 key 的长度,如果不知道的话,需要爆破出来
我们可以控制 message 的消息。
我们已经知道了包含 key 的一个消息的hash值。
这样我们就可以得到一对(messge,x)满足x=H(key ∥ message)虽然我们并不清楚key的内容。
攻击原理
这里不妨假设我们我们知道了 hash(key+s) 的 hash 值,其中 s 是已知的,那么其本身在计算的时候,必然会进行填充。那么我们首先可以得到 key+s 扩展后的字符串 now,即
now=key|s|padding
那么如果我们在 now 的后面再次附加上一部分信息extra,即
key|s|padding|extra
这样再去计算hash值的时候,
会对 extra 进行填充直到满足条件。
先计算 now 对应的链接变量 IV1,而我们已经知道这部分的 hash 值,并且链接变量产生 hash 值的算法是可逆的,所以我们可以得到链接变量。
下面会根据得到的链接变量 IV1,对 extra 部分进行哈希算法,并返回hash值。
那么既然我们已经知道了第一部分的 hash 值,并且,我们还知道 extra 的值,那么我们便可以得到最后的hash值。
而之前我们也说了我们可以控制 message 的值。那么其实 s,padding,extra 我们都是可以控制的。所以我们自然可以找到对应的(message,x)满足x=hash(key|message)。
例子
似乎大都是web里面的,,不太懂web,暂时先不给例子了。
工具
如何使用请参考github上的readme。
hash算法设计有误
一些自定义的hash算法可能是可逆的。
Hashinator
题目的逻辑很简单,从一个知名的密码字典"rockyou"挑选出一个password,并且使用多种hash算法随机的哈希32轮。我们需要从最后的hash结果中破解出原始的password。
分析
题目采用的hash算法有:md5,sha1,blake,scrypt。 关键的代码如下:
程序首先通过从
rockyou.txt中随机抽取一个password,作为加密的明文。然后根据抽取的
password的长度,生成一个长度为128 - len(password)的salt。从之前列举的4种hash算法中抽取,组成32轮的哈希运算。
根据之前得到的
password、salt计算出最后给我们的password_hash。
很明显,我们不可能通过逆向hash算法来完成题目。 我们知道所有的可能的明文,首先考虑能否通过构造彩虹表来完成穷举。但是注意到generate_salt()函数中,salt和password的长度组合超过了128byte的长度,并且被注释了
so,只能无奈放弃。
那这样的话,只存在一种可能,也即算法可逆。查看calculate_hash()函数的具体实现,可以发现如下可疑的代码:
重新梳理一下我们知道的信息:
hash_rounds中保存了32轮,即每轮要使用的hash函数句柄。
final_hash是最后给我们的hash结果。
hash_rounds中的内容也会在生成之后打印给我们。
我们希望得到
interim_salt和interim_hash在第一轮的值。interim_salt和interim_hash的长度均为64byte。
仔细观察一下interim_salt和interim_hash的计算方法,可以发现它是可逆的。
这行代码里,我们已知 $interim_hash_1$ 和 $interim_salt_3$,由此可以推出$interim_hash_2$的值,而$interim_hash_2$则是上一轮的interim_hash。 以此方法逆推32次,则可以得到最初的password和salt。
具体的解密脚本为:
原hash算法
Last updated