[THM] Crypto Failures

文章发布时间:

文章总字数:
1.6k

[THM] Crypto Failures

信息收集

首先使用nmap查看端口情况,发现只开放了80和22端口

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
nmap -sV -sC -v 10.49.141.45 
Starting Nmap 7.95 ( https://nmap.org ) at 2026-02-07 03:16 EST
NSE: Loaded 157 scripts for scanning.
NSE: Script Pre-scanning.
Initiating NSE at 03:16
Completed NSE at 03:16, 0.00s elapsed
Initiating NSE at 03:16
Completed NSE at 03:16, 0.00s elapsed
Initiating NSE at 03:16
Completed NSE at 03:16, 0.00s elapsed
Initiating Ping Scan at 03:16
Scanning 10.49.141.45 [4 ports]
Completed Ping Scan at 03:16, 0.22s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 03:16
Completed Parallel DNS resolution of 1 host. at 03:16, 0.04s elapsed
Initiating SYN Stealth Scan at 03:16
Scanning 10.49.141.45 [1000 ports]
Discovered open port 22/tcp on 10.49.141.45
Discovered open port 80/tcp on 10.49.141.45
Completed SYN Stealth Scan at 03:16, 17.15s elapsed (1000 total ports)
Initiating Service scan at 03:16
Scanning 2 services on 10.49.141.45
Completed Service scan at 03:16, 6.42s elapsed (2 services on 1 host)
NSE: Script scanning 10.49.141.45.
Initiating NSE at 03:16
Completed NSE at 03:16, 5.33s elapsed
Initiating NSE at 03:16
Completed NSE at 03:16, 0.79s elapsed
Initiating NSE at 03:16
Completed NSE at 03:16, 0.00s elapsed
Nmap scan report for 10.49.141.45
Host is up (0.20s latency).
Not shown: 998 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.7 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 57:2c:43:78:0c:d3:13:5b:8d:83:df:63:cf:53:61:91 (ECDSA)
|_ 256 45:e1:3c:eb:a6:2d:d7:c6:bb:43:24:7e:02:e9:11:39 (ED25519)
80/tcp open http Apache httpd 2.4.59 ((Debian))
|_http-server-header: Apache/2.4.59 (Debian)
|_http-title: Did not follow redirect to /
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

NSE: Script Post-scanning.
Initiating NSE at 03:16
Completed NSE at 03:16, 0.00s elapsed
Initiating NSE at 03:16
Completed NSE at 03:16, 0.00s elapsed
Initiating NSE at 03:16
Completed NSE at 03:16, 0.00s elapsed
Read data files from: /usr/share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 30.22 seconds
Raw packets sent: 1146 (50.400KB) | Rcvd: 1111 (44.436KB)

去80端口查看http服务,进去就是一个页面,提示我是guest用户

然后我先是打算先抓包,看看都有些什么,这里看到抓到两个数据包,第一个给了cookie,然后第二个根据cookie信息显示了页面信息

不过还是不知道怎么利用,先dirsearch爆破下目录,看看有没有其他收获

这里找到一个.bak,应该是一个备份文件,下载到本地查看

利用

获取到的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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
<?php
include('config.php');

function generate_cookie($user,$ENC_SECRET_KEY) {
$SALT=generatesalt(2);

$secure_cookie_string = $user.":".$_SERVER['HTTP_USER_AGENT'].":".$ENC_SECRET_KEY;

$secure_cookie = make_secure_cookie($secure_cookie_string,$SALT);

setcookie("secure_cookie",$secure_cookie,time()+3600,'/','',false);
setcookie("user","$user",time()+3600,'/','',false);
}

function cryptstring($what,$SALT){

return crypt($what,$SALT);

}


function make_secure_cookie($text,$SALT) {

$secure_cookie='';

foreach ( str_split($text,8) as $el ) {
$secure_cookie .= cryptstring($el,$SALT);
}

return($secure_cookie);
}


function generatesalt($n) {
$randomString='';
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
for ($i = 0; $i < $n; $i++) {
$index = rand(0, strlen($characters) - 1);
$randomString .= $characters[$index];
}
return $randomString;
}



function verify_cookie($ENC_SECRET_KEY){


$crypted_cookie=$_COOKIE['secure_cookie'];
$user=$_COOKIE['user'];
$string=$user.":".$_SERVER['HTTP_USER_AGENT'].":".$ENC_SECRET_KEY;

$salt=substr($_COOKIE['secure_cookie'],0,2);

if(make_secure_cookie($string,$salt)===$crypted_cookie) {
return true;
} else {
return false;
}
}


if ( isset($_COOKIE['secure_cookie']) && isset($_COOKIE['user'])) {

$user=$_COOKIE['user'];

if (verify_cookie($ENC_SECRET_KEY)) {

if ($user === "admin") {

echo 'congrats: ******flag here******. Now I want the key.';

} else {

$length=strlen($_SERVER['HTTP_USER_AGENT']);
print "<p>You are logged in as " . $user . ":" . str_repeat("*", $length) . "\n";
print "<p>SSO cookie is protected with traditional military grade en<b>crypt</b>ion\n";
}

} else {

print "<p>You are not logged in\n";


}

}
else {

generate_cookie('guest',$ENC_SECRET_KEY);

header('Location: /');


}
?>

这里的逻辑就是开始的时候判断有没有cookie,如果没有,就是给一个guest身份的secure_cookie

generate_cookie这个函数是设置cookie的,然后verify_cookie是校验cookie的,make_secure_cookie主要的secure_cookie就是通过这个函数生成的

这里的secure_cookieguest:ua头:$ENC_SECRET_KEY三个部分组成,然后每8个字节和盐进行crypt函数,生成一个哈希值,然后根据代码可以发现前两位是盐

我这里的cookie是,这里的cookie需要url解码的

1
Go2eu5Edb%2FTTYGoi5jrmOyFmMsGoogjO7cirQi.GoQHXoTuuJtsUGoaUC8ZvmJp7AGoySg6M9UxtcoGoqIZO3jfUS5AGo9Db1Q1V9hN2GoTBEcw0It%2FXIGoIxovHkS9MdMGo4dC0N3WpuEsGoJgdIAfmw%2FWUGo6Q0goQWz%2FawGoCdkLScbHTHkGouqg2Q%2FnuwzwGov90UGSuozPIGothpUYnNE07oGoE.zA8Zkx40YGoYW..mZv4IDUGoaF2qa6cQYvIGoiVfvtXMTeEEGoTSjARy%2Fp6jQGoWvkTU0YbhrcGoCkPABb0FIZsGojPxKg7FJ9KMGo3YgvFvNK5PQGoiBplbYMaJwoGod8VkqQw2adYGoLpmvrxMAgO2GowefcfLfAGPIGodYE5TWxTmykGoNew%2FnqC4ttgGo8VEosThGyiE

然后我查看了我的ua头,每8个字节排列,使用phpprint crypt("admin:Mo", "Go");发现正好是符合的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
guest:Mo 
zilla/5.
0 (X11;
Linux x8
6_64) Ap
pleWebKi
t/537.36
(KHTML,
like Gec
ko) Chro
me/142.0
.0.0 Saf
ari/537.
36

那么第一个flag感觉是需要admin身份才可以获得,突然发现正好ua头的前两个Mo加上guest:admin:是一样的长度啊,那我们可以生成一个哈希值,来替换第一块的哈希值,那样不就是admin身份了吗?

果然这里很容易就拿到了我们的flag

Snipaste_2026-02-07_18-00-23

获取key

有了前面拿flag的经验,我就想guest:这是6个字节,如果ua头就两个,那么后面就全是key的了,直接爆破就可以拿到key了

不过想法很美好,8个字节,任意可读字符的搭配实在是太大了,根本爆破不下来

我去看了其他大佬wp的思路,我发现了另一个做法,就是每次爆破一个字节,这样确实可以提高很多的效率啊

这里的爆破逻辑是:

比如一开始的guest::这里是7个字节,那么key的第一个字节加上正好是8个,其中7个已经知道,很容易达到第一个

之后key的第二个字节,guest::的7个加上爆破出来的一个key,就是有了9个,但是要凑16个字节,还要7个,这些就可以放到ua头中

那么接下来通过控制ua头的长度,来一点点通过对应的cookie中的那一部分来进行匹配从而爆破出key的结果,最后推导出来的ua头部公式如下

1
ua = A*(7-len(“guest::”)-len[n])%8

不过作为一个半吊子的脚本小子,代码能力实在是捉襟见肘,这里就直接使用其他大佬的脚本跑了一下,也是懦夫的拿到了flag

总结

过去我的代码的能力一直没有作为重点提升,过去很长时间都只是使用别人提供的工具,确实是需要提升自己代码能力了