如何书写一个shell code

一:shellcode基本算法分析
在程序中,执行一个shell的程序是这样写的

      shellcode.c 
------------------------------------------------------------------------ 
#include  
void main() { 
char *name[2]; 
name[0] = "/bin/sh" 
name[1] = NULL; 
execve(name[0], name, NULL); 
} 
-

execve函数将执行一个程序。他需要程序的名字地址作为第一个参数。一个内容为该程序的argvi的指针数组作为第二个参数,以及(char*) 0作为第三个参数。

我们来看以看execve的汇编代码

[nkl10]$Content$nbsp;gcc -o shellcode -static shellcode.c 
[nkl10]$Content$nbsp;gdb shellcode 
(gdb) disassemble __execve 
Dump of assembler code for function __execve: 
0x80002bc <__execve>: pushl %ebp ; 
0x80002bd <__execve+1>: movl %esp,%ebp 
;上面是函数头。 
0x80002bf <__execve+3>: pushl %ebx 
;保存ebx 
0x80002c0 <__execve+4>: movl $0xb,%eax 
;eax=0xb,eax指明第几号系统调用。 
0x80002c5 <__execve+9>: movl 0x8(%ebp),%ebx 
;ebp+8是第一个参数"/bin/sh\0" 
0x80002c8 <__execve+12>: movl 0xc(%ebp),%ecx 
;ebp+12是第二个参数name数组的地址 
0x80002cb <__execve+15>: movl 0x10(%ebp),%edx 
;ebp+16是第三个参数空指针的地址。 
;name[2-1]内容为NULL,用来存放返回值。 
0x80002ce <__execve+18>: int $0x80 
;执行0xb号系统调用(execve) 
0x80002d0 <__execve+20>: movl %eax,%edx 
;下面是返回值的处理就没有用了。 
0x80002d2 <__execve+22>: testl %edx,%edx 
0x80002d4 <__execve+24>: jnl 0x80002e6 <__execve+42> 
0x80002d6 <__execve+26>: negl %edx 
0x80002d8 <__execve+28>: pushl %edx 
0x80002d9 <__execve+29>: call 0x8001a34 
<__normal_errno_location> 
0x80002de <__execve+34>: popl %edx 
0x80002df <__execve+35>: movl %edx,(%eax) 
0x80002e1 <__execve+37>: movl $0xffffffff,%eax 
0x80002e6 <__execve+42>: popl %ebx 
0x80002e7 <__execve+43>: movl %ebp,%esp 
0x80002e9 <__execve+45>: popl %ebp 
0x80002ea <__execve+46>: ret 
0x80002eb <__execve+47>: nop 
End of assembler dump.

经过以上的分析,可以得到如下的精简指令算法:

movl $execve的系统调用号,%eax 

movl "bin/sh\0"的地址,%ebx 
movl name数组的地址,%ecx 
movl name[n-1]的地址,%edx 
int $0x80 ;执行系统调用(execve)

当execve执行成功后,程序shellcode就会退出,/bin/sh将作为子进程继续执行。可是,如果我们的execve执行失败,(比如没有/bin/sh这个文件),CPU就会继续执行后续的指令,结果不知道跑到哪里去了。所以必须再执行一个exit()系统调用,结束shellcode.c的执行。

我们来看以看exit(0)的汇编代码:`


movl $0x1,%eax ;1号系统调用 
movl 0,%ebx ;ebx为exit的参数0 
int $0x80 ;引发系统调用
``那么总结一下,合成的汇编代码为:
movl $execve的系统调用号,%eax 

movl "bin/sh\0"的地址,%ebx 
movl name数组的地址,%ecx 
movl name[n-1]的地址,%edx 
int $0x80 ;执行系统调用(execve) 
movl $0x1,%eax ;1号系统调用 
movl 0,%ebx ;ebx为exit的参数0 
int $0x80 ;执行系统调用(exit)`

实时更新,欢迎关注!
发布了8 篇原创文章 · 获赞 8 · 访问量 1783

猜你喜欢

转载自blog.csdn.net/qq_45748475/article/details/104180361