A few days ago, I was wondering how one could teach himself heap-based overflow exploitation.
So I searched through documentation, subsequently practicing what I read in order to have a better insight of how the heap works under Linux.
We are told that the malloc() / free() function works around Doug Lea's memory allocator but, in spite of the great explanation given by the link, I cannot figure things out as I debug my program.
Given this example:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int n = 5;
int main(int argc, char** argv) {
char* p;
char* q;
p = malloc(1024);
q = malloc(1024);
printf("real size = %d\n",*(((int*)p)-1) & 0xFFFFFFF8);
if(argc >= 2) {
strcpy(p, argv[1]);
}
free(q);
printf("n = 0x%08X\n", n);
free(p);
return EXIT_SUCCESS;
}
I would like to dump this structure in memory:
struct chunk {
int prev_size;
int size;
struct chunk *fd;
struct chunk *bk;
};
Here is my workflow:
geo@lilith:~/c/vuln_malloc$ gcc -o vuln vuln.c -m32 -ggdb
geo@lilith:~/c/vuln_malloc$ gdb ./vuln
GNU gdb (GDB) 7.4.1-debian
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/geo/c/vuln_malloc/vuln...done.
(gdb) b 21
Breakpoint 1 at 0x804850f: file vuln.c, line 21.
(gdb) r `perl -e 'print "A" x 1024'`
Starting program: /home/geo/c/vuln_malloc/vuln `perl -e 'print "A" x 1024'`
real size = 1032
Breakpoint 1, main (argc=2, argv=0xffffd414) at vuln.c:21
21 free(q);
(gdb) x/10x q-4
0x804a40c: 0x00000409 0x00000000 0x00000000 0x00000000
0x804a41c: 0x00000000 0x00000000 0x00000000 0x00000000
0x804a42c: 0x00000000 0x00000000
(gdb)
Here I can see the size-field's value, which is 0x409. I can easily guess that the real size of my chunk is 0x409 & 0xFFFFFF8 = 0x408 = 1032, as explained by the documentation (the three least significant actually define some flags). Then I run until the free() function is processed.
(gdb) b 22
Breakpoint 2 at 0x804851b: file vuln.c, line 22.
(gdb) c
Continuing.
Breakpoint 2, main (argc=2, argv=0xffffd414) at vuln.c:22
22 printf("n = 0x%08X\n", n);
(gdb) x/10x q-4
0x804a40c: 0x00020bf9 0x00000000 0x00000000 0x00000000
0x804a41c: 0x00000000 0x00000000 0x00000000 0x00000000
0x804a42c: 0x00000000 0x00000000
Firstly I don't understand the new value - 0x20bf9 - at all, secondly I don't understand why there isn't any relevant values as regard the fd and bk pointers either.
All of that stuff does not make much sense for me, that's why I was wondering wether you could give me some clues about all of this or not. Does the Doug Lea's implementation still exist in recent glibc versions, or...?