I am learning about heap overflow attacks, but I am encountering a problem. Based on the knowledge I found online and my own guesses, I believe that a heap overflow attack involves overwriting metadata in the heap, such as a pointer to a function, to execute the code that the attacker wants to run. However, when I use GDB to inspect memory allocated by malloc, I find that the header of the heap only contains the size allocated by malloc, And the footer only contains the remaining available size. Why???
Here is the process I followed to inspect the memory: source c:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char const *argv[])
{
char *buf,*buf2;
buf=(char*)malloc(1024);
buf2=(char*)malloc(1024*2);
free(buf2);
strcpy(buf,argv[1]);
printf("Done.");
return 0;
}
- compile:
gcc heap2.c -o heap2 -g
- Start gdb:
┌──(kali㉿kali)-[~/Desktop/book_c]
└─$ gdb heap2
GNU gdb (Debian 15.2-1+b1) 15.2
Copyright (C) 2024 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".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from heap2...
(gdb)
- Setting a breakpoint in main:
(gdb) b main
Breakpoint 1 at 0x1178: file heap2.c, line 8.
(gdb)
- run:
(gdb) run AAAAAAAA
Starting program: /home/kali/Desktop/book_c/heap2 AAAAAAAA
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Breakpoint 1, main (argc=2, argv=0x7fffffffdd88) at heap2.c:8
8 buf=(char*)malloc(1024);
(gdb)
- Executing the n command to let malloc allocate memory
(gdb) n
9 buf2=(char*)malloc(1024*2);
(gdb)
- View memory
(gdb) x/32wx buf-32
0x555555559280: 0x00000000 0x00000000 0x00000000 0x00000000
0x555555559290: 0x00000000 0x00000000 0x00000411 0x00000000
0x5555555592a0: 0x00000000 0x00000000 0x00000000 0x00000000
0x5555555592b0: 0x00000000 0x00000000 0x00000000 0x00000000
0x5555555592c0: 0x00000000 0x00000000 0x00000000 0x00000000
0x5555555592d0: 0x00000000 0x00000000 0x00000000 0x00000000
0x5555555592e0: 0x00000000 0x00000000 0x00000000 0x00000000
0x5555555592f0: 0x00000000 0x00000000 0x00000000 0x00000000
(gdb)
Why only one size? I guess that the metadata might be at the end, so I inspected the memory at the end of the allocated block.
(gdb) x/32wx buf-32+0x00000411-1
0x555555559690: 0x00000000 0x00000000 0x00000000 0x00000000
0x5555555596a0: 0x00000000 0x00000000 0x00020961 0x00000000
0x5555555596b0: 0x00000000 0x00000000 0x00000000 0x00000000
0x5555555596c0: 0x00000000 0x00000000 0x00000000 0x00000000
0x5555555596d0: 0x00000000 0x00000000 0x00000000 0x00000000
0x5555555596e0: 0x00000000 0x00000000 0x00000000 0x00000000
0x5555555596f0: 0x00000000 0x00000000 0x00000000 0x00000000
0x555555559700: 0x00000000 0x00000000 0x00000000 0x00000000
(gdb)
There are no pointers at all!!!! Why????
So, I guessed that the first allocated block might be special. I continued to inspect the next allocated block.
Execute the n command
(gdb) n
11 free(buf2);
(gdb)
Inspect the header of the block.
(gdb) x/32wx buf-32+0x00000411-1
0x555555559690: 0x00000000 0x00000000 0x00000000 0x00000000
0x5555555596a0: 0x00000000 0x00000000 0x00000811 0x00000000
0x5555555596b0: 0x00000000 0x00000000 0x00000000 0x00000000
0x5555555596c0: 0x00000000 0x00000000 0x00000000 0x00000000
0x5555555596d0: 0x00000000 0x00000000 0x00000000 0x00000000
0x5555555596e0: 0x00000000 0x00000000 0x00000000 0x00000000
0x5555555596f0: 0x00000000 0x00000000 0x00000000 0x00000000
0x555555559700: 0x00000000 0x00000000 0x00000000 0x00000000
(gdb) x/32wx buf2-32
0x555555559690: 0x00000000 0x00000000 0x00000000 0x00000000
0x5555555596a0: 0x00000000 0x00000000 0x00000811 0x00000000
0x5555555596b0: 0x00000000 0x00000000 0x00000000 0x00000000
0x5555555596c0: 0x00000000 0x00000000 0x00000000 0x00000000
0x5555555596d0: 0x00000000 0x00000000 0x00000000 0x00000000
0x5555555596e0: 0x00000000 0x00000000 0x00000000 0x00000000
0x5555555596f0: 0x00000000 0x00000000 0x00000000 0x00000000
0x555555559700: 0x00000000 0x00000000 0x00000000 0x00000000
(gdb)
There are still no pointers at all!!!! Why????
So, I made another guess and executed free(buf2). I hope this will give me some clues.
(gdb) n
12 strcpy(buf,argv[1]);
(gdb)
head:
(gdb) x/32wx buf2-32
0x555555559690: 0x00000000 0x00000000 0x00000000 0x00000000
0x5555555596a0: 0x00000000 0x00000000 0x00020961 0x00000000
0x5555555596b0: 0x00000000 0x00000000 0x00000000 0x00000000
0x5555555596c0: 0x00000000 0x00000000 0x00000000 0x00000000
0x5555555596d0: 0x00000000 0x00000000 0x00000000 0x00000000
0x5555555596e0: 0x00000000 0x00000000 0x00000000 0x00000000
0x5555555596f0: 0x00000000 0x00000000 0x00000000 0x00000000
0x555555559700: 0x00000000 0x00000000 0x00000000 0x00000000
(gdb)
end:
(gdb) x/32wx buf2-32+0x00000811-1
0x555555559ea0: 0x00000000 0x00000000 0x00000000 0x00000000
0x555555559eb0: 0x00000000 0x00000000 0x00020151 0x00000000
0x555555559ec0: 0x00000000 0x00000000 0x00000000 0x00000000
0x555555559ed0: 0x00000000 0x00000000 0x00000000 0x00000000
0x555555559ee0: 0x00000000 0x00000000 0x00000000 0x00000000
0x555555559ef0: 0x00000000 0x00000000 0x00000000 0x00000000
0x555555559f00: 0x00000000 0x00000000 0x00000000 0x00000000
0x555555559f10: 0x00000000 0x00000000 0x00000000 0x00000000
(gdb)
I have no clues....
Is this because GDB has some limitation? Or is there another reason?
Of course, the most important thing is how heap overflow attacks are implemented? How can I reproduce this attack?
malloc. One is to record the size of each allocation in the bytes preceding the allocation, and thenfreecan easily find that size and link the allocation back into the database. This method does not require there be any pointers in or near the allocated memory. Another way to implementmallocis to keep a bitmap of fixed-size blocks that have been allocated within a region, using different regions for different sizes of allocations…freecan look them up. Which of these implementations ofmallocare you using? You should identify the specific implementation of the C standard library you are using. And be aware that any sort of exploit on one is not likely to work the same way on another.