diff options
-rw-r--r-- | src/include/ndpi_protocol_ids.h | 1 | ||||
-rw-r--r-- | src/include/ndpi_typedefs.h | 3 | ||||
-rw-r--r-- | src/lib/ndpi_content_match.c.inc | 11 | ||||
-rw-r--r-- | src/lib/ndpi_main.c | 17 | ||||
-rw-r--r-- | src/lib/protocols/tls.c | 53 | ||||
-rw-r--r-- | tests/pcap/forticlient.pcap | bin | 0 -> 462955 bytes | |||
-rw-r--r-- | tests/result/forticlient.pcap.out | 12 |
7 files changed, 85 insertions, 12 deletions
diff --git a/src/include/ndpi_protocol_ids.h b/src/include/ndpi_protocol_ids.h index d4c7bda88..f1480643b 100644 --- a/src/include/ndpi_protocol_ids.h +++ b/src/include/ndpi_protocol_ids.h @@ -287,6 +287,7 @@ typedef enum { NDPI_PROTOCOL_HPVIRTGRP = 256, /* Toni Uhlig <matzeton@googlemail.com> */ NDPI_PROTOCOL_GENSHIN_IMPACT = 257, /* Toni Uhlig <matzeton@googlemail.com> */ NDPI_PROTOCOL_ACTIVISION = 258, + NDPI_PROTOCOL_FORTICLIENT = 259, #ifdef CUSTOM_NDPI_PROTOCOLS #include "../../../nDPI-custom/custom_ndpi_protocol_ids.h" diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h index d863c4e24..48bb8488c 100644 --- a/src/include/ndpi_typedefs.h +++ b/src/include/ndpi_typedefs.h @@ -1184,6 +1184,9 @@ struct ndpi_detection_module_struct { /* NDPI_PROTOCOL_STUN and subprotocols */ struct ndpi_lru_cache *stun_cache; + /* NDPI_PROTOCOL_TLS and subprotocols */ + struct ndpi_lru_cache *tls_cert_cache; + /* NDPI_PROTOCOL_MINING and subprotocols */ struct ndpi_lru_cache *mining_cache; diff --git a/src/lib/ndpi_content_match.c.inc b/src/lib/ndpi_content_match.c.inc index 7b807e7d9..4a3e6c554 100644 --- a/src/lib/ndpi_content_match.c.inc +++ b/src/lib/ndpi_content_match.c.inc @@ -9432,11 +9432,12 @@ static ndpi_protocol_match host_match[] = /* ******************************************************************** */ static ndpi_tls_cert_name_match tls_certificate_match [] = { - { "CN=AnyDesk Client", NDPI_PROTOCOL_ANYDESK }, - { "O=Kakao", NDPI_PROTOCOL_KAKAOTALK }, - { "O=ntop.org", NDPI_PROTOCOL_NTOP }, - { "CN=simplednscrypt.org", NDPI_PROTOCOL_DNSCRYPT }, - { "CN=*.gateway.messenger.live.com", NDPI_PROTOCOL_SKYPE }, + { "CN=AnyDesk Client", NDPI_PROTOCOL_ANYDESK }, + { "O=Kakao", NDPI_PROTOCOL_KAKAOTALK }, + { "O=ntop.org", NDPI_PROTOCOL_NTOP }, + { "CN=simplednscrypt.org", NDPI_PROTOCOL_DNSCRYPT }, + { "CN=*.gateway.messenger.live.com", NDPI_PROTOCOL_SKYPE }, + { "OU=FortiGate", NDPI_PROTOCOL_FORTICLIENT }, { NULL, 0 } }; diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c index ae3e08ac3..b7de36497 100644 --- a/src/lib/ndpi_main.c +++ b/src/lib/ndpi_main.c @@ -1632,6 +1632,10 @@ static void ndpi_init_protocol_defaults(struct ndpi_detection_module_struct *ndp "Activision", NDPI_PROTOCOL_CATEGORY_GAME, ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); + ndpi_set_proto_defaults(ndpi_str, NDPI_PROTOCOL_SAFE, NDPI_PROTOCOL_FORTICLIENT, + "FortiClient", NDPI_PROTOCOL_CATEGORY_VPN, + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */); #ifdef CUSTOM_NDPI_PROTOCOLS #include "../../../nDPI-custom/custom_ndpi_main.c" @@ -2562,6 +2566,9 @@ void ndpi_exit_detection_module(struct ndpi_detection_module_struct *ndpi_str) { if(ndpi_str->stun_cache) ndpi_lru_free_cache(ndpi_str->stun_cache); + if(ndpi_str->tls_cert_cache) + ndpi_lru_free_cache(ndpi_str->tls_cert_cache); + if(ndpi_str->mining_cache) ndpi_lru_free_cache(ndpi_str->mining_cache); @@ -6753,6 +6760,16 @@ uint8_t ndpi_connection_tracking(struct ndpi_detection_module_struct *ndpi_str, } /* ****************************************************** */ + + void ndpi_check_subprotocol_risk(struct ndpi_flow_struct *flow, u_int16_t subprotocol_id) { + switch(subprotocol_id) { + case NDPI_PROTOCOL_ANYDESK: + ndpi_set_risk(flow, NDPI_DESKTOP_OR_FILE_SHARING_SESSION); /* Remote assistance */ + break; + } + } + + /* ****************************************************** */ u_int16_t ndpi_match_host_subprotocol(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow, diff --git a/src/lib/protocols/tls.c b/src/lib/protocols/tls.c index 871b6f435..107bc501d 100644 --- a/src/lib/protocols/tls.c +++ b/src/lib/protocols/tls.c @@ -297,6 +297,31 @@ static int extractRDNSequence(struct ndpi_packet_struct *packet, /* **************************************** */ +static void checkTLSSubprotocol(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) { + if(flow->detected_protocol_stack[1] == NDPI_PROTOCOL_UNKNOWN) { + /* Subprotocol not yet set */ + + if(ndpi_struct->tls_cert_cache && flow->packet.iph) { + u_int32_t key = flow->packet.iph->daddr + flow->packet.tcp->dest; + u_int16_t cached_proto; + + if(ndpi_lru_find_cache(ndpi_struct->tls_cert_cache, key, + &cached_proto, 0 /* Don't remove it as it can be used for other connections */)) { + ndpi_protocol ret = { NDPI_PROTOCOL_TLS, cached_proto, NDPI_PROTOCOL_CATEGORY_UNSPECIFIED }; + + flow->detected_protocol_stack[0] = cached_proto, + flow->detected_protocol_stack[1] = NDPI_PROTOCOL_TLS; + + flow->category = ndpi_get_proto_category(ndpi_struct, ret); + ndpi_check_subprotocol_risk(flow, cached_proto); + } + } + } +} + +/* **************************************** */ + /* See https://blog.catchpoint.com/2017/05/12/dissecting-tls-using-wireshark/ */ static void processCertificateElements(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, @@ -569,11 +594,23 @@ static void processCertificateElements(struct ndpi_detection_module_struct *ndpi rdnSeqBuf, strlen(rdnSeqBuf),&proto_id); if(rc == 0) { + /* Match found */ + ndpi_protocol ret = { NDPI_PROTOCOL_TLS, proto_id, NDPI_PROTOCOL_CATEGORY_UNSPECIFIED}; + flow->detected_protocol_stack[0] = proto_id, flow->detected_protocol_stack[1] = NDPI_PROTOCOL_TLS; - if(proto_id == NDPI_PROTOCOL_ANYDESK) - ndpi_set_risk(flow, NDPI_DESKTOP_OR_FILE_SHARING_SESSION); /* Remote assistance */ + flow->category = ndpi_get_proto_category(ndpi_struct, ret); + ndpi_check_subprotocol_risk(flow, proto_id); + + if(ndpi_struct->tls_cert_cache == NULL) + ndpi_struct->tls_cert_cache = ndpi_lru_cache_init(1024); + + if(ndpi_struct->tls_cert_cache && flow->packet.iph) { + u_int32_t key = flow->packet.iph->daddr + flow->packet.tcp->dest; + + ndpi_lru_add_to_cache(ndpi_struct->tls_cert_cache, key, proto_id); + } } } } @@ -736,6 +773,8 @@ static int processTLSBlock(struct ndpi_detection_module_struct *ndpi_struct, && (packet->payload[0] == 0x02 /* Server Hello */)) { flow->l4.tcp.tls.certificate_processed = 1; /* No Certificate with TLS 1.3+ */ } + + checkTLSSubprotocol(ndpi_struct, flow); break; case 0x0b: /* Certificate */ @@ -1442,7 +1481,7 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: safari_ciphers++; break; - + case TLS_CIPHER_GREASE_RESERVED_0: case TLS_AES_128_GCM_SHA256: case TLS_AES_256_GCM_SHA384: @@ -1452,14 +1491,14 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: - case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: + case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: case TLS_RSA_WITH_AES_128_CBC_SHA: case TLS_RSA_WITH_AES_256_CBC_SHA: case TLS_RSA_WITH_AES_128_GCM_SHA256: - case TLS_RSA_WITH_AES_256_GCM_SHA384: + case TLS_RSA_WITH_AES_256_GCM_SHA384: safari_ciphers++, chrome_ciphers++; break; } @@ -1682,7 +1721,7 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, if(rc < 0) break; } - + for(i=0; i<tot_signature_algorithms_len; i+=2) { u_int16_t cipher_id = (u_int16_t)ntohs(*((u_int16_t*)&packet->payload[s_offset+i])); @@ -1715,7 +1754,7 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, if(chrome_signature_algorithms != 8) flow->protos.tls_quic_stun.tls_quic.browser_euristics.is_chrome_tls = 0; - + ja3.client.signature_algorithms[i*2] = '\0'; #ifdef DEBUG_TLS diff --git a/tests/pcap/forticlient.pcap b/tests/pcap/forticlient.pcap Binary files differnew file mode 100644 index 000000000..4012bdb7a --- /dev/null +++ b/tests/pcap/forticlient.pcap diff --git a/tests/result/forticlient.pcap.out b/tests/result/forticlient.pcap.out new file mode 100644 index 000000000..1b6cacbb1 --- /dev/null +++ b/tests/result/forticlient.pcap.out @@ -0,0 +1,12 @@ +FortiClient 2000 430931 5 + +JA3 Host Stats: + IP Address # JA3C + 1 192.168.1.178 2 + + + 1 TCP 192.168.1.178:61820 <-> 82.81.46.13:10443 [proto: 91.259/TLS.FortiClient][cat: VPN/2][1150 pkts/146555 bytes <-> 751 pkts/256436 bytes][Goodput ratio: 48/81][13.06 sec][bytes ratio: -0.273 (Download)][IAT c2s/s2c min/avg/max/stddev: 0/0 12/19 5218/5218 173/225][Pkt Len c2s/s2c min/avg/max/stddev: 66/66 127/341 1477/1506 88/427][Risk: ** TLS (probably) not carrying HTTPS **** Possibly Malicious JA3 Fingerprint **][TLSv1.2][Client: 82.81.46.13][JA3C: 40adfd923eb82b89d8836ba37a19bca1][JA3S: e35df3e00ca4ef31d42b34bebaa2f86e][Issuer: C=US, ST=California, L=Sunnyvale, O=Fortinet, OU=Certificate Authority, CN=support][Subject: C=US, ST=California, L=Sunnyvale, O=Fortinet, OU=FortiGate, CN=FWF60E4Q16012050][Certificate SHA-1: AA:8A:CE:95:99:2A:E0:A4:11:42:E4:C8:40:D7:DB:87:1F:4A:23:45][Firefox][Validity: 2016-09-12 10:06:20 - 2038-01-19 03:14:07][Cipher: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384][Plen Bins: 0,19,33,15,17,6,0,3,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] + 2 TCP 192.168.1.178:61812 <-> 82.81.46.13:10443 [proto: 91.259/TLS.FortiClient][cat: VPN/2][15 pkts/1753 bytes <-> 14 pkts/7481 bytes][Goodput ratio: 43/87][1.09 sec][bytes ratio: -0.620 (Download)][IAT c2s/s2c min/avg/max/stddev: 0/0 79/81 336/340 94/113][Pkt Len c2s/s2c min/avg/max/stddev: 66/66 117/534 450/1506 104/626][Risk: ** TLS (probably) not carrying HTTPS **][TLSv1.2][Client: 82.81.46.13][JA3C: e4d448cdfe06dc1243c1eb026c74ac9a][JA3S: 0debd3853f330c574b05e0b6d882dc27][Issuer: C=US, ST=California, L=Sunnyvale, O=Fortinet, OU=Certificate Authority, CN=support][Subject: C=US, ST=California, L=Sunnyvale, O=Fortinet, OU=FortiGate, CN=FWF60E4Q16012050][Certificate SHA-1: AA:8A:CE:95:99:2A:E0:A4:11:42:E4:C8:40:D7:DB:87:1F:4A:23:45][Firefox][Validity: 2016-09-12 10:06:20 - 2038-01-19 03:14:07][Cipher: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384][Plen Bins: 16,16,0,8,0,0,8,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,8,0,0,0,0,0,0,0,0,0,25,0,0] + 3 TCP 192.168.1.178:61806 <-> 82.81.46.13:10443 [proto: 91.259/TLS.FortiClient][cat: VPN/2][14 pkts/1462 bytes <-> 11 pkts/6959 bytes][Goodput ratio: 36/89][1.09 sec][bytes ratio: -0.653 (Download)][IAT c2s/s2c min/avg/max/stddev: 0/0 93/89 336/401 92/145][Pkt Len c2s/s2c min/avg/max/stddev: 66/66 104/633 269/1506 66/634][Risk: ** TLS (probably) not carrying HTTPS **][TLSv1.2][Client: 82.81.46.13][JA3C: e4d448cdfe06dc1243c1eb026c74ac9a][JA3S: 0debd3853f330c574b05e0b6d882dc27][Issuer: C=US, ST=California, L=Sunnyvale, O=Fortinet, OU=Certificate Authority, CN=support][Subject: C=US, ST=California, L=Sunnyvale, O=Fortinet, OU=FortiGate, CN=FWF60E4Q16012050][Certificate SHA-1: AA:8A:CE:95:99:2A:E0:A4:11:42:E4:C8:40:D7:DB:87:1F:4A:23:45][Firefox][Validity: 2016-09-12 10:06:20 - 2038-01-19 03:14:07][Cipher: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384][Plen Bins: 9,18,0,9,0,9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,27,0,0] + 4 TCP 192.168.1.178:61811 <-> 82.81.46.13:10443 [proto: 91.259/TLS.FortiClient][cat: VPN/2][13 pkts/1582 bytes <-> 11 pkts/3875 bytes][Goodput ratio: 45/81][1.09 sec][bytes ratio: -0.420 (Download)][IAT c2s/s2c min/avg/max/stddev: 0/0 102/102 203/231 56/98][Pkt Len c2s/s2c min/avg/max/stddev: 66/66 122/352 269/1506 77/487][Risk: ** TLS (probably) not carrying HTTPS **][TLSv1.2][Client: 82.81.46.13][JA3C: e4d448cdfe06dc1243c1eb026c74ac9a][JA3S: 0debd3853f330c574b05e0b6d882dc27][Issuer: C=US, ST=California, L=Sunnyvale, O=Fortinet, OU=Certificate Authority, CN=support][Subject: C=US, ST=California, L=Sunnyvale, O=Fortinet, OU=FortiGate, CN=FWF60E4Q16012050][Certificate SHA-1: AA:8A:CE:95:99:2A:E0:A4:11:42:E4:C8:40:D7:DB:87:1F:4A:23:45][Firefox][Validity: 2016-09-12 10:06:20 - 2038-01-19 03:14:07][Cipher: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384][Plen Bins: 10,20,0,10,10,0,20,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0] + 5 TCP 192.168.1.178:61805 <-> 82.81.46.13:10443 [proto: 91.259/TLS.FortiClient][cat: VPN/2][12 pkts/1297 bytes <-> 9 pkts/3531 bytes][Goodput ratio: 38/83][1.11 sec][bytes ratio: -0.463 (Download)][IAT c2s/s2c min/avg/max/stddev: 0/0 104/123 332/395 92/157][Pkt Len c2s/s2c min/avg/max/stddev: 66/66 108/392 237/1506 64/508][Risk: ** TLS (probably) not carrying HTTPS **][TLSv1.2][Client: 82.81.46.13][JA3C: e4d448cdfe06dc1243c1eb026c74ac9a][JA3S: 0debd3853f330c574b05e0b6d882dc27][Issuer: C=US, ST=California, L=Sunnyvale, O=Fortinet, OU=Certificate Authority, CN=support][Subject: C=US, ST=California, L=Sunnyvale, O=Fortinet, OU=FortiGate, CN=FWF60E4Q16012050][Certificate SHA-1: AA:8A:CE:95:99:2A:E0:A4:11:42:E4:C8:40:D7:DB:87:1F:4A:23:45][Firefox][Validity: 2016-09-12 10:06:20 - 2038-01-19 03:14:07][Cipher: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384][Plen Bins: 11,22,0,11,0,22,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0] |