diff options
author | Toni <matzeton@googlemail.com> | 2021-04-27 07:22:04 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-27 07:22:04 +0200 |
commit | da3e6bd61b7eaf54cad432bd737d5d894e6c9bf9 (patch) | |
tree | a17150a4de40c385c179202dbd875e0c7f210dfe /src/lib/protocols/tls.c | |
parent | d5b395f35a10ae22a2f35c087600e249d2c42d0f (diff) |
Check for common ALPNs and set a flow risk if not known. (#1175)
* Increased risk bitmask to 64bit (instead of 32bit).
* Removed annoying "Unknown datalink" error message for fuzzers.
Signed-off-by: Toni Uhlig <matzeton@googlemail.com>
Diffstat (limited to 'src/lib/protocols/tls.c')
-rw-r--r-- | src/lib/protocols/tls.c | 96 |
1 files changed, 86 insertions, 10 deletions
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 */ |