MSMQ QueueJumper (RCE-Schwachstelle): eine detaillierte technische Analyse.

Arbeiten bei Nacht an mehreren Bildschirmen

Die Sicherheitsupdates, die Microsoft am 11. April 2023 veröffentlichte, beseitigten über 90 einzelne Sicherheitslücken. Besonders bemerkenswert war CVE-2023-21554, genannt QueueJumper, eine Schwachstelle für die Remote-Codeausführung, die den Microsoft Message Queueing (MSMQ) Dienst betrifft. MSMQ ist eine optionale Windows-Komponente, die es Anwendungen ermöglicht, Nachrichten über Nachrichtenwarteschlangen auszutauschen, die sowohl lokal als auch aus der Ferne erreichbar sind. Diese Analyse wurde in Zusammenarbeit mit den Teams von Randori und X-Force Adversary Services durchgeführt, von Valentina Palmiotti, Fabius Watson und Aaron Portnoy.

Beweggründe für die Forschung

Die folgenden Eigenschaften von CVE-2023-21554 erregten zunächst Aufmerksamkeit:

  • Aufgrund der unterschiedlichen Nutzung von MSMQ-Warteschlangen durch Anwendungen von Drittanbietern ist es schwierig, das gesamte Ausmaß der Auswirkungen von Schwachstellen zwischen und über Umgebungen hinweg zu ermitteln.
  • Erste Berichte sprachen von 360.000 über das Internet erreichbaren Hosts, auf denen der MSMQ-Dienst offengelegt war. Shodan, den ich zu dieser Zeit konsultierte, zeigte nur 250 an. Diese Diskrepanz machte das Ausmaß einer möglichen Gefährdung noch unklarer.
  • Die Schwachstelle wird als Remote-Code-Ausführung klassifiziert, die keine Authentifizierung erfordert und ebenfalls eine Vielzahl von Windows-Plattformen betrifft.
  • Die einzige offensichtliche Voraussetzung ist, dass der Dienst über TCP-Port 1801 erreichbar ist.

Anfängliche Triage

Identifikation von MSMQ-Endgeräten

Um zu bestimmen, wie das Vorhandensein von MSMQ erkannt werden kann, wurde ein Testsystem mit der Komponente in einer Laborumgebung konfiguriert. Beim Verbindungsaufbau zum MSMQ-Endgerät auf Port 1801 antwortete der Server nicht mit Daten. Man könnte davon ausgehen, dass der Server nicht antwortet, wenn er keine plausiblen Daten erhält. Um zu verstehen, wie man mit dem Endgerät kommuniziert, war eine genauere Untersuchung des zugrundeliegenden Codes erforderlich.

Lokalisieren von MSMQ-Code

Aus dem Advisory geht nicht unmittelbar hervor, welche Binärdatei gepatcht wurde. Der erste Schritt zur Identifizierung des geänderten Codes war das Herunterladen der Update-Datei. Das wurde durch die Suche nach KB5025224 im Microsoft Update-Katalog erreicht.

Screenshot der Suche nach MSMQ-Code

Suchergebnisse im Microsoft Update-Katalog für KB5025224

Insbesondere die kumulative Aktualisierungsdatei 

windows10.0-kb5025224-x64_3522b1b562ed44bc949541dd1c7d08e1e967d925.msu 

für Windows 11 für x86-basierte Systeme wurde abgerufen.

Der 7-Zip-Extractor wurde verwendet, um den Inhalt der MSU-Datei und der darin enthaltenen CAB-Dateien zu entpacken. Die Suche nach der Zeichenfolge „msmq“ in allen Dateien in den resultierenden Ordnern ergab die Container-Indexdatei, 

Windows11.0-KB5025239-x64/express.psf.cix.xml,

wozu auch folgender Eintrag gehörte:

<File id="21296" name="amd64_microsoft-windows-msmq-queuemanager-core_31bf3856ad364e35_10.0.22621.1555_none_5f975f8fdb349517\f\mqqm.dll" length="34811" time="133245266510000000" attr="128">

Dieser Eintrag bezieht sich auf MQQM.dll , das als Ziel für weitere Analysen identifiziert wurde.

Identifizierung von gepatchtem Code

Um die Änderungen zwischen der gepatchten und der ungepatchten Version der DateiMQQM.dll zu ermitteln, wurde das BinDiff-Tool von Zynamics verwendet. Das folgende Bild zeigt die abgestimmten Funktionen mit einem Ähnlichkeitswert unter1.00:

Screenshot des gepatchten Codes

BinDiff-Ergebnisse zwischen gepatchten und ungepatchten MQQM.dll-Dateien 

Die Analyse dieser Funktionen mit dem Hex-Rays Decompiler ergab Symbole für die gepatchte Version, die ausführliche Funktionsnamen enthalten, welche anscheinend auf Schwachstellenkennungen des Microsoft Security Research Center (MSRC) verweisen:

Screenshot der Referenz Microsoft Security Research Center (MSRC)

Funktions-Flag-Symbole in MQQM.dll

Funktions-Flag-Analyse

Bei näherer Betrachtung entsprechen die Symbole mit MSRC-Fallnummern den Feature Flags für Schwachstellenbehebungen. Feature Flags sind eine Komponente von Windows, mit der verschiedene Funktionen und Experimente aktiviert oder deaktiviert werden können. In diesem Fall handelt es sich bei dem entdeckten „Feature” tatsächlich um einen Patch für eine Schwachstelle. Wenn das Feature aktiviert ist, wird der sichere, gepatchte Codepfad ausgeführt. Andernfalls wird der ursprüngliche, ungepatchte Codepfad ausgeführt.

Screenshot des ursprünglich ausgeführten ungepatchten Codepfads

Dekompilierter Codeausschnitt mit Funktion zur Behebung der Sicherheitslücke

Für jede der Sicherheitslücken, die CVE-2023-21554 umfassten, wurde sowohl in der Benutzer- als auch in der Kernelkomponente eine Funktions-Flag-Überprüfung durchgeführt. Die Analyse der verbleibenden Binärdateien, die im Sicherheitsupdate-Paket enthalten sind, ergab, dass auch Funktions-Flags für die meisten oder alle Sicherheitslücken eingeführt wurden, die am Patch Tuesday im April 2023 behoben wurden.

Ursachenanalyse

Durch den Abgleich dieser Flags konnten wir die Stellen im gepatchten Code schnell lokalisieren. Insbesondere die Änderungen innerhalb von CQmPacket::CQmPacket, welche sich auf die ixes-Flag MSRC76146_MSMQ_OOBRWF bezog, schien von größtem Interesse zu sein.

Die Überprüfung dieses Funktions-Flags erfolgt achtmal innerhalb der Funktion. Eine solche Überprüfung ist unten dargestellt:

Screenshot der Ursachenanalyse

Dekompilierter Codeausschnitt, der die Fixes der Sicherheitslücke zeigt 

Im oben gezeigten dekompilierten Codeausschnitt erhält der gepatchte Codepfad den Zeiger auf den nächsten Abschnitt der MSMQ-Nachricht durch einen Aufruf von GetNextSectionPtrSafe. Im ungepatchten Pfad wird der Zeiger einfach durch Addition der Größe des Abschnitts ohne weitere Prüfungen ermittelt. Die neue Funktion GetNextSectionPtrSafe überprüft, ob der berechnete Zeiger auf den nächsten Abschnitt des Pakets die Länge des Pakets selbst nicht überschreitet.

Screenshot einer Funktion

Dekompilierungsausschnitt der Funktion GetNextSectionPtrSafe

Nach der Untersuchung aller Vorkommnisse dieser Funktion und anderer wurde festgestellt, dass CVE-2023-21554 aus mehreren Fehlern besteht, die die Größe verschiedener MSMQ-Nachrichtenabschnittstypen unzureichend überprüfen. Durch diese Schwachstellen kann der Hinweis auf das Ende der MSMQ-Nachricht um einen beliebigen 32-Bit-Offset außerhalb der Grenzen des ursprünglich zugewiesenen Buffers erhöht werden.

Nach der Paketverarbeitung wird im letzten Schritt von CQmPacket::CQmPacket ein OnDiskExtensionHeader an das Ende des Paketpuffers angehängt. Aufgrund der zuvor genannten Sicherheitslücken kann es vorkommen, dass der berechnete Zeiger auf das Ende der Nachricht außerhalb des gültigen Bereichs liegt. Das Anhängen des OnDiskExtensionHeader kann daher zu mehreren Schreibvorgängen außerhalb des zulässigen Speicherbereichs führen. Der untenstehende dekompilierte Code zeigt eine korrigierte Überprüfung des anfälligen Nachrichtenendzeigers, bevor die OOB-Schreibvorgänge erfolgen:

Screenshot einer gepatchten Prüfung auf den Hinweis des anfälligen Nachrichtenendes, bevor die OOB-Schreibvorgänge stattfinden

Überprüfung des Speicherzugriffs außerhalb des Speicherbereichs für Nachrichtenende

Kernelvarianten

Bei der Bewertung der Ausnutzbarkeit der Schwachstellen wurden weitere Kernel-Schwachstellen im entsprechenden Treiber für den MSMQ-Dienst identifiziert, mqac.sys. Die Schwachstellen wurden erneut durch Funktion-Flag-Symbole angezeigt, die ebenfalls auf den MSRC-Fall 76146 verweisen, wie in MQQM.dll beobachtet.

Screenshot einer Funktion

Funktions-Flag-Symbole in mqac.sys

Die Analyse der FunktionKernelVariants hat ergeben, dass die entsprechenden Schwachstellen analog zu denen sind, die in der Komponente gefunden wurden. Die Kernel-Komponentemqac.sys  ist an verschiedenen Operationen für den MSMQ-Service beteiligt, wie dem Weiterleiten von Nachrichten an Dead-Letter Queues, dem Senden von Bestätigungsnachrichten und der Speicherverwaltung von MSMQ-Paketpuffern.

Um die zugehörigen Vorgänge auszuführen, analysiert die Kernelkomponente verschiedene Abschnitte des MSMQ-Paketpuffers. Zwei solcher Instanzen sind unten abgebildet:

Screenshot von Um die entsprechenden Operationen durchzuführen, analysiert die Kernel-Komponente verschiedene Abschnitte des MSMQ-Paketbuffers

Dekompilierter Codeausschnitt, der das Funktions-Flag zur Behebung einer Sicherheitslücke im Kernel-Treiber mqac.sys zeigt

Wie im dekompilierten Codeschnipsel oben zu sehen ist, werden, wenn das Feature-Flag aktiviert ist, die „sicheren“ Funktionen CPacketBuffer::MsgDeadletterHeaderSafe  und CPacketBuffer::MsgOnDiskExtensionHeaderSafe  aufgerufen, um die entsprechenden Header aus dem Paketpuffer abzurufen. Wenn diese Option nicht aktiviert ist, werden die „unsicheren“ Funktionen aufgerufen, die keine ausreichenden Prüfungen der Abschnittsgröße durchführen.

Auslösende Schwachstelle

Protokoll-Reverse-Engineering

Der Großteil des Codes für das Parsen von Protokollen befindet sich in der BibliothekMQQM.dll , die durch den Prozessmqsvc.exe geladen wird. Um den Code zu erreichen, der von MSRC76146_MSMQ_OOBRWFixes referenziert wird, muss eine gültige MSMQ-Anfrage vom Client gesendet werden. Die MSMQ-Nachrichtenspezifikation und das Protokoll sind umfangreich und komplex. Anfangs wurde öffentlicher Code für das Scannen von MSMQ-Servern in einem GitHub-Gist gefunden, der die Grundlage für eine tiefere Untersuchung der Paketverarbeitung bildete. Darüber hinaus war die Microsoft-Dokumentation hilfreich, um das MSMQ-Nachrichtenformat zu verstehen.

Der Code innerhalb der DLL akzeptiert Daten über Port 1801 mit einem Aufruf der WSARecc-Funktion, wie in der untenstehenden Debugging-Sitzung zu sehen ist:

0:020> bp ws2_32!wsarecv ; g

Breakpoint 0 erreicht

WS2_32!WSARecv:

00007ffd`651115c0 48895c2408      mov     qword ptr [rsp+8],rbx ss:000000aa`f07fef30=0000000000000006

 

0:019> k

# Child-SP          RetAddr               Call Site

00 000000aa`f07fef28 00007ffd`57ba9cb0     WS2_32!WSARecv

01 000000aa`f07fef30 00007ffd`57b9683d    

MQQM!NoReceivePartialBuffer+0x38

02 000000aa`f07fefb0 00007ffd`57b2078e     MQQM!CWinsockConnection::ReceivePartialBuffer+0x7d

03 000000aa`f07ff010 00007ffd`57b25b28    

MQQM!CSockTransport::BeginReceive+0xe6

04 000000aa`f07ff060 00007ffd`57b2d40b    

MQQM!CSockTransport::NewSession+0x194

05 000000aa`f07ff3f0 00007ffd`57b2d367     MQQM!CSessionMgr::AcceptSockSession+0x6f

06 000000aa`f07ff430 00007ffd`645e26bd     MQQM!AcceptIPThread+0x6a7

07 000000aa`f07ff7d0 00007ffd`6650a9f8    

KERNEL32!BaseThreadInitThunk+0x1d

08 000000aa`f07ff800 00000000`00000000     ntdll!RtlUserThreadStart+0x28

 

0:019> r @$t0=@rdx

0:019> pt

WS2_32!WSARecv+0x19f:

00007ffd`6511175f c3              ret

0:019> dc poi(@$t0+8) LC

000001b5`880ff490  62f06110 524f494c 00000070 5a5a5a5a  .a.bLIORp…ZZZZ

000001b5`880ff4a0  0073006e 00610074 0063006e 00200065  n.s.t.a.n.c.e. .

000001b5`880ff4b0  00440049 00000000 00000000 00000000  I.D………….

 

0:019> ba r1 poi(@$t0+8) ; g

Breakpoint 1 erreicht

MQQM!CBaseHeader::SectionIsValid+0x154:

00007ffd`57b53450 7462            je     

MQQM!CBaseHeader::SectionIsValid+0x1b8 (00007ffd`57b534b4) [br=1]
 

Die Funktion CBaseHeader::SectionIsValid ist dafür verantwortlich, den Anfang einer neuen Nachricht zu parsen, die mit einer BaseHeader-Struktur der Form beginnt:

Screenshot der BaseHeader-Struktur des Formulars

Struktur des BaseHeader-Objekts

Die Felder der eingehenden Nachricht werden durch SectionIsValid validiert, bevor der Server eine Antwort sendet:

Screenshot der Nachrichtenfelder

Disassemblierungscode für SectionIsValid innerhalb von MQQM.dll 

Nach der ersten Validierung findet der Großteil des Protokollparsings innerhalb der KonstruktorfunktionCQmPacket:: CQmPacket statt. Um eine Sicherheitslücke gemäß CVE-2023-21554 auszulösen, kann eine MSMQ-Nachricht gesendet werden, die einen fehlerhaften Abschnittskopf enthält, der nicht richtig verarbeitet wird. Das folgende Beispiel beschreibt das Auslösen einer Sicherheitslücke mit einem EodHeader für einen Eod-Abschnitt (Exactly-Once-Delivery).

Screenshot der Auslösung einer Sicherheitslücke mithilfe eines EodHeader für einen Eod

Dekompilierung zeigt Sicherheitslücke bei der Handhabung von EodHeader

Die obige Dekompilierung zeigt den gepatchten Pfad, der die FunktionCEodHeader::GetNextSectionSafe. T aufruft. Der ungepatchte Pfad führt einfach einen Zeiger hinzu und verwendet Werte innerhalb der Überschrift, um den Beginn des nächsten Abschnitts zu berechnen.

Die Struktur einesEodHeader  ist nicht dokumentiert; das Flag-Bit, das das Vorhandensein einesEodHeader inUserHeader anzeigt, ist in der Dokumentation von Microsoft als „reserviert“ angegeben, was besagt, dass das Flag-Bit beim Senden nicht gesetzt werden sollte. Der Blick auf die Disassembly kann Einblick in die Struktur des Headers geben:

Screenshot der Header-Struktur

Demontage Berechnung der Gesamtgröße des EodHeader-Abschnitts

