Nexus
Executive summary — Nexus is a black-box Easy Linux box, with no starting credentials, solved through five tightly-chained phases. Subdomain fuzzing reveals two hidden apps —a Gitea and a Krayin CRM— and the key is that Gitea allows browsing public repos without authentication: one of them has a committed
.env, and although the currentHEADshows it "cleaned", the commit history still holds the original password. That credential works on the Krayin CRM admin login, which is vulnerable to an unrestricted upload (CVE-2026-38526, CVSS 9.9) in its TinyMCE editor: uploading a PHP webshell by simply faking theContent-Typegives RCE aswww-data. The server's real.envleaks another MySQL password that, through password reuse, also unlocks the OS account of userjones(USER). The final escalation abuses a custom systemd timer running as root that syncs Gitea "template repos": the script doesn't sanitise the filenames coming out ofgit ls-tree -r, so a hand-crafted git tree with entries literally named..produces a path traversal that writes an SSH key into root'sauthorized_keys(ROOT). Path: Gitea (secret in history) -> Krayin RCE -> jones (password reuse) -> path traversal in root timer -> SSH root.
| Platform | Hack The Box |
| Operating system | Linux (Ubuntu) |
| Difficulty | Easy |
| Status | Retired |
| Target IP | 10.129.234.54 |
Attack map
[80/HTTP] nexus.htb (static) -> subdomain (vhost) fuzzing
| git.nexus.htb (Gitea) + billing.nexus.htb (Krayin CRM)
v
[Gitea] commit history -> leaked DB_PASSWORD (HEAD clean, history isn't)
| j.matthew@nexus.htb : N27xh!!2ucY04
v
[Krayin CRM] admin login -> CVE-2026-38526 (unrestricted TinyMCE upload) -> RCE
v
[SHELL] www-data -> real .env -> reused MySQL password
v
[jones] (user.txt)
| gitea-template-sync.timer (root, every minute) -> path traversal in ls-tree -r
v
[ROOT] arbitrary write to root's authorized_keys -> SSH root (root.txt)
1. Reconnaissance and hidden subdomain discovery
nmap -sC -sV -T4 10.129.234.54
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 9.6p1 Ubuntu 3ubuntu13.16
80/tcp open http nginx 1.24.0 (Ubuntu)
|_http-title: Did not follow redirect to http://nexus.htb/
An nmap -p- --min-rate 3000 confirms that only 22 and 80 are open across the whole range. We map the name and browse the site:
echo "10.129.234.54 nexus.htb" | sudo tee -a /etc/hosts
http://nexus.htb/ is a static corporate site (a single page, no forms, no backend). Directory fuzzing with raft-medium-directories.txt yields nothing. The only useful data in the HTML are two emails: careers@nexus.htb and j.matthew@nexus.htb —a possibly valid username on other systems.
Why fuzz subdomains: with no more visible surface on the main site, the logical next step is testing whether the server responds differently based on the
Host:header (virtual hosting). We first need to filter out nginx's catch-all response size to avoid drowning in false positives.
BASESIZE=$(curl -s -o /dev/null -w "%{size_download}" \
-H "Host: zzznonexistent999.nexus.htb" http://10.129.234.54/)
ffuf -u http://10.129.234.54/ -H "Host: FUZZ.nexus.htb" \
-w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt \
-fs "$BASESIZE" -mc all -t 60
git [Status: 200, Size: 14474]
billing [Status: 302, Size: 390] -> Location: http://billing.nexus.htb/admin/login
echo "10.129.234.54 git.nexus.htb billing.nexus.htb" | sudo tee -a /etc/hosts
git.nexus.htb is a Gitea instance (cookie i_like_gitea). billing.nexus.htb redirects to /admin/login with cookies krayin_crm_session and XSRF-TOKEN: a Krayin CRM (built on Laravel).
Resumen ejecutivo — Nexus es un Linux Easy de caja negra, sin credenciales de partida, resuelto en cinco fases muy encadenadas. El fuzzing de subdominios revela dos aplicaciones ocultas —un Gitea y un Krayin CRM— y la clave esta en que Gitea permite explorar repos publicos sin autenticacion: uno de ellos tiene el
.envcommitteado directamente, y aunque elHEADactual lo muestra "limpio", el historial de commits conserva la contraseña original. Esa credencial sirve para el login admin de Krayin CRM, que es vulnerable a un upload sin restricciones (CVE-2026-38526, CVSS 9.9) en su editor TinyMCE: sube una webshell PHP con solo falsear elContent-Typey da RCE comowww-data. El.envreal del servidor filtra otra contraseña de MySQL que, por reutilizacion, tambien abre la cuenta del sistema del usuariojones(USER). La escalada final abusa de un timer de systemd personalizado que corre como root y sincroniza "repos plantilla" de Gitea: el script no sanea los nombres de fichero que salen degit ls-tree -r, asi que un arbol git construido a mano con entradas llamadas..produce un path traversal que escribe una clave SSH en elauthorized_keysde root (ROOT). Recorrido Gitea (secreto en historial) -> Krayin RCE -> jones (reutilizacion) -> path traversal en timer root -> SSH root.
| Plataforma | Hack The Box |
| Sistema operativo | Linux (Ubuntu) |
| Dificultad | Easy |
| Estado | Retired |
| IP objetivo | 10.129.234.54 |
Mapa del ataque
[80/HTTP] nexus.htb (estatico) -> fuzzing de subdominios (vhost)
| git.nexus.htb (Gitea) + billing.nexus.htb (Krayin CRM)
v
[Gitea] historial de commits -> DB_PASSWORD filtrada (HEAD limpio, historial no)
| j.matthew@nexus.htb : N27xh!!2ucY04
v
[Krayin CRM] login admin -> CVE-2026-38526 (upload sin restriccion en TinyMCE) -> RCE
v
[SHELL] www-data -> .env real -> password de MySQL reutilizada
v
[jones] (user.txt)
| gitea-template-sync.timer (root, cada minuto) -> path traversal en ls-tree -r
v
[ROOT] escritura arbitraria en authorized_keys de root -> SSH root (root.txt)
1. Reconocimiento y descubrimiento de subdominios ocultos
nmap -sC -sV -T4 10.129.234.54
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 9.6p1 Ubuntu 3ubuntu13.16
80/tcp open http nginx 1.24.0 (Ubuntu)
|_http-title: Did not follow redirect to http://nexus.htb/
Un nmap -p- --min-rate 3000 confirma que solo 22 y 80 estan abiertos en todo el rango. Mapeamos el nombre y visitamos la web:
echo "10.129.234.54 nexus.htb" | sudo tee -a /etc/hosts
http://nexus.htb/ es un sitio corporativo estatico (una sola pagina, sin formularios ni backend). El fuzzing de directorios con raft-medium-directories.txt no da nada. Lo unico util del HTML son dos correos: careers@nexus.htb y j.matthew@nexus.htb —un posible usuario valido en otros sistemas.
Por que fuzzear subdominios: sin mas superficie visible en la web principal, el siguiente paso logico es probar si el servidor responde distinto segun la cabecera
Host:(virtual hosting). Hay que filtrar primero el tamaño de respuesta del catch-all de nginx para no ahogarnos en falsos positivos.
BASESIZE=$(curl -s -o /dev/null -w "%{size_download}" \
-H "Host: zzznonexistent999.nexus.htb" http://10.129.234.54/)
ffuf -u http://10.129.234.54/ -H "Host: FUZZ.nexus.htb" \
-w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt \
-fs "$BASESIZE" -mc all -t 60
git [Status: 200, Size: 14474]
billing [Status: 302, Size: 390] -> Location: http://billing.nexus.htb/admin/login
echo "10.129.234.54 git.nexus.htb billing.nexus.htb" | sudo tee -a /etc/hosts
git.nexus.htb es una instancia de Gitea (cookie i_like_gitea). billing.nexus.htb redirige a /admin/login con cookies krayin_crm_session y XSRF-TOKEN: es un Krayin CRM (sobre Laravel).
This is USER ACCESS content — free to unlock, no payment. The rest of the write-up (and everything else at this level) opens up once you're signed in.
Create a free accountEsto es contenido de nivel USER ACCESS — se desbloquea gratis, sin pago. El resto del writeup (y todo lo demás de este nivel) se abre en cuanto inicies sesión.
Crear una cuenta gratis