Showing posts with label reversing. Show all posts
Showing posts with label reversing. Show all posts

10/17/2008

Fandango on free()

I apologize for the delay in keeping this blog updated. As I was working in the solution for the 9th level of the Advanced Buffer Overflows challenge I had some serious troubles with the different implementations of Doug Lea's Malloc (dlmalloc from now on) management system which I thought would do for a good article. Althought the solution for abo9 is in its final stages, I'll elaborate on the heap implementation this time.

Lots of good articles have been already written in this subject (Which I'll link at the end of this post for anyone that's interested) but with the versions I was using in my VMs as lab I had more than one headache(In fact, vulnerable versions of glibc seem to be already patched in SuSE versions 9.X. In my case switching to Red Hat 9.0 did the job). None of the popular papers seemed to work in my case, hence, I decided to dig myself in the inner workings of this dynamic memory allocation system. Instead of explaining a C implementation I went for a Reverse Code Engineering approach which turned as follows. In this post I won't explain the inner workings of dlmalloc, that's already been nicely documented in other papers such as Vudo - An object superstitiously believed to embody magical powers by Michel "MaXX" Kaempf, hence I'll avoid any reference to that.

The function in question is free() which takes care of freeing a used chunk once we have finished our work with it. free() is actually a wrapper around _int_free() which does the real job. _int_free() makes some checks and then makes use of the unlink() macro to unlink two adjacent chunks and join them to create a larger one. You can get the interesting part of the disassembly of _int_free() here.

At address 0x42074464 it loads the pointer to the chunk we want to free into the edi register. In 0x4207446b loads the address of the prev_size field of the buf2 buffer into ecx. Right in the next intruction the contents of size field of buf2 are copied into eax. After check int the arena struct we jump to 0x420744a0 at 0x42074481. In the next two instructions it checks wether or not the 2nd least significant bit of the size field is enabled and if it is(which is not our case) it jumps to another region within _int_free().

Now is where the fun part for exploitation begins. At 0x420744ad, we calculate the address of the next chunk using our address + the prev_size field of buf2 (which we can control overflowing the first buf1) and store it in eax, which can now contain the address of the prev_size of a fake chunk we can create. In the next instruction we load the size field of our fake chunk into edx. After some saving into local variables, some 8 byte boundary roundings and a PREV_INUSE checks, we arrive to 0x420744c8. Here we load in eax the prev_size of buf2 and in the next instruction we store in ecx the address of buf2's prev_size minus the prev_size of buf2 itself. This hypothetically would get us the previous chunk's prev_size address but since we manipulated buf2's prev_size we can make it go wherever we want.

So, since ecx now points to the prev_size of our fake chunk, let's talk a little bit about the unlink() macro. This macro basically swaps the fd and bk fields of unused chunks to make the use of free space in memory more efficient and to avoid fragmentation. Being a macro as it is, is compiled inline with the rest of the code and, since doesn't provide any sanity checking it'll swap some addresses we control with information we control allowing us to overwrite 4 bytes wherever we want in memory with the information we want. You can see unlink() in action in address 0x420744cd, 0x420744d2, 0x420744d5 and 0x420744d8. From then on the function continues his normal path as the damage has already been done.

Well that's it. I'll talk about exploitability and it's techniques in the next post. If anybody felt this was quite messy to follow I apologize; I understand it's a difficult matter (at least it was for me :P) but I hope somebody else learned something from this. I also hope I can bring a final solution for abo9 in the upcoming days. As promised I include some references to previous works in the topic here:

7/21/2008

Book Review: Reversing, Secrets of Reverse Engineering.

Even thought I have some more solutions for the Advanved Buffer Overflow Challenges in the line, today I come with a different kind of article. This time I'll be reviewing one of the latest additions to my shelf: "Reversing, Secrets of Reverse Engineering" by Eldad Eilam. As every experienced hacker knows, understanding of the lowest and most-inner workings of a program sometimes goes throught analizing it's low level code representation and the most basic interaction with the underlaying OS.



From my experience, the documentation available in the net is often either very specific or largely outdated, hence I decided to give a shot to a all-in-one physical format like a book. I don't regret it a second. I knew the book since some time ago, It's been around since 2005, but I never felt it would report much to what I needed at the time. I couldn't be more wrong. Lately I've been trying to take a look at real life vulnerability code in order to get away from artificial yet educational exploitme-like situations. Most of the time the environment used to be Windows in a 32bit environment, which fortunately is documented on the web. Still, it takes a trained eye to recognize vulnerable portions of code in a sea of mov's,lea's and cmp's. A hands-on reversing lesson was on demand.

At first I was a bit reluctant to the book, the initial chapters are just refreshers for some basic architecture and tool knowledge which is handy considering the solid base they make for the rest of the book. After that it goes to reversing a group of windows undocumented APIs; basic training to recognize C/C++ structures and functions. Then it moves to the topic that interest's us the most: Binary Auditing.

It makes for a good help to pay a visit to our old overflow friends and taking a look at how the look under the cover. The chapter also makes a detailed analysis of the famous IIS Unicode Bug that worked as launchpad to the also known CodeRed worm.

After that came one of the chapters that I had the most fun reading, mostly because I had no previous exposure to it: Malware Analysis. Using a Trojan as example it goes to understand it's internals. Isolated virtual environment is a MUST for this :)

From then on the book continues his way throught cracking, anti-cracking and some protection schemes. Mention deserved to the last chapters dealing with virtual machine based languages using Microsoft's very own .NET platform as example which seemed to me as lightening for other languages such as Java. The book gets completed with 4 Appendixes that make for good reference sections for future reversing sessions.

All in all, a great book, a must have, one of those that takes more than the others to get outdated because not only shows hands-on experience but also shows the path to follow for upcoming techniques developed in the area. After all, reversing is a tool that many different research areas benefit from in greater or lesser way.