Cold Hard Cache – Umgehung der RPC-Schnittstellensicherheit durch Cache-Missbrauch
Zusammenfassung
Forscher von Akamai fanden zwei wichtige Schwachstellen in Microsoft Windows RPC- Services, die CVE-2022-38034 und CVE-2022-38045 mit Basiswerten von 4,3 bzw. 8,8.
Die Schwachstellen nutzen einen Designfehler aus, der die Umgehung von MS-RPC-Sicherheitscallbacks durch Caching ermöglicht.
Wir konnten bestätigen, dass die Schwachstelle in nicht gepatchten Windows 10- und Windows 11-Computern besteht.
Die Schwachstellen wurden verantwortungsvoll an Microsoft weitergegeben und im Patch Tuesday für Oktober behoben.
Der Prozess der Schwachstellenerkennung wird durch ein Automatisierungstool und eine von Akamai-Forschern entwickelte Methodik unterstützt.
Wir stellen im RPC-Toolkit-Repository einen Machbarkeitsnachweis für die in unserer Forschung verwendeten Schwachstellen und Tools zur Verfügung.
Einführung
MS-RPC ist einer der Eckpfeiler des Windows-Betriebssystems. Es wurde bereits in den 1990er Jahren eingeführt und hat sich seitdem in den meisten Bereichen des Systems etabliert. Der Service-Manager? RPC. LSASS? RPC. COM? RPC. Sogar einige Domain-Operationen gegen den Domain Controller verwenden RPC. Wenn man bedenkt, wie alltäglich MS-RPC geworden ist, sollte man erwarten, dass es intensiv geprüft, dokumentiert und erforscht wurde.
Doch das wurde es nicht. Obwohl die Dokumentation von Microsoft über die Verwendung von RPC recht gut ist, wurde nicht viel über das Thema geschrieben, auch nicht von Forschern, die sich mit RPC befassen, insbesondere mit dessen Sicherheit. Dies ist wahrscheinlich auf die Tatsache zurückzuführen, dass RPC (nicht nur MS-RPC, auch wenn Microsoft sicherlich seinen Teil dazu beigetragen hat) sehr komplex ist. Dadurch sind die Recherche und das Verständnis eine enorme Aufgabe.
Aber wir schrecken vor keiner Herausforderung zurück und haben beschlossen, in die Tiefen von MS-RPC einzutauchen. Nicht nur, weil es ein interessantes Forschungsthema ist, sondern auch wegen seiner Auswirkungen auf die Sicherheit – selbst heute noch basieren gängige Angriffstechniken auf RPC (T1021.003 läuft über MS-COM, T1053.005 ist MS-TSCH, T1543.003 ist MS-SCMR, um nur einige zu nennen). MS-RPC enthält zwar Sicherheitsmechanismen, aber was ist, wenn es Schwachstellen gibt, durch die sie umgangen oder missbraucht werden können, oder wenn ein exponierter RPC-Service missbraucht werden kann, um Rechner in unerwünschter Weise zu beeinflussen?
Tatsächlich haben wir einen Weg gefunden, einen Sicherheitsmechanismus durch Caching zu umgehen. Dadurch fanden wir einige Services, die wir missbrauchen konnten, um die Privilegien auf entfernten Servern zu erhöhen, ohne dass viele Bedingungen erfüllt sein mussten. (Darauf werden wir später in diesem Beitrag noch eingehen.) Im Moment können wir Ihnen Informationen über zwei reale Beispiele einer möglichen Ausnutzung geben, WksSvc und SrvSvc. Wir werden Updates zu den anderen gefundenen Sicherheitslücken veröffentlichen, sobald deren Offenlegungsprozess abgeschlossen ist.
In diesem Blogbeitrag konzentrieren wir uns auf den Sicherheitscallback-Mechanismus von RPC-Servern, wie er durch Caching umgangen werden kann und wie wir unsere Forschung automatisiert haben, um Windows-Services als potenziell anfällig zu kennzeichnen. Unsere Automatisierungstools sowie deren Rohdaten finden Sie auch in unserem RPC-Toolkitin unserem GitHub-Repository. Unser Repository enthält auch Links zu anderen nützlichen Referenzen und Arbeiten anderer Forscher, auf die wir uns bezogen haben.
Sicherheitscallbacks
Bevor wir uns die Schwachstellen selbst ansehen, müssen wir einen der grundlegendsten Sicherheitsmechanismen von MS-RPC beleuchten: Sicherheitscallbacks. Mit Sicherheitscallbacks können Entwickler von RPC-Servern den Zugriff auf eine RPC-Schnittstelle einschränken. So können sie ihre eigene Logik anwenden, um bestimmten Nutzern den Zugriff zu ermöglichen, Authentifizierung oder Transporttypen zu erzwingen oder den Zugriff auf bestimmte opnums zu verhindern (vom Server angebotene Funktionen werden durch opnums, d. h. Operationsnummern, dargestellt).
Dieser Callback wird von der RPC-Laufzeitumgebung immer dann ausgelöst, wenn der Client eine exponierte Funktion auf dem Server aufruft.
Bei unserer Untersuchung haben wir uns auf die Remote-Interaktion zwischen Client und Server konzentriert. Wir erwähnen dies, da sich die Implementierungen des serverseitigen RPC-Laufzeitcodes zwischen einem ALPC-Endpunkt und einem Remote-Endpunkt wie einer benannte Pipe unterscheiden.
Caching
Die RPC-Laufzeit implementiert die Zwischenspeicherung des Ergebnisses eines Sicherheitscallbacks für eine bessere Performance und Nutzung. Das bedeutet im Grunde, dass die Laufzeit versucht, einen zwischengespeicherten Eintrag zu verwenden, bevor sie den Sicherheitscallback jedes Mal aufruft. Sehen wir uns nun die Implementierung an.
Bevor RPC_INTERFACE::DoSyncSecurityCallback den Sicherheitscallback aufruft, wird geprüft, ob ein Cache-Eintrag vorhanden ist. Dazu wird OSF_SCALL::FindOrCreateCacheEntry aufgerufen.
OSF_SCALL::FindOrCreateCacheEntry führt die folgenden Operationen aus:
Es ruft den Sicherheitskontext des Clients aus dem SCALL ab (ein Objekt, das einen Client-Aufruf darstellt).
Es holt das Caching-Wörterbuch aus dem Sicherheitskontext des Clients.
Es verwendet den Schnittstellenzeiger als Schlüssel für das Wörterbuch. Der Wert ist der Cache-Eintrag.
Wenn kein Cache-Eintrag vorhanden ist, wird ein Cache-Eintrag erstellt.
Ein Cache-Eintrag hat drei wichtige Felder: die Anzahl der Prozeduren in der Schnittstelle, eine Bitmap und die Schnittstellengenerierung.
Während der Lebensdauer eines RPC-Servers kann die Schnittstelle geändert werden, z. B. wenn der Server RpcServerRegisterIf3 auf einer vorhandenen Schnittstelle aufruft. Dies wiederum ruft RPC_INTERFACE::UpdateRpcInterfaceInformation auf, wodurch die Schnittstelle aktualisiert und die Schnittstellengenerierung erhöht wird. Auf diese Weise weiß das Caching, dass es „zurückgesetzt“ werden muss, da die Cache-Einträge von der alten Schnittstelle stammen könnten.
Der Caching-Mechanismus kann auf zwei Arten funktionieren: auf Schnittstellenbasis (das ist das Standardverhalten) und auf Basis von Aufrufen.
Caching auf Schnittstellenbasis
In diesem Modus arbeitet das Caching auf Schnittstellenbasis. Das bedeutet, aus Sicht des Caching gibt es keinen Unterschied zwischen zwei Aufrufen von zwei verschiedenen Funktionen, solange sie auf derselben Schnittstelle sind.
Um herauszufinden, ob der Cache-Eintrag verwendet werden kann, anstatt den Sicherheitscallback aufzurufen, vergleicht die RPC-Laufzeit die Schnittstellengenerierung, die im Cache-Eintrag gespeichert ist, mit der tatsächlichen Schnittstellengenerierung. Da die Initialisierung des Cache-Eintrags die Schnittstellengenerierung auf Null setzt, werden die Schnittstellengenerationen beim ersten Vergleich unterschiedlich sein, weshalb der Sicherheitscallback aufgerufen wird. Wenn der Callback erfolgreich zurückgegeben wird, aktualisiert die RPC-Laufzeit die Schnittstellengenerierung des Cache-Eintrags. (Er wird als erfolgreicher Cache-Eintrag gekennzeichnet, der den Zugriff auf die Schnittstelle ohne erneuten Aufruf des Sicherheitscallbacks ermöglicht.) Wenn der Client das nächste Mal eine Funktion auf derselben Schnittstelle aufruft, wird der Cache-Eintrag verwendet.
Caching auf Basis von Aufrufen
Dieser Modus wird verwendet, wenn die RPC-Schnittstelle mit dem Flag RPC_IF_SEC_CACHE_PER_PROC registriert wird. In diesem Modus basiert das Caching auf einer Bitmap, die nachverfolgt, auf welche Prozeduren der Sicherheitscallback Zugriff gewährt hat. Wenn der Client die Funktion Foo aufgerufen hat und der Sicherheitscallback erfolgreich zurückgegeben wurde, haben wir also einen Cache-Eintrag für Foo. Wenn der Client Bar aufruft, wird der Securitycallback erneut aufgerufen.
Caching-Anforderungen
Was brauchen wir also, damit das Caching funktioniert? Zunächst müssen wir einige Begriffe klären. MS-RPC stellt eine logische Verbindung zwischen einem Client und einem Server über ein Bindungshandle dar. Client und Server können die Bindungsdaten mit speziellen Funktionen bearbeiten.
Eine Bindung kann authentifiziert werden. Dies geschieht, wenn der Server Authentifizierungsinformationen registriert (indem er RpcServerRegisterAuthInfo) aufruft. Dann legt der Client Authentifizierungsinformationen für die Bindung fest. Somit kann der Server Informationen über die Identität des Clients abrufen. Die Ausgabe dieses Authentifizierungsprozesses ist ein für den Client erstelltes Sicherheitskontextobjekt.
Der gesamte Caching-Mechanismus basiert auf diesem Sicherheitskontext. Wenn die Bindung nicht authentifiziert ist, wird somit kein Sicherheitskontext für den Client erstellt und das Caching nicht aktiviert. Damit das Caching funktioniert, müssen sich sowohl der Server als auch der Client registrieren und Authentifizierungsdaten festlegen.
Was aber, wenn der Server keine Authentifizierungsinformationen registriert hat? Kann das Caching trotzdem aktiviert werden? Wir stellen vor: Multiplexing.
Multiplexing
Bis Windows 10, Version 1703, konnte ein Service denselben svchost-Prozess mit anderen Services teilen. Dieses Verhalten wirkt sich auf die MS-RPC-Sicherheit aus, da einige RPC-Laufzeitobjekte von allen Schnittstellen gemeinsam genutzt werden. Bei der Registrierung eines Endpunkts (z. B. TCP-Port 7777) kann dieser beispielsweise für den Zugriff auf alle Schnittstellen verwendet werden, die unter demselben Prozess ausgeführt werden. Daher kann jetzt auch remote auf andere Services zugegriffen werden, die eigentlich lokal zugänglich sein sollten. Das wird von Microsoft auch auf dieser Seite beschrieben.
Obwohl die Tatsache, dass Endpunkte gemultiplext werden, bereits einigermaßen bekannt und dokumentiert ist, möchten wir ein weiteres ähnliches Verhalten vorstellen – SSPI-Multiplexing. Als Teil der Registrierung von Authentifizierungsinformationen muss der Server den zu verwendenden Authentifizierungsservice angeben. Der Authentifizierungsservice ist ein Security Support Provider (SSP), ein Paket, das die vom Client empfangenen Authentifizierungsinformationen verarbeitet. In den meisten Fällen handelt es sich um NTLM SSP, Kerberos SSP oder Microsoft Negotiate SSP, das die beste verfügbare Option, entweder Kerberos oder NTLM, auswählt.
Die RPC-Laufzeit speichert die Authentifizierungsinformationen global. Das bedeutet, wenn zwei RPC-Server sich denselben Prozess teilen und einer von ihnen Authentifizierungsinformationen registriert, verfügt der andere Server ebenfalls über Authentifizierungsinformationen. Ein Client kann nun die Bindung authentifizieren, wenn auf jeden der Server zugegriffen wird. Server, die keine Authentifizierungsinformationen registriert haben und daher möglicherweise nicht erwarten, dass Clients die Bindung authentifizieren oder dass ein Caching stattfindet, können dies aus Sicherheitsgründen erzwingen.
CVE-2022-38045 – srvsvc
Gewappnet mit unserem neuen Wissen über RPC-Sicherheitscallbacks und Zwischenspeicherung wollen wir nun herausfinden, ob wir den Mechanismus in der Praxis missbrauchen können. Wir kehrten zu srvsvc zurück, wo wir bereits in der Vergangenheit eine „Off-by-One“-Schwachstelle gefunden haben.
Srvsvc exponiert die MS-SRVS Schnittstelle. Der Server-Service (auch LanmanServer genannt) ist ein Windows-Service, der für die Verwaltung von SMB-Freigaben verantwortlich ist. Freigaben sind Ressourcen – Dateien, Drucker und Verzeichnisbäume –, die über das Netzwerk von einem Common Internet File System-Server (CIFS) zugänglich gemacht werden. Im Wesentlichen ermöglichen es Netzwerkfreigaben Nutzern, andere Geräte im Netzwerk zu verwenden, um verschiedene alltägliche Aufgaben auszuführen.
Als wir uns den Sicherheitscallback von Srvsvc anschauten, bemerkten wir, dass die Funktion eine andere Schwachstelle haben könnte, die sich von der bereits gefundenen unterscheidet. Sehen wir uns nun die Logik des Sicherheitscallbacks an:
Wie oben gezeigt, nutzt der srvsvc-Sicherheitscallback die folgende Logik:
Wenn ein Remoteclient versucht, auf eine Funktion im Bereich von 64 bis 73 (einschließlich) zuzugreifen, wird der Zugriff verweigert.
Wenn ein Remoteclient, bei dem es sich nicht um ein Clusterkonto handelt, versucht, auf eine Funktion im Bereich von 58 bis 63 (einschließlich) zuzugreifen, wird der Zugriff verweigert.
Im Wesentlichen werden also Remoteclients daran gehindert, auf diese speziellen Funktionen der Oberfläche zuzugreifen. Diese Bereichsprüfung weist darauf hin, dass die eingeschränkten Funktionen empfindlich sind und nur von erwarteten (lokalen) Prozessen aufgerufen werden sollten.
Obwohl diese Prüfung versucht, den Remotezugriff auf diese Funktionen zu verhindern, kann ein Angreifer diese über das Netzwerk umgehen, indem er das Caching missbraucht. Zunächst ruft er über das Netzwerk eine Funktion auf, die sich nicht in diesem Bereich befindet, sondern remote verfügbar ist. Da die Funktion Sicherheitscallback RPC_S_OK zurückgibt, wird die RPC-Laufzeit das Ergebnis als erfolgreich zwischenspeichern. Und da die Schnittstelle nicht mit dem Flag RPC_IF_SEC_CACHE_PER_PROC registriert ist, erfolgt das Caching auf Schnittstellenbasis. Wenn der Angreifer dann beim nächsten Mal eine beliebige Funktion auf derselben Schnittstelle aufruft, wird der Cache-Eintrag verwendet und der Zugriff gewährt. Das bedeutet, dass der Angreifer nun die lokalen Funktionen aufrufen kann, auf die er keinen Zugriff haben sollte, denn der Sicherheitscallback wird überhaupt nicht aufgerufen.
Srvsvc registriert keine Authentifizierungsinformationen, weshalb Clients unter normalen Umständen die Bindung nicht authentifizieren können und daher das Zwischenspeichern nicht aktiviert ist. Wie sich herausstellt, teilt Srvsvc den gleichen svchost-Prozess mit anderen Services, wenn der Servercomputer weniger als 3,5 GB RAM-Speicher hat. Die Services „AD Harvest Sites and Subnets Service“ und „Remote Desktop Configuration Service“ registrieren Authentifizierungsinformationen, weshalb srvsvc jetzt für Cache-Angriffe anfällig ist.
In diesem speziellen Szenario kann ein Angreifer mit den opnums 58–74 auf eingeschränkte Funktionen zugreifen. Mit diesen Funktionen kann ein Angreifer unter anderem die Authentifizierung des Remote-Computers erzwingen.
Auf Schatzsuche gehen
Nachdem wir verstanden hatten, dass der Missbrauch des Caching-Mechanismus des Sicherheitscallbacks zu tatsächlichen Schwachstellen führen kann, haben wir uns entschlossen, andere Schnittstellen zu finden, die anfällig für einen Caching-Angriff sein könnten. Aber alle Schnittstellen manuell zu finden, wäre eine lange und mühsame Aufgabe, weshalb wir eine Möglichkeit finden wollten, sie zu automatisieren.
Bei der Suche nach RPC-Schnittstellen können wir zwei Ansätze nutzen: aktuell laufende Prozesse oder das Dateisystem.
Bei laufenden Prozessen können wir uns bereits im Arbeitsspeicher geladene RPC-Server ansehen, entweder auf einem Remote-Server, indem wir den Remote-Endpunkt-Mapper abfragen (mit Impackets rpcmap oder rpcdump zum Beispiel) oder lokal (mit Tools wie RPcView oder RpcEnum). Allerdings gibt es ein Problem mit diesem Ansatz: Uns entgehen alle derzeit nicht geladenen Schnittstellen und wir sind nicht in der Lage, nicht registrierte Client-Schnittstellen zu betrachten.
Alternativ können wir das Windows-Dateisystem auswerten und nach RPC-Schnittstellen suchen, die darin kompiliert sind. Für jede Schnittstelle analysieren wir ihre Registrierungsinformationen, indem wir die an RpcServerRegisterIfübergebenen Argumente analysieren. Dies ist ein ähnlicher Ansatz wie in RpcEnum, aber wir werten das Dateisystem anstelle des Speichers aus.
Für unsere Untersuchung haben wir uns für die Dateisystemmethode entschieden, um Schnittstellen einzuschließen, die nicht zwingend in den Speicher geladen wurden. Wir haben verschiedene Skripte und Tools zur Automatisierung des Prozesses verfasst, die in unserem RPC-Toolkit-Repositoryverfügbar sind.
Um Schnittstellen mit aktiviertem Caching zu finden, müssen wir nicht unbedingt die RPC-Schnittstelle selbst analysieren. Alle erforderlichen Informationen können aus dem RPC-Server-Registrierungsaufruf extrahiert werden. Die Registrierungsfunktion akzeptiert die RPC-Schnittstellenstruktur, Registrierungsflags und den Sicherheitscallback-Zeiger. Dennoch kann das Parsen der RPC-Schnittstellenstruktur nützliche Informationen liefern, wie die von der Schnittstelle freigelegten Funktionen oder ob sie von einem RPC-Server oder -Client verwendet wird. Obwohl wir hauptsächlich an RPC-Servern interessiert sind (wo eine Schwachstelle vorhanden sein könnte), bieten RPC-Clients gute Einblicke in den Serveraufruf, auf den wir uns für eine Ausnutzung beziehen können.
Die Struktur der RPC-Server-Schnittstelle ist dokumentiert, sodass wir die Felder kennen. Außerdem sind das Größenfeld und die Transfersyntax konstant (es gibt eigentlich zwei mögliche Transfersyntax, DCE NDR und NDR64, aber wir sind bisher nur auf DCE NDR gestoßen).
Es ist einfache, alle RPC-Schnittstellenstrukturen zu finden, indem man nach diesen beiden Konstanten sucht (mit Yara oder regulären Ausdrücken). Sobald sie gefunden wurden, können wir das Interpreter-Informationfeld verwenden, um zu sehen, welche Funktionen der Server implementiert.
Aber uns fehlen noch immer Informationen über den Sicherheitscallback der Schnittstelle (falls vorhanden) und ob er zwischengespeichert ist. Dafür müssen wir uns an die Disassemblers wenden. Jeder gute Disassembler wird eine xref-Funktionalität haben, so dass es ein Leichtes ist, alle Aufrufe der Schnittstellenregistrierungsfunktion in einem RPC-Server zu finden. Von dort aus müssen wir nur die Funktionsaufrufargumente analysieren, um die Adresse der Schnittstellenstruktur zu extrahieren (damit wir diese mit unseren ausgewerteten RPC-Serverdaten überarbeiten können), ebenso wie die Sicherheitscallbackadresse (falls vorhanden) und die RPC-Schnittstellenflags.
Wir haben unsere Scraping-Skripte veröffentlicht, die genau das tun; sie sind in unserem RPC-Toolkit zusammen mit ihrer Ausgabe von Windows Server 2012 und Server 2022 verfügbar.
CVEs oder es ist nicht passiert
All diese Methoden und Theorien sind ganz gut, aber liefern sie tatsächlich Ergebnisse?
Die Antwort darauf ist ja. Es gibt mehr als 120 Schnittstellen mit Sicherheitscallback und Caching, von denen viele undokumentiert sind. Dies allein ist kein Grund zur Panik, da der Sicherheitscallback in den meisten Fällen durch das Caching nicht viel beeinflusst wird. In der Regel werden die durch den Sicherheitscallback durchgeführten Prüfungen an Werten durchgeführt, die nicht cachefähig sind, wie z. B. die Transportsequenz (z. B. TCP) oder die Authentifizierungsebene. Jede Änderung dort erfordert ohnehin einen neuen Sicherheitskontext, da eine neue Verbindung aufgebaut werden muss, die den Cache zurücksetzt und jeden möglichen Caching-Bypass annulliert.
Durch diesen Forschungsansatz haben wir einige Schwachstellen gefunden. Wir können derzeit nur über eine sprechen, da sich der Rest noch im Offenlegungsprozess befindet.
WksSvc
CVE-2022-38034 CVSS-Score: 4,3
WksSvc legt die MS-WKST Schnittstelle offen. Der Service ist für die Verwaltung von Domainmitgliedschaften, Computernamen und Verbindungen zu SMB-Netzwerk-Redirectors wie SMB-Druckerserver verantwortlich. Mit Blick auf den Sicherheitscallback der Schnittstelle können wir sehen, dass einige Funktionen anders behandelt werden als andere.
Funktionen, deren opnum zwischen 8-11 liegt, werden ebenfalls dahingehend überprüft, ob sie von einem lokalen Client aufgerufen werden können, was bedeutet, dass ein Remote-Aufruf nicht zulässig ist. Was würde jedoch aufgrund von Caching passieren, wenn wir zuerst eine andere Funktion aufrufen, die remote zulässig ist, und dann eine der eingeschränkten Funktionen aufrufen?
Sie haben es erraten: Wir wären in der Lage, die lokal eingeschränkten Funktionen aufgrund des Cachings des ersten Aufrufergebnisses remote aufzurufen. Die Frage lautet nun: Sind diese Funktionen wichtig genug, dass eine Beschränkung auf lokale Clients gerechtfertigt ist?
Die exponierten Funktionen sind NetrUseAdd, NetrUseGetInfo, NetrUseDelund NetrUseEnum. Wenn sie Ihnen bekannt vorkommen, liegt es daran, dass sie über netapi32.dll zugänglich sind (siehe beispielsweise NetUseAdd).
Das ist gut, denn es gibt uns einen Hinweis darauf, was wir mit diesem Angriff tun können. Wir können nämlich den Remote-Server mit einem freigegebenen Netzwerkordner unserer Wahl verbinden und ihn sogar einem logischen Laufwerksbuchstaben unserer Wahl zuordnen, ähnlich wie bei der Netznutzung. (Ein Zufall? Wahrscheinlich nicht.)
Dies gibt uns zwei Angriffsszenarien:
1. Wir können eine Authentifizierung in unserem freigegebenen Ordner verlangen; wir können ihn dann entweder an einen anderen Server für einen NTLM-Relay-Angriff weiterleiten oder die Token speichern und das Passwort offline knacken.
2. Oder wir können einen vorhandenen Fileserver mit interessanten oder nützlichen Dateien vortäuschen (oder so tun, als wäre er ein neuer). Da diese Dateien unter unserer Kontrolle sind, können wir sie nach Belieben „bewaffnen“, was uns hoffentlich erlaubt, den Zielnutzer zu infizieren.
Diese beiden Szenarien und die Möglichkeit, lokal eingeschränkte Funktionen remote aufrufen zu können, reichten für Microsoft aus, diese Sicherheitsanfälligkeit mit einem Score von 4,3 als EOP zu kategorisieren.
Das ist aber noch nicht das Ende der Geschichte. Wir haben noch ein paar Vorbehalte, die wir überwinden müssen.
Sicherheitskontext
Der RPC-Server unter WksSvc führt von sich aus keine Authentifizierungsregistrierung durch. Wenn der Service eigenständig ausgeführt wird, ist keine clientseitige Authentifizierung möglich (dies führt zu dem Fehler RPC_S_UNKNOWN_AUTHN_SERVICE). Daher müssen wir den Service mit anderen Services betreiben, um auch SSPI-Multiplexingauszunutzen. Dies schränkt unsere betroffenen Windows-Versionen auf jene vor Windows 10, Version 1703oder auf neuere Versionen ein, die mit weniger als 3,5 GB RAM ausgeführt werden.
Anmeldesitzungen
Ein weiteres Problem, das in die Funktionsweise von Netzwerkordnern integriert ist, besteht darin, dass sie auf die Anmeldesitzung des Nutzers beschränkt sind, der sie erstellt hat. Da wir uns zuerst anmelden müssen, um Sicherheitsbindung und Caching zu erhalten, müssen wir immer eine andere Anmeldesitzung erstellen als die vorhandene (interaktive) Sitzung auf dem Zielcomputer. Im Grunde genommen bedeutet dies, dass unsere Schwachstelle keine Auswirkungen hat. Das Netzwerk-Mapping, das wir erstellen, befindet sich unter unserer kurzlebigen Anmeldesitzung und nicht unter der, die ein normaler Nutzer erstellt, wenn er sich auf dem Rechner anmeldet, so dass sie nicht sichtbar sein wird.
Um das zu überwinden, mussten wir uns ein wenig tiefer in den Code von NetrUseAddeinarbeiten. Wie sich herausstellt, gibt es Flags, die wir NetrUseAdd übergeben können und die es anweisen, die Zuordnung im globalen Namespace zu erstellen, was alle Nutzer betrifft. Diese Flags befinden sich sogar in der verfügbaren Header-Datei LMUse.h:
Bewaffnet mit diesen Flags erstellt unser Code nun erfolgreich ein globales Mapping, das sich auf die interaktive Sitzung auswirkt und unseren Versuch der Ausnutzung beendet.
Zusammenfassung
MS-RPC ist ein großes und komplexes Protokoll. Es dient auch einigen der Kernfunktionen von Windows. Obwohl es über Sicherheitsfunktionen verfügt, mit denen Entwickler ihre RPC-Server absichern können, ist es ein interessantes Thema für Sicherheitsforscher, gerade weil es eine Schwachstelle enthält, die Auswirkungen auf die Sicherheit haben kann.
Trotzdem wurde zu diesem Thema kaum öffentliche Forschung betrieben. In diesem Blogbeitrag haben wir einen großen Sicherheitsmechanismus in MS-RPC unter die Lupe genommen – die Sicherheitscallbacks – und eine Umgehung in Form des Cachings von Callback-Ergebnissen gefunden. Außerdem haben wir unsere Forschungsmethoden zum Auffinden anfälliger RPC-Server detailliert dargelegt und einige unserer Ergebnisse mit Schwachstellenbeschreibungen demonstriert.
Wir hoffen, dass dieser Beitrag und das begleitende RPC-Toolkit-Repository zur Erforschung von RPC-Servern und Sicherheitsmechanismen von Nutzen ist.