NWHStealer Verbreitung durch Bun JavaScript Runtime
Detection stack
- AIDR
- Alert
- ETL
- Query
Zusammenfassung
Der Artikel erklärt, wie Bedrohungsakteure die Bun-JavaScript-Laufzeit nutzen, um den Rust-basierten Infostealer NWHStealer zu verbreiten. Bösartige ZIP-Archive enthalten einen Hauptinstaller, der einen Bun-verpackten JavaScript-Loader zusammen mit einem sekundären Loader namens dw.exe startet. Die JavaScript-Komponente führt Anti-Virtualisierungstests durch, greift auf die Kommando-und-Kontroll-Infrastruktur zu, entschlüsselt eine Folge-Payload und missbraucht native Windows-APIs, um den Stealer in den Speicher zu injizieren. Um Verdacht zu reduzieren, versteckt die Kampagne bösartige Dateien hinter legitimen Hosting-Plattformen wie GitHub, MediaFire und SourceForge.
Untersuchung
Forscher fanden heraus, dass Bun verwendet wurde, um bösartigen JavaScript-Code innerhalb des .bun -Abschnitts des Loaders zu verpacken. Zwei Skripte, sysreq.js and memload.js, behandelten Umgebungstests und die Kommunikation mit der Angreifer-Infrastruktur. Der Loader rief Konfigurationsdaten und verschlüsselte Payloads von Domains wie silent-harvester.cc ab, entschlüsselte sie mit AES-256-CBC und injizierte sie durch Win32-API-Aufrufe. Die endgültige Payload war der NWHStealer, der Anmeldeinformationen, Browserdaten und Kryptowährungs-Wallet-Informationen stiehlt und auch zusätzliche Mining-Aktivitäten starten kann.
Abmilderung
Benutzer sollten das Herunterladen von ausführbaren Dateien von nicht vertrauenswürdigen Websites vermeiden und Installationssignaturen vor der Ausführung überprüfen. Sicherheitsteams sollten ungewöhnliche Aktivitäten der Bun-Laufzeit, PowerShell-CIM-Abfragen, die für Virtualisierungstests verwendet werden, und verdächtige API-Aufrufe wie VirtualAlloc and LoadLibraryA überwachen. Organisationen sollten auch die bekannten bösartigen Domains blockieren und Mindestprivileg-Ausführungsrichtlinien durchsetzen, um Missbrauch zu begrenzen.
Reaktion
Wird diese Aktivität entdeckt, sollte der betroffene Endpunkt isoliert, Speicher- und Festplatten-Images gesammelt und nach Installer.exe, dw.exe und verdächtigen .bun Abschnitten gesucht werden. Blockieren Sie die identifizierten Kommando-und-Kontroll-Domains und URLs an der Netzwerkperipherie. Implementieren Sie Endpunkt-Erkennungen für die beobachteten PowerShell-Befehle und Win32-API-Muster. Erneuern Sie exponierte Anmeldeinformationen und überwachen Sie betroffene Systeme auf Anzeichen von unbefugtem Kryptowährungs-Mining.
graph TB %% Klassendefinitionen classDef technique fill:#ffcc99 classDef action fill:#99ccff %% Knoten node_initial_access[„<b>Initialer Zugriff</b><br/><b>T1036.008 Verschleierung: Dateityp</b>: Schädliches ZIP, als harmlose Datei getarnt.<br/><b>T1204.002 Benutzerausführung: Schädliche Datei</b>: Der Benutzer führt die heruntergeladene Datei aus.“] class node_initial_access technique node_obfuscated_loader[„<b>Obfuszierter Loader</b><br/><b>T1027.016 Junk-Code-Einfügung</b>: Einfügen irrelevanten JavaScripts zur Verschleierung der Logik.<br/><b>T1027.008 Entfernung von Payload-Teilen</b>: Entfernen nicht essenzieller Teile zur Analyseumgehung.“] class node_obfuscated_loader technique node_discovery[„<b>Aufklärung</b><br/><b>T1082 Systeminformationen sammeln</b>: Betriebssystem-, Hardware- und Softwaredaten.<br/><b>T1016 Netzwerk-Konfigurationsaufklärung</b>: IP-Adressen, Adapter und Routing-Informationen.“] class node_discovery technique node_credential_access[„<b>Credential Access</b><br/><b>T1555.003 Browser-Zugangsdaten</b>: Extraktion gespeicherter Passwörter und Autofill-Daten.<br/><b>T1550.004 Nutzung alternativer Authentifizierungsdaten</b>: Diebstahl von Session-Cookies.“] class node_credential_access technique node_c2[„<b>Command & Control</b>: Abruf eines AES-Schlüssels und verschlüsselter Payload vom Remote-Server.“] class node_c2 action node_execution[„<b>Ausführung</b><br/><b>T1620 Reflektives Code-Laden</b>: Ausführung im Speicher ohne Festplatten-Schreibzugriff.<br/><b>T1055.009 Prozessinjektion</b>: Einschleusen von Code in laufenden Prozess.“] class node_execution technique node_persistence[„<b>Persistenz</b><br/><b>T1053 Geplante Aufgabe</b>: Erstellung einer geplanten Aufgabe zur wiederholten Ausführung.“] class node_persistence technique %% Verbindungen node_initial_access –>|führt zu| node_obfuscated_loader node_obfuscated_loader –>|führt zu| node_discovery node_discovery –>|führt zu| node_credential_access node_credential_access –>|führt zu| node_c2 node_c2 –>|führt zu| node_execution node_execution –>|führt zu| node_persistence
Angriffsablauf
Erkennungen
Verdächtige Kommando-und-Kontrolle durch ungewöhnliche Top-Level-Domain (TLD) DNS-Anfrage (via DNS)
Ansicht
Mögliche Umgehungsprüfungen (via PowerShell)
Ansicht
Mögliche versuchte IP-Lookup-Domain-Kommunikationen (via DNS)
Ansicht
IOCs (HashSha256) zur Erkennung: Angreifer nutzen JavaScript-Laufzeit Bun, um NWHStealer zu verbreiten
Ansicht
Erkennung des NWHStealer JavaScript Loaders Selbsteinjektion [Windows-Prozesserstellung]
Ansicht
Erkennung der NWHStealer Anti-Virtualisierung PowerShell-Befehle [Windows PowerShell]
Ansicht
Simulationsausführung
Voraussetzung: Der Telemetrie- & Baseline-Pre‑flight-Check muss bestanden haben.
Begründung: Dieser Abschnitt beschreibt die genaue Ausführung der gegnerischen Technik (TTP), die darauf abzielt, die Erkennungsregel auszulösen. Die Befehle und das Narrativ MÜSSEN direkt die identifizierten TTPs widerspiegeln und darauf abzielen, die genaue Telemetrie zu erzeugen, die von der Erkennungslogik erwartet wird. Abstrakte oder nicht verwandte Beispiele führen zu Fehldiagnosen.
-
Angriffs-Narrativ & Befehle:
- Erster Zugriff: Der Angreifer liefert eine bösartige JavaScript-Datei (
loader.js) auf das Opfersystem und führt sie mit der bun Laufzeit (bun loader.js). - Selbsteinjektionsroutine: Der JavaScript-Code ruft native Win32-APIs über einen PowerShell-Helfer auf, der Add‑Type verwendet, um P/Invoke-Signaturen zu definieren für
VirtualAlloc,VirtualProtect, undLoadLibraryA. - Speicherallokation:
VirtualAllocreserviert eine RWX-Region in der Größe für den eingebetteten Shellcode. - Shellcode-Injektion: Das PowerShell-Skript kopiert den base64-codierten Shellcode in den zugewiesenen Speicher mit
Marshal.Copy. - Berechtigungsänderung:
VirtualProtectändert den Seitenschutz in PAGE_EXECUTE_READ. - Payload-Ausführung:
LoadLibraryAwird auf eine bösartige DLL angewendet, die nur im Speicher residiert (der DLL-Header wird in die zugewiesene Region geschrieben, dann wird die Adresse anLoadLibraryA). - Kein neuer Thread: Der Angreifer vermeidet bewusst den Aufruf von
CreateThread; DllMain der DLL wird im Kontext des aktuellen Prozesses ausgeführt, was die Ausschlussklausel der Regel erfüllt.
- Erster Zugriff: Der Angreifer liefert eine bösartige JavaScript-Datei (
-
Regressionstest-Skript:
# ------------------------------------------------- # NWHStealer JavaScript Loader – Selbsteinjektionsdemo # ------------------------------------------------- # Dieses Skript imitiert das Verhalten des echten NWHStealer-Loaders. # Es ruft absichtlich VirtualAlloc, VirtualProtect und LoadLibraryA # auf, ohne CreateThread zu verwenden. # 1. Win32-API-Signaturen definieren $sig = @" using System; using System.Runtime.InteropServices; public class Win32 { [DllImport("kernel32.dll", SetLastError=true)] public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect); [DllImport("kernel32.dll", SetLastError=true)] public static extern bool VirtualProtect(IntPtr lpAddress, uint dwSize, uint flNewProtect, out uint lpflOldProtect); [DllImport("kernel32.dll", CharSet=CharSet.Ansi, SetLastError=true)] public static extern IntPtr LoadLibraryA(string lpFileName); } "@ Add-Type $sig # 2. Ausführbaren Speicher zuweisen (RWX) $size = 0x1000 $MEM_COMMIT = 0x1000 $PAGE_EXECUTE_READWRITE = 0x40 $mem = [Win32]::VirtualAlloc([IntPtr]::Zero, $size, $MEM_COMMIT, $PAGE_EXECUTE_READWRITE) if ($mem -eq [IntPtr]::Zero) { throw "VirtualAlloc failed" } # 3. Beispiel-Shellcode (MessageBox) – base64-codiert zur besseren Lesbarkeit $b64 = "AQAAANAAAABAAEAAAABAAAAAgAAAAEAAABWAAAAAQAAAAIAAAD/////AQAAAAAAAAA=" $shellcode = [Convert]::FromBase64String($b64) # 4. Shellcode in zugewiesenen Bereich kopieren [System.Runtime.InteropServices.Marshal]::Copy($shellcode, 0, $mem, $shellcode.Length) # 5. Schutz auf EXECUTE_READ ändern $oldProtect = 0 $PAGE_EXECUTE_READ = 0x20 $ok = [Win32]::VirtualProtect($mem, $size, $PAGE_EXECUTE_READ, [ref]$oldProtect) if (-not $ok) { throw "VirtualProtect failed" } # 6. Die im Speicher befindliche "DLL" laden (hier rufen wir einfach LoadLibraryA auf kernel32 als Platzhalter auf) # Im echten Loader wäre dies eine benutzerdefinierte DLL, die in $mem geschrieben wurde. $hLib = [Win32]::LoadLibraryA("kernel32.dll") if ($hLib -eq [IntPtr]::Zero) { throw "LoadLibraryA failed" } Write-Host "Selbsteinjektionsschritte abgeschlossen – Der Prozess sollte jetzt von der Erkennungsregel gekennzeichnet werden." # ------------------------------------------------- -
Bereinigungskommandos:
# Beenden Sie die PowerShell-Instanz, die die Injektion durchgeführt hat Stop-Process -Id $PID -Force # (Optional) Wenn eine benutzerdefinierte DLL zum Testen auf die Festplatte geschrieben wurde, entfernen Sie sie Remove-Item -Path "$env:TEMPmalicious.dll" -ErrorAction SilentlyContinue
Post-Execution Validierung
-
Alarmgenerierung bestätigen: Führen Sie die folgende KQL-Abfrage aus, um zu überprüfen, ob die Regel ausgelöst wurde:
// Erkennungsregel: VirtualAlloc/VirtualProtect/LoadLibraryA ohne CreateThread Sysmon | where EventID == 1 | where CallTrace contains "VirtualAlloc" or CallTrace contains "VirtualProtect" or CallTrace contains "LoadLibraryA" | where not(CallTrace contains "CreateThread") | project TimeGenerated, Process, CallTrace, EventID -
Keine False-Positiv bestätigen: Führen Sie den harmlosen Notepad-Befehl erneut aus und stellen Sie sicher, dass die Abfrage null Ergebnisse für diesen Lauf zurückgibt.
Ende des Berichts