之前做CTF的题目时碰到了,过了几天再来总结,加深印象。
0x01 介绍
- 哈希长度扩展攻击(hash length extension attacks)是指针对某些允许包含额外信息的加密散列函数的攻击手段。该攻击适用于在消息与密钥的长度已知的情形下,所有采取了基于Merkle–Damgård构造的算法(MD5和SHA-1等)均对此类攻击显示出脆弱性。
- 好了,讲简单点,这到底是个啥意思呢,首先,给你a1、b1对这两个字符串,然后做hash得出M1。
- 这四个数当中,b1、M1都是已知的,a1未知,但是知道a1的长度。
- 那么,当满足上面的条件时,可以使用a1、b2做hash生成M2,注意此时a1仍然是不知道为什么字符串的。
- 现在有没有看懂一点呢~我相信,你现在可能看懂我上面的话了,不过新的疑问就来了,那这玩意有什么用???
0x02 应用
- 这个例子是我在其它的文章看到的,非常好的例子。
- 例如,假设有一个网站,在用户下载文件之前需验证下载权限。这个网站会用如下的算法产生一个关于文件名的MAC:
def create_mac(key, fileName) return Digest::SHA1.hexdigest(key + fileName) End
- 最终产生的URL会是这样:
http://example.com/download?file=report.pdf&mac=563162c9c71a17367d44c165b84b85ab59d036f9
- 当用户发起请求要下载一个文件时,将会执行下面这个函数:
def verify_mac(key, fileName, userMac) validMac = create_mac(key, filename) if (validMac == userMac) do initiateDownload() else displayError() end End
- 这样,只有当用户没有擅自更改文件名时服务器才会执行initiateDownload()开始下载。实际上,这种生成MAC的方式,给攻击者在文件名后添加自定义字串留下可乘之机。
http://example.com/download?file=report.pdf%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%00%00%00%00%00%00%00%00%00%00%00%A8/../../../../../../../etc/passwd&mac=ee40aa8ec0cfafb7e2ec4de20943b673968857a5
- 上面就是一种漏洞利用方式,可以下载到服务器中的文件,url最后面的mac的值就是在不知道key的情况下进行伪造的。我想大家现在应该可以看懂了,那么这又是怎么做到的呢?
0x03 原理
- 这个得说明一md5类似hash算法了,先看下面这张图,我偷来的。。。
- 这图说的是先把一个message分成若干个block,其实就是把一个大的数据段(message),分割成很多个小的数据块(block),message多大没限制,block是为512bit,也就是64个字节,那么这个message不一定正好可以分成这么多个block,所以最后一个block需要填充到64个字节。
- 填充的字节以0x80开头,后面全以00填充。
- 然后用IV(初始向量,其实就是个初始的字符串)和block1做复杂的数学运算(哈哈,我又没法口算md5~),然后把得到的结果和第二个block2运算,一直这样下去直到和最后一个填充过的block进行运算得到最后的hash值。
- 我相信大家肯定看到这里就懂了,如果你还说你不懂,那么,就再看一遍。。。
- 接着说怎么利用这个完成攻击,在之前写的key+message生成md5值,虽然我们不知道key的值 ,但是如果知道key的长度的话,那么我在写message2的值时,可以直接将key+message填充到64字节,然后再写我们真正需要计算的message2,那么message2就是另外一个block了,而key和message的hash值我们是知道的,所以就相当于IV我们知道了,再用它和message2做hash,结果必然也是能够计算出来的,这样就实现了计算md5值!
总结
- 具体实现大家可以去看我博客中,“实验吧-CTF”中的“让我进去”这篇文章,这里就不重复说明了。