Einführung
Elastic Security Labs analysiert verschiedene Malware-Aktivitäten, die durch unsere Pipelines zur Bedrohungssuche und Telemetriewarteschlangen gelangen. Vor kurzem sind wir auf eine neue Malware-Familie namens DOUBLELOADER gestoßen, die neben dem RHADAMANTHYS Infostealer zu sehen ist. Ein interessantes Merkmal von DOUBLELOADER ist, dass es mit einem Open-Source-Obfuskator geschützt ist, ALCATRAZ , der erstmals 2023 veröffentlicht wurde. Während dieses Projekt seine Wurzeln in der Game-Hacking-Community hat, wurde es auch im Bereich der E-Kriminalität beobachtet und bei gezielten Einbrüchen eingesetzt.
Das Ziel dieses Beitrags ist es, verschiedene Verschleierungstechniken zu erläutern, die von ALCATRAZ eingesetzt werden, und gleichzeitig Methoden zur Bekämpfung dieser Techniken als Malware-Analysten hervorzuheben. Zu diesen Techniken gehören die Abflachung des Kontrollflusses, die Mutation von Anweisungen, die ständige Entfaltung von LEA, Anti-Disassembly-Tricks und die Verschleierung von Einstiegspunkten.
Wichtigste Erkenntnisse
- Der Open-Source-Obfuskator ALCATRAZ wurde in einer neuen Malware gesehen, die zusammen mit RHADAMANTHYS-Infektionen eingesetzt wurde
- Verschleierungstechniken wie die Abflachung der Kontrollabläufe stellen für Analysten weiterhin ein Hindernis dar
- Durch das Verständnis von Verschleierungstechniken und deren Bekämpfung können Unternehmen ihre Fähigkeit verbessern, geschützte Binärdateien effektiv zu selektieren und zu analysieren.
- Elastic Security Labs veröffentlicht Tools zur Entschleierung von ALCATRAZ-geschützten Binärdateien, die mit diesem Beitrag veröffentlicht werden
DOPPELLADER
Ab Dezember letzten Jahres beobachtete unser Team eine generische Backdoor-Malware in Verbindung mit RHADAMANTHYS-Stealer-Infektionen . Basierend auf dem PDB-Pfad wird diese Malware selbst als DOUBLELOADER bezeichnet.
Diese Malware nutzt Systemaufrufe wie NtOpenProcess, NtWriteVirtualMemory NtCreateThreadEx nicht gesicherten Code im Windows-Desktop-/Dateimanager (explorer.exe). Die Malware sammelt Host-Informationen, fordert eine aktualisierte Version von sich selbst an und beginnt mit dem Beaconing zu einer fest codierten IP (185.147.125.81), die in der Binärdatei gespeichert ist.
DOUBLELOADER-Beispiele enthalten einen nicht standardmäßigen Abschnitt (.0Dev) mit ausführbaren Berechtigungen, dies ist ein Toolmark, das auf dem Handle des Autors für das binäre Verschleierungswerkzeug basiert, ALCATRAZ.
Obfuskatoren wie ALCATRAZ erhöhen die Komplexität bei der Sichtung von Malware. Sein Hauptziel ist es, binäre Analysewerkzeuge zu behindern und die Zeit des Reverse-Engineering-Prozesses durch verschiedene Techniken zu verlängern; z. B. das Ausblenden der Ablaufsteuerung oder das Erschweren der Nachverfolgung der Dekompilierung. Unten sehen Sie ein Beispiel für eine verschleierte Ablaufsteuerung einer Funktion innerhalb von DOUBLELOADER.
Der Rest des Beitrags konzentriert sich auf die verschiedenen Verschleierungstechniken, die von ALCATRAZ verwendet werden. Wir werden die erste Stufe von DOUBLELOADER zusammen mit grundlegenden Codebeispielen verwenden, um die Funktionen von ALCATRAZ hervorzuheben.
ALCATRAZ
ALCATRAZ Übersicht
Alcatraz ist ein Open-Source-Obfuskator, der ursprünglich im Januar 2023 veröffentlicht wurde. Während das Projekt in der Game-Hacking-Community als grundlegendes Werkzeug zum Erlernen von Verschleierungstechniken anerkannt ist, wurde auch beobachtet, dass es von E-Crime- und APT-Gruppen missbraucht wird.
Die Codebasis von Alcatraz enthält 5 Hauptfunktionen, die sich auf Standard-Code-Verschleierungstechniken konzentrieren, sowie Verbesserungen zur Verschleierung des Einstiegspunkts. Der Workflow folgt einem Standard- bin2bin -Format, d.h. der Benutzer stellt eine kompilierte Binärdatei zur Verfügung und erhält nach den Transformationen eine neue kompilierte Binärdatei. Dieser Ansatz ist besonders attraktiv für Spielehacker/Malware-Entwickler, da er einfach zu bedienen ist und nur minimalen Aufwand und keine Änderungen auf Quellcode-Ebene erfordert.
Der Entwickler kann wählen, ob er alle oder bestimmte Funktionen verschleiern möchte und welche Verschleierungstechniken auf die einzelnen Funktionen angewendet werden sollen. Nach der Kompilierung wird die Datei mit der Zeichenfolge (obf) am Ende des Dateinamens generiert.
Verschleierungstechniken in ALCATRAZ
In den folgenden Abschnitten werden die verschiedenen Verschleierungstechniken erläutert, die von ALCATRAZ implementiert werden.
Verschleierung des Einstiegspunkts
Der Umgang mit einem verschleierten Einstiegspunkt ist wie ein platter Reifen zu Beginn eines Familienausflugs. Die Idee dreht sich um verwirrende Analysten und binäre Tools, bei denen nicht direkt klar ist, wo das Programm startet, was zu Verwirrung gleich zu Beginn des Analyseprozesses führt.
Im Folgenden sehen Sie die Ansicht eines sauberen Einstiegspunkts (0x140001368) von einem nicht verschleierten Programm in IDA Pro.
Durch die Aktivierung der Einstiegspunktverschleierung verschiebt ALCATRAZ den Einstiegspunkt und fügt dann zusätzlichen Code mit einem Algorithmus hinzu, um den neuen Einstiegspunkt des Programms zu berechnen. Unten sehen Sie einen Ausschnitt der dekompilierten Ansicht des verschleierten Einstiegspunkts.
Da ALCATRAZ ein Open-Source-Obfuskator ist, können wir den benutzerdefinierten Einstiegspunktcode finden, um zu sehen, wie die Berechnung durchgeführt wird, oder unser eigenes verschleiertes Beispiel umkehren. In unserer Dekompilierung können wir sehen, dass der Algorithmus einige Felder aus dem PE-Header verwendet, z. B. das Size of the Stack Commit Time Date Stamp zusammen mit den ersten vier Bytes aus dem .0dev -Abschnitt. Diese Felder werden analysiert und dann mit bitweisen Operationen wie "Rotate Right" (ROR) und "Exclusive-OR" (XOR) verwendet, um den Einstiegspunkt zu berechnen.
Nachfolgend finden Sie eine Beispielausgabe eines IDA-Python-Skripts (Anhang A), das das PE analysiert und den wahren Einstiegspunkt findet, wobei der ursprüngliche Startpunkt (0x140001368) mit dem nicht verschleierten Beispiel bestätigt wird.
Anti-Demontage
Malware-Entwickler und -Obfuskatoren verwenden Anti-Disassemblierungstricks, um Disassembler zu verwirren oder zu brechen, um die statische Analyse zu erschweren. Diese Techniken nutzen Schwachstellen während linearer Sweeps und rekursiver Disassemblierung aus und verhindern eine saubere Coderekonstruktion, bei der der Analyst dann gezwungen ist, die zugrunde liegenden Anweisungen manuell oder automatisch zu korrigieren.
ALCATRAZ implementiert eine Form dieser Technik, indem es alle Anweisungen, die mit dem 0xFF Byte beginnen, modifiziert, indem es eine kurze Sprunganweisung ( 0xEB) davor hinzufügt. Das 0xFF Byte kann den Beginn mehrerer gültiger Anweisungen darstellen, die sich mit Aufrufen, indirekten Sprüngen und Pushes auf dem Stack befassen. Durch das Hinzufügen des kurzen Sprungs 0xEB davor springt dies effektiv zum nächsten Byte 0xFF. Es ist zwar nicht komplex, aber der Schaden entsteht durch die Demontage und erfordert einen Eingriff.
Um diese spezielle Technik zu beheben, kann die Datei gepatcht werden, indem jedes Vorkommen des 0xEB -Bytes durch NOPs ersetzt wird. Nach dem Patchen wird der Code in einem saubereren Zustand wiederhergestellt, sodass die folgende call Anweisung ordnungsgemäß disassembliert werden kann.
Mutation der Anweisungen
Eine gängige Technik, die von Obfuskatoren verwendet wird, ist die Instruktionsmutation, bei der Anweisungen so transformiert werden, dass ihr ursprüngliches Verhalten beibehalten wird, der Code jedoch schwerer zu verstehen ist. Frameworks wie Tigress oder Perses sind großartige Beispiele für die Verschleierungsforschung rund um die Mutation von Anweisungen.
Im Folgenden finden Sie ein Beispiel für diese von ALCATRAZ implementierte Technik, bei der jede Addition zwischen zwei Registern geändert wird, aber ihre semantische Äquivalenz intakt bleibt. Die einfache add Anweisung wird in 5 verschiedene Anweisungen umgewandelt (push, not, sub, pop, sub).
Um dies zu korrigieren, können wir den Musterabgleich verwenden, um diese 5 Anweisungen zusammen zu finden, die Bytes zerlegen, um herauszufinden, welche Register beteiligt sind, und dann einen Assembler wie Keystone verwenden, um die richtigen entsprechenden Bytes zu generieren.
Ständige Entfaltung
Diese Verschleierungstechnik ist in der gesamten DOUBLELOADER-Stichprobe weit verbreitet und eine weit verbreitete Methode bei verschiedenen Formen von Malware. Das Konzept hier konzentriert sich auf die Umkehrung des Kompilierungsprozesses; Anstatt Berechnungen zu optimieren, die zur Kompilierzeit bekannt sind, "entfaltet" der Obfuskator diese Konstanten, wodurch die Disassemblierung und Dekompilierung komplex und verwirrend wird. Im Folgenden finden Sie ein einfaches Beispiel für diese Technik, bei der die bekannte Konstante (46) in zwei mathematische Operationen aufgeteilt wird.
In DOUBLELOADER stoßen wir darauf, dass diese Technik immer dann verwendet wird, wenn unmittelbare Werte in ein Register verschoben werden. Diese unmittelbaren Werte werden durch mehrere bitweise Operationen ersetzt, die diese konstanten Werte maskieren, wodurch jeglicher Kontext und der Fluss des Analysten unterbrochen werden. In der Demontage unten auf der linken Seite befindet sich beispielsweise eine Vergleichsanweisung des EAX-Wertes an der Adresse (0x18016CD93). Wenn man sich die vorherigen Anweisungen ansieht, ist es nicht offensichtlich oder klar, wie hoch der EAX-Wert sein sollte, da mehrere obskure bitweise Berechnungen durchgeführt wurden. Wenn wir das Programm debuggen, können wir sehen, dass der EAX-Wert auf 0gesetzt ist.
Um diese Verschleierungstechnik zu bereinigen, können wir ihr Verhalten mit unserem eigenen Beispiel bestätigen, in dem wir den folgenden Quellcode verwenden und sehen können, wie die Transformation angewendet wird.
#include <iostream>
int add(int a, int b)
{
return a + b;
}
int main()
{
int c;
c = add(1, 2);
printf("Meow %d",c);
return 0;
}
Nach dem Kompilieren können wir die Deassemblierung der Funktion main in der sauberen Version auf der linken Seite sehen und sehen, wie diese beiden Konstanten (2,1) in das EDX- und ECX-Register verschoben wurden. Auf der rechten Seite befindet sich die transformierte Version, die beiden Konstanten sind unter den neu hinzugefügten Anweisungen versteckt.
Durch die Verwendung von Mustervergleichstechniken können wir nach diesen Anweisungssequenzen suchen, die Anweisungen emulieren, um die verschiedenen Berechnungen durchzuführen, um die ursprünglichen Werte wiederherzustellen, und dann die verbleibenden Bytes mit NOPs patchen, um sicherzustellen, dass das Programm weiterhin ausgeführt wird.
LEA-Verschleierung
Ähnlich wie bei der zuvor besprochenen Technik konzentriert sich die LEA-Verschleierung (Load Effective Address) darauf, die unmittelbaren Werte zu verschleiern, die mit LEA-Anweisungen verbunden sind. Direkt hinter der LEA-Anweisung folgt eine arithmetische Berechnung mit Subtraktion, um den ursprünglich beabsichtigten Wert zu berechnen. Dies mag zwar wie eine kleine Änderung erscheinen, kann aber erhebliche Auswirkungen auf Querverweise auf Zeichenfolgen und Daten haben, die für eine effektive binäre Analyse unerlässlich sind.
Im Folgenden finden Sie ein Beispiel für diese Technik in DOUBLELOADER, bei dem der RAX-Registerwert durch ein Muster verschleiert wird, bei dem ein Anfangswert (0x1F4DFCF4F) geladen und dann (0x74D983C7) subtrahiert wird, um einen neuen berechneten Wert (0x180064B88) zu erhalten.
Wenn wir zu dieser Adresse in unserem Beispiel gehen, werden wir zum schreibgeschützten Datenabschnitt weitergeleitet, wo wir die referenzierte Zeichenfolge bad array new lengthfinden.
Um diese Technik zu korrigieren, können wir den Musterabgleich verwenden, um diese spezifischen Anweisungen zu finden, die Berechnung durchzuführen und dann eine neue LEA-Anweisung zu rekonstruieren. Im 64-Bit-Modus verwendet LEA eine RIP-relative Adressierung, sodass die Adresse auf der Grundlage des aktuellen Befehlszeigers (RIP) berechnet wird. Letztendlich erhalten wir eine neue Anleitung, die so aussieht: lea rax, [rip - 0xFF827].
Im Folgenden finden Sie die Schritte zum Erstellen dieser endgültigen Anweisung:
Mit diesen Informationen können wir IDA Python verwenden, um all diese Muster auszubessern, unten sehen Sie ein Beispiel für eine feste LEA-Anweisung.
Verschleierung der Ablaufsteuerung
Die Ablaufsteuerungsvereinfachung ist eine leistungsstarke Verschleierungstechnik, die die traditionelle Struktur der Ablaufsteuerung eines Programms stört, indem herkömmliche Konstrukte wie bedingte Verzweigungen und Schleifen eliminiert werden. Stattdessen wird die Ausführung mithilfe eines zentralen Dispatchers neu strukturiert, der den nächsten auszuführenden Basisblock auf der Grundlage einer Zustandsvariablen bestimmt, was die Analyse und Dekompilierung erheblich erschwert. Im Folgenden finden Sie ein einfaches Diagramm, das die Unterschiede zwischen einer nicht vereinfachten und einer vereinfachten Ablaufsteuerung darstellt.
Unser Team hat diese Technik in verschiedenen Malware wie DOORME beobachtet, und es sollte in diesem Fall keine Überraschung sein, dass die abgeflachte Kontrolle eines der Hauptmerkmale des ALCATRAZ-Obfuskators ist. Um uns dem Deflattening zu nähern, haben wir uns auf etablierte Tools konzentriert, indem wir das IDA-Plugin D810 verwendet haben, das vom Sicherheitsforscher Boris Batteux geschrieben wurde.
Wir beginnen mit unserem vorherigen Beispielprogramm mit der allgemeinen _security_init_cookie Funktion, die zur Erkennung von Pufferüberläufen verwendet wird. Nachfolgend sehen Sie das Kontrollflussdiagramm der Cookie-Initialisierungsfunktion in nicht verschleierter Form. Basierend auf dem Diagramm können wir sehen, dass es sechs grundlegende Blöcke und zwei bedingte Zweige gibt, und wir können dem Ausführungsablauf leicht folgen.
Wenn wir die gleiche Funktion verwenden und die Funktion zur Abflachung der Ablaufsteuerung von ALCATRAZ anwenden, sieht die Ablaufsteuerung des Programms mit 22 Basisblöcken, 8 bedingten Verzweigungen und einem neuen Dispatcher völlig anders aus. In der folgenden Abbildung stellen die farblich gefüllten Blöcke die vorherigen Basisblöcke der nicht verschleierten Version dar, die restlichen Blöcke in Weiß stellen den hinzugefügten Verschleierungscode dar, der zum Verteilen und Steuern der Ausführung verwendet wird.
Wenn wir uns die Dekompilierung ansehen, können wir sehen, dass die Funktion jetzt in verschiedene Teile innerhalb einer while Schleife unterteilt ist, in der eine neue state Variable verwendet wird, um das Programm zusammen mit Überresten der Verschleierung, einschließlich popf/pushf Anweisungen, zu führen.
Zum Bereinigen dieser Funktion wendet D810 zwei verschiedene Regeln (UnflattenerFakeJump, FixPredecessorOfConditionalJumpBlock) an, die Mikrocodetransformationen anwenden, um die Dekompilierung zu verbessern.
2025-04-03 15:44:50,182 - D810 - INFO - Starting decompilation of function at 0x140025098
2025-04-03 15:44:50,334 - D810 - INFO - glbopt finished for function at 0x140025098
2025-04-03 15:44:50,334 - D810 - INFO - BlkRule 'UnflattenerFakeJump' has been used 1 times for a total of 3 patches
2025-04-03 15:44:50,334 - D810 - INFO - BlkRule 'FixPredecessorOfConditionalJumpBlock' has been used 1 times for a total of 2 patches
Wenn wir den Decompiler aktualisieren, wird die Abflachung des Kontrollflusses entfernt, und der Pseudocode wird bereinigt.
Dies ist zwar ein gutes Beispiel, aber das Beheben der Verschleierung der Ablaufsteuerung kann oft ein manueller und zeitnaher Prozess sein, der funktionsabhängig ist. Im nächsten Abschnitt werden wir einige der Techniken, die wir gelernt haben, zusammentragen und auf DOUBLELOADER anwenden.
Reinigen einer DOUBLELOADER-Funktion
Eine der Herausforderungen beim Umgang mit Verschleierung in Malware sind nicht so sehr die einzelnen Verschleierungstechniken, sondern die Schichtung der Techniken. Darüber hinaus werden im Fall von DOUBLELOADER große Teile des Codes in Funktionsblöcken mit mehrdeutigen Grenzen platziert, was die Analyse erschwert. In diesem Abschnitt gehen wir ein praktisches Beispiel durch, das den Reinigungsprozess für eine durch ALCATRAZ geschützte DOUBLELOADER-Funktion zeigt.
Beim Start beim Start Export geht einer der ersten Aufrufe an loc_18016C6D9. Dies scheint ein Eintrag in eine größere Funktion zu sein, jedoch ist IDA aufgrund undefinierter Anweisungen bei 0x18016C8C1nicht in der Lage, eine Funktion zu erstellen.
Wenn wir zu dieser Adresse scrollen, können wir sehen, dass die erste Störung auf die Anti-Demontage-Technik mit kurzem Sprung zurückzuführen ist, die wir weiter oben im Blogbeitrag (EB FF) gesehen haben.
Nachdem wir 6 nahegelegenen Vorkommen derselben Technik behoben haben, können wir zur Startadresse (0x18016C6D9) zurückkehren und die MakeFunction-Funktion verwenden. Die Funktion wird zwar dekompiliert, ist aber immer noch stark verschleiert, was für eine Analyse nicht ideal ist.
Wenn wir auf die Disassemblierung zurückkommen, sehen wir unten die LEA-Verschleierungstechnik, die in dieser Funktion verwendet wird, wo die Zeichenfolgenkonstante ”Error” nun mit der früheren Lösung wiederhergestellt wird.
Ein weiteres Beispiel zeigt die Transformation eines verschleierten Parameters für einen LoadIcon Aufruf, bei dem der lpIconName Parameter bereinigt wird, um 0x7f00 (IDI_APPLICATION).
Jetzt, da sich die Dekompilierung verbessert hat, können wir die Bereinigung abschließen, indem wir die Verschleierung der Ablaufsteuerung mit dem D810-Plugin entfernen. Nachfolgend finden Sie eine Demonstration, die die Vorher-Nachher-Effekte zeigt.
In diesem Abschnitt wurde ein reales Szenario behandelt, in dem auf die Bereinigung einer bösartigen verschleierten Funktion hingearbeitet wird, die durch ALCATRAZ geschützt ist. Während Malware-Analyseberichte oft die endgültigen Ergebnisse anzeigen, wird oft ein großer Teil der Zeit damit verbracht, die Verschleierung zu entfernen und die Binärdatei zu reparieren, damit sie dann ordnungsgemäß analysiert werden kann.
IDA-Python-Skripte
Unser Team veröffentlicht eine Reihe von Proof-of-Concept-IDA-Python-Skripten, die verwendet werden, um die vom ALCATRAZ-Obfuskator auferlegten Standard-Verschleierungstechniken zu handhaben. Diese sollen als grundlegende Beispiele für den Umgang mit diesen Techniken dienen und sollten zu Forschungszwecken verwendet werden. Leider gibt es kein Patentrezept für den Umgang mit Verschleierung, aber einige Beispiele und allgemeine Strategien können wertvoll sein, um ähnliche Herausforderungen in Zukunft anzugehen.
YARA
Elastic Security hat YARA-Regeln erstellt, um diese Aktivität zu identifizieren.
Beobachtungen
Die folgenden Observablen wurden in dieser Studie diskutiert.
| Überwachbar | Typ | Name | Referenz |
|---|---|---|---|
3050c464360ba7004d60f3ea7ebdf85d9a778d931fbf1041fa5867b930e1f7fd | SHA256 | DoubleLo.dll | DOPPELLADER |
Referenzen
In der obigen Studie wurde auf Folgendes Bezug genommen:
