@highKer12月前

09/22
03:08
杂谈

通过一道CTF题浅析哈希长度扩展攻击

所谓的Hash,翻译过来呢,也就是“散列”,这里就简单的将其替换为音译“哈希”。

对于不同的哈希算法,其总会有一个共同的特点“对于输入的数据,不管其长度,经过哈希算法运算后总会是一个固定的长度”。也就是说,对于散列空间,通常输入数据的空间是远大于散列空间的。而对于散列值,相同的输入是有可能会散列成相同的输出,所以不可能从散列值来确定唯一的输入值。

  • 简单来讲,所谓的将数据经由哈希算法加密,实际上就是“信息摘要”。

而我们在这里就以某道CTF题目中遇到的问题来做研究,接下来我们将亲自“破解MD5”!

那么有些对MD5有些认知的同学可能会说:“破解MD5?吹什么牛X呢,把自己当王小云博士了啊”,但是我想说的是,不妨看完再说。

当然了,具体的实现我也就不会去深究了,免得在大佬面前班门弄斧。

哈希长度扩展攻击,本质是针对由于很多哈希算法比如非常流行的MD5、SHA-1等都使用了Merkle–Damgård construction进行数据压缩。

在MD5中,首先算法将消息以512-bit64bytes)的长度分为了n组。而最后一组必然不足512-bit,这时候算法就会自动往最后一组中填充字节,这个过程被称为Padding。Padding的规则是,在最末一个字节之后补充0x80,其余的部分填充为0x00,而Padding最后的8字节用来表示需要哈希的消息长度。

在这里直接看那道题的源码

  • 从源码中可以提取到重要的信息

首先,明文长度为$secret.urldecode("admin"."admin")(在PHP中“.”是连接符),前面给出$secret的长度为15位,也就是该脚本会下发给浏览器一个cookie,字段名为“sample-hash”,值为该明文的md5加密值(所给值为571580b26c65f306376d4f64e53cb5c7)。

那么我们可知,flag获取的要求是:传进一个cookie使其等于$secret.urldecode($username . $password)MD5加密后的结果且$password不能为admin。

  • 综上,我们可以尝试构造payload_1

首先是$secret的15个未知位,在这里我直接用问号代替表示,之后按照源码的提示,跟上字符串“adminadmin”

接下来便是对其进行字节填充,在末尾加入0x80,之后为0x00,在最后的8个字节,要表明哈希的长度,总长度为15+10=25,转为16进制,即为0xC8

这时我们已经填充到了64bytes,完成了Padding,接下来MD5算法开始依次对每组消息进行压缩,经过64轮数学变换。这个过程中,一开始会有定义好的初始化向量,为4个中间值,初始化向量不是随机生成的,是标准里定义死的。

  • 实施Length Extension Attack

在这里要将原哈希值(571580b26c65f306376d4f64e53cb5c7)拆分为四组,即为:571580b2;6c65f306;376d4f64;e53cb5c7

在此将四组数值按照小端规则反序,可得如下四组

  • A=0xb2801557;
  • B=0x06f3656c;
  • C=0x644f6d37;
  • D=0xc7b53ce5;

若向补位后的消息再追加一条消息字符串“Hacker”,则会对这个字符串进行补位,再利用上一个运算算出的值作为初始向量进行函数运算,最终得到的MD5值为6df6547d222c30afcb9fd3809dc04c13。

  • 构造payload_2

按照源码提示,直接构造$username="admin",$password="admin%80%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%

00%00%00%00%00%00%00%00%00%00%00%00%00%c8%00%00%00%00%00%00%00Hacker"即可

参靠文章:

1、浅析哈希长度拓展攻击

2、Understanding MD5 Length Extension Attack

通过一道CTF题浅析哈希长度扩展攻击