关于shellcode的编写

2008-04-09 03:59:17来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折

关于 Shell Code 的编写。

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

backend 于 99-9-29 18:24:47 加贴在 UNIX系统安全:

Shell Code 的编写

下面是一个创建Shell的C程序shellcode.c: (本文以IntelX86上的Linux为例说明)

void main() {
  char *name[2];

  name[0] = "/bin/sh";
  name[1] = NULL;
  execve(name[0], name, NULL);
}

我们先将它编译为执行代码,然后再用gdb来分析一下.(注意编译时要用-static选项,否则execve的代码将不会放入执行代码,而是作为动态链接在运行时才链入.)
------------------------------------------------------------------------------
[aleph1]$ gcc -o shellcode -ggdb -static shellcode.c
[aleph1]$ gdb shellcode
GDB is free software and you are welcome to 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.
GDB 4.15 (i586-unknown-linux), Copyright 1995 Free Software Foundation, Inc...
(gdb) disassemble main
Dump of assembler code for function main:
0x8000130 <main>: pushl 雙
0x8000131 <main 1>: movl %esp,雙
0x8000133 <main 3>: subl $0x8,%esp
0x8000136 <main 6>: movl $0x80027b8,0xfffffff8(雙)
0x800013d <main 13>: movl $0x0,0xfffffffc(雙)
0x8000144 <main 20>: pushl $0x0
0x8000146 <main 22>: leal 0xfffffff8(雙),陎
0x8000149 <main 25>: pushl 陎
0x800014a <main 26>: movl 0xfffffff8(雙),陎
0x800014d <main 29>: pushl 陎
0x800014e <main 30>: call 0x80002bc <__execve>
0x8000153 <main 35>: addl $0xc,%esp
0x8000156 <main 38>: movl 雙,%esp
0x8000158 <main 40>: popl 雙
0x8000159 <main 41>: ret
End of assembler dump.
(gdb) disassemble __execve
Dump of assembler code for function __execve:
0x80002bc <__execve>: pushl 雙
0x80002bd <__execve 1>: movl %esp,雙
0x80002bf <__execve 3>: pushl 離
0x80002c0 <__execve 4>: movl $0xb,陎
0x80002c5 <__execve 9>: movl 0x8(雙),離
0x80002c8 <__execve 12>: movl 0xc(雙),靫
0x80002cb <__execve 15>: movl 0x10(雙),韝
0x80002ce <__execve 18>: int $0x80
0x80002d0 <__execve 20>: movl 陎,韝
0x80002d2 <__execve 22>: testl 韝,韝
0x80002d4 <__execve 24>: jnl 0x80002e6 <__execve 42>
0x80002d6 <__execve 26>: negl 韝
0x80002d8 <__execve 28>: pushl 韝
0x80002d9 <__execve 29>: call 0x8001a34 <__normal_errno_location>
0x80002de <__execve 34>: popl 韝
0x80002df <__execve 35>: movl 韝,(陎)
0x80002e1 <__execve 37>: movl $0xffffffff,陎
0x80002e6 <__execve 42>: popl 離
0x80002e7 <__execve 43>: movl 雙,%esp
0x80002e9 <__execve 45>: popl 雙
0x80002ea <__execve 46>: ret
0x80002eb <__execve 47>: nop
End of assembler dump.
------------------------------------------------------------------------------

下面我们来首先来分析一下main代码中每条语句的作用:

0x8000130 <main>: pushl 雙
0x8000131 <main 1>: movl %esp,雙
0x8000133 <main 3>: subl $0x8,%esp
这跟前面的例子一样,也是一段函数的入口处理,保存以前的栈帧指针,更新栈帧指针,最后为局部变量留出空间.在这里,局部变量为:
char *name[2];
也就是两个字符指针.每个字符指针占用4个字节,所以总共留出了 8 个字节的位置.

0x8000136 <main 6>: movl $0x80027b8,0xfffffff8(雙)
这里, 将字符串"/bin/sh"的地址放入name[0]的内存单元中, 也就是相当于 :
name[0] = "/bin/sh";

0x800013d <main 13>: movl $0x0,0xfffffffc(雙)
将NULL放入name[1]的内存单元中, 也就是相当于:
name[1] = NULL;

对execve()的调用从下面开始:
0x8000144 <main 20>: pushl $0x0
开始将参数以逆序压入堆栈, 第一个是NULL.

0x8000146 <main 22>: leal 0xfffffff8(雙),陎
0x8000149 <main 25>: pushl 陎
将name[]的起始地址压入堆栈

0x800014a <main 26>: movl 0xfffffff8(雙),陎
0x800014d <main 29>: pushl 陎
将字符串"/bin/sh"的地址压入堆栈

0x800014e <main 30>: call 0x80002bc <__execve>
调用execve() . call 指令首先将 EIP 压入堆栈

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

现在我们再来看一下execve()的代码. 首先要注意的是, 不同的操作系统,不同的CPU,他们产生系统调用的方法也不尽相同. 有些使用软中断,有些使用远程调用.从参数传递的角度来说,有些使用寄存器,有些使用堆栈.
我们的这个例子是在基于Intel X86的Linux上运行的.所以我们首先应该知道Linux中,系统调用以软中断的方式产生( INT 80h),参数是通过寄存器传递给系统的.

0x80002bc <__execve>:  pushl 雙
0x80002bd <__execve 1>: movl %esp,雙
0x80002bf <__execve 3>: pushl 離
同样的入口处理

0x80002c0 <__execve 4>: movl $0xb,陎
将0xb(11)赋给eax , 这是execve()在系统中的索引号.

0x80002c5 <__execve 9>: movl 0x8(雙),離
将字符串"/bin/sh"的地址赋给ebx

0x80002c8 <__execve 12>: movl 0xc(雙),靫

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:深入SQl编程

下一篇:perl程序设计(八)