Skip to content

Commit

Permalink
Implemented JA4 raw (ja4_r) fingerprint
Browse files Browse the repository at this point in the history
Example:
./example/ndpiReader -i tests/pcap/safari.pcap --cfg=tls,metadata.ja4r_fingerprint,1
  • Loading branch information
lucaderi committed Sep 5, 2024
1 parent 2964c23 commit 42ded07
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 5 deletions.
1 change: 1 addition & 0 deletions src/include/ndpi_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion src/include/ndpi_typedefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
8 changes: 6 additions & 2 deletions src/lib/ndpi_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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 },
Expand Down
26 changes: 24 additions & 2 deletions src/lib/protocols/tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand All @@ -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
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand All @@ -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
Expand Down Expand Up @@ -2901,7 +2923,7 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct,
}

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 */
}
Expand Down

0 comments on commit 42ded07

Please sign in to comment.