struct malloc_chunk* fd; struct malloc_chunk* bk;}; 1.- FD would point to a 'x' address. 2.- The 'x' + 12 address would be written with the address where BK is pointing. ¿Where will we make bk point? To the code we want to execute.(A.K.A., shellcode) ¿How do we modify the pointers? As we have said, with a buffer overflow. With our payload we have to achieve: Demonstration Time to patch /* Take a chunk off a bin list */#define unlink(P, BK, FD) { \ FD = P->fd; \ BK = P->bk; \ if (__builtin_expect (FD->bk != P || BK->fd != P, 0)) \ malloc_printerr (check_action, "corrupted double-linked list", P); \ else { \ FD->bk = BK; \ BK->fd = FD; \ } \} Satisfies the condition Doesn't satisfy the condition Timeline 1999, unlink technique releases 2004, unlink technique patched 2005, Malloc Maleficarum released 2009, patch for some Malloc Maleficarum techniques 5 years for the patch 4 years for the patch Summing up... bck = unsorted_chunks(av);fwd = bck->fd;p->bk = bck;p->fd = fwd;bck->fd = p;fwd->bk = p; File - malloc.c:4338 /* The otherwise unindexable 1-bin is used to hold unsorted chunks. */#define unsorted_chunks(M) (bin_at(M, 1)) General idea It returns the address of the first bin of the arena 'av' If we were able to control the contents of the arena, we would be able to control the address returned by unsorted_chunks() ¿How can we achieve it? bck->fd = p Standing on the shoulders of giants ¿How can we place heap_info structure in 0x08100000? If chunk p has the bit NON_MAIN_ARENA to 1: #define arena_for_chunk(ptr) \ (chunk_non_main_arena(ptr) ? heap_for_ptr(ptr)->ar_ptr : &main_arena) #define heap_for_ptr(ptr) \ ((heap_info *)((unsigned long)(ptr) & ~(HEAP_MAX_SIZE-1))) ~( HEAP_MAX_SIZE - 1 ) = 111...11100000000000000000000 20 zeroes p Interesting data Patch for The House of Mind in glibc version 2.11 Patch bck = unsorted_chunks(av);fwd = bck->fd;if (__builtin_expect (fwd->bk != bck, 0)) { errstr = "malloc(): corrupted unsorted chunks"; goto errout; } Requirements for The House of Mind It must exist a buffer overflow.Control content of two or more memory chunks.Control the content of a memory chunk placed in address 0x08100000 (to store the fake heap_info structure).Freeing a memory chunk placed in an address as 0x081xxxxx.Knowing the address of a memory chunk P of which we could control its content. ¿But then... ? /* Take a chunk off a bin list */#define unlink(P, BK, FD) { \ FD = P->fd; \ BK = P->bk; \ if (__builtin_expect (FD->bk != P || BK->fd != P, 0)) \ malloc_printerr (check_action, "corrupted double-linked list", P); \ else { \ FD->bk = BK; \ BK->fd = FD; \ } \} So knowing the address of P, ¿wouldn't it be possible to bypass unlink patch? Patch ¿Where does FD->bk point? To .dtors section ¿Can we control its contents? ¡Yes! ¿Where does BK->fd point? To the start of our shellcode + 8 bytes ¿Can we control its contents? ¡Yes! Demonstration Back to Unlink Development of an updated theoretical framework. Development of a method to bypass unlink patch Theoretical development of a bypass to the House of Mind patch. Development of two new payloads not previously published for the unlink exploitation. Some conclusions The security measures implemented in the algorithm are not enough. The problem is that control data and user data are adjacent. The security in the heap is based on external security measures such as ASLR. The End Thanks for your attention¿Questions? ¿What is this about? malloc(), realloc() or free() interact with the heap. Used when the size of data is unknown. Future work Apply the methodologies used to bypass ASLR in order to exploit heap vulnerabilities. Search new attack vectors. Overwriting .dtors section in 2013 __do_global_dtors_aux() functionfortified It doesn't matter what readelf says, .dtors section is read only. Function pointers in .dtors section are not executed unless they are declared as destructors in source code. RELRO (RELocation Read-Only) Thanks to In special to Wadalbertia In general to vlan7 y TuXeD And obviously to blackngel y Phantasmal Phantasmagoria See you in www.overflowedminds.net