Heap Overflow Issue - Can Overwrite Chunk Header, Corrupt Free(), But Program Doesn't Crash


I have been studying computer vulnerabilities and have been working on this problem for countless hours. I cannot seem to get the heap to overflow correctly. Despite glibc detecting a memory corruption, after disabling MALLOC_CHECK_ my program executes and exits correctly as if overwriting the chunk header didn't matter. I am running Kubuntu 12.04.

This exercise is from "The Shellcoder's Handbook, 2nd Edition" and is also featured on Heap Overflow tutorials online. I have followed the instructions to a T multiple times and have received the same result.

Here is the code of my program:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, char ** argv){

    char *buf;
    char *buf2;

printf("buf=%p buf2=%p\n", buf, buf2);

when I write past the buffer with glibc on:

xxx@xxx-xxx:~/CProgs$ ./basicheap $(perl -e 'print "A"x1028')
buf=0x9356718 buf2=0x9356b20
*** glibc detected *** ./basicheap: double free or corruption (!prev): 0x09356b20 ***
======= Backtrace: =========
======= Memory map: ========
08048000-080ec000 r-xp 00000000 08:07 6816172    /home/xxx/CProgs/basicheap
080ec000-080ee000 rw-p 000a3000 08:07 6816172    /home/xxx/CProgs/basicheap
080ee000-080f0000 rw-p 00000000 00:00 0 
09355000-09377000 rw-p 00000000 00:00 0          [heap]
b772a000-b772c000 rw-p 00000000 00:00 0 
b772c000-b772d000 r-xp 00000000 00:00 0          [vdso]
bfc14000-bfc36000 rw-p 00000000 00:00 0          [stack]
Aborted (core dumped)

When I write past the buffer with glibc off:

xxx@xxx-xxx:~/CProgs$ MALLOC_CHECK_=0 ./basicheap $(perl -e 'print "A"x1028')
buf=0xa077718 buf2=0xa077b20

GDB of the Chunk header without overwrite:

(gdb) run $(perl -e 'print "A"x1024')
Starting program: /home/xxx/CProgs/basicheap $(perl -e 'print "A"x1024')
buf=0x80f1718 buf2=0x80f1b20

Breakpoint 1, main (argc=2, argv=0xbfffedf4) at basicheap.c:16
16      free(buf2);
(gdb) x/x buf2-4
0x80f1b1c:      0x00000409
(gdb) x/x buf2-8
0x80f1b18:      0x00000000
(gdb) x/x buf2-12
0x80f1b14:      0x41414141

GDB of the chunk header with overwrite:

(gdb) run $(perl -e 'print "A"x1032')
Starting program: /home/xxx/CProgs/basicheap $(perl -e 'print "A"x1032')
buf=0x80f1718 buf2=0x80f1b20

Breakpoint 1, main (argc=2, argv=0xbfffede4) at basicheap.c:16
16      free(buf2);
(gdb) x/x buf2-4
0x80f1b1c:      0x41414141
(gdb) x/x buf2-8
0x80f1b18:      0x41414141
(gdb) x/x buf2-12
0x80f1b14:      0x41414141

Both times the program exits normally. What am I missing? Did they change up how the heap works on the latest versions of Ubuntu? Any help would be greatly appreciated!

UPDATE: I have stepped through the assembly in gdb and have found that my program enters the function free_check() and the function mem2chunk_check().

In the mem2chunk_check() function, my overwritten value is picked up in the ESI register, and the EDI register points to the address of that value. The only thing I see it doing with my value in ESI is subtracting 1 and then dumping the value.

I have not been able to find any documentation on the mem2chunk_check() function after many google searches.

Are these heap overflows obsolete on modern systems?

asked on Stack Overflow Aug 9, 2012 by (unknown user) • edited Aug 9, 2012 by (unknown user)

2 Answers


In the last few years, vendors have defaulted to using the 'fortified' versions of any memory manipulating function. For instance, instead of memset you get 'builtin_memset_chk', instead of strcpy, you get 'strcpy_chk'

For your simple overflow program to work, you would have to build your program with:

-fno-stack-protector -D_FORTIFY_SOURCE=0
answered on Stack Overflow Aug 9, 2012 by dans3itz

First thing is that nowadays, heap exploitation in Linux is really hard. Well, it is easy to overwrite different buffers if they overflow, but the hard thing is to execute arbitrary code.

If you want to know the inner workings of heap exploitation you should read the papers I mentioned in this post: Use a heap overflow to write arbitrary data

Once you understand those concepts, I will warn you saying that most of the methods used/explained in malloc malleficarum were (silently) patched. I don't know if any of those still works today.

On the other hand, if you really want to improve your knowledge, I advice you to download the ptmalloc implementation (from http://www.malloc.de/en/) that is the one on which is based the allocator in Linux, compile it ("make shared", it is also useful to add the "-g" flag) and load it with LD_PRELOAD. This way you will be able to debug the malloc code with gdb, step by step.

Good luck!

answered on Stack Overflow Aug 27, 2012 by newlog • edited May 23, 2017 by Community

User contributions licensed under CC BY-SA 3.0