MS11-002 Pwn2Own heap overflow

Today Microsoft patched the heap overflow I used in pwn2own 2010. The vulnerability was a int wrap during heap allocation. The small allocation was later used to store a bit more information then would fit in there.

More specifically:

<XML ID="xmlid1">

Inside an HTML file would give you access to what is called an XML Data Island. This is actually acts as an database interface. You can query the XML data, retrieve rows and data and add more rows. The underlying object is an MSAdo object.
The db objects exposes a property called ‘CacheSize’ that you can use to determine how many records it should keep in its cache. Internally the CacheSize is multiplied by 0x4 and then 0x10 is added (I am typing this from memory so I might be a bit off, but the rough data is correct).

By specifying a big size for the CacheSize property an intwrap will occur and there will only be a small amound of memory reserved to hold the data. The data being stored in the CacheSize buffer is the row number of the cashed row.
You can add rows to the Cache by calling functions that move you through the records, like ‘MoveFirst’, ‘MoveNext’ or similar methods. It will ofcourse not write more record numbers to the cache then there are available.
So you can reliable overflow as much bytes as you want by adding new records and issuing a command that moves to the next records to cache it. I had best success with the MoveFirst method.

The cache buffer resides in a ‘private’ heap and not in the default IE8 heap so the normal heapspray technics dont work. Since I wanted to use this vulnerability to bypass ASLR I needed to find some way to elevate this into information disclosure. On the private heap the buffer resides there are also some C++ Objects and Strings.
I overwrote the \00\00 bytes of one of the strings on the heap to get the vtable address of one of the objects on the heap that gave me enough information to know the location of msado.dll in memory, and that was all I needed for a DEP evasion trick.

To overwrite the \00\00 byes of the string you do need a rather high record number, ie: higher then 0x00010001. I simply added and removed enough records untill I had reached that number. I removed them because I didnt want to write 0x00010001 records all to the cache at once.

When you have increased the record number high enough you can lay a string on the heap and then write enough records to the cache to overwrite the \00\00 string termination bytes. If you then read back the string in javascript you can glance at the memory that is located behind the string. If you dont find what you want there (your string will still terminate on the next \00\00 sequence) you can simply add another record and write that to the cache as well until you find what you are looking for.

This will of course require you to layout the heap in the right order: [cachebuffer][string][objects] I managed to do this and it was working and stable when I ran it on the pwn2own machine, but it is probly specific for only one exact IE8 & Windows 7 patch level so dont be too suprised if the POC does not work right away.

A little trick I did find out was the fact that you can create ‘holes’ in the private heap by specifying a certain CacheSize for an XML Data Island and then closing the RecordSet. This allows some control over the heap layout.

Also: I only used the heap overflow for the information disclosure, but there are enough options to turn this into RCE, at least for WinXP, and maybe also for Windows 7. But for the actual RCE I used a use-after-free bug that has been patched a few months ago:

I have several versions of the exploit on my HD and I have no idea which was the final version that actually worked, so I just dump one out here.
Also: the DEP evasion that I used is based in the msado.dll version that was shipped with W7 at the time of pwn2opwn, and basically did a VirtualProtect call on my Aligned heap spray and turned it executable.

Remember, this is the raw code, and it was written when I was pretty busy so it is both ugly, inefficient and probably full of weird variable names. Also, it needs Alex Sotirovs heapLib.js to run.

My original pwn2own paper

Comments (8)

SrblcheJanuary 12th, 2011 at 21:57

Each day Windows fails!

Great work author!

Crabore NumbnutsJanuary 20th, 2011 at 4:33

Nice work.

SecurityXplodedJanuary 20th, 2011 at 19:30

Good one,

Thanks for sharing !

GApril 19th, 2011 at 9:02

why aways execute :alert(‘sadly we failed to read the base address of msado15.dll :( ‘);
my pc is xp Pro,SP3,IE7

ClarkJuly 29th, 2011 at 9:54

Werkt niet bij mij….

Foutdetails webpagina

Gebruikersagent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Win64; x64; Trident/4.0; .NET CLR 2.0.50727; SLCC2; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C)
Tijdstempel: Fri, 29 Jul 2011 07:51:48 UTC

Bericht: Onvoldoende opslagruimte beschikbaar om deze bewerking te voltooien.
Regel: 65
Teken: 3
Code: 0

softproerAugust 9th, 2011 at 15:37

Thanx for sharing!
here and at pwn2own!

secmanOctober 18th, 2011 at 8:03

thank you, share the full code!

K_KOctober 31st, 2011 at 12:55

THX for sharing!

Leave a comment

Your comment

Spam protection by WP Captcha-Free