Skip to content
KitploitKITPLOIT
OutilsExploitsBlog
Log in
Soumettre
OutilsExploitsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

FluxContactConfidentialité© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
Outils/GitHubGitHub/dinosn/log4j-4255
Analyse des VulnérabilitésExploitationSécurité WebApprentissage et ÉducationExploitation de Binaires
GitHubdinosn/log4j-4255

log4j-4255

Laboratoire Docker de bout en bout reproduisant Apache log4j2 #4255 — contournement de la liste blanche de FilteredObjectInputStream via java.rmi.MarshalledObject (désérialisation non filtrée → RCE) sur Log4j 2.26.1 / JDK 17.

Voir le dépôtSite web
281419il y a 1 moisPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

log4j2 #4255 — Contournement de la liste blanche de FilteredObjectInputStream via java.rmi.MarshalledObject

Un laboratoire autonome et conteneurisé qui reproduit de bout en bout le problème Apache log4j2 #4255 contre les artefacts officiels Log4j 2.26.1 sur JDK 17, avec des contrôles positifs, un oracle durci et une atténuation validée.

⚠️ Utilisation responsable

Ce laboratoire contient une RCE par désérialisation fonctionnelle contre un problème Log4j actuellement non corrigé (#4255 est OUVERT / waiting-for-maintainer au moment de la rédaction ; aucun CVE attribué). Il s'exécute entièrement dans des conteneurs Docker jetables sur votre propre machine et ne se connecte à rien d'externe sauf Maven Central (pour télécharger les jars officiels) — aucune cible n'est contactée.

  • Le rapporteur d'origine (U-Sec / Wujie Security) retient son PoC en attendant un correctif. Il s'agit d'une reproduction indépendante conçue pour la validation par les défenseurs et l'ingénierie de détection.
  • Ne pas exécuter ceci contre des systèmes que vous ne possédez pas ou pour lesquels vous n'êtes pas explicitement autorisé à tester.
  • Ceci démontre une RCE conditionnelle à l'application, pas une RCE Log4j universelle (voir Portée).

TL;DR

Le FilteredObjectInputStream (FOIS) de Log4j est une liste blanche de désérialisation basée sur resolveClass. Sa liste blanche inclut java.rmi.MarshalledObject. Un MarshalledObject stocke sa charge utile sous forme de byte[] opaque, et MarshalledObject.get() désérialise cette charge utile sur un ObjectInputStream frais et non filtré — la liste blanche n'inspecte donc jamais le graphe interne.

Log4j déclenche cela lui-même : Log4jLogEvent$LogEventProxy (la forme filaire sérialisée d'un LogEvent, depuis 2.8) transporte le Message de l'événement dans un MarshalledObject et appelle .get() automatiquement pendant la désérialisation (readResolve() → message()). Toute application qui lit un LogEvent sérialisé via FOIS effectue donc une désérialisation non filtrée d'octets attaquants — et comme message() avale l'exception résultante et retombe sur SimpleMessage, le récepteur journalise un événement bénin et continue de fonctionner. L'exploit est silencieux.

Cause racine (vérifiée contre rel/2.26.1)

#EmplacementDéfaut
1log4j-api …/util/internal/SerializationUtil.javaREQUIRED_JAVA_CLASSES contient java.rmi.MarshalledObject
2log4j-api …/util/FilteredObjectInputStream.javane surcharge que resolveClass() ; la charge utile objBytes du MarshalledObject lui est invisible
3log4j-core …/impl/Log4jLogEvent.javaLogEventProxy.marshalledMessage est un MarshalledObject<Message>
4log4j-core …/impl/Log4jLogEvent.javamessage() appelle marshalledMessage.get() (sans filtre) et avale toutes les exceptions

Ce que le laboratoire exécute

Un substitut fidèle du ObjectInputStreamLogEventBridge déprécié de log4j-samples : un récepteur TCP non authentifié qui lit un LogEvent sérialisé par connexion via FOIS. L'attaquant envoie un seul objet sérialisé ; l'oracle est un fichier de preuve écrit dans un répertoire monté en bind uniquement dans le conteneur du récepteur, de sorte que son apparition prouve que du code s'est exécuté dans le récepteur via la désérialisation.

#ScénarioClasspath de la victimejdk.serialFilterAttendu
S1gadget interdit envoyé au niveau supérieur+ gadgetaucunrejet — FOIS applique sa liste blanche
S2même gadget enveloppé dans un LogEvent+ gadgetaucunrce — déclenchement automatique (nécessite la classe du gadget sur la victime)
S3CommonsCollections6 brut au niveau supérieurlog4j + cc-3.2.1aucunrejet — FOIS bloque CC
S4CC6 inséré dans le MarshalledObjectlog4j + cc-3.2.1 uniquementaucunrce — aucune classe attaquante sur la victime
S5charge utile S4log4j + cc-3.2.1!java.rmi.MarshalledObjectrejet — atténuation
S6charge utile S4log4j + cc-3.2.1maxdepth=5;maxbytes=1000000silencieux — le flux interne hérite du filtre ; CC6 trop profond
S7charge utile S4log4j + cc-3.2.2aucunsilencieux — 3.2.2 désactive la désérialisation de foncteurs non sûrs

rce = code exécuté. reject = FOIS a levé une exception sur le flux externe. silent = objet externe traité, aucun code exécuté (bloqué plus profondément, ou version du gadget sûre).

Exécution

./run.sh            # ou : make run

Prérequis : Docker uniquement (un JDK est tiré comme eclipse-temurin:17-jdk). Le script télécharge les jars officiels et les vérifie contre les SHA-1 de Maven Central avant utilisation. Épinglez une version Log4j différente dans la plage vulnérable avec LOG4J_VERSION=2.20.0 ./run.sh.

Impact et méthode d'attaque

  • Livraison : une seule écriture TCP non authentifiée d'environ 2,8 Ko d'un LogEvent sérialisé vers un récepteur basé sur FOIS. Ce n'est pas déclenchable en faisant journaliser une chaîne (contrairement à Log4Shell) — il faut des octets sérialisés bruts atteignant le pont socket.
  • Résultat : exécution arbitraire de commandes dans le processus du récepteur, silencieusement.
  • Chemin d'attaque : construire un LogEvent → writeReplace()/writeObject() de Log4j enveloppe le Message dans un MarshalledObject → le gadget se cache dans son byte[] opaque → sur le récepteur, readResolve() → message() → MarshalledObject.get() ouvre un flux non filtré frais → gadget → Runtime.exec. src/attacker/Attacker.java (poc2) insère un graphe pure-CommonsCollections6 dans objBytes du MarshalledObject, donc aucune classe attaquante n'est nécessaire sur la victime.

Atténuation

  • Fiable : -Djdk.serialFilter='!java.rmi.MarshalledObject' sur la JVM du récepteur (S5). Mise en garde : cela bloque aussi les objets LogEventProxy sérialisés légitimes (ils utilisent MarshalledObject également) — c'est efficace mais pas transparent pour le transport de journaux sérialisés.
  • Non fiable : filtres génériques maxdepth/maxbytes. Le filtre à l'échelle du processus se propage dans le flux MarshalledObject interne et la profondeur y redémarre, donc maxdepth=5 bloque CC6 (S6) mais un gadget peu profond passerait. Dépendant de la profondeur de chaîne, pas une frontière.
  • Structurel : éliminer le transport de journaux sérialisés Java (utiliser JSON / RFC 5424 sur TLS authentifié) ; supprimer les dépendances de gadgets connues ; ne pas exposer les récepteurs sérialisés hérités à des réseaux non fiables. Correctif en amont (selon le problème) : retirer MarshalledObject de la liste blanche et déplacer le message marshallé vers writeWrappedObject/readWrappedObject filtrés de Log4j.

Portée et limites honnêtes

Télécharger l’outil