I'm reading Shellcoder's Handbook to learn more about exploitation and overflows. I reached the chapter on Heap Overflows. The book mentions that a heap is split into chunks where each chunk contains two important pieces of info:
- The size of the previous chunk, if allocated
- Size of current chunck
- Data
The following image is taken from a Blackhat presentation
I made a small demo to test this. Below is the code:
1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4
5 int
6 main (int argc, char *argv[]){
7 char *buf, *buf2;
8
9 buf = (char *) malloc(1024);
10 buf2 = (char *) malloc(1024);
11
12 printf("buf=%p\n", buf);
13 printf("buf2=%p\n", buf2);
14 strcpy(buf, argv[1]);
15 strcpy(buf2, argv[2]);
16 printf("buf=%s\n", buf);
17 printf("buf2=%s\n", buf2);
18 free(buf2);
19 return 0;
20 }
I've placed a breakpoint on line 18 and checked the memory. Here's the dump after running the following command:
./basicheap $(python -c 'print("A"*1000 + " " +"XXXXABCDEFGH")')
This is the memory dump of buf1
:
[0x08048543]> pxw 0x50 @ [fcnvar.local_1ch]-8
0x0804b158 0x00000000 0x00000411 0x41414141 0x41414141 ........AAAAAAAA
0x0804b168 0x41414141 0x41414141 0x41414141 0x41414141 AAAAAAAAAAAAAAAA
0x0804b178 0x41414141 0x41414141 0x41414141 0x41414141 AAAAAAAAAAAAAAAA
0x0804b188 0x41414141 0x41414141 0x41414141 0x41414141 AAAAAAAAAAAAAAAA
0x0804b198 0x41414141 0x41414141 0x41414141 0x41414141 AAAAAAAAAAAAAAAA
This is the memory dump of buf2
:
[0x08048543]> pxw 0x50 @ [fcnvar.local_20h]-8
0x0804b568 0x00000000 0x00000411 0x58585858 0x44434241 ........XXXXABCD
0x0804b578 0x48474645 0x00000000 0x00000000 0x00000000 EFGH............
0x0804b588 0x00000000 0x00000000 0x00000000 0x00000000 ................
0x0804b598 0x00000000 0x00000000 0x00000000 0x00000000 ................
0x0804b5a8 0x00000000 0x00000000 0x00000000 0x00000000 ................
The output shows 0x411
as the size of the both chunk, which is 1024 + 17 bits for whatever. This is the the first (and only) piece of information in the header for both chunks.
However, I don't see any info relating to any previous chunks. In Shellcoder's, the author is trying to demonstrate how one can overflow buf1
to overwrite the header info of buf2
.
Did the writers of glibc forgo the size of previous chunk in the header info, or is it something I'm missing?
P.S: The build command I used was gcc -no-pie -g basicheap.c -o basicheap