Heap exploitation notes part 1
“The heap is so hard, I don’t know from whom I should learn!”
Everytime I want to watch an action film I have the same problem - which is the most interesting film I would choose for this evening so I truly understand your pain. Heap exploitation is not so easy, especially in the beginning. What’s even worse - there’s a lot of stuff about heap exploitation on the Internet describing different complexity, details, architectures and examples etc. and you don’t know where to start. Tons of blog posts, YouTube films and courses. This “situation” in psychology has its own name - The Paradox of Choice. The Paradox of Choice written by American psychologist Barry Schwartz it’s some kind of a little Denial of Service in your head.
In this article I want to show you my point of view, what road I have covered to learn this amazing journey like Heap Exploitation.
Back to the cybersec
Let’s get back to cybersec stuff. - start slow and then run. I would like to introduce you two very beginning articles about heap exploitation that you should start first:
https://infosecwriteups.com/heap-exploitation-for-homo-sapiens-f166cd6a59fe
https://infosecwriteups.com/arming-the-use-after-free-bc174a26c5f4
If you are familiar with RISC exploitation architectures I recommend you to install buildroot to test examples from tutorials above. “Buildroot is a set of Makefiles and patches that simplifies and automates the process of building a complete and bootable Linux environment”.
This is just an summary of how you can debug malloc() function:
Debug malloc() function Cheat Sheet
...
array = malloc(size);
...
Hit a breakpoint one instruction after malloc() function.
...
<+64>: bl <__libc_malloc>
<+68>: mov bucket, water # —> breakpoint here!
...
Malloc returns an address to the data section:
malloc(2 * sizeof(unsigned int)) -> 2 * 4 bytes # address of data section -> 0x94d48 (R0)
Now, debug this address:
(gdb) x/10wx 0x94d44
4 bytes 4 bytes 4 bytes 4 bytes
header data data data
0x94d44: 0x00000011 0x00000000 0x00000000 0x00000000
0x94d54: 0x000212b1 0x00000000 0x00000000 0x00000000
0x94d64: 0x00000000 0x00000000
Explanation of chunk
header[4 bytes] + data[4 bytes] * 3 0x00000011 -> 0x10[hex][size] + 1[PREV: IN USE] = 16[dec] bytes + 1 = 0x11
Why 16 bytes? Minimum allocated memory block - 16 bytes (32bit sys)
16 in hex is 0x10, but our field contains 0x11. The extra one bit is from the flag “PREV: IN USE” which means that the chunk that is allocated from the heap is under usage. This will be set as we are using the current chunks. This is how the size becomes 0x11.
Another example
malloc(8 * sizeof(unsigned int)) -> 8 * 4 bytes -> 0x94d48 (R0)
(gdb) x/30wx 0x94d44
4 bytes 4 bytes 4 bytes 4 bytes
header data data data
0x94d44: 0x00000029 0x00000000 0x00000000 0x00000000
data data data data
0x94d54: 0x00000000 0x00000000 0x00000000 0x00000000
data data
0x94d64: 0x00000000 0x00000000 0x00021299 0x00000000
header[4 bytes] + data[4 bytes] * 9
0x00000029 -> 0x28[hex][size] + 1[PREV: IN USE] = 40[dec] bytes + 1 = 0x29 The same situation above.
One of the most important Tip
Take a few (at least 3 or 4) days for researching, nothing else. Seriously. It’s crucial to dive into this topic to better understand and REMEMBER how the heap works.