Pruebas de penetracion para Log4j

Log4Shell y la importancia de las pruebas de penetración

Una pregunta válida cuando de vulnerabilidades se trata, es si realmente esta nos puede afectar y en que medida. Trataremos de mostrar vía un ejercicio de pruebas de penetración que es realmente la vulnerabilidad log4Shell y como podemos evaluar su impacto en nuestra organización, este artículo es una continuación del artículo ¿Qué es y cómo me afecta la vulnerabilidad Log4Shell?


Notificación de una vulnerabilidad

Cuando los equipos de seguridad ya sean internos o externos nos comunican una vulnerabilidad, la pregunta que nos hacemos es si realmente es algo que debe de preocuparnos, nos preguntamos si debemos o no tomar acciones y cuantos recursos asignarle a esa tarea.

Contestar esta pregunta de manera general no es sencillo y se debe revisar caso por caso, en ese sentido las pruebas de penetración o pentest son una herramienta que nos puede ayudar a determinar el impacto en nuestras organizaciones y así poder tomar una decisión informada.

Este documento es un documento técnico, pero queriendo ser muy didáctico, que esboza como un equipo puede evaluar el impacto en sus sistemas, para fines de claridad la metodología de pruebas de penetración se ha modificado , se han omitido muchos pasos y se ha modificado el orden de algunos de ellos. Toda la información y el código se proporcionan únicamente con fines educativos y/o para probar sus propios sistemas en busca de estas vulnerabilidades y no se deberá utilizar para acceder a ningún sistema sin autorización expresa del dueño de la infraestructura.

Entendiendo el funcionamiento de la log4j.

Para poder tomar acciones y evaluar como nos afecta y más importante en donde nos afecta esta vulnerabilidad es necesario entender de manera detallada, en que técnica y prácticamente nos afecta, sin caer en la tentación de entender con el máximo detalle  toda la tecnología que esta atrás de la vulnerabilidad, pero con el detalle suficiente para no poder tomar decisiones.

Empecemos explicado que es log4j, log4j es una biblioteca de software ampliamente utilizada para imprimir en un log, información relevante del comportamiento de la aplicación, esto puede ser para fines de evaluación del rendimiento de la aplicación, para temas estadísticos etc. En palabras muy simples se trata de imprimir mensajes en un archivo para su revisión posterior.

Esta librería es utilizada en ambientes Java, fue desarrollada por el equipo de código abierto Apache, y como cualquier biblioteca de software en Java es necesario agregarla a la compilación esto es en el ClassPath de la aplicación .

Una vez que se agrega esta biblioteca a la aplicación se debe importar esta para poder utilizarla con la instrucción import.

Pruebas de penetracion para Log4j 1

Una vez importado la biblioteca es necesario crear una variable para poder utilizar la funcionalidad.

Pruebas de penetracion para Log4j 2

En este caso creamos una variable llamada logger que será utilizada para escribir en el log los mensajes que sean necesarios en la aplicación de acuerdo con nuestras necesidades particulares. Con esto estamos listos para escribir en el log de una aplicación. El siguiente código es un programa simple que escribe un mensaje en la pantalla.

Pruebas de penetracion para Log4j 3

En este ejemplo, (el método main es la función principal de un programa en Java) cuando se ejecuta muestra el siguiente mensaje.

Pruebas de penetracion para Log4j 4

Comunicación externa

El comportamiento anterior es una de las funciones generales y más utilizadas de la escritura en logs. Sin embargo, existen más funcionalidades avanzadas para el uso de esta bilioteca y estas son poder escribir mensajes que proviene de una fuente externa a nuestro programa, esto se hace a través del protocolo JNDI , para fines de la explicación considérese como una manera de referenciar información a desplegar de una fuente que no es directamente el programa.

La forma de referenciar una fuente externa es via la sentencias JNDI de la siguiente manera: jndi:// {protocolo externo}, donde protocolo son los diferentes protocolos soportados por el estándar JNDI que principalmente para fines de este documento son LDAP y RMI , de tal manera que las sintaxis para LDAP sería jndi://ldap://direccion_ip/recurso.

Esta funcionalidad en sí no es un problema, puede ser válida en algunos casos de negocio como en el de centralizar los mensajes de error en un servidor único de mensajes errores e informativos.

Siguiendo lo anterior un programa podría pedir un mensaje de un servidor externo. Por ejemplo supongamos que tenemos un servidor central LDAP que tiene los mensajes de error que debemos desplegar nuestro programa podría quedar de la siguiente manera:

Pruebas de penetracion para Log4j 5

En esta caso lo que estamos indicándole al programa es que escriba un mensaje que será tomado de un recurso LDAP externo en un servidor LDAP en la dirección 127.0.0.1. El resultado de nuestro programa modificado es:

Pruebas de penetracion para Log4j 6

Como podemos ver la ejecución del programa generó un error, esto es debido a que en la dirección 127.0.0.1 no existe un servidor LDAP por lo que hay un problema de comunicación, lo importante aquí para los fines del documento es que hubo un intento de comunicación a un recurso externo.

¿Dónde esta el problema?

La funcionalidad mostrada no presenta en teoría ningún problema, ya que estos mensajes son controlados por el flujo del programa, el problema se presenta cuando la ejecución de estos mensajes es forzada por un posible atacante. Para mostrar este riesgo modifiquemos nuestro programa para que tenga una funcionalidad más cercana a un caso real.

Agreguemos la funcionalidad de leer de un archivo de usuarios separados por comas, simulando el procesamiento Batch de algunos procesos típicos en muchas empresas, e imprimamos en pantalla su contenido.

Creemos un archivo Usuarios.txt con el siguiente contenido:

  • Juan,Perez
  • Juana,Perez
  • John,Doe
  • Jean,Doe
  • Max,Musterman

Ahora modificamos nuestro programa para que lea línea por línea el archivo y separe los componentes del cada registro en Nombre y Apellido. Nuestro programa quedaría de la siguiente manera:

Pruebas de penetracion para Log4j 7

La salida del programa será:

Pruebas de penetracion para Log4j 8

El Ataque

Supongamos ahora que un atacante tiene acceso al archivo y logra modificarlo de la siguiente manera:

  • Juan,Perez
  • Juana,Perez
  • John,Doe
  • Jean,${jndi:ldap://127.0.0.1/mensaje=0001}
  • Max,Musterman
  • La salida del programa es la siguiente:

    Pruebas de penetracion para Log4j 9

    Como podemos ver en la salida del programa logramos hacer que el programa hiciera una comunicación fuera del servidor que está corriendo la aplicación a un servidor indicado en el archivo de texto en este caso podría ser el servidor de un atacante.

    ¿Dónde esta el peligro?

    Hasta este punto lograríamos conectarnos a un servidor LDAP externo controlado por un atacante, por lo que con esta información podemos entender que tan vulnerable son nuestros sistemas de acuerdo a nuestra propia arquitectura.

    Es labor del equipo de pruebas de penetración ( Read Team ) evaluar, por un lado, si somos vulnerables o no, pero la siguiente labor es explotar vulnerabilidad para evaluar el impacto que se podría tener.

    Se configuró un servidor LDAP para recibir la petición que fue inyectada en el archivo de texto, con esta llamada al servidor LDAP se configuró a través de un servidor HTTP una clase en Java de tal manera que la respuesta de la petición LDAP fuera esta clase, esta tenía la funcionalidad de ejecutar un comando de sistema operativo que fue ejecutado de manera exitosa. En un siguiente artículo se mostrará el laboratorio que se realizó del cual se obtuvieron algunas conclusiones, la principal que hay en algunos casos si es posible tomar control completo a través de esta vulnerabilidad

    Conclusiones

    Es muy importante entender cada una de las vulnerabilidades reportadas para entender el impacto en nuestras organizaciones, no es suficiente hacer un análisis de vulnerabilidades para poder tomar una decisión informado es relevante ejecutar pruebas de penetración que determinen el impacto real.

    Para esta vulnerabilidad en particular el riesgo depende de tres factores en particular

    • Que tan fácil puede resultar para un atacante modificar la información que se escribe en los diferentes logs, encabezados HTTP, los campos que ingresan los usuarios etc.
    • Los permisos que tenga la aplicación para ejecutar comandos de sistema operativo.
    • La versión de la máquina virtual de java.

    Acerca de este artículo

    Este artículo es parte de la campaña de concientización de ciberseguridad de En1gm4.