½Ã½ºÅÛ ÇØÅ·

 1576, 1/79 ȸ¿ø°¡ÀÔ  ·Î±×ÀΠ 
   vngkv123
   ubuntu 16.04 UAF¹ö±×..

http://www.hackerschool.org/HS_Boards/zboard.php?AllArticle=true&no=1861 [º¹»ç]


root@ubuntu:/home/ssun/system_exploit/pwn# vi uaf_vuln2.c
root@ubuntu:/home/ssun/system_exploit/pwn# gcc -fno-stack-protector -o uaf_vuln2 uaf_vuln2.c
root@ubuntu:/home/ssun/system_exploit/pwn# ./uaf_vuln2
one -> number : 0
one -> number : 12345
Address of one -> number : 0x1a89010
two -> number : 0
Address of two -> number : 0x1a89010

ÀÌ°Ô ÀÌ·¸°Ô ³ª¿À´Â°Å¸é ÀÌÀü¿¡ ÇÒ´çµÇ¾ú´ø°÷À¸·Î ´Ù½Ã ÀçÇÒ´çµÇ¾úÁö¸¸,
ÀÚµ¿À¸·Î ÃʱâÈ­°¡ µÈ°Ç°¡¿ä?

  Hit : 4184     Date : 2017/04/16 08:36



    
ÇØÄð·¯ uaf_vuln2.c ¼Ò½ºÄڵ带 ¿Ã·ÁÁÖ¼¼¿ä 2017/04/16  
vngkv123 #include <stdio.h>
#include <stdlib.h>

typedef struct UAF{
int number;
} uaf;

int main(){
uaf *one;
uaf *two;

one = malloc(100);
printf("one -> number : %d\n",one->number);

one->number = 12345;
printf("one -> number : %d\n", one->number);
printf("Address of one -> number : %p\n", &one->number);

free(one);
two = malloc(100);

printf("two -> number : %d\n",two->number);
printf("Address of two -> number : %p\n", &two->number);
}
root@ubuntu:/home/ssun/system_exploit/pwn#
2017/04/16  
vngkv123 Áö±Ý º¸±â¿£ freeÇϰԵǸ鼭 µ¿½Ã¿¡ °Å±â ÀÖ´ø °ªµéÀÌ 0À¸·Î ÃʱâÈ­µÇ´Â°Å °°¾Æº¸À̴µ© ¤Ð 2017/04/16  
ÇØÄð·¯ ¾Æ ¾î·Á¿ü³×¿ä malloc chunk´Â
struct malloc_chunk {

INTERNAL_SIZE_T mchunk_prev_size; /* Size of previous chunk (if free). */
INTERNAL_SIZE_T mchunk_size; /* Size in bytes, including overhead. */

struct malloc_chunk* fd; /* double links -- used only if free. */
struct malloc_chunk* bk;

/* Only used for large blocks: pointer to next larger size. */
struct malloc_chunk* fd_nextsize; /* double links -- used only if free. */
struct malloc_chunk* bk_nextsize;
};
¿ì¸®°¡ mallocÀ¸·Î ÈüÇÒ´çÀ» ¿äûÇÒ ¶§ ¹Þ´Â Æ÷ÀÎÅʹ ù µÎ¹øÂ°²¨ ÀÌÈÄÀÇ ÁÖ¼Ò¸¦ ¹Þ½À´Ï´Ù. ±×·¡¼­ ù ÇÒ´çÀ» ¹ÞÀ» ¶§ size_t*2¸¸Å­ÀÌ ÆäÀÌÁöÀÇ ¹è¼ö¿¡¼­ ´õÇØÁø »óÅ·Π¸®ÅϵǴ°̴ϴÙ(32ºñÆ®¿¡¼­´Â +8, 64ºñÆ®¿¡¼­´Â +0x10)
ÀÌ·¸°Ô ¼±¾ðµÅÀÖ°í, number°¡ 0À¸·Î µÇ´Â ½ÃÁ¡Àº ¸»¾¸ÇϽŴë·Î freeÇϴµ¥¼­ Á¸ÀçÇÕ´Ï´Ù
free(one)À» ÇÒ ¶§ one->fd = fwd ¸¦ Çϴµ¥ Èü ûũ ¸®½ºÆ®¿¡¼­ ¾Õ¿¡ Àִ ûũ°¡ ¾ø±â ¶§¹®¿¡ fwd´Â 0ÀÌ°í µû¶ó¼­ one->fd¿¡ 0ÀÌ µé¾î°¡¸é¼­, one->number°¡ 0À¸·Î µ¤¾î ¾º¿öÁö°Ô µÇ´Â°Å±¸¿ä
sizeof(pointer)*2 ÀÌÈÄ¿¡ ÀÖ´Â °ªÀº µ¤¾î¾º¿öÁöÁö¾Ê½À´Ï´Ù(nextsize suffix°¡ ºÙÀº ¸â¹öµéÀº large bin¿¡¼­¸¸ »ç¿ëµÇ¹Ç·Î)
2017/04/16  
ÇØÄð·¯ root@ ~/tmp # ./test
one -> n1 : 12345
one -> n2 : 23456
one -> n2 : 34567
two -> n1 : 0
two -> n2 : 0
two -> n3 : 34567
root@ ~/tmp # cat test.c
#include <stdio.h>
#include <stdlib.h>

typedef struct UAF{
int n1;
int n2;
int n3;
} uaf;

int main(){
uaf *one;
uaf *two;

one = malloc(100);

one->n1 = 12345;
one->n2 = 23456;
one->n3 = 34567;
printf("one -> n1 : %d\n", one->n1);
printf("one -> n2 : %d\n", one->n2);
printf("one -> n2 : %d\n", one->n3);

free(one);
two = malloc(100);

printf("two -> n1 : %d\n",two->n1);
printf("two -> n2 : %d\n",two->n2);
printf("two -> n3 : %d\n",two->n3);
}
2017/04/16  
ÇØÄð·¯ ¾Æ óÀ½¿¡ ºÐ¼®Çѳ»¿ë Ʋ·È½À´Ï´Ù Áö±Ý ´Ù½Ã ºÐ¼®ÁßÀÌ¿¡¿ä 2017/04/16  
ÇØÄð·¯ ½±°Ô ÀÌÇØÇÏ·Á¸é Èü¿¡¼­ ÇÁ¸®¸¦ ÇÒ¶§ Èü ûũ¸¦ °ü¸®ÇÏ´Â ±¸Á¶Ã¼¸¦ ÇÁ¸®µÈ°Í¿¡ ¸Â°Ô º¯°æÇϸ鼭 ¼öÁ¤µÈ°ÍÀ̶ó°í ÀÌÇØÇÏ¸é µÇ±¸¿ä
¾î·Æ°Ô ÀÌÇØÇÏ·Á¸é Èü¿¡´Â ¸Þ¸ð¸® »çÀÌÁî¿¡ ¸Â´Â ÃÖÀûÈ­¸¦ À§ÇØ ¸Þ¸ð¸® ºí·ÏÀÇ ¹üÀ§¿¡ µû¶ó ´Ù¸£°Ô ó¸®Çϰí ÀÖ½À´Ï´Ù
32ºñÆ® ¸®´ª½º¿¡¼­´Â,
512¹ÙÀÌÆ®¸¦ ±âÁØÀ¸·Î ÀÛÀ¸¸é small bin, Å©¸é large binÀ¸·Î 󸮵ǰí, ÀÌÁß¿¡¼­ 72¹ÙÀÌÆ® ¹Ì¸¸ÀÎ ºí·ÏµéÀº fastbinÀ¸·Î µû·Î ó¸®ÇØ malloc/free ½Ã¿¡ ¿À¹öÇìµå¸¦ ÃÖ¼ÒÈ­ Çϵµ·Ï ÇÕ´Ï´Ù
Àúµµ ±×·¸°Ô ¾Ë°íÀ־ ¿Ö 100¹ÙÀÌÆ®¸¦ ÇÒ´ç¹Þ¾Ò´Âµ¥ fastbin free ·çƾÀ» Ÿ³ª Çߴµ¥
http://daehee87.tistory.com/478
ÀÌ ±ÛÀ» º¸´Ï 64bit¿¡¼­´Â 120¹ÙÀÌÆ® ÀÌÇÏÀÇ ºí·ÏÀ» fastbinÀ¸·Î ó¸®ÇÏ´õ±º¿ä
°á±¹ fastbin free·çƾÀ» ÅÀ°í °Å±â¼­´Â fd¸¸ ÃʱâÈ­ ÇÕ´Ï´Ù(sizeof(pointer), Áï 8¹ÙÀÌÆ®, sizeof(int)*2)
glibc-2.25ÀÇ malloc.cÀÇ L3941~L3961À» º¸¸é
if (__builtin_expect (old == p, 0))
{
errstr = "double free or corruption (fasttop)";
goto errout;
}
/* Check that size of fastbin chunk at the top is the same as
size of the chunk that we are adding. We can dereference OLD
only if we have the lock, otherwise it might have already been
deallocated. See use of OLD_IDX below for the actual check. */
if (have_lock && old != NULL)
old_idx = fastbin_index(chunksize(old));
p->fd = old2 = old;
}
while ((old = catomic_compare_and_exchange_val_rel (fb, p, old2)) != old2);

if (have_lock && old != NULL && __builtin_expect (old_idx != idx, 0))
{
errstr = "invalid fastbin entry (free)";
goto errout;
}
}
ÀÌ·¸°Ô p->fd¸¸ º¯°æÇÏ´Â ºÎºÐÀ» º¼ ¼ö ÀÖ½À´Ï´Ù

»çÀÌÁ 256¹ÙÀÌÆ®·Î ¹Ù²ã¼­ ´Ù½ÃÇØº¸¸é fastbinÀÌ ¾Æ´Ï±â ¶§¹®¿¡ sizeof(pointer)*4°¡ º¯°æµÇ¾î Á¦°¡ ¾´ ¿¹Á¦Äڵ忡¼­ n1~n3 -> n1~n5·Î ÇßÀ» ¶§ n1~n4°¡ º¯°æµÈ°É º¼ ¼ö ÀÖ½À´Ï´Ù
2017/04/16  
ÇØÄð·¯ ¾Æ 64ºñÆ®¿¡¼­ ÇϽÅÁÙ ¾Ë¾Ò´Âµ¥ 32ºñÆ®¿¡¼­ Çϼ̾ú±º¿ä 32ºñÆ®¿¡¼­´Â sizeof(pointer) == sizeof(int)Àΰ͸¸ »©¸é ¶È°°½À´Ï´Ù 2017/04/16  
ÇØÄð·¯ ±×·¡¼­ °á±¹Àº memset(chunk, 0, sizeof(chunk)) °¡ ¾Æ´Ï¶ó
chunk->first = something Çϸ鼭 ù 4¹ÙÀÌÆ®¸¸ º¯°æµÈ°Ì´Ï´Ù
ûũ Àüü°¡ ÃʱâÈ­µÈ°Ô ¾Æ´Ñ°ÅÁÒ
2017/04/16  
vngkv123 °¨»çÇÕ´Ï´ç ±Ùµ¥ Àú 64ºñƮȯ°æ¿¡¼­ ÇѰſ¡¿ë 2017/04/16