⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nessus_tcp_scanner.c

📁 漏洞扫描源码,可以扫描linux,windows,交换机路由器
💻 C
📖 第 1 页 / 共 4 页
字号:
	    const int	read_timeout,	    const int	min_cnx,	    const int	max_cnx,	    struct arglist *globals, 	    struct arglist *desc,	    struct arglist *hostinfos,	    const int	flags){  char			buf[2048], kb[64];  int			s, tcpproto, pass;  struct protoent	*proto;  fd_set		rfs, wfs, efs;  struct timeval	timeout, ti;  struct sockaddr_in	sa;#ifdef IPV6_SUPPORT  struct sockaddr_in6   sa6;#endif  int			port = 23;  int			imax, i, j, x, opt;  unsigned int		optsz;  int			minport;  int			open_sock_nb, open_sock_max, open_sock_max2;  int			dropped_ports_nb, rejected_ports_nb;  int			dropped_nb, timeout_nb;  int			open_ports_nb, closed_ports_nb, untested_ports_nb;  int			scanned_port_nb = 0, total_ports_nb =0;  int 			done_ports_nb = 0; /* debug */  struct timeval	ti1;	/* debug */  int			cnx_max[3], rtt_max[3], rtt_min[3], ping_rtt = 0;#if defined COMPUTE_RTT  double		rtt_sum[3], rtt_sum2[3];  int			rtt_nb[3];  static const char	*rtt_type[] = {"unfiltered", "open", "closed" };#endif  time_t		start_time = time(NULL), start_time_1pass, end_time;  long			diff_time, diff_time1;  int			rst_rate_limit_flag = 0, doublecheck_flag = 0, old_doublecheck = 0;#if defined COMPUTE_RTT  double		mean, sd = -1.0, emax = -1.0;#endif  /* Big variables are kept on the heap for broken OS    * No need to free on function exit in the current architecture */  unsigned char		*ports_states = emalloc(65536 * sizeof(ports_states[0]));  grab_socket_t		*sockets = emalloc((max_cnx+1) * sizeof(sockets[0]));  debug_printf(pia, 1, "portrange=%s read_timeout=%dmin_cnx=%d max_cnx=%d flags=0x%x\n", portrange, read_timeout, min_cnx, max_cnx, flags);  proto = getprotobyname("tcp");  if (proto == NULL)    {      perror("nessus_tcp_scanner->getprotobyname(\"tcp\")");      return -1;    }  tcpproto = proto->p_proto;  for (i = 0; i < 65536; i ++)    ports_states[i] = GRAB_PORT_NOT_TESTED;  for (i = 0; i < 3; i ++)    {#if defined COMPUTE_RTT      rtt_sum[i] = rtt_sum2[i] = 0.0;      rtt_nb[i] = 0;#endif      rtt_max[i] = cnx_max[i] = 0;      rtt_min[i] = MAXINT;    }  ping_rtt = get_ping_rtt(pia, desc);  if ((untested_ports_nb = get_port_range((char*)portrange, ports_states)) < 0)    {      debug_printf(pia, 0, "nessus_tcp_scanner: get_port_range(%s) returns NULL. Fix your Nessus installation!\n", portrange);    }  for (i = 0; i < max_cnx; i ++)    {      sockets[i].state = GRAB_SOCKET_UNUSED;      sockets[i].fd = -1;    }  open_sock_nb = 0;   open_sock_max2 = max_cnx;  open_ports_nb = closed_ports_nb = dropped_ports_nb = rejected_ports_nb = 0;  /*************************************************************************   * The main loop: we redo passes until the number of filtered ports reaches   * zero, or do not change from the old pass.   * We stop after MAX_SANE_RTT to protect us against pathological cases, like   * a firewalled machine that returns (rate limited) ICMP   *************************************************************************/  for (pass = 1; pass <= MAX_PASS_NB; pass ++)    {      int	open_ports_nb1 = 0, closed_ports_nb1 = 0, dropped_ports_nb1 = 0;      int	old_open_sock_max = -1;      int	old_filtered = -1, old_opened = -1, old_untested_ports_nb;      int	wait_sock_nb = 0;      int	prev_scanned_port_nb = 0;      int 	ipcced = 0;      int       err;      int	dropped_flag = 0;      open_sock_max = pass == 1 || doublecheck_flag ? 1 : min_cnx / pass;      if (open_sock_max < 1) open_sock_max = 1;      if (open_sock_max2 <= open_sock_max)	open_sock_max2 = open_sock_max * 2;      if (open_sock_max2 > max_cnx)	open_sock_max2 = max_cnx;      old_untested_ports_nb = untested_ports_nb;      /* recount ports & reset filtered ports */      recount_ports(ports_states, 		    ! doublecheck_flag, /* standard filtered ports were already reset by double_check_std_ports */		    &open_ports_nb, &closed_ports_nb, 		    &dropped_ports_nb, &rejected_ports_nb, &untested_ports_nb);      scanned_port_nb = open_ports_nb + closed_ports_nb + dropped_ports_nb + rejected_ports_nb;      total_ports_nb = scanned_port_nb + untested_ports_nb;      if (pass > 1)	{	  if (doublecheck_flag)	    old_filtered = old_untested_ports_nb + rejected_ports_nb;	  else	    old_filtered = rejected_ports_nb + untested_ports_nb;	  old_opened = open_ports_nb;  	}      minport = 1;      start_time_1pass = time(NULL);      debug_printf(pia, 1, "pass #%d: open_sock_max=%d open_sock_max2=%d max_cnx=%d\n", pass, open_sock_max, open_sock_max2, max_cnx);      FD_ZERO(&rfs); FD_ZERO(&wfs); imax = -1;      /********************************************************************       * The secondary loop: we test each port until everything is scanned        ********************************************************************/      while (scanned_port_nb < total_ports_nb)	{	  int	congestion = 0;	  scanned_port_nb = open_ports_nb + closed_ports_nb + dropped_ports_nb + rejected_ports_nb;	  if (scanned_port_nb > prev_scanned_port_nb + 99)	    {	      if ( globals != NULL ) comm_send_status(globals, arg_get_value(hostinfos, "NAME"),"portscan", 			       scanned_port_nb, 			       total_ports_nb);	      prev_scanned_port_nb = scanned_port_nb;	    }	            x = open_ports_nb + closed_ports_nb + dropped_ports_nb + rejected_ports_nb;	  debug_printf(pia, 2, "%d / %d = %02d%% - %d ports remaining\n", 		       x, total_ports_nb,		       (x * 100) / (total_ports_nb > 0 ? total_ports_nb : 1),		       untested_ports_nb);#if 1	  if (open_sock_max > max_cnx) /* Bug! */	    {	      debug_printf(pia, 0, "open_sock_max=%d > max_cnx=%d\n", open_sock_max, max_cnx);	      return -1;	    }#endifagain:	  while (open_sock_nb < open_sock_max)	    {	      static const int primes[] = { 		/* Those primes numbers are common service ports */		23, 53, 113, 37,		3389, 1433, 587, 563,		443, 389, 139, 79,		7, 13, 17, 19	      };	      if (ipcc() != 0)		{		  ipcced ++;		  goto select;		}#define N_PRIMES	(sizeof(primes) / sizeof(primes[0]))	      int	i, multip = primes[pass % N_PRIMES];	      for (i = minport; i < 65536; i ++)		{		  if (flags & RANDOMIZE_PORTS_OPT)		  	port = (i * multip) % 65536;		  else		  	port = i;		  if (ports_states[port] == GRAB_PORT_UNKNOWN) break;		}	      if (i > 65535)	/* all ports done */		break;	      minport = i;	      /**************************************************	       * Open socket & set TCP/IP options	       **************************************************/	      ports_states[port] = GRAB_PORT_TESTING;	      debug_printf(pia, 3, "Trying TCP:%d\n", port);#ifdef IPV6_SUPPORT	      s = socket(pia != NULL ? PF_INET:PF_INET6, SOCK_STREAM, tcpproto);#else	      s = socket(PF_INET, SOCK_STREAM, tcpproto);#endif	      /* Error at this point are rather bad */	      if (s < 0)		{		  if (errno == ENFILE) /* File table overflow */		    {		      open_sock_max = open_sock_max2 = open_sock_nb / 2 - 1;		      /* NB: if open_sock_max2 < 0, the scanner aborts */		      if (debug_level > 0) 			/* DEBUG: otherwise, we print a less frigthtening message */			perror("nessus_tcp_scanner->socket");		      debug_printf(pia, 1, "Reducing the number of maximum open connections to %d [ENFILE]\n", open_sock_max);		      continue;		    }		  else if (errno == EMFILE)	/* Too many open files */		    {		      x = open_sock_nb  / 16;	/* 6.25% */		      open_sock_max = open_sock_max2 = 			open_sock_nb - (x > 0 ? x : 1);		      /* NB: if open_sock_max2 < 0, the scanner aborts */		      if (debug_level > 0)			/* DEBUG: otherwise, we print a less frigthtening message */			perror("nessus_tcp_scanner->socket");		      debug_printf(pia, 1, "Reducing the number of maximum open connections to %d [EMFILE]\n", open_sock_max);		      continue;		    }		  else		    {		      perror("nessus_tcp_scanner->socket");		      return -1;		    }		}#if defined FD_SETSIZE	      if (s >= FD_SETSIZE)		{		  open_sock_max --; 		  open_sock_max2 --;		  debug_printf(pia, 1, "socket=%d > FD_SETSIZE=%d - reducing the number of maximum open connections to %d\n", s, FD_SETSIZE, open_sock_max);		  if (close(s) < 0)		    perror("nessus_tcp_scanner->close");		  continue;		}#endif	      set_socket_source_addr(s, 0);	      if (set_nonblock(s) < 0)		{		  debug_printf(pia, 0, "Could not set O_NONBLOCK. Aborting!\n");		  return -1;		}	      /* SMB only accepts one incoming connection. 	       * It is safer to close the connection in foreground so that	       * if these ports are hit at the end of the scan, there is no 	       * conflict if the next plugin tries to connect to SMB */	      if (port != 139 && port != 445)  set_so_linger(s);	      set_ip_tos(s);	      /* Things like TCP_QUICKACK or TCP_NODELAY are probably useless */	      /***************************	       * Connect the socket	       ***************************/	      if (pia != NULL)		{		  sa.sin_addr = *pia;		  sa.sin_family = AF_INET;		  sa.sin_port = htons(port);		}#ifdef IPV6_SUPPORT	      else if (pia6 != NULL)		{		  sa6 = *pia6;		  sa6.sin6_port = htons(port);		}#endif	      ipci();	      err = 0;	      if (pia != NULL)		{		  if (! cct(*pia, port))		    {		      err = -1;		      errno = ECONNREFUSED;		    }		}	      if (err == 0)	      {#ifdef IPV6_SUPPORT		err = connect(s, pia != NULL ? (struct sockaddr*)&sa:(struct sockaddr*)&sa6, pia != NULL ?  sizeof(sa):sizeof(sa6));#else		err = connect(s, (struct sockaddr*)&sa, sizeof(sa));#endif	      }		if (err < 0)		{		  switch (errno)		    {		    case EINPROGRESS:		    case EALREADY:		      sockets[open_sock_nb].fd = s;		      sockets[open_sock_nb].port = port;		      sockets[open_sock_nb].state = GRAB_SOCKET_OPENING;		      (void) gettimeofday(&sockets[open_sock_nb].tictac, NULL);		      open_sock_nb ++;		      FD_SET(s, &wfs);		      if (s > imax) imax = s;		      break;		  		    case EAGAIN:		      x = open_sock_nb  / 16;	/* 6.25% */		      open_sock_max = open_sock_max2 = 			open_sock_nb - (x > 0 ? x : 1);		      /* If open_sock_max2 < 0, the scanner aborts */		      debug_printf(pia, 1, "Reducing the number of maximum open connections to %d [EAGAIN]\n", open_sock_max);		      continue;		      /* As the socket  is in asynchronous mode, connect()		       * should only return EINPROGRESS or EAGAIN		       * But against 127/8, this call is synchronous */		    case ECONNREFUSED:		      ports_states[port] = GRAB_PORT_CLOSED;		      debug_printf(pia, 3, ">>> %d: CLOSED\n", port);		      my_socket_close(s);		      closed_ports_nb ++;		      closed_ports_nb1 ++;		      untested_ports_nb --;		      continue;		  		    case ENETUNREACH:		    case EHOSTUNREACH:		      ports_states[port] = GRAB_PORT_REJECTED;		      debug_printf(pia, 3, ">>> %d: FILTERED\n", port);		      my_socket_close(s);		      rejected_ports_nb ++;		      untested_ports_nb --;		      continue;		    default:		      perror("nessus_tcp_scanner->connect");		      return -1;		    }		}	      else		/* This should only happen against 127/8 */		{		  sockets[open_sock_nb].fd = s;		  sockets[open_sock_nb].port = port;		  sockets[open_sock_nb].state = GRAB_SOCKET_OPEN;		  debug_printf(pia, 3, ">>> %d: OPEN\n", port);		  (void) gettimeofday(&sockets[open_sock_nb].tictac, NULL);		  open_sock_nb ++;		  ports_states[port] = GRAB_PORT_OPEN;		  open_ports_nb ++;		  open_ports_nb1 ++;		  wait_sock_nb ++;		  untested_ports_nb --;		  scanner_add_port(desc, port, "tcp");		}	      if (imax >= 0)	/* imax is the biggest file descriptor */		{		  timeout.tv_sec = timeout.tv_usec = 0;		  if (select(imax + 1, NULL, &wfs, NULL, &timeout) > 0)		    {		      debug_printf(pia, 2, "select! Breaking loop (open_sock_nb=%d / %d)\n", open_sock_nb, open_sock_max);		      break;		    }		}	    } /* while(open_sock_nb < open_sock_max) */	  if (open_sock_max2 <= 0)	    {	      debug_printf(pia, 0, "file table is full. Aborting\n");	      return -1;	    }	  if (open_sock_nb == 0)	    {	      debug_printf(pia, 1, "No more open socket\n");	      goto end;	    }	  /******************	   * Init fd_sets	   ******************/	select:	  FD_ZERO(&rfs); FD_ZERO(&wfs); FD_ZERO(&efs); imax = -1;	  for (i = 0; i < open_sock_nb; i ++)	    {	      if (sockets[i].fd >= 0)		{		  switch (sockets[i].state)		    {		    case GRAB_SOCKET_OPEN:		      FD_SET(sockets[i].fd, &rfs);		      break;		    case GRAB_SOCKET_OPENING:		      FD_SET(sockets[i].fd, &wfs);		      break;		    default:		      debug_printf(pia, 0, "BUG! Bad status %d - s=%d\n", sockets[i].state, sockets[i].fd);		      break;		    }		  if (sockets[i].fd > imax)		    imax = sockets[i].fd;		}	    }	  if (imax < 0)	    {	      if (untested_ports_nb > 0)		{		  if (ipcced != 0)  continue;		  debug_printf(pia, 0, "No socket! %d ports remaining\n", untested_ports_nb);		  return -1;		}	      else		{		  debug_printf(pia, 1, "No socket! No port remaining\n");		  goto end;		}	    }	  /*****************************	   * Estimate RTT & set timeout	   *****************************/	  timeout_nb = 0; dropped_nb = 0; #if defined COMPUTE_RTT	  if (rtt_nb[0] > 1)	    {	      /* All values are in micro-seconds */	      int	em, moy;	      mean = rtt_sum[0] / (double)rtt_nb[0];	      if ((double)rtt_max[0] > mean)		{		  sd = sqrt((rtt_sum2[0] / rtt_nb[0] - mean * mean) * (double)rtt_nb[0] / (rtt_nb[0] - 1));		  emax = mean + 3 * sd;		  em = floor(emax + 0.5);		  moy = floor(rtt_sum[0] / rtt_nb[0] + 0.5);		  if (em <= moy)		    {		      debug_printf(pia, 1, "arithmetic overflow: %g -> %d\n", emax, em);		      em = moy;		    }		  if (rtt_max[0] > em) 		    {		      debug_printf(pia, 2, "rtt_nb=%d rtt_max = %g > %g (M=%g, SD=%g)\n", rtt_nb[0], (double)rtt_max[0] / 1e6, emax / 1e6, mean / 1e6, sd / 1e6);		      rtt_max[0] = em;		    }		  else		    debug_printf(pia, 3, "rtt_nb=%d rtt_max = %g < %g\n", rtt_nb[0], (double)rtt_max[0] / 1e6, emax / 1e6);		}	      if (rtt_max[0] < rtt_min[0])		{		  debug_printf(pia, 2, "absurdly low rtt_max=%g < rtt_min = %g\n", (double)rtt_max[0] / 1e6, (double)rtt_min[0] / 1e6);		  rtt_max[0] = rtt_min[0];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -