Hash算法原理简化版
分组不够56字节用\x80\x00\x00…补够,然后最后八字节为长度描述符,由Hash算法补充,一共64字节。
长度描述符计算的是文本的真实长度(单位bit,1字节=8 it),不包含填充长度。
Hash长度扩展攻击原理
从图1中可以看出,Hash算法初始向量是固定的,第n个向量可以通过第n-1个向量与第n个分组计算得出。这个第n个向量经高低位互换后也就是这个文本的Hash值。
假设有两个不同的字符串str1和str2,他们的分组1相同,str2有分组2而str1没有。
1 | str1: 分组1 |
那么由于他们的分组1相同,所以向量1也相同(初始向量和分组1计算得到向量1)。
正常的Hahs算法为下图中的实线部分。
解释虚线部分:
由str1的Hash值(经高低位互换后成为向量1)和str2的分组2计算也可以得到str2的Hash值。这个就是Hash长度扩展攻击的利用原理。
利用场景如下。
Demo
1 | <?php |
这里的md5($key.$text) 就相当于上面str1的Hash值,分组1是
1 | $key(21字节) + "guest"(5字节) + "\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"(30字节) + "\x00\x00\x00\x00\x00\x00\x00\xd0"(8字节) |
根据前面的原理,我们构造一个str2,让它的分组1和str1的分组1相同,分组2为包含admin
用以绕过检查。然后用str1的分组1(已知,即str1的hash值高低位互换)计算出str2的hash值。
str2字符串的值为:
1 | $key(21字节) + "guest"(5字节) + "\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"(30字节) + "\x00\x00\x00\x00\x00\x00\x00\xd0"(8字节) + "admin" |
Hashdump可以帮我们自动化计算:
1 | root@kali2018:~/md5/HashPump# ./hashpump |
所以提交$_COOKIE['verify']=84b4590d78bf2a8cdd5612cad68e4ab5
,username=guest%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%f8%00%00%00%00%00%00%00admin
即可。