aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuca Deri <deri@ntop.org>2024-09-05 19:46:18 +0200
committerLuca Deri <deri@ntop.org>2024-09-05 19:47:01 +0200
commit42ded07139e41c54a9ae2c8875a9e2c56d50af41 (patch)
tree9974adf195c5478cd135f684254bc4faf8a16bff
parent2964c23ca1f9af4df5c93e337987c6823b2ac663 (diff)
Implemented JA4 raw (ja4_r) fingerprint
Example: ./example/ndpiReader -i tests/pcap/safari.pcap --cfg=tls,metadata.ja4r_fingerprint,1
-rw-r--r--src/include/ndpi_private.h1
-rw-r--r--src/include/ndpi_typedefs.h2
-rw-r--r--src/lib/ndpi_main.c8
-rw-r--r--src/lib/protocols/tls.c26
4 files changed, 32 insertions, 5 deletions
diff --git a/src/include/ndpi_private.h b/src/include/ndpi_private.h
index 10a2a064e..b9f197ad6 100644
--- a/src/include/ndpi_private.h
+++ b/src/include/ndpi_private.h
@@ -236,6 +236,7 @@ struct ndpi_detection_module_config_struct {
int tls_ja3c_fingerprint_enabled;
int tls_ja3s_fingerprint_enabled;
int tls_ja4c_fingerprint_enabled;
+ int tls_ja4r_fingerprint_enabled;
int tls_subclassification_enabled;
int quic_subclassification_enabled;
diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h
index 0756e5a24..deb8d9624 100644
--- a/src/include/ndpi_typedefs.h
+++ b/src/include/ndpi_typedefs.h
@@ -1353,7 +1353,7 @@ struct ndpi_flow_struct {
struct {
char *server_names, *advertised_alpns, *negotiated_alpn, *tls_supported_versions, *issuerDN, *subjectDN;
u_int32_t notBefore, notAfter;
- char ja3_client[33], ja3_server[33], ja4_client[37];
+ char ja3_client[33], ja3_server[33], ja4_client[37], *ja4_client_raw;
u_int16_t server_cipher;
u_int8_t sha1_certificate_fingerprint[20];
u_int8_t client_hello_processed:1, ch_direction:1, subprotocol_detected:1, server_hello_processed:1, fingerprint_set:1, webrtc:1, _pad:2;
diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c
index db3a83bb9..a61a8e804 100644
--- a/src/lib/ndpi_main.c
+++ b/src/lib/ndpi_main.c
@@ -6717,7 +6717,10 @@ void ndpi_free_flow_data(struct ndpi_flow_struct* flow) {
if(flow->protos.tls_quic.encrypted_sni.esni)
ndpi_free(flow->protos.tls_quic.encrypted_sni.esni);
- }
+
+ if(flow->protos.tls_quic.ja4_client_raw)
+ ndpi_free(flow->protos.tls_quic.ja4_client_raw);
+ }
if(flow->tls_quic.message[0].buffer)
ndpi_free(flow->tls_quic.message[0].buffer);
@@ -11403,10 +11406,11 @@ static const struct cfg_param {
{ "tls", "metadata.ja3c_fingerprint", "enable", NULL, NULL, CFG_PARAM_ENABLE_DISABLE, __OFF(tls_ja3c_fingerprint_enabled), NULL },
{ "tls", "metadata.ja3s_fingerprint", "enable", NULL, NULL, CFG_PARAM_ENABLE_DISABLE, __OFF(tls_ja3s_fingerprint_enabled), NULL },
{ "tls", "metadata.ja4c_fingerprint", "enable", NULL, NULL, CFG_PARAM_ENABLE_DISABLE, __OFF(tls_ja4c_fingerprint_enabled), NULL },
+ { "tls", "metadata.ja4r_fingerprint", "disable", NULL, NULL, CFG_PARAM_ENABLE_DISABLE, __OFF(tls_ja4r_fingerprint_enabled), NULL },
{ "tls", "subclassification", "enable", NULL, NULL, CFG_PARAM_ENABLE_DISABLE, __OFF(tls_subclassification_enabled), NULL },
{ "quic", "subclassification", "enable", NULL, NULL, CFG_PARAM_ENABLE_DISABLE, __OFF(quic_subclassification_enabled), NULL },
-
+
{ "smtp", "tls_dissection", "enable", NULL, NULL, CFG_PARAM_ENABLE_DISABLE, __OFF(smtp_opportunistic_tls_enabled), NULL },
{ "imap", "tls_dissection", "enable", NULL, NULL, CFG_PARAM_ENABLE_DISABLE, __OFF(imap_opportunistic_tls_enabled), NULL },
diff --git a/src/lib/protocols/tls.c b/src/lib/protocols/tls.c
index a41b2d691..b26a57998 100644
--- a/src/lib/protocols/tls.c
+++ b/src/lib/protocols/tls.c
@@ -1658,7 +1658,8 @@ static bool is_grease_version(u_int16_t version) {
/* **************************************** */
-static void ndpi_compute_ja4(struct ndpi_flow_struct *flow,
+static void ndpi_compute_ja4(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow,
u_int32_t quic_version,
union ja_info *ja) {
u_int8_t tmp_str[JA_STR_LEN];
@@ -1670,6 +1671,9 @@ static void ndpi_compute_ja4(struct ndpi_flow_struct *flow,
char * const ja_str = &flow->protos.tls_quic.ja4_client[0];
const u_int16_t ja_max_len = sizeof(flow->protos.tls_quic.ja4_client);
bool is_dtls = ((flow->l4_proto == IPPROTO_UDP) && (quic_version == 0)) || flow->stun.maybe_dtls;
+ int ja4_r_len = 0;
+ char ja4_r[1024];
+
/*
Compute JA4 TLS/QUIC client
@@ -1771,6 +1775,12 @@ static void ndpi_compute_ja4(struct ndpi_flow_struct *flow,
if((rc > 0) && (tmp_str_len + rc < JA_STR_LEN)) tmp_str_len += rc; else break;
}
+ ja_str[ja_str_len] = 0;
+ i = snprintf(&ja4_r[ja4_r_len], sizeof(ja4_r)-ja4_r_len, "%s", ja_str); if(i > 0) ja4_r_len += i;
+
+ tmp_str[tmp_str_len] = 0;
+ i = snprintf(&ja4_r[ja4_r_len], sizeof(ja4_r)-ja4_r_len, "%s_", tmp_str); if(i > 0) ja4_r_len += i;
+
ndpi_sha256(tmp_str, tmp_str_len, sha_hash);
rc = ndpi_snprintf(&ja_str[ja_str_len], ja_max_len - ja_str_len,
@@ -1802,7 +1812,18 @@ static void ndpi_compute_ja4(struct ndpi_flow_struct *flow,
#ifdef DEBUG_JA
printf("[EXTN] %s [len: %u]\n", tmp_str, tmp_str_len);
#endif
+
+ tmp_str[tmp_str_len] = 0;
+ i = snprintf(&ja4_r[ja4_r_len], sizeof(ja4_r)-ja4_r_len, "%s", tmp_str); if(i > 0) ja4_r_len += i;
+ if(ndpi_struct->cfg.tls_ja4r_fingerprint_enabled) {
+ if(flow->protos.tls_quic.ja4_client_raw == NULL)
+ flow->protos.tls_quic.ja4_client_raw = ndpi_strdup(ja4_r);
+#ifdef DEBUG_JA
+ printf("[JA4_r] %s [len: %u]\n", ja4_r, ja4_r_len);
+#endif
+ }
+
ndpi_sha256(tmp_str, tmp_str_len, sha_hash);
rc = ndpi_snprintf(&ja_str[ja_str_len], ja_max_len - ja_str_len,
@@ -1812,6 +1833,7 @@ static void ndpi_compute_ja4(struct ndpi_flow_struct *flow,
if((rc > 0) && (ja_str_len + rc < JA_STR_LEN)) ja_str_len += rc;
ja_str[36] = 0;
+
#ifdef DEBUG_JA
printf("[JA4] %s [len: %lu]\n", ja_str, strlen(ja_str));
#endif
@@ -2901,7 +2923,7 @@ compute_ja3c:
}
if(ndpi_struct->cfg.tls_ja4c_fingerprint_enabled) {
- ndpi_compute_ja4(flow, quic_version, &ja);
+ ndpi_compute_ja4(ndpi_struct, flow, quic_version, &ja);
}
/* End JA3/JA4 */
}