lunes, 21 de junio de 2010

The so called Return Oriented Programming...

Dear Diary,
I always hate the name Returned Oriented Programming, not because it might be an accurate name but just cause it sounds like they are reinventing the wheel once again. Paraphrasing aeschylus sometimes i think the offensive security is just bread crumbs from the great banquet of the end of the 90's hackers.
Anyway, recently I have to teach a class in Norway, the group of students was very smart which always help you push further and further. The last day, as part of our advance stack overflow class, we teach them how to write a ROP shellcode and go the next step and write their automatically tool.
Obviously, one day is not much to write your own tool, but was enough to write their shellcode which I'm proud to said it was half the size of the public exploit I saw.
Since the term start getting over-hyped, I think in a way it make it look far and harder. But thinkings of way to teach it in a class, makes me realize how simple it is. You see some exploits going for the most complicated solutions while the simple ones are shorter and more accurate sometimes.
So let me give you some hints, which are part of the Advance Stack Overflow class at Immunity:

The first step before start writing a ROP shellcode is to plan the strategy ahead, else you will be improvising in the middle of your shellcode and the consequences are going to be just ugly.

Here are some bulletpoints of what you should be thinking ahead before starting your shellcode:

  1. Restriction Bypass
    As we know, the trick behind ROP is that you are basing all your return values on one or two dlls whose base is known by you, either by an infoleak or just lack of REBASE flag.
    With that in mind, you need to find out which API functions are being imported (statically or dinamically) in order to find out how you are going to bypass it.

    There are probably a bunch more, you just need to use your imagination. A recently paper from Brett Moore, make me realize you can use the same trick too.
    Let said you don't have access to any of those API functions, so as you see, the field to play with is very small, an interesting way to potentially bypass it will be by using GlobalAlloc, or any kind of heap wrapper.
    When we call any of those functions with normal size, it will returns us a memory chunk. With the address of the memory chunk we can easily obtain the Heap Segment (usually the LSB are zero). Once you get the Heap Segment, you can grab the address of the PHEAP from it and change the permission flag into EXECUTABLE HEAP. Then the next step will be to force a second allocation of a big size such as it's going to use VirtualAlloc and make it Executable. Voila!
  2. Which registers we control?
    a) Can we control the content to all the registers (In Immunity Debugger a good way to check it, is just to get a POP R32/RETN)
    b) Exchange / Move between registers: All kind of combinations and flavour, whether is just a “MOV RA, RB” , “OR RA, RB” or “XCHG RA, RB”. And so on... Swapping with ESP is always important.
    c) Register logic: Look for different types of register logic, this will allow you to later bypass bad characters restrictions. (NEG R32, etc)
  3. Memory Access Instruction
    You most likely will be doing a lot of READ / WRITE operations, thats the main point of the so called ROP.
    MOV [R32], R32
    MOV R32, [R32]
  4. CPU Context
    Very important to reduce the amount of dwords used, always check if there is more than just ESP pointing to the controlled buffer.

Exploiting 101

The main trick to make ROP very simple (if we can really called it a trick), is just generate a parallel stack for calling functions. The parallel stack if needs to be created on a known address (if possible, which most of the time it is, else we can use ESP itself), if you know the base address of your dll, you most of the times can calculate the address of the .data (RW) section. That's a good spot to start creating your parallel stack (There are static RW pages at the same address along all version of Windows, but that is an exercise for the readers).

In the exercise we were exploiting on class, we were able to respond to all of the questions in the strategy, we have VirtualProtect imported, all the registers could be written with whatever we want, we were able to xchg with the stack , all kind of combinations of memory READ and WRITE and finally EBP was pointing to our stack.

pop R32/ ret // All the registers
mov [ecx], eax / ret // Write to ECX
mov eax, [ecx] / ret // Read from ECX
mov [eax], ebp / ret // Write to EAX content of EBP
xchg eax, esp // Exchange eax with ESP
neg eax // To bypass character restrictions

With that combination, creating the parallel stack to call VirtualProtect on our stack was trivial:
We just need to get the address of VirtualProtect, copy into the parallel stack and start writing all the arguments of VirtualProtect in the parallel stack, for the address to “unprotect” we used the stack itself taken from EBP, the other arguments were just trivial to craft. At the end, you xchg ESP with your parallel stack that will execute VirtualProtect (with the same ret2libc trick you were using) and later jump back to the stack, this time to actually execute your shellcode.


MOV EAX, [ECX] // EAX now holds the address of VirtualProtect
MOV [ECX], EAX // Paralel Stack : 0: [ VirtualProtect ]
MOV [EAX], EBP // Paralel Stack: 8 [ Address of Stack ]
NEG EAX // EAX= 0x2000 Bypassing bad characters
DATA + 0xC // ECX = DATA + 0xC
MOV [ECX], EAX // Paralel Stack : C: [ Size: 0x2000 ]
-0x40 // EAX = -0x40
NEG EAX // EAX = 0x40
DATA + 0xC // ECX = DATA+0xC
MOV [ECX], EAX // Paralel Stack : 0x10: [ Flag: 0x40 ]
DATA + 0x10 // ecx = data+0x10
DATA + 0x60 // eax = data+0x60
MOV [ECX], EAX // Paralel Stack : 0x14: [ OldProtect: Writeable addres in data ]
DATA // eax = data

At this point in code, where we change switch to a parallel stack that it will look like:

[ VirtualProtect ]
[ XXXXXXXX      ]
[ Stack addr      ]
[ 0x2000            ]
[ 0x40                ]
[ DATA +0x60   ]

When the new parallel stack get executed, it will call VirtualProtect on our stack address and later return to XXXXX (I didn't set it, but that should be your stack :)


Once you get shellcode execution, you should go back to your very simple primitives and try to sequence of opcode that do what you one in less step, like a combination of POP or multiple memory access. Always keep in mind that the less return addresses you have, the easy to port and make universal (?).
The lesson learned is that a rop shellcode can easily be understood and written as a series of calls, read and writes instructions. 
At the end, this is nothing more than the old school return to libc, I recommend to read Pablo's 2008 presentation about DEPLIB  for ideas on how to write your own ROP tool.
Sorry for the lack of images or screenshot, but i'm actually should be spending all my free time getting my research done for Blackhat.

The picture on this post was taken by Igor Siwanowicz

viernes, 26 de marzo de 2010

(A)leatory (P)ersitent (T)hreat

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

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.
VariantChangeTypeEx called with the same source and destination

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

VariantClear will decrement the reference counter or free the object

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', p);
e.setAttribute('s', t);
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 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.

Bypassing DEP
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 );

As you can see from the msdn description, we have two interesting thing, first the "this" object which is usually the first thing we have pushed on the stack and we also have the bstrName, which is the function name that we want to call. Javascript is flexible enough to allow us to do:

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.
Some ideas:

If you are precise enough, you will have defeat randomess and will have a proper shell:

sábado, 20 de marzo de 2010

BlueHat Security Forum 2010 - Argentina

Dear diary,
I'm finally back into blog writing. The main reason why I stop is pretty much everyone else reason: lack of time. Although time is still a precious asset, i found some time to write this entry.
Two days ago, Microsoft finally made BlueHat for the very first time in Argentina. It is a great honour as an Argentinian still living in the country, to have Microsoft decide that we are a strategic point to extend the conference outside the US. Andrew Cushman told me its the second time they do it outside Redmond, they have a first experience in Brussels which was a bittersweet experience, but he said they learn from that experience and they renew the hopes in Argentina.
Their strategy this time was to blend the latinamerican CSO/CTO with the researchers community. Spotting who was who, was just a simple visual exercise: Suits vs tshirt.

The kicking point to archive this almost impossible objective (The Microsoft Security team has a past of choosing high objective that they commonly archive) was a round table lead by Andrew which a bunch of well-known researchers (FX, Damian Hasse, Manuel Caballero, Rodrigo Rubira Branco, Ivan Arce, Luiz Eduardo and me) with the title "Hackers and You". The idea was great, sadly, we run out of time to discuss and expose all the different flavours from such a broad topic.
I believe there are four main points made, not only in the round table but in BlueHat in general.

o Offensive security is a key part of enterprise security. Microsoft understood this looong time ago and act greatly upon it. No matter the size of your bussiness, If you ever stop considering the offensive part of the security, you will end up without strategy and simply relying on your IDS/IPS/Firewall/AV devices, that quoting FX presentation "its a very very very *bad* idea".
o Security needs to be consider in every step of your business cycle. The Microsoft presentation were very clear on that subject.
o Hire researchers for your team and make them happy. Certifying them with theoretical exams (study/take the test/immediately forget) won't make them either happy or help them secure your network. Talk to them, research on practical training and let their creative spirit fly a bit (on controlled environments).
o Prevention is prediction. This subject briefly came from a very smart question of a conference attendee to the panel, she said "having all this new technique and tricks, seems that prevention gets old". Ivan have enough time to reply saying that prevention models can be correctly designed, which i totally agree. Prevention models became prediction models. Prediction needs not to be understand as the result of a lucky cookie but rather how the philosopher Ricoeur understand the term futurology (bad translation of the term from my part): Understanding and trying to win yards on randomness. And this is where in my opinion, offensive security help you go the extra mile along with the great researchers we have on that area, they know how to hack and help you understand current and future out of the box risks.

Finally, there was an interesting presentation by Kristen Dennesen and Anchises de Paula on the Latin American vulnerability market. I had high expectation about this presentation, because i want to see how they focus this subject having to face a more executive crowd (Pedram did a great job at the ekoparty, but that was more focused on researchers).
They did a very nice job, i have the feeling that they have at least three presentations in one, so as an attendee i was thirsty for more information on the each of them but due the lack of time they couldn't go where i want. But again, this was an executive crowd. The subject in my understanding of their presentation were: Vulnerability Market in Latin America, New security legislation and their impact on the security scene and the security threats in latinamerica.
Luckily Bluehat encourage the corridor and bar discussion, which usually allows you to talk with the presenters, exchange opinion and get the backstage information.

In summary, great conference, glad too get together with old and new friends. Kudos to Celene, Katie, Mike, Mark, Damian and Andrew for putting together such a great conference. I'll be looking for more next year.

PS: My favourite presentation was Hernan Ochoas "5 minutes to explain the 14-year old unpatched SMB bug", which was fast, fun and with great content.

PS2: Fede present a very nice draft of what is going to be our future Hackerspace in Buenos Aires, i'm in the group that is trying to push this project and we hope we can gave the big news soon.