Skip to content
KitploitKITPLOIT
HerramientasExploitsBlog
Log in
Enviar
HerramientasExploitsBlog
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.

FeedsContactoPrivacidad© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
log4j-4255 — Laboratorio Docker de extremo a extremo que reproduce Apache log4j2 #4255 — omisión de la lista blanca de FilteredObjectInputStream mediante java.rmi.MarshalledObject (deserialización sin filtrar → RCE) en Log4j 2.26.1 / JDK 17. | Kitploit
Herramientas/GitHubGitHub/dinosn/log4j-4255
Análisis de VulnerabilidadesExplotaciónSeguridad WebAprendizaje y EducaciónExplotación de Binarios
GitHubdinosn/log4j-4255

log4j-4255

Laboratorio Docker de extremo a extremo que reproduce Apache log4j2 #4255 — omisión de la lista blanca de FilteredObjectInputStream mediante java.rmi.MarshalledObject (deserialización sin filtrar → RCE) en Log4j 2.26.1 / JDK 17.

Ver Repositorio
281419hace 1 mesAún no revisado
Sitio web

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

log4j2 #4255 — Bypass de la lista blanca de FilteredObjectInputStream mediante java.rmi.MarshalledObject

Un laboratorio autocontenido y contenerizado que reproduce de extremo a extremo el problema #4255 de Apache log4j2 contra los artefactos oficiales de Log4j 2.26.1 en JDK 17, con controles positivos, un oráculo endurecido y una mitigación validada.

⚠️ Uso responsable

Este laboratorio contiene una RCE de deserialización funcional contra un problema de Log4j actualmente sin parchear (#4255 está ABIERTO / waiting-for-maintainer al momento de escribir esto; no se ha asignado ningún CVE). Se ejecuta enteramente dentro de contenedores Docker desechables en tu propia máquina y no se conecta a nada externo excepto a Maven Central (para descargar los jars oficiales) — no se contacta ningún objetivo.

  • El reportante original (U-Sec / Wujie Security) está reteniendo su PoC a la espera de un parche. Esta es una reproducción independiente construida para la validación de defensores y la ingeniería de detección.
  • No ejecutes esto contra sistemas que no te pertenezcan o para los que no tengas autorización explícita de prueba.
  • Esto demuestra una RCE condicionada a la aplicación, no una RCE universal de Log4j (ver Alcance).

TL;DR

El FilteredObjectInputStream (FOIS) de Log4j es una lista blanca de deserialización basada en resolveClass. Su lista blanca incluye java.rmi.MarshalledObject. Un MarshalledObject almacena su carga útil como un byte[] opaco, y MarshalledObject.get() deserializa esa carga útil en un ObjectInputStream nuevo y sin filtrar — por lo que la lista blanca nunca inspecciona el grafo interno.

Log4j lo activa por sí mismo: Log4jLogEvent$LogEventProxy (la forma serializada en el cable de un LogEvent, desde 2.8) transporta el Message del evento dentro de un MarshalledObject y llama a .get() automáticamente durante la deserialización (readResolve() → message()). Cualquier aplicación que lea un LogEvent serializado a través de FOIS realiza, por tanto, una deserialización sin filtrar de bytes del atacante — y como message() se traga la excepción resultante y recurre a SimpleMessage, el receptor registra un evento benigno y sigue ejecutándose. El exploit es silencioso.

Causa raíz (verificada contra rel/2.26.1)

#UbicaciónDefecto
1log4j-api …/util/internal/SerializationUtil.javaREQUIRED_JAVA_CLASSES contiene java.rmi.MarshalledObject
2log4j-api …/util/FilteredObjectInputStream.javasolo sobrescribe resolveClass(); la carga útil objBytes del MarshalledObject es invisible para él
3log4j-core …/impl/Log4jLogEvent.javaLogEventProxy.marshalledMessage es un MarshalledObject<Message>
4log4j-core …/impl/Log4jLogEvent.javamessage() llama a marshalledMessage.get() (sin filtro) y se traga todas las excepciones

Qué ejecuta el laboratorio

Un sustituto fiel del obsoleto ObjectInputStreamLogEventBridge de log4j-samples: un receptor TCP no autenticado que lee un LogEvent serializado por conexión a través de FOIS. El atacante envía un único objeto serializado; el oráculo es un archivo de prueba escrito en un directorio montado por bind únicamente en el contenedor del receptor, de modo que su aparición demuestra que el código se ejecutó dentro del receptor mediante deserialización.

#EscenarioClasspath de la víctimajdk.serialFilterResultado esperado
S1gadget no permitido enviado de nivel superior+ gadgetningunorechazo — FOIS aplica su lista blanca
S2el mismo gadget envuelto en un LogEvent+ gadgetningunorce — auto-activación (necesita la clase del gadget en la víctima)
S3CommonsCollections6 crudo de nivel superiorlog4j + cc-3.2.1ningunorechazo — FOIS bloquea CC
S4CC6 insertado en el MarshalledObjectlog4j + cc-3.2.1 soloningunorce — sin clase del atacante en la víctima
S5carga útil de S4log4j + cc-3.2.1!java.rmi.MarshalledObjectrechazo — mitigación
S6carga útil de S4log4j + cc-3.2.1maxdepth=5;maxbytes=1000000silencioso — el flujo interno hereda el filtro; CC6 es demasiado profundo
S7carga útil de S4log4j + cc-3.2.2ningunosilencioso — 3.2.2 deshabilita la deserialización insegura de funtores

rce = código ejecutado. rechazo = FOIS lanzó una excepción en el flujo externo. silencioso = objeto externo procesado, no se ejecutó código (bloqueado más adentro, o la versión del gadget es segura).

Ejecutarlo

./run.sh            # o: make run

Requisitos: solo Docker (se descarga un JDK como eclipse-temurin:17-jdk). El script descarga los jars oficiales y los verifica contra el SHA-1 de Maven Central antes de usarlos. Fija una versión diferente de Log4j dentro del rango vulnerable con LOG4J_VERSION=2.20.0 ./run.sh.

Impacto y método de ataque

  • Entrega: una única escritura TCP no autenticada de ~2.8 KB de un LogEvent serializado a un receptor basado en FOIS. No se puede activar haciendo que se registre una cadena (a diferencia de Log4Shell) — necesita bytes serializados crudos que lleguen al puente de socket.
  • Resultado: ejecución arbitraria de comandos en el proceso receptor, de forma silenciosa.
  • Ruta de ataque: construir un LogEvent → writeReplace()/writeObject() de Log4j envuelve el Message en un MarshalledObject → el gadget se oculta dentro de su byte[] opaco → en el receptor, readResolve() → message() → MarshalledObject.get() abre un flujo nuevo sin filtrar → gadget → Runtime.exec. src/attacker/Attacker.java (poc2) inserta un grafo de CommonsCollections6 puro en el objBytes del MarshalledObject, por lo que no se necesita ninguna clase del atacante en la víctima.

Mitigación

  • Fiable: -Djdk.serialFilter='!java.rmi.MarshalledObject' en la JVM del receptor (S5). Advertencia: esto también bloquea los objetos LogEventProxy serializados legítimos (también usan MarshalledObject) — es eficaz pero no transparente para el transporte de logs serializados.
  • Poco fiable: filtros genéricos de maxdepth/maxbytes. El filtro de todo el proceso se propaga al flujo interno del MarshalledObject y la profundidad se reinicia allí, por lo que maxdepth=5 bloquea CC6 (S6) pero un gadget poco profundo pasaría. Depende de la profundidad de la cadena, no es un límite.
  • Estructural: eliminar el transporte de logs serializados en Java (usar JSON / RFC 5424 sobre TLS autenticado); eliminar las dependencias de gadgets conocidos; no exponer receptores serializados heredados a redes no confiables. Parche ascendente (según el problema): eliminar MarshalledObject de la lista blanca y mover el mensaje marshalled a los métodos filtrados writeWrappedObject/readWrappedObject de Log4j.

Alcance y limitaciones honestas

Descargar herramienta