Präambel
Elastic Security Labs hat einen neuartigen Rust-basierten Infostealer aufgedeckt, der über Fake-CAPTCHA-Kampagnen verbreitet wird. Diese Malware wird auf mehreren von Angreifern kontrollierten Web-Eigenschaften gehostet. Diese Kampagne nutzt irreführende CAPTCHA-Verifizierungsseiten, die Benutzer dazu verleiten, ein bösartiges PowerShell-Skript auszuführen, das schließlich den Infostealer einsetzt und sensible Daten wie Anmeldeinformationen, Browserinformationen und Kryptowährungs-Wallet-Details sammelt. Wir nennen diese Malware EDDIESTEALER.
Die Einführung von Rust in der Malware-Entwicklung spiegelt einen wachsenden Trend unter Bedrohungsakteuren wider, die moderne Sprachfunktionen nutzen wollen, um die Tarnung, Stabilität und Widerstandsfähigkeit gegenüber herkömmlichen Analyse-Workflows und Bedrohungserkennungs-Engines zu verbessern. Ein scheinbar einfacher Infostealer, der in Rust geschrieben wurde, erfordert im Vergleich zu seinem C/C++-Pendant oft einen höheren Analyseaufwand, was auf Faktoren wie kostenlose Abstraktionen, das Typsystem von Rust, Compiler-Optimierungen und inhärente Schwierigkeiten bei der Analyse speichersicherer Binärdateien zurückzuführen ist.
Wichtigste Erkenntnisse
- Fake-CAPTCHA-Kampagne lädt EDDIESTEALER
- EDDIESTEALER ist ein neu entdeckter Rust-Infostealer, der auf Windows-Hosts abzielt
- EDDIESTEALER erhält vom C2-Server eine Aufgabenliste, in der die zu adressierenden Daten aufgeführt sind
Anfänglicher Zugang
Überblick
Gefälschte CAPTCHAs sind bösartige Konstrukte, die das Aussehen und die Funktionalität legitimer CAPTCHA-Systeme replizieren, die zur Unterscheidung zwischen menschlichen Benutzern und automatisierten Bots verwendet werden. Im Gegensatz zu ihren legitimen Gegenstücken dienen gefälschte CAPTCHAs als Einfallstor für Malware und nutzen Social Engineering, um Benutzer zu täuschen. Sie erscheinen oft als Aufforderungen wie "Verifizieren Sie, dass Sie ein Mensch sind" oder "Ich bin kein Roboter" und fügen sich nahtlos in kompromittierte Websites oder Phishing-Kampagnen ein. Wir sind auch auf eine ähnliche Kampagne gestoßen, bei der GHOSTPULSE Ende 2024 verteilt wurde.
Bei unserer Telemetrieanalyse, die zur Auslieferung von EDDIESTEALER führte, war der ursprüngliche Vektor eine kompromittierte Website, die eine verschleierte React-basierte JavaScript-Nutzlast einsetzte, die einen gefälschten "Ich bin kein Roboter"-Verifizierungsbildschirm anzeigte.
In Anlehnung an die reCAPTCHA-Verifizierungsschnittstelle von Google verwendet die Malware die document.execCommand("copy") -Methode, um einen PowerShell-Befehl in die Zwischenablage des Benutzers zu kopieren, als nächstes weist sie den Benutzer an, Windows + R zu drücken (um das Windows-Dialogfeld "Ausführen" zu öffnen), dann Strg + V, um den Inhalt der Zwischenablage einzufügen und schließlich die Eingabetaste, um den bösartigen PowerShell-Befehl auszuführen.
Dieser Befehl lädt im Hintergrund eine Nutzlast der zweiten Stufe (gverify.js) aus dem vom Angreifer kontrollierten Domänen- hxxps://llll.fit/version/ herunter und speichert sie im Downloads Ordner des Benutzers.
Schließlich führt die Malware gverify.js mit cscript in einem versteckten Fenster aus.
gverify.js ist eine weitere verschleierte JavaScript-Nutzlast, die mit Open-Source-Tools entschleiert werden kann. Die Funktionsweise ist ziemlich einfach: Es wird eine ausführbare Datei (EDDIESTEALER) von hxxps://llll.fit/io geholt und die Datei im Ordner Downloads des Benutzers mit einem pseudozufälligen 12-stelligen Dateinamen gespeichert.
EDDIESTEALER
Überblick
EDDIESTEALER ist ein neuartiger, auf Rust basierender Infostealer. Die meisten Zeichenfolgen, die ihre böswillige Absicht verraten, sind verschlüsselt. Der Malware fehlt ein robuster Anti-Sandbox-/VM-Schutz gegen verhaltensbasierte Fingerabdrücke. Neuere Varianten deuten jedoch darauf hin, dass die Anti-Sandbox-/VM-Überprüfungen möglicherweise auf der Serverseite durchgeführt werden. Mit relativ einfachen Funktionen erhält es eine Aufgabenliste vom C2-Server als Teil seiner Konfiguration, um auf bestimmte Daten abzuzielen, und kann sich nach der Ausführung selbst löschen, falls angegeben.
Entfernte Symbole
EDDIESTEALER-Beispiele enthielten entfernte Funktionssymbole, die wahrscheinlich die standardmäßige Kompilierungsoption von Rust verwendeten und eine Symbolwiederherstellung vor der statischen Analyse erforderten. Wir haben rustbinsignverwendet, das Signaturen für Rust-Standardbibliotheken und -Kisten basierend auf bestimmten Rust-/Compiler-/Abhängigkeitsversionen generiert. Während rustbinsign nur hashbrown und rustc-demangleerkannte, was darauf hindeutet, dass nur wenige externe Kisten verwendet wurden, wurden Kisten wie tinyjson und tungstenite in neueren Varianten nicht identifiziert. Dies geschah aufgrund des Mangels an eindeutigen String-Artefakten. Es ist immer noch möglich, Kisten manuell zu identifizieren, indem man eindeutige Zeichenfolgen findet und auf GitHub nach dem Repository sucht, um dann im download_sign -Modus Signaturen für sie herunterzuladen, zu kompilieren und zu erstellen. Es ist etwas umständlich, wenn wir die genaue Version der verwendeten Kiste nicht kennen. Die Wiederherstellung der Standardbibliothek und der Laufzeitsymbole ist jedoch ausreichend, um den statischen Analyseprozess voranzutreiben.
Verschleierung von Zeichenfolgen
EDDIESTEALER verschlüsselt die meisten Zeichenketten über eine einfache XOR-Chiffre. Die Entschlüsselung umfasst zwei Phasen: Zuerst wird der XOR-Schlüssel durch Aufrufen einer von mehreren Schlüsselableitungsfunktionen abgeleitet. Anschließend wird die Entschlüsselung inline innerhalb der Funktion durchgeführt, die die Zeichenfolge verwendet.
Dies wird im folgenden Beispiel veranschaulicht, wobei sub_140020fd0 die Schlüsselableitungsfunktion und data_14005ada8 die Adresse des verschlüsselten Blobs ist.
Jede Entschlüsselungsroutine verwendet ihre eigene Funktion zur Schlüsselableitung. Diese Funktionen akzeptieren konsistent zwei Argumente: eine Adresse innerhalb der Binärdatei und einen konstanten 4-Byte-Wert. Für diese Argumente werden dann einige grundlegende Operationen ausgeführt, um die Adresse zu berechnen, an der sich der XOR-Schlüssel befindet.
Binary Ninja verfügt über eine praktische Funktion namens User-Informed Data Flow (UIDF), mit der wir die Variablen auf bekannte Werte setzen können, um eine konstante Ausbreitungsanalyse auszulösen und die Ausdrücke zu vereinfachen. Andernfalls kann auch ein CPU-Emulator wie Unicorn in Kombination mit einem skriptfähigen binären Analysetool für die Batch-Analyse nützlich sein.
Es gibt ein allgemeines Muster für die threadsichere, verzögerte Initialisierung von freigegebenen Ressourcen, z. B. verschlüsselte Zeichenfolgen für Modulnamen, C2-Domäne und -Port, den eindeutigen Bezeichner des Beispiels, die nur einmal entschlüsselt werden, aber während der Laufzeit mehrmals referenziert werden. Jede spezifische Getter-Funktion prüft ein Statusflag für ihre Ressource. Wenn die Initialisierung nicht erfolgt, wird eine gemeinsam genutzte Synchronisierungsfunktion auf niedriger Ebene aufgerufen. Diese Synchronisationsroutine verwendet atomare Operationen und OS-Wait-Primitive (WaitOnAddress/WakeByAddressAll), um sicherzustellen, dass nur ein Thread die eigentliche Initialisierungslogik ausführt, die indirekt über einen Funktionszeiger in der vtable eines dyn Trait -Objekts aufgerufen wird.
API-Verschleierung
EDDIESTEALER verwendet für die meisten API-Aufrufe einen benutzerdefinierten WinAPI-Lookup-Mechanismus. Es beginnt mit der Entschlüsselung der Namen des Zielmoduls und der Zielfunktion. Vor dem Versuch der Auflösung wird eine lokal verwaltete Hashtabelle überprüft, um festzustellen, ob der Funktionsname und die Adresse bereits aufgelöst wurden. Wenn es nicht gefunden wird, lädt es das erforderliche Modul mithilfe eines benutzerdefinierten LoadLibrary Wrappers dynamisch in den Adressraum des Prozesses und ruft eine bekannte Implementierung von GetProcAddress auf, um die Adresse der exportierten Funktion abzurufen. Der API-Name und die API-Adresse werden dann in die Hashtabelle eingefügt, um zukünftige Nachschlagevorgänge zu optimieren.
Mutex-Erstellung
EDDIESTEALER beginnt mit der Erstellung eines Mutex, um sicherzustellen, dass immer nur eine Instanz der Malware ausgeführt wird. Der Mutex-Name ist eine entschlüsselte UUID-Zeichenkette 431e2e0e-c87b-45ac-9fdb-26b7e24f0d39 (unique per sample), auf die später beim ersten Kontakt mit dem C2-Server erneut verwiesen wird.
Sandbox-Erkennung
EDDIESTEALER führt eine schnelle Überprüfung durch, um zu beurteilen, ob die Gesamtmenge des physischen Speichers über ~4,0 liegt GB als schwacher Sandbox-Erkennungsmechanismus. Wenn die Prüfung fehlschlägt, löscht sie sich selbst von der Festplatte.
Selbstlöschung
Basierend auf einer ähnlichen Selbstlöschtechnik , die in LATRODECTUS beobachtet wurde, ist EDDIESTEALER in der Lage, sich durch Umbenennung von NTFS Alternate Data Streams selbst zu löschen, um Dateisperren zu umgehen.
Die Malware verwendet GetModuleFileName , um den vollständigen Pfad ihrer ausführbaren Datei zu erhalten, und CreateFileW (in jy::ds::OpenHandleumschlossen), um ein Handle zu ihrer ausführbaren Datei mit den entsprechenden Zugriffsrechten zu öffnen. Anschließend wird eine FILE_RENAME_INFO -Struktur mit einem neuen Stream-Namen an SetFileInformationByHandle übergeben, um den Standard-Stream $DATA in :metadataumzubenennen. Das Dateihandle wird geschlossen und erneut geöffnet, diesmal mit SetFileInformationByHandle auf dem Handle, wobei das Flag FILE_DISPOSITION_INFO.DeleteFile auf TRUE gesetzt ist, um das Flag "Löschen beim Schließen des Handles" zu aktivieren.
Zusätzliche Konfigurationsanforderung
Die anfänglichen Konfigurationsdaten werden als verschlüsselte Zeichenfolgen innerhalb der Binärdatei gespeichert. Nach der Entschlüsselung werden diese Daten verwendet, um eine Anforderung nach dem URI-Muster zu erstellen: <C2_ip_or_domain>/<resource_path>/<UUID>. Die resource_path wird als api/handlerangegeben. Der UUID, der zuvor zum Erstellen eines Mutex verwendet wurde, wird als eindeutiger Bezeichner für die Buildnachverfolgung verwendet.
EDDIESTEALER kommuniziert dann mit seinem C2-Server, indem es eine HTTP GET-Anfrage mit der erstellten URI sendet, um eine Konfiguration der zweiten Stufe abzurufen, die eine Liste von Aufgaben enthält, die die Malware ausführen soll.
Die Konfigurationsdaten der zweiten Stufe sind AES CBC-verschlüsselt und Base64-kodiert. Der Base64-kodierte IV wird in der Nachricht vor dem Doppelpunkt (:) vorangestellt.
Base64(IV):Base64(AESEncrypt(data))
Der AES-Schlüssel zum Entschlüsseln der Server-zu-Client-Nachricht wird unverschlüsselt in UTF-8-Codierung im Abschnitt .rdata gespeichert. Es wird über eine Getter-Funktion abgerufen.
Die entschlüsselte Konfiguration für dieses Beispiel enthält Folgendes im JSON-Format:
- Sitzungs-ID
- Liste der Aufgaben (Daten zum Ziel)
- AES-Schlüssel für die Verschlüsselung von Client-zu-Server-Nachrichten
- Selbstlösch-Flag
{
"session": "<unique_session_id>",
"tasks": [
{
"id": "<unique_task_id>",
"prepare": [],
"pattern": {
"path": "<file_system_path>",
"recursive": <true/false>,
"filters": [
{
"path_filter": <null/string>,
"name": "<file_or_directory_name_pattern>",
"entry_type": "<FILE/DIR>"
},
...
]
},
"additional": [
{
"command": "<optional_command>",
"payload": {
"<command_specific_config>": <value>
}
},
...
]
},
...
],
"network": {
"encryption_key": "<AES_encryption_key>"
},
"self_delete": <true/false>
}
Für dieses spezielle Beispiel und basierend auf den Aufgaben, die während unserer Analyse vom Server empfangen wurden, finden Sie hier eine Liste der dateisystembasierten Exfiltrationsziele:
- Krypto-Geldbörsen
- Browser
- Passwort-Manager
- FTP-Clients
- Messaging-Anwendungen
| Krypto-Geldbörse | Filter für Zielpfad |
|---|---|
| Waffenkammer | %appdata%\\Armory\\*.wallet |
| Bitcoin (Englisch) | %appdata%\\Bitcoin\\wallets\\* |
| GeldbörseWasabi | %appdata%\\WalletWasabi\\Client\\Wallets\\* |
| Daedalus Mainnet | %appdata%\\Daedalus Mainnet\\wallets\\* |
| Coinomi | %localappdata%\\Coinomi\\Coinomi\\wallets\\* |
| Elektron | %appdata%\\Electrum\\wallets\\* |
| Exodus | %appdata%\\Exodus\\exodus.wallet\\* |
| DashCore | %appdata%\\DashCore\\wallets\\* |
| ElectronCash | %appdata%\\ElectronCash\\wallets\\* |
| Electrum-DASH | %appdata%\\Electrum-DASH\\wallets\\* |
| Guarda | %appdata%\\Guarda\\IndexedDB |
| Atomar | %appdata%\\atomic\\Local Storage |
| Browser | Filter für Zielpfad |
|---|---|
| Microsoft Edge | %localappdata%\\Microsoft\\Edge\\User Data\\[Web Data,History,Bookmarks,Local Extension Settings\\...] |
| Tapfer | %localappdata%\\BraveSoftware\\Brave-Browser\\User Data\\[Web Data,History,Bookmarks,Local Extension Settings\\...] |
| Google Chrome | %localappdata%\\Google\\Chrome\\User Data\\[Web Data,History,Bookmarks,Local Extension Settings\\...] |
| Mozilla Firefox | %appdata%\\Mozilla\\Firefox\\Profiles\\[key4.db,places.sqlite,logins.json,cookies.sqlite,formhistory.sqlite,webappsstore.sqlite,*+++*] |
| Passwort-Manager | Filter für Zielpfad |
|---|---|
| Bitwarden | %appdata%\\Bitwarden\\data.json |
| 1Password | %localappdata%\\1Password\\[1password.sqlite,1password_resources.sqlite] |
| KeePass | %userprofile%\\Documents\\*.kdbx |
| FTP-Client | Filter für Zielpfad |
|---|---|
| FileZilla | %appdata%\\FileZilla\\recentservers.xml |
| FTP-Manager Lite | %localappdata%\\DeskShare Data\\FTP Manager Lite\\2.0\\FTPManagerLiteSettings.db |
| FTPbox | %appdata%\\FTPbox\\profiles.conf |
| FTP Commander Deluxe | %ProgramFiles(x86)%\\FTP Commander Deluxe\\FTPLIST.TXT |
| Automatischer FTP-Manager | %localappdata%\\DeskShare Data\\Auto FTP Manager\\AutoFTPManagerSettings.db |
| 3D-FTP | %programdata%\\SiteDesigner\\3D-FTP\\sites.ini |
| FTPGetter | %appdata%\\FTPGetter\\servers.xml |
| Gesamter Kommandant | %appdata%\\GHISLER\\wcx_ftp.ini |
| Messaging-App | Filter für Zielpfad |
|---|---|
| Telegramm-Desktop | %appdata%\\Telegram Desktop\\tdata\\* |
Eine Liste der gezielten Browsererweiterungen finden Sie hier.
Diese Ziele können sich ändern, da sie vom C2-Operator konfiguriert werden können.
EDDIESTEALER liest dann die Zieldateien mit Standard- kernel32.dll Funktionen wie CreateFileW, GetFileSizeEx, ReadFileund CloseHandle.
Nachfolgender C2-Verkehr
Nach erfolgreichem Abruf der Aufgaben führt EDDIESTEALER eine Systemprofilerstellung durch, um einige Informationen über das infizierte System zu sammeln:
- Speicherort der ausführbaren Datei (
GetModuleFileNameW) - Gebietsschema-ID (
GetUserDefaultLangID) - Benutzername (
GetUserNameW) - Gesamtmenge des physischen Speichers (
GlobalMemoryStatusEx) - Betriebssystem-Version (
RtlGetVersion)
Nach dem gleichen Datenformat (Base64(IV):Base64(AESEncrypt(data))) für Client-zu-Server-Nachrichten werden die anfänglichen Hostinformationen AES-verschlüsselt mit dem Schlüssel, der aus der zusätzlichen Konfiguration abgerufen und über eine HTTP-POST-Anfrage an <C2_ip_or_domain>/<resource_path>/info/<session_id>gesendet wird. Anschließend werden die gesammelten Daten für jede abgeschlossene Aufgabe ebenfalls verschlüsselt und in separaten POST-Anfragen an <C2_ip_or_domain>/<resource_path><session_id>/<task_id>übertragen, direkt nachdem jede Aufgabe abgeschlossen ist. Diese Methodik generiert ein eindeutiges C2-Datenverkehrsmuster, das durch mehrere, aufgabenspezifische POST-Anfragen gekennzeichnet ist. Dieses Muster ist besonders leicht zu erkennen, da diese Malware-Familie für ihre C2-Kommunikation primär auf HTTP statt auf HTTPS setzt.
Unsere Analyse deckte verschlüsselte Strings auf, die zu Panic-Metadaten-Strings entschlüsselt werden und interne Rust-Quelldateipfade offenlegen, wie z. B.:
apps\bin\src\services\chromium_hound.rsapps\bin\src\services\system.rsapps\bin\src\structs\search_pattern.rsapps\bin\src\structs\search_entry.rs
Wir haben festgestellt, dass Fehlermeldungen, die an den C2-Server gesendet werden, diese Zeichenfolgen enthalten, einschließlich der genauen Quelldatei, der Zeilennummer und der Spaltennummer, aus der der Fehler stammt, sodass der Malware-Entwickler ein integriertes Debugging-Feedback erhalten kann.
Chromium-spezifische Funktionen
Seit der Einführung der anwendungsgebundenen Verschlüsselung haben sich Malware-Entwickler an alternative Methoden angepasst, um diesen Schutz zu umgehen und Zugriff auf unverschlüsselte sensible Daten wie Cookies zu erhalten. ChromeKatz ist eine der am meisten angenommenen Open-Source-Lösungen, die Malware implementiert hat. EDDIESTEALER ist da keine Ausnahme – die Malware-Entwickler haben es in Rust neu implementiert.
Unten sehen Sie einen Ausschnitt der Logik zur Überprüfung der Browserversion, die der von COOKIEKATZ ähnelt, nachdem die Versionsinformationen von %localappdata%\<browser_specific_path>\\User Data\\Last Versionabgerufen wurden.
COOKIEKATZ-Signaturmuster zur Erkennung von COOKIEMONSTER-Instanzen:
CredentialKatz-Signaturmuster zur Erkennung von CookieMonster-Instanzen:
Hier ist ein Beispiel für die exakte Copy-Paste-Logik der FindPatternvon COOKIEKATZ, bei der PatchBaseAddress eingebunden ist.
Die Entwickler haben eine Änderung vorgenommen, um Fälle zu behandeln, in denen der Ziel-Chromium-Browser nicht ausgeführt wird. Wenn inaktiv, erzeugt EDDIESTEALER eine neue Browserinstanz mit den Befehlszeilenargumenten --window-position=-3000,-3000 https://google.com. Dadurch wird das neue Fenster weit außerhalb des Bildschirms positioniert und für den Benutzer unsichtbar. Ziel ist es, sicherzustellen, dass die Malware immer noch den Speicher (ReadProcessMemory) des erforderlichen untergeordneten Prozesses lesen kann - des Netzwerkdienstprozesses, der durch das --utility-sub-type=network.mojom.NetworkService -Flag identifiziert wird. Eine detailliertere Erläuterung dieser Browser-Prozessinteraktion finden Sie in unserer früheren Studie zu MaaS-Infostealern.
Unterschiede bei den Varianten
Nach der Analyse wurden neuere Proben mit zusätzlichen Fähigkeiten identifiziert.
Zu den auf den Opfercomputern gesammelten Informationen gehören nun:
- Running processes
- GPU-Informationen
- Anzahl der CPU-Kerne
- CPU-Name
- CPU-Anbieter
Das C2-Kommunikationsmuster wurde leicht verändert. Die Malware sendet nun präventiv Informationen über das Host-System an den Server, bevor sie die entschlüsselte Konfiguration anfordert. In einigen Fällen, in denen der Opfercomputer den C2-Server erreichen konnte, aber eine leere Aufgabenliste erhielt, deutet die Anpassung auf eine Umgehungstaktik hin: Entwickler haben wahrscheinlich serverseitige Überprüfungen eingeführt, um ein Profil der Client-Umgebung zu erstellen und die Hauptkonfiguration zurückzuhalten, wenn eine Sandbox oder ein Analysesystem erkannt wird.
Der Verschlüsselungsschlüssel für die Client-zu-Server-Kommunikation wird nicht mehr dynamisch vom C2-Server empfangen. Stattdessen ist es jetzt in der Binärdatei fest codiert. Der Schlüssel, der vom Client zum Entschlüsseln von Server-zu-Client-Nachrichten verwendet wird, bleibt ebenfalls hartcodiert.
Neuere kompilierte Beispiele weisen eine umfangreiche Verwendung der Funktionsinlineerweiterung auf, bei der viele Funktionen - sowohl benutzerdefinierte als auch aus Standardbibliotheken und -kästen - häufiger direkt in ihre Aufrufer eingebunden wurden, was zu größeren Funktionen führte und es schwierig machte, Benutzercode zu isolieren. Dieses Verhalten ist wahrscheinlich das Ergebnis der Verwendung des Inliners von LLVM. Während einige Funktionen nicht eingebunden bleiben, erschwert das weit verbreitete Inlining die Analyse zusätzlich.
Um alle Einträge des Passwort-Managers von Chrome zu erhalten, beginnt EDDIESTEALER seine Routine zum Diebstahl von Anmeldeinformationen, indem es einen neuen Chrome-Prozess mit dem --remote-debugging-port=<port_num> -Flag startet und das DevTools-Protokoll von Chrome über eine lokale WebSocket-Schnittstelle aktiviert. Auf diese Weise kann die Malware ohne Kopf mit dem Browser interagieren, ohne dass eine sichtbare Benutzerinteraktion erforderlich ist.
Nach dem Start von Chrome fragt die Malware http://localhost:<port>/json/version ab, um den webSocketDebuggerUrlabzurufen, der den Endpunkt für die Interaktion mit der Browserinstanz über WebSocket bereitstellt.
Über diese Verbindung gibt es einen Target.createTarget Befehl mit dem Parameter chrome://password-manager/passwordsaus, der Chrome anweist, seinen internen Passwort-Manager in einem neuen Tab zu öffnen. Obwohl diese interne Seite ihren Inhalt nicht direkt für das DOM oder DevTools verfügbar macht, bewirkt das Öffnen der Seite, dass Chrome gespeicherte Anmeldeinformationen entschlüsselt und in den Arbeitsspeicher lädt. Dieses Verhalten wird von EDDIESTEALER in nachfolgenden Schritten durch den CredentialKatz-Lookalike-Code ausgenutzt, wobei der Chrome-Prozessspeicher gescannt wird, um Klartext-Anmeldeinformationen zu extrahieren, nachdem sie vom Browser geladen wurden.
Basierend auf entschlüsselten Zeichenfolgen os_crypt, encrypted_key, CryptUnprotectData, local_state_patternund login_data_patternscheinen EDDIESTEALER-Varianten abwärtskompatibel zu sein und unterstützen Chrome-Versionen, die noch DPAPI-Verschlüsselung verwenden.
Wir haben 15 weitere Samples von EDDIESTEALER durch Code- und Infrastrukturähnlichkeiten auf VirusTotal identifiziert. Die Beobachtungstabelle enthält die ermittelten Beispiele, die zugehörigen C2-IP-Adressen/Domänen und eine Liste der Infrastrukturen, die EDDIESTEALER hosten.
Ein paar Analyse-Tipps
Pause
Um den Kontrollfluss besser zu verstehen und die genauen Ziele von indirekten Sprüngen oder Aufrufen in großen Codeblöcken zu bestimmen, können wir binäre Ablaufverfolgungstechniken nutzen. Tools wie TinyTracer können einen API-Trace erfassen und eine .tag -Datei generieren, die alle ausgewählten API-Aufrufe, die aufgezeichnet werden sollen, der ausführenden Linie in der Baugruppe zuordnet. Die Standardbibliotheksfunktionen von Rust rufen WinAPIs unter der Haube auf, und dies erfasst auch jeden Code, der WinAPI Funktionen direkt aufruft, unter Umgehung der Abstraktion der Standardbibliothek. Die Tag-Datei kann dann in Decompiler-Tools importiert werden, um die Codeblöcke mit Plugins wie IFLautomatisch zu markieren.
Panik-Metadaten für die Code-Segmentierung
Panic-Metadaten – die eingebetteten Quelldateipfade (.rs-Dateien), Zeilennummern und Spaltennummern, die mit Panic-Speicherorten verknüpft sind – bieten wertvolle Hinweise für die Segmentierung und das Verständnis verschiedener Teile der Binärdatei. Dies ist jedoch nur dann der Fall, wenn solche Metadaten nicht aus der Binärdatei entfernt wurden. Pfade wie apps\bin\src\services\chromium.rs, apps\bin\src\structs\additional_task.rs oder jeder Pfad, der wie Teil eines benutzerdefinierten Projekts aussieht, verweist in der Regel auf die eindeutige Logik der Anwendung. Pfade, die mit library<core/alloc/std>\src\ beginnen, geben Code aus der Rust-Standardbibliothek an. Pfade, die den Namen und die Version der Box enthalten, wie z. B. hashbrown-0.15.2\src\raw\mod.rs verweisen auf externe Bibliotheken.
Wenn das Malware-Projekt über eine einigermaßen organisierte Codebasis verfügt, können die Dateipfade in Panic-Zeichenfolgen direkt logischen Modulen zugeordnet werden. Zum Beispiel wird die entschlüsselte Zeichenfolge apps\bin\src\utils\json.rs:48:39 in sub_140011b4creferenziert.
Durch die Untersuchung der Aufrufstruktur auf eingehende Aufrufe der Funktion lassen sich viele von ihnen auf sub_14002699dzurückführen. Diese Funktion (sub_14002699d) wird innerhalb einer bekannten C2-Kommunikationsroutine (jy::C2::RetrieveAndDecryptConfig) direkt nach der Entschlüsselung zusätzlicher Konfigurationsdaten aufgerufen, von denen bekannt ist, dass sie im JSON-Format formatiert sind.
Basierend auf dem json.rs Pfad und seinem Aufrufkontext wäre eine fundierte Vermutung, dass sub_14002699d für das Parsen von JSON-Daten verantwortlich ist. Wir können dies überprüfen, indem wir den Funktionsaufruf überspringen. Durch die Überprüfung der Stack-Struktur, die als Referenz für den Funktionsaufruf übergeben wird, verweist sie nun auf eine Heap-Adresse, die mit analysierten Konfigurationsfeldern gefüllt ist.
Bei Standardbibliotheken und Open-Source-Crates von Drittanbietern können Sie mit dem Dateipfad, der Zeilennummer und (falls verfügbar) dem rustc-Commit-Hash oder der Crate-Version den genauen Quellcode online nachschlagen.
Wiederverwendung von Stack-Slots
Eine der Optimierungsfunktionen besteht darin, Stack-Slots für Variablen/Stack-Strukturen wiederzuverwenden, die keine überlappenden Zeitachsen haben. Variablen, die nicht gleichzeitig "live" sind, können denselben Stack-Speicherort gemeinsam nutzen, wodurch die Gesamtgröße des Stack-Frames reduziert wird. Im Wesentlichen ist eine Variable von dem Moment an, in dem ihr ein Wert zugewiesen wird, bis zum letzten Punkt, an dem auf diesen Wert zugegriffen werden kann, live. Dies macht die dekompilierte Ausgabe verwirrend, da derselbe Speicheroffset an verschiedenen Stellen unterschiedliche Typen oder Werte enthalten kann.
Um dies zu handhaben, können wir Vereinigungen definieren, die alle möglichen Typen umfassen, die den gleichen Speicheroffset innerhalb der Funktion teilen.
Rost-Fehlerbehandlung und Enumerationen
Rust-Enumerationen sind getaggte Unionen, die Typen mit mehreren Varianten definieren, die optional Daten enthalten und sich ideal für die Modellierung von Zuständen wie Erfolg oder Misserfolg eignen. Varianten werden durch eine Diskriminante (Tag) gekennzeichnet.
Fehlerbehandlungscode ist in der gesamten Binärdatei zu sehen und macht einen erheblichen Teil des dekompilierten Codes aus. Der primäre Mechanismus von Rust für die Fehlerbehandlung ist die Result<T, E> generische Enumeration. Es gibt zwei Varianten: Ok(T), das einen Erfolg anzeigt und einen Wert vom Typ Tenthält, und Err(E), das einen Fehler anzeigt und einen Fehlerwert vom Typ Eenthält.
Im folgenden Beispiel-Snippet wird der diskriminante Wert 0x8000000000000000 verwendet, um die Ergebnisse der Auflösung der CreateFileW -API zu unterscheiden. Wenn CreateFileW erfolgreich aufgelöst wurde, enthält der Variablentyp reuse den API-Funktionszeiger, und der else Zweig wird ausgeführt. Andernfalls wird der Zweig if ausgeführt und arg1eine Fehlerinformationszeichenfolge von reuse zugewiesen.
Weitere Informationen darüber, wie andere gängige Rust-Typen im Gedächtnis aussehen könnten, findest du in diesem Spickzettel und in diesem tollen Vortrag von Cindy Xiao!
Malware und MITRE ATT&CK
Elastic verwendet das MITRE ATT&CK-Framework , um gängige Taktiken, Techniken und Verfahren zu dokumentieren, die Bedrohungen gegen Unternehmensnetzwerke einsetzen.
Taktiken
Techniken
Techniken stellen dar, wie ein Angreifer ein taktisches Ziel erreicht, indem er eine Aktion ausführt.
- Phishing
- Einspeisung von Inhalten
- Befehls- und Skript-Interpreter
- Anmeldeinformationen aus Passwortspeichern
- User Execution
- Verschleierte Dateien oder Informationen
- Exfiltration über C2-Kanal
- Virtualisierung/Sandbox-Umgehung
Entdeckungen
YARA
Elastic Security hat die folgenden YARA-Regeln im Zusammenhang mit dieser Studie erstellt:
Regeln zur Verhaltensprävention
- Suspicious PowerShell Execution
- Übertragung des Eingangswerkzeugs über PowerShell
- Potenzielle Erkennung von Browserinformationen
- Potential Self Deletion of a Running Executable
Beobachtungen
Die folgenden Observablen wurden in dieser Studie diskutiert.
| Überwachbar | Typ | Name | Referenz |
|---|---|---|---|
47409e09afa05fcc9c9eff2c08baca3084d923c8d82159005dbae2029e1959d0 | SHA-256 | MvUlUwagHeZd.exe | EDDIESTEALER |
162a8521f6156070b9a97b488ee902ac0c395714aba970a688d54305cb3e163f | SHA-256 | :metadata (copy) | EDDIESTEALER |
f8b4e2ca107c4a91e180a17a845e1d7daac388bd1bb4708c222cda0eff793e7a | SHA-256 | AegZs85U6COc.exe | EDDIESTEALER |
53f803179304e4fa957146507c9f936b38da21c2a3af4f9ea002a7f35f5bc23d | SHA-256 | :metadata (copy) | EDDIESTEALER |
20eeae4222ff11e306fded294bebea7d3e5c5c2d8c5724792abf56997f30aaf9 | SHA-256 | PETt3Wz4DXEL.exe | EDDIESTEALER |
1bdc2455f32d740502e001fce51dbf2494c00f4dcadd772ea551ed231c35b9a2 | SHA-256 | Tk7n1al5m9Qc.exe | EDDIESTEALER |
d905ceb30816788de5ad6fa4fe108a202182dd579075c6c95b0fb26ed5520daa | SHA-256 | YykbZ173Ysnd.exe | EDDIESTEALER |
b8b379ba5aff7e4ef2838517930bf20d83a1cfec5f7b284f9ee783518cb989a7 | SHA-256 | 2025-04-03_20745dc4d048f67e0b62aca33be80283_akira_cobalt-strike_satacom | EDDIESTEALER |
f6536045ab63849c57859bbff9e6615180055c268b89c613dfed2db1f1a370f2 | SHA-256 | 2025-03-23_6cc654225172ef70a189788746cbb445_akira_cobalt-strike | EDDIESTEALER |
d318a70d7f4158e3fe5f38f23a241787359c55d352cb4b26a4bd007fd44d5b80 | SHA-256 | 2025-03-22_c8c3e658881593d798da07a1b80f250c_akira_cobalt-strike | EDDIESTEALER |
73b9259fecc2a4d0eeb0afef4f542642c26af46aa8f0ce2552241ee5507ec37f | SHA-256 | 2025-03-22_4776ff459c881a5b876da396f7324c64_akira_cobalt-strike | EDDIESTEALER |
2bef71355b37c4d9cd976e0c6450bfed5f62d8ab2cf096a4f3b77f6c0cb77a3b | SHA-256 | TWO[1].file | EDDIESTEALER |
218ec38e8d749ae7a6d53e0d4d58e3acf459687c7a34f5697908aec6a2d7274d | SHA-256 | EDDIESTEALER | |
5330cf6a8f4f297b9726f37f47cffac38070560cbac37a8e561e00c19e995f42 | SHA-256 | verifcheck.exe | EDDIESTEALER |
acae8a4d92d24b7e7cb20c0c13fd07c8ab6ed8c5f9969504a905287df1af179b | SHA-256 | 3zeG4jGjFkOy.exe | EDDIESTEALER |
0f5717b98e2b44964c4a5dfec4126fc35f5504f7f8dec386c0e0b0229e3482e7 | SHA-256 | verification.exe | EDDIESTEALER |
e8942805238f1ead8304cfdcf3d6076fa0cdf57533a5fae36380074a90d642e4 | SHA-256 | g_verify.js | EDDIESTEALER Lader |
7930d6469461af84d3c47c8e40b3d6d33f169283df42d2f58206f43d42d4c9f4 | SHA-256 | verif.js | EDDIESTEALER Lader |
45.144.53[.]145 | IPv4-ADDR | EDDIESTEALER C2 | |
84.200.154[.]47 | IPv4-ADDR | EDDIESTEALER C2 | |
shiglimugli[.]xyz | Domain-Name | EDDIESTEALER C2 | |
xxxivi[.]com | Domain-Name | EDDIESTEALER C2 und intermediäre Infrastruktur | |
llll[.]fit | Domain-Name | EDDIESTEALER Zwischeninfrastruktur | |
plasetplastik[.]com | Domain-Name | EDDIESTEALER Zwischeninfrastruktur | |
militrex[.]wiki | Domain-Name | EDDIESTEALER Zwischeninfrastruktur |
Referenzen
In der obigen Studie wurde auf Folgendes Bezug genommen:
- https://github.com/N0fix/rustbinsign
- https://github.com/Meckazin/ChromeKatz
- https://github.com/hasherezade/tiny_tracer
- https://docs.binary.ninja/dev/uidf.html
- https://www.unicorn-engine.org/
- https://github.com/LloydLabs/delete-self-poc/tree/main
- https://cheats.rs/#memory-layout
- https://www.youtube.com/watch?v=SGLX7g2a-gw&t=749s
- https://cxiao.net/posts/2023-12-08-rust-reversing-panic-metadata/
