Somebody once said..

"If you convince people that the wheel isn't right, they will allow you to re-invent it"

Wednesday, July 13, 2011

Quick look into CVE-2011-1255 Microsoft IE Time Element Memory Corruption vulnerability

Microsoft patched this vulnerability in June’s Patch Tuesday, but as usual an exploit has emerged for it. The M86 Security team stumbled upon an exploit in the wild and they have already done an excellent job of covering the exploit vector. I fired up Malzilla and decided to dig a little bit deeper to see how the exploit works.

This is a use-after-free vulnerability that is exploited using standard Heap spraying techniques and injected into the browser using a iFrame. Initially, it might seem confusing due to the obfuscation but its pretty straight forward to understand once we break it down into 4 parts -

  1. The Trigger
  2. The vulnerability
  3. Shell code
  4. Heap Spray & Main exploit

Trigger :

There are 4 functions that act as a trigger to the exploit – SetCookie(), GetCookie(), GetCookieVal() and DisplayInfo()

image

The exploit is designed to run only a couple of times in a day and this check is done with the help of client side cookies. So, the above functions are used to check the cookie. Since, the exploit was related to the Time element, initially I thought that the DisplayInfo() function was related to that, but that is not case. After the check is done, the JavaScript then calls eecc(), which is main function that exploits the vulnerability.

The Vulnerability :

According to the Microsoft Advisory MS11-050, the vulnerability is present in the way Internet Explorer attempts to access an HTML Time element object that has not been initialized or has been deleted.

But first, what is this Time element functionality ? – MSDN says:

HTML+TIME (Timed Interactive Multimedia Extensions), first released in Microsoft Internet Explorer 5, adds timing and media synchronization support to HTML pages. Using a few Extensible Markup Language (XML)-based elements and attributes, you can add images, video, and sounds to an HTML page, and synchronize them with HTML text elements over a specified amount of time.

Removing the shellcode and clearing up the script, with a few trial and errors I was able to create the PoC that will trigger the vulnerability -

image

The bug seems to be present in handling of freed up Time element objects. Line numbers #1 and #2 define the HTML time2 behaviour whereas #4 is the declaration of the “div” attribute that is used for associating the time2 functions.

Using JavaScript, #8 tries to free up this object and then #9 reloads the whole page. I think, this is where the memory corruption occurs and IE is not able to handle the objects properly giving us chance to reuse the allocated memory for the freed up object – hence the “use-after-free” title.

Note that all the above lines are required to reproduce the vulnerability including the Transition Filter definitions. According to the MS advisory IE 6,7 and 8 are vulnerable to this.

Shellcode :

Now that we know what the vulnerability is, achieving remote code execution is done by using standard Heap spraying techniques. But before we jump to that, there is an interesting obfuscation techniques deployed by the author of this exploit for aligning the shell code.

image

Just immediately after <div> tag, its easy to notice the blob of shellcode. However, if you look closely there are demarcations used for defining the boundaries in capital letters like “MM” or “NN”. So, while it may appear to be a single chunk of  shellcode, there are actually multiple parts of it.

image

Functions de(), codebk() and getdata() do the job of retrieving the shellcode in proper format. Normally, Shellcode is part of JS functions and obfuscation is done using bunch of math functions and eval calls but this technique of retrieving shellcode is pretty unique and I haven’t seen it before.

Removing the DOM references and modifying function getdata() as shown below, we can easily retrieve the proper shellcode using Malzilla’s JS engine or simply by running in the browser itself.

function getdata(a,b){

    var blob = “MMu9090u9090u10EBu4B5BuC933uB966u03F9u3480uE20BuFAE2u05E…”

//Truncated for sake of brevity. Put the entire shellcode text starting from MM to UU without spaces

    var aa=blob.indexOf(a);
    var bb=blob.indexOf(b);
    var temp="";
    temp=blob.substring(aa+2,bb);
    return temp;   
}
var sc = getdata("MM", "NN");
var ls = getdata("LL", "UU");
var block = codebk(getdata("TT", "KK"));
var pad = codebk(getdata("JJ", "LL"));
var base = codebk(getdata("XX", "YY"));
var s = getdata("OO", "PP");

document.write("SC="+sc);
document.write("\nLS="+ls);
document.write("\nBlock="+block);
document.write("\nPad="+pad);
document.write("\nBase="+base);
document.write("\nS="+s);

Using the modified getdata() and rest of the functions, we can easily print out the various parts of the shell code. The function codebk() and de() are just used to covert it into proper unicode format and unescape the Shell code.

Now, this post is turning out much longer than I thought, so I will cover the shell code probably in some other part, but from my basic dynamic analysis it looks like it drops a binary to a disk and executes it, which in-turn downloads further malware from the exploit hosting site itself.

Heap Spray and main exploit function :

Coming to the main function – eecc() - this is where all the magic happens. Once you substitute the various variables shown above and compare this with any standard Heap spraying code, you will immediately notice the similarities.

image

I wont spend to much time on Heap-spraying technique (Google it !) but most of it is pretty straight forward.

image

Initially, the function checks the value of the “User-Agent” string to detect the Browser version from which the page was accessed. Looks like the exploit was designed for IE 8.0, so If the browser is IE 8.0, the script proceeds with the exploit and gets all the Shellcode in the variables.

image

This is part which sprays the shellcode all over the heap. Next, the time element object is freed and page is reloaded triggering the memory corruption as we have already seen.

That’s it ! Some clever obfuscation tricks and a heap spray will get you malware installed on your system in no time. At this point, I don’t see anyone having a compelling reason to use Internet Explorer, but IE Fan boys should upgrade to the latest version of IE to remain safe, at least for the time being ;)

Sunday, July 10, 2011

Blocking Ultrasurf

As part of maintaining Application Recognition signatures, I often get asked by customers if we have support for blocking Ultrasurf – the free proxy based anonymizer tool that is often (miss)used for bypassing content filters in enterprises.

Unfortunately, blocking this over Network using IPS signatures is not possible since the traffic is encrypted. There has been good amount of analysis done on this and many alternative solutions have been proposed – like blocking DNS requests or connections to its servers. But most of the times its not practical to keep blocking IP’s & DNS requests, especially to something like docs.google.com.

The only way to block this thing effectively is from the end host or the Desktop on which it runs. But even that is tricky as the application itself is just one Executable and is not dependant on any registry or file information.

So, using my Ninja windows Batch scripting skillz I came up with this simple one liner which kills the application if found running on the host -

@for /f "tokens=5 delims= " %%i in ('netstat -ano -p tcp ^| find "127.0.0.1:9666"') do Taskkill /F /PID %%i

The way this command works is by looking for the process that listens port TCP 9666 on the “localhost” (127.0.0.1) which the application uses by default and then killing it. As of this writing, in the latest version this port number is hard coded and cannot be changed. Effectively, this little command when fired from a batch file will prevent Ultrasurf from running on the end host. All that needs to be done is to add a schedule task that runs this batch file every min.

So, till Ultrasurf releases a new version that can let user configure the local listening port, this should work like a charm ! :)