Hash长度拓展攻击

"CTF"

Posted by y1r0nz on December 19, 2017

前言

​ 基于Hash拓展长度攻击的CTF比赛题层出不穷,这里对这种攻击方式做下总结。

​ Hash散列是密码学中比较著名的单向加密模式,单向顾名思义,即密文不可逆且唯一。关于Hash散列的另一种解释是(预映射,pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值,也就是一种压缩映射。


0x01 关于Hash长度拓展攻击

​ md5哈希加密的总体结构图,基于Merkle-Damgard构造

img

​ 上图可以看出,Merkle–Damgård算法的流程如下:

​ 1. 把消息划分为n个消息块

​ 2. 对最后一个消息块做长度填充

​ 3. 每个消息块都会和一个输入向量做一个运算,把这个计算结果当成下个消息块的输入向量

​ 4. IV这个初始化向量是知道的且固定不变

​ 进行Hash长度拓展攻击需要以下几个初始条件:

​ 1.知道密文secret的长度

​ 2.知道一个密文secret的Hash值

​ 这样在不知道密文的条件下可以推算出密文+填充bit位(填充0补齐到消息长度mod 512bit = 448)+追加长度的Hash值,也就是在知道上述两个条件的情况下,可以预测出密文和另一消息拼接后的Hash值。


0x02 Hash算法流程

​ 这里以MD5算法为例。MD5算法主要包含三大步骤:

​ 1.padding:填充bit

​ 2.length:填充长度

​ 3.vector:初始化向量

​ 4.Process:进行复杂的函数运算

​ 这里关于复杂函数Process的运算无需我们关注,因为针对Hash拓展长度的攻击与复杂函数的运算无关,只需要关心前三步就可以。

​ 具体流程如下:

​ 1.根据消息长度填充字节,填充后的长度需满足 消息长度 mod 512bit =448bit,打个比方,假如消息是”admin”,则这个消息的长度是5*8bit=40bit,所以要填充408bit。

​ 2.不管消息长度是多少,都需要填充的,即使消息长度mod 512bit=448bit。

​ 3.padding部分第一个字节是0x80,剩余用0x00填充,这是数据本身定义。

​ 4.之后填充消息长度,填充长度大小是64bit,长度大小以小端格式存储,即高字节放在高地址中。

​ 在hashpump中对消息’admin’的填充结果如下图所示:

img

​ 因为初始化向量值为默认的固定值:

​ A 01 23 45 67 0x67452301

​ B 89 AB CD EF 0xEFCDAB89

​ C FE DC BA 98 0x98BADCFE

​ D 76 54 32 10 0x10325476

​ 之后,进行复杂函数运算MD5(vector,’admin’+padding+length)得到消息’admin’的md5值


0x03 理解Hash长度拓展攻击

​ 这里以实验吧的ctf web题为例子举例:

img

​ 题中可以知道,sample-hash的值我们是知道的,secret的长度我们也知道secret本身长度是15,加上后面的admin,长度就是20,数据admin,不满448bit,在16进制下把消息补至448bit,也就是56byte。之后进行最初消息位数的补位,此题的长度是25byte=25*8=200bit,换算成16进制为0xc8,故上图第57位为c8,之后继续补00到64byte,填充过后的64byte如下图所示,这里要注意的是MD5中存储的是小端的方式。

img

​ 通俗一点说,就是本来我们不知道secret是什么,只知道md5(secret)的值,只要知道secret的长度,人为将他补齐,在新的64byte分组中加入自己想要得到md5值的原值并继续填充为新的分组,填充过后的hex值如下图

img

​ 这里我们可以知道XXXXXXXXXXXXXXXadminadmin第一个分组的MD5加密值为571580b26c65f306376d4f64e53cb5c7,回顾我们之前的Merkle-Damgard构造图,这个MD5的值就是下个分组的初始化向量,其中:

A=0xb2801557

B=0x06f3656c

C=0x644f6d37

D=0xc7b53ce5

​ 这样,再经过复杂函数的运算后就可以在不用知道secret情况下得到我们想要字符串的MD5哈希值了。


0x04 工具使用

​ 为了方便,这里参考网上大多数教程的hashpump这个工具

sudo git clone https://github.com/bwall/HashPump

sudu apt-get install lib++ libssl-dev

cd /HashPump

make

make install

​ 在输入已知的Hash值(作为初始化向量),secret长度和需要加密的字符串’y1r0nz’之后得到新的add分组,放入md5算法中又会进行下一轮的复杂函数运算,最终得到想要知道字符串’y1r0nz’的MD5哈希值

img

​ 将得到的md5值作为cookies的getmein,把\x替换为%后,作为post的password提交即可(题目的username必须为’admin’)


0x05 参考文献

http://www.cnblogs.com/pcat/p/5478509.html

http://blog.nsfocus.net/hash-length-extension-attack/