diff options
author | Ivan Nardi <12729895+IvanNardi@users.noreply.github.com> | 2025-03-05 16:14:03 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-03-05 16:14:03 +0100 |
commit | f56831336334dddcff00eaf2132e5e0f226f0e32 (patch) | |
tree | 89fc2a29d429133dc01077e6f01d98c287b1d2e1 | |
parent | 086d41c22e3e1888b67519a0e6c05f2262ce379e (diff) |
Add configuration parameter to enable/disable export of flow risk info (#2761)
For the most common protocols, avoid creating the string message if we
are not going to use it
-rw-r--r-- | doc/configuration_parameters.md | 1 | ||||
-rw-r--r-- | fuzz/fuzz_config.cpp | 5 | ||||
-rw-r--r-- | src/include/ndpi_main.h | 2 | ||||
-rw-r--r-- | src/include/ndpi_private.h | 1 | ||||
-rw-r--r-- | src/lib/ndpi_main.c | 27 | ||||
-rw-r--r-- | src/lib/ndpi_utils.c | 13 | ||||
-rw-r--r-- | src/lib/protocols/dns.c | 22 | ||||
-rw-r--r-- | src/lib/protocols/http.c | 224 | ||||
-rw-r--r-- | src/lib/protocols/quic.c | 10 | ||||
-rw-r--r-- | src/lib/protocols/stun.c | 2 | ||||
-rw-r--r-- | src/lib/protocols/tls.c | 172 | ||||
-rw-r--r-- | tests/cfgs/flow_risk_infos_disabled/config.txt | 1 | ||||
l--------- | tests/cfgs/flow_risk_infos_disabled/pcap/http_invalid_server.pcap | 1 | ||||
l--------- | tests/cfgs/flow_risk_infos_disabled/pcap/tls_malicious_sha1.pcapng | 1 | ||||
-rw-r--r-- | tests/cfgs/flow_risk_infos_disabled/result/http_invalid_server.pcap.out | 27 | ||||
-rw-r--r-- | tests/cfgs/flow_risk_infos_disabled/result/tls_malicious_sha1.pcapng.out | 32 |
16 files changed, 376 insertions, 165 deletions
diff --git a/doc/configuration_parameters.md b/doc/configuration_parameters.md index a966d753f..b27059880 100644 --- a/doc/configuration_parameters.md +++ b/doc/configuration_parameters.md @@ -20,6 +20,7 @@ List of the supported configuration options: | NULL | "dpi.guess_ip_before_port" | disable | NULL | NULL | Enable/disable guessing by IP first when guessing flow classifcation. Disabled = guess by port first. | | NULL | "flow_risk.$FLOWRISK_NAME_OR_ID" | enable | NULL | NULL | Enable/disable the specific flow risk. Use "any" as flow risk name if you want to easily enable/disable all flow risks. The names of the flow risks are available at `src/include/ndpi_typedefs.h`: look for `ndpi_risk_shortnames` | | NULL | "flow_risk_lists.load" | 1 | NULL | NULL | Enable/disable loading of every IP addresses lists used to check any flow risks | +| NULL | "flow_risk_infos" | enable | NULL | NULL | Enable/disable the export of flow risk information, i.e. some strings clarifing some details about the specific flow risk set | | NULL | "flow_risk.anonymous_subscriber.list.icloudprivaterelay.load" | 1 | NULL | NULL | Enable/disable loading of internal iCouldPrivateRealy IP address list used to check `NDPI_ANONYMOUS_SUBSCRIBER` flow risk | | NULL | "flow_risk.anonymous_subscriber.list.protonvpn.load" | 1 | NULL | NULL | Enable/disable loading of internal IP address list of ProtonVPN exit nodes used to check `NDPI_ANONYMOUS_SUBSCRIBER` flow risk | | NULL | "flow_risk.anonymous_subscriber.list.tor.load" | 1 | NULL | NULL | Enable/disable loading of internal IP address list of TOR exit nodes used to check `NDPI_ANONYMOUS_SUBSCRIBER` flow risk | diff --git a/fuzz/fuzz_config.cpp b/fuzz/fuzz_config.cpp index 1a5b0e5b0..9439ae335 100644 --- a/fuzz/fuzz_config.cpp +++ b/fuzz/fuzz_config.cpp @@ -491,6 +491,11 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { if(fuzzed_data.ConsumeBool()) { value = fuzzed_data.ConsumeIntegralInRange(0, 1 + 1); snprintf(cfg_value, sizeof(cfg_value), "%d", value); + ndpi_set_config(ndpi_info_mod, NULL, "flow_risk_infos", cfg_value); + } + if(fuzzed_data.ConsumeBool()) { + value = fuzzed_data.ConsumeIntegralInRange(0, 1 + 1); + snprintf(cfg_value, sizeof(cfg_value), "%d", value); ndpi_set_config(ndpi_info_mod, NULL, "flow_risk.anonymous_subscriber.list.icloudprivaterelay.load", cfg_value); } if(fuzzed_data.ConsumeBool()) { diff --git a/src/include/ndpi_main.h b/src/include/ndpi_main.h index 641993fcf..63ae8aed1 100644 --- a/src/include/ndpi_main.h +++ b/src/include/ndpi_main.h @@ -96,7 +96,7 @@ extern "C" { ndpi_port_range *udpDefPorts); void ndpi_set_risk(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow, ndpi_risk_enum r, char *risk_message); - void ndpi_unset_risk(struct ndpi_flow_struct *flow, ndpi_risk_enum r); + void ndpi_unset_risk(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow, ndpi_risk_enum r); int ndpi_isset_risk(struct ndpi_flow_struct *flow, ndpi_risk_enum r); int ndpi_is_printable_buffer(u_int8_t const * const buf, size_t len); int ndpi_normalize_printable_string(char * const str, size_t len); diff --git a/src/include/ndpi_private.h b/src/include/ndpi_private.h index 67eb34b43..1dee6a862 100644 --- a/src/include/ndpi_private.h +++ b/src/include/ndpi_private.h @@ -331,6 +331,7 @@ struct ndpi_detection_module_config_struct { NDPI_PROTOCOL_BITMASK flowrisk_bitmask; int flow_risk_lists_enabled; + int flow_risk_infos_enabled; int risk_anonymous_subscriber_list_icloudprivaterelay_enabled; int risk_anonymous_subscriber_list_protonvpn_enabled; int risk_anonymous_subscriber_list_tor_exit_nodes_enabled; diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c index 504d44023..d817a557c 100644 --- a/src/lib/ndpi_main.c +++ b/src/lib/ndpi_main.c @@ -7465,7 +7465,7 @@ static void ndpi_connection_tracking(struct ndpi_detection_module_struct *ndpi_s else if(flow->packet_direction_complete_counter[!flow->client_packet_direction] == 0) ndpi_set_risk(ndpi_str, flow, NDPI_UNIDIRECTIONAL_TRAFFIC, "No server to client traffic"); else { - ndpi_unset_risk(flow, NDPI_UNIDIRECTIONAL_TRAFFIC); /* Clear bit */ + ndpi_unset_risk(ndpi_str, flow, NDPI_UNIDIRECTIONAL_TRAFFIC); /* Clear bit */ } } @@ -7813,7 +7813,7 @@ static void ndpi_reconcile_protocols(struct ndpi_detection_module_struct *ndpi_s case NDPI_PROTOCOL_SFLOW: case NDPI_PROTOCOL_COLLECTD: /* Remove NDPI_UNIDIRECTIONAL_TRAFFIC from unidirectional protocols */ - ndpi_unset_risk(flow, NDPI_UNIDIRECTIONAL_TRAFFIC); + ndpi_unset_risk(ndpi_str, flow, NDPI_UNIDIRECTIONAL_TRAFFIC); break; case NDPI_PROTOCOL_SYSLOG: @@ -7821,7 +7821,7 @@ static void ndpi_reconcile_protocols(struct ndpi_detection_module_struct *ndpi_s case NDPI_PROTOCOL_SONOS: case NDPI_PROTOCOL_RTP: if(flow->l4_proto == IPPROTO_UDP) - ndpi_unset_risk(flow, NDPI_UNIDIRECTIONAL_TRAFFIC); + ndpi_unset_risk(ndpi_str, flow, NDPI_UNIDIRECTIONAL_TRAFFIC); break; case NDPI_PROTOCOL_TLS: @@ -10471,19 +10471,27 @@ u_int16_t ndpi_match_host_subprotocol(struct ndpi_detection_module_struct *ndpi_ string_to_match, string_to_match_len, &proto_id, NULL, NULL); if(rc1 > 0) { - char str[64] = { '\0' }; + if(ndpi_str->cfg.flow_risk_infos_enabled) { + char str[64] = { '\0' }; - strncpy(str, string_to_match, ndpi_min(string_to_match_len, sizeof(str)-1)); - ndpi_set_risk(ndpi_str, flow, NDPI_RISKY_DOMAIN, str); + strncpy(str, string_to_match, ndpi_min(string_to_match_len, sizeof(str)-1)); + ndpi_set_risk(ndpi_str, flow, NDPI_RISKY_DOMAIN, str); + } else { + ndpi_set_risk(ndpi_str, flow, NDPI_RISKY_DOMAIN, NULL); + } } } /* Add punycode check */ if(ndpi_check_punycode_string(string_to_match, string_to_match_len)) { - char str[64] = { '\0' }; + if(ndpi_str->cfg.flow_risk_infos_enabled) { + char str[64] = { '\0' }; - strncpy(str, string_to_match, ndpi_min(string_to_match_len, sizeof(str)-1)); - ndpi_set_risk(ndpi_str, flow, NDPI_PUNYCODE_IDN, str); + strncpy(str, string_to_match, ndpi_min(string_to_match_len, sizeof(str)-1)); + ndpi_set_risk(ndpi_str, flow, NDPI_PUNYCODE_IDN, str); + } else { + ndpi_set_risk(ndpi_str, flow, NDPI_PUNYCODE_IDN, NULL); + } } return(rc); @@ -11762,6 +11770,7 @@ static const struct cfg_param { { NULL, "metadata.tcp_fingerprint", "enable", NULL, NULL, CFG_PARAM_ENABLE_DISABLE, __OFF(tcp_fingerprint_enabled), NULL }, { NULL, "flow_risk_lists.load", "1", NULL, NULL, CFG_PARAM_ENABLE_DISABLE, __OFF(flow_risk_lists_enabled), NULL }, + { NULL, "flow_risk_infos", "enable", NULL, NULL, CFG_PARAM_ENABLE_DISABLE, __OFF(flow_risk_infos_enabled), NULL }, { NULL, "flow_risk.$FLOWRISK_NAME_OR_ID", "enable", NULL, NULL, CFG_PARAM_FLOWRISK_ENABLE_DISABLE, __OFF(flowrisk_bitmask), NULL }, diff --git a/src/lib/ndpi_utils.c b/src/lib/ndpi_utils.c index 99fabbc96..9e856ee2f 100644 --- a/src/lib/ndpi_utils.c +++ b/src/lib/ndpi_utils.c @@ -3103,7 +3103,8 @@ void ndpi_set_risk(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_fl // ndpi_handle_risk_exceptions(ndpi_str, flow); if(flow->risk != 0 /* check if it has been masked */) { - if(risk_message != NULL) { + if(ndpi_str->cfg.flow_risk_infos_enabled && + risk_message != NULL) { if(flow->num_risk_infos < MAX_NUM_RISK_INFOS) { char *s = ndpi_strdup(risk_message); @@ -3115,7 +3116,7 @@ void ndpi_set_risk(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_fl } } } - } else if(risk_message) { + } else if(ndpi_str->cfg.flow_risk_infos_enabled && risk_message) { u_int8_t i; for(i = 0; i < flow->num_risk_infos; i++) @@ -3140,13 +3141,17 @@ void ndpi_set_risk(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_fl /* ******************************************************************** */ -void ndpi_unset_risk(struct ndpi_flow_struct *flow, ndpi_risk_enum r) { +void ndpi_unset_risk(struct ndpi_detection_module_struct *ndpi_str, + struct ndpi_flow_struct *flow, ndpi_risk_enum r) { if(ndpi_isset_risk(flow, r)) { u_int8_t i, j; ndpi_risk v = 1ull << r; flow->risk &= ~v; + if(!ndpi_str->cfg.flow_risk_infos_enabled) + return; + for(i = 0; i < flow->num_risk_infos; i++) { if(flow->risk_infos[i].id == r) { flow->risk_infos[i].id = 0; @@ -3321,7 +3326,7 @@ void ndpi_entropy2risk(struct ndpi_detection_module_struct *ndpi_struct, } reset_risk: - ndpi_unset_risk(flow, NDPI_SUSPICIOUS_ENTROPY); + ndpi_unset_risk(ndpi_struct, flow, NDPI_SUSPICIOUS_ENTROPY); } /* ******************************************************************** */ diff --git a/src/lib/protocols/dns.c b/src/lib/protocols/dns.c index 6ad8e67c6..de0a74d8b 100644 --- a/src/lib/protocols/dns.c +++ b/src/lib/protocols/dns.c @@ -828,11 +828,15 @@ static void search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct flow->protos.dns.num_answers = dns_header.num_answers + dns_header.authority_rrs + dns_header.additional_rrs; if(flow->protos.dns.reply_code != 0) { - char str[32], buf[16]; + if(ndpi_struct->cfg.flow_risk_infos_enabled) { + char str[32], buf[16]; - snprintf(str, sizeof(str), "DNS Error Code %s", - dns_error_code2string(flow->protos.dns.reply_code, buf, sizeof(buf))); - ndpi_set_risk(ndpi_struct, flow, NDPI_ERROR_CODE_DETECTED, str); + snprintf(str, sizeof(str), "DNS Error Code %s", + dns_error_code2string(flow->protos.dns.reply_code, buf, sizeof(buf))); + ndpi_set_risk(ndpi_struct, flow, NDPI_ERROR_CODE_DETECTED, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_ERROR_CODE_DETECTED, NULL); + } } else { if(ndpi_isset_risk(flow, NDPI_SUSPICIOUS_DGA_DOMAIN)) { ndpi_set_risk(ndpi_struct, flow, NDPI_RISKY_DOMAIN, "DGA Name Query with no Error Code"); @@ -866,10 +870,14 @@ static void search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct packet->udp && packet->payload_packet_len > PKT_LEN_ALERT && packet->payload_packet_len > flow->protos.dns.edns0_udp_payload_size) { - char str[48]; + if(ndpi_struct->cfg.flow_risk_infos_enabled) { + char str[48]; - snprintf(str, sizeof(str), "%u Bytes DNS Packet", packet->payload_packet_len); - ndpi_set_risk(ndpi_struct, flow, NDPI_DNS_LARGE_PACKET, str); + snprintf(str, sizeof(str), "%u Bytes DNS Packet", packet->payload_packet_len); + ndpi_set_risk(ndpi_struct, flow, NDPI_DNS_LARGE_PACKET, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_DNS_LARGE_PACKET, NULL); + } } NDPI_LOG_DBG2(ndpi_struct, "Response: [num_queries=%d][num_answers=%d][reply_code=%u][rsp_type=%u][host_server_name=%s]\n", diff --git a/src/lib/protocols/http.c b/src/lib/protocols/http.c index 949e93e8c..25d78b1cf 100644 --- a/src/lib/protocols/http.c +++ b/src/lib/protocols/http.c @@ -199,11 +199,15 @@ static void ndpi_http_check_human_redeable_content(struct ndpi_detection_module_ && (content[3] == 0x00)) { /* Looks like compressed data */ } else { - char str[32]; - - snprintf(str, sizeof(str), "Susp content %02X%02X%02X%02X", - content[0], content[1], content[2], content[3]); - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_CONTENT, str); + if(ndpi_struct->cfg.flow_risk_infos_enabled) { + char str[32]; + + snprintf(str, sizeof(str), "Susp content %02X%02X%02X%02X", + content[0], content[1], content[2], content[3]); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_CONTENT, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_CONTENT, NULL); + } } } } @@ -493,7 +497,7 @@ static void ndpi_http_parse_subprotocol(struct ndpi_detection_module_struct *ndp if(packet->server_line.len > 7 && strncmp((const char *)packet->server_line.ptr, "ntopng ", 7) == 0) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_NTOP, NDPI_PROTOCOL_HTTP, NDPI_CONFIDENCE_DPI); - ndpi_unset_risk(flow, NDPI_KNOWN_PROTOCOL_ON_NON_STANDARD_PORT); + ndpi_unset_risk(ndpi_struct, flow, NDPI_KNOWN_PROTOCOL_ON_NON_STANDARD_PORT); } /* Matching on Content-Type. @@ -714,10 +718,14 @@ static void ndpi_check_user_agent(struct ndpi_detection_module_struct *ndpi_stru float upper_case_ratio = (float)upper_case_count / (float)ua_len; if (upper_case_ratio >= 0.2f) { - char str[64]; + if(ndpi_struct->cfg.flow_risk_infos_enabled) { + char str[64]; - snprintf(str, sizeof(str), "UA %s", ua); - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_USER_AGENT, str); + snprintf(str, sizeof(str), "UA %s", ua); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_USER_AGENT, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_USER_AGENT, NULL); + } } } } @@ -725,20 +733,28 @@ static void ndpi_check_user_agent(struct ndpi_detection_module_struct *ndpi_stru if((!strncmp(ua, "<?", 2)) || strchr(ua, '$') ) { - char str[64]; + if(ndpi_struct->cfg.flow_risk_infos_enabled) { + char str[64]; - snprintf(str, sizeof(str), "UA %s", ua); - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_USER_AGENT, str); + snprintf(str, sizeof(str), "UA %s", ua); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_USER_AGENT, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_USER_AGENT, NULL); + } } if((double_slash = strstr(ua, "://")) != NULL) { if(double_slash != ua) /* We're not at the beginning of the user agent */{ if((double_slash[-1] != 'p') /* http:// */ && (double_slash[-1] != 's') /* https:// */) { - char str[64]; + if(ndpi_struct->cfg.flow_risk_infos_enabled) { + char str[64]; - snprintf(str, sizeof(str), "UA %s", ua); - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_USER_AGENT, str); + snprintf(str, sizeof(str), "UA %s", ua); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_USER_AGENT, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_USER_AGENT, NULL); + } } } } @@ -766,11 +782,15 @@ static void ndpi_check_user_agent(struct ndpi_detection_module_struct *ndpi_stru || ndpi_strncasestr(ua, "Crawler", ua_len) || ndpi_strncasestr(ua, "Bot", ua_len) /* bot/robot */ ) { - char str[64]; + if(ndpi_struct->cfg.flow_risk_infos_enabled) { + char str[64]; - snprintf(str, sizeof(str), "UA %s", ua); + snprintf(str, sizeof(str), "UA %s", ua); - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_CRAWLER_BOT, str); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_CRAWLER_BOT, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_CRAWLER_BOT, NULL); + } } } @@ -839,7 +859,7 @@ static void http_process_user_agent(struct ndpi_detection_module_struct *ndpi_st } if(ndpi_user_agent_set(flow, ua_ptr, ua_ptr_len) != NULL) { - ndpi_unset_risk(flow, NDPI_HTTP_SUSPICIOUS_USER_AGENT); + ndpi_unset_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_USER_AGENT); ndpi_check_user_agent(ndpi_struct, flow, flow->http.user_agent, ua_ptr_len); } else { NDPI_LOG_DBG2(ndpi_struct, "Could not set HTTP user agent (already set?)\n"); @@ -865,10 +885,14 @@ static void ndpi_check_numeric_ip(struct ndpi_detection_module_struct *ndpi_stru ip_addr.s_addr = inet_addr(buf); if(strcmp(inet_ntoa(ip_addr), buf) == 0) { - char str[64]; + if(ndpi_struct->cfg.flow_risk_infos_enabled) { + char str[64]; - snprintf(str, sizeof(str), "Found host %s", buf); - ndpi_set_risk(ndpi_struct, flow, NDPI_NUMERIC_IP_HOST, str); + snprintf(str, sizeof(str), "Found host %s", buf); + ndpi_set_risk(ndpi_struct, flow, NDPI_NUMERIC_IP_HOST, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_NUMERIC_IP_HOST, NULL); + } } } @@ -911,11 +935,19 @@ static void ndpi_check_http_server(struct ndpi_detection_module_struct *ndpi_str char msg[64]; if((off == 7) && (version < MIN_APACHE_VERSION)) { - snprintf(msg, sizeof(msg), "Obsolete Apache server %s", buf); - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_OBSOLETE_SERVER, msg); + if(ndpi_struct->cfg.flow_risk_infos_enabled) { + snprintf(msg, sizeof(msg), "Obsolete Apache server %s", buf); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_OBSOLETE_SERVER, msg); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_OBSOLETE_SERVER, NULL); + } } else if((off == 6) && (version < MIN_NGINX_VERSION)) { - snprintf(msg, sizeof(msg), "Obsolete nginx server %s", buf); - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_OBSOLETE_SERVER, msg); + if(ndpi_struct->cfg.flow_risk_infos_enabled) { + snprintf(msg, sizeof(msg), "Obsolete nginx server %s", buf); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_OBSOLETE_SERVER, msg); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_OBSOLETE_SERVER, NULL); + } } } } @@ -1129,10 +1161,14 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_ if(ndpi_is_valid_hostname((char *)packet->host_line.ptr, packet->host_line.len) == 0) { - char str[128]; + if(ndpi_struct->cfg.flow_risk_infos_enabled) { + char str[128]; - snprintf(str, sizeof(str), "Invalid host %s", flow->host_server_name); - ndpi_set_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS, str); + snprintf(str, sizeof(str), "Invalid host %s", flow->host_server_name); + ndpi_set_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS, NULL); + } /* This looks like an attack */ ndpi_set_risk(ndpi_struct, flow, NDPI_POSSIBLE_EXPLOIT, "Suspicious hostname: attack ?"); @@ -1145,11 +1181,15 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_ /* IPv4 */ if(ndpi_struct->packet.iph->daddr != inet_addr(flow->host_server_name)) { - char buf[64], msg[128]; - - snprintf(msg, sizeof(msg), "Expected %s, found %s", - ndpi_intoav4(ntohl(ndpi_struct->packet.iph->daddr), buf, sizeof(buf)), flow->host_server_name); - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, msg); + if(ndpi_struct->cfg.flow_risk_infos_enabled) { + char buf[64], msg[128]; + + snprintf(msg, sizeof(msg), "Expected %s, found %s", + ndpi_intoav4(ntohl(ndpi_struct->packet.iph->daddr), buf, sizeof(buf)), flow->host_server_name); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, msg); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, NULL); + } } } } @@ -1286,82 +1326,118 @@ static void ndpi_check_http_header(struct ndpi_detection_module_struct *ndpi_str switch(packet->line[i].ptr[0]) { case 'A': if(is_a_suspicious_header(suspicious_http_header_keys_A, packet->line[i])) { - char str[64]; + if(ndpi_struct->cfg.flow_risk_infos_enabled) { + char str[64]; - snprintf(str, sizeof(str), "Found %.*s", packet->line[i].len, packet->line[i].ptr); - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, str); + snprintf(str, sizeof(str), "Found %.*s", packet->line[i].len, packet->line[i].ptr); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, NULL); + } return; } break; case 'C': if(is_a_suspicious_header(suspicious_http_header_keys_C, packet->line[i])) { - char str[64]; + if(ndpi_struct->cfg.flow_risk_infos_enabled) { + char str[64]; - snprintf(str, sizeof(str), "Found %.*s", packet->line[i].len, packet->line[i].ptr); - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, str); + snprintf(str, sizeof(str), "Found %.*s", packet->line[i].len, packet->line[i].ptr); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, NULL); + } return; } break; case 'M': if(is_a_suspicious_header(suspicious_http_header_keys_M, packet->line[i])) { - char str[64]; + if(ndpi_struct->cfg.flow_risk_infos_enabled) { + char str[64]; - snprintf(str, sizeof(str), "Found %.*s", packet->line[i].len, packet->line[i].ptr); - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, str); + snprintf(str, sizeof(str), "Found %.*s", packet->line[i].len, packet->line[i].ptr); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, NULL); + } return; } break; case 'O': if(is_a_suspicious_header(suspicious_http_header_keys_O, packet->line[i])) { - char str[64]; + if(ndpi_struct->cfg.flow_risk_infos_enabled) { + char str[64]; - snprintf(str, sizeof(str), "Found %.*s", packet->line[i].len, packet->line[i].ptr); - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, str); + snprintf(str, sizeof(str), "Found %.*s", packet->line[i].len, packet->line[i].ptr); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, NULL); + } return; } break; case 'R': if(is_a_suspicious_header(suspicious_http_header_keys_R, packet->line[i])) { - char str[64]; + if(ndpi_struct->cfg.flow_risk_infos_enabled) { + char str[64]; - snprintf(str, sizeof(str), "Found %.*s", packet->line[i].len, packet->line[i].ptr); - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, str); + snprintf(str, sizeof(str), "Found %.*s", packet->line[i].len, packet->line[i].ptr); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, NULL); + } return; } break; case 'S': if(is_a_suspicious_header(suspicious_http_header_keys_S, packet->line[i])) { - char str[64]; + if(ndpi_struct->cfg.flow_risk_infos_enabled) { + char str[64]; - snprintf(str, sizeof(str), "Found %.*s", packet->line[i].len, packet->line[i].ptr); - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, str); + snprintf(str, sizeof(str), "Found %.*s", packet->line[i].len, packet->line[i].ptr); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, NULL); + } return; } break; case 'T': if(is_a_suspicious_header(suspicious_http_header_keys_T, packet->line[i])) { - char str[64]; + if(ndpi_struct->cfg.flow_risk_infos_enabled) { + char str[64]; - snprintf(str, sizeof(str), "Found %.*s", packet->line[i].len, packet->line[i].ptr); - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, str); + snprintf(str, sizeof(str), "Found %.*s", packet->line[i].len, packet->line[i].ptr); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, NULL); + } return; } break; case 'U': if(is_a_suspicious_header(suspicious_http_header_keys_U, packet->line[i])) { - char str[64]; + if(ndpi_struct->cfg.flow_risk_infos_enabled) { + char str[64]; - snprintf(str, sizeof(str), "Found %.*s", packet->line[i].len, packet->line[i].ptr); - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, str); + snprintf(str, sizeof(str), "Found %.*s", packet->line[i].len, packet->line[i].ptr); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, NULL); + } return; } break; case 'X': if(is_a_suspicious_header(suspicious_http_header_keys_X, packet->line[i])) { - char str[64]; + if(ndpi_struct->cfg.flow_risk_infos_enabled) { + char str[64]; - snprintf(str, sizeof(str), "Found %.*s", packet->line[i].len, packet->line[i].ptr); - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, str); + snprintf(str, sizeof(str), "Found %.*s", packet->line[i].len, packet->line[i].ptr); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, NULL); + } return; } @@ -1557,19 +1633,19 @@ static void reset(struct ndpi_detection_module_struct *ndpi_struct, /* Reset flow risks. We should reset only those risks triggered by the previous HTTP response... */ /* TODO */ - ndpi_unset_risk(flow, NDPI_BINARY_APPLICATION_TRANSFER); - ndpi_unset_risk(flow, NDPI_HTTP_SUSPICIOUS_CONTENT); - ndpi_unset_risk(flow, NDPI_POSSIBLE_EXPLOIT); - ndpi_unset_risk(flow, NDPI_HTTP_SUSPICIOUS_USER_AGENT); - ndpi_unset_risk(flow, NDPI_HTTP_CRAWLER_BOT); - ndpi_unset_risk(flow, NDPI_NUMERIC_IP_HOST); - ndpi_unset_risk(flow, NDPI_URL_POSSIBLE_RCE_INJECTION); - ndpi_unset_risk(flow, NDPI_HTTP_OBSOLETE_SERVER); - ndpi_unset_risk(flow, NDPI_CLEAR_TEXT_CREDENTIALS); - ndpi_unset_risk(flow, NDPI_INVALID_CHARACTERS); - ndpi_unset_risk(flow, NDPI_HTTP_SUSPICIOUS_HEADER); - ndpi_unset_risk(flow, NDPI_ERROR_CODE_DETECTED); - ndpi_unset_risk(flow, NDPI_MALFORMED_PACKET); + ndpi_unset_risk(ndpi_struct, flow, NDPI_BINARY_APPLICATION_TRANSFER); + ndpi_unset_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_CONTENT); + ndpi_unset_risk(ndpi_struct, flow, NDPI_POSSIBLE_EXPLOIT); + ndpi_unset_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_USER_AGENT); + ndpi_unset_risk(ndpi_struct, flow, NDPI_HTTP_CRAWLER_BOT); + ndpi_unset_risk(ndpi_struct, flow, NDPI_NUMERIC_IP_HOST); + ndpi_unset_risk(ndpi_struct, flow, NDPI_URL_POSSIBLE_RCE_INJECTION); + ndpi_unset_risk(ndpi_struct, flow, NDPI_HTTP_OBSOLETE_SERVER); + ndpi_unset_risk(ndpi_struct, flow, NDPI_CLEAR_TEXT_CREDENTIALS); + ndpi_unset_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS); + ndpi_unset_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER); + ndpi_unset_risk(ndpi_struct, flow, NDPI_ERROR_CODE_DETECTED); + ndpi_unset_risk(ndpi_struct, flow, NDPI_MALFORMED_PACKET); } static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct, diff --git a/src/lib/protocols/quic.c b/src/lib/protocols/quic.c index abcda2704..e19e1b27a 100644 --- a/src/lib/protocols/quic.c +++ b/src/lib/protocols/quic.c @@ -1468,10 +1468,14 @@ void process_chlo(struct ndpi_detection_module_struct *ndpi_struct, if(ndpi_is_valid_hostname((char *)&crypto_data[tag_offset_start + prev_offset], len) == 0) { - char str[128]; + if(ndpi_struct->cfg.flow_risk_infos_enabled) { + char str[128]; - snprintf(str, sizeof(str), "Invalid host %s", flow->host_server_name); - ndpi_set_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS, str); + snprintf(str, sizeof(str), "Invalid host %s", flow->host_server_name); + ndpi_set_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS, NULL); + } /* This looks like an attack */ ndpi_set_risk(ndpi_struct, flow, NDPI_POSSIBLE_EXPLOIT, "Suspicious hostname: attack ?"); diff --git a/src/lib/protocols/stun.c b/src/lib/protocols/stun.c index 683559853..ac8cd8a47 100644 --- a/src/lib/protocols/stun.c +++ b/src/lib/protocols/stun.c @@ -882,7 +882,7 @@ static int stun_search_again(struct ndpi_detection_module_struct *ndpi_struct, reset_detected_protocol(flow); /* We keep the category related to STUN traffic */ /* STUN often triggers this risk; clear it. TODO: clear other risks? */ - ndpi_unset_risk(flow, NDPI_KNOWN_PROTOCOL_ON_NON_STANDARD_PORT); + ndpi_unset_risk(ndpi_struct, flow, NDPI_KNOWN_PROTOCOL_ON_NON_STANDARD_PORT); /* Give room for DTLS handshake, where we might have retransmissions and fragments */ diff --git a/src/lib/protocols/tls.c b/src/lib/protocols/tls.c index a2f6213bc..1dcae22c4 100644 --- a/src/lib/protocols/tls.c +++ b/src/lib/protocols/tls.c @@ -734,7 +734,7 @@ static void checkTLSSubprotocol(struct ndpi_detection_module_struct *ndpi_struct ndpi_set_detected_protocol(ndpi_struct, flow, cached_proto, __get_master(ndpi_struct, flow), NDPI_CONFIDENCE_DPI_CACHE); flow->category = ndpi_get_proto_category(ndpi_struct, ret); ndpi_check_subprotocol_risk(ndpi_struct, flow, cached_proto); - ndpi_unset_risk(flow, NDPI_NUMERIC_IP_HOST); + ndpi_unset_risk(ndpi_struct, flow, NDPI_NUMERIC_IP_HOST); } } } @@ -828,10 +828,13 @@ void processCertificateElements(struct ndpi_detection_module_struct *ndpi_struct ndpi_struct->cfg.tls_cert_issuer_enabled) { flow->protos.tls_quic.issuerDN = ndpi_strdup(rdnSeqBuf); if(ndpi_normalize_printable_string(rdnSeqBuf, rdn_len) == 0) { - char str[64]; - - snprintf(str, sizeof(str), "Invalid issuerDN %s", flow->protos.tls_quic.issuerDN); - ndpi_set_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS, str); + if(ndpi_struct->cfg.flow_risk_infos_enabled) { + char str[64]; + snprintf(str, sizeof(str), "Invalid issuerDN %s", flow->protos.tls_quic.issuerDN); + ndpi_set_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS, NULL); + } } } @@ -905,41 +908,53 @@ void processCertificateElements(struct ndpi_detection_module_struct *ndpi_struct if(flow->protos.tls_quic.notBefore > TLS_LIMIT_DATE) if((flow->protos.tls_quic.notAfter-flow->protos.tls_quic.notBefore) > TLS_THRESHOLD) { - char str[64]; + if(ndpi_struct->cfg.flow_risk_infos_enabled) { + char str[64]; - snprintf(str, sizeof(str), "TLS Cert lasts %u days", - (flow->protos.tls_quic.notAfter-flow->protos.tls_quic.notBefore) / 86400); + snprintf(str, sizeof(str), "TLS Cert lasts %u days", + (flow->protos.tls_quic.notAfter-flow->protos.tls_quic.notBefore) / 86400); - ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_CERT_VALIDITY_TOO_LONG, str); /* Certificate validity longer than 13 months */ + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_CERT_VALIDITY_TOO_LONG, str); /* Certificate validity longer than 13 months */ + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_CERT_VALIDITY_TOO_LONG, NULL); + } } if((time_sec < flow->protos.tls_quic.notBefore) || (time_sec > flow->protos.tls_quic.notAfter)) { - char str[96], b[32], e[32]; - struct tm result; - time_t theTime; + if(ndpi_struct->cfg.flow_risk_infos_enabled) { + char str[96], b[32], e[32]; + struct tm result; + time_t theTime; - theTime = flow->protos.tls_quic.notBefore; - strftime(b, sizeof(b), "%d/%b/%Y %H:%M:%S", ndpi_gmtime_r(&theTime, &result)); + theTime = flow->protos.tls_quic.notBefore; + strftime(b, sizeof(b), "%d/%b/%Y %H:%M:%S", ndpi_gmtime_r(&theTime, &result)); - theTime = flow->protos.tls_quic.notAfter; - strftime(e, sizeof(e), "%d/%b/%Y %H:%M:%S", ndpi_gmtime_r(&theTime, &result)); + theTime = flow->protos.tls_quic.notAfter; + strftime(e, sizeof(e), "%d/%b/%Y %H:%M:%S", ndpi_gmtime_r(&theTime, &result)); - snprintf(str, sizeof(str), "%s - %s", b, e); - ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_CERTIFICATE_EXPIRED, str); /* Certificate expired */ + snprintf(str, sizeof(str), "%s - %s", b, e); + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_CERTIFICATE_EXPIRED, str); /* Certificate expired */ + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_CERTIFICATE_EXPIRED, NULL); + } } else if((time_sec > flow->protos.tls_quic.notBefore) && (time_sec > (flow->protos.tls_quic.notAfter - (ndpi_struct->cfg.tls_certificate_expire_in_x_days * 86400)))) { - char str[96], b[32], e[32]; - struct tm result; - time_t theTime; + if(ndpi_struct->cfg.flow_risk_infos_enabled) { + char str[96], b[32], e[32]; + struct tm result; + time_t theTime; - theTime = flow->protos.tls_quic.notBefore; - strftime(b, sizeof(b), "%d/%b/%Y %H:%M:%S", ndpi_gmtime_r(&theTime, &result)); + theTime = flow->protos.tls_quic.notBefore; + strftime(b, sizeof(b), "%d/%b/%Y %H:%M:%S", ndpi_gmtime_r(&theTime, &result)); - theTime = flow->protos.tls_quic.notAfter; - strftime(e, sizeof(e), "%d/%b/%Y %H:%M:%S", ndpi_gmtime_r(&theTime, &result)); + theTime = flow->protos.tls_quic.notAfter; + strftime(e, sizeof(e), "%d/%b/%Y %H:%M:%S", ndpi_gmtime_r(&theTime, &result)); - snprintf(str, sizeof(str), "%s - %s", b, e); - ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_CERTIFICATE_ABOUT_TO_EXPIRE, str); /* Certificate almost expired */ + snprintf(str, sizeof(str), "%s - %s", b, e); + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_CERTIFICATE_ABOUT_TO_EXPIRE, str); /* Certificate almost expired */ + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_CERTIFICATE_ABOUT_TO_EXPIRE, NULL); + } } } } @@ -1075,7 +1090,7 @@ void processCertificateElements(struct ndpi_detection_module_struct *ndpi_struct !flow->protos.tls_quic.subprotocol_detected) { if(ndpi_match_hostname_protocol(ndpi_struct, flow, __get_master(ndpi_struct, flow), dNSName, dNSName_len)) { flow->protos.tls_quic.subprotocol_detected = 1; - ndpi_unset_risk(flow, NDPI_NUMERIC_IP_HOST); + ndpi_unset_risk(ndpi_struct, flow, NDPI_NUMERIC_IP_HOST); } } @@ -1096,10 +1111,14 @@ void processCertificateElements(struct ndpi_detection_module_struct *ndpi_struct } /* while */ if(!matched_name) { - char str[128]; + if(ndpi_struct->cfg.flow_risk_infos_enabled) { + char str[128]; - snprintf(str, sizeof(str), "%s vs %s", flow->host_server_name, flow->protos.tls_quic.server_names); - ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_CERTIFICATE_MISMATCH, str); /* Certificate mismatch */ + snprintf(str, sizeof(str), "%s vs %s", flow->host_server_name, flow->protos.tls_quic.server_names); + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_CERTIFICATE_MISMATCH, str); /* Certificate mismatch */ + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_CERTIFICATE_MISMATCH, NULL); /* Certificate mismatch */ + } } } } @@ -1126,7 +1145,7 @@ void processCertificateElements(struct ndpi_detection_module_struct *ndpi_struct ndpi_set_detected_protocol(ndpi_struct, flow, proto_id, __get_master(ndpi_struct, flow), NDPI_CONFIDENCE_DPI); flow->category = ndpi_get_proto_category(ndpi_struct, ret); ndpi_check_subprotocol_risk(ndpi_struct, flow, proto_id); - ndpi_unset_risk(flow, NDPI_NUMERIC_IP_HOST); + ndpi_unset_risk(ndpi_struct, flow, NDPI_NUMERIC_IP_HOST); if(ndpi_struct->tls_cert_cache) { u_int64_t key = make_tls_cert_key(packet, 0 /* from the server */); @@ -1596,7 +1615,7 @@ int ndpi_search_tls_tcp(struct ndpi_detection_module_struct *ndpi_struct, suited than NDPI_CONFIDENCE_DPI_CACHE */ ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_OOKLA, NDPI_PROTOCOL_TLS, NDPI_CONFIDENCE_DPI_AGGRESSIVE); /* TLS over port 8080 usually triggers that risk; clear it */ - ndpi_unset_risk(flow, NDPI_KNOWN_PROTOCOL_ON_NON_STANDARD_PORT); + ndpi_unset_risk(ndpi_struct, flow, NDPI_KNOWN_PROTOCOL_ON_NON_STANDARD_PORT); flow->extra_packets_func = NULL; return(0); /* That's all */ /* Loook for TLS-in-TLS */ @@ -1909,21 +1928,25 @@ static void tlsCheckUncommonALPN(struct ndpi_detection_module_struct *ndpi_struc alpn_len = comma_or_nul - alpn_start; if(!is_a_common_alpn(ndpi_struct, alpn_start, alpn_len)) { - char str[64]; - size_t str_len; + if(ndpi_struct->cfg.flow_risk_infos_enabled) { + char str[64]; + size_t str_len; #ifdef DEBUG_TLS - printf("TLS uncommon ALPN found: %.*s\n", (int)alpn_len, alpn_start); + printf("TLS uncommon ALPN found: %.*s\n", (int)alpn_len, alpn_start); #endif - str[0] = '\0'; - str_len = ndpi_min(alpn_len, sizeof(str)); - if(str_len > 0) { - strncpy(str, alpn_start, str_len); - str[str_len - 1] = '\0'; - } + str[0] = '\0'; + str_len = ndpi_min(alpn_len, sizeof(str)); + if(str_len > 0) { + strncpy(str, alpn_start, str_len); + str[str_len - 1] = '\0'; + } - ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_UNCOMMON_ALPN, str); + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_UNCOMMON_ALPN, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_UNCOMMON_ALPN, NULL); + } break; } @@ -2015,15 +2038,20 @@ static void checkExtensions(struct ndpi_detection_module_struct *ndpi_struct, } if(extension_found == 0) { - char str[64]; - - snprintf(str, sizeof(str), "Extn id %u", extension_id); #ifdef DEBUG_TLS - printf("[TLS] suspicious extension id: %u\n", extension_id); + printf("[TLS] suspicious extension id: %u\n", extension_id); #endif + + if(ndpi_struct->cfg.flow_risk_infos_enabled) { + char str[64]; + + snprintf(str, sizeof(str), "Extn id %u", extension_id); ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_SUSPICIOUS_EXTENSION, str); - return; - } + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_SUSPICIOUS_EXTENSION, NULL); + } + return; + } } /* Check for DTLS-only extensions. */ @@ -2031,14 +2059,18 @@ static void checkExtensions(struct ndpi_detection_module_struct *ndpi_struct, { if(extension_id == 53 || extension_id == 54) { - char str[64]; - - snprintf(str, sizeof(str), "Extn id %u", extension_id); - #ifdef DEBUG_TLS - printf("[TLS] suspicious DTLS-only extension id: %u\n", extension_id); + printf("[TLS] suspicious DTLS-only extension id: %u\n", extension_id); #endif - ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_SUSPICIOUS_EXTENSION, str); + + if(ndpi_struct->cfg.flow_risk_infos_enabled) { + char str[64]; + + snprintf(str, sizeof(str), "Extn id %u", extension_id); + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_SUSPICIOUS_EXTENSION, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_SUSPICIOUS_EXTENSION, NULL); + } return; } } @@ -2362,11 +2394,15 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, if(ndpi_struct->cfg.tls_cipher_enabled) { if((flow->protos.tls_quic.server_unsafe_cipher = ndpi_is_safe_ssl_cipher(ja.server.cipher[0])) != NDPI_CIPHER_SAFE) { - char str[64]; - char unknown_cipher[8]; + if(ndpi_struct->cfg.flow_risk_infos_enabled) { + char str[64]; + char unknown_cipher[8]; - snprintf(str, sizeof(str), "Cipher %s", ndpi_cipher2str(ja.server.cipher[0], unknown_cipher)); - ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_WEAK_CIPHER, str); + snprintf(str, sizeof(str), "Cipher %s", ndpi_cipher2str(ja.server.cipher[0], unknown_cipher)); + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_WEAK_CIPHER, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_WEAK_CIPHER, NULL); + } } flow->protos.tls_quic.server_cipher = ja.server.cipher[0]; @@ -2590,13 +2626,17 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, flow->protos.tls_quic.ssl_version = ja.client.tls_handshake_version = tls_version; if(flow->protos.tls_quic.ssl_version < 0x0303) /* < TLSv1.2 */ { - char str[32], buf[32]; - u_int8_t unknown_tls_version; - - snprintf(str, sizeof(str), "%s", ndpi_ssl_version2str(buf, sizeof(buf), - flow->protos.tls_quic.ssl_version, - &unknown_tls_version)); - ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_OBSOLETE_VERSION, str); + if(ndpi_struct->cfg.flow_risk_infos_enabled) { + char str[32], buf[32]; + u_int8_t unknown_tls_version; + + snprintf(str, sizeof(str), "%s", ndpi_ssl_version2str(buf, sizeof(buf), + flow->protos.tls_quic.ssl_version, + &unknown_tls_version)); + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_OBSOLETE_VERSION, str); + } else { + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_OBSOLETE_VERSION, NULL); + } } if((session_id_len+base_offset+3) > packet->payload_packet_len) diff --git a/tests/cfgs/flow_risk_infos_disabled/config.txt b/tests/cfgs/flow_risk_infos_disabled/config.txt new file mode 100644 index 000000000..a081f2099 --- /dev/null +++ b/tests/cfgs/flow_risk_infos_disabled/config.txt @@ -0,0 +1 @@ +--cfg=flow_risk_infos,0 diff --git a/tests/cfgs/flow_risk_infos_disabled/pcap/http_invalid_server.pcap b/tests/cfgs/flow_risk_infos_disabled/pcap/http_invalid_server.pcap new file mode 120000 index 000000000..5d0c340e8 --- /dev/null +++ b/tests/cfgs/flow_risk_infos_disabled/pcap/http_invalid_server.pcap @@ -0,0 +1 @@ +../../default/pcap/http_invalid_server.pcap
\ No newline at end of file diff --git a/tests/cfgs/flow_risk_infos_disabled/pcap/tls_malicious_sha1.pcapng b/tests/cfgs/flow_risk_infos_disabled/pcap/tls_malicious_sha1.pcapng new file mode 120000 index 000000000..c7cf588f0 --- /dev/null +++ b/tests/cfgs/flow_risk_infos_disabled/pcap/tls_malicious_sha1.pcapng @@ -0,0 +1 @@ +../../default/pcap/tls_malicious_sha1.pcapng
\ No newline at end of file diff --git a/tests/cfgs/flow_risk_infos_disabled/result/http_invalid_server.pcap.out b/tests/cfgs/flow_risk_infos_disabled/result/http_invalid_server.pcap.out new file mode 100644 index 000000000..b7daeae2d --- /dev/null +++ b/tests/cfgs/flow_risk_infos_disabled/result/http_invalid_server.pcap.out @@ -0,0 +1,27 @@ +DPI Packets (TCP): 6 (6.00 pkts/flow) +Confidence DPI : 1 (flows) +Num dissector calls: 16 (16.00 diss/flow) +LRU cache ookla: 0/0/0 (insert/search/found) +LRU cache bittorrent: 0/0/0 (insert/search/found) +LRU cache stun: 0/0/0 (insert/search/found) +LRU cache tls_cert: 0/0/0 (insert/search/found) +LRU cache mining: 0/0/0 (insert/search/found) +LRU cache msteams: 0/0/0 (insert/search/found) +LRU cache fpc_dns: 0/1/0 (insert/search/found) +Automa host: 1/0 (search/found) +Automa domain: 1/0 (search/found) +Automa tls cert: 0/0 (search/found) +Automa risk mask: 1/0 (search/found) +Automa common alpns: 0/0 (search/found) +Patricia risk mask: 2/0 (search/found) +Patricia risk mask IPv6: 0/0 (search/found) +Patricia risk: 0/0 (search/found) +Patricia risk IPv6: 0/0 (search/found) +Patricia protocols: 1/1 (search/found) +Patricia protocols IPv6: 0/0 (search/found) + +OCSP 12 1301 1 + +Safe 12 1301 1 + + 1 TCP 192.168.1.29:51536 <-> 143.204.14.183:80 [proto: 7.63/HTTP.OCSP][IP: 265/AmazonAWS][ClearText][Confidence: DPI][FPC: 265/AmazonAWS, Confidence: IP address][DPI packets: 6][cat: Web/5][7 pkts/556 bytes <-> 5 pkts/745 bytes][Goodput ratio: 15/55][0.04 sec][Hostname/SNI: ocsp.rootg2.amazontrust.com][bytes ratio: -0.145 (Mixed)][IAT c2s/s2c min/avg/max/stddev: 0/0 5/4 12/12 6/6][Pkt Len c2s/s2c min/avg/max/stddev: 66/66 79/149 148/468 28/160][URL: ocsp.rootg2.amazontrust.com/][StatusCode: 200][Content-Type: application/ocsp-response][Server: ¯\_(ツ)_/¯][User-Agent: **][Risk: ** HTTP Susp User-Agent **** HTTP Susp Header **][Risk Score: 200][TCP Fingerprint: 2_64_65535_d29295416479/macOS][PLAIN TEXT (GET / HTTP/1.1)][Plen Bins: 33,0,33,0,0,0,0,0,0,0,0,0,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] diff --git a/tests/cfgs/flow_risk_infos_disabled/result/tls_malicious_sha1.pcapng.out b/tests/cfgs/flow_risk_infos_disabled/result/tls_malicious_sha1.pcapng.out new file mode 100644 index 000000000..6eca74293 --- /dev/null +++ b/tests/cfgs/flow_risk_infos_disabled/result/tls_malicious_sha1.pcapng.out @@ -0,0 +1,32 @@ +DPI Packets (TCP): 8 (8.00 pkts/flow) +Confidence DPI : 1 (flows) +Num dissector calls: 1 (1.00 diss/flow) +LRU cache ookla: 0/0/0 (insert/search/found) +LRU cache bittorrent: 0/0/0 (insert/search/found) +LRU cache stun: 0/0/0 (insert/search/found) +LRU cache tls_cert: 0/2/0 (insert/search/found) +LRU cache mining: 0/0/0 (insert/search/found) +LRU cache msteams: 0/0/0 (insert/search/found) +LRU cache fpc_dns: 0/1/0 (insert/search/found) +Automa host: 2/0 (search/found) +Automa domain: 2/0 (search/found) +Automa tls cert: 1/0 (search/found) +Automa risk mask: 0/0 (search/found) +Automa common alpns: 2/2 (search/found) +Patricia risk mask: 0/0 (search/found) +Patricia risk mask IPv6: 0/0 (search/found) +Patricia risk: 0/0 (search/found) +Patricia risk IPv6: 1/0 (search/found) +Patricia protocols: 0/0 (search/found) +Patricia protocols IPv6: 1/1 (search/found) + +TLS 22 7204 1 + +Safe 22 7204 1 + +JA Host Stats: + IP Address # JA4C + 1 2001:b07:a3d:c112:9726:f643:a838:b0c4 1 + + + 1 TCP [2001:b07:a3d:c112:9726:f643:a838:b0c4]:40294 <-> [2a00:1450:4002:414::2013]:443 [proto: 91/TLS][IP: 126/Google][Encrypted][Confidence: DPI][FPC: 126/Google, Confidence: IP address][DPI packets: 8][cat: Web/5][12 pkts/1574 bytes <-> 10 pkts/5630 bytes][Goodput ratio: 34/85][0.12 sec][Hostname/SNI: www.prbtest.dev][(Advertised) ALPNs: h2;http/1.1][(Negotiated) ALPN: h2][bytes ratio: -0.563 (Download)][IAT c2s/s2c min/avg/max/stddev: 0/0 4/6 23/20 7/7][Pkt Len c2s/s2c min/avg/max/stddev: 86/86 131/563 316/2502 62/920][Risk: ** Malicious SSL Cert/SHA1 Fingerp. **][Risk Score: 50][TCP Fingerprint: 2_64_65320_5c453b01be6e/Unknown][TLSv1.2][JA4: t12d2808h2_d943125447b4_dd0a478c1db3][ServerNames: www.prbtest.dev][JA3S: e2bc06b738d7e5d2b0cec5d2196b1d80][Issuer: C=US, O=Google Trust Services LLC, CN=GTS CA 1D4][Subject: CN=www.prbtest.dev][Certificate SHA-1: 0D:DB:34:F8:75:63:2C:7E:1E:C0:9D:75:82:7F:82:D2:33:6D:FE:B6][Firefox][Validity: 2023-11-28 12:50:11 - 2024-02-26 13:39:22][Cipher: TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256][Plen Bins: 16,51,8,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16] |