Delivery
Executive summary — Delivery is an Easy Linux box that isn't solved with a technical exploit but by chaining logic flaws: osTicket is used as an indirect mailbox (
<ticketID>@delivery.htb) to bypass Mattermost's email verification and get in; inside, an internal channel leaksmaildeliverer's SSH credentials and the hint that root's password is a variation of «PleaseSubscribe!». A Mattermost configuration file exposes its database credentials, which we use to dump root's bcrypt hash; with the hint in hand we apply hashcat rules instead of brute force to crack the password, which turns out to be reused as the system's root password. An osTicket → Mattermost → SSH → MySQL → hashcat rules → root path.
| Platform | Hack The Box |
| Operating system | Linux |
| Difficulty | Easy |
| Status | Retired |
| Target IP | 10.129.23.103 |
Attack map
[80] delivery.htb + [helpdesk] osTicket + [8065] Mattermost
│ osTicket (guest): open a ticket → «<ticketID>@delivery.htb» mailbox
│ Check Ticket Status trusts email+ID → an unvalidated mail viewer
│ register on Mattermost with that email → read the confirmation in the ticket
▼
[Mattermost] internal channel leaks: maildeliverer SSH creds + hint «root ~ PleaseSubscribe!»
▼
[SSH] maildeliverer : Youve_G0t_Mail! (user.txt)
│ /opt/mattermost/config/config.json → mmuser:Crack_The_MM_Admin_PW
│ MySQL → Users table → «root» bcrypt hash
▼
[hashcat] base «PleaseSubscribe!» + best64 rules → PleaseSubscribe!21
▼
[ROOT] su - (password reuse) → root.txt
1. Reconnaissance
We start by mapping the attack surface with two nmap passes: a fast sweep across every TCP port, then a second one with scripts and version detection against the ports found.
nmap -p- --min-rate 10000 10.129.23.103
nmap -p22,80,8065 -sC -sV 10.129.23.103
22/tcp open ssh
80/tcp open http
8065/tcp open http (Mattermost)
Hypothesis: a public web port (80) plus a secondary application (8065) plus open SSH is a very typical pattern for an easy box: the entry point is the web app, and the end goal is reusable credentials for the system.
Resumen ejecutivo — Delivery es un Linux Easy que no se resuelve con un exploit técnico, sino encadenando fallos lógicos: osTicket se usa como buzón de correo indirecto (
<ticketID>@delivery.htb) para saltarse la verificación de email de Mattermost y entrar; dentro, un canal interno filtra credenciales SSH demaildeliverery la pista de que la contraseña de root es una variación de «PleaseSubscribe!». Un archivo de configuración de Mattermost expone las credenciales de su base de datos, de donde sacamos el hash bcrypt de root; con la pista aplicamos reglas de hashcat en vez de fuerza bruta y craqueamos la contraseña, que además está reutilizada como la del usuario root del sistema. Recorrido osTicket → Mattermost → SSH → MySQL → hashcat rules → root.
| Plataforma | Hack The Box |
| Sistema operativo | Linux |
| Dificultad | Easy |
| Estado | Retired |
| IP objetivo | 10.129.23.103 |
Mapa del ataque
[80] delivery.htb + [helpdesk] osTicket + [8065] Mattermost
│ osTicket (invitado): abrir ticket → buzón «<ticketID>@delivery.htb»
│ Check Ticket Status confía en email+ID → visor de correo sin validar
│ registrarse en Mattermost con ese correo → leer la confirmación en el ticket
▼
[Mattermost] canal interno filtra: creds SSH de maildeliverer + pista «root ~ PleaseSubscribe!»
▼
[SSH] maildeliverer : Youve_G0t_Mail! (user.txt)
│ /opt/mattermost/config/config.json → mmuser:Crack_The_MM_Admin_PW
│ MySQL → tabla Users → hash bcrypt de «root»
▼
[hashcat] base «PleaseSubscribe!» + reglas best64 → PleaseSubscribe!21
▼
[ROOT] su - (reutilización de contraseña) → root.txt
1. Reconocimiento
Empezamos mapeando la superficie de ataque con dos pasadas de nmap: una barrida rápida de todos los puertos TCP y una segunda con scripts y detección de versión sobre los puertos encontrados.
nmap -p- --min-rate 10000 10.129.23.103
nmap -p22,80,8065 -sC -sV 10.129.23.103
22/tcp open ssh
80/tcp open http
8065/tcp open http (Mattermost)
Hipótesis: web pública (80) + aplicación secundaria (8065) + SSH abierto es un patrón muy típico de máquina fácil: la entrada va por la web y el objetivo final es conseguir credenciales reutilizables para el sistema.
2. The main site and the vhosts
The site on port 80 doesn't have much functionality, but it mentions a helpdesk and warns that accessing Mattermost requires an email on the @delivery.htb domain. It also references delivery.htb and helpdesk.delivery.htb, which we add to /etc/hosts:
echo "10.129.23.103 delivery.htb helpdesk.delivery.htb" | sudo tee -a /etc/hosts
Why: many applications serve different content depending on the Host header or a specific subdomain; without resolving those names locally we'd lose entire routes. The
@delivery.htbemail requirement already hints at the key restriction: we don't control that domain… or so it seems.
3. The helpdesk: osTicket as an indirect mailbox
helpdesk.delivery.htb is an osTicket instance with a very specific logic: anyone can open a ticket as a guest with any email address, then check its status via Check Ticket Status by entering just email + ticket number. We open a ticket with an arbitrary email (e.g. test@test.com) and note the ticket number it's given.
The logic flaw: osTicket trusts that whoever knows the email and the ticket number is the legitimate owner, without ever validating that email. In a real system, if a ticket contains sensitive messages sent by email, you'd want strong guarantees that the user actually controls that address — here there are none, turning the helpdesk into an abusable mail viewer.
And here's the piece that ties everything together: when you open a ticket, osTicket also assigns you an email address on its own domain, <ticketID>@delivery.htb. Mail arriving at that address can be read from the ticket itself. Without ever controlling delivery.htb, we've still obtained a valid mailbox on it.
4. Practical bypass: registering on Mattermost
At http://delivery.htb:8065 we register on Mattermost using exactly that <ticketID>@delivery.htb address. Mattermost requires email verification and sends a confirmation email… which, being an internal email on that domain, lands right in our own osTicket ticket. We read it via Check Ticket Status, click the verification link, and the account is now active.
The lesson: we didn't need to break Mattermost's verification directly; it was enough to find another system (the helpdesk) that received and exposed those emails for us. Systems that talk to each other —helpdesk + email + chat— amplify each other's risk.
5. Inside Mattermost: leaked credentials
Once authenticated, we join the team and browse the available channels. In one internal channel, a privileged user has left credentials and a very specific hint about root's password:
maildeliverer : Youve_G0t_Mail!
# note: root's password is a variation of PleaseSubscribe!
The box changes phase here: up to now we were exploiting web logic; from here on it's credential reuse and lateral movement.
PleaseSubscribe!isn't root's password yet, but it's a very strong semantic hint for the escalation.
6. Initial access over SSH
Port 22 was open from the initial recon; with leaked credentials and SSH active, testing for credential reuse is one of the first mandatory moves:
ssh maildeliverer@10.129.23.103
# password: Youve_G0t_Mail!
cat ~/user.txt
Initial access confirmed. Time for local enumeration.
7. Local enumeration: Mattermost's configuration
We know Mattermost runs on the box itself, so we check its configuration for database credentials or application secrets:
cd /opt/mattermost/config
cat config.json | grep -i sql
mmuser : Crack_The_MM_Admin_PW
Why it matters: there's no CVE or exotic SUID involved —it's a very common operational mistake: an application's configuration file, readable by an already-compromised user, contains the credentials for its own database.
8. The database and root's hash
With those credentials we log into MySQL/MariaDB and go straight to the users table, the natural place to look for usernames, hashes, emails and roles:
mysql -u mmuser -pCrack_The_MM_Admin_PW mattermost
show tables;
select Username,Password from Users;
root $2a$10$...................................... (bcrypt)
Not the operating system's root yet, but a bcrypt hash tied to a «root» account inside Mattermost. On an easy box this usually leads to cracking the hash and testing password reuse —the right path here.
9. Targeted cracking with hashcat rules
Cracking a bcrypt hash blindly is expensive, but we already have the hint from the Mattermost channel: the password is a variation of PleaseSubscribe!. Instead of a huge wordlist, we use that single word as a base and apply mutation rules (best64):
echo "PleaseSubscribe!" > password.txt
hashcat -m 3200 hash.txt password.txt --user -r /usr/share/hashcat/rules/best64.rule
PleaseSubscribe!21
Why it works: hashcat rules generate thousands of variants of a base word (case, numeric suffixes, l33t…). With a password hint we're no longer attacking blindly: we apply a semantic base plus targeted mutations, far more efficient than brute force even against bcrypt. The
--userflag tells hashcat the hash file follows theusername:hashformat.
10. Privilege escalation — password reuse
With the cracked password in hand, we test whether it also works for the operating system's root user:
su -
# password: PleaseSubscribe!21
cat /root/root.txt
Why it works: pure credential reuse. There's no complex local vulnerability involved: a password meant for an application account (Mattermost) turned out to also be the Linux root user's password.
Vulnerability summary
| Phase | Component | Vulnerability | Impact |
|---|---|---|---|
| Bypass | osTicket | Check Ticket Status trusts email + ID without validating ownership → abusable mail viewer | Controlled @delivery.htb mailbox |
| Bypass | osTicket + Mattermost | Mattermost's confirmation email is readable from the ticket → email verification bypassed | Active Mattermost account |
| Foothold | Mattermost channel | Plaintext SSH credentials leaked + root password hint | SSH as maildeliverer |
| Local enumeration | Mattermost's config.json | Database credentials in a readable configuration file | MySQL access (mmuser) |
| PrivEsc | Mattermost DB + hashcat | Root's bcrypt hash + weak password pattern crackable with targeted rules | Root (password reuse) |
Lessons learned
- Web enumeration is king: the entry point wasn't SSH or an unusual port, it was understanding the relationship between services (helpdesk ↔ email ↔ chat).
- Logic flaws are just as dangerous as technical ones: no RCE was needed in osTicket, just abuse of its ticket logic and the missing email validation.
- Interconnected systems amplify risk: helpdesk + email + internal chat formed a chain that none of the three, on its own, would have allowed.
- Don't trust «email + ID» as proof of ownership: require real verification of the email, not just knowledge of it.
- Configuration files are gold: if an attacker can read
config.json, they'll likely walk away with database credentials, API keys, or tokens. - Hints matter, and pattern-based passwords fall: «PleaseSubscribe!» looked like an innocent phrase in a chat, but it was the semantic base that made cracking trivial with hashcat rules, even against bcrypt.
- Password reuse kills: an application account's password doubling as the system's root password is a very realistic, very common failure.
2. La web principal y los vhosts
La página del puerto 80 no tiene demasiada funcionalidad, pero menciona un helpdesk y avisa de que para acceder a Mattermost hace falta un correo del dominio @delivery.htb. Aparecen además los nombres delivery.htb y helpdesk.delivery.htb, que añadimos a /etc/hosts:
echo "10.129.23.103 delivery.htb helpdesk.delivery.htb" | sudo tee -a /etc/hosts
Por qué: muchas aplicaciones sirven contenido distinto según el Host header o un subdominio concreto; sin resolver esos nombres localmente perderíamos rutas enteras. El requisito del correo
@delivery.htbya apunta a una restricción clave: no controlamos ese dominio… o eso parece.
3. El helpdesk: osTicket como buzón indirecto
helpdesk.delivery.htb es una instancia de osTicket, con una lógica muy concreta: cualquiera puede abrir un ticket como invitado con el correo que quiera, y luego consultar su estado con la opción Check Ticket Status introduciendo solo email + número de ticket. Abrimos un ticket con un correo cualquiera (p. ej. test@test.com) y guardamos el número asignado.
El fallo lógico: osTicket confía en que quien conoce el email y el número del ticket es el propietario legítimo, sin haber validado nunca ese correo. En un sistema real, si un ticket contiene mensajes sensibles enviados por email, deberías tener garantías fuertes de que el usuario controla esa dirección — aquí no las hay, y eso convierte al helpdesk en un visor de correos abusable.
Y aquí está la pieza que conecta todo: al abrir un ticket, osTicket te asigna también una dirección de correo de su propio dominio, <ticketID>@delivery.htb. Los correos que lleguen a esa dirección se pueden leer desde el propio ticket. Sin controlar delivery.htb, acabamos de conseguir igualmente un buzón válido en ese dominio.
4. Bypass práctico: registro en Mattermost
En http://delivery.htb:8065 nos registramos en Mattermost usando exactamente ese correo <ticketID>@delivery.htb. Mattermost exige verificación por email y envía un correo de confirmación… que, al ser un correo interno del dominio, aterriza en nuestro propio ticket de osTicket. Lo leemos desde Check Ticket Status, pulsamos el enlace de verificación y la cuenta queda activa.
La lección: no hizo falta romper la verificación de Mattermost directamente; bastó con encontrar otro sistema (el helpdesk) que recibiera y expusiera esos correos por nosotros. Los sistemas conectados entre sí —helpdesk + correo + chat— amplifican el riesgo de cada uno por separado.
5. Dentro de Mattermost: credenciales filtradas
Ya autenticados, nos unimos al equipo y revisamos los canales disponibles. En uno interno, un usuario con privilegios ha dejado credenciales y una pista muy concreta sobre la contraseña de root:
maildeliverer : Youve_G0t_Mail!
# nota: la contraseña de root es una variación de PleaseSubscribe!
Con esto la máquina cambia de fase: hasta ahora explotábamos lógica web; a partir de aquí toca reutilización de credenciales y movimiento lateral.
PleaseSubscribe!aún no es la contraseña de root, pero es una pista semántica muy fuerte para la escalada.
6. Acceso inicial por SSH
El puerto 22 estaba abierto desde el reconocimiento inicial; con credenciales filtradas y SSH activo, probar la reutilización es de los primeros movimientos obligados:
ssh maildeliverer@10.129.23.103
# contraseña: Youve_G0t_Mail!
cat ~/user.txt
Acceso inicial confirmado. Toca ahora la enumeración local.
7. Enumeración interna: configuración de Mattermost
Sabemos que Mattermost corre en la propia máquina, así que revisamos su configuración en busca de credenciales de base de datos o secretos de aplicación:
cd /opt/mattermost/config
cat config.json | grep -i sql
mmuser : Crack_The_MM_Admin_PW
Por qué importa: no hay CVE ni SUID exótico de por medio —es una mala práctica operacional muy común: el archivo de configuración de una aplicación, legible por un usuario ya comprometido, contiene las credenciales de su propia base de datos.
8. La base de datos y el hash de root
Con esas credenciales entramos a MySQL/MariaDB y vamos directos a la tabla de usuarios, el lugar natural donde buscar nombres, hashes, correos y roles:
mysql -u mmuser -pCrack_The_MM_Admin_PW mattermost
show tables;
select Username,Password from Users;
root $2a$10$...................................... (bcrypt)
Aún no es el root del sistema operativo, pero sí un hash bcrypt asociado a una cuenta «root» dentro de Mattermost. En una máquina fácil esto suele derivar en craquear el hash y probar reutilización de contraseña —el camino correcto aquí.
9. Crackeo dirigido con hashcat rules
Craquear un hash bcrypt a ciegas es costoso, pero ya tenemos la pista del canal de Mattermost: la contraseña es una variación de PleaseSubscribe!. En vez de una wordlist gigante, usamos esa única palabra como base y aplicamos reglas de mutación (best64):
echo "PleaseSubscribe!" > password.txt
hashcat -m 3200 hash.txt password.txt --user -r /usr/share/hashcat/rules/best64.rule
PleaseSubscribe!21
Por qué funciona: las reglas de hashcat generan miles de variantes de una palabra base (mayúsculas, sufijos numéricos, l33t…). Con una pista de contraseña ya no atacamos a ciegas: aplicamos una base semántica y mutaciones dirigidas, muchísimo más eficiente que fuerza bruta incluso contra bcrypt. El flag
--userle dice a hashcat que el fichero de hashes lleva el formatousuario:hash.
10. Escalada a root — reutilización de contraseña
Con la contraseña craqueada, probamos si también sirve para el usuario root del sistema operativo:
su -
# contraseña: PleaseSubscribe!21
cat /root/root.txt
Por qué funciona: reutilización de credenciales pura. No hay vulnerabilidad local compleja de por medio: una contraseña pensada para una cuenta de aplicación (Mattermost) resultó ser también la del usuario root del sistema Linux.
Resumen de vulnerabilidades
| Fase | Componente | Vulnerabilidad | Impacto |
|---|---|---|---|
| Bypass | osTicket | Check Ticket Status confía en email + ID sin validar propiedad → visor de correo abusable | Buzón @delivery.htb controlado |
| Bypass | osTicket + Mattermost | El correo de confirmación de Mattermost es legible desde el ticket → verificación de email eludida | Cuenta de Mattermost activa |
| Foothold | Canal de Mattermost | Credenciales SSH filtradas en texto claro + pista de la contraseña de root | SSH como maildeliverer |
| Enumeración local | config.json de Mattermost | Credenciales de base de datos en fichero de configuración legible | Acceso a MySQL (mmuser) |
| PrivEsc | BD de Mattermost + hashcat | Hash bcrypt de root + patrón de contraseña débil craqueable con reglas dirigidas | Root (reutilización de contraseña) |
Lecciones aprendidas
- La enumeración web manda: la entrada no estaba en SSH ni en un puerto raro, sino en entender la relación entre servicios (helpdesk ↔ correo ↔ chat).
- Los fallos lógicos son tan peligrosos como los técnicos: no hizo falta un RCE en osTicket, bastó con abusar de su lógica de tickets y de la falta de validación de email.
- Los sistemas conectados amplifican el riesgo: helpdesk + email + chat interno formaron una cadena que ninguno de los tres, por separado, habría permitido.
- No confíes «email + ID» como prueba de propiedad: exige verificación real del correo, no solo su conocimiento.
- Los archivos de configuración son oro: si un atacante puede leer
config.json, probablemente saca credenciales de base de datos, API keys o tokens. - Las pistas importan y las contraseñas basadas en patrones caen: «PleaseSubscribe!» parecía una frase inocua en un chat, pero fue la base semántica que hizo trivial el crackeo con reglas de hashcat, aunque el hash fuera bcrypt.
- La reutilización de contraseñas mata: una contraseña de una cuenta de aplicación siendo también la de root del sistema es un fallo muy realista y muy común.