Skip to content
KitploitKITPLOIT
StrumentiExploitsBlog
Log in
Invia
StrumentiExploitsBlog
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.

FeedContattoPrivacy© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
CVE-2026-33701-Unsafe-Deserialization-in-OpenTelemetry-Java-Agent-RMI-Instrumentation — Analisi tecnica di CVE-2026-33701, una vulnerabilità di deserializzazione non sicura nell'instrumentazione RMI di OpenTelemetry Java Agent, inclusi condizioni di sfruttamento, dettagli della patch e strategie di mitigazione. | Kitploit
Strumenti/GitHubGitHub/pl4tyz/cve-2026-33701-unsafe-deserialization-in-opentelemetry-java-agent-rmi-instrumentation
Analisi delle VulnerabilitàExploitSicurezza WebApprendimento e Formazione
GitHubpl4tyz/cve-2026-33701-unsafe-deserialization-in-opentelemetry-java-agent-rmi-instrumentation

CVE-2026-33701-Unsafe-Deserialization-in-OpenTelemetry-Java-Agent-RMI-Instrumentation

Analisi tecnica di CVE-2026-33701, una vulnerabilità di deserializzazione non sicura nell'instrumentazione RMI di OpenTelemetry Java Agent, inclusi condizioni di sfruttamento, dettagli della patch e strategie di mitigazione.

Vedi Repository
116 mesi faNon ancora revisionato

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

CVE-2026-33701 — Deserializzazione non sicura nell'instrumentazione RMI dell'OpenTelemetry Java Agent

Gravità: Critica (CVSS v4.0: 9.3)
Versioni interessate: opentelemetry-javaagent < 2.26.1
Corretta in: 2.26.1 (rilasciata il 23 marzo 2026)


Panoramica

OpenTelemetry è probabilmente il framework di osservabilità più adottato nell'ecosistema Java al momento. L'agente Java in particolare viene utilizzato da migliaia di servizi in produzione per instrumentare automaticamente le applicazioni per tracing, metriche e logging senza richiedere alcuna modifica al codice da parte dello sviluppatore. Basta allegarlo come flag javaagent e fa tutto dietro le quinte.

Ciò che rende interessante CVE-2026-33701 non è solo la vulnerabilità in sé, ma la natura di come è stata introdotta. L'agente registra silenziosamente un endpoint RMI personalizzato come effetto collaterale della sua instrumentazione RMI. Gli sviluppatori non sanno che è lì. Non è in alcun codice applicativo. Non è qualcosa che hanno configurato. L'agente lo ha messo lì automaticamente e, per le versioni precedenti alla 2.26.1, quell'endpoint deserializzava i dati in arrivo senza alcun filtro applicato.

Se l'applicazione aveva già una porta RMI o JMX esposta, un attaccante con accesso di rete a quella porta poteva inviare un payload serializzato appositamente costruito all'endpoint personalizzato dell'agente e potenzialmente ottenere l'esecuzione remota di codice con i privilegi del processo JVM. Il problema è che l'RCE richiede una catena di gadget compatibile presente nel classpath dell'applicazione. Ne parleremo più avanti.


Come l'Agente Instrumenta RMI

Quando l'agente OTel Java si aggancia a una JVM, instrumenta le chiamate RMI per la propagazione del contesto. L'idea è che quando un client RMI chiama un metodo remoto, l'agente deve propagare il contesto di trace corrente al lato server affinché gli span si colleghino correttamente attraverso i confini dei servizi.

Per fare ciò, l'agente registra il proprio oggetto RMI personalizzato utilizzando un ObjID hardcoded. In ContextPropagator.java:

public static final ObjID CONTEXT_CALL_ID =
    new ObjID("io.opentelemetry.javaagent.context-call".hashCode());

Questo ObjID è il modo in cui l'agente identifica il proprio endpoint all'interno del runtime RMI. Quando un client RMI instrumentato si connette a un server, prima verifica se il server ha questo ObjID registrato. Se lo ha, invia un payload di propagazione del contesto. Se non lo ha, salta la propagazione del contesto e fa solo la chiamata regolare.

Il problema è che questo endpoint è registrato all'interno del runtime RMI della JVM, il che significa che condivide lo stesso trasporto di qualsiasi porta RMI o JMX che l'applicazione ha aperta. Se l'applicazione ha impostato -Dcom.sun.management.jmxremote.port, o se esporta i propri servizi RMI, l'endpoint dell'agente è raggiungibile su quella stessa porta da chiunque possa connettersi.


Il Codice Vulnerabile

La deserializzazione avviene in ContextPayload.java. Nelle versioni precedenti alla 2.26.1, il metodo read() appariva così:

@SuppressWarnings("BanSerializableRead") // fine
public static ContextPayload read(ObjectInput oi) throws IOException {
    try {
        Object object = oi.readObject();
        if (object instanceof Map) {
            @SuppressWarnings("unchecked")
            Map<String, String> map = (Map<String, String>) object;
            return new ContextPayload(map);
        }
    } catch (ClassCastException | ClassNotFoundException ex) {
        logger.log(FINE, "Error reading object", ex);
    }
    return null;
}

L'annotazione @SuppressWarnings("BanSerializableRead") con il commento // fine è in realtà piuttosto rivelatrice. Qualcuno nel team ha segnalato questo come una preoccupazione a un certo punto, è stata aggiunta la soppressione e il commento doveva giustificarla. Chiaramente non era a posto.

oi.readObject() senza filtri di serializzazione è il classico pattern di deserializzazione non sicura. La serializzazione Java istanzierà felicemente qualsiasi classe nel classpath durante la deserializzazione e, se l'attaccante può controllare lo stream serializzato, può scegliere quali classi istanziare e in quale ordine. Questa è la base degli attacchi a catena di gadget.

Il codice controlla instanceof Map dopo la deserializzazione, ma a quel punto il danno è già fatto. La catena di gadget si esegue durante la chiamata readObject() stessa, prima che avvenga qualsiasi controllo di tipo. Il controllo instanceof è completamente irrilevante dal punto di vista della sicurezza.


La Patch

La correzione nella 2.26.1 sostituisce completamente l'approccio di deserializzazione. Invece di serializzare un oggetto Map e chiamare readObject(), la nuova implementazione legge manualmente le voci di contesto come tipi primitivi:

@Nullable
public static ContextPayload read(ObjectInput oi) throws IOException {
    int size = oi.readInt();
    if (size > MAX_CONTEXT_ENTRIES) {
        logger.log(
            FINE,
            "RMI context propagation payload size {0} exceeds maximum allowed of {1}, skipping context propagation.",
            new Object[] {size, MAX_CONTEXT_ENTRIES});
        return null;
    }
    Map<String, String> map = new HashMap<>();
    for (int i = 0; i < size; i++) {
        String key = oi.readUTF();
        String value = oi.readUTF();
        map.put(key, value);
    }
    return new ContextPayload(map);
}

E il lato scrittura è stato aggiornato per corrispondere:

public void write(ObjectOutput out) throws IOException {
    int size = context.size();
    if (size > MAX_CONTEXT_ENTRIES) {
        out.writeInt(0);
        return;
    }
    out.writeInt(size);
    for (Map.Entry<String, String> entry : context.entrySet()) {
        out.writeUTF(entry.getKey());
        out.writeUTF(entry.getValue());
    }
}

Questo approccio legge solo tipi primitivi (int e stringhe UTF) dallo stream. Non avviene alcuna istanziazione di oggetti. Nessuna catena di gadget può eseguire tramite readInt() o readUTF(). La correzione è corretta e completa.

C'è anche una seconda modifica degna di nota. L'ObjID utilizzato per identificare l'endpoint personalizzato dell'agente è stato versionato:

// Prima (2.26.0)
new ObjID("io.opentelemetry.javaagent.context-call".hashCode());

// Dopo (2.26.1)
new ObjID("io.opentelemetry.javaagent.context-call-v2".hashCode());

Questo significa che un agente corretto non risponderà affatto al vecchio ObjID. Un attaccante che prende di mira il vecchio endpoint non riceverà alcuna risposta da un server corretto. Questa è una bella misura di hardening aggiuntiva oltre alla correzione della deserializzazione: rompe efficacemente qualsiasi exploit costruito contro l'endpoint v1 anche se in qualche modo la deserializzazione fosse ancora raggiungibile.


Condizioni di Sfruttabilità

Tutte e tre le seguenti condizioni devono essere vere simultaneamente affinché questo sia sfruttabile:

1. OpenTelemetry Java Agent agganciato su JDK 16 o inferiore

Questo è il vincolo più importante. JDK 17 ha introdotto modifiche significative agli internals RMI e impone un'incapsulazione dei moduli molto più rigorosa tramite il Java Platform Module System. La maggior parte delle catene di gadget che funzionano contro la deserializzazione Java si affidano alla riflessione per accedere a classi JDK interne o per invocare metodi che normalmente non sarebbero accessibili. JDK 17 rompe quei percorsi di riflessione per impostazione predefinita a causa della forte incapsulazione, il che significa che la maggior parte delle catene di gadget note semplicemente non funziona su JDK 17 e successivi.

Scarica lo strumento