diff options
author | Luca Deri <deri@ntop.org> | 2022-05-30 00:31:52 +0200 |
---|---|---|
committer | Luca Deri <deri@ntop.org> | 2022-05-30 00:32:32 +0200 |
commit | f25deeccb1ccbebd6346271828762fdd8326c32b (patch) | |
tree | 677c846f19b9b1468e6ec62637e77ae354fe0a24 | |
parent | a9d7cc4841ea098074b3dc0b42b7b6e73d4d8cd9 (diff) |
Added RiskInfo string
-rw-r--r-- | example/ndpiReader.c | 3 | ||||
-rw-r--r-- | example/reader_util.c | 10 | ||||
-rw-r--r-- | example/reader_util.h | 1 | ||||
-rw-r--r-- | src/include/ndpi_main.h | 3 | ||||
-rw-r--r-- | src/include/ndpi_typedefs.h | 5 | ||||
-rw-r--r-- | src/lib/ndpi_main.c | 61 | ||||
-rw-r--r-- | src/lib/ndpi_utils.c | 53 | ||||
-rw-r--r-- | src/lib/protocols/dns.c | 31 | ||||
-rw-r--r-- | src/lib/protocols/ftp_control.c | 2 | ||||
-rw-r--r-- | src/lib/protocols/http.c | 172 | ||||
-rw-r--r-- | src/lib/protocols/mail_imap.c | 2 | ||||
-rw-r--r-- | src/lib/protocols/mail_pop.c | 4 | ||||
-rw-r--r-- | src/lib/protocols/mail_smtp.c | 6 | ||||
-rw-r--r-- | src/lib/protocols/quic.c | 9 | ||||
-rw-r--r-- | src/lib/protocols/rdp.c | 2 | ||||
-rw-r--r-- | src/lib/protocols/smb.c | 2 | ||||
-rw-r--r-- | src/lib/protocols/snmp_proto.c | 8 | ||||
-rw-r--r-- | src/lib/protocols/ssh.c | 10 | ||||
-rw-r--r-- | src/lib/protocols/teamviewer.c | 4 | ||||
-rw-r--r-- | src/lib/protocols/telnet.c | 4 | ||||
-rw-r--r-- | src/lib/protocols/tls.c | 146 | ||||
-rw-r--r-- | src/lib/protocols/vnc.c | 2 |
22 files changed, 377 insertions, 163 deletions
diff --git a/example/ndpiReader.c b/example/ndpiReader.c index f8886fed1..d7dac2e15 100644 --- a/example/ndpiReader.c +++ b/example/ndpiReader.c @@ -1515,6 +1515,9 @@ static void printFlow(u_int32_t id, struct ndpi_flow_info *flow, u_int16_t threa fprintf(out, "]"); fprintf(out, "[Risk Score: %u]", ndpi_risk2score(flow->risk, &cli_score, &srv_score)); + + if(flow->risk_str) + fprintf(out, "[Risk Info: %s]", flow->risk_str); } if(flow->ssh_tls.ssl_version != 0) fprintf(out, "[%s]", ndpi_ssl_version2str(buf_ver, sizeof(buf_ver), diff --git a/example/reader_util.c b/example/reader_util.c index 49c647516..cb591d52e 100644 --- a/example/reader_util.c +++ b/example/reader_util.c @@ -541,6 +541,8 @@ void ndpi_flow_info_free_data(struct ndpi_flow_info *flow) { #else ndpi_free_bin(&flow->payload_len_bin); #endif + + if(flow->risk_str) ndpi_free(flow->risk_str); } /* ***************************************************** */ @@ -1036,11 +1038,17 @@ u_int8_t plen2slot(u_int16_t plen) { void process_ndpi_collected_info(struct ndpi_workflow * workflow, struct ndpi_flow_info *flow) { u_int i, is_quic = 0; - + char out[128], *s; + if(!flow->ndpi_flow) return; flow->info_type = INFO_INVALID; + s = ndpi_get_flow_risk_info(flow->ndpi_flow, out, sizeof(out)); + + if(s != NULL) + flow->risk_str = ndpi_strdup(s); + flow->confidence = flow->ndpi_flow->confidence; ndpi_snprintf(flow->host_server_name, sizeof(flow->host_server_name), "%s", diff --git a/example/reader_util.h b/example/reader_util.h index 6259de5f2..c2a152d38 100644 --- a/example/reader_util.h +++ b/example/reader_util.h @@ -198,6 +198,7 @@ typedef struct ndpi_flow_info { u_int32_t src2dst_packets, dst2src_packets; u_int32_t has_human_readeable_strings; char human_readeable_string_buffer[32]; + char *risk_str; // result only, not used for flow identification ndpi_protocol detected_protocol; diff --git a/src/include/ndpi_main.h b/src/include/ndpi_main.h index b62caa2bc..4c1f328ac 100644 --- a/src/include/ndpi_main.h +++ b/src/include/ndpi_main.h @@ -147,7 +147,8 @@ extern "C" { const u_int8_t ** l4ptr, u_int16_t * l4len, u_int8_t * nxt_hdr); void ndpi_set_risk(struct ndpi_detection_module_struct *ndpi_str, - struct ndpi_flow_struct *flow, ndpi_risk_enum r); + struct ndpi_flow_struct *flow, ndpi_risk_enum r, + char *risk_message); int ndpi_isset_risk(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow, ndpi_risk_enum r); int ndpi_is_printable_string(char * const str, size_t len); diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h index 5530f98bb..58a4d231f 100644 --- a/src/include/ndpi_typedefs.h +++ b/src/include/ndpi_typedefs.h @@ -169,6 +169,7 @@ typedef struct node_t { /* NDPI_MASK_SIZE */ typedef u_int32_t ndpi_ndpi_mask; +#define MAX_NUM_RISK_INFOS 8 /* NDPI_PROTO_BITMASK_STRUCT */ #ifdef NDPI_CFFI_PREPROCESSING @@ -1197,7 +1198,9 @@ struct ndpi_flow_struct { u_int8_t risk_checked:1, ip_risk_mask_evaluated:1, host_risk_mask_evaluated:1, tree_risk_checked:1, _notused:4; ndpi_risk risk_mask; /* Stores the flow risk mask for flow peers */ ndpi_risk risk; /* Issues found with this flow [bitmask of ndpi_risk] */ - + char *risk_infos[MAX_NUM_RISK_INFOS]; /* String that contains information about the risks found */ + u_int8_t num_risk_infos; + /* This structure below will not not stay inside the protos structure below as HTTP is used by many subprotocols diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c index 52c2b8f85..68c2bd244 100644 --- a/src/lib/ndpi_main.c +++ b/src/lib/ndpi_main.c @@ -3128,7 +3128,7 @@ u_int16_t ndpi_guess_protocol_id(struct ndpi_detection_module_struct *ndpi_str, /* Run some basic consistency tests */ if(packet->payload_packet_len < sizeof(struct ndpi_icmphdr)) - ndpi_set_risk(ndpi_str, flow, NDPI_MALFORMED_PACKET); + ndpi_set_risk(ndpi_str, flow, NDPI_MALFORMED_PACKET, NULL); else { u_int8_t icmp_type = (u_int8_t)packet->payload[0]; u_int8_t icmp_code = (u_int8_t)packet->payload[1]; @@ -3136,19 +3136,22 @@ u_int16_t ndpi_guess_protocol_id(struct ndpi_detection_module_struct *ndpi_str, /* https://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml */ if(((icmp_type >= 44) && (icmp_type <= 252)) || (icmp_code > 15)) - ndpi_set_risk(ndpi_str, flow, NDPI_MALFORMED_PACKET); + ndpi_set_risk(ndpi_str, flow, NDPI_MALFORMED_PACKET, NULL); if (packet->payload_packet_len > sizeof(struct ndpi_icmphdr)) { flow->entropy = ndpi_entropy(packet->payload + sizeof(struct ndpi_icmphdr), packet->payload_packet_len - sizeof(struct ndpi_icmphdr)); if (NDPI_ENTROPY_ENCRYPTED_OR_RANDOM(flow->entropy) != 0) { - ndpi_set_risk(ndpi_str, flow, NDPI_SUSPICIOUS_ENTROPY); + char str[32]; + + snprintf(str, sizeof(str), "Entropy %.2f", flow->entropy); + ndpi_set_risk(ndpi_str, flow, NDPI_SUSPICIOUS_ENTROPY, str); } u_int16_t chksm = ndpi_calculate_icmp4_checksum(packet->payload, packet->payload_packet_len); if (chksm) { - ndpi_set_risk(ndpi_str, flow, NDPI_MALFORMED_PACKET); + ndpi_set_risk(ndpi_str, flow, NDPI_MALFORMED_PACKET, NULL); } } } @@ -3175,7 +3178,7 @@ u_int16_t ndpi_guess_protocol_id(struct ndpi_detection_module_struct *ndpi_str, /* Run some basic consistency tests */ if(packet->payload_packet_len < sizeof(struct ndpi_icmphdr)) - ndpi_set_risk(ndpi_str, flow, NDPI_MALFORMED_PACKET); + ndpi_set_risk(ndpi_str, flow, NDPI_MALFORMED_PACKET, NULL); else { u_int8_t icmp6_type = (u_int8_t)packet->payload[0]; u_int8_t icmp6_code = (u_int8_t)packet->payload[1]; @@ -3183,7 +3186,7 @@ u_int16_t ndpi_guess_protocol_id(struct ndpi_detection_module_struct *ndpi_str, /* https://en.wikipedia.org/wiki/Internet_Control_Message_Protocol_for_IPv6 */ if(((icmp6_type >= 5) && (icmp6_type <= 127)) || ((icmp6_code >= 156) && (icmp6_type != 255))) - ndpi_set_risk(ndpi_str, flow, NDPI_MALFORMED_PACKET); + ndpi_set_risk(ndpi_str, flow, NDPI_MALFORMED_PACKET, NULL); } } return(NDPI_PROTOCOL_IP_ICMPV6); @@ -4709,6 +4712,13 @@ static u_int8_t ndpi_detection_get_l4_internal(struct ndpi_detection_module_stru void ndpi_free_flow_data(struct ndpi_flow_struct* flow) { if(flow) { + if(flow->num_risk_infos) { + u_int i; + + for(i=0; i<flow->num_risk_infos; i++) + ndpi_free(flow->risk_infos[i]); + } + if(flow->http.url) ndpi_free(flow->http.url); @@ -5305,12 +5315,12 @@ static void ndpi_reconcile_protocols(struct ndpi_detection_module_struct *ndpi_s break; case NDPI_PROTOCOL_RDP: - ndpi_set_risk(ndpi_str, flow, NDPI_DESKTOP_OR_FILE_SHARING_SESSION); /* Remote assistance */ + ndpi_set_risk(ndpi_str, flow, NDPI_DESKTOP_OR_FILE_SHARING_SESSION, "Found RDP"); /* Remote assistance */ break; case NDPI_PROTOCOL_ANYDESK: if(flow->l4_proto == IPPROTO_TCP) /* TCP only */ - ndpi_set_risk(ndpi_str, flow, NDPI_DESKTOP_OR_FILE_SHARING_SESSION); /* Remote assistance */ + ndpi_set_risk(ndpi_str, flow, NDPI_DESKTOP_OR_FILE_SHARING_SESSION, "Found AnyDesk"); /* Remote assistance */ break; } /* switch */ @@ -5319,7 +5329,7 @@ static void ndpi_reconcile_protocols(struct ndpi_detection_module_struct *ndpi_s case NDPI_PROTOCOL_UNSAFE: case NDPI_PROTOCOL_POTENTIALLY_DANGEROUS: case NDPI_PROTOCOL_DANGEROUS: - ndpi_set_risk(ndpi_str, flow, NDPI_UNSAFE_PROTOCOL); + ndpi_set_risk(ndpi_str, flow, NDPI_UNSAFE_PROTOCOL, NULL); break; default: /* Nothing to do */ @@ -6152,7 +6162,7 @@ ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct if((r == NULL) || ((r->proto->protoId != ret.app_protocol) && (r->proto->protoId != ret.master_protocol))) - ndpi_set_risk(ndpi_str, flow, NDPI_KNOWN_PROTOCOL_ON_NON_STANDARD_PORT); + ndpi_set_risk(ndpi_str, flow, NDPI_KNOWN_PROTOCOL_ON_NON_STANDARD_PORT, NULL); } } } else if((!ndpi_is_ntop_protocol(&ret)) && default_ports && (default_ports[0] != 0)) { @@ -6182,7 +6192,7 @@ ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct if((r == NULL) || ((r->proto->protoId != ret.app_protocol) && (r->proto->protoId != ret.master_protocol))) - ndpi_set_risk(ndpi_str, flow, NDPI_KNOWN_PROTOCOL_ON_NON_STANDARD_PORT); + ndpi_set_risk(ndpi_str, flow, NDPI_KNOWN_PROTOCOL_ON_NON_STANDARD_PORT,NULL); } } @@ -6203,8 +6213,9 @@ ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct addr.s_addr = packet->iph->daddr; net_risk = ndpi_network_risk_ptree_match(ndpi_str, &addr); } + if(net_risk != NDPI_NO_RISK) - ndpi_set_risk(ndpi_str, flow, net_risk); + ndpi_set_risk(ndpi_str, flow, net_risk, NULL); } } flow->tree_risk_checked = 1; @@ -7653,7 +7664,7 @@ void ndpi_check_subprotocol_risk(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow, u_int16_t subprotocol_id) { switch(subprotocol_id) { case NDPI_PROTOCOL_ANYDESK: - ndpi_set_risk(ndpi_str, flow, NDPI_DESKTOP_OR_FILE_SHARING_SESSION); /* Remote assistance */ + ndpi_set_risk(ndpi_str, flow, NDPI_DESKTOP_OR_FILE_SHARING_SESSION, "Found AnyDesk"); /* Remote assistance */ break; } } @@ -7686,15 +7697,23 @@ u_int16_t ndpi_match_host_subprotocol(struct ndpi_detection_module_struct *ndpi_ if(ndpi_str->risky_domain_automa.ac_automa != NULL) { u_int32_t proto_id; u_int16_t rc1 = ndpi_match_string_common(ndpi_str->risky_domain_automa.ac_automa, - string_to_match,string_to_match_len, + string_to_match, string_to_match_len, &proto_id, NULL, NULL); - if(rc1 > 0) - ndpi_set_risk(ndpi_str, flow, NDPI_RISKY_DOMAIN); + if(rc1 > 0) { + 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); + } } /* Add punycode check */ - if(ndpi_strnstr(string_to_match, "xn--", string_to_match_len)) - ndpi_set_risk(ndpi_str, flow, NDPI_PUNYCODE_IDN); + if(ndpi_strnstr(string_to_match, "xn--", string_to_match_len)) { + 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); + } return(rc); } @@ -8191,7 +8210,7 @@ int ndpi_check_dga_name(struct ndpi_detection_module_struct *ndpi_str, if(rc) { if(flow) - ndpi_set_risk(ndpi_str, flow, NDPI_SUSPICIOUS_DGA_DOMAIN); + ndpi_set_risk(ndpi_str, flow, NDPI_SUSPICIOUS_DGA_DOMAIN, name); } return(rc); @@ -8340,7 +8359,7 @@ int ndpi_check_dga_name(struct ndpi_detection_module_struct *ndpi_str, || ((max_domain_element_len >= 19 /* word too long. Example bbcbedxhgjmdobdprmen.com */) && ((num_char_repetitions > 1) || (num_digits > 1))) ) { if(flow) { - ndpi_set_risk(ndpi_str, flow, NDPI_SUSPICIOUS_DGA_DOMAIN); + ndpi_set_risk(ndpi_str, flow, NDPI_SUSPICIOUS_DGA_DOMAIN, name); } if(ndpi_verbose_dga_detection) @@ -8501,7 +8520,7 @@ int ndpi_check_dga_name(struct ndpi_detection_module_struct *ndpi_str, printf("[DGA] Result: %u\n", rc); if(rc && flow) - ndpi_set_risk(ndpi_str, flow, NDPI_SUSPICIOUS_DGA_DOMAIN); + ndpi_set_risk(ndpi_str, flow, NDPI_SUSPICIOUS_DGA_DOMAIN, name); return(rc); } diff --git a/src/lib/ndpi_utils.c b/src/lib/ndpi_utils.c index e5739ae5c..6d832115b 100644 --- a/src/lib/ndpi_utils.c +++ b/src/lib/ndpi_utils.c @@ -1286,7 +1286,7 @@ int ndpi_dpi2json(struct ndpi_detection_module_struct *ndpi_struct, ndpi_serialize_start_of_block(serializer, "http"); if(flow->host_server_name[0] != '\0') ndpi_serialize_string_string(serializer, "hostname", flow->host_server_name); - if(flow->http.url != NULL){ + if(flow->http.url != NULL) { ndpi_serialize_string_string(serializer, "url", flow->http.url); ndpi_serialize_string_uint32(serializer, "code", flow->http.response_status_code); ndpi_serialize_string_string(serializer, "content_type", flow->http.content_type); @@ -2239,12 +2239,27 @@ static void ndpi_handle_risk_exceptions(struct ndpi_detection_module_struct *ndp /* ******************************************************************** */ void ndpi_set_risk(struct ndpi_detection_module_struct *ndpi_str, - struct ndpi_flow_struct *flow, ndpi_risk_enum r) { - ndpi_risk v = 1ull << r; + struct ndpi_flow_struct *flow, ndpi_risk_enum r, + char *risk_message) { + /* Check if the risk is not yet set */ + if(!ndpi_isset_risk(ndpi_str, flow, r)) { + ndpi_risk v = 1ull << r; + + // NDPI_SET_BIT(flow->risk, (u_int32_t)r); + flow->risk |= v; + + ndpi_handle_risk_exceptions(ndpi_str, flow); - // NDPI_SET_BIT(flow->risk, (u_int32_t)r); - flow->risk |= v; - ndpi_handle_risk_exceptions(ndpi_str, flow); + if(risk_message != NULL) { + if(flow->num_risk_infos < MAX_NUM_RISK_INFOS) { + char *s = ndpi_strdup(risk_message); + + if(s != NULL) { + flow->risk_infos[flow->num_risk_infos++] = s; + } + } + } + } } /* ******************************************************************** */ @@ -2501,6 +2516,32 @@ int ndpi_snprintf(char * str, size_t size, char const * format, ...) { va_start(va_args, format); int ret = ndpi_vsnprintf(str, size, format, va_args); va_end(va_args); + return ret; } +/* ******************************************* */ + +char* ndpi_get_flow_risk_info(struct ndpi_flow_struct *flow, + char *out, u_int out_len) { + if(out == NULL) + return(NULL); + else + out[0] = '\0'; + + if(flow->num_risk_infos) { + u_int i, offset = 0; + for(i=0; i<flow->num_risk_infos; i++) { + int rc = snprintf(&out[offset], out_len-offset, "%s%s", + (i == 0) ? "" : " / ", + flow->risk_infos[i]); + + if(rc <= 0) + break; + else + offset += rc; + } + } + + return(out[0] == '\0' ? NULL : out); +} diff --git a/src/lib/protocols/dns.c b/src/lib/protocols/dns.c index 58c9f968c..8c387e304 100644 --- a/src/lib/protocols/dns.c +++ b/src/lib/protocols/dns.c @@ -94,7 +94,7 @@ static void ndpi_check_dns_type(struct ndpi_detection_module_struct *ndpi_struct case 106: case 107: case 259: - ndpi_set_risk(ndpi_struct, flow, NDPI_DNS_SUSPICIOUS_TRAFFIC); + ndpi_set_risk(ndpi_struct, flow, NDPI_DNS_SUSPICIOUS_TRAFFIC, NULL); break; } } @@ -220,7 +220,7 @@ static int search_valid_dns(struct ndpi_detection_module_struct *ndpi_struct, else if((dns_header->flags & FLAGS_MASK) == 0x8000) *is_query = 0; else { - ndpi_set_risk(ndpi_struct, flow, NDPI_MALFORMED_PACKET); + ndpi_set_risk(ndpi_struct, flow, NDPI_MALFORMED_PACKET, "Invalid DNS Flags"); return(1 /* invalid */); } @@ -246,15 +246,19 @@ static int search_valid_dns(struct ndpi_detection_module_struct *ndpi_struct, x++; } } else { - ndpi_set_risk(ndpi_struct, flow, NDPI_MALFORMED_PACKET); + ndpi_set_risk(ndpi_struct, flow, NDPI_MALFORMED_PACKET, "Invalid DNS Header"); return(1 /* invalid */); } } else { /* DNS Reply */ flow->protos.dns.reply_code = dns_header->flags & 0x0F; - if(flow->protos.dns.reply_code != 0) - ndpi_set_risk(ndpi_struct, flow, NDPI_ERROR_CODE_DETECTED); + if(flow->protos.dns.reply_code != 0) { + char str[32]; + + snprintf(str, sizeof(str), "DNS Error Code %d", flow->protos.dns.reply_code); + ndpi_set_risk(ndpi_struct, flow, NDPI_ERROR_CODE_DETECTED, str); + } if((dns_header->num_queries > 0) && (dns_header->num_queries <= NDPI_MAX_DNS_REQUESTS) /* Don't assume that num_queries must be zero */ && ((((dns_header->num_answers > 0) && (dns_header->num_answers <= NDPI_MAX_DNS_REQUESTS)) @@ -463,7 +467,7 @@ static void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, st #ifdef DNS_DEBUG printf("[DNS] Invalid query len [%u >= %u]\n", i+4, packet->payload_packet_len); #endif - ndpi_set_risk(ndpi_struct, flow, NDPI_MALFORMED_PACKET); + ndpi_set_risk(ndpi_struct, flow, NDPI_MALFORMED_PACKET, "Invalid DNS Query Lenght"); break; } else { idx = i+5, num_queries++; @@ -507,7 +511,7 @@ static void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, st ndpi_hostname_sni_set(flow, (const u_int8_t *)_hostname, j); if (hostname_is_valid == 0) - ndpi_set_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS); + ndpi_set_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS, NULL); if(j > 0) { ndpi_protocol_match_result ret_match; @@ -577,9 +581,14 @@ static void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, st if((flow->detected_protocol_stack[0] == NDPI_PROTOCOL_DNS) || (flow->detected_protocol_stack[1] == NDPI_PROTOCOL_DNS)) { /* TODO: add support to RFC6891 to avoid some false positives */ - if(packet->udp != NULL && packet->payload_packet_len > PKT_LEN_ALERT) - ndpi_set_risk(ndpi_struct, flow, NDPI_DNS_LARGE_PACKET); + if((packet->udp != NULL) + && (packet->payload_packet_len > PKT_LEN_ALERT)) { + 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); + } + if(packet->iph != NULL) { /* IPv4 */ u_int8_t flags = ((u_int8_t*)packet->iph)[6]; @@ -587,14 +596,14 @@ static void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, st /* 0: fragmented; 1: not fragmented */ if((flags & 0x20) || (ndpi_iph_is_valid_and_not_fragmented(packet->iph, packet->l3_packet_len) == 0)) { - ndpi_set_risk(ndpi_struct, flow, NDPI_DNS_FRAGMENTED); + ndpi_set_risk(ndpi_struct, flow, NDPI_DNS_FRAGMENTED, NULL); } } else if(packet->iphv6 != NULL) { /* IPv6 */ const struct ndpi_ip6_hdrctl *ip6_hdr = &packet->iphv6->ip6_hdr; if(ip6_hdr->ip6_un1_nxt == 0x2C /* Next Header: Fragment Header for IPv6 (44) */) { - ndpi_set_risk(ndpi_struct, flow, NDPI_DNS_FRAGMENTED); + ndpi_set_risk(ndpi_struct, flow, NDPI_DNS_FRAGMENTED, NULL); } } } diff --git a/src/lib/protocols/ftp_control.c b/src/lib/protocols/ftp_control.c index 6cc5c612a..ff624c419 100644 --- a/src/lib/protocols/ftp_control.c +++ b/src/lib/protocols/ftp_control.c @@ -53,7 +53,7 @@ static int ndpi_ftp_control_check_request(struct ndpi_detection_module_struct *n ndpi_user_pwd_payload_copy((u_int8_t*)flow->l4.tcp.ftp_imap_pop_smtp.username, sizeof(flow->l4.tcp.ftp_imap_pop_smtp.username), 5, payload, payload_len); - ndpi_set_risk(ndpi_struct, flow, NDPI_CLEAR_TEXT_CREDENTIALS); + ndpi_set_risk(ndpi_struct, flow, NDPI_CLEAR_TEXT_CREDENTIALS, "Found FTP username"); return 1; } diff --git a/src/lib/protocols/http.c b/src/lib/protocols/http.c index 257585512..4788a4e52 100644 --- a/src/lib/protocols/http.c +++ b/src/lib/protocols/http.c @@ -52,14 +52,15 @@ static void ndpi_search_http_tcp(struct ndpi_detection_module_struct *ndpi_struc /* *********************************************** */ static void ndpi_set_binary_application_transfer(struct ndpi_detection_module_struct *ndpi_struct, - struct ndpi_flow_struct *flow) { + struct ndpi_flow_struct *flow, + char *msg) { /* Check known exceptions */ if(ndpi_ends_with((char*)flow->host_server_name, ".windowsupdate.com")) ; else - ndpi_set_risk(ndpi_struct, flow, NDPI_BINARY_APPLICATION_TRANSFER); + ndpi_set_risk(ndpi_struct, flow, NDPI_BINARY_APPLICATION_TRANSFER, msg); } /* *********************************************** */ @@ -67,29 +68,30 @@ static void ndpi_set_binary_application_transfer(struct ndpi_detection_module_st static void ndpi_analyze_content_signature(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { u_int8_t set_risk = 0; + const char *msg = NULL; if((flow->initial_binary_bytes_len >= 2) && (flow->initial_binary_bytes[0] == 0x4D) && (flow->initial_binary_bytes[1] == 0x5A)) - set_risk = 1; /* Win executable */ + set_risk = 1, msg = "Found Windows Exe"; /* Win executable */ else if((flow->initial_binary_bytes_len >= 4) && (flow->initial_binary_bytes[0] == 0x7F) && (flow->initial_binary_bytes[1] == 'E') && (flow->initial_binary_bytes[2] == 'L') && (flow->initial_binary_bytes[3] == 'F')) - set_risk = 1; /* Linux executable */ + set_risk = 1, msg = "Found Linux Exe"; /* Linux executable */ else if((flow->initial_binary_bytes_len >= 4) && (flow->initial_binary_bytes[0] == 0xCF) && (flow->initial_binary_bytes[1] == 0xFA) && (flow->initial_binary_bytes[2] == 0xED) && (flow->initial_binary_bytes[3] == 0xFE)) - set_risk = 1; /* Linux executable */ + set_risk = 1, msg = "Found Linux Exe"; /* Linux executable */ else if((flow->initial_binary_bytes_len >= 3) && (flow->initial_binary_bytes[0] == '#') && (flow->initial_binary_bytes[1] == '!') && (flow->initial_binary_bytes[2] == '/')) - set_risk = 1; /* Unix script (e.g. #!/bin/sh) */ + set_risk = 1, msg = "Found Unix Script"; /* Unix script (e.g. #!/bin/sh) */ else if(flow->initial_binary_bytes_len >= 8) { u_int8_t exec_pattern[] = { 0x64, 0x65, 0x78, 0x0A, 0x30, 0x33, 0x35, 0x00 }; if(memcmp(flow->initial_binary_bytes, exec_pattern, 8) == 0) - set_risk = 1; /* Dalvik Executable (Android) */ + set_risk = 1, msg = "Found Android Exe"; /* Dalvik Executable (Android) */ } if(set_risk) - ndpi_set_binary_application_transfer(ndpi_struct, flow); + ndpi_set_binary_application_transfer(ndpi_struct, flow, (char*)msg); } /* *********************************************** */ @@ -148,8 +150,13 @@ static void ndpi_http_check_human_redeable_content(struct ndpi_detection_module_ && (content[2] == 0x08) && (content[3] == 0x00)) { /* Looks like compressed data */ - } else - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_CONTENT); + } 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); + } } } } @@ -197,7 +204,7 @@ static void ndpi_validate_http_content(struct ndpi_detection_module_struct *ndpi https://corelight.com/blog/detecting-log4j-exploits-via-zeek-when-java-downloads-java */ - ndpi_set_risk(ndpi_struct, flow, NDPI_POSSIBLE_EXPLOIT); + ndpi_set_risk(ndpi_struct, flow, NDPI_POSSIBLE_EXPLOIT, "Suspicious Log4J"); } } @@ -258,8 +265,11 @@ static ndpi_protocol_category_t ndpi_http_check_content(struct ndpi_detection_mo for(i = 0; cmp_mimes[i] != NULL; i++) { if(strncasecmp(app, cmp_mimes[i], app_len_avail) == 0) { + char str[64]; + + snprintf(str, sizeof(str), "Found mime exe %s", cmp_mimes[i]); flow->guessed_category = flow->category = NDPI_PROTOCOL_CATEGORY_DOWNLOAD_FT; - ndpi_set_binary_application_transfer(ndpi_struct, flow); + ndpi_set_binary_application_transfer(ndpi_struct, flow, str); NDPI_LOG_INFO(ndpi_struct, "Found executable HTTP transfer"); return(flow->category); } @@ -287,8 +297,11 @@ static ndpi_protocol_category_t ndpi_http_check_content(struct ndpi_detection_mo /* Use memcmp in case content-disposition contains binary data */ if(memcmp(&packet->content_disposition_line.ptr[attachment_len], binary_file_ext[i], ATTACHMENT_LEN) == 0) { + char str[64]; + + snprintf(str, sizeof(str), "Found file extn %s", binary_file_ext[i]); flow->guessed_category = flow->category = NDPI_PROTOCOL_CATEGORY_DOWNLOAD_FT; - ndpi_set_binary_application_transfer(ndpi_struct, flow); + ndpi_set_binary_application_transfer(ndpi_struct, flow, str); NDPI_LOG_INFO(ndpi_struct, "found executable HTTP transfer"); return(flow->category); } @@ -414,7 +427,7 @@ static void ndpi_check_user_agent(struct ndpi_detection_module_struct *ndpi_stru struct ndpi_flow_struct *flow, char const *ua, size_t ua_len) { char *double_slash; - + if((!ua) || (ua[0] == '\0')) return; @@ -438,32 +451,42 @@ static void ndpi_check_user_agent(struct ndpi_detection_module_struct *ndpi_stru } } - if (i == ua_len) - { + if (i == ua_len) { float upper_case_ratio = (float)upper_case_count / (float)ua_len; - if (upper_case_ratio >= 0.2f) - { - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_USER_AGENT); + + if (upper_case_ratio >= 0.2f) { + char str[64]; + + snprintf(str, sizeof(str), "UA %s", ua); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_USER_AGENT, str); } } } if((!strncmp(ua, "<?", 2)) || strchr(ua, '$') - ) - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_USER_AGENT); + ) { + char str[64]; + + snprintf(str, sizeof(str), "UA %s", ua); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_USER_AGENT, str); + } 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:// */) - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_USER_AGENT); + && (double_slash[-1] != 's') /* https:// */) { + char str[64]; + + snprintf(str, sizeof(str), "UA %s", ua); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_USER_AGENT, str); + } } } - + /* no else */ if(!strncmp(ua, "jndi:ldap://", 12)) /* Log4J */ { - ndpi_set_risk(ndpi_struct, flow, NDPI_POSSIBLE_EXPLOIT); + ndpi_set_risk(ndpi_struct, flow, NDPI_POSSIBLE_EXPLOIT, "Suspicious Log4J"); } else if( (ua_len < 4) /* Too short */ || (ua_len > 256) /* Too long */ @@ -471,7 +494,7 @@ static void ndpi_check_user_agent(struct ndpi_detection_module_struct *ndpi_stru || strchr(ua, '{') || strchr(ua, '}') ) { - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_USER_AGENT); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_USER_AGENT, "Suspicious Log4J"); } /* @@ -484,7 +507,11 @@ 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 */ ) { - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_CRAWLER_BOT); + char str[64]; + + snprintf(str, sizeof(str), "UA %s", ua); + + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_CRAWLER_BOT, str); } } @@ -579,8 +606,12 @@ static void ndpi_check_numeric_ip(struct ndpi_detection_module_struct *ndpi_stru double_dot[0] = '\0'; ip_addr.s_addr = inet_addr(buf); - if(strcmp(inet_ntoa(ip_addr), buf) == 0) - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_NUMERIC_IP_HOST); + if(strcmp(inet_ntoa(ip_addr), buf) == 0) { + char str[64]; + + snprintf(str, sizeof(str), "Found host %s", buf); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_NUMERIC_IP_HOST, str); + } } /* ************************************************************* */ @@ -651,7 +682,7 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_ || (flow->http.method == NDPI_HTTP_METHOD_RPC_OUT_DATA)) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_RPC, flow->detected_protocol_stack[0], NDPI_CONFIDENCE_DPI); check_content_type_and_change_protocol(ndpi_struct, flow); - } + } } if(packet->server_line.ptr != NULL && (packet->server_line.len > 7)) { @@ -681,16 +712,19 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_ if(strlen(flow->host_server_name) > 0) { ndpi_check_dga_name(ndpi_struct, flow, flow->host_server_name, 1); - + if(ndpi_is_valid_hostname(flow->host_server_name, strlen(flow->host_server_name)) == 0) { - ndpi_set_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS); - + char str[64]; + + snprintf(str, sizeof(str), "Invalid host %s", flow->host_server_name); + ndpi_set_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS, str); + /* This looks like an attack */ - ndpi_set_risk(ndpi_struct, flow, NDPI_POSSIBLE_EXPLOIT); + ndpi_set_risk(ndpi_struct, flow, NDPI_POSSIBLE_EXPLOIT, NULL); } } - + if(packet->forwarded_line.ptr) { if(flow->http.nat_ip == NULL) { len = packet->forwarded_line.len; @@ -766,7 +800,8 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_ "Basic", packet->authorization_line.len) || ndpi_strncasestr((const char*)packet->authorization_line.ptr, "Digest", packet->authorization_line.len)) { - ndpi_set_risk(ndpi_struct, flow, NDPI_CLEAR_TEXT_CREDENTIALS); + ndpi_set_risk(ndpi_struct, flow, NDPI_CLEAR_TEXT_CREDENTIALS, + "Found credentials in HTTP Auth Line"); } } @@ -942,55 +977,82 @@ 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])) { - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER); + char str[64]; + + snprintf(str, sizeof(str), "Found %s", packet->line[i].ptr); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, str); return; } break; case 'C': if(is_a_suspicious_header(suspicious_http_header_keys_C, packet->line[i])) { - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER); + char str[64]; + + snprintf(str, sizeof(str), "Found %s", packet->line[i].ptr); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, str); return; } break; case 'M': if(is_a_suspicious_header(suspicious_http_header_keys_M, packet->line[i])) { - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER); + char str[64]; + + snprintf(str, sizeof(str), "Found %s", packet->line[i].ptr); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, str); return; } break; case 'O': if(is_a_suspicious_header(suspicious_http_header_keys_O, packet->line[i])) { - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER); + char str[64]; + + snprintf(str, sizeof(str), "Found %s", packet->line[i].ptr); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, str); return; } break; case 'R': if(is_a_suspicious_header(suspicious_http_header_keys_R, packet->line[i])) { - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER); + char str[64]; + + snprintf(str, sizeof(str), "Found %s", packet->line[i].ptr); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, str); return; } break; case 'S': if(is_a_suspicious_header(suspicious_http_header_keys_S, packet->line[i])) { - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER); + char str[64]; + + snprintf(str, sizeof(str), "Found %s", packet->line[i].ptr); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, str); return; } break; case 'T': if(is_a_suspicious_header(suspicious_http_header_keys_T, packet->line[i])) { - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER); + char str[64]; + + snprintf(str, sizeof(str), "Found %s", packet->line[i].ptr); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, str); return; } break; case 'U': if(is_a_suspicious_header(suspicious_http_header_keys_U, packet->line[i])) { - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER); + char str[64]; + + snprintf(str, sizeof(str), "Found %s", packet->line[i].ptr); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, str); return; } break; case 'X': if(is_a_suspicious_header(suspicious_http_header_keys_X, packet->line[i])) { - ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER); + char str[64]; + + snprintf(str, sizeof(str), "Found %s", packet->line[i].ptr); + ndpi_set_risk(ndpi_struct, flow, NDPI_HTTP_SUSPICIOUS_HEADER, str); return; } @@ -998,6 +1060,7 @@ static void ndpi_check_http_header(struct ndpi_detection_module_struct *ndpi_str } } } + /*************************************************************************************************/ static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct, @@ -1036,25 +1099,28 @@ static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct buf[3] = '\0'; flow->http.response_status_code = atoi(buf); - + /* https://en.wikipedia.org/wiki/List_of_HTTP_status_codes */ if((flow->http.response_status_code < 100) || (flow->http.response_status_code > 509)) flow->http.response_status_code = 0; /* Out of range */ else if(flow->http.response_status_code >= 400) { + char ec[48]; + if(flow->http.url != NULL) { /* Let's check for Wordpress */ char *slash = strchr(flow->http.url, '/'); - + if( ((flow->http.method == NDPI_HTTP_METHOD_POST) && (strncmp(slash, "/wp-admin/", 10) == 0)) - || ((flow->http.method == NDPI_HTTP_METHOD_GET) && (strncmp(slash, "/wp-content/uploads/", 20) == 0)) + || ((flow->http.method == NDPI_HTTP_METHOD_GET) && (strncmp(slash, "/wp-content/uploads/", 20) == 0)) ) { /* Example of popular exploits https://www.wordfence.com/blog/2022/05/millions-of-attacks-target-tatsu-builder-plugin/ */ - ndpi_set_risk(ndpi_struct, flow, NDPI_POSSIBLE_EXPLOIT); + ndpi_set_risk(ndpi_struct, flow, NDPI_POSSIBLE_EXPLOIT, "Possible Wordpress Exploit"); } } - - ndpi_set_risk(ndpi_struct, flow, NDPI_ERROR_CODE_DETECTED); + + snprintf(ec, sizeof(ec), "HTTP Error Code %u", flow->http.response_status_code); + ndpi_set_risk(ndpi_struct, flow, NDPI_ERROR_CODE_DETECTED, ec); } } @@ -1158,7 +1224,7 @@ static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct packet->http_method.ptr = packet->line[0].ptr; packet->http_method.len = filename_start - 1; - + /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */ flow->l4.tcp.http_stage = packet->packet_direction + 1; // packet_direction 0: stage 1, packet_direction 1: stage 2 return; @@ -1341,7 +1407,7 @@ static void ndpi_search_http_tcp(struct ndpi_detection_module_struct *ndpi_struc ndpi_http_method ndpi_get_http_method(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { if(!flow) { - ndpi_set_risk(ndpi_struct, flow, NDPI_MALFORMED_PACKET); + ndpi_set_risk(ndpi_struct, flow, NDPI_MALFORMED_PACKET, (char*)"Unknown HTTP Method"); return(NDPI_HTTP_METHOD_UNKNOWN); } else return(flow->http.method); diff --git a/src/lib/protocols/mail_imap.c b/src/lib/protocols/mail_imap.c index 6877a61cf..2195e9f6e 100644 --- a/src/lib/protocols/mail_imap.c +++ b/src/lib/protocols/mail_imap.c @@ -182,7 +182,7 @@ void ndpi_search_mail_imap_tcp(struct ndpi_detection_module_struct *ndpi_struct, sizeof(flow->l4.tcp.ftp_imap_pop_smtp.username), "%s", user); - ndpi_set_risk(ndpi_struct, flow, NDPI_CLEAR_TEXT_CREDENTIALS); + ndpi_set_risk(ndpi_struct, flow, NDPI_CLEAR_TEXT_CREDENTIALS, "Found IMAP Username"); pwd = strtok_r(NULL, " \"\r\n", &saveptr); if(pwd) { diff --git a/src/lib/protocols/mail_pop.c b/src/lib/protocols/mail_pop.c index 2dca5d39b..7d6a03284 100644 --- a/src/lib/protocols/mail_pop.c +++ b/src/lib/protocols/mail_pop.c @@ -81,7 +81,7 @@ static int ndpi_int_mail_pop_check_for_client_commands(struct ndpi_detection_mod sizeof(flow->l4.tcp.ftp_imap_pop_smtp.username), 5, packet->payload, packet->payload_packet_len); - ndpi_set_risk(ndpi_struct, flow, NDPI_CLEAR_TEXT_CREDENTIALS); + ndpi_set_risk(ndpi_struct, flow, NDPI_CLEAR_TEXT_CREDENTIALS, "Found username"); flow->l4.tcp.pop_command_bitmask |= POP_BIT_USER; return 1; } else if((packet->payload[0] == 'P' || packet->payload[0] == 'p') @@ -92,7 +92,7 @@ static int ndpi_int_mail_pop_check_for_client_commands(struct ndpi_detection_mod sizeof(flow->l4.tcp.ftp_imap_pop_smtp.password), 5, packet->payload, packet->payload_packet_len); - ndpi_set_risk(ndpi_struct, flow, NDPI_CLEAR_TEXT_CREDENTIALS); + ndpi_set_risk(ndpi_struct, flow, NDPI_CLEAR_TEXT_CREDENTIALS, "Found password"); flow->l4.tcp.pop_command_bitmask |= POP_BIT_PASS; return 1; } else if((packet->payload[0] == 'C' || packet->payload[0] == 'c') diff --git a/src/lib/protocols/mail_smtp.c b/src/lib/protocols/mail_smtp.c index 9d183976f..e3e5cecc9 100644 --- a/src/lib/protocols/mail_smtp.c +++ b/src/lib/protocols/mail_smtp.c @@ -98,7 +98,7 @@ static void get_credentials_auth_plain(struct ndpi_detection_module_struct *ndpi memcpy(flow->l4.tcp.ftp_imap_pop_smtp.username, out + 1, user_len); flow->l4.tcp.ftp_imap_pop_smtp.username[user_len] = '\0'; - ndpi_set_risk(ndpi_struct, flow, NDPI_CLEAR_TEXT_CREDENTIALS); + ndpi_set_risk(ndpi_struct, flow, NDPI_CLEAR_TEXT_CREDENTIALS, "Found username"); if(1 + user_len + 1 < out_len) { unsigned int pwd_len; @@ -254,7 +254,7 @@ void ndpi_search_mail_smtp_tcp(struct ndpi_detection_module_struct *ndpi_struct, ndpi_free(out); } - ndpi_set_risk(ndpi_struct, flow, NDPI_CLEAR_TEXT_CREDENTIALS); + ndpi_set_risk(ndpi_struct, flow, NDPI_CLEAR_TEXT_CREDENTIALS, "Found username"); } else if(flow->l4.tcp.ftp_imap_pop_smtp.password[0] == '\0') { /* Password */ u_int8_t buf[48]; @@ -279,7 +279,7 @@ void ndpi_search_mail_smtp_tcp(struct ndpi_detection_module_struct *ndpi_struct, ndpi_free(out); } - ndpi_set_risk(ndpi_struct, flow, NDPI_CLEAR_TEXT_CREDENTIALS); + ndpi_set_risk(ndpi_struct, flow, NDPI_CLEAR_TEXT_CREDENTIALS, "Found password"); flow->l4.tcp.ftp_imap_pop_smtp.auth_done = 1; } else { diff --git a/src/lib/protocols/quic.c b/src/lib/protocols/quic.c index d3512cd9b..0f1d37a70 100644 --- a/src/lib/protocols/quic.c +++ b/src/lib/protocols/quic.c @@ -1395,10 +1395,13 @@ static void process_chlo(struct ndpi_detection_module_struct *ndpi_struct, if(ndpi_is_valid_hostname(flow->host_server_name, strlen(flow->host_server_name)) == 0) { - ndpi_set_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS); + char str[64]; + + snprintf(str, sizeof(str), "Invalid host %s", flow->host_server_name); + ndpi_set_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS, str); /* This looks like an attack */ - ndpi_set_risk(ndpi_struct, flow, NDPI_POSSIBLE_EXPLOIT); + ndpi_set_risk(ndpi_struct, flow, NDPI_POSSIBLE_EXPLOIT, NULL); } sni_found = 1; @@ -1426,7 +1429,7 @@ static void process_chlo(struct ndpi_detection_module_struct *ndpi_struct, /* Add check for missing SNI */ if(flow->host_server_name[0] == '\0') { /* This is a bit suspicious */ - ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_MISSING_SNI); + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_MISSING_SNI, NULL); } } diff --git a/src/lib/protocols/rdp.c b/src/lib/protocols/rdp.c index ec4e6a4a5..b63c5a6a6 100644 --- a/src/lib/protocols/rdp.c +++ b/src/lib/protocols/rdp.c @@ -52,7 +52,7 @@ void ndpi_search_rdp(struct ndpi_detection_module_struct *ndpi_struct, NDPI_LOG_INFO(ndpi_struct, "found RDP\n"); rdp_found: ndpi_int_rdp_add_connection(ndpi_struct, flow); - ndpi_set_risk(ndpi_struct, flow, NDPI_DESKTOP_OR_FILE_SHARING_SESSION); /* Remote assistance */ + ndpi_set_risk(ndpi_struct, flow, NDPI_DESKTOP_OR_FILE_SHARING_SESSION, "Found RDP"); /* Remote assistance */ return; } diff --git a/src/lib/protocols/smb.c b/src/lib/protocols/smb.c index ae18816eb..6ae319ccf 100644 --- a/src/lib/protocols/smb.c +++ b/src/lib/protocols/smb.c @@ -46,7 +46,7 @@ void ndpi_search_smb_tcp(struct ndpi_detection_module_struct *ndpi_struct, struc if(memcmp(&packet->payload[4], smbv1, sizeof(smbv1)) == 0) { if(packet->payload[8] != 0x72) /* Skip Negotiate request */ { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_SMBV1, NDPI_PROTOCOL_NETBIOS, NDPI_CONFIDENCE_DPI); - ndpi_set_risk(ndpi_struct, flow, NDPI_SMB_INSECURE_VERSION); + ndpi_set_risk(ndpi_struct, flow, NDPI_SMB_INSECURE_VERSION, "Found SMBv1"); } } else ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_SMBV23, NDPI_PROTOCOL_NETBIOS, NDPI_CONFIDENCE_DPI); diff --git a/src/lib/protocols/snmp_proto.c b/src/lib/protocols/snmp_proto.c index 07d5ce35f..12ca29d82 100644 --- a/src/lib/protocols/snmp_proto.c +++ b/src/lib/protocols/snmp_proto.c @@ -151,8 +151,12 @@ void ndpi_search_snmp(struct ndpi_detection_module_struct *ndpi_struct, flow->protos.snmp.error_status = error_status; - if(error_status != 0) - ndpi_set_risk(ndpi_struct, flow, NDPI_ERROR_CODE_DETECTED); + if(error_status != 0) { + char str[64]; + + snprintf(str, sizeof(str), "SNMP Error %d", error_status); + ndpi_set_risk(ndpi_struct, flow, NDPI_ERROR_CODE_DETECTED, str); + } } } } diff --git a/src/lib/protocols/ssh.c b/src/lib/protocols/ssh.c index 714faf5cb..16b9ffe58 100644 --- a/src/lib/protocols/ssh.c +++ b/src/lib/protocols/ssh.c @@ -128,7 +128,7 @@ static void ssh_analyse_cipher(struct ndpi_detection_module_struct *ndpi_struct, char *rem; char *cipher; - u_int8_t found_obsolete_cipher = 0; + u_int found_obsolete_cipher = 0; char *cipher_copy; /* List of obsolete ciphers can be found at @@ -161,7 +161,7 @@ static void ssh_analyse_cipher(struct ndpi_detection_module_struct *ndpi_struct, for(i = 0; obsolete_ciphers[i]; i++) { if(strcmp(cipher, obsolete_ciphers[i]) == 0) { - found_obsolete_cipher = 1; + found_obsolete_cipher = i; #ifdef SSH_DEBUG printf("[SSH] [SSH obsolete %s cipher][%s]\n", is_client_signature ? "client" : "server", @@ -175,8 +175,12 @@ static void ssh_analyse_cipher(struct ndpi_detection_module_struct *ndpi_struct, } if(found_obsolete_cipher) { + char str[64]; + + snprintf(str, sizeof(str), "Found cipher %s", obsolete_ciphers[found_obsolete_cipher]); ndpi_set_risk(ndpi_struct, flow, - (is_client_signature ? NDPI_SSH_OBSOLETE_CLIENT_VERSION_OR_CIPHER : NDPI_SSH_OBSOLETE_SERVER_VERSION_OR_CIPHER)); + (is_client_signature ? NDPI_SSH_OBSOLETE_CLIENT_VERSION_OR_CIPHER : NDPI_SSH_OBSOLETE_SERVER_VERSION_OR_CIPHER), + str); } ndpi_free(cipher_copy); diff --git a/src/lib/protocols/teamviewer.c b/src/lib/protocols/teamviewer.c index 9c602a55e..53b78f8a4 100644 --- a/src/lib/protocols/teamviewer.c +++ b/src/lib/protocols/teamviewer.c @@ -72,7 +72,7 @@ void ndpi_search_teamview(struct ndpi_detection_module_struct *ndpi_struct, stru if (flow->l4.udp.teamviewer_stage == 4 || packet->udp->dest == ntohs(5938) || packet->udp->source == ntohs(5938)) { ndpi_int_teamview_add_connection(ndpi_struct, flow); - ndpi_set_risk(ndpi_struct, flow, NDPI_DESKTOP_OR_FILE_SHARING_SESSION); /* Remote assistance (UDP only) */ + ndpi_set_risk(ndpi_struct, flow, NDPI_DESKTOP_OR_FILE_SHARING_SESSION, "Found TeamViewer"); /* Remote assistance (UDP only) */ } return; } @@ -93,7 +93,7 @@ void ndpi_search_teamview(struct ndpi_detection_module_struct *ndpi_struct, stru flow->l4.udp.teamviewer_stage++; if (flow->l4.udp.teamviewer_stage == 4) { ndpi_int_teamview_add_connection(ndpi_struct, flow); - ndpi_set_risk(ndpi_struct, flow, NDPI_DESKTOP_OR_FILE_SHARING_SESSION); /* Remote assistance (UDP only) */ + ndpi_set_risk(ndpi_struct, flow, NDPI_DESKTOP_OR_FILE_SHARING_SESSION, "Found TeamViewer"); /* Remote assistance (UDP only) */ } } return; diff --git a/src/lib/protocols/telnet.c b/src/lib/protocols/telnet.c index bfc8c3d86..45ab36d0b 100644 --- a/src/lib/protocols/telnet.c +++ b/src/lib/protocols/telnet.c @@ -63,7 +63,7 @@ static int search_telnet_again(struct ndpi_detection_module_struct *ndpi_struct, return(1); flow->protos.telnet.password_detected = 1; - ndpi_set_risk(ndpi_struct, flow, NDPI_CLEAR_TEXT_CREDENTIALS); + ndpi_set_risk(ndpi_struct, flow, NDPI_CLEAR_TEXT_CREDENTIALS, "Found password"); flow->protos.telnet.password[flow->protos.telnet.character_id] = '\0'; return(0); } @@ -90,7 +90,7 @@ static int search_telnet_again(struct ndpi_detection_module_struct *ndpi_struct, if(packet->payload[0] == '\r') { flow->protos.telnet.username_detected = 1; - ndpi_set_risk(ndpi_struct, flow, NDPI_CLEAR_TEXT_CREDENTIALS); + ndpi_set_risk(ndpi_struct, flow, NDPI_CLEAR_TEXT_CREDENTIALS, "Found username"); flow->protos.telnet.username[flow->protos.telnet.character_id] = '\0'; flow->protos.telnet.character_id = 0; return(1); diff --git a/src/lib/protocols/tls.c b/src/lib/protocols/tls.c index a878e21ae..aef6ede7e 100644 --- a/src/lib/protocols/tls.c +++ b/src/lib/protocols/tls.c @@ -395,7 +395,10 @@ static void processCertificateElements(struct ndpi_detection_module_struct *ndpi if(rdn_len && (flow->protos.tls_quic.issuerDN == NULL)) { flow->protos.tls_quic.issuerDN = ndpi_strdup(rdnSeqBuf); if(ndpi_is_printable_string(rdnSeqBuf, rdn_len) == 0) { - ndpi_set_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS); + 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); } } @@ -465,14 +468,43 @@ static void processCertificateElements(struct ndpi_detection_module_struct *ndpi } if(flow->protos.tls_quic.notBefore > TLS_LIMIT_DATE) - if((flow->protos.tls_quic.notAfter-flow->protos.tls_quic.notBefore) > TLS_THRESHOLD) - ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_CERT_VALIDITY_TOO_LONG); /* Certificate validity longer than 13 months */ - - if((time_sec < flow->protos.tls_quic.notBefore) || (time_sec > flow->protos.tls_quic.notAfter)) - ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_CERTIFICATE_EXPIRED); /* Certificate expired */ - else if((time_sec > flow->protos.tls_quic.notBefore) - && (time_sec > (flow->protos.tls_quic.notAfter - (ndpi_struct->tls_certificate_expire_in_x_days * 86400)))) - ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_CERTIFICATE_ABOUT_TO_EXPIRE); /* Certificate almost expired */ + if((flow->protos.tls_quic.notAfter-flow->protos.tls_quic.notBefore) > TLS_THRESHOLD) { + char str[64]; + + 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 */ + } + + if((time_sec < flow->protos.tls_quic.notBefore) || (time_sec > flow->protos.tls_quic.notAfter)) { + char str[64], 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", localtime_r(&theTime, &result)); + + theTime = flow->protos.tls_quic.notAfter; + strftime(e, sizeof(e), "%d/%b/%Y %H:%M:%S", localtime_r(&theTime, &result)); + + snprintf(str, sizeof(str), "%s - %s", b, e); + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_CERTIFICATE_EXPIRED, str); /* Certificate expired */ + } else if((time_sec > flow->protos.tls_quic.notBefore) + && (time_sec > (flow->protos.tls_quic.notAfter - (ndpi_struct->tls_certificate_expire_in_x_days * 86400)))) { + char str[64], 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", localtime_r(&theTime, &result)); + + theTime = flow->protos.tls_quic.notAfter; + strftime(e, sizeof(e), "%d/%b/%Y %H:%M:%S", localtime_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 */ + } } } } @@ -556,10 +588,10 @@ static void processCertificateElements(struct ndpi_detection_module_struct *ndpi here that will create false positives */ if(ndpi_is_printable_string(dNSName, dNSName_len) == 0) { - ndpi_set_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS); + ndpi_set_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS, dNSName); /* This looks like an attack */ - ndpi_set_risk(ndpi_struct, flow, NDPI_POSSIBLE_EXPLOIT); + ndpi_set_risk(ndpi_struct, flow, NDPI_POSSIBLE_EXPLOIT, NULL); } if(matched_name == 0) { @@ -614,7 +646,7 @@ static void processCertificateElements(struct ndpi_detection_module_struct *ndpi #if DEBUG_TLS printf("[TLS] Leftover %u bytes", packet->payload_packet_len - i); #endif - ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_SUSPICIOUS_EXTENSION); + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_SUSPICIOUS_EXTENSION, NULL); break; } } else { @@ -622,8 +654,12 @@ static void processCertificateElements(struct ndpi_detection_module_struct *ndpi } } /* while */ - if(!matched_name) - ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_CERTIFICATE_MISMATCH); /* Certificate mismatch */ + if(!matched_name) { + 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 */ + } } } } @@ -677,7 +713,7 @@ static void processCertificateElements(struct ndpi_detection_module_struct *ndpi head = head->next; } - ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_SELFSIGNED_CERTIFICATE); + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_SELFSIGNED_CERTIFICATE, flow->protos.tls_quic.subjectDN); } #if DEBUG_TLS @@ -707,7 +743,7 @@ int processCertificate(struct ndpi_detection_module_struct *ndpi_struct, if((packet->payload_packet_len != (length + 4 + (is_dtls ? 8 : 0))) || (packet->payload[1] != 0x0) || certificates_offset >= packet->payload_packet_len) { - ndpi_set_risk(ndpi_struct, flow, NDPI_MALFORMED_PACKET); + ndpi_set_risk(ndpi_struct, flow, NDPI_MALFORMED_PACKET, NULL); return(-1); /* Invalid length */ } @@ -716,7 +752,7 @@ int processCertificate(struct ndpi_detection_module_struct *ndpi_struct, packet->payload[certificates_offset - 1]; if((packet->payload[certificates_offset - 3] != 0x0) || ((certificates_length+3) != length)) { - ndpi_set_risk(ndpi_struct, flow, NDPI_MALFORMED_PACKET); + ndpi_set_risk(ndpi_struct, flow, NDPI_MALFORMED_PACKET, NULL); return(-2); /* Invalid length */ } @@ -791,7 +827,7 @@ int processCertificate(struct ndpi_detection_module_struct *ndpi_struct, u_int16_t rc1 = ndpi_match_string(ndpi_struct->malicious_sha1_automa.ac_automa, sha1_str); if(rc1 > 0) - ndpi_set_risk(ndpi_struct, flow, NDPI_MALICIOUS_SHA1_CERTIFICATE); + ndpi_set_risk(ndpi_struct, flow, NDPI_MALICIOUS_SHA1_CERTIFICATE, sha1_str); } processCertificateElements(ndpi_struct, flow, certificates_offset, certificate_len); @@ -949,7 +985,7 @@ static int ndpi_search_tls_tcp(struct ndpi_detection_module_struct *ndpi_struct, u_int8_t alert_level = flow->l4.tcp.tls.message.buffer[5]; if(alert_level == 2 /* Warning (1), Fatal (2) */) - ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_FATAL_ALERT); + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_FATAL_ALERT, NULL); } u_int16_t const alert_len = ntohs(*(u_int16_t const *)&flow->l4.tcp.tls.message.buffer[3]); @@ -1179,10 +1215,14 @@ 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] = { '\0' }; + #ifdef DEBUG_TLS printf("TLS uncommon ALPN found: %.*s\n", (int)alpn_len, alpn_start); #endif - ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_UNCOMMON_ALPN); + + strncpy(str, alpn_start, alpn_len); + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_UNCOMMON_ALPN, str); break; } @@ -1234,7 +1274,7 @@ static void checkExtensions(struct ndpi_detection_module_struct *ndpi_struct, printf("[TLS] extension length exceeds remaining packet length: %u > %u.\n", extension_len, packet->payload_packet_len - extension_payload_offset); #endif - ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_SUSPICIOUS_EXTENSION); + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_SUSPICIOUS_EXTENSION, NULL); return; } @@ -1260,20 +1300,21 @@ static void checkExtensions(struct ndpi_detection_module_struct *ndpi_struct, u_int8_t extension_found = 0; size_t i; - for (i = 0; i < allowed_non_iana_extensions_size; ++i) - { - if(allowed_non_iana_extensions[i] == extension_id) - { - extension_found = 1; - break; - } + for (i = 0; i < allowed_non_iana_extensions_size; ++i) { + if(allowed_non_iana_extensions[i] == extension_id) { + extension_found = 1; + break; } - if(extension_found == 0) - { + } + + 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); #endif - ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_SUSPICIOUS_EXTENSION); + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_SUSPICIOUS_EXTENSION, str); return; } } @@ -1283,10 +1324,14 @@ 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); #endif - ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_SUSPICIOUS_EXTENSION); + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_SUSPICIOUS_EXTENSION, str); return; } } @@ -1371,9 +1416,13 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, return(0); /* Not found */ ja3.server.num_cipher = 1, ja3.server.cipher[0] = ntohs(*((u_int16_t*)&packet->payload[offset])); - if((flow->protos.tls_quic.server_unsafe_cipher = ndpi_is_safe_ssl_cipher(ja3.server.cipher[0])) == 1) - ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_WEAK_CIPHER); + if((flow->protos.tls_quic.server_unsafe_cipher = ndpi_is_safe_ssl_cipher(ja3.server.cipher[0])) == 1) { + char str[64]; + snprintf(str, sizeof(str), "Cipher %08X", ja3.server.cipher[0]); + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_WEAK_CIPHER, str); + } + flow->protos.tls_quic.server_cipher = ja3.server.cipher[0]; #ifdef DEBUG_TLS @@ -1453,18 +1502,17 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, alpn_str_len++; } - for(alpn_i=0; alpn_i<alpn_len; alpn_i++) - { + for(alpn_i=0; alpn_i<alpn_len; alpn_i++) { alpn_str[alpn_str_len+alpn_i] = packet->payload[s_offset+alpn_i]; } s_offset += alpn_len, alpn_str_len += alpn_len;; } else { - ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_UNCOMMON_ALPN); + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_UNCOMMON_ALPN, alpn_str); break; } } else { - ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_UNCOMMON_ALPN); + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_UNCOMMON_ALPN, alpn_str); break; } } /* while */ @@ -1475,7 +1523,7 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, printf("Server TLS [ALPN: %s][len: %u]\n", alpn_str, alpn_str_len); #endif if(ndpi_is_printable_string(alpn_str, alpn_str_len) == 0) - ndpi_set_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS); + ndpi_set_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS, alpn_str); if(flow->protos.tls_quic.alpn == NULL) flow->protos.tls_quic.alpn = ndpi_strdup(alpn_str); @@ -1590,9 +1638,13 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, ja3.client.alpn[0] = '\0'; flow->protos.tls_quic.ssl_version = ja3.client.tls_handshake_version = tls_version; - if(flow->protos.tls_quic.ssl_version < 0x0303) /* < TLSv1.2 */ - ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_OBSOLETE_VERSION); + if(flow->protos.tls_quic.ssl_version < 0x0303) /* < TLSv1.2 */ { + char str[32]; + snprintf(str, sizeof(str), "%04X", flow->protos.tls_quic.ssl_version); + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_OBSOLETE_VERSION, str); + } + if((session_id_len+base_offset+3) > packet->payload_packet_len) return(0); /* Not found */ @@ -1801,10 +1853,10 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, printf("[TLS] SNI: [%s]\n", sni); #endif if(ndpi_is_valid_hostname(sni, sni_len) == 0) { - ndpi_set_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS); + ndpi_set_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS, sni); /* This looks like an attack */ - ndpi_set_risk(ndpi_struct, flow, NDPI_POSSIBLE_EXPLOIT); + ndpi_set_risk(ndpi_struct, flow, NDPI_POSSIBLE_EXPLOIT, NULL); } if(!is_quic) { @@ -2325,21 +2377,21 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, flow->protos.tls_quic.ja3_client); if(rc1 > 0) - ndpi_set_risk(ndpi_struct, flow, NDPI_MALICIOUS_JA3); + ndpi_set_risk(ndpi_struct, flow, NDPI_MALICIOUS_JA3, flow->protos.tls_quic.ja3_client); } } /* Before returning to the caller we need to make a final check */ if((flow->protos.tls_quic.ssl_version >= 0x0303) /* >= TLSv1.2 */ && (flow->protos.tls_quic.alpn == NULL) /* No ALPN */) { - ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_NOT_CARRYING_HTTPS); + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_NOT_CARRYING_HTTPS, "No ALPN"); } /* Suspicious Domain Fronting: https://github.com/SixGenInc/Noctilucent/blob/master/docs/ */ if(flow->protos.tls_quic.encrypted_sni.esni && flow->host_server_name[0] != '\0') { - ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_SUSPICIOUS_ESNI_USAGE); + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_SUSPICIOUS_ESNI_USAGE, "Found ESNI w/o SNI"); } /* Add check for missing SNI */ @@ -2348,7 +2400,7 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, && (flow->protos.tls_quic.encrypted_sni.esni == NULL) /* No ESNI */ ) { /* This is a bit suspicious */ - ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_MISSING_SNI); + ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_MISSING_SNI, NULL); } return(2 /* Client Certificate */); diff --git a/src/lib/protocols/vnc.c b/src/lib/protocols/vnc.c index b949b2063..0d351d213 100644 --- a/src/lib/protocols/vnc.c +++ b/src/lib/protocols/vnc.c @@ -51,7 +51,7 @@ void ndpi_search_vnc_tcp(struct ndpi_detection_module_struct *ndpi_struct, struc ((memcmp(packet->payload, "RFB 004.", 7) == 0) && (packet->payload[11] == 0x0a)))) { NDPI_LOG_INFO(ndpi_struct, "found vnc\n"); ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_VNC, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); - ndpi_set_risk(ndpi_struct, flow, NDPI_DESKTOP_OR_FILE_SHARING_SESSION); /* Remote assistance */ + ndpi_set_risk(ndpi_struct, flow, NDPI_DESKTOP_OR_FILE_SHARING_SESSION, "Found VNC"); /* Remote assistance */ return; } } |