📄 find_service.c
字号:
int num_unknown = 0; int len_head = strlen(head); int rw_timeout = 5, cnx_timeout = 5, wrap_timeout = 3; int x, timeout; char *rw_timeout_s = get_plugin_preference(desc, RW_TIMEOUT_PREF); char *cnx_timeout_s = get_plugin_preference(desc, CNX_TIMEOUT_PREF);#ifdef DETECT_WRAPPED_SVC char *wrap_timeout_s = get_plugin_preference(desc, WRAP_TIMEOUT_PREF);#endif unsigned char *p; fd_set rfds, wfds, xfds; struct timeval tv; char k[32];#ifdef DEBUG struct arglist *hostinfos = arg_get_value(desc, "HOSTNAME"); struct in_addr *p_ip = arg_get_value(hostinfos, "IP");#endif if (rw_timeout_s != NULL && (x = atoi(rw_timeout_s)) > 0) rw_timeout = x; if (cnx_timeout_s != NULL && (x = atoi(cnx_timeout_s)) > 0) cnx_timeout = x;#ifdef DETECT_WRAPPED_SVC if (wrap_timeout_s != NULL && (x = atoi(wrap_timeout_s)) >= 0) wrap_timeout = x;#endif bzero(unknown, sizeof(unknown)); while (h && h->next) { if ((strlen(h->name) > len_head) && !strncmp(h->name, head, len_head)) { int cnx; char *line; char *origline; int trp, i; unsigned char buffer[2049]; unsigned char *banner = NULL, *bannerHex = NULL; int banner_len; int port = atoi(h->name + len_head); int flg = 0; int unindentified_service = 0; int three_digits = 0; int maybe_wrapped = 0; char kb[64]; int get_sent = 0; int ssl_port = known_ssl_port(port); int std_port = ssl_port || (port_to_name(port) != NULL); int cnx_timeout2 = std_port ? cnx_timeout * 2 : cnx_timeout; int rw_timeout2 = std_port ? rw_timeout * 2 : rw_timeout; struct timeval tv1, tv2; int diff_tv = 0, diff_tv2 = 0; int type, no_banner_grabbed = 0; if ( port == 139 || port == 445 ) { if ( h != NULL ) h = h->next; continue; } #define DIFFTV1000(t1,t2) ((t1.tv_sec - t2.tv_sec)*1000 + (t1.tv_usec - t2.tv_usec)/1000) bzero(buffer, sizeof(buffer)); banner_len = 0; snprintf(kb, sizeof(kb), "BannerHex/%d", port); bannerHex = plug_get_key(desc, kb, &type); if (type == ARG_STRING && bannerHex != NULL && bannerHex[0] != '\0') { int i, c1, c2; banner_len = strlen((char *) bannerHex) / 2; if (banner_len >= sizeof(buffer)) banner_len = sizeof(buffer) - 1; for (i = 0; i < banner_len; i++) { c1 = bannerHex[2 * i]; if (c1 >= '0' && c1 <= '9') c1 -= '0'; else if (c1 >= 'a' && c1 <= 'f') c1 = c1 - 'a' + 10; else if (c1 >= 'A' && c1 <= 'F') c1 = c1 - 'A' + 10; else {#ifdef DEBUG printf("Invalid value '%x' (%c, off%d)\n", c1, c1, i * 2 + 1);#endif banner_len = 0; /* Invalid value */ } c2 = bannerHex[2 * i + 1]; if (c2 >= '0' && c2 <= '9') c2 -= '0'; else if (c2 >= 'a' && c2 <= 'f') c2 = c2 - 'a' + 10; else if (c2 >= 'A' && c2 <= 'F') c2 = c2 - 'A' + 10; else {#ifdef DEBUG printf("Invalid value '%x' (%c, off%d)\n", c2, c2, i * 2 + 1);#endif banner_len = 0; /* Invalid value */ } buffer[i] = c1 << 4 | c2; } buffer[i] = '\0'; if (banner_len > 0) banner = (unsigned char *) buffer;#ifdef DEBUG fprintf(stderr, "find_service(%s): found hex banner in KB for port %d. len=%d\n", inet_ntoa(*p_ip), port, banner_len);#endif } if (banner_len == 0) { snprintf(kb, sizeof(kb), "Banner/%d", port); banner = plug_get_key(desc, kb, &type); if (type == ARG_STRING && banner != NULL) { banner_len = strlen((char *) banner);#ifdef DEBUG fprintf(stderr, "find_service(%s): found banner in KB for port %d. len=%d\n", inet_ntoa(*p_ip), port, banner_len);#endif } } if (banner_len > 0) {#ifdef DEBUG fprintf(stderr, "find_service(%s): banner is known on port %d - will not open a new connection\n", inet_ntoa(*p_ip), port);#endif cnx = -1; trp = NESSUS_ENCAPS_IP; } else {#ifdef DEBUG fprintf(stderr, "find_service(%s): banner is unknown on port %d - connecting...\n", inet_ntoa(*p_ip), port);#endif if (banner != NULL) efree(&banner); banner = NULL; if (test_ssl == 2 || (test_ssl == 1 && ssl_port)) { cnx = open_stream_connection_unknown_encaps5(desc, port, cnx_timeout2, &trp, &diff_tv); diff_tv /= 1000; /* Now in milliseconds */ } else { (void) gettimeofday(&tv1, NULL); trp = NESSUS_ENCAPS_IP; cnx = open_stream_connection(desc, port, trp, cnx_timeout2); (void) gettimeofday(&tv2, NULL); diff_tv = DIFFTV1000(tv2, tv1); } } if (cnx >= 0 || banner_len > 0) { int len, line_len; int realfd = -1; if (cnx >= 0) { realfd = nessus_get_socket_from_connection(cnx); snprintf(k, sizeof(k), "FindService/CnxTime1000/%d", port); plug_replace_key(desc, k, ARG_INT, (void *) diff_tv); snprintf(k, sizeof(k), "FindService/CnxTime/%d", port); plug_replace_key(desc, k, ARG_INT, (void *) ((diff_tv + 500) / 1000)); if (diff_tv / 1000 > cnx_timeout) plug_replace_key(desc, "/tmp/SlowFindService", ARG_INT, (void *) 1); }#ifdef DEBUG fprintf(stderr, "find_service(%s): Port %d is open. \"Transport\" is %d\n", inet_ntoa(*p_ip), port, trp);#endif plug_set_port_transport(desc, port, trp); (void) stream_set_timeout(port, rw_timeout2);#ifdef HAVE_SSL if (IS_ENCAPS_SSL(trp)) { char report[160]; snprintf(report, sizeof(report), "A %s server answered on this port\n", get_encaps_name(trp)); post_note(desc, port, report); plug_set_key(desc, "Transport/SSL", ARG_INT, (void *) port); }#endif#define HTTP_GET "GET / HTTP/1.0\r\n\r\n" len = 0; timeout = 0; if (banner_len > 0) { len = banner_len; if (banner != (unsigned char *) buffer) { if (len >= sizeof(buffer)) len = sizeof(buffer) - 1; memcpy(buffer, banner, len); buffer[len] = '\0'; } } else { snprintf(kb, sizeof(kb), "/tmp/NoBanner/%d", port); p = plug_get_key(desc, kb, &type); if (p != NULL) if (type == ARG_INT) no_banner_grabbed = (int) p; else if (type == ARG_STRING) no_banner_grabbed = atoi((char *) p);#ifdef DEBUG fprintf(stderr, "find_service(%s): no banner on port %d according to KB\n", inet_ntoa(*p_ip), port);#endif if (!no_banner_grabbed) {#ifdef SMART_TCP_RW if (trp == NESSUS_ENCAPS_IP && realfd >= 0) { select_again: FD_ZERO(&rfds); FD_ZERO(&wfds); FD_SET(realfd, &rfds); FD_SET(realfd, &wfds); (void) gettimeofday(&tv1, NULL); tv.tv_usec = 0; tv.tv_sec = rw_timeout2; x = select(realfd + 1, &rfds, &wfds, NULL, &tv); if (x < 0) { if (errno == EINTR) goto select_again; perror("select"); } else if (x == 0) timeout = 1; else if (x > 0) { if (FD_ISSET(realfd, &rfds)) { len = read_stream_connection_min(cnx, buffer, 1, sizeof(buffer) - 2); } } (void) gettimeofday(&tv2, NULL); diff_tv = DIFFTV1000(tv2, tv1); } } else { /* No banner was found * by nessus_tcp_scanner */#ifdef DEBUG fprintf(stderr, "find_service(%s): no banner was found by nessus_tcp_scanner on port %d - sending GET without waiting\n", inet_ntoa(*p_ip), port);#endif len = 0; timeout = 0; } if (len <= 0 && !timeout)#endif {#ifdef DEBUG if (!no_banner_grabbed) fprintf(stderr, "No banner on port %d - sending GET\n", port);#endif write_stream_connection(cnx, HTTP_GET, sizeof(HTTP_GET) - 1); (void) gettimeofday(&tv1, NULL); get_sent = 1; buffer[sizeof(buffer) - 1] = '\0'; len = read_stream_connection(cnx, buffer, sizeof(buffer) - 1);#if 1 /* * Try to work around broken * web server (or "magic * read" bug??) */ if (len > 0 && len < 8 && strncmp(buffer, "HTTP/1.", len) == 0) { int len2 = read_stream_connection(cnx, buffer + len, sizeof(buffer) - 1 - len); if (len2 > 0) len += len2; }#endif (void) gettimeofday(&tv2, NULL); diff_tv = DIFFTV1000(tv2, tv1); } if (len > 0) { snprintf(k, sizeof(k), "FindService/RwTime1000/%d", port); plug_replace_key(desc, k, ARG_INT, (void *) diff_tv); snprintf(k, sizeof(k), "FindService/RwTime/%d", port); plug_replace_key(desc, k, ARG_INT, (void *) ((diff_tv + 500) / 1000)); if (diff_tv / 1000 > rw_timeout) plug_replace_key(desc, "/tmp/SlowFindService", ARG_INT, (void *) 1); } } if (len > 0) { banner = emalloc(len + 1); memcpy(banner, buffer, len); banner[len] = '\0'; for (i = 0; i < len; i++) buffer[i] = tolower(buffer[i]); line = estrdup(buffer); if (strchr(line, '\n') != NULL) { char *t = strchr(line, '\n'); t[0] = '\0'; } if (isdigit(banner[0]) && isdigit(banner[1]) && isdigit(banner[2]) && (banner[3] == '\0' || isspace(banner[3]) || banner[3] == '-')) { /* * Do NOT use * plug_replace_key! */ plug_set_key(desc, "Services/three_digits", ARG_INT, (void *) port); /* * Do *not* set * Known/tcp/<port> to * "three_digits": the * service must remain * "unknown" */ three_digits = 1; } if (get_sent) snprintf(kb, sizeof(kb), "FindService/tcp/%d/get_http", port); else snprintf(kb, sizeof(kb), "FindService/tcp/%d/spontaneous", port); plug_replace_key(desc, kb, ARG_STRING, banner); { char buf2[sizeof(buffer) * 2 + 1]; int y, flag = 0; char kbHex[64]; snprintf(kbHex, sizeof(kbHex), "%sHex", kb); if (len >= sizeof(buffer)) len = sizeof(buffer); for (y = 0; y < len; y++) { snprintf(buf2 + 2 * y, sizeof(buf2) - (2 * y), "%02x", (unsigned char) banner[y]); if (banner[y] == '\0') flag = 1; } buf2[2 * y] = '\0'; if (flag) plug_replace_key(desc, kbHex, ARG_STRING, buf2); } origline = estrdup((char *) banner); if (strchr(origline, '\n') != NULL) { char *t = strchr(origline, '\n'); t[0] = '\0'; } line_len = strlen(origline); /* * Many services run on the top of an HTTP protocol, * so the HTTP test is not an 'ELSE ... IF' */ if ((!strncmp(line, "http/1.", 7) || strstr((char *) banner, "<title>Not supported</title>"))) { /* <- broken hp * jetdirect */ flg++; if (!(port == 5000 && (strstr(line, "http/1.1 400 bad request") != NULL)) && !(strncmp(line, "http/1.0 403 forbidden", strlen("http/1.0 403 forbidden")) == 0 && strstr(buffer, "server: adsubtract") != NULL)) mark_http_server(desc, port, banner, trp); } /* * RFC 854 defines commands between 240 and 254 * shouldn't we look for them too? */ if (((u_char) buffer[0] == 255) && (((u_char) buffer[1] == 251) || ((u_char) buffer[1] == 252) || ((u_char) buffer[1] == 253) || ((u_char) buffer[1] == 254))) mark_telnet_server(desc, port, origline, trp); else if (((u_char) buffer[0] == 0) && ((u_char) buffer[1] == 1) && ((u_char) buffer[2] == 1) && ((u_char) buffer[3] == 0)) mark_gnome14_server(desc, port, origline, trp); else if (strncmp(line, "http/1.0 403 forbidden", strlen("http/1.0 403 forbidden")) == 0 && strstr(buffer, "server: adsubtract") != NULL) { mark_locked_adsubtract_server(desc, port, banner, trp); } else if (strstr((char *) banner, "Eggdrop") != NULL && strstr((char *) banner, "Eggheads") != NULL) mark_eggdrop_server(desc, port, origline, trp); else if (strncmp(line, "$lock ", strlen("$lock ")) == 0) mark_direct_connect_hub(desc, port, trp); else if (len > 34 && strstr(&(buffer[34]), "iss ecnra")) mark_iss_realsecure(desc, port, origline, trp); else if (len == 4 && origline[0] == 'Q' && origline[1] == 0 && origline[2] == 0 && origline[3] == 0) mark_fw1(desc, port, origline, trp); else if (strstr(line, "adsgone blocked html ad") != NULL) mark_adsgone(desc, port, origline, trp); else if (strncmp(line, "icy 200 ok", strlen("icy 200 ok")) == 0) mark_shoutcast_server(desc, port, origline, trp); else if ( (!strncmp(line, "200", 3) && (strstr(line, "running eudora internet mail server"))) || (strstr(line, "+ok applepasswordserver") != NULL) ) mark_pop3pw_server(desc, port, origline, trp); else if ((strstr(line, "smtp") || strstr(line, "simple mail transfer") || strstr(line, "mail server") || strstr(line, "messaging") || strstr(line, "Weasel")) && !strncmp(line, "220", 3)) mark_smtp_server(desc, port, origline, trp); else if (strstr(line, "220 ***************") || strstr(line, "220 eSafe@")) /* CISCO SMTP (?) - see * bug #175 */ mark_smtp_server(desc, port, origline, trp); else if (strstr(line, "220 esafealert") != NULL) mark_smtp_server(desc, port, origline, trp); else if (strncmp(line, "220", 3) == 0 && strstr(line, "groupwise internet agent") != NULL) mark_smtp_server(desc, port, origline, trp); else if (strncmp(line, "220", 3) == 0 && strstr(line, " SNPP ") != NULL) mark_snpp_server(desc, port, origline, trp); else if (strncmp(line, "200", 3) == 0 && strstr(line, "mail ") != NULL) mark_smtp_server(desc, port, origline, trp); else if (strncmp(line, "421", 3) == 0 && strstr(line, "smtp ") != NULL) mark_smtp_server(desc, port, origline, trp); else if (line[0] != '\0' && (strncmp(line + 1, "host '", 6) == 0) && strstr(line, "mysql") != NULL) mark_mysql(desc, port, origline, trp); else if (!strncmp(line, "efatal", 6) || !strncmp(line, "einvalid packet length", strlen("einvalid packet length"))) mark_postgresql(desc, port, origline, trp); else if (strstr(line, "cvsup server ready") != NULL) mark_cvsupserver(desc, port, origline, trp); else if (!strncmp(line, "cvs [pserver aborted]:", 22) || !strncmp(line, "cvs [server aborted]:", 21)) mark_cvspserver(desc, port, origline, trp); else if (!strncmp(line, "cvslock ", 8)) mark_cvslockserver(desc, port, origline, trp); else if (!strncmp(line, "@rsyncd", 7)) mark_rsyncd(desc, port, origline, trp); else if ((len == 4) && may_be_time((time_t *) banner)) mark_time_server(desc, port, banner, trp); else if (strstr(buffer, "rmserver") || strstr(buffer, "realserver")) mark_rmserver(desc, port, origline, trp); else if ((strstr(line, "ftp") || strstr(line, "winsock") || strstr(line, "axis network camera") || strstr(line, "netpresenz") || strstr(line, "serv-u") || strstr(line, "service ready for new user")) && !strncmp(line, "220", 3)) mark_ftp_server(desc, port, origline, trp); else if (strncmp(line, "220-", 4) == 0) /* FTP server with a * long banner */ mark_ftp_server(desc, port, NULL, trp); else if (strstr(line, "220") && strstr(line, "whois+")) mark_whois_plus2_server(desc, port, origline, trp); else if (strstr(line, "520 command could not be executed")) mark_mon_server(desc, port, origline, trp); else if (strstr(line, "ssh-")) mark_ssh_server(desc, port, origline); else if (!strncmp(line, "+ok", 3) || (!strncmp(line, "+", 1) && strstr(line, "pop"))) mark_pop_server(desc, port, origline); else if (strstr(line, "imap4") && !strncmp(line, "* ok", 4)) mark_imap_server(desc, port, origline, trp); else if (strstr(line, "*ok iplanet messaging multiplexor")) mark_imap_server(desc, port, origline, trp); else if (strstr(line, "*ok communigate pro imap server")) mark_imap_server(desc, port, origline, trp); else if (strstr(line, "* ok courier-imap")) mark_imap_server(desc, port, origline, trp); else if (strncmp(line, "giop", 4) == 0) mark_giop_server(desc, port, origline, trp); else if (strstr(line, "microsoft routing server")) mark_exchg_routing_server(desc, port, origline, trp); /* Apparently an iPlanet ENS server */ else if (strstr(line, "gap service ready")) mark_ens_server(desc, port, origline, trp); else if (strstr(line, "-service not available")) mark_tcpmux_server(desc, port, origline, trp); /* * Citrix sends 7f 7f 49 43 41, that * we converted to lowercase */ else if (strlen(line) > 2 && line[0] == 0x7F && line[1] == 0x7F && strncmp(&line[2], "ica", 3) == 0) mark_citrix_server(desc, port, origline, trp); else if (strstr(origline, " INN ") || strstr(origline, " Leafnode ") || strstr(line, " nntp daemon") || strstr(line, " nnrp service ready") || strstr(line, "posting ok") || strstr(line, "posting allowed") || strstr(line, "502 no permission") || (strcmp(line, "502") == 0 && strstr(line, "diablo") != NULL)) mark_nntp_server(desc, port, origline, trp); else if (strstr(buffer, "networking/linuxconf") || strstr(buffer, "networking/misc/linuxconf") || strstr(buffer, "server: linuxconf")) mark_linuxconf(desc, port, banner); else if (strncmp(buffer, "gnudoit:", 8
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -