Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
log4j-4255 — Laboratorio Docker end-to-end che riproduce Apache log4j2 #4255 — bypass dell'allowlist di FilteredObjectInputStream tramite java.rmi.MarshalledObject (deserializzazione non filtrata → RCE) su Log4j 2.26.1 / JDK 17. | Kitploit
Strumenti/GitHubGitHub/dinosn/log4j-4255
Analisi delle VulnerabilitàExploitSicurezza WebApprendimento e FormazioneBinary Exploitation
GitHubdinosn/log4j-4255

log4j-4255

Laboratorio Docker end-to-end che riproduce Apache log4j2 #4255 — bypass dell'allowlist di FilteredObjectInputStream tramite java.rmi.MarshalledObject (deserializzazione non filtrata → RCE) su Log4j 2.26.1 / JDK 17.

Vedi Repository
18131 giorno faNon ancora revisionato
Sito web

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

log4j2 #4255 — Bypass della allowlist di FilteredObjectInputStream tramite java.rmi.MarshalledObject

Un laboratorio autonomo e containerizzato che riproduce end-to-end l'issue Apache log4j2 #4255 utilizzando gli artefatti ufficiali Log4j 2.26.1 su JDK 17, con controlli positivi, un oracle indurito e una mitigazione validata.

⚠️ Uso responsabile

Questo laboratorio contiene una RCE funzionante tramite deserializzazione contro un'issue Log4j attualmente non corretta (#4255 è APERTA / waiting-for-maintainer al momento della scrittura; nessun CVE assegnato). Viene eseguito interamente all'interno di container Docker usa-e-getta sulla tua macchina e non si connette a nulla di esterno tranne Maven Central (per scaricare i jar ufficiali) — nessun target viene contattato.

  • Il reporter originale (U-Sec / Wujie Security) sta trattenendo il proprio PoC in attesa di una correzione. Questa è una riproduzione indipendente costruita per la validazione dei difensori e l'ingegneria del rilevamento.
  • Non eseguire questo contro sistemi che non possiedi o per cui non sei esplicitamente autorizzato a testare.
  • Questo dimostra una RCE condizionata dall'applicazione, non una RCE Log4j universale (vedi Scope).

  • TL;DR

    FilteredObjectInputStream (FOIS) di Log4j è una allowlist di deserializzazione basata su resolveClass. La sua allowlist include java.rmi.MarshalledObject. Un MarshalledObject memorizza il proprio payload come byte[] opaco, e MarshalledObject.get() deserializza quel payload su un ObjectInputStream nuovo e non filtrato — quindi la allowlist non ispeziona mai il grafo interno.

    Log4j lo innesca da solo: Log4jLogEvent$LogEventProxy (la forma serializzata su filo di un LogEvent, dal 2.8) trasporta il Message dell'evento all'interno di un MarshalledObject e chiama .get() automaticamente durante la deserializzazione (readResolve() → message()). Qualsiasi applicazione che legge un LogEvent serializzato tramite FOIS esegue quindi una deserializzazione non filtrata di byte dell'attaccante — e poiché message() inghiotte l'eccezione risultante e ripiega su SimpleMessage, il ricevente registra un evento benigno e continua a funzionare. Lo sfruttamento è silenzioso.

    Causa principale (verificata contro rel/2.26.1)

    #PosizioneDifetto
    1log4j-api …/util/internal/SerializationUtil.javaREQUIRED_JAVA_CLASSES contiene java.rmi.MarshalledObject
    2log4j-api …/util/FilteredObjectInputStream.javasovrascrive solo resolveClass(); il payload objBytes del MarshalledObject è invisibile ad esso
    3log4j-core …/impl/Log4jLogEvent.javaLogEventProxy.marshalledMessage è un MarshalledObject<Message>
    4log4j-core …/impl/Log4jLogEvent.javamessage() chiama marshalledMessage.get() (senza filtro) e inghiotte tutte le eccezioni

    Cosa esegue il laboratorio

    Un sostituto fedele del deprecato ObjectInputStreamLogEventBridge di log4j-samples: un ricevitore TCP non autenticato che legge un LogEvent serializzato per connessione tramite FOIS. L'attaccante invia un singolo oggetto serializzato; l'oracle è un file di prova scritto in una directory montata in bind solo nel container del ricevitore, quindi la sua comparsa dimostra che il codice è stato eseguito all'interno del ricevitore tramite deserializzazione.

    #ScenarioClasspath vittimajdk.serialFilterAtteso
    S1gadget non consentito inviato a livello top+ gadgetnessunorifiuto — FOIS applica la sua allowlist
    S2stesso gadget avvolto in un LogEvent+ gadgetnessunorce — auto-innesco (richiede la classe gadget sulla vittima)
    S3CommonsCollections6 grezzo a livello toplog4j + cc-3.2.1nessunorifiuto — FOIS blocca CC
    S4CC6 inserito nel MarshalledObjectlog4j + cc-3.2.1 solonessunorce — nessuna classe dell'attaccante sulla vittima
    S5payload S4log4j + cc-3.2.1!java.rmi.MarshalledObjectrifiuto — mitigazione
    S6payload S4log4j + cc-3.2.1maxdepth=5;maxbytes=1000000silenzioso — lo stream interno eredita il filtro; CC6 troppo profondo
    S7payload S4log4j + cc-3.2.2nessunosilenzioso — 3.2.2 disabilita la deserializzazione di functor non sicuri

    rce = codice eseguito. rifiuto = FOIS ha lanciato un'eccezione sullo stream esterno. silenzioso = oggetto esterno elaborato, nessun codice eseguito (bloccato più in profondità, o la versione del gadget è sicura).

    Eseguilo

    root@kitploit:~
    ./run.sh            # oppure: make run
    

    Requisiti: solo Docker (un JDK viene scaricato come eclipse-temurin:17-jdk). Lo script scarica i jar ufficiali e li verifica contro lo SHA-1 di Maven Central prima dell'uso. Fissa una versione Log4j diversa nell'intervallo vulnerabile con LOG4J_VERSION=2.20.0 ./run.sh.

    Impatto e metodo di attacco

    • Consegna: una singola scrittura TCP non autenticata di ~2,8 KB di un LogEvent serializzato verso un ricevitore basato su FOIS. Non è attivabile facendo registrare una stringa nei log (a differenza di Log4Shell) — richiede byte serializzati grezzi che raggiungono il bridge socket.
    • Risultato: esecuzione arbitraria di comandi nel processo del ricevitore, in modo silenzioso.
    • Percorso di attacco: costruisci un LogEvent → writeReplace()/writeObject() di Log4j avvolge il Message in un MarshalledObject → il gadget si nasconde nel suo byte[] opaco → sul ricevitore, readResolve() → message() → MarshalledObject.get() apre uno stream nuovo non filtrato → gadget → Runtime.exec. src/attacker/Attacker.java (poc2) inserisce un grafo puro CommonsCollections6 nei objBytes del MarshalledObject, quindi nessuna classe dell'attaccante è necessaria sulla vittima.

    Mitigazione

    • Affidabile: -Djdk.serialFilter='!java.rmi.MarshalledObject' sulla JVM del ricevitore (S5). Avvertenza: questo blocca anche gli oggetti LogEventProxy serializzati legittimi (anche loro usano MarshalledObject) — è efficace ma non trasparente per il trasporto di log serializzati.
    • Non affidabile: filtri generici maxdepth/maxbytes. Il filtro a livello di processo si propaga nello stream interno del MarshalledObject e la profondità ricomincia lì, quindi maxdepth=5 blocca CC6 (S6) ma un gadget poco profondo passerebbe. Dipende dalla profondità della catena, non è un confine.
    • Strutturale: elimina il trasporto di log serializzati in Java (usa JSON / RFC 5424 su TLS autenticato); rimuovi le dipendenze gadget note; non esporre ricevitori serializzati legacy a reti non fidate. Correzione a monte (secondo l'issue): rimuovi MarshalledObject dalla allowlist e sposta il messaggio marshallato nei metodi filtrati writeWrappedObject/readWrappedObject di Log4j.

    Scope e limiti onesti

    • Condizionata dall'applicazione, non una RCE Log4j generale. Richiede un'app che espone un ricevitore LogEvent serializzato non autenticato basato su FOIS e ha una versione di gadget utilizzabile nel proprio classpath. Le distribuzioni Log4j ordinarie non eseguono un tale ricevitore.
    • Il server socket serializzato nel core è esistito solo fino alla 2.8.2 (net.server.TcpSocketServer è stato spostato fuori da log4j-core nel 2017; assente dalla 2.9.0 in poi). I ricevitori moderni sono codice applicativo/di esempio, che questo laboratorio modella.
    • Dipende dalla versione del gadget. commons-collections 3.2.1 → RCE; 3.2.2 lo blocca (S7). Qualsiasi gadget utilizzabile è sufficiente, ma "avere commons-collections" non è di per sé sufficiente.
    • uid=0 nel laboratorio è root del container — non c'è fuga da Docker; la RCE viene eseguita come processo del ricevitore.
    • Il primitivo (MarshalledObject che sconfigge un filtro resolveClass) è arte nota precedente; vedi la discussione Apache #4168 ("Log4j 2.x deserialization hardening"). L'auto-innesco specifico di Log4j è il contributo di #4255.

    Struttura

    root@kitploit:~
    run.sh                     esecutore portabile (checksum bloccato, oracle indurito)
    Makefile                   make build | run | clean
    src/victim/Receiver.java   ricevitore log FOIS (sostituto di ObjectInputStreamLogEventBridge)
    src/attacker/Attacker.java costruttore di payload: controlli, PoC-1, PoC-2 (CC6 + byte-splice)
    src/attacker/EvilMessage.java  gadget autonomo PoC-1
    docs/RESULTS.md            matrice di evidenze + analisi
    

    Riferimenti

    • Issue #4255 — https://github.com/apache/logging-log4j2/issues/4255
    • Discussione #4168 (indurimento deserializzazione) — https://github.com/apache/logging-log4j2/discussions/4168
    • FAQ Log4j CWE-502 — https://logging.apache.org/security/faq.html
    • Avviso di sicurezza Apache Commons Collections — https://commons.apache.org/proper/commons-collections/security.html

    Crediti

    Vulnerabilità segnalata da U-Sec (Wujie Security) nell'issue Apache log4j2 #4255. Questo repository è un laboratorio indipendente di riproduzione/validazione per ricerca difensiva e ingegneria del rilevamento.

    Scarica lo strumento