哈希长度扩展攻击(hash length extension attacks)--笔记

在密码学和计算机安全中,长度扩展攻击(Length extension attacks)是指针对某些允许包含额外信息的加密散列函数的攻击手段。 该攻击适用于在消息密钥的长度已知的情形下,所有采取了 H(密钥消息) 此类构造的散列函数。MD5和SHA-1等基于Merkle–Damgård构造的算法均对此类攻击显示出脆弱性。注意,由于密钥散列消息认证码(HMAC)并未采取 H(密钥消息) 的构造方式,因此不会受到此类攻击的影响(如HMAC-MD5、HMAC-SHA1)。SHA-3算法对此攻击免疫。(源自维基百科)

攻击的要点在于:

  • 攻击者可以控制message
  • 攻击者需要知道key的长度,如不知道可以考虑暴力破解
  • 攻击已经知道了包含key的一个消息的hash值
  • hash算法使用了Merkle–Damgård construction进行数据的压缩(比如MD5、SHA-1等)并采取 H(密钥消息) 构造

攻击可以达到的效果在于,如果知道一个原消息哈希值H(key∥M1)及其(key∥M1)长度,对于任意的字符串M2,攻击者可以计算出H(pad(key∥M1) + M2)的值,而不需要知道是key及M1是多少

原因在于基于Merkle–Damgård构造哈希函数有类似的特点:

以区块为单位操作数据(MD5, SHA1, SHA256的区块长度是512 bits,大多数message的长度不会刚好可以被哈希函数的区块长度整除。这样一来,message就必须被填充(padding)至区块长度的整数倍)

每个消息块都会和一个输入向量做一个运算,把这个计算结果当成下个消息块的输入向量 ,初始化向量是定义好的,在最后一块的时候,才会将其对应的链接变量转换为hash值。

由已知的MD5值逆向得到对应的链接变量,利用得到的链接变量对填充后的新加的消息进行哈希算法,最后得到hash值。(具体算法:http://blog.chinaunix.net/uid-27070210-id-3255947.html)

如何去防止攻击?使用HMAC可以有效避免攻击;另外针对Flickr API等将参数签名的应用来说,secret放置在 参数末尾也能防止这种攻击。 比如 MD5(m+secret),希望推导出 MD5(m+secret||padding||m’),结果由于自动附加secret在末尾的关系,会变成MD5(m||padding||m’||secret),从而导致Length Extension run不起来。

工具可以采用的有HashPumphexpand ,不同在于HashPump需要提供原始消息数据,而hexpand则不需要


下面以两个CTF题为例:

实验吧-让我进去

首先burpsuit抓包查看,特别的地方在于cookie前两个字段

sample-hash=571580b26c65f306376d4f64e53cb5c7; source=0;

尝试修改source字段为1,返回了原代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
$flag = "XXXXXXXXXXXXXXXXXXXXXXX";
$secret = "XXXXXXXXXXXXXXX"; // This secret is 15 characters long for security!
$username = $_POST["username"];
$password = $_POST["password"];
if (!empty($_COOKIE["getmein"])) {
if (urldecode($username) === "admin" && urldecode($password) != "admin") {
if ($COOKIE["getmein"] === md5($secret . urldecode($username . $password))) {
echo "Congratulations! You are a registered user.\n";
die ("The flag is ". $flag);
}
else {
die ("Your cookies don't match up! STOP HACKING THIS SITE.");
}
}
else {
die ("You are not an admin! LEAVE.");
}
}
setcookie("sample-hash", md5($secret . urldecode("admin" . "admin")), time() + (60 * 60 * 24 * 7));
if (empty($_COOKIE["source"])) {
setcookie("source", 0, time() + (60 * 60 * 24 * 7));
}
else {
if ($_COOKIE["source"] != 0) {
echo ""; // This source code is outputted here
}
}

分析源码可以知道,sample-hash字段为进过MD5加密的字符串”adminadmin”加未知的secret,只知道secret长度为15。要得到flag,需要getmein字段的值为进过MD5加密的输入的username和password加secret的值。并且固定了username为admin,password不能为admin。

这里就用到哈希长度拓展攻击,目前我们知道字符串secret+adminadmin的MD5hash值,secret的长度为15,我们需要添加一个字符串M2,构造字符串为secret+admin+M2,并计算出其MD5值

这里使用hashpump,附加数据至少1位以上

1
2
3
4
5
6
7
root@kali:~/HashPump# hashpump
Input Signature: 571580b26c65f306376d4f64e53cb5c7
Input Data: admin
Input Key Length: 20
Input Data to Add: venture
57545bbf734b02db716893eefe9899ad
admin\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\x00\xc8\x00\x00\x00\x00\x00\x00\x00venture

抓包添加cookie字段getmein,对password反urldecode一下,16进制urlencode即将\x换成%

1
2
3
getmein=57545bbf734b02db716893eefe9899ad
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%00venture

就可以得到flag

Jarvis OJ-flag在管理员手里

index.php~源码泄露 ,查看源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<!DOCTYPE html>
<html>
<head>
<title>Web 350</title>
<style type="text/css">
body {
background:gray;
text-align:center;
}
</style>
</head>
<body>
<?php
$auth = false;
$role = "guest";
$salt =
if (isset($_COOKIE["role"])) {
$role = unserialize($_COOKIE["role"]);
$hsh = $_COOKIE["hsh"];
if ($role==="admin" && $hsh === md5($salt.strrev($_COOKIE["role"]))) {
$auth = true;
} else {
$auth = false;
}
} else {
$s = serialize($role);
setcookie('role',$s);
$hsh = md5($salt.strrev($s));
setcookie('hsh',$hsh);
}
if ($auth) {
echo "<h3>Welcome Admin. Your flag is
} else {
echo "<h3>Only Admin can see the flag!!</h3>";
}
?>
</body>
</html>

这里反序列化在php版本低的时候可以使用%00截断 ,所以反序之后原本添加在后的admin成为首部,之后的部分被00截断

这里知道原数据:;”tseug”:5:s ;原hash值:3a4727d57463f122833d9e732f94e4e0;但salt长度未知需要爆破

需要添加的内容:;”nimda”:5:s

1
2
3
4
5
6
7
root@kali:~# hashpump
Input Signature: 3a4727d57463f122833d9e732f94e4e0
Input Data: ;"tseug":5:s
Input Key Length: 11
Input Data to Add: ;"nimda":5:s
fcdc3840332555511c4e4323f6decb07
;"tseug":5:s\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\x00\x00\x00\xb8\x00\x00\x00\x00\x00\x00\x00;"nimda":5:s

还需要反序

1
role = s%3a5%3a"admin"%3b%00%00%00%00%00%00%00%c0%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%80s%3a5%3a"guest"%3b
文章作者: Venture
文章链接: http://yoursite.com/2018/08/14/hash长度扩展/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Venture's Blog