# Trigger double free to get shell # I. Source code - Trong quá trình giải các chall về heap thì tự nhiên mình bắt gặp 1 hiện tượng "lạ" : Khi mình gây lỗi DBF trên fastbin(với TH "fast top" ) thì vô tình lại gọi hàm trong __malloc_hook . Và mình đặt ra câu hỏi tại sao??? -> Chính vì vậy quyết định debug kĩ hơn đoạn này. - Source debug: ```clike #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <malloc.h> int main() { void *chunk = malloc(0x10); free(chunk) ; free(chunk) ; return 0; } // gcc chall.c -o chall ``` -> Chương trình mình sẽ build ở 2 phiên bản libc khác nhau để debug so sánh (tcache và fastbin) gồm : libc2.23 và libc2.27 # II. DEBUG ## 1. Glibc 2.27 < demo trên tcache > - Chạy thử ctrinh: ![image](https://hackmd.io/_uploads/rJZhfL9Wkl.png) - Chương trình băt đầu chạy và mình sẽ thay đổi __malloc__hook sau khi gọi malloc (tránh malloc gọi __malloc_hook) ![image](https://hackmd.io/_uploads/ByiIzIcWye.png) - Trước tiên hãy thử review qua [source code](https://elixir.bootlin.com/glibc/glibc-2.35/source/malloc/malloc.c#L4459): ```clike if (__glibc_unlikely (e->key == tcache_key)) { tcache_entry *tmp; size_t cnt = 0; LIBC_PROBE (memory_tcache_double_free, 2, e, tc_idx); for (tmp = tcache->entries[tc_idx]; tmp; tmp = REVEAL_PTR (tmp->next), ++cnt) { if (cnt >= mp_.tcache_count) malloc_printerr ("free(): too many chunks detected in tcache"); if (__glibc_unlikely (!aligned_OK (tmp))) malloc_printerr ("free(): unaligned chunk detected in tcache 2"); if (tmp == e) malloc_printerr ("free(): double free detected in tcache 2"); /* If we get here, it was a coincidence. We've wasted a few cycles, but don't abort. */ } } ``` -> Dựa vao output khi run binary và source thì mình sẽ debug từ `malloc_printerr ("free(): double free detected in tcache 2");` - Trong GDB (ở lần free thứ 2) ![image](https://hackmd.io/_uploads/HyM6A0t-yl.png) - Đọc source [malloc_printerr](https://elixir.bootlin.com/glibc/glibc-2.35/source/malloc/malloc.c#L5661) ```clike malloc_printerr (const char *str) { #if IS_IN (libc) __libc_message (do_abort, "%s\n", str); #else __libc_fatal (str); #endif __builtin_unreachable (); } ``` ![image](https://hackmd.io/_uploads/ryDlJ19byx.png) - hàm [__libc_message](https://elixir.bootlin.com/glibc/glibc-2.35/source/sysdeps/posix/libc_fatal.c#L57) ```clike ... if (nlist > 0) { struct iovec *iov = alloca (nlist * sizeof (struct iovec)); ssize_t total = 0; for (int cnt = nlist - 1; cnt >= 0; --cnt) { iov[cnt].iov_base = (char *) list->str; iov[cnt].iov_len = list->len; total += list->len; list = list->next; } WRITEV_FOR_FATAL (fd, iov, nlist, total); ... ``` -> Đây là đoạn trực tiếp in ra message cho mình ![image](https://hackmd.io/_uploads/SkKLf1qWyl.png) - Đến 1 hàm quan trọng khác là [abort](https://elixir.bootlin.com/glibc/glibc-2.35/source/stdlib/abort.c#L48) ![image](https://hackmd.io/_uploads/H16OGkc-yx.png) ![image](https://hackmd.io/_uploads/S12KfJcZkx.png) - Bên trong hàm abort thì chúng ta hãy quan tâm đên hàm [raise](https://elixir.bootlin.com/glibc/glibc-2.35/source/sysdeps/posix/raise.c#L24) ; hàm này sẽ gọi `__pthread_kill` và hàm này sẽ kill chương trình của mình ```clike raise (int sig) { int ret = __pthread_kill (__pthread_self (), sig); if (ret != 0) { __set_errno (ret); ret = -1; } return ret; } ``` ![image](https://hackmd.io/_uploads/SJuhqIcZJe.png) - Ta có thể dùng lệnh `backtrace` tromg pwndbg : ![image](https://hackmd.io/_uploads/rkjgo85WJg.png) ## 2. Glibc 2.23 < debug fastbin > - Debug tương tự như trên mình sẽ debug cùng với việc đọc source code libc :::info - Recommend sử dụng IDA để reverse + kết hợp GDB để tìm được hàm đúng( vì libc 1 hàm có thể nằm nhiều thư mục) ::: - Ngoài ra mình sử dụng backtrace để xem workflow của chương trình. ![image](https://hackmd.io/_uploads/H1jcWPc-ye.png) ![image](https://hackmd.io/_uploads/Syf2-wq-1l.png) -> Ta có thể thấy chương trình gọi hàm `malloc` mà trước đấy mình đã overwrite __malloc__hook -> ta thấy chương trình đáng `jmp` tới hàm ở `__malloc_hook` - Check trong libc : ![image](https://hackmd.io/_uploads/H1vVzwqZJl.png) -> offset = 0x842f3 ![image](https://hackmd.io/_uploads/rkXPzP5-yl.png) ![image](https://hackmd.io/_uploads/H1oOfwc-ke.png)