rosieblue
article thumbnail
728x90

House of Spirit

House of Spirit은 free함수의 인자를 우리가 원하는 값으로 보내서, 이 값에다가 재할당해서 AAW이나 AAR등을 할 수 있는 기법이다. 해당 기법으로 원하는 위치(Heap 영역이 아니어도 상관 x! 스택이나 다른 곳도 가능~~)에 청크를 할당하여 임의의 주소의 값을 알거나 덮을 수 있다!
 

예) free(main의 return address) - 이렇게 해서 return address overwrite 하기

위 예시와 같은 공격을 하기 위해서는 당연히 main의 return address를 알아야할 것이고 그렇다면 스택의 주소를 구하는 과정 또한 선행되어야겠다!
 

예시 1

// gcc -o spirit1 spirit1.c -no-pie

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

int main()
{
	long long fake_chunk[10] = {0,};
	fake_chunk[0] = 0;
	fake_chunk[1] = 0x31;
	fake_chunk[2] = 0x41414141;
    
	free(&fake_chunk[2]);
	char *fake_alloc = malloc(0x20);
    
	printf("fake chunk: %p\n", fake_alloc);
}

일단 free를 하기 전에 fake chunk을 만들어주었다. fake_chunk[1]에 가짜 사이즈 0x31을 넣어주었다!
사이즈를 조작해주지 않으면 오류가 나는데 그 이유는 아래에 적어놨다!! 알면 그냥 넘어가도 된다 (틀리면 제발 지적해주세여)
 

Fake Chunk을 만들어야 하는 이유

바로 free하면 오류가 난다! 이유?
_int_free함수에서는 아래와 같은 코드가 있어서 free 할 때 사이즈 검증을 한다!

#define MIN_CHUNK_SIZE        (offsetof(struct malloc_chunk, fd_nextsize))
#define MINSIZE  \
  (unsigned long)(((MIN_CHUNK_SIZE+MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK))
if (__glibc_unlikely (size < MINSIZE || !aligned_OK (size)))
{
  errstr = "free(): invalid size";
  goto errout;
}

_int_free 함수에서는 size가 MINSIZE보다 작거나 align이 이상할 경우 에러를 내뿜는다
따라서 size를 맞추고 align에 맞게 만들어줘야 한다.
 
또한 재할당할 때 malloc(0x20)이 있는데 여기서도 사이즈 검증을 한다.
아래는 _int_malloc 함수의 코드이다. 여기서는 할당하려는 청크의 크기와 할당될 영역의 크기를 구한 후 그 크기가 같은 bin에 속하는지 검증한다.

#define fastbin_index(sz) \
  ((((unsigned int) (sz)) >> (SIZE_SZ == 8 ? 4 : 3)) - 2)
idx = fastbin_index (nb);
if (victim != 0)
{
    if (__builtin_expect (fastbin_index (chunksize (victim)) != idx, 0))
    {
        errstr = "malloc(): memory corruption (fast)";
       errout:
        malloc_printerr (check_action, errstr, chunk2mem (victim), av);
        return NULL;
    }
}

위 예제 코드의 경우 만약 fake chunk을 통해 사이즈를 fastbin에 들어가는 사이즈로 조작해주지 않았다면 에러가 떴을 것이다.
 
사실 _int_malloc이랑 _int_free 내용은 내가 분석을 잘 안 해봐서 ㅠㅠ 다음에 포스트로 제대로 분석해서 다시 올리겠당.....
아무튼 위 이유때문에 fake chunk을 만들어야하는 것 같다(?)
 
 
아무튼 !!! 이렇게 size를 조작하면 예제의 아래 코드가 잘 실행된다.

	free(&fake_chunk[2]); //0x20짜리 이므로 tcache에 들어감
	char *fake_alloc = malloc(0x20); //tcache에 있는 fake chunk가 재할당됨

 
fake chunk가 stack에 속해있는데도 malloc을 통해 잘 할당된 것을 볼 수 있다!!

이처럼 House of Force 기법을 사용하기 위해서는 예제 코드와 같이 1)스택 주소를 알고, 2)해당 영역을 해제할 수 있어야 한다!
만약 해당 주소에 값까지 쓸 수 있다면 스택 내에 존재하는 다른 지역 변수나 리턴 주소를 바꿀 수 있게 된다! 이건 스택 예시지만 스택 뿐만 아니라 다른 영역도 가능할듯?
 

위 내용을 그림으로 표현한 것! (출처: 드림핵)

 
이걸 이용한 문제는 아래에 있다!

[드림핵(Dreamhack] house_of _spirit

hannahsecurity.tistory.com

profile

rosieblue

@Rosieblue

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!