diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/include/ndpi_typedefs.h | 9 | ||||
-rw-r--r-- | src/lib/ndpi_utils.c | 7 | ||||
-rw-r--r-- | src/lib/protocols/tls.c | 96 |
3 files changed, 96 insertions, 16 deletions
diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h index 54a5caaf6..c65d241ef 100644 --- a/src/include/ndpi_typedefs.h +++ b/src/include/ndpi_typedefs.h @@ -98,13 +98,14 @@ typedef enum { NDPI_RISKY_DOMAIN, NDPI_MALICIOUS_JA3, NDPI_MALICIOUS_SHA1_CERTIFICATE, - NDPI_DESKTOP_OR_FILE_SHARING_SESSION, - + NDPI_DESKTOP_OR_FILE_SHARING_SESSION, /* 30 */ + NDPI_TLS_UNCOMMON_ALPN, + /* Leave this as last member */ - NDPI_MAX_RISK /* must be <= 31 due to (**) */ + NDPI_MAX_RISK /* must be <= 63 due to (**) */ } ndpi_risk_enum; -typedef u_int32_t ndpi_risk; /* (**) */ +typedef u_int64_t ndpi_risk; /* (**) */ /* NDPI_VISIT */ typedef enum { diff --git a/src/lib/ndpi_utils.c b/src/lib/ndpi_utils.c index 262cb2d72..05e7b086b 100644 --- a/src/lib/ndpi_utils.c +++ b/src/lib/ndpi_utils.c @@ -1776,7 +1776,10 @@ const char* ndpi_risk2str(ndpi_risk_enum risk) { case NDPI_DESKTOP_OR_FILE_SHARING_SESSION: return("Desktop/File Sharing Session"); - + + case NDPI_TLS_UNCOMMON_ALPN: + return("Uncommon TLS ALPN"); + default: snprintf(buf, sizeof(buf), "%d", (int)risk); return(buf); @@ -2460,7 +2463,7 @@ int ndpi_hash_add_entry(ndpi_str_hash *h, char *key, u_int8_t key_len, u_int8_t /* ******************************************************************** */ void ndpi_set_risk(struct ndpi_flow_struct *flow, ndpi_risk_enum r) { - u_int32_t v = 1 << r; + ndpi_risk v = 1ull << r; // NDPI_SET_BIT(flow->risk, (u_int32_t)r); flow->risk |= v; diff --git a/src/lib/protocols/tls.c b/src/lib/protocols/tls.c index 035142f00..d970980ab 100644 --- a/src/lib/protocols/tls.c +++ b/src/lib/protocols/tls.c @@ -1010,6 +1010,73 @@ static void tlsInitExtraPacketProcessing(struct ndpi_detection_module_struct *nd /* **************************************** */ +static void tlsCheckUncommonALPN(struct ndpi_flow_struct *flow) +{ + /* see: https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml */ + static char const * const common_alpns[] = { + "http/0.9", "http/1.0", "http/1.1", + "spdy/1", "spdy/2", "spdy/3", "spdy/3.1", + "stun.turn", "stun.nat-discovery", + "h2", "h2c", "h2-16", "h2-15", "h2-14", + "webrtc", "c-webrtc", + "ftp", "imap", "pop3", "managesieve", "coap", + "xmpp-client", "xmpp-server", + "acme-tls/1", + "mqtt", "dot", "ntske/1", "sunrpc", + "h3", + "smb", + "irc", + + /* QUIC ALPNs */ + "h3-T051", "h3-T050", + "h3-32", "h3-30", "h3-29", "h3-28", "h3-27", "h3-24", "h3-22", + "hq-30", "hq-29", "hq-28", "hq-27", + "h3-fb-05", "h1q-fb", + "doq-i00" + }; + + /* + * If the ALPN list increases in size, iterating over all items for every incoming ALPN may + * have a performance impact. A hash map could solve this issue. + */ + + char * alpn_start = flow->protos.tls_quic_stun.tls_quic.alpn; + char * comma_or_nul = alpn_start; + do { + comma_or_nul = strchr(comma_or_nul, ','); + if (comma_or_nul == NULL) + { + comma_or_nul = alpn_start + strlen(alpn_start); + } + + int alpn_found = 0; + int alpn_len = comma_or_nul - alpn_start; + char const * const alpn = alpn_start; + for (size_t i = 0; i < sizeof(common_alpns)/sizeof(common_alpns[0]); ++i) + { + if (strlen(common_alpns[i]) == alpn_len && + strncmp(alpn, common_alpns[i], alpn_len) == 0) + { + alpn_found = 1; + break; + } + } + + if (alpn_found == 0) + { +#ifdef DEBUG_TLS + printf("TLS uncommon ALPN found: %.*s\n", alpn_len, alpn); +#endif + ndpi_set_risk(flow, NDPI_TLS_UNCOMMON_ALPN); + break; + } + + alpn_start = comma_or_nul + 1; + } while (*(comma_or_nul++) != '\0'); +} + +/* **************************************** */ + static void ndpi_int_tls_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, u_int32_t protocol) { #if DEBUG_TLS @@ -1179,19 +1246,25 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, #endif if((alpn_str_len+alpn_len+1) < (sizeof(alpn_str)-1)) { - if(alpn_str_len > 0) { - alpn_str[alpn_str_len] = ','; - alpn_str_len++; - } + if(alpn_str_len > 0) { + alpn_str[alpn_str_len] = ','; + alpn_str_len++; + } - for(alpn_i=0; alpn_i<alpn_len; alpn_i++) - alpn_str[alpn_str_len+alpn_i] = packet->payload[s_offset+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 - break; - } else + s_offset += alpn_len, alpn_str_len += alpn_len;; + } else { + ndpi_set_risk(flow, NDPI_TLS_UNCOMMON_ALPN); + break; + } + } else { + ndpi_set_risk(flow, NDPI_TLS_UNCOMMON_ALPN); break; + } } /* while */ alpn_str[alpn_str_len] = '\0'; @@ -1202,6 +1275,9 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, if(flow->protos.tls_quic_stun.tls_quic.alpn == NULL) flow->protos.tls_quic_stun.tls_quic.alpn = ndpi_strdup(alpn_str); + if(flow->protos.tls_quic_stun.tls_quic.alpn != NULL) + tlsCheckUncommonALPN(flow); + snprintf(ja3.server.alpn, sizeof(ja3.server.alpn), "%s", alpn_str); /* Replace , with - as in JA3 */ |