aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLuca Deri <deri@ntop.org>2021-02-22 23:19:23 +0100
committerLuca Deri <deri@ntop.org>2021-02-22 23:19:23 +0100
commitf1b22b199f08469407c55dcd98ec24af85da0fd3 (patch)
tree9311e4920c5fe876624f6ca2b0185456fd14c8cf /src
parentfc3db8f1691e913b03ca88a47770c5abf3104ef8 (diff)
Added NDPI_MALICIOUS_JA3 flow risk
Added ndpi_load_malicious_ja3_file() API call
Diffstat (limited to 'src')
-rw-r--r--src/include/ndpi_api.h.in10
-rw-r--r--src/include/ndpi_typedefs.h4
-rw-r--r--src/lib/ndpi_main.c60
-rw-r--r--src/lib/ndpi_utils.c5
-rw-r--r--src/lib/protocols/tls.c9
5 files changed, 83 insertions, 5 deletions
diff --git a/src/include/ndpi_api.h.in b/src/include/ndpi_api.h.in
index 65d06fafc..33a795ea0 100644
--- a/src/include/ndpi_api.h.in
+++ b/src/include/ndpi_api.h.in
@@ -705,6 +705,16 @@ extern "C" {
*/
int ndpi_load_risk_domain_file(struct ndpi_detection_module_struct *ndpi_str, const char* path);
+ /**
+ * Read a file and load the list of malicious JA3 signatures
+ *
+ * @par ndpi_mod = the detection module
+ * @par path = the path of the file
+ * @return 0 if the file is loaded correctly;
+ * -1 else
+ */
+ int ndpi_load_malicious_ja3_file(struct ndpi_detection_module_struct *ndpi_str, const char *path);
+
/**
* Get the total number of the supported protocols
*
diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h
index dce9c34d8..dd6e83e2b 100644
--- a/src/include/ndpi_typedefs.h
+++ b/src/include/ndpi_typedefs.h
@@ -91,6 +91,7 @@ typedef enum {
NDPI_HTTP_SUSPICIOUS_CONTENT,
NDPI_RISKY_ASN,
NDPI_RISKY_DOMAIN,
+ NDPI_MALICIOUS_JA3,
/* Leave this as last member */
@@ -1099,7 +1100,8 @@ struct ndpi_detection_module_struct {
content_automa, /* Used for HTTP subprotocol_detection */
subprotocol_automa, /* Used for HTTP subprotocol_detection */
bigrams_automa, impossible_bigrams_automa, /* TOR */
- risky_domain_automa, tls_cert_subject_automa;
+ risky_domain_automa, tls_cert_subject_automa,
+ malicious_ja3_automa;
/* IMPORTANT: please update ndpi_finalize_initialization() whenever you add a new automa */
struct {
diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c
index ad6745d8f..8a27184e3 100644
--- a/src/lib/ndpi_main.c
+++ b/src/lib/ndpi_main.c
@@ -2142,6 +2142,7 @@ struct ndpi_detection_module_struct *ndpi_init_detection_module(ndpi_init_prefs
ndpi_str->bigrams_automa.ac_automa = ac_automata_init(ac_match_handler);
ndpi_str->impossible_bigrams_automa.ac_automa = ac_automata_init(ac_match_handler);
ndpi_str->tls_cert_subject_automa.ac_automa = ac_automata_init(ac_match_handler);
+ ndpi_str->malicious_ja3_automa.ac_automa = NULL; /* Initialized on demand */
ndpi_str->risky_domain_automa.ac_automa = NULL; /* Initialized on demand */
if((sizeof(categories) / sizeof(char *)) != NDPI_PROTOCOL_NUM_CATEGORIES) {
@@ -2196,13 +2197,13 @@ void ndpi_finalize_initialization(struct ndpi_detection_module_struct *ndpi_str)
break;
case 4:
- automa = &ndpi_str->risky_domain_automa;
+ automa = &ndpi_str->tls_cert_subject_automa;
break;
case 5:
- automa = &ndpi_str->tls_cert_subject_automa;
+ automa = &ndpi_str->malicious_ja3_automa;
break;
-
+
default:
return;
}
@@ -2465,6 +2466,9 @@ void ndpi_exit_detection_module(struct ndpi_detection_module_struct *ndpi_str) {
if(ndpi_str->tls_cert_subject_automa.ac_automa != NULL)
ac_automata_release((AC_AUTOMATA_t *) ndpi_str->tls_cert_subject_automa.ac_automa, 0);
+ if(ndpi_str->malicious_ja3_automa.ac_automa != NULL)
+ ac_automata_release((AC_AUTOMATA_t *) ndpi_str->malicious_ja3_automa.ac_automa, 0);
+
if(ndpi_str->custom_categories.hostnames.ac_automa != NULL)
ac_automata_release((AC_AUTOMATA_t *) ndpi_str->custom_categories.hostnames.ac_automa,
1 /* free patterns strings memory */);
@@ -2912,6 +2916,56 @@ int ndpi_load_risk_domain_file(struct ndpi_detection_module_struct *ndpi_str, co
/* ******************************************************************** */
/*
+ * Format:
+ *
+ * <domain name>[,<other info>]
+ *
+ */
+int ndpi_load_malicious_ja3_file(struct ndpi_detection_module_struct *ndpi_str, const char *path) {
+ char buffer[128], *line;
+ FILE *fd;
+ int len, num = 0;
+
+ if(ndpi_str->malicious_ja3_automa.ac_automa == NULL)
+ ndpi_str->malicious_ja3_automa.ac_automa = ac_automata_init(ac_match_handler);
+
+ fd = fopen(path, "r");
+
+ if(fd == NULL) {
+ NDPI_LOG_ERR(ndpi_str, "Unable to open file %s [%s]\n", path, strerror(errno));
+ return(-1);
+ }
+
+ while(1) {
+ char *comma;
+
+ line = fgets(buffer, sizeof(buffer), fd);
+
+ if(line == NULL)
+ break;
+
+ len = strlen(line);
+
+ if((len <= 1) || (line[0] == '#'))
+ continue;
+
+ line[len - 1] = '\0';
+
+ if((comma = strchr(line, ',')) != NULL)
+ comma[0] = '\0';
+
+ if(ndpi_add_string_to_automa(ndpi_str->malicious_ja3_automa.ac_automa, line) >= 0)
+ num++;
+ }
+
+ fclose(fd);
+
+ return(num);
+}
+
+/* ******************************************************************** */
+
+/*
Format:
<tcp|udp>:<port>,<tcp|udp>:<port>,.....@<proto>
diff --git a/src/lib/ndpi_utils.c b/src/lib/ndpi_utils.c
index e3ae4b780..834d12e2e 100644
--- a/src/lib/ndpi_utils.c
+++ b/src/lib/ndpi_utils.c
@@ -1758,7 +1758,10 @@ const char* ndpi_risk2str(ndpi_risk_enum risk) {
case NDPI_RISKY_DOMAIN:
return("Risky domain name");
-
+
+ case NDPI_MALICIOUS_JA3:
+ return("Malicious JA3 Fingerprint");
+
default:
snprintf(buf, sizeof(buf), "%d", (int)risk);
return(buf);
diff --git a/src/lib/protocols/tls.c b/src/lib/protocols/tls.c
index 99f5f5649..f38f4f87d 100644
--- a/src/lib/protocols/tls.c
+++ b/src/lib/protocols/tls.c
@@ -1576,9 +1576,18 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct,
md5_hash[i]);
if(rc > 0) j += rc; else break;
}
+
#ifdef DEBUG_TLS
printf("[JA3] Client: %s \n", flow->protos.tls_quic_stun.tls_quic.ja3_client);
#endif
+
+ if(ndpi_struct->malicious_ja3_automa.ac_automa != NULL) {
+ u_int16_t rc1 = ndpi_match_string(ndpi_struct->malicious_ja3_automa.ac_automa,
+ flow->protos.tls_quic_stun.tls_quic.ja3_client);
+
+ if(rc1 > 0)
+ NDPI_SET_BIT(flow->risk, NDPI_MALICIOUS_JA3);
+ }
}
/* Before returning to the caller we need to make a final check */