In der obigen Disassemblierung wird der Zeiger auf den Anfang von EodHeader in das Register rdx  geladen. Es kann vermutet werden, dass das erste und zweite Feld des Headers ganzzahlige Größen beschreiben (Header-Größe und Datengröße, oder etwas Ähnliches). Die beiden Größen plus 0xF geben die Gesamtgröße des Eod-Abschnitts in Bytes an. Durch das Senden einer Nachricht mit einem EodHeader, dessen entsprechende Größenfelder auf große Werte gesetzt sind, wird ein Schreibvorgang außerhalb des zulässigen Bereichs ausgelöst. Dies führt zu einer Zugriffsverletzung, wenn OnDiskExtensionHeader bis zu dem geschrieben wird, was (das Programm) als Ende der Nachricht denkt:

Screenshot einer Erweiterungsüberschrift

WinDbg-Sitzung zeigt eine Zugriffsverletzung beim Schreiben an das Ende einer fehlerhaften MSMQ-Nachricht an.

Ausnutzbarkeit

Speicherverwaltung und -manipulation

Um die Stärke des durch die Sicherheitslücken erzielten Schreibvorgangs außerhalb des zulässigen Bereichs zu bewerten, haben wir zunächst die Zuweisung und Verwaltung des zugrunde liegenden Speichers untersucht.

Bevor ein Nachrichtenpaket MSMQ verarbeitet wird, wird sein Inhalt in einen Puffer kopiert, der in der Funktion QmAcAllocatePacket zugewiesen wurde. Diese Funktion ruft den Kernel-Treiber mqac.sys überNtDeviceIoControl.

Screenshot von Funktionsaufrufen in der Datei mqac.sys

Dekompilierung der Paket-Bufferzuweisungsfunktion

Die Kernel-Komponente gibt einen Puffer zurück, der aus einer gemappten Ansicht einer Datei auf der Festplatte partitioniert ist, gespeichert im VerzeichnisC:\Windows\System32\msmq\storage mit einer Erweiterung.mq  . Jede Datei kann bis zu 4 MB groß sein und Nachrichten aus mehreren Warteschlangen enthalten.

Screenshot der Kernel-Komponente

ProcessHacker-Speicherlayout des MQSVC-Prozesses, das zeigt, dass der Paketpufferspeicher eine Dateizuordnung ist

Die Paketpufferadresse wird zusammen mit einem zufälligen Paket-Handle nach der Zuweisungsanforderung über IOCTL an den Benutzerbereich zurückgegeben. Der Treiber verwendet das Handle, um die Paketpufferadresse bei der Bearbeitung von Anforderungen aus dem Benutzerbereich zu berechnen.

Heap-Pflege

Der zugrundeliegende Speicherplatz für die anfälligen Buffer befindet sich in einer zugeordneten Datei und somit nicht im Heap des Prozesses. Außerdem speichert der betroffene Speicher keine Objekte. Die Dateizuordnung enthält ausschließlich den Inhalt der MSMQ-Nachrichten sowie die darin gespeicherten Metadaten. OnDiskExtension.

Darüber hinaus ist es ohne Vorkenntnisse über den Speicheraufbau nicht möglich, die relative Positionierung der Dateizuordnung zum Heap des Prozesses zu kennen, um Objektzeiger zu überschreiben. Um also die Ausführung von Remote-Code zu ermöglichen, benötigen wir eine Methode, mit der sich der Speicher in eine vorhersagbare Position bringen lässt.

Nach Experimenten mit dem Senden legitimer MSMQ-Nachrichten an das Ziel wurde festgestellt, dass es möglich ist, eine neue Heap-Allokation neben einer Dateizuordnung .mq durch Versenden vieler Nachrichten zu erzwingen. Nachrichten werden sequentiell in den Speicher geschrieben, bis sie empfangen werden, und mithilfe der MSMQ-Nachrichteneigenschaft TimeToBeReceived kann die Freigabe bestimmter Nachrichten zeitlich genau gesteuert werden.

Screenshot der Kernel-Komponente

Speicherlayout des MQSVC-Prozesses zeigt einen neuen Heap, der direkt an eine MQ-Dateizuordnung angrenzt

Dies setzt jedoch voraus, dass der Angreifer Zugriff auf das Senden von Nachrichten an mindestens eine Warteschlange des Ziels hat. Andernfalls werden die Nachrichten verworfen und überschrieben und belegen daher den Paketspeicher nicht dauerhaft.

In den durchgeführten Forschungsversuchen wurde festgestellt, dass es einem nicht privilegierten Benutzer möglich ist, eine Warteschlange zu erstellen, die standardmäßig für jeden zugänglich ist, um Nachrichten aus der Ferne zu senden. Die  Warteschlange bleibt auf dem System auf unbestimmte Zeit bestehen. Obwohl die meisten modernen Anwendungen von MSMQ als optionale Komponenten und Adapter existieren, bieten Anbieter wie Oracle, Veritas und Xerox Unternehmenssoftware an, die MSMQ als zentrale Abhängigkeit nutzt. Daher ist das Angriffsszenario nicht unrealistisch.

Ausnutzende Primitive

Die Sicherheitslücke im Zusammenhang mit ausgehendem Speicherzugriff führt ein Exploit-Primitiv ein, das es einem böswilligen Client ermöglicht, einenOnDiskExtensionHeader jenseits der Boundary des für das Paket zugewiesenen Speichers hinaus zu schreiben.

Bei der Bewertung einer Schwachstelle, die das Schreiben von Werten in einen Offset ermöglicht, müssen einige Eigenschaften
berücksichtigt werden:

  • Kann der Offset kontrolliert werden?
  • Können die geschriebenen Werte kontrolliert werden?

Im Fall der QueueJumper-Sicherheitslücken ist der Offset des zugewiesenen Puffers zum OOB-Schreiben kontrollierbar, da er anhand von vom Angreifer kontrollierten Daten berechnet wird. Der Inhalt des OOB-Schreibens unterliegt jedoch einer begrenzten Kontrolle.

Hier stelltAddress den beschädigten Zeiger auf das Ende der Paketnachricht dar, wo der Header OnDiskExtension geschrieben wird. Die Abfolge der Vorgänge ist wie folgt:

  • Wert 0x000000000000000C wird geschrieben aufAddress
  • Wert0x00000000 wird geschrieben an Address+0x2
  • Wert0x0000000000000000 wird geschrieben an Address+0x12
  • Wert 0x0000000000000000 wird geschrieben an Address+0x1A
  • Wert 0x00000094 wird geschrieben Address+0xE
  • Wert0x0000 wird geschriebenAddress+0x22
  • Wert 0x0000 wird geschrieben an Address+0x62
  • memcpy(Address+0xA6, Source, Source->AddressLength+0x08)

DerSource , der im Ruf zumemcpy verwendet wird, bezieht sich auf ein TA_ADDRESS-Objekt. Die Struktur TA_ADDRESS definiert eine einzelne Transportadresse eines bestimmten Typs (zum Beispiel NetBIOS). Die Definition lautet wie folgt:

typedef struct _TA_ADDRESS {

    USHORT AddressLength;;

    USHORT AddressType; Info;

    UCHAR-Address[1];;

} TA_ADDRESS, *PTA_ADDRESS;

AddressLength

Gibt die Anzahl der Bytes in einer Adresse des angegebenen AddressType an.

AddressType

Gibt den Typ der Transportadresse an.

Address

Gibt ein Array variabler Größe an, das die Transportadresse enthält.

In der folgenden Debugging-Sitzung enthältTA_ADDRESS vom Angreifer beeinflusste Daten in Form einer IP-Adresse:

rax=0000014e1d110180 rbx=0000014e1d110180 rcx=0000014e1d110184

rdx=0000014e1ce86b10 rsi=0000014e1d110001 rdi=0000000545d7fa50

rip=00007ff843208074 rsp=0000000545d7f940 rbp=0000000545d7f980

r8=000000000000000c  r9=0000000000000002 r10=0000000000000000

r11=0000000545d7f938 r12=0000000000000002 r13=0000000000001000

r14=0000014e1ce86b10 r15=0000000000000000

iopl=0         nv up ei pl nz na po nc

cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000206

MQQM!CQmPacket::CQmPacket+0x89c:

00007ff8`43208074 e8a5780a00      call    MQQM!memcpy (00007ff8`432af91e)

0:017> dc rcx

0000014e`1d110184  00010004 00000000 8620a8c0 00000000  ………. …..
 

Oben hat das ObjektTA_ADDRESS eine Länge von 4 , eine Art von1 und einen Wert von 0x8620a8c0 . Die Umwandlung jedes Bytes in ein IPv4-Oktett ergibt die Adresse 192.168.32.134 , das ist die IPv4-Quelladresse des Clients.

Dieses Szenario erlaubt das Schreiben von angreifergesteuerten Daten über eine Adresse zu einem kontrollierten Offset zur Paketallokation im Speicher. Dies ist zwar sehr restriktiv und möglicherweise unpraktisch, könnte aber theoretisch verwendet werden, um die in den Speicher geschriebenen Werte genau zu kontrollieren, indem mehrere Anfragen von unterschiedlichen Adressen mit abnehmenden Paketoffsets gestellt werden.

Alternative Angriffe

Aufgrund der Vielzahl von Einschränkungen bei der blinden Remote-Codeausführung wurden alternative Angriffsszenarien, wie z. B. Datenlecks, untersucht.

Ein Angriff, der in Frage kam, bestand darin, den Hinweis auf einen bestimmten Nachrichtenabschnitt zu beschädigen, um auf einen Speicher außerhalb der Grenzen zu verweisen, und später die Nachricht abzurufen, um den benachbarten Speicher zu lesen.

Allerdings wird zu Beginn jedes Abschnitts-Parsings die Position des aktuellen Abschnitts überprüft, sodass wir die Parsing-Logik nicht dazu bringen können, einen Datenabschnitt zu parsen, der außerhalb der Grenzen liegt.

Ein anderes mögliches Angriffsszenario besteht darin, den OnDiskExtensionHeader einer anderen Nachricht zu überschreiben, um den Empfänger der Nachricht über den Ursprung der empfangenen Nachricht zu täuschen. Ebenso ist es möglich, den Inhalt von Nachrichten zu überschreiben, die für Warteschlangen bestimmt sind, auf die der Angreifer keinen Zugriff hat. Um bestimmte Inhalte einer Nachricht zu überschreiben, müsste der Angreifer Informationen über die Nachricht besitzen, beispielsweise über deren Größe.

Es gibt einen optionalen Abschnitt namens SoapHeader, der anfällig für den Datenzugriff außerhalb des zulässigen Bereichs ist und das folgende Format hat:

Screenshot eines SoapHeader

SoapHeader-Paketformat

Es wurde festgestellt, dass der Speicher, der zum Speichern von MSMQ-Paketdaten verwendet wird, beim Freigeben des Puffers nicht ordnungsgemäß gelöscht wird. Dadurch führt das Senden eines MSMQ-Pakets, das kleiner ist als ein vorheriges MSMQ-Paket, dazu, dass das Speicherlayout die Daten des aktuellen Pakets gefolgt von Daten aus zuvor verarbeiteten MSMQ-Paketen enthält.

Es wurde entdeckt, dass  SoapHeader dazu verwendet werden kann, diese Eigenschaft zu missbrauchen, um Daten aus zuvor verarbeiteten Paketen oder benachbarten gespeicherten Nachrichten offenzulegen. Ein Angreifer kann die Seite BodyDataLength beliebig definieren und den Abschnitt Body ganz ausschließen. Dies führt zu einer MSMQ-Nachricht, die potenziell sensible Daten aus zuvor verarbeiteten MSMQ-Paketen als Ergebnisse Body des Angreifers SoapHeader enthält. Der gepatchte Codepfad verhindert diesen Missbrauchsfall, da er validiert, dass die Daten Body Daten innerhalb der Grenzen der MSMQ-Paketdaten liegen.

Die eingeschränkte Kontrolle über Schreibinhalte, wobei zusätzliche unkontrollierte Schreibvorgänge benachbarte Speicherbereiche beschädigten, sowie begrenzte Kenntnisse über das Nachrichtenlayout erwiesen sich als großes Hindernis bei der Ausbeutung.

Angriff über den Kernel

Zum Zeitpunkt der Analyse wurden nur die Nutzerraum-Schwachstellen bei der anfänglichen Verarbeitung eines MSMQ-Nachrichtenpakets auf Ausnutzbarkeit geprüft. Die Analyse der Schwachstellen der Kernel-Variante könnte zusätzliche Ausbeutungsmöglichkeiten aufdecken. Zum Beispiel ist es möglich, dass das Einfügen eines fehlgeleiteten Headers ein Schreibprimitiv in der Kernel-Speicherzuordnung der Datei .mq erzeugt. In einigen Fällen verhindern Kontrollen in der Benutzerraumverarbeitung, dass der Kernel einige Nachbearbeitungsoperationen durchführen kann.

Außerdem hat der Angreifer bei den Kernel-Varianten weniger direkte Kontrolle über den Inhalt der Nachrichten und arbeitet mit derselben Dateizuordnung wie der Benutzerbereich und nicht in einem Kernel-Pool (Heap). Auch Schutzmaßnahmen wie KASLR stellen Hindernisse dar, die für die Ausbeutung schwer zu überwinden sind.

Erkennen von anfälligen Servern

Aufgrund der Implementierung des gepatchten Codes kann ein Remote-Client sicher feststellen, ob ein System das Update installiert hat. Dies kann durch das Senden einer MSMQ-Nachricht erfolgen, die eine Sicherheitslücke auslöst, aber keinen ausgehenden Zugriff verursacht, wodurch der Dienstprozess nicht zum Absturz gebracht wird. Wenn das HTTP-Flag im UserHeader der Nachricht gesetzt ist, wird ein SRMPEnvelopeHeader erwartet. Im Patch wird eine Überprüfung auf einen ganzzahligen Überlauf im Feld multipliziert mit 2 durchgeführt. Diese Länge kann so eingestellt werden, dass das Ergebnis der Multiplikation eine kleine Zahl ergibt, die der tatsächlichen Größe der Daten DataLength entspricht.

Dekompilierter Codeausschnitt, der die Überprüfung auf Integer-Überlauf bei SRMPEnvelopeHeader DataLength zeigt

Dekompilierter Codeausschnitt, der die Überprüfung auf Integer-Überlauf bei SRMPEnvelopeHeader DataLength zeigt

Wenn das Ziel gepatcht wird, führt die Schwachstelle dazu, dass eine Ausnahme ausgelöst wird und der Server die Verarbeitung der Nachricht abbricht, sodass keine Antwort an den Client zurückgesendet wird. Wenn das Problem nicht behoben wird, verarbeitet der Server die Nachricht normal und sendet eine Antwort.

Zusammenfassung

Aufgrund des Speicherplatzes der anfälligen Puffer scheint die Remotecodeausführung für einen Angreifer mit der Fähigkeit, Nachrichten an eine beliebige Warteschlange des Ziels zu senden, praktikabler. In diesem Szenario ist es möglich, den Heap so zu pflegen, dass ein angrenzender Heap zugewiesen wird. Die extrem eingeschränkte Kontrolle über Schreibinhalte stellt eine Herausforderung für die Remote-Ausbeutung dar. Aufgrund von Abschwächungen wie ASLR muss auch ein Informationsleck erhalten werden. Es ist möglich, dass ein einzelner Schreibvorgang einer Konstanten (0xC, 0x0 – mit Hilfe des Primitivs) auf ein Objekt dies erreichen könnte, allerdings muss das Objekt ein nützliches Feld enthalten, in dem die angrenzenden Felder einer Beschädigung durch die anderen Schreibvorgänge standhalten können. Darüber hinaus muss das Objekt vom Angreifer vorhersehbar zugewiesen werden können, die Lebensdauer des Objekts muss die Dauer der Ausbeutung umfassen und eine bestimmte Aktion des Objekts muss vom Angreifer auslösbar sein. Im Verlauf dieser Forschung wurden keine geeigneten Objekte entdeckt.

Letztendlich kommen wir zu dem Schluss, dass die Ausbeutung von QueueJumper aus der Ferne zwar nicht unmöglich ist, die zuvor genannten Anforderungen dies jedoch erschweren. Dieser Blogbeitrag zeigt nur die Oberfläche von einer sehr komplexen Nachrichtenspezifikation, einem Dienst und einem Protokoll. Weitere Recherchen zu den Schwachstellen sowohl im Benutzerbereich als auch bei den Kernel-Komponenten sind gerechtfertigt.

Mixture of Experts | 12. Dezember, Folge 85

KI entschlüsseln: Wöchentlicher Nachrichtenüberblick

Schließen Sie sich unserer erstklassigen Expertenrunde aus Ingenieuren, Forschern, Produktführern und anderen an, die sich durch das KI-Rauschen kämpfen, um Ihnen die neuesten KI-Nachrichten und Erkenntnisse zu liefern.