Below is an example of obfuscated malicious Web content.
Using an alternative method to a simulator, we're able to start up a browser, hook in our decoder hook, and watch the deobfuscation output in a debug view window. Of course this is done in a VMWARE machine.
So how does the Ultimate Deobfuscator work?
The Ultimate Deobfuscator works by starting up a real instance of Internet Explorer and injecting a dll into its process space. That dll then hooks various functions that we care about, like document.write and eval.
I'm releasing the code (with zero guarantees of support) for you to look at and play with, but let's go over how it works.
First, all the addresses that are hooked are hard-coded. That means that the document.write that I'm hooking in mshtml.dll and the eval in jscript.dll have to be the same versions on your machine for them to work. If they're not, you'll have to change the code a little bit.
Again for the purpose of simplicity, I've hooked only document.write and eval. After opening up the dlls that they're present in (mshtml.dll and jscript.dll) and downloading the symbols, you'll easily be able to find them.
For document.write we're just going to install our detours style hook at the beginning of the function, because the buffer we're interested in is passed in as an argument to the function.
For eval it's a bit more complicated. The buffer we want to output isn't passed in as an argument; it's computed in the middle of the function. So we'll want to hook in the middle of a function in a place that allows us to write over 5 bytes.
Once we're found the addresses we're going to hook, 0x437350EA for document.write and 0x6339A085 for eval, we start writing our code.
The detoured eval function will save the state of the registers, call our own jseval to print out the buffer, and then call the real jseval function. The one complication in this function is that, because we had to hook js eval in the middle of the function, we had to choose a safe place to overwrite 5 bytes. Those 5 bytes fell on a move ebx, [ebx + 8].
So in our detoured function, we have to make sure to execute that instruction, since it had been overwritten. We also want to push ebx to the stack, because by looking at the disassembly, we can see that's where the buffer we want to print out is.
The code for the detoured document.write is even simpler. The buffer we're interested in is held in a safearray, and because the arguments to document.write can be a string (or even an integer), we have to print out the correct type.
The code makes a lot more sense if you look at the full source code. But the last two things to take care of are (1) making sure our hard-coded addresses that we want to hook are defined, and then (2) having a hook function.
Since I wrote most of this code for the presentation knowing I'd be giving it out, I used a few open source and free utilities. I use DLLInject to inject the DLL into a process, and I use XDE v1.01 by Z0MBie.
Good luck! If you have any additions or fixes to that code, feel free to email them to me, and I'll make sure to keep the code updated. I'll also make sure to list out any contributors.
Thanks to: Moti Joseph (who helped me write most of this code) and Derek Soeder for suggestions.
Security Researcher: Stephan Chenette