aboutsummaryrefslogtreecommitdiff
path: root/src/lib/protocols/tls.c
diff options
context:
space:
mode:
authorToni <matzeton@googlemail.com>2021-04-27 07:22:04 +0200
committerGitHub <noreply@github.com>2021-04-27 07:22:04 +0200
commitda3e6bd61b7eaf54cad432bd737d5d894e6c9bf9 (patch)
treea17150a4de40c385c179202dbd875e0c7f210dfe /src/lib/protocols/tls.c
parentd5b395f35a10ae22a2f35c087600e249d2c42d0f (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')
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 */