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 + -
显示快捷键?