Cabecera blog ciberseguridad

Seguimiento de los ataques JNDI: Cazando Log4Shell en su red

Cazando Log4Shell es una investigación del equipo de Threat Hunting de BlackArrow

El equipo de Threat Hunting de BlackArrow utiliza un servidor de Minecraft para ilustrar el impacto de Log4Shell tanto desde el punto de vista de un atacante como de un defensor

El ataque de inyección por JNDI que afecta al componente de Java Log4j está suponiendo un impacto importante para las organizaciones, especialmente al tratarse de un componente de Java tan común, que su mitigación podría llevar más tiempo del que sería aconsejable. Más allá de su corrección o mitigación, se pone más de manifiesto que nunca la necesidad de contar con unas capas defensivas capaces de detectar esta amenaza a nivel de endpoint. ¿Qué opciones tienen los responsables de seguridad a la hora de detectar que Log4Shell está siendo explotado activamente en uno de sus activos?

Para ilustrar este ataque y su perspectiva tanto en el lado del atacante o de un Red Team como del defensor, hemos utilizado un servidor del conocido videojuego Minecraft Java Edition, ya que éste utiliza una versión de log4j vulnerable a este ataque.

Se trata de un ejemplo sencillo y representativo de cualquier aplicación Java y que haga uso de las funciones proporcionadas por Log4j. El atacante básicamente solo tiene que localizar qué parámetros de entrada del usuario son registrados por el motor de Java vía Log4j para ejecutar código en el contexto de la aplicación vulnerable.

Telemetría y análisis de la amenaza Log4Shell

Bajo este escenario, todo el chat del juego es enviado a Log4j, por lo que es el espacio idóneo para realizar la inyección. Nuestro equipo víctima es un Ubuntu que incluye una solución EDR que nos permitirá monitorizar la actividad y generar telemetría suficiente para analizar la amenaza.

En el lado del atacante hay que preparar un servidor LDAP que incluya el payload que queremos ejecutar en el servidor objetivo. En este caso utilizaremos una herramienta que ha publicado @pimps (https://github.com/pimps/JNDI-Exploit-Kit), fork del proyecto creado por @welk1n.

Esta herramienta recibe como argumento el comando que queremos ejecutar en nuestro objetivo y se encargará de paquetizarlo en una clase Java maliciosa que servirá en el puerto 1389 (si optamos por el método LDAP) o el 1099 (si optamos por RMI).

Los investigadores usaron un servidor de Minecraft

Vemos que la propia herramienta nos divide la respuesta en diferentes opciones, separadas por enlaces únicos.

Esto simplifica sustancialmente el trabajo del atacante, ya que tendrá todas las opciones disponibles del exploit en función de la versión de JDK que tenga instalada, así como diferentes alternativas para Tomcat 8.

En nuestro escenario ya sabemos que contamos con JDK 1.8 y tenemos habilitado trustURLCodebase como “true”, por lo que usaremos el enlace LDAP que nos indica y lo enviaremos por el chat del juego.

Minecraft es un videojuego muy popular

Recurso JNDI

Una vez enviado el mensaje de texto, vemos en el lado del servidor que efectivamente el mensaje es interpretado por el servidor como un recurso JNDI, que llegará a realizar una consulta LDAP al servidor atacante.

Log4Shell es una de las mayores vulnerabilidades de la década

Justo en ese momento, la clase Java maliciosa se genera al vuelo para ejecutar el comando deseado por el atacante. Para nuestro escenario queremos que la aplicación vulnerable descargue una shell inversa escrita en python y que sea ejecutada.

A continuación se analiza qué ejecuta la clase maliciosa construido al vuelo:

La prueba de concepto hace uso exclusivo de cmd.exe y de bash para realizar la ejecución

De forma sencilla, el código únicamente consulta si el sistema operativo es un Windows o no y, en función del resultado, hará una llamada a cmd.exe o a /bin/bash, incorporando nuestro comando como argumento.

Finalmente nuestro comando es ejecutado y la shell inversa llega al atacante:

Los puertos utilizados en esta prueba de concepto se pueden alterar

Siguiendo con este escenario, ahora tomamos el rol de Threat Hunter y centramos nuestros esfuerzos en identificar el origen de esta shell inversa a partir de la telemetría generada durante el ataque.

Análisis de la telemetría

Vemos que la telemetría es suficiente para identificar los siguientes hechos:

  • El origen de esta shell inversa es el proceso JAVA, aunque la herramienta no muestra qué técnica ha sido utilizada para llegar a esta ejecución.
  • El proceso responsable de esta shell inversa ha realizado conexiones LDAP al equipo atacante en la misma ventana de tiempo que la ejecución de esta shell inversa.
  • Es posible identificar todos los comandos realizados por el atacante a partir de este proceso hijo de Java.
El payload es interpretado por una aplicación que funciona sobre Java

Además, desde el punto de vista del defensor, hay diferentes puntos a tener en cuenta:

  • La prueba de concepto hace uso exclusivo de cmd.exe y de bash para realizar la ejecución. Esto no significa que los atacantes no incorporen binarios adicionales en sus payloads y que utilicen otros recursos para realizar la ejecución (como powershell o zsh, entre otros).
  • Los puertos utilizados en esta prueba de concepto se pueden alterar, por lo que no deben ser considerados identificadores exclusivos de este vector de ataque. No obstante pueden ser utilizados los mismos puertos para identificar si la misma prueba de concepto ha sido utilizada en nuestra infraestructura.
  • El payload es interpretado por una aplicación que funciona sobre Java, pero el responsable de todas las ejecuciones y conexiones será siempre el propio motor de Java.

Las siguientes búsquedas, junto con análisis de sus resultados, serían suficientes para centrar la atención sobre la hipótesis de compromiso a partir de la utilización de la prueba de concepto de Log4Shell.

Detección de la explotación de Log4Shell

A alto nivel, la query para detectar dicha explotación sería la siguiente:

  • Proceso padre=*java*
  • Proceso hijo= cualquier binario que permita ejecución de código en el sistema operativo (cmd, powershell, sh, bash, wscript,…)
  • Conexiones desde el proceso “java” a puertos destino relacionados con la prueba de concepto (636, 389, 1099,1389,…)

De forma particular, a continuación se proporciona una implementación particular de dicha query para un conocido EDR, la cual podría ser convertida a otros EDR/XDR de forma trivial:

Conexiones realizadas por el proceso Java:

  • Se incluyen exclusiones para el direccionamiento interno (en caso de que solo interesen ataques externos).
  • Se incluye un número reducido de puertos comunes a este ataque (el ataque no se limita exclusivamente a estos puertos).

event_simpleName=ProcessRollup2 FileName = *java*
| join max=0 aid TargetProcessId_decimal [search event_simpleName=NetworkConnectIP4 NOT RemoteIP IN (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 127.0.0.0/8) RPort IN (636, 389, 1099,1389)
| rename ContextProcessId_decimal as TargetProcessId_decimal
| table TargetProcessId_decimal RemoteIP RemotePort_decimal aid]
| table _time UserName ComputerName RemoteIP RemotePort_decimal FileName ParentBaseFileName

Procesos invocados desde Java:

  • Se limita la búsqueda de procesos hijos de Java a binarios que permitan ejecución de código, incluyendo más allá de los que aparecen en la prueba de concepto original (pueden incluirse más binarios).

event_simpleName=ProcessRollup2 ParentBaseFileName = java FileName IN (cmd.exe, bash, sh, zsh, powershell.exe, wscript.exe, cscript.exe, mshta.exe, tcsh)
| table _time UID_decimal ComputerName UserName GrandParentBaseFileName ParentBaseFileName FilePath FileName CommandLine

Es previsible que esta vulnerabilidad vaya evolucionando a medida en que pasa el tiempo y se conoce más información. Buena prueba de ello es que la versión de Log4j 2.15, llamada a solventar la vulnerabilidad, no impide la realización de ataques orientados a la denegación de servicio, tal y como se ha anunciado recientemente.

Aquellos productos y desarrollos que se hayan actualizado a la versión 2.15 deberán también actualizar a la versión 2.16 la cual deshabilita la funcionalidad JNDI por defecto.

Esperamos que esta información sea de utilidad a Threat Hunters para proteger a nuestros clientes. Para cualquier otra cuestión, no duden en consultar nuestros servicios deseguridad ofensiva y de Threat Hunting.

Más artículos de la serie Log4Shell

Este artículo forma parte de una serie de articulos sobre Log4Shell

  1. Vulnerabilidad Log4Shell CVE-2021-44228, el nuevo ciberapocalipsis
  2. Seguimiento de los ataques JNDI: Cazando Log4Shell en su red
  3. Log4j foto completa: Todas las vulnerabilidades de Log4Shell