From 770e460ba9be589c9793ad118f9dc7697b188d33 Mon Sep 17 00:00:00 2001
From: Luca Deri <deri@ntop.org>
Date: Thu, 7 Sep 2023 23:42:42 +0200
Subject: Added NDPI_TLS_ALPN_SNI_MISMATCH flow risk

---
 src/include/ndpi_typedefs.h |  3 ++-
 src/lib/ndpi_main.c         |  1 +
 src/lib/ndpi_utils.c        |  4 ++++
 src/lib/protocols/tls.c     | 21 ++++++++++++++++++++-
 4 files changed, 27 insertions(+), 2 deletions(-)

(limited to 'src')

diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h
index 53535a441..caa5f2336 100644
--- a/src/include/ndpi_typedefs.h
+++ b/src/include/ndpi_typedefs.h
@@ -149,7 +149,8 @@ typedef enum {
   NDPI_MINOR_ISSUES,           /* Generic packet issues (e.g. DNS with 0 TTL) */
   NDPI_TCP_ISSUES,             /* 50 */ /* TCP issues such as connection failed, probing or scan */
   NDPI_FULLY_ENCRYPTED,        /* This (unknown) session is fully encrypted */
-
+  NDPI_TLS_ALPN_SNI_MISMATCH,  /* Invalid ALPN/SNI combination */
+  
   /* Leave this as last member */
   NDPI_MAX_RISK /* must be <= 63 due to (**) */
 } ndpi_risk_enum;
diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c
index 1aa844f37..c2da19baf 100644
--- a/src/lib/ndpi_main.c
+++ b/src/lib/ndpi_main.c
@@ -189,6 +189,7 @@ static ndpi_risk_info ndpi_known_risks[] = {
   { NDPI_MINOR_ISSUES,                          NDPI_RISK_LOW,    CLIENT_LOW_RISK_PERCENTAGE,  NDPI_BOTH_ACCOUNTABLE   },
   { NDPI_TCP_ISSUES,                            NDPI_RISK_MEDIUM, CLIENT_FAIR_RISK_PERCENTAGE, NDPI_CLIENT_ACCOUNTABLE },
   { NDPI_FULLY_ENCRYPTED,                       NDPI_RISK_MEDIUM, CLIENT_FAIR_RISK_PERCENTAGE, NDPI_CLIENT_ACCOUNTABLE },
+  { NDPI_TLS_ALPN_SNI_MISMATCH,                 NDPI_RISK_MEDIUM, CLIENT_FAIR_RISK_PERCENTAGE, NDPI_CLIENT_ACCOUNTABLE },
 
   /* Leave this as last member */
   { NDPI_MAX_RISK,                              NDPI_RISK_LOW,    CLIENT_FAIR_RISK_PERCENTAGE, NDPI_NO_ACCOUNTABILITY   }
diff --git a/src/lib/ndpi_utils.c b/src/lib/ndpi_utils.c
index 854b548f0..c0e9fa446 100644
--- a/src/lib/ndpi_utils.c
+++ b/src/lib/ndpi_utils.c
@@ -2050,6 +2050,10 @@ const char* ndpi_risk2str(ndpi_risk_enum risk) {
   case NDPI_FULLY_ENCRYPTED:
     return("Fully encrypted flow");
 
+  case NDPI_TLS_ALPN_SNI_MISMATCH:
+    return("ALPN/SNI Mismatch");
+    break;
+    
   default:
     ndpi_snprintf(buf, sizeof(buf), "%d", (int)risk);
     return(buf);
diff --git a/src/lib/protocols/tls.c b/src/lib/protocols/tls.c
index b1c97225f..bedc3be59 100644
--- a/src/lib/protocols/tls.c
+++ b/src/lib/protocols/tls.c
@@ -1428,6 +1428,8 @@ void switch_to_tls(struct ndpi_detection_module_struct *ndpi_struct,
   ndpi_search_tls_wrapper(ndpi_struct, flow);
 }
 
+/* **************************************** */
+
 static void tls_subclassify_by_alpn(struct ndpi_detection_module_struct *ndpi_struct,
 				    struct ndpi_flow_struct *flow) {
   /* Right now we have only one rule so we can keep it trivial */
@@ -2709,8 +2711,25 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct,
 	       ) {
 	      /* This is a bit suspicious */
 	      ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_MISSING_SNI, NULL);
-	    }
+	      
+	      if(flow->protos.tls_quic.advertised_alpns != NULL) {
+		char buf[256], *tmp, *item;
 
+		snprintf(buf, sizeof(buf), "%s", flow->protos.tls_quic.advertised_alpns);
+
+		item = strtok_r(buf, ",", &tmp);
+		
+		while(item != NULL) {
+		  if(item[0] == 'h') {
+		    /* Example 'h2' */
+		    ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_ALPN_SNI_MISMATCH, NULL);
+		    break;
+		  } else
+		    item = strtok_r(NULL, ",", &tmp);
+		}
+	      }
+	    }
+	    
 	    return(2 /* Client Certificate */);
 	  } else {
 #ifdef DEBUG_TLS
-- 
cgit v1.2.3