http://kingofdkingz99.blogspot.com/2013/03/new-heap-spray-technique-for-metasploit.html
Browser
vulnerabilities have always been serious threats in today's security
trends. It's almost becoming too common to see people dropping browser
0days to beef up botnets, or deploying them for "sophisticated"
APT-level attacks, etc. Although browser 0days surface more frequently
than ever, some of the techniques don't seem to change much. The most
common trick you'll see is a
heap spray
-- this is a way to setup memory by controlling heap allocations, and
then place arbitrary code in a predictable place. That way when you
control the crash, you can just trick the program to go there and gain
code execution. However, this technique has gotten more difficult over
the years, so a typical heap spray you see in IE6 and 7 probably won't
work against IE8. And a spray in IE 8 probably won't work in IE9 and
10.
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.
Environment
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:
http://msdn.microsoft.com/en-us/windows/hardware/gg463009.aspx
Code Example
The
new heap spraying routine is written in JavaScript. In order to use
this, make sure to include the "Msf::Exploit::Remote::HttpServer::HTML"
mixin, and then simply call the "
js_property_spray"
routine, which will return the sprayHeap() code that you can embed in
your webpage. The sprayHeap() function supports the following
parameters:
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
HTML tag. If you don't supply this parameter,
then the JavaScript will just generate a "div" element for you.
|
offset | Optional. Padding to align the shellcode to some address you want. The default is 0x104 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 0x80000. |
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 0x500. The default
value is 0x350. |
You may also download the test case here to try the heap spraying function:
https://gist.github.com/wchen-r7/89f6d6c8d26745e99e00
Examine the Heap Spray
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:
!heap -stat -h
WinDBG should give you a list of allocations under the default process heap, something like this:
Since
the default value for heapBlockSize is 0x80000, and the default for
maxAllocs is 0x350, it's evident that our spray is working properly. To
dump all these allocations, simply do:
!heap -flt s 0x80000
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:
db 2b108018
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
0x20302228 in Internet Explorer, but you'll need around 0x500 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 0x20302210. 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:
http://www.metasploit.com/download/
Source:
Rapid7