Skip to main content

Solución de Fetch the Flag CTF 2022: Logster

Escrito por
feature ctf logster

10 de noviembre de 2022

0 minutos de lectura

¡Gracias por jugar Fetch con nosotros! Felicitaciones a los miles de jugadores que participaron en Fetch the Flag CTF. Y muchas gracias a los Snykers que crearon, probaron y documentaron los desafíos!

Si participaste en Fetch the Flag de Snyk en 2022 y buscas la respuesta al desafío Logster, llegaste al lugar indicado. ¡Veamos la solución paso a paso!

Empecemos por la fase de reconocimiento

En esta fase, un atacante identifica un objetivo vulnerable y explora cómo aprovecharlo. En nuestro caso, se nos presenta un enlace a un sitio web. Solo necesitamos un punto de entrada para comenzar.

Herramienta de búsqueda Logster 500 para un shell Jnioromous, con un enlace a logster.cctf-snyk.io

Primero revisamos el enlace y vamos a http://logster.c.ctf-snyk.io/. Este sitio web nos permite escanear sitios web.

Interfaz de escaneo de sitios web con un campo para ingresar una dirección, botones Más y Escanear, y un panel de encabezados sin procesar que no muestra datos

Probemos con https://www.cnn.com/. Muestra los encabezados:

Escáner de sitios web que muestra https://www.cnn.com/ en el campo de URL y un registro de encabezados sin procesar con un estado HTTP 200

A partir de ahí, podemos deducir por la descripción del desafío (lookup) y el lenguaje de programación (Java) que estamos ante Log4Shell.

¡Empecemos a crear un túnel!

Ahora, creemos un servidor web Express para configurar encabezados personalizados, creemos un túnel de ngrok para ejecutar el servidor localmente y luego expongámoslo a Internet. Después lo escanearemos y veremos qué sucede.

Si no sabes cómo configurar un servidor Express, la documentación oficial te ayudará con este paso.

Editor de código con tema oscuro que muestra un servidor Express.js con una ruta raíz que devuelve “¡Hola, mundo!”; el servidor escucha en el puerto 3000.

Creamos nuestro servidor Express para que escuche en el puerto 3000 y configuramos un encabezado personalizado con ('PWN', 'pwn').

Ejecutémoslo con el comando node express.js:

Terminal que muestra una aplicación de ejemplo de Node.js Express de Fetch the Flag escuchando en el puerto 3000

También creemos el túnel de ngrok con el comando ngrok http 3000. Consulta la documentación oficial de ngrok para configurarlo en tu máquina.

Terminal que muestra una sesión de ngrok en línea que reenvía una URL HTTPS pública a localhost:3000, con estadísticas de conexión y una URL de inspección.

Copia el enlace de reenvío, pégalo en el sitio web y escanéalo. En la consola de ngrok (http://localhost:4040/) podemos ver que el encabezado refleja lo que pusimos en el archivo express.js

Consola de inspección de ngrok que muestra una lista de solicitudes GET con respuestas 200 OK y encabezados HTTP detallados

Probemos a configurar un encabezado con un payload de tipo Log4Shell. Volvamos al archivo express.js y cambiemos el encabezado a ('${java:version}', 'pwn'):

Editor de código oscuro que muestra una aplicación de Express.js con una ruta raíz que devuelve “Hello World!” y escucha en el puerto 3000

Reiniciemos el servidor y hagamos otro escaneo del sitio web. Obtenemos un 500 Internal Server Error y, si revisamos los registros, vemos que el nombre del encabezado debe ser un token HTTP válido.

Monitor de solicitudes del servidor que muestra una solicitud GET seleccionada con un error 500 Internal Server Error y un mensaje de token HTTP no válido

Express no permite encabezados no válidos: $ y {} no son caracteres válidos. Así que tenemos que eludir esta restricción. Podemos hacerlo creando un servidor de sockets que devuelva una respuesta personalizada cada vez que reciba una conexión.

El servidor de sockets se ve así. Escuchará en el socket y, con cada conexión, enviará la respuesta, que en este caso incluye la versión de Java. Intentaremos inyectar este encabezado personalizado para ver si se evalúa.

Código JavaScript en index.js que crea un servidor de red, envía una respuesta HTTP 200 y escucha en el puerto 3000

Iniciemos el servidor con el comando node index.js y cambiemos el túnel de ngrok a un túnel TCP con el comando ngrok tcp 3000. Debes crear una cuenta en ngrok para poder usar la función de túnel TCP.

Terminal que muestra una sesión de ngrok en línea que redirige tráfico TCP desde 0.tcp.eu.ngrok.io:14584 a localhost:3000.

Copia el enlace Forwarding sin TCP y pégalo en el sitio web. Agrega https:// al principio y escanea el enlace. Vemos que se evaluó el encabezado personalizado. Se hizo una búsqueda y obtuvimos la versión de Java. Sabemos que lookup funciona.

Interfaz de análisis de sitios web que muestra un campo de URL, los botones «Más» y «Analizar», y resultados de encabezados sin procesar, incluido el estado 200.

Ahora tenemos que configurar un exploit de Log4Shell.

¿Qué es Log4Shell?

CVE-2021-44228, también conocida como Log4Shell, es una vulnerabilidad de ejecución remota de código (RCE) sin autenticación que afecta a casi todas las versiones de Apache Log4j 2. El 9 de diciembre de 2021, la noticia de esta vulnerabilidad de día cero se difundió en las comunidades de seguridad informática, junto con una prueba de concepto (POC) disponible públicamente.

Si quieres aprender más sobre la vulnerabilidad Log4Shell, consulta nuestra lección gratuita en Snyk Learn .

La POC

Usaremos esta POC disponible públicamente en los siguientes pasos. Este repositorio contiene todo lo que necesitamos para realizar el ataque.

Clona el proyecto con Git y ve a la clase Evil.java. Tenemos que modificarla para crear el payload de este desafío. Queremos listar todos los archivos del directorio raíz. Crearemos un objeto File, obtendremos una lista de archivos e imprimiremos sus nombres.

Editor de código con tema oscuro que muestra Evil.java, una ObjectFactory de Java que enumera los archivos del directorio raíz y devuelve “¡Te han hackeado!”

Creemos nuestra imagen de Docker con el siguiente comando:

docker build -t log4shell-vulnerable-server-exploit .

Iniciemos el servidor TCP de ngrok con el comando:

ngrok tcp 9999
Terminal de ngrok que muestra una sesión en línea que reenvía tcp://7.tcp.eu.ngrok.io:18771 a localhost:9999

Y el servidor HTTP de ngrok con el comando: ngrok http 8888

Terminal de ngrok que muestra una sesión en línea que redirige una URL HTTPS pública a http://localhost:8888

Tendremos que ejecutar el contenedor de Docker de forma remota con el siguiente comando:

Comando de terminal que ejecuta un contenedor de Docker con asignaciones de puertos, un host de servidor HTTP y el nombre de una prueba de vulnerabilidad de Log4Shell

Pero primero, tenemos que configurar el servidor LDAP para que apunte al enlace Forwarding correcto. Copia y pega el enlace del servidor HTTP que escucha en el puerto 8888.

También necesitamos incluir en el archivo de sockets index.js la dirección del servidor TCP que escucha en el puerto 9999. Aquí enviamos un encabezado con un payload real de Log4Shell. Estamos sirviendo la clase Evil que modificamos antes.

Código JavaScript que muestra una respuesta del servidor con una dirección TCP de ngrok incrustada y el texto «Evil», seguido de «hello».

Reiniciemos el servidor de sockets con el comando: node index.js

Volvamos a ejecutar este comando:

Captura de terminal que muestra un comando de Docker ejecutando un servidor vulnerable a Log4Shell, con los puertos 8888 y 9999 expuestos.

Deberías ver el mismo resultado en tu terminal:

Terminal que muestra un comando de Docker para iniciar un exploit de servidor vulnerable, con servidores LDAP y HTTP escuchando en los puertos 9999 y 8888.

Al volver al sitio web, deberías poder ver la lista de archivos del directorio raíz. ¡Y podemos ver que está la flag!

Captura de pantalla titulada «Encabezados sin procesar» que muestra resultados de depuración con una lista de directorios y archivos del servidor, incluidos package.json y node_modules.

Tenemos que modificar el payload una última vez para revelar la flag. Volvamos a la clase Evil. Este fragmento de código nos permitirá leer la flag y mostrar el contenido del archivo.

Editor de código con tema oscuro que muestra Evil.java, una ObjectFactory de Java que lee /flag y devuelve “¡te han comprometido!”

Tenemos que volver a ejecutar el contenedor de Docker para que se reflejen los cambios. Si escaneamos una vez más, veremos el contenido del archivo de la flag.

Captura de pantalla de encabezados sin procesar que muestra registros de depuración y una cadena de token de SNYK resaltada.

Resumen de Logster

La sencillez de este exploit y el uso generalizado de la biblioteca han hecho que los profesionales de seguridad se apresuren a responder desde que se divulgó el error. La recomendación inicial para mitigar Log4Shell era actualizar a la versión 2.16; lamentablemente, después se descubrió un exploit de denegación de servicio en esa versión. La recomendación actual es actualizar a la versión 2.17.

Para conocer en detalle las recomendaciones de corrección, consulta nuestra guía rápida de corrección de Log4Shell. La actualizamos continuamente a medida que hay nueva información disponible.

¡Espero que hayas disfrutado Logster y los demás desafíos del CTF :) ¿Quieres saber cómo encontramos las otras flags? Visita nuestra página de soluciones de Fetch the Flag para ver cómo lo hicimos.

Leer más

Blog

Los modelos de frontera encontraron las vulnerabilidades. Solo el atacante encontró las cadenas.

El análisis estático encontró las fallas, pero solo las pruebas de ataque en vivo demostraron cómo podían encadenarse para provocar brechas. Una comparación de Evo COS, Claude Security y Claude Code Security.

feature insights context
Blog

Los ataques autónomos ya están aquí. La defensa debe estar a su altura.

Los atacantes autónomos están reduciendo el tiempo disponible para defenderse. Descubre cómo el descubrimiento, la corrección, la validación y la prevención continuos pueden ayudar a los equipos de seguridad a seguirles el ritmo.

Blog

Por qué los agentes de programación con IA siguen generando fallas de control de acceso

Los agentes de programación con IA pueden generar lógica de autorización que compila y supera la revisión, pero expone los datos de un inquilino a otro. Descubre por qué es difícil detectar el control de acceso roto y cómo prevenirlo.