Tuesday, December 16, 2008

SPAN, The Heap, and esoteric memory buggery…

Have you ever heard someone say they needed a pointer that pointed to itself and was also a nop? Maybe one they could write to? No? Where are you hanging out?

For the rest of you, I'll explain why this set of properties can be useful, and when you might want to make use of it. Now is a great time. The IE 0-day that's prancing around is a heap corruption bug which HD Moore explains here. The vulnerability allows you to overwrite an object pointer with four arbitrary bytes. In this case we don't get the true write-what-where you often end up with when you toast a chunk header, but that's okay – what you do get is just as useful. The object we control the pointer to contains within it a function pointer which is eventually called. Great. Ostensibly what we need to do is make a fake data structure in memory with a pointer to our shellcode in the place of the function pointer, then point the controlled pointer at this fake data structure.

Sadly, this is easier said than done when it comes to guessing where a 200 byte data structure might be in the heap of a crazy multi-threaded program like IE. It'd be easier if we could have kind of a NOP-sled to get to the data structure, and just aim for a general area. Obviously, this is impossible; we can't "slide" into our data structure because we're not executing, we have to hit it right on. Don't we?

Let's evaluate our goals. We'd like to be able to create:

  1. an arbitrary data structure that is simple to guess the address of reliably, and
  2. some chunk of shellcode we can also guess the address of and point the function pointer in #1 to

Another thing we could do is create our data structure in such a way that it needn't be aligned to work in the manner we'd like it to. If we could manage this, we'd only need to know approximately where it lives in memory. For this to be the case though, alignment can't matter – just like in a NOP-sled. One of the simpler ways this is accomplished is to find a single byte NOP (such as 0x90) and repeat it over and over. For this to be a valid solution to our problem, we'd have to be able to ensure that the address at which we stored our structure could also be used to store our shellcode, and additionally that returning into the pile of bytes which comprise the structure would not cause a fault. The later is necessary because the function pointer will point to nearly the same address as object itself. Thus, we will need a self referential pointer, which is also a NOP, is writable and executable, and is in a place we can write to arbitrarily. Quite a set of requirements!

Luckily, due to the grand work of others in the field this set of requirements is simple to check off in a web browser. Using javascript, we can force the allocation of an arbitrary amount of memory, filled with whatever we like simply by creating strings. This method, known as heap-spray will allow us to create a large area of memory filled with our fakey structure, as well as a place to store our shellcode.

Now, we can begin to look at what addresses are filled with our heap-spray to determine likely values to overwrite the object pointer. The values we're interested in will have the same value for all four bytes, ie. 0x01010101, 0x02020202 etc. such that we are not required to adhere to an alignment. They will also be NOPs in our particular case. Two common values used in IE heap exploitation are 0x0a0a0a0a and 0x0c0c0c0c which are easily allocated, and disassemble to or cl, [edx] and or al, 0xC respectively. (Note that for the 0x0a0a0a0a address to be viable, the edx register must contain a readable address at the time you take control.)

The live exploit makes use of the 0x0a0a0a0a address, filling it with 0x0a. At the end of a large chunk of these bytes, the shellcode is placed. The object pointer (ObjPtr) is overwritten with 0x0a0a0a0a. When its function pointer (FuncPtr) is called in the code, it too points to 0x0a0a0a0a. Since this byte was confirmed to be a NOP, execution continues merrily along until it runs head long into our shellcode.


 

    |0a0a0a0a|0a0a0a0a|0a0a0a0a|0a0a0a0a|0x0a0a0a0a … SHELLCODE

    ^ObjPtr         ^FuncPtr    

Right now I'm being berated for not having a conclusion here, because apparently hitting shellcode isn't the conclusion for everyone that it is for me. Therefore, (.)(.)


 

Add to Technorati Favorites Digg! This

No comments: