GhostEmperor: Ein tiefer Einblick in hochentwickelte Cyberangriffe – Was die “securelist kaspersky” enthüllt

Verschlüsselter PowerShell-Code, der zur Laufzeit basierend auf einem vom Angreifer bereitgestellten AES-Schlüssel entschlüsselt wird

Die digitale Welt entwickelt sich ständig weiter, und mit ihr auch die Raffinesse von Cyberbedrohungen. Im Bereich der Cybersicherheit ist es entscheidend, auf dem neuesten Stand zu bleiben, um sich effektiv schützen zu können. Die “Securelist Kaspersky” hat wiederholt Einblicke in komplexe Bedrohungslandschaften gegeben, und ein besonders aufschlussreicher Bericht beleuchtete die Operationen der Gruppe “GhostEmperor”. Diese Gruppe, bekannt für ihre hochentwickelten Angriffe, nutzte ein Arsenal an ausgeklügelten Techniken, um ihre Ziele zu erreichen. Dieser Artikel taucht tief in die technischen Details ein, die von Kaspersky durch die “securelist kaspersky” aufgedeckt wurden, und beleuchtet die Taktiken, die GhostEmperor so gefährlich machten.

Die Entstehung von GhostEmperor: Ein Überblick über die Bedrohung

Bei der Untersuchung einer Zunahme von Angriffen auf Exchange-Server bemerkte ein wiederkehrendes Muster von Aktivitäten, das sich in mehreren kompromittierten Netzwerken abzeichnete. Dieses Muster zeichnete sich durch die Verwendung eines bisher unbekannten Windows Kernel-Mode Rootkits namens Demodex aus, gepaart mit einem ausgeklügelten, mehrstufigen Malware-Framework zur Fernsteuerung der angegriffenen Server. Das Rootkit diente dazu, Artefakte der User-Mode-Malware vor Ermittlern und Sicherheitslösungen zu verbergen. Bemerkenswert war dabei die Verwendung einer undokumentierten Lademethode, die auf die Kernel-Mode-Komponente eines Open-Source-Projekts namens Cheat Engine zurückgriff, um die Windows Driver Signature Enforcement zu umgehen.

Unsere Analysen, dokumentiert in der “securelist kaspersky”, zeigten, dass dieses Toolset bereits ab Juli 2020 im Einsatz war. Die Angreifer konzentrierten sich überwiegend auf Ziele in Südostasien, mit vereinzelten Ausnahmen in Ägypten, Afghanistan und Äthiopien. Zu den Opfern zählten mehrere Regierungsstellen und Telekommunikationsunternehmen. Angesichts des langjährigen Betriebs, der hochkarätigen Opfer, des fortschrittlichen Toolsets und der Tatsache, dass keine bekannte Bedrohungsgruppe dahintersteckte, entschieden wir uns, diese Aktivität als “GhostEmperor” zu klassifizieren. Unsere Untersuchung deutet darauf hin, dass die dahinterstehende Akteurin bzw. die Akteure hochqualifiziert und versiert sind, was sich in der breiten Palette ungewöhnlicher und raffinierter Anti-Forensik- und Anti-Analyse-Techniken widerspiegelt.

Die anfängliche Infektionskette: Wie Opfer kompromittiert wurden

Wir identifizierten mehrere Angriffsvektoren, die eine Infektionskette auslösten, die zur Ausführung von Malware im Arbeitsspeicher führte. Die Mehrheit der GhostEmperor-Infektionen wurde auf öffentlich zugänglichen Servern bereitgestellt. Dies deutet darauf hin, dass die Angreifer wahrscheinlich Schwachstellen in den auf diesen Systemen laufenden Webanwendungen ausnutzten, um ihre Dateien abzulegen und auszuführen. Auffällig war, dass viele der bösartigen Artefakte vom Apache-Server-Prozess httpd.exe, dem IIS-Prozess w3wp.exe oder dem Oracle-Server-Prozess oc4j.jar installiert wurden.

Es ist erwähnenswert, dass eine der GhostEmperor-Infektionen einen Exchange-Server betraf und am 4. März 2021 stattfand – nur zwei Tage nach der Veröffentlichung des Patches für die ProxyLogon-Schwachstelle durch Microsoft. Es ist daher denkbar, dass die Angreifer diese Schwachstelle ausnutzten, um die Ausführung von Remote-Code auf anfälligen Exchange-Servern zu ermöglichen.

Obwohl die Infektionen von GhostEmperor oft mit einer BAT-Datei beginnen, wurde die bekannte Infektionskette in einigen Fällen von einer früheren Phase eingeleitet: einer bösartigen DLL, die von wdichost.exe, einem legitimen Befehlszeilen-Dienstprogramm von Microsoft (ursprünglich MpCmdRun.exe genannt), “side-loaded” wurde. Die “side-loaded” DLL dekodierte und lud dann eine zusätzliche ausführbare Datei namens license.rtf. Leider konnten wir diese ausführbare Datei nicht wiederherstellen, aber wir beobachteten, dass die nachfolgenden Aktionen des Ladens die Erstellung und Ausführung von GhostEmperor-Skripten durch wdichost.exe umfassten.

Zuletzt wurden einige der Demodex-Bereitstellungen remote von einem anderen System im Netzwerk aus mithilfe legitimer Tools wie WMI oder PsExec durchgeführt, was darauf hindeutet, dass die Angreifer Teile der Opfernetzwerke bereits im Vorfeld infiziert hatten.

Die Rolle von kaspersky und putin im Kontext der Sicherheitslandschaft

Obwohl der vorliegende Bericht nicht direkt auf die Verbindungen zwischen Kaspersky und politischen Akteuren wie Putin eingeht, ist es wichtig zu verstehen, dass Cybersicherheitsunternehmen wie Kaspersky eine entscheidende Rolle in der globalen Sicherheitslandschaft spielen. Ihre Forschungen, die oft in der “securelist kaspersky” veröffentlicht werden, helfen Regierungen und Unternehmen weltweit, Bedrohungen zu verstehen und sich davor zu schützen. Die Art und Weise, wie diese Informationen aufbereitet und zugänglich gemacht werden, ist von zentraler Bedeutung für die allgemeine Cybersicherheit.

Übersicht der Infektionskette: Eine mehrstufige Operation

Die Infektion lässt sich in mehrere Phasen unterteilen, die nacheinander ablaufen, um ein In-Memory-Implantat zu aktivieren und die Bereitstellung zusätzlicher Payloads zur Laufzeit zu ermöglichen.

Phase 1: Der PowerShell-Dropper

Der Infektionsfluss beginnt mit einem PowerShell-Dropper. Dieses Komponente dient dazu, das nachfolgende Element in der Kette als Dienst zu installieren. Zuvor erstellt es einige Registrierungsschlüssel, denen verschlüsselte Daten zugewiesen werden, von denen einer einer Payload entspricht, die in späteren Phasen bereitgestellt wird. Es ist erwähnenswert, dass das Skript selbst in einer gepackten Form geliefert wird, wobei seine vollständige Ausführung von einem Kommandozeilenargument abhängt, das als Schlüssel zur Entschlüsselung des Großteils seiner Logik und Daten dient. Ohne diesen Schlüssel ist es unmöglich, den nachfolgenden Ablauf wiederherzustellen.

Verschlüsselter PowerShell-Code, der zur Laufzeit basierend auf einem vom Angreifer bereitgestellten AES-Schlüssel entschlüsselt wirdVerschlüsselter PowerShell-Code, der zur Laufzeit basierend auf einem vom Angreifer bereitgestellten AES-Schlüssel entschlüsselt wird

Phase 2: Der Vorläufer-Dienst

Die nächste Phase, die als Dienst ausgeführt wird, dient als weiterer Vorläufer für die nachfolgenden Phasen. Sie wird verwendet, um die verschlüsselten Daten aus den zuvor geschriebenen Registrierungsschlüsseln zu lesen und zu entschlüsseln, um die Ausführung eines In-Memory-Implantats zu initiieren. Wir identifizierten zwei Varianten dieser Komponente: eine in C++ und eine in .NET. Letztere, die bereits im März 2021 auftauchte, verwendet die GUID des infizierten Rechners zur Ableitung des Entschlüsselungsschlüssels und ist somit auf dieses spezifische System zugeschnitten. Die C++-Variante hingegen verwendet fest codierte AES-256-Verschlüsselungsschlüssel.

Phase 3: Das Kern-Implantat und die C2-Kommunikation

Die dritte Phase ist das Kern-Implantat, das nach der Bereitstellung durch den oben genannten Lader im Arbeitsspeicher operiert und in den Adressraum eines neu erstellten svchost.exe-Prozesses injiziert wird. Sein Hauptziel ist es, einen Kommunikationskanal mit einem C2-Server (Command and Control) zu ermöglichen, wobei bösartiger Datenverkehr unter dem Deckmantel der Kommunikation mit einem gutartigen Dienst getarnt wird, basierend auf einem eingebetteten Malleable C2-Profil in seiner Konfiguration. Es ist wichtig zu beachten, dass die Implementierung der Malleable C2-Funktion, die ursprünglich im Cobalt Strike-Framework enthalten ist, angepasst und höchstwahrscheinlich basierend auf Reverse Engineering von Cobalt Strike-Code neu geschrieben wurde.

Eine weitere interessante Technik zur Verschleierung des bösartigen Datenverkehrs ist die Verwendung von gefälschten Dateiformat-Headern durch die Malware, um die an den C&C-Server übermittelten Daten zu kapseln. Zu diesem Zweck synthetisiert das In-Memory-Implantat eine gefälschte Mediendatei in einem der Formate RIFF, JPEG oder PNG und platziert darin verschlüsselte Daten als Body. Somit erscheint das übertragene Paket als Bild- oder Audiodatei und fügt sich in den übrigen legitimen Datenverkehr im Netzwerk ein.

Phase 4: Die Remote-Control-Payload

Die letzte Phase ist die Payload, die vom oben genannten Implantat in den winlogon.exe-Prozess injiziert wird und den Angreifern Remote-Control-Fähigkeiten bietet. Zu diesen Fähigkeiten gehören die Initiierung einer Remote-Konsolen- oder Desktop-Sitzung, wobei letztere die Ausführung gesendeter Mausklicks und Tastatureingaben auf dem Zielrechner unterstützt und periodische Screenshots abruft, die die Ergebnisse dieser Aktionen widerspiegeln. Diese Phase kann es den Angreifern auch ermöglichen, beliebige .NET-Assemblies zu laden oder PowerShell-Befehle auszuführen, sowie die vollständige Kontrolle über das Dateisystem des Opfers zu erlangen, um Dateien zu suchen, abzurufen oder darauf zu pushen.

Weiterlesen >>  Adobe Photoshop 2022 v23.4.2.603 x64: Revolutionäre Bildbearbeitung für Kreative

Zusätzlich zur letzten Payload ist die Kernkomponente auch in der Lage, einen Windows Kernel-Mode-Treiber auf dem System bereitzustellen. Dieser Treiber dient als Rootkit, das Malware-Artefakte wie Dateien, Registrierungsschlüssel und Netzwerkverkehr verbirgt und somit unentdeckt bleiben kann und die Erkennung durch Sicherheitsprodukte und forensische Ermittler vermeidet. Die folgenden Abschnitte erläutern, wie dieser Treiber bereitgestellt wird (insbesondere wie er Windows-Schutzmaßnahmen umgeht, da er nicht digital signiert ist) und welche spezifischen Funktionen er dem User-Mode-Malware-Implantat bietet.

Übersicht der GhostEmperor InfektionsketteÜbersicht der GhostEmperor Infektionskette

Rootkit-Ladeanalyse: Umgehung der Sicherheitsmechanismen

Auf modernen 64-Bit-Windows-Betriebssystemen ist es aufgrund des von Microsoft eingeführten Driver Signature Enforcement-Mechanismus im Allgemeinen nicht möglich, einen unsignierten Treiber auf dokumentierte Weise zu laden. Aus diesem Grund haben Angreifer Schwachstellen in signierten Treibern ausgenutzt, um die Ausführung von unsigniertem Code im Kernel-Bereich zu ermöglichen. Ein typischer Ansatz, der bisher von vielen Akteuren verfolgt wurde und hauptsächlich in älteren Windows-Versionen zum Einsatz kam, besteht darin, den Code Integrity-Mechanismus zu deaktivieren, indem das nt!g_CiEnabled-Flag im Kernel-Modul CI.DLL umgeschaltet wird, nachdem Schreib- und Ausführungsrechte über anfällige signierte Treiber erlangt wurden. Nach dem Abschalten des Code Integrity-Mechanismus kann ein unsignierter Treiber geladen werden.

Dieser Ansatz wurde durch die Einführung von Kernel Patch Protection (auch PatchGuard genannt) von Microsoft eingeschränkt. Dieser Mechanismus schützt die Modifikation spezifischer Datenstrukturen im Speicherbereich des Windows-Kernels, einschließlich des nt!g_CiEnabled-Flags. Aus diesem Grund kann die Modifikation dieses Flags nun einen BSOD (Blue Screen of Death) verursachen. Dies kann dadurch umgangen werden, dass der Flag-Wert schnell gesetzt, ein unsignierter Treiber geladen und dann in seinen vorherigen Zustand zurückgeschaltet wird, bevor PatchGuard eine Änderung erkennt – dies birgt jedoch weiterhin ein Wettlaufproblem, das das System zum Absturz bringen kann.

Der von den Entwicklern dieses Rootkits verwendete Ansatz ermöglicht das Laden eines unsignierten Treibers, ohne das Code Integrity-Image zu modifizieren und sich mit einem potenziellen Absturz auseinanderzusetzen. Er nutzt die Funktionen eines legitimen und Open-Source-signierten Treibers namens dbk64.sys, der zusammen mit Cheat Engine ausgeliefert wird – einer Anwendung, die entwickelt wurde, um Schutzmechanismen von Videospielen zu umgehen und Cheats einzuführen. Dieser Treiber bietet von Haus aus die Möglichkeit, Code im Kernel-Bereich zu schreiben und auszuführen, wodurch beliebiger Code im Kernel-Modus ausgeführt werden kann.

Nachdem der dbk64.sys-Treiber unter einem zufällig generierten Dateinamen auf die Festplatte gelegt und geladen wurde, gibt die Malware dokumentierte IOCTLs (Input/Output Control) an den Treiber aus, die die Ausführung von Shellcode im Kernel-Bereich durch die folgende Aktionssequenz ermöglichen:

  1. IOCTL_CE_ALLOCATEMEM_NONPAGED: Ein Speicherpuffer wird im nicht-seitigen Pool des Kernel-Bereichs zugewiesen.
  2. IOCTL_CE_MAP_MEMORY: Der zugewiesene Speicherpuffer wird zwischen dem User-Mode-Malware-Prozess und dem Kernel-Adressraum geteilt, indem die Seiten des Puffers im physischen Speicher gesperrt werden und eine MDL (Memory Descriptor List) erstellt wird. Anschließend wird die Funktion MmMapLockedPagesSpecifyCache aufgerufen. Über einen Zeiger im User-Mode kann nun auf den Puffer zugegriffen und hineingeschrieben werden, wobei die Änderungen im Kernel-Bereich reflektiert werden. Dies wird zum Schreiben des Shellcodes in den Puffer genutzt.
  3. IOCTL_CE_UNMAP_MEMORY: Der Puffer wird aus dem User-Mode entkoppelt.
  4. IOCTL_CE_EXECUTE_CODE: Der geschriebene Shellcode kann nun im Kernel-Bereich ausgeführt werden.

Der Zweck des Shellcodes ist es, den IOCTL-Dispatcher von dbk64.sys durch einen alternativen zu ersetzen, der wiederum das Laden eines unsignierten Treibers ermöglicht. Der alternative Dispatcher ist ebenfalls als positionsunabhängiger Code implementiert und wird mit dem Shellcode gebündelt. Um den ursprünglichen Dispatcher zu ersetzen, ordnet der Shellcode den Code des neuen Dispatchers im Speicher zu und patchet den Zeiger auf die IRP_MJ_DEVICE_CONTROL-Routine im Treiberobjekt von dbk64.sys. An diesem Punkt wird der IRP_MJ_DEVICE_CONTROL-Zeiger auf die Adresse des neuen Dispatchers gesetzt, und jede an den Treiber ausgegebene IOCTL läuft durch diesen.

IRP_MJ_DEVICE_CONTROL HookingIRP_MJ_DEVICE_CONTROL Hooking

Der alternative Dispatcher bietet dieselben Kernfunktionen wie der ursprüngliche, mit zusätzlichen Möglichkeiten zum Laden eines neuen Treibers in den Kernel-Bereich. Diese Funktionalität wird über eine Reihe von IOCTL-Handlern bereitgestellt, die nacheinander aufgerufen werden und schließlich zum Laden des Kernel-Mode-Rootkits der Malware führen.

IOCTL-CodeBeschreibung
0x220180Verarbeitet einen vom User-Mode-Malware-Komponente bereitgestellten Puffer, indem er dessen Größe auf 272 Bytes prüft und dann durch Negation der Bytes dekodiert. Diese IOCTL wird tatsächlich nicht vom User-Mode-Code aufgerufen.
0x220184Weist einen Puffer im Kernel-Bereich zu, sperrt dessen Seiten, erstellt eine MDL und ordnet den Puffer einem User-Mode-Adresse über MmMapLockedPagesSpecifyCache zu. Dies entspricht im Wesentlichen der Verkettung von Funktionalitäten in IOCTL_CE_ALLOCATEMEM_NONPAGED und IOCTL_CE_MAP_MEMORY des ursprünglichen Dispatchers. Nach diesem Aufruf hat der User-Mode-Code Zugriff auf einen Kernel-Mode-Puffer und kann mittels eines Zeigers im User-Mode hineinschreiben, wie es beim Schreiben des Shellcodes der Fall war. Diesmal lädt die Malware das PE-Image des Rootkits manuell in den zugewiesenen Puffer.
0x2201B4Da der User-Mode-Code der Malware für das manuelle Laden des Rootkit-Images in IOCTL 0x220184 zuständig ist, muss er einige Funktionsadressen im Kernel-Bereich auflösen, die als Abhängigkeiten im Import Address Table (IAT) des Images erscheinen. Diese IOCTL ermöglicht es, die Funktionsnamen als Strings aus dem User-Mode zu empfangen, ihre Adressen über die MmGetSystemRoutineAddress-API abzurufen und sie an den User-Mode-Code zurückzugeben. Letzterer platziert die aufgelöste Adresse im entsprechenden IAT-Eintrag des geladenen Images.
0x220188Entkoppelt die Adresse des Kernel-Mode-Puffers aus dem User-Mode, sodass er nur über seinen Kernel-Mode-Zeiger zugänglich ist.
0x2201B8Erstellt ein neues Treiberobjekt mithilfe der Funktion IoCreateDriver und weist den Zeiger auf die Treiberinitialisierungsfunktion einer positionsunabhängigen Stub zu, die mit dem Shellcode geliefert wird und nach dem Aufruf die DriverEntry-Funktion des geladenen Rootkits aufruft.

Es ist erwähnenswert, dass der Dienst der Malware das Cheat Engine-Dienstprogramm kernelmoduleuloader.exe (MD5: 96F5312281777E9CC912D5B2D09E6132) beim Laden des dbk64.sys-Treibers verwendet. Der Treiber wird zusammen mit dem Dienstprogramm und einer .sig-Datei abgelegt. Letztere wird verwendet, um die Komponente zu authentifizieren, die dbk64.sys aufruft, indem sie eine digitale Signatur übermittelt, die mit ihrer Binärdatei verknüpft ist.

Da die Malware keine Komponente von Cheat Engine ist, führt sie kernelmoduleunloader.exe als neuen Prozess aus und injiziert ihn mit einem kleinen Shellcode, der lediglich über die CreateFileW-API ein Handle zum dbk64.sys-Gerät öffnet. Der Wert des Handles wird als zweites QWORD in den injizierten Puffer geschrieben, vom Prozess der Malware gelesen und über die DuplicateHandle-API dupliziert. Von diesem Zeitpunkt an kann der Dienst der Malware den Treiber aufrufen, als wäre er eine signierte Cheat Engine-Komponente.

Die Demodex-Rootkit-Funktionalität: Unsichtbarkeit und Tarnung

Das geladene Rootkit, das wir Demodex nannten, dient dazu, verschiedene Artefakte des Malware-Dienstes zu verbergen. Dies wird durch eine Reihe von IOCTLs erreicht, die vom Treiber des Rootkits bereitgestellt und von der User-Mode-Code des Dienstes aufgerufen werden, wobei jeder eine bestimmte bösartige Artefakt tarnen. Um auf die Funktionalität des Rootkits zugreifen zu können, muss die Malware ein Handle zum entsprechenden Geräteobjekt erhalten, wonach die folgenden IOCTLs für die weitere Nutzung zur Verfügung stehen:

  • 0x220204: Empfängt ein Argument mit der PID des svchost.exe-Prozesses, der den Code des bösartigen Dienstes ausführt, und speichert es in einer globalen Variablen. Diese Variable wird von anderen IOCTLs später verwendet.
  • 0x220224: Initialisiert globale Variablen, die später zur Speicherung von Daten wie der oben genannten svchost.exe-PID, dem Namen des Malware-Dienstes, dem Pfad zur Malware-DLL und einem Netzwerkport verwendet werden.
  • 0x220300: Verbirgt den Malware-Dienst in einer Liste im Adressraum des services.exe-Prozesses. Der Name des Dienstes wird als Argument an die IOCTL übergeben und dann in einer systemverwalteten verknüpften Liste gesucht. Der entsprechende Eintrag wird aus der Liste entfernt, wodurch der Dienst leicht zu erkennen ist. Die Logik in diesem Handler erinnert an die dort beschriebene Technik.
  • 0x220304: Diese IOCTL wird verwendet, um eine Benachrichtigungsroutine eines Dateisystemfiltertreibers mithilfe der IoRegisterFSRegistrationChange-API zu registrieren. Die Benachrichtigungsroutine, die bei der Registrierung eines neuen Dateisystems aufgerufen wird, prüft, ob es sich um ein NTFS-basiertes handelt. Wenn ja, wird ein Geräteobjekt für das Rootkit erstellt, das an den Geräte-Stack des betroffenen Dateisystems angehängt wird. Zusätzlich werden sowohl das Geräteobjekt des Dateisystems als auch das zugehörige Rootkit-Geräteobjekt in einer globalen Liste registriert, die vom Treiber des Rootkits verwaltet wird. Nachfolgende Versuche, Informationen aus einer Datei abzurufen, darauf zuzugreifen oder sie zu ändern, schlagen fehl und generieren Fehlercodes wie STATUS_NO_MORE_FILES oder STATUS_NO_SUCH_FILE.
  • 0x220308: Verbirgt TCP-Verbindungen, die Ports innerhalb eines bestimmten Bereichs verwenden, vor Dienstprogrammen wie netstat. Dies geschieht durch eine bekannte Methode, bei der die IOCTL-Dispatch-Routine des NSI-Proxy-Treibers gehookt wird und die Abschlussroutine so eingestellt wird, dass sie den Port einer bestimmten Verbindung inspiziert. Fällt der Port der zugrunde liegenden Verbindung in den angegebenen Bereich, wird sein Eintrag aus der TCP-Tabelle des Systems entfernt. Die beiden Ports, die den Bereich bilden, werden als Argumente an die IOCTL übergeben.
  • 0x22030C: Verbirgt Malware-bezogene Registrierungsschlüssel durch Hooking mehrerer Registrierungsoperationen über die CmRegisterCallback-API. Der registrierte Callback prüft die Art der Operation und handelt entsprechend der folgenden Logik:
    • Für Operationen vom Typ RegNtPostEnumerateKey oder RegNtPostEnumerateValueKey (Enumeration eines Schlüssels oder Unterschlüssels) wird geprüft, ob versucht wird, den treiberbezogenen Schlüssel unter HKLM\SYSTEM\ControlSet0**\Services\ zu enumerieren. Wenn ja, wird der Rückgabestatus der Operation auf STATUS_NO_MORE_ENTRIES gesetzt, um anzuzeigen, dass keine Daten für die angeforderte Enumeration vorliegen.
    • Für Operationen vom Typ RegNtPreOpenKeyEx (Versuch, einen Schlüssel zu öffnen) auf SOFTWARE\Microsoft\{EAAB20A7-9B68-4185-A447-7E4D21621943} werden alle globalen Variablen des Treibers gelöscht, was einer Zurücksetzung seiner Operation entspricht. Dies liegt daran, dass dieser Schlüssel vom PowerShell-Deinstallationsskript der Malware verwendet wird, das in früheren Abschnitten erwähnt wurde.
    • Bei jedem Versuch, einen Schlüssel unter HKLM\MACHINE\SYSTEM über eine Operation mit dem Code RegNtPreSaveKey oder niedriger zu ändern, wird der Rückgabestatus auf den Anwendungsfehler 0xC0000043 gesetzt.
Weiterlesen >>  Google als Standard-Suchmaschine im Edge-Browser: Eine detaillierte Anleitung

Interessanterweise enthält der an CmRegisterCallback übergebene Zeiger nicht die direkte Adresse der Funktion, die die obige Logik behandelt, sondern stattdessen eine Adresse am Ende des ausführbaren Abschnitts des pci.sys-Treiber-Images, der ursprünglich mit Nullen gefüllt ist, um den Abschnitt im Speicher auszurichten. Bevor der Callback-Zeiger an CmRegisterCallback übergeben wird, wird ein solcher Abschnitt im pci.sys-Treiber gesucht und die entsprechenden Bytes darin gepatcht, um den Aufruf des eigentlichen Callbacks, der die Logik zur Verschleierung der Registrierungsschlüssel der Malware behandelt, auszulösen. Dies ermöglicht, dass alle abgefangenen Registrierungsoperationen so erscheinen, als würden sie von Code behandelt, der vom legitimen pci.sys-Treiber stammt.

Beispiel für Code, der einen Abschnitt im pci.sys-Image im Speicher patchet, um ihn mit einem kurzen Shellcode-Stub zu überschreiben, der zu einem Registrierungsinspektions-Callback springtBeispiel für Code, der einen Abschnitt im pci.sys-Image im Speicher patchet, um ihn mit einem kurzen Shellcode-Stub zu überschreiben, der zu einem Registrierungsinspektions-Callback springt

Es ist erwähnenswert, dass das Demodex-Rootkit nativ Windows 10 unterstützt und gemäß unseren Tests auch auf Windows 10 Builds funktioniert. Dies zeigt sich an mehreren Stellen im Code des Treibers, wo unterschiedliche Code-Pfade basierend auf der Version des zugrunde liegenden Betriebssystems genommen werden. Bei solchen Prüfungen sind einige Pfade erkennbar, die den neuesten Windows 10-Builds entsprechen.

Obfuscation und Anti-Analyse-Methoden: Ein Kampf gegen Forensiker

Die Autoren der Malware-Komponenten, die in der GhostEmperor-Aktivität verwendet werden, haben einige Entwicklungsentscheidungen getroffen, die Auswirkungen auf den forensischen Analyseprozess haben. Um einige der Hürden aufzuzeigen, denen Ermittler gegenüberstehen, beschränken wir die Diskussion auf zwei gängige Analysetools: WinDbg und Volatility. Andere Tools können bei der Behandlung der fraglichen Implantate auf ähnliche Schwierigkeiten stoßen.

Erstens wird der Treiber von Demodex aufgrund der Art und Weise, wie er geladen wird, nicht ordnungsgemäß in WinDbg aufgeführt, zusammen mit anderen Systemmodulen, die auf dokumentierte Weise geladen werden. Dennoch ist es möglich, das Treiberobjekt des Rootkits anhand seines Namens (\driver\dump_audio_codec0) zu finden und somit auch seine zugehörigen Geräteobjekte aufzulisten.

In ähnlicher Weise ist der Demodex-Treiber bei dem Versuch, Systemmodule mit dem Volatility3-Modul windows.driverscan aufzulisten, in der Ausgabe abwesend. Das Framework weist jedoch darauf hin, dass beim Scannen des Kernel-Speicherbereichs nach dem Treiber eine Anomalie erkannt wird.

Darüber hinaus haben die Malware-Autoren bewusst alle PE-Header aus speicherresidenten Images sowohl in der dritten Phase der Malware als auch im Treiber des Rootkits entfernt. Dies geschieht entweder durch die Einführung des Images mit einem bereits auf Null gesetzten Header (wie in der dritten Phase) und durch Verlassen auf einen benutzerdefinierten Lader zur Vorbereitung der Ausführung, oder durch Ersetzen des Headers des Images nach dem Laden mit dem Wert 0x00, wie im Fall des Rootkit-Treibers. Aus forensischer Sicht behindert dies den Prozess der Identifizierung von PE-Images, die in den Speicher geladen wurden, indem nach ihren Headern gesucht wird.

Wie bereits erwähnt, implementierten die Entwickler einen “Trampolin” im legitimen pci.sys-Treiber, um die Quelle von Callbacks zu verschleiern, die für Registrierungsoperationen aufgerufen werden. Daher können Analysten, die versuchen, solche Callbacks zu verfolgen, diese übersehen, da sie wie gutartige Aufrufe erscheinen werden. Wie die WinDbg-Auflistung der Cm*-Callbacks zeigt, ist einer davon mit dem Symbol pci!ArbLibraryDeinitialize+0xa4 assoziiert; wenn wir jedoch den Code an derselben Adresse betrachten, sehen wir, dass es sich tatsächlich um ein kleines Stück Shellcode handelt, das vom Rootkit emittiert wurde, um zu dem eigentlichen bösartigen Callback zu springen, der die Registrierungsschlüssel der Malware verbirgt.

Zusätzlich zu den oben genannten Punkten haben die Entwickler weitere Standardmethoden der Obfuscation eingeführt, die typischerweise die statische Analyse des Codes verlangsamen und in mehreren Malware-Komponenten sichtbar sind. Ein Beispiel hierfür ist ein Muster der String-Obfuscation, bei dem jeder String mit einer Reihe vordefinierter arithmetischer und logischer Operationen dekodiert wird, wobei für jeden String unterschiedliche Operanden (z.B. Shift-Offsets) gewählt werden. Dies deutet darauf hin, dass jeder String während der Kompilierung obfuskiert wird und die Autoren eine Art SDK etabliert haben, das dabei hilft, jeden Sample während der Build-Zeit eindeutig zu obfuskieren.

In ähnlicher Weise können mehrere Instanzen der API-Aufruf-Obfuscation im Code beobachtet werden. Dies geschieht, indem Inline-Aufrufe von API-Funktionen durch andere Stub-Funktionen ersetzt werden, die den angeforderten API-Namen als Stack-String aufbauen, ihn mit GetProcAddress auflösen und ihn aufrufen, während die Argumente, die in einer speziellen Struktur bereitgestellt werden, an die Stub-Funktion übergeben werden. Die Struktur hat eine größere Größe als erforderlich, um die Argumentdaten zu übergeben, und der größte Teil davon ist mit Junk gefüllt, sodass nur bestimmte Felder aussagekräftige Daten enthalten, die vor der Übergabe an den Stub kodiert werden. Diese Felder werden innerhalb der Stub-Funktion dekodiert und wiederum an die API-Funktion übergeben.

Beispiel eines Stubs für API-Aufruf-ObfuscationBeispiel eines Stubs für API-Aufruf-Obfuscation

Es ist erwähnenswert, dass, ähnlich wie bei der String-Obfuscation, jeder Stub eindeutig aufgebaut ist und eine Argumentstruktur mit unterschiedlicher Größe verwendet, wobei die Felder, die mit tatsächlichen Argumentdaten belegt sind, zufällig ausgewählt werden. Auch die Reihenfolge, in der der Stack-String initialisiert wird, ist zufällig, und jede Stub-Funktion wird nur einmal als Ersatz für einen einzelnen Inline-API-Funktionsaufruf verwendet. Mit anderen Worten, dieselbe API-Funktion, die an verschiedenen Stellen im Code verwendet wird, hat unterschiedliche Stubs für jeden Ort mit unterschiedlichen Argumentstrukturen. Dies verstärkt die Beobachtung, dass die Autoren ein bestimmtes Obfuscation-SDK verwendeten, in dem die API-Aufruf-Obfuscation eine weitere Funktion darstellt.

Weiterlesen >>  Chromebooks & Photoshop: Neue Kreativmöglichkeiten für digitale Nomaden

Schließlich ist es möglich zu sehen, dass einige Varianten sowohl in obfuskierten als auch in nicht-obfuskierten Formen erschienen sind. Wir konnten beispielsweise die C++-Version des Laders der zweiten Stufe in zwei Formen sehen – eine Form ohne jegliche Obfuscation und eine weitere, die stark obfuskiert ist (MD5: 18BE25AB5592329858965BEDFCC105AF). In der folgenden Abbildung können wir dieselbe Funktion in den beiden Varianten sehen: eine hat den ursprünglichen Codefluss, wie er von einem Compiler ohne Obfuscation erzeugt wurde, während die andere seinen Kontrollfluss so stark abgeflacht hat, dass die Reihenfolge der Aktionen nicht mehr nachvollziehbar ist.

Post-Exploitation-Toolset: Die Werkzeuge der Angreifer

Nachdem die Angreifer über die beschriebene Infektionskette Zugriff auf die kompromittierten Systeme erlangt haben, verwenden sie eine Mischung aus legitimen und Open-Source-Offensiv-Toolsets, um Benutzeranmeldeinformationen zu ernten und sich auf andere Systeme im Netzwerk zu verteilen. Dazu gehören gängige Dienstprogramme aus der Sysinternals-Suite zur Prozesskontrolle (z. B. PsExec, PsList und ProcDump) sowie andere Tools wie WinRAR, CertUtil und BITSAdmin. Bei den Open-Source-Tools setzten die Angreifer Tools wie mimkat_ssp, Get-PassHashes.ps1, Token.exe und Ladon ein. Die Erkundung und Kommunikation im internen Netzwerk erfolgte häufig über NBTscan und Powercat.

Eine umfassendere Übersicht dieser Tools zusammen mit den tatsächlichen Kommandozeilen, die vom Bedrohungsakteur für deren Betrieb verwendet wurden, finden Sie im ergänzenden technischen Dokument.

Netzwerkinfrastruktur: Die Kommunikationswege der Angreifer

Für die C2-Kommunikation registrierten die Angreifer Domänennamen, deren Namen zufällig generiert zu sein schienen, um möglicherweise keine Aufmerksamkeit auf den bösartigen Datenverkehr zu lenken. GhostEmperor nutzte hauptsächlich Hosting-Dienste in Hongkong und Südkorea, wie Daou Technology oder Anchent Asia Limited.

Wir beobachteten auch zusätzliche IP-Adressen, die zum Herunterladen einiger bösartiger Samples oder für die C2-Kommunikation durch das In-Memory-Implantat verwendet wurden.

Die Ziele: Wer wurde ins Visier genommen?

Die Mehrheit der Opfer von GhostEmperor waren Regierungsstellen und Telekommunikationsunternehmen in Südostasien, wobei mehrere prominente Einrichtungen in Malaysia, Thailand, Vietnam und Indonesien ins Visier genommen wurden. Wir beobachteten auch zusätzliche Opfer ähnlicher Art aus Ländern wie Ägypten, Äthiopien und Afghanistan. Auch wenn dieser letztere Cluster von Opfern einer anderen Region angehört als die, in der GhostEmperor sehr aktiv war, stellten wir fest, dass einige der Organisationen darin starke Verbindungen zu Ländern in Südostasien aufweisen. Dies bedeutet, dass die Angreifer diese Infektionen möglicherweise genutzt haben, um die Aktivitäten in Ländern auszuspionieren, die für sie von geostrategischem Interesse sind.

Wer steckt hinter den Angriffen?

Wir ordnen diese Aktivität einem bisher unbekannten chinesischsprachigen Bedrohungsakteur zu. Dies liegt daran, dass die Angreifer Open-Source-Tools wie Ladon oder Mimikat_ssp verwendeten, die bei solchen Akteuren beliebt sind. Zusätzliche Datenpunkte wie Versionsinformationen, die im Ressourcenbereich von Binärdateien der zweiten Ladephase gefunden wurden, enthielten ein Feld für die rechtliche Marke mit einem chinesischen Zeichen: “Windows® ist eine eingetragene Marke der Microsoft Corporation.”

Versionsinformationen der Lader-Binärdatei mit chinesischem ZeichenVersionsinformationen der Lader-Binärdatei mit chinesischem Zeichen

Ebenso stellten wir fest, dass einer der Entschlüsselungsschlüssel, der in einer Kommandozeile von den Angreifern bereitgestellt und zum Dekodieren der PowerShell-Skripte der ersten Phase verwendet wurde, “wudi520” lautete. Eine Suche nach diesem Namen in öffentlich zugänglichen Quellen führte uns zu einem GitHub-Konto unter demselben Namen. Obwohl wir nicht bestätigen können, dass dieses Konto tatsächlich mit den GhostEmperor-Angreifern verbunden ist, hat es mehrere Code-Repositorys “geforkt”, die Beschreibungen in chinesischer Sprache enthalten oder anderweitig von chinesischsprachigen Entwicklern verfasst wurden.

Darüber hinaus bemerkten wir einige Ähnlichkeiten zwischen den Merkmalen von Demodex und denen des Derusbi-Rootkits, das in der Vergangenheit öffentlich beschrieben wurde und ebenfalls einem chinesischsprachigen Akteur zugeschrieben wurde. Der Zweck beider ist es, bösartige Artefakte zu verbergen, wobei beide einen fast identischen Ablauf zur Verschleierung von TCP-Verbindungen aufweisen, indem sie den IOCTL-Dispatcher von nsiproxy.sys hooken. Die Implementierung dieser Filterung im analysierten Demodex-Sample ist nahezu identisch mit der in einem älteren Derusbi-Sample (MD5: 24E9870973CEA42E6FAF705B14208E52) bis zu dem Punkt, an dem beide denselben Geräte-Kontrollcode für diese Aktion verwenden und eine IOCTL-Eingabe derselben Größe erhalten. Es ist jedoch erwähnenswert, dass Derusbi einen fest codierten Bereich von 1025 bis 1777 für die zu verbergenden Zielports verwendete, während Demodex einen beliebigen Bereich zulässt, der von den Angreifern über die User-Mode-Malware konfiguriert werden kann.

Vergleich einer ähnlichen IOCTL in den Demodex und Derusbi RootkitsVergleich einer ähnlichen IOCTL in den Demodex und Derusbi Rootkits

Es ist erwähnenswert, dass wir auf einem der Opfer-Systeme zwei Instanzen von bösartigen Samples beobachteten, die über eine Webshell bereitgestellt wurden. Eine führte zur Initiierung einer Infektionskette, bestehend aus dem PowerShell-Dropper der ersten Stufe und der .NET-Dienst-DLL der zweiten Stufe, und die andere war ein Drop von zwei Binärdateien der Netbot-Malware, die zuvor von der Lucky Mouse-Gruppe verwendet wurde. Auch wenn wir nicht bestätigen können, dass dieselbe Webshell zum Ablegen beider Dateien verwendet wurde, deutet die Nähe der Ereignisse innerhalb von zwei Tagen darauf hin, dass der zugrunde liegende Akteur tatsächlich beide Samples eingesetzt hat und eine mögliche Verbindung zur Lucky Mouse-Gruppe besteht, sei es durch gemeinsame Entwicklungsressourcen oder wiederverwendete Tools.

Schlussfolgerungen: Die anhaltende Bedrohung durch fortschrittliche Akteure

GhostEmperor ist ein Beispiel für einen fortgeschrittenen Bedrohungsakteur, der prominente Ziele ins Visier nimmt und bestrebt ist, eine langjährige und persistente Operation in ihren Umgebungen aufrechtzuerhalten. Wir beobachteten, dass es dem zugrunde liegenden Akteur gelang, monatelang unentdeckt zu bleiben, während er gleichzeitig Finesse bei der Entwicklung des bösartigen Toolsets, ein tiefes Verständnis der Denkweise von Ermittlern und die Fähigkeit zur Abwehr forensischer Analysen auf vielfältige Weise demonstrierte.

Darüber hinaus zeigen dieser Fall und andere aktuelle Fälle, dass Rootkits, obwohl sie im Allgemeinen als veraltete Angriffsmethode gelten, mit einem kreativen Ansatz immer noch genutzt werden können, um ein beträchtliches Maß an Tarnung zu erzielen. Wie wir gesehen haben, führten die Angreifer die erforderliche Forschung durch, um das Demodex-Rootkit vollständig unter Windows 10 funktionsfähig zu machen, was ihm ermöglichte, sich über dokumentierte Funktionen eines Drittanbieter-signierten und gutartigen Treibers zu laden. Dies deutet darauf hin, dass Rootkits bei Ermittlungen weiterhin als TTP (Taktiken, Techniken und Prozeduren) berücksichtigt werden müssen und dass fortgeschrittene Bedrohungsakteure wie der hinter GhostEmperor bereit sind, sie auch in zukünftigen Kampagnen weiterhin einzusetzen.

Indikatoren für Kompromittierung (Indicators of Compromise – IoCs)

Stufe 1 – PowerShell Dropper

  • 012862165EC105A44FEA14FACE53492Fu_ex200822.ps1

Stufe 2 – Service DLL

  • 6A44FDD66AB841C33949620666CA847ARAudioUniConfig.dll
  • 2DD0885F84B890883A396030DB841D28
  • 1BC301AA9B861F762CE5F376228E992Asvchosts.exe

Stufe 4

  • 0BBFBA106FBB9E310330DC87C32CB6D1 – Payload DLL
  • 6685323C61D8EDB4A6E35796AF34D626 – Remote Desktop Control DLL

Post-Exploitation

  • BE38D173E4E9118BDC2E83FD5F90BE3Bkekeo.exe
  • F078AC9B012C503D35254AF9629D3B67debugall.vbs

Treiber

  • 7394229455151a9cd036383027a1536b

Dateipfade

  • C:\Windows\debug\wia

PDB-Pfade

  • C:\c\getpwd\x64\Release\getpwd.pdb
  • D:\Source\workspace\ExCtrl\XControl\Release\XCLoader.pdb

Dienstname und DLL-Pfad

  • MsMp4Hw – C:\Windows\System32\msmp4dec.dll
  • Msdecode – C:\ProgramData\Microsoft\Network\Connections\msdecode.dll
  • AuthSvc – C:\Windows\System32\AuthSvc.dll

Registrierungsschlüssel für verschlüsselten Puffer

  • HKLM\Software\Microsoft\hiaudio
  • HKLM\Software\Microsoft\midihelp
  • HKLM\Software\Microsoft\data
  • HKLM\Software\Microsoft\update

Domänen und IPs

  • imap.newlylab[.]com
  • mail.reclubpress[.]com
  • imap.webdignusdata[.]com
  • freedecrease[.]com
  • aftercould[.]com
  • datacentreonline[.]com
  • game.newfreepre[.]com
  • 27.102.113[.]57
  • 27.102.113[.]240
  • 27.102.114[.]55
  • 27.102.115[.]51
  • 27.102.129[.]120
  • 107.148.165[.]158
  • 154.223.135[.]214

[1] Dieser Ansatz ist gut dokumentiert und wird im öffentlichen Repository von DSEFix demonstriert: https://github.com/hfiref0x/DSEFix [2] Der Quellcode des Treibers ist auf GitHub zu finden: https://github.com/cheat-engine/cheat-engine/blob/master/DBKKernel/IOPLDispatcher.c [3] Sie sind im Quellcode von IOPLDispatcher.c im Cheat Engine-Repository beschrieben. [4] Eine Technik, die der im Demodex-Rootkit beobachteten ähnelt, wird in diesem Code beschrieben: https://github.com/bowlofstew/rootkit.com/blob/master/cardmagic/PortHidDemo_Vista.c [5] Diese Binärdateien hatten die MD5s: 145FF08E736693D522F8A09C8D3405D6, 7A162C26D56B0C55E6CD81CD953F510B [6] https://securelist.com/ksb-2019-review-of-the-year/95394/, eine detaillierte Analyse der Netbot-Malware als Teil von Lucky Mouse-Kampagnen ist für Kunden unseres APT-Reporting-Dienstes verfügbar.