Hash长度扩展攻击
在ctf题里遇到一个hash长度攻击的题
关键代码:
|
|
这里的secret我们不可知 但是我们知道它的长度 这就是在设计了hash扩展长度攻击
介绍一下MD5算法
上面的图示是转载别人博客上的
MD5会把原数据分成512为一块的许多块,最后一块加上64字节来表示他的长度,一共构成512*n个字节然后再对这N个512数据块进行N次加密计算
举个例子
比如计算字符串“test”
十六进制0x74657374
二进制0b1110100011001010111001101110100
md5后面运算过程都是需要512比特为一组来进行运算,先说一下简单的数据比较少 不存在分组的时候的填充,首先512比特的末尾64比特是存放原明文消息的长度,512比特开始是明文数据紧接着明文后填一位1(2进制),其余全是0,假设我明文就一个字符串‘test’那么填充就是0x74657374800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000
最后的四字节 2000000000000000 代表’test’长度
将补位后的数据进行一次复杂的运算,计算出
A=0xcd6b8f09
B=0x73d32146
C=0x834edeca
D=0xf6b42726
因为数据小于512位 将ABCD通过小端规则转换就是MD5值
如果输入不是test 而是大于512小于1024就要算两次,大于1024小于1536就要算3次
用前面一次的512的ABCD值来计算后面一次512ABCD值,直到最后一次数据小于512位
那么 两个字符串组成一个字符串($str=$a+$b),第一个字符串不可知也不可控,只可控第二个字符串(b),同时知道第一个字符串(a)的MD5值和长度,把第二个字符串构造一下,就可以算出(str)的MD5值
假如$a = “test”,为了方便转为十六进制0x74657374
构造第二个字符串首先手动把$str补为一个标准的可以直接计算的512位 就像上面的例子的
然后我们添加一个0x746573748
使得str大于512小于1024位 补充之后是
|
|
我们可以计算前面一部分的ABCD的值,和之前test计算值相同
第二部分就用第一部分的ABCD再去计算 算出来是:
|
|
我们知道的条件:
a的MD5值 a的长度 = 4 b为我们控制
由第一个可以得到ABCD(逆算) 我们构造
|
|
str里的a我们不知道 假设四个长度a=“aaaa”
|
|
我们再继续算str
因为大于512位,补为1024位,分为两个部分,计算第一个部分ABCD值,再用第一部分算出来的ABCD算第二部分
因为第一部分ABCD我们可以逆推出来,我们可以直接进行用第一步ABCD算第二部分的值,只需要把标准MD5值改为逆推的值