aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/ndpi_typedefs.h1
-rw-r--r--src/lib/ndpi_main.c63
-rw-r--r--src/lib/ndpi_utils.c4
-rw-r--r--src/lib/protocols/dhcp.c10
-rw-r--r--src/lib/protocols/dns.c19
-rw-r--r--src/lib/protocols/http.c9
-rw-r--r--src/lib/protocols/tls.c12
7 files changed, 84 insertions, 34 deletions
diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h
index 3784f995a..f81d80073 100644
--- a/src/include/ndpi_typedefs.h
+++ b/src/include/ndpi_typedefs.h
@@ -73,6 +73,7 @@ typedef enum {
NDPI_HTTP_SUSPICIOUS_HEADER,
NDPI_TLS_NOT_CARRYING_HTTPS,
NDPI_SUSPICIOUS_DGA_DOMAIN,
+ NDPI_MALFORMED_PACKET,
/* Leave this as last member */
NDPI_MAX_RISK
diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c
index 7799db0c1..e34a5a5ee 100644
--- a/src/lib/ndpi_main.c
+++ b/src/lib/ndpi_main.c
@@ -578,7 +578,7 @@ static void init_string_based_protocols(struct ndpi_detection_module_struct *ndp
for (i = 0; ndpi_en_popular_bigrams[i] != NULL; i++)
ndpi_string_to_automa(ndpi_str, &ndpi_str->bigrams_automa, (char *) ndpi_en_popular_bigrams[i], 1, 1, 1, 0);
#endif
-
+
for (i = 0; ndpi_en_impossible_bigrams[i] != NULL; i++)
ndpi_string_to_automa(ndpi_str, &ndpi_str->impossible_bigrams_automa, (char *) ndpi_en_impossible_bigrams[i], 1,
1, 1, 0);
@@ -2421,6 +2421,21 @@ u_int16_t ndpi_guess_protocol_id(struct ndpi_detection_module_struct *ndpi_str,
return(NDPI_PROTOCOL_IP_GRE);
break;
case NDPI_ICMP_PROTOCOL_TYPE:
+ {
+ /* Run some basic consistency tests */
+
+ if(flow->packet.payload_packet_len < sizeof(struct ndpi_icmphdr))
+ NDPI_SET_BIT(flow->risk, NDPI_MALFORMED_PACKET);
+ else {
+ u_int8_t icmp_type = (u_int8_t)flow->packet.payload[0];
+ u_int8_t icmp_code = (u_int8_t)flow->packet.payload[1];
+
+ /* https://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml */
+ if(((icmp_type >= 44) && (icmp_type <= 252))
+ || (icmp_code > 15))
+ NDPI_SET_BIT(flow->risk, NDPI_MALFORMED_PACKET);
+ }
+ }
return(NDPI_PROTOCOL_IP_ICMP);
break;
case NDPI_IGMP_PROTOCOL_TYPE:
@@ -2439,6 +2454,22 @@ u_int16_t ndpi_guess_protocol_id(struct ndpi_detection_module_struct *ndpi_str,
return(NDPI_PROTOCOL_IP_IP_IN_IP);
break;
case NDPI_ICMPV6_PROTOCOL_TYPE:
+ {
+ /* Run some basic consistency tests */
+
+ if(flow->packet.payload_packet_len < sizeof(struct ndpi_icmphdr))
+ NDPI_SET_BIT(flow->risk, NDPI_MALFORMED_PACKET);
+ else {
+ u_int8_t icmp6_type = (u_int8_t)flow->packet.payload[0];
+ u_int8_t icmp6_code = (u_int8_t)flow->packet.payload[1];
+
+ /* https://en.wikipedia.org/wiki/Internet_Control_Message_Protocol_for_IPv6 */
+ if(((icmp6_type >= 5) && (icmp6_type <= 127))
+ || (icmp6_type >= 156)
+ || ((icmp6_code > 7) && (icmp6_type != 255)))
+ NDPI_SET_BIT(flow->risk, NDPI_MALFORMED_PACKET);
+ }
+ }
return(NDPI_PROTOCOL_IP_ICMPV6);
break;
case 112:
@@ -3621,6 +3652,10 @@ static int ndpi_init_packet_header(struct ndpi_detection_module_struct *ndpi_str
flow->packet.udp = (struct ndpi_udphdr *) l4ptr;
flow->packet.payload_packet_len = flow->packet.l4_packet_len - 8;
flow->packet.payload = ((u_int8_t *) flow->packet.udp) + 8;
+ } else if((l4protocol == IPPROTO_ICMP && flow->packet.l4_packet_len >= sizeof(struct ndpi_icmphdr))
+ || (l4protocol == IPPROTO_ICMPV6 && flow->packet.l4_packet_len >= sizeof(struct ndpi_icmp6hdr))) {
+ flow->packet.payload = ((u_int8_t *) l4ptr);
+ flow->packet.payload_packet_len = flow->packet.l4_packet_len;
} else {
flow->packet.generic_l4_ptr = l4ptr;
}
@@ -4378,13 +4413,13 @@ static void ndpi_reconcile_protocols(struct ndpi_detection_module_struct *ndpi_s
Skype for a host doing MS Teams means MS Teams
(MS Teams uses Skype as transport protocol for voice/video)
*/
-
+
if(flow) {
/* Do not go for DNS when there is an application protocol. Example DNS.Apple */
if((flow->detected_protocol_stack[1] != NDPI_PROTOCOL_UNKNOWN)
&& (flow->detected_protocol_stack[0] /* app */ != flow->detected_protocol_stack[1] /* major */))
NDPI_CLR_BIT(flow->risk, NDPI_SUSPICIOUS_DGA_DOMAIN);
- }
+ }
switch(ret->app_protocol) {
case NDPI_PROTOCOL_MSTEAMS:
@@ -6519,7 +6554,7 @@ int ndpi_check_dga_name(struct ndpi_detection_module_struct *ndpi_str,
int len, rc = 0;
len = strlen(name);
-
+
if(len >= 5) {
int i, j, num_found = 0, num_impossible = 0, num_bigram_checks = 0, num_digits = 0, num_vowels = 0, num_words = 0;
char tmp[128], *word, *tok_tmp;
@@ -6538,29 +6573,29 @@ int ndpi_check_dga_name(struct ndpi_detection_module_struct *ndpi_str,
if(!word) break;
num_words++;
-
+
if(strlen(word) < 3) continue;
#ifdef DGA_DEBUG
printf("-> %s [%s][len: %u]\n", word, name, (unsigned int)strlen(word));
#endif
-
+
for(i = 0; word[i+1] != '\0'; i++) {
if(isdigit(word[i])) {
num_digits++;
-
+
// if(!isdigit(word[i+1])) num_impossible++;
-
- continue;
+
+ continue;
}
-
+
switch(word[i]) {
case '_':
case '-':
case ':':
continue;
break;
-
+
case '.':
continue;
break;
@@ -6575,13 +6610,13 @@ int ndpi_check_dga_name(struct ndpi_detection_module_struct *ndpi_str,
num_vowels++;
break;
}
-
+
if(isdigit(word[i+1])) {
num_digits++;
// num_impossible++;
continue;
}
-
+
num_bigram_checks++;
if(ndpi_match_bigram(ndpi_str, &ndpi_str->bigrams_automa, &word[i])) {
@@ -6603,7 +6638,7 @@ int ndpi_check_dga_name(struct ndpi_detection_module_struct *ndpi_str,
printf("[num_found: %u][num_impossible: %u][num_digits: %u][num_bigram_checks: %u][num_vowels: %u/%u]\n",
num_found, num_impossible, num_digits, num_bigram_checks, num_vowels, j-num_vowels);
#endif
-
+
if(num_bigram_checks
&& ((num_found == 0) || ((num_digits > 5) && (num_words <= 3)) || enough(num_found, num_impossible)))
rc = 1;
diff --git a/src/lib/ndpi_utils.c b/src/lib/ndpi_utils.c
index 335b9dd87..0eb399783 100644
--- a/src/lib/ndpi_utils.c
+++ b/src/lib/ndpi_utils.c
@@ -1500,7 +1500,9 @@ const char* ndpi_risk2str(ndpi_risk_enum risk) {
case NDPI_SUSPICIOUS_DGA_DOMAIN:
return("Suspicious DGA domain name");
-
+
+ case NDPI_MALFORMED_PACKET:
+ return("Malformed packet");
default:
snprintf(buf, sizeof(buf), "%d", (int)risk);
return(buf);
diff --git a/src/lib/protocols/dhcp.c b/src/lib/protocols/dhcp.c
index f40a8138c..5bf2a122c 100644
--- a/src/lib/protocols/dhcp.c
+++ b/src/lib/protocols/dhcp.c
@@ -89,8 +89,10 @@ void ndpi_search_dhcp_udp(struct ndpi_detection_module_struct *ndpi_struct, stru
u_int8_t len = ndpi_min(dhcp->options[i+1] /* len as found in the packet */,
dhcp_options_size - (i+2) /* 1 for the type and 1 for the value */);
- if(len == 0) break;
-
+ if(len == 0)
+ break;
+
+
#ifdef DHCP_DEBUG
NDPI_LOG_DBG2(ndpi_struct, "[DHCP] Id=%d [len=%d]\n", id, len);
#endif
@@ -150,8 +152,8 @@ void ndpi_search_dhcp_udp(struct ndpi_detection_module_struct *ndpi_struct, stru
}
-void init_dhcp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask)
-{
+void init_dhcp_dissector(struct ndpi_detection_module_struct *ndpi_struct,
+ u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) {
ndpi_set_bitmask_protocol_detection("DHCP", ndpi_struct, detection_bitmask, *id,
NDPI_PROTOCOL_DHCP,
ndpi_search_dhcp_udp,
diff --git a/src/lib/protocols/dns.c b/src/lib/protocols/dns.c
index 897fb1e4b..5e6d01d69 100644
--- a/src/lib/protocols/dns.c
+++ b/src/lib/protocols/dns.c
@@ -104,9 +104,11 @@ static int search_valid_dns(struct ndpi_detection_module_struct *ndpi_struct,
/* 0x8000 RESPONSE */
else if((dns_header->flags & FLAGS_MASK) == 0x8000)
*is_query = 0;
- else
+ else {
+ NDPI_SET_BIT(flow->risk, NDPI_MALFORMED_PACKET);
return(1 /* invalid */);
-
+ }
+
if(*is_query) {
/* DNS Request */
if((dns_header->num_queries > 0) && (dns_header->num_queries <= NDPI_MAX_DNS_REQUESTS)
@@ -125,16 +127,18 @@ static int search_valid_dns(struct ndpi_detection_module_struct *ndpi_struct,
} else
x++;
}
- } else
+ } else {
+ NDPI_SET_BIT(flow->risk, NDPI_MALFORMED_PACKET);
return(1 /* invalid */);
+ }
} else {
/* DNS Reply */
flow->protos.dns.reply_code = dns_header->flags & 0x0F;
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))
- || ((dns_header->authority_rrs > 0) && (dns_header->authority_rrs <= NDPI_MAX_DNS_REQUESTS))
- || ((dns_header->additional_rrs > 0) && (dns_header->additional_rrs <= NDPI_MAX_DNS_REQUESTS)))
+ && ((((dns_header->num_answers > 0) && (dns_header->num_answers <= NDPI_MAX_DNS_REQUESTS))
+ || ((dns_header->authority_rrs > 0) && (dns_header->authority_rrs <= NDPI_MAX_DNS_REQUESTS))
+ || ((dns_header->additional_rrs > 0) && (dns_header->additional_rrs <= NDPI_MAX_DNS_REQUESTS))))
) {
/* This is a good reply: we dissect it both for request and response */
@@ -213,8 +217,7 @@ static int search_valid_dns(struct ndpi_detection_module_struct *ndpi_struct,
(s_port == 5355) ? NDPI_PROTOCOL_LLMNR : NDPI_PROTOCOL_DNS,
NDPI_PROTOCOL_UNKNOWN);
}
- } else
- return(1 /* invalid */);
+ }
}
/* Valid */
diff --git a/src/lib/protocols/http.c b/src/lib/protocols/http.c
index 7d54d1470..dd6d39c88 100644
--- a/src/lib/protocols/http.c
+++ b/src/lib/protocols/http.c
@@ -594,7 +594,9 @@ static u_int16_t http_request_url_offset(struct ndpi_detection_module_struct *nd
packet->payload_packet_len);
/* Check first char */
- if(!packet->payload_packet_len || !strchr(http_fs,packet->payload[0])) return 0;
+ if(!packet->payload_packet_len || !strchr(http_fs,packet->payload[0]))
+ return 0;
+
/**
FIRST PAYLOAD PACKET FROM CLIENT
**/
@@ -1011,9 +1013,10 @@ 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_mod,
struct ndpi_flow_struct *flow) {
- if(!flow)
+ if(!flow) {
+ NDPI_SET_BIT(flow->risk, NDPI_MALFORMED_PACKET);
return(NDPI_HTTP_METHOD_UNKNOWN);
- else
+ } else
return(flow->http.method);
}
diff --git a/src/lib/protocols/tls.c b/src/lib/protocols/tls.c
index b2cf1f23c..c9b2d0ee2 100644
--- a/src/lib/protocols/tls.c
+++ b/src/lib/protocols/tls.c
@@ -508,14 +508,18 @@ int processCertificate(struct ndpi_detection_module_struct *ndpi_struct,
packet->payload[3], packet->payload[4], packet->payload[5]);
#endif
- if((packet->payload_packet_len != (length + 4)) || (packet->payload[1] != 0x0))
+ if((packet->payload_packet_len != (length + 4)) || (packet->payload[1] != 0x0)) {
+ NDPI_SET_BIT(flow->risk, NDPI_MALFORMED_PACKET);
return(-1); /* Invalid length */
-
+ }
+
certificates_length = (packet->payload[4] << 16) + (packet->payload[5] << 8) + packet->payload[6];
- if((packet->payload[4] != 0x0) || ((certificates_length+3) != length))
+ if((packet->payload[4] != 0x0) || ((certificates_length+3) != length)) {
+ NDPI_SET_BIT(flow->risk, NDPI_MALFORMED_PACKET);
return(-2); /* Invalid length */
-
+ }
+
if(!flow->l4.tcp.tls.srv_cert_fingerprint_ctx) {
if((flow->l4.tcp.tls.srv_cert_fingerprint_ctx = (void*)ndpi_malloc(sizeof(SHA1_CTX))) == NULL)
return(-3); /* Not enough memory */