Recently, Peter Van Eeckhoutte introduced a new heap spraying technique that works against multiple browsers such as Internet Explorer 8, 9, 10, as well as the latest Firefox.Â I am pretty much convinced this technique may change the way we write browse exploits for Metasploit, so I decided to port Peter’s example to Metasploit as a new function (with his assistance), and show you fellas an example on how to use it.
In this demonstration, I’ll just use Internet Explorer 10 on Windows 8.Â Please make sure to enable script debugging in IE during development.Â The debugger we’ll be using is WinDBG, which can be downloaded here:
|shellcode||The shellcode code to spray.Â As an example, the input should be in this format:Â unescape(“%u4141%u4141″).Â Usually this means a ROP, plus the shellcode.|
|objId||Optional.Â The ID for a
|offset||Optional.Â Padding to align the shellcode to some address you want.Â The default is 0×104 bytes.|
|heapBlockSize||Optional. The allocation size you want.Â Please note: if this size is too small, your shellcode will not remain at a predicable location in memory.Â Default is 0×80000.|
|maxAllocs||Optional. Number of allocations.Â Please note: On IE10, if this is too low, then the shellcode won’t be predicable enough, either.Â The “sweet spot” in our experiment for now seems to be somewhere above 0×500.Â The default value is 0×350.|
You may also download the test case here to try the heap spraying function:
In Internet Explorer, each iteration should generate two allocations that contain our data — one happens when the substring() function is called, but this one will eventually get freed.Â The other one is when the data is being assigned to the property, which will trigger a call to SetStringProperty (or SetProperty in IE9), and the data remains in memory.Â All allocations can be found in the default process heap.
When the heap spray is done, you can simply do this in the debugger:
WinDBG should give you a list of allocations under the default process heap, something like this:
Since the default value for heapBlockSize is 0×80000, and the default for maxAllocs is 0×350, it’s evident that our spray is working properly.Â To dump all these allocations, simply do:
And then you will see something liket his:
Notice all the heap entries end with XXXXXX18, which looks like a predictable pattern.Â When the allocation pattern is predictable, that indicates your payload should remain in a predicable location, too.Â Now, to inspect the data, here’s what you can do…. let’s pick the last entry:
You will see that this points to a field of 0x20s, that means we’re looking at the junk padding of the spray.Â At this point you’re probably wondering where the data is, right?Â One simple thing you can do in WinDBG is go to “View” -> “Memory”, and then enter the heap entry address (in our case, again, it’s 0x2b108018), and that’ll show you a nice memory dump which allows you to scroll up/down to find your data.Â Like this:
As a reference, the default spray should also land your data at address 0×20302228 in Internet Explorer, but you’ll need around 0×500 iterations for IE 10 just to make sure.Â We have also learned that address 0x0c0d0228 seems to be a reliable place, too.Â In Firefox, the same data can be seen at 0×20302210.Â To experiment this yourself, you may simply gather test results and compare them by using mona.py.
“js_property_spray” can also be used to manipulate LFH (Low-Fragmentation Heap) allocations.Â I recommend to read up Chris Valasek’s paper on “Understanding the Low Fragmentation Heap” before trying it out yourself.
To try out this new technique, please make sure to update your Metasploit repository to get the latest changes.Â If you’ve never tried Metasploit before, you can download it here: