The Random House Dictionary defines aleatory as:
2. of or pertaining to accidental causes; of luck or chance; unpredictable: an aleatory element.
I will stay with accidental causes, or just plain luck to describe the exploit that was found on the wild for the CVE-2010-0806 vulnerability a couple of weeks ago. The bug is nothing more than 0day found on the wild attached with your favourite trojan (Zeus in this case) that works against Internet Explorer 6-7.
The bug class is what we known as a use-after-free, that means that at some point some object is freed but we continue use it. A good example of this bug class on a non-browser was the 2001 globbing capabilities bug on wu-ftpd that people cleverly exploit (yes, pretty much everything was done by 2001).
In the case of CVE-2010-0806 (a.k.a. ie_peers), the bug is on an old DHTML featured called behaviours "DHTML behaviors are components that encapsulate specific functionality or behavior on a page".
The bug itself is when trying to persist an object using the setAttribute, which end up calling VariantChangeTypeEx with both the source and the destination being the same variant. So if you send as a variant an IDISPATCH the algorythm will try to do a VariantClear of the destination before using it. This will end up on a call to PlainRelease which decref the reference and clean the object.
Mark dowd, the internet security oracle already talk about those kind of potential bugs here: bh2009_dowd_smith_dewey.pdf
Pertaining to accidental causes
When i first read the chinese/russian exploit, i was thrill on how it really works. Specially since my conception of a use-after-free was:
1) free the object
2) allocate memory to fill it
3) Use it
Well, my conception of a use-after-free remains the same, but the on-the-wild exploit was just relying on the mystery of heap randomness to make this exploit execute shellcode.
The exploit first do a common heap spray with shellcode and later just run the use-after-free trying to free the window object and later just wait the lord to work in mysterious ways and 1/10 times execute shellcode. This is what we called in Immunity: pray-after-free.
The exploitation mechanism of a use-after-free is very simple, everything that was free need to be allocated with something we control. You can use every resource you want, just be sure that whatever you are allocating, it has to be on the exact same heap.
Another important decision is what to free. The public exploit use the window global which to me looks like something that could be potentially use it before we fill it. That's why creating your own element is always recommend it.
var p = document.createElement("BODY");
Creating our own element also gave us a very good idea of the reference count of the object, instead of just looping 10 times, we just call setAttribute on the createdElement.
On the TEAROFF classes, such as the Elements returned by document.createElement it does the decref through the PlainRelease. This function has 2 dword where it cache the thunk before actually free it.
We need to do two more setAttribute, in order to take p out of the cache and call MemFree.
e.setAttribute('s', w); // In this VarClear call, is when it actually going to free the chunk.
The Element objects are allocated on the default heap, so our soft-memleak needs to be on the same heap. Strings are allocated through SysAllocateLen which end up on the default heap as explained by Sotirov's Heap Feng Shui but (there is always a but...) jscript String had the length as the first dword, which on our object is a vtable pointer, exactly what we want to control.
Object Chunk that need to be filled (The alerted readers will notice that the chunk is a Low Fragmentation Heap chunk).
In CANVAS exploit, we use XMLHttpRequest.open() but there are many tricks like @WTFuzz document.createElement(‘div’).className
The next step is finding the exact size of the chunk, so we can allocate our object and replace the vtable.
Trigger the bug is trivial. Whatever function we want to call on the free object it will try to do a IDispatch->GetDispID and that will use the modified vtable. The next step for a good boyscout is to transform a function pointer execution into ret2libc. To do that we need to move a buffer we control to ESP.
GetDispID is a very interesting function:
HRESULT GetDispID( BSTR bstrName, DWORD grfdex, DISPID *pid );
The "this" object is also under our control since it's the buffer that we use on the use-after-free.
Triggering the vulnerability. In this case, i set the bstrName as "getElement" but could be transformed into whatever we want.
Now is just a matter of finding the correct piece of code in order to pop the first or the 2nd dword from the stack.
If you are precise enough, you will have defeat randomess and will have a proper shell: