nessus_tcp_scanner.c

来自「漏洞扫描源码,可以扫描linux,windows,交换机路由器」· C语言 代码 · 共 1,859 行 · 第 1/4 页

C
1,859
字号
		   */		  /* 1st check on this pass only */		  closed_ports_nb1 >= (diff_time1 + 1) * 10 && 		  closed_ports_nb1 < (diff_time1 + 1) * 201 && 		  /* 2nd check on all passes */		  closed_ports_nb >= (diff_time + 1) * 10 && 		  closed_ports_nb < (diff_time + 1) * 201)		{		  /* BSD-like system */		  int	break_flag = (open_sock_max2 <= max_cnx) || rst_rate_limit_flag;		  int	tbd = (break_flag && !old_doublecheck) ? double_check_std_ports(ports_states, NULL) : 0;		  if (tbd > 0)		    {		      doublecheck_flag = 1;		      break_flag = 0;		      untested_ports_nb = tbd;		    }		  debug_printf(pia, 1, "system seems to be limiting RST rate - %s - pass=%d min_cnx=%d - closed_ports_nb1=%d - diff_time1=%ld - closed_ports_nb=%d - diff_time=%ld\n", break_flag ? "Stopping immediately" : doublecheck_flag ? "Double checking standard ports" : "Running one last pass", pass, min_cnx, closed_ports_nb1, diff_time1, closed_ports_nb, diff_time);		  rst_rate_limit_flag ++ ;		  if (break_flag) break;		}	    } /* RST */	  debug_printf(pia, 2, "min_cnx=%d - open_ports_nb1=%d - closed_ports_nb1=%d - diff_time1=%ld - closed_ports_nb=%d - diff_time=%ld\n", min_cnx, open_ports_nb1, closed_ports_nb1, diff_time1, closed_ports_nb, diff_time);	  if (! dropped_flag)	    {	      open_sock_max2 *= 2;	      open_sock_max2 /= 3;	    } 	  else if (! rst_rate_limit_flag && open_sock_max2 <= open_sock_max)	    open_sock_max2 = open_sock_max * 2;	}      else if (dropped_ports_nb > 0 && ! doublecheck_flag)	{	  /* Double check standard ports, just to avoid being ridiculous */	  if ((untested_ports_nb = double_check_std_ports(ports_states, NULL)) == 0)	    {	      debug_printf(pia, 1, "pass #%d - No filtered standard ports - stopping\n", pass);	      break;	    }	  else	    debug_printf(pia, 1, "pass #%d - Double checking %d standard ports\n", pass, untested_ports_nb);	  doublecheck_flag = 1;	}      else	/* No filtered ports */	break;    } /* for (pass = 1; pass <= MAX_PASS_NB; pass ++) */  if (pass > MAX_PASS_NB)    {      pass --;      debug_printf(pia, 0, "gave up after %d pass\n", pass);      /*dropped_ports_nb = old_dropped;*/    }  /********************************************   * Set miscellaneous information into the KB   ********************************************/  plug_set_key(desc, "TCPScanner/NbPasses", ARG_INT, (void*) pass);  if (old_doublecheck)		/* We need to re-count the filtered ports */    recount_ports(ports_states, 0, 		  &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;  debug_printf(pia, 1, "ran in %d pass(es) in %ld s - min_cnx=%d max_cnx=%d read_timeout=%d - open_ports_nb=%d closed_ports_nb=%d dropped_ports_nb=%d rejected_ports_nb=%d - rtt_min=%f rtt_max=%f cnx_max=%f\n", pass, diff_time, min_cnx, max_cnx, read_timeout, open_ports_nb, closed_ports_nb, dropped_ports_nb, rejected_ports_nb, rtt_min[0] / 1e6, rtt_max[0] / 1e6, cnx_max[0] / 1e6);#if defined COMPUTE_RTT  for (i = 0; i < 3; i ++)    if (rtt_nb[i] > 0)      {	char	rep[64];	double	mean, sd = -1.0, emax = -1.0;	/* Convert from micro-seconds to seconds */	rtt_sum[i] /= 1e6; rtt_sum2[i] /= 1e12;	mean = rtt_sum[i] / rtt_nb[i];#if 1	snprintf(rep, sizeof(rep), "%6g", mean);	snprintf(kb, sizeof(kb), "TCPScanner/%s/MeanRTT", rtt_type[i]);	plug_set_key(desc, kb, ARG_STRING, rep);	x = floor(mean * 1000 + 0.5);	snprintf(kb, sizeof(kb), "TCPScanner/%s/MeanRTT1000", rtt_type[i]);	plug_set_key(desc, kb, ARG_INT, (void*) x);	/* rtt_max is integer (uS) */	snprintf(kb, sizeof(kb), "TCPScanner/%s/MaxRTT1000", rtt_type[i]);	plug_set_key(desc, kb, ARG_INT, (void*) ((rtt_max[i] + 500)/1000));	snprintf(rep, sizeof(rep), "%6g", (rtt_max[i] + 500000.0) / 1000000.0);	snprintf(kb, sizeof(kb), "TCPScanner/%s/MaxRTT", rtt_type[i]);	plug_set_key(desc, kb, ARG_STRING, rep);#endif	if (rtt_nb[i] > 1)	  {	    sd = sqrt((rtt_sum2[i] / rtt_nb[i] - mean * mean) * rtt_nb[i] / (rtt_nb[i] - 1));	    emax = mean + 3 * sd;#if 1	    snprintf(rep, sizeof(rep), "%6g", sd);	    snprintf(kb, sizeof(kb), "TCPScanner/%s/SDRTT", rtt_type[i]);	    plug_set_key(desc, kb, ARG_STRING, rep);	    x = floor(sd * 1000 + 0.5);	    snprintf(kb, sizeof(kb), "TCPScanner/%s/SDRTT1000", rtt_type[i]);	    plug_set_key(desc, kb, ARG_INT, (void*)x);	    snprintf(rep, sizeof(rep), "%6g", emax);	    snprintf(kb, sizeof(kb), "TCPScanner/%s/EstimatedMaxRTT", rtt_type[i]);	    plug_set_key(desc, kb, ARG_STRING, rep);	    x = floor(emax * 1000 + 0.5);	    snprintf(kb, sizeof(kb), "TCPScanner/%s/EstimatedMaxRTT1000", rtt_type[i]);	    plug_set_key(desc, kb, ARG_INT, (void*)x);#endif	  }	if (rtt_nb[i] > 0)	  debug_printf(pia, 1, "Mean RTT to %s = %g s - [%g, %g] - SD = %g - +3SD = %g [%d %s ports]\n", 		  pia ? inet_ntoa(*pia):"ipv6", mean, 		  rtt_min[i] / 1e6, cnx_max[i] / 1e6,		  sd, emax, rtt_nb[i], rtt_type[i]);      }#endif  plug_set_key(desc, "TCPScanner/OpenPortsNb", ARG_INT, (void*)open_ports_nb);  plug_set_key(desc, "TCPScanner/ClosedPortsNb", ARG_INT, (void*)closed_ports_nb);  plug_set_key(desc, "TCPScanner/DroppedPortsNb", ARG_INT, (void*)dropped_ports_nb);  plug_set_key(desc, "TCPScanner/RejectedPortsNb", ARG_INT, (void*)rejected_ports_nb);  plug_set_key(desc, "TCPScanner/FilteredPortsNb", ARG_INT, (void*)(dropped_ports_nb+rejected_ports_nb));  plug_set_key(desc, "TCPScanner/UnfilteredPortsNb", ARG_INT, (void*)(open_ports_nb+closed_ports_nb));  plug_set_key(desc, "TCPScanner/RSTRateLimit", ARG_INT, (void*) rst_rate_limit_flag);  if (total_ports_nb == 65535)    plug_set_key(desc, "Host/full_scan", ARG_INT, (void*) 1);  plug_set_key(desc, "Host/num_ports_scanned", ARG_INT, (void*) total_ports_nb);  return 0;}static intread_sysctl_maxsysfd(){  int		cur_sys_fd = 0, max_sys_fd = 0;  FILE		*fp;  int		stderr_fd = -1, devnull_fd= -1;  if (find_in_path("sysctl", 0) == NULL) return -1;  if (debug_level == 0)    {      /* Avoid error messages from sysctl */      stderr_fd = dup(2);      if (stderr_fd < 0)	perror("dup(2)");      else	{	  devnull_fd = open("/dev/null", O_WRONLY);	  if (devnull_fd < 0)	    {	      perror("/dev/null");	      close(stderr_fd);	      stderr_fd = -1;	    }	  else	    if (dup2(devnull_fd, 2) < 0)	      perror("dup2");	}    }	  if ((fp = popen("sysctl fs.file-nr", "r")) != NULL)    {      if (fscanf(fp, "%*s = %d %*d %d", &cur_sys_fd, &max_sys_fd) == 2)	max_sys_fd -= cur_sys_fd;      else	max_sys_fd = 0;	          pclose(fp);    }	    if (max_sys_fd <= 0 && (fp = popen("sysctl fs.file-max", "r")) != NULL)    {      if (fscanf(fp, "%*s = %d", &max_sys_fd) != 1)	max_sys_fd = 0;      pclose(fp);    }  if (max_sys_fd <= 0 && (fp = popen("sysctl kern.maxfiles", "r")) != NULL)    {      if (fscanf(fp, "%*s = %d", &max_sys_fd) != 1)	max_sys_fd = 0;      pclose(fp);    }  /* On BSD, net.inet.tcp.rexmit_min gives the initial TCP SYN    * retransmission interval. We could use it.   * On Solaris, the situation looks more complex:    * http://www.sean.de/Solaris/rexmit.html   */    /* Restore stderr */  if (debug_level == 0)    {      if (devnull_fd >= 0) close(devnull_fd);      if (stderr_fd >= 0)	{	  dup2(stderr_fd, 2);	  close(stderr_fd);	}    }  return max_sys_fd;}static voidcompute_min_max_cnx(int max_hosts, int max_checks, int safe_checks,                    int *pmin, int *pmax){  int		max_sys_fd;  int           min_cnx = *pmin, max_cnx = *pmax;  struct rlimit	rlim;  int		i, x;  double	loadavg[3], maxloadavg = -1.0;  if (max_hosts <= 0) max_hosts = 15;  if (max_checks <= 0 || max_checks > 5)      {	max_checks = 5; /* bigger values do not make sense */	debug_printf(NULL, 1, "max_checks forced to %d\n", max_checks);      }    min_cnx = 4 * max_checks;    if (safe_checks)      max_cnx = 24 * max_checks;    else      max_cnx = 80 * max_checks;    getloadavg(loadavg, 3);    for (i = 0; i < 3; i ++)      if (loadavg[i] > maxloadavg) maxloadavg = loadavg[i];    if (maxloadavg >= 0.0)      {	int	x = max_cnx;	max_cnx /= (1.0 + maxloadavg);	debug_printf(NULL, 1, "max_cnx reduced from %d to %d because of maxloadavg=%f\n", x, max_cnx, maxloadavg);      }      max_sys_fd = read_sysctl_maxsysfd();    debug_printf(NULL, 1, "max_sys_fd=%d\n", max_sys_fd);    if (max_sys_fd <= 0) max_sys_fd = 16384; /* reasonable default */    /* Let's leave at least 1024 FD for other processes */    if (max_sys_fd < 1024)      x = GRAB_MIN_SOCK;    else      {	max_sys_fd -= 1024;	x = max_sys_fd / max_hosts;      }    if (max_cnx > x) max_cnx = x;#if 0    fprintf(stderr, "min_cnx = %d ; max_cnx = %d\n", min_cnx, max_cnx);#endif    if (max_cnx > GRAB_MAX_SOCK) max_cnx = GRAB_MAX_SOCK;    if (max_cnx < GRAB_MIN_SOCK) max_cnx = GRAB_MIN_SOCK;    if (safe_checks && max_cnx > GRAB_MAX_SOCK_SAFE)      max_cnx = GRAB_MAX_SOCK_SAFE;    if (getrlimit(RLIMIT_NOFILE, &rlim) < 0)      perror("nessus_tcp_scanner->getrlimit(RLIMIT_NOFILE)");    else      {	/* value = one greater than the maximum  file  descriptor number */	if (rlim.rlim_cur != RLIM_INFINITY && max_cnx >= rlim.rlim_cur)	  max_cnx = rlim.rlim_cur - 1;      }    x = max_cnx / 2;    if (min_cnx > x) min_cnx = x > 0 ? x : 1;  debug_printf(NULL, 1, "min_cnx = %d ; max_cnx = %d\n", min_cnx, max_cnx);    *pmin = min_cnx;  *pmax = max_cnx;}  #if !defined STANDALONEPlugExport int plugin_run(struct arglist * desc){  struct arglist * globals = arg_get_value(desc, "globals");  struct arglist * preferences = arg_get_value(desc, "preferences");  struct arglist * hostinfos = arg_get_value(desc, "HOSTNAME");  char * port_range = arg_get_value(preferences, "port_range");  char * p;  struct in_addr *p_addr = NULL;#ifdef IPV6_SUPPORT  struct sockaddr_in6 *p_addr6 = NULL;#endif  int	timeout = 0, max_cnx, min_cnx, safe_checks = 0, x;  char		*opt;  int		flags = 0;  int   max_hosts = 40, max_checks = 5;  opt = getenv("NESSUS_TCP_SCANNER_DEBUG");  if (opt != NULL)    {      debug_level = atoi(opt);      if (debug_level < 0) debug_level = 0;      debug_printf(NULL, 1, "debug_level=%d\n", debug_level);    }  opt = get_plugin_preference(desc, RANDOMIZE_PORTS_TXT);  if (opt == NULL || strcmp(opt, "yes") == 0) flags |= RANDOMIZE_PORTS_OPT;  opt = get_plugin_preference(desc, RST_RATE_LIMIT_TXT);  if (opt == NULL || strcmp(opt, "yes") == 0) flags |= RST_RATE_LIMIT_OPT;  opt = get_plugin_preference(desc, DETECT_FIREWALL_TXT);  if (opt == NULL || strcmp(opt, "yes") == 0) flags |= DETECT_FIREWALL_OPT;#ifdef TCP_INFO  opt = get_plugin_preference(desc, NET_CONGESTION_TXT);  if (opt == NULL || strcmp(opt, "yes") == 0) flags |= NET_CONGESTION_OPT;#endif  p = arg_get_value(preferences, "safe_checks");  if (p != NULL && strcmp(p, "yes") == 0) safe_checks = 1;  p =  arg_get_value(preferences, "checks_read_timeout");  if (p != NULL) timeout = atoi(p);  if (timeout <= 0)    timeout = 5;  debug_printf(NULL, 1, "safe_checks=%d checks_read_timeout=%d\n", safe_checks, timeout);    p = arg_get_value(preferences, "max_hosts");  if (p != NULL) max_hosts = atoi(p);  p = arg_get_value(preferences, "max_checks");  if (p != NULL) max_checks = atoi(p);    compute_min_max_cnx(max_hosts, max_checks, safe_checks, &min_cnx, &max_cnx);    p_addr = plug_get_host_ip(desc);  if( p_addr == NULL )  {#ifdef IPV6_SUPPORT     p_addr6 = plug_get_host_ip6(desc);    if ( p_addr6 == NULL ) return -1;#else    return -1;#endif  }  if (banner_grab(p_addr, #ifdef IPV6_SUPPORT		  p_addr6,#endif		  port_range, timeout, min_cnx, max_cnx, globals, desc, hostinfos, flags) < 0)    return -1;  comm_send_status(globals, arg_get_value(hostinfos, "NAME"),"portscan", 65535, 65535);  plug_set_key(desc, "Host/scanned", ARG_INT, (void*)1);  plug_set_key(desc, "Host/scanners/nessus_tcp_scanner", ARG_INT, (void*)1);  return 0;}#endif/* Special code for standalone version * Compile with: * gcc -DSTANDLONE -I/opt/nessus/include/nessus nessus_tcp_scanner.c -o nessus_tcp_scanner -L/opt/nessus/lib -lnessus -lssl -lpcap -lm */#if defined STANDALONEvoidusage(){  fprintf(stderr, "Usage: nessus_tcp_scanner [options] IP port_range\n\Options are:\n\-C max_checks\n\-H max_hosts\n\-S\tSet safe_checks flag to TRUE\n\-R\tDo not detect & circumvent RST rate limitation\n\-F\tDo not detect firewalls (= IP filters)\n\-r\tDo not randomize ports, use +1 increments\n\-N\tIgnore congestion (reported by the Linux kernel)\n\-m min_cnx\tspecify the minimum number of connections\n\-M max_cnx\tspecify the maximum number of connections\n\Normally, min_cnx and max_cnx are computed from all other parameters\n\-h\tPrint this help.\n\");  exit(1);}intmain(int argc, char *argv[]){  struct in_addr ia, *pia = NULL;#ifdef IPV6_SUPPORT  struct sockaddr_in6 ia6, *pia6 = NULL;#endif  int    timeout = 5, min_cnx, max_cnx, flags = ~0;  int    safe_checks = 0, max_checks = 4, max_hosts = 4;  int    min1 = 0, max1 = 0;  int    i;    while ((i = getopt(argc, argv, "m:M:C:H:ShrFRN")) != -1)    switch(i)    {    case 'm':      if (optarg == NULL) usage();      else min1 = atoi(optarg);      break;    case 'M':      if (optarg == NULL) usage();      else max1 = atoi(optarg);      break;    case 'S':      safe_checks = 1; break;    case 'C':      if (optarg == NULL) usage();      else max_checks = atoi(optarg);      break;    case 'H':      if (optarg == NULL) usage();      else max_hosts = atoi(optarg);      break;    case 'R':      flags &= ~RST_RATE_LIMIT_OPT; break;    case 'F':      flags &= ~DETECT_FIREWALL_OPT; break;    case 'r':      flags &= ~RANDOMIZE_PORTS_OPT; break;    case 'N':      flags &= ~NET_CONGESTION_OPT; break;          case 'h':      usage();      break;  }  if (argc != optind + 2) usage();  if (inet_pton(AF_INET, argv[optind], &ia) > 0)    pia = &ia;#ifdef IPV6_SUPPORT  else if (inet_pton(AF_INET6, argv[optind], &ia6) > 0)    {      pia6 = &ia6;      ia6.sin6_family = AF_INET6;    }#endif  else    {      fprintf(stderr, "Bad IP address %s\n", argv[optind]);      return 1;    }  if (min1 <= 0 || max1 <= 0)    compute_min_max_cnx(max_hosts, max_checks, safe_checks,                        &min_cnx, &max_cnx);  if (min1 > 0) min_cnx = min1;  if (max1 > 0) max_cnx = max1;    if (banner_grab(pia, #ifdef IPV6_SUPPORT		  pia6,#endif		  argv[optind+1], timeout, min_cnx, max_cnx, NULL, NULL, NULL, flags) < 0)    return -1;  return 0;}#endif/* STANDALONE */

⌨️ 快捷键说明

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