diff options
author | Ivan Nardi <12729895+IvanNardi@users.noreply.github.com> | 2023-11-07 17:46:29 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-07 17:46:29 +0100 |
commit | b539b0d0902bc0fda235d8bbf1bc7f64e9028465 (patch) | |
tree | b4f3e0283cfd2ed757d5721ffb9c6d6862db8597 | |
parent | 58a9e2d9679f268a64b9082dae70498147bb58a8 (diff) |
fuzz: improve coverage and remove dead code (#2135)
We are not able to remove custom rules: remove the empty stubs (which
originate from the original OpenDPI code).
`ndpi_guess_protocol_id()` is only called on the first packet of the
flow, so the bitmask `flow->excluded_protocol_bitmask` is always empty,
since we didn't call any dissectors yet.
Move another hash function to the dedicated source file.
-rw-r--r-- | fuzz/fuzz_alg_crc32_md5.c | 3 | ||||
-rw-r--r-- | fuzz/fuzz_ds_hash.cpp | 2 | ||||
-rw-r--r-- | fuzz/fuzz_gcrypt_cipher.cpp | 42 | ||||
-rw-r--r-- | fuzz/fuzz_gcrypt_gcm.cpp | 10 | ||||
-rw-r--r-- | src/lib/ndpi_hash.c | 27 | ||||
-rw-r--r-- | src/lib/ndpi_main.c | 82 | ||||
-rw-r--r-- | src/lib/ndpi_utils.c | 34 | ||||
-rw-r--r-- | tests/cfgs/default/pcap/stun.pcap | bin | 29574 -> 34424 bytes | |||
-rw-r--r-- | tests/cfgs/default/result/stun.pcap.out | 18 |
9 files changed, 84 insertions, 134 deletions
diff --git a/fuzz/fuzz_alg_crc32_md5.c b/fuzz/fuzz_alg_crc32_md5.c index 1f45e476e..def56566c 100644 --- a/fuzz/fuzz_alg_crc32_md5.c +++ b/fuzz/fuzz_alg_crc32_md5.c @@ -15,6 +15,9 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { ndpi_murmur_hash((const char *)data, size); ndpi_quick_hash(data, size); + if(size >= 16) + ndpi_quick_16_byte_hash(data); + str = ndpi_malloc(size + 1); if(str) { memcpy(str, data, size); diff --git a/fuzz/fuzz_ds_hash.cpp b/fuzz/fuzz_ds_hash.cpp index 5b26d684b..2b7463b49 100644 --- a/fuzz/fuzz_ds_hash.cpp +++ b/fuzz/fuzz_ds_hash.cpp @@ -57,6 +57,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { ndpi_hash_find_entry(h, value_added.data(), value_added.size(), &value); } + if (fuzzed_data.ConsumeBool()) + ndpi_hash_free(NULL, cleanup_func); ndpi_hash_free(&h, cleanup_func); return 0; diff --git a/fuzz/fuzz_gcrypt_cipher.cpp b/fuzz/fuzz_gcrypt_cipher.cpp index 7eaffcdc2..270c583ea 100644 --- a/fuzz/fuzz_gcrypt_cipher.cpp +++ b/fuzz/fuzz_gcrypt_cipher.cpp @@ -67,28 +67,34 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { rc_e = mbedtls_cipher_setkey(ctx_e, key.data(), key.size() * 8, MBEDTLS_ENCRYPT); rc_d = mbedtls_cipher_setkey(ctx_d, key.data(), key.size() * 8, MBEDTLS_DECRYPT); if(rc_e == 0 && rc_d == 0) { - rc_e = mbedtls_cipher_set_iv(ctx_e, iv.data(), iv.size()); - rc_d = mbedtls_cipher_set_iv(ctx_d, iv.data(), iv.size()); - if(rc_e == 0 && rc_d == 0) { - mbedtls_cipher_reset(ctx_e); - mbedtls_cipher_reset(ctx_d); - - rc_e = mbedtls_cipher_update(ctx_e, input.data(), input.size(), output, &output_size); - if(rc_e == 0) { - rc_e = mbedtls_cipher_finish(ctx_e, NULL, &output_size2); + + if(fuzzed_data.ConsumeBool()) { + rc_e = mbedtls_cipher_crypt(ctx_e, iv.data(), iv.size(), + input.data(), input.size(), output, &output_size); + } else { + rc_e = mbedtls_cipher_set_iv(ctx_e, iv.data(), iv.size()); + rc_d = mbedtls_cipher_set_iv(ctx_d, iv.data(), iv.size()); + if(rc_e == 0 && rc_d == 0) { + mbedtls_cipher_reset(ctx_e); + mbedtls_cipher_reset(ctx_d); + + rc_e = mbedtls_cipher_update(ctx_e, input.data(), input.size(), output, &output_size); if(rc_e == 0) { + rc_e = mbedtls_cipher_finish(ctx_e, NULL, &output_size2); + if(rc_e == 0) { - rc_d = mbedtls_cipher_update(ctx_d, output, output_size, decrypted, &decrypted_size); - if(rc_d == 0) { - rc_d = mbedtls_cipher_finish(ctx_d, NULL, &output_size2); - /* TODO: decryption doesn't work with no-aesni data path! - Note that with MASAN, aesni is always disabled */ + rc_d = mbedtls_cipher_update(ctx_d, output, output_size, decrypted, &decrypted_size); + if(rc_d == 0) { + rc_d = mbedtls_cipher_finish(ctx_d, NULL, &output_size2); + /* TODO: decryption doesn't work with no-aesni data path! + Note that with MASAN, aesni is always disabled */ #if 0 - if(rc_d == 0) { - assert(input.size() == decrypted_size); - assert(memcmp(input.data(), decrypted, decrypted_size) == 0); - } + if(rc_d == 0) { + assert(input.size() == decrypted_size); + assert(memcmp(input.data(), decrypted, decrypted_size) == 0); + } #endif + } } } } diff --git a/fuzz/fuzz_gcrypt_gcm.cpp b/fuzz/fuzz_gcrypt_gcm.cpp index debead9b4..3e0b85cca 100644 --- a/fuzz/fuzz_gcrypt_gcm.cpp +++ b/fuzz/fuzz_gcrypt_gcm.cpp @@ -20,13 +20,14 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { int key_len, rc_e, rc_d; mbedtls_cipher_id_t cipher; unsigned char *tag; - int iv_len, tag_len, input_length, force_auth_tag_error; + int iv_len, tag_len, ad_len, input_length, force_auth_tag_error; /* No real memory allocations involved */ if(fuzzed_data.remaining_bytes() < 1 + 4 + 512 / 8 + 1 + 64 + /* iv */ 1 + /* tag_len */ + 1 + 17 + /* ad */ 1 + 64 + /* input */ 1 + /* force_auth_tag_error */ 1 /* useless data: to be able to add the check with assert */) @@ -50,6 +51,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { tag_len = fuzzed_data.ConsumeIntegralInRange(0, 17); tag = (unsigned char *)malloc(tag_len); + ad_len = fuzzed_data.ConsumeIntegralInRange(0, 17); + std::vector<u_int8_t>ad = fuzzed_data.ConsumeBytes<uint8_t>(ad_len); + input_length = fuzzed_data.ConsumeIntegralInRange(16, 64); std::vector<unsigned char>input = fuzzed_data.ConsumeBytes<u_int8_t>(input_length); output = (unsigned char *)malloc(input_length); @@ -71,7 +75,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { rc_e = mbedtls_gcm_crypt_and_tag(gcm_e_ctx, MBEDTLS_GCM_ENCRYPT, input.size(), iv.data(), iv.size(), - NULL, 0, /* TODO */ + ad.data(), ad.size(), input.data(), output, tag_len, tag); @@ -85,7 +89,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { rc_d = mbedtls_gcm_auth_decrypt(gcm_d_ctx, input.size(), iv.data(), iv.size(), - NULL, 0, /* TODO */ + ad.data(), ad.size(), tag, tag_len, output, decrypted); diff --git a/src/lib/ndpi_hash.c b/src/lib/ndpi_hash.c index 567e1d67c..0a3507d76 100644 --- a/src/lib/ndpi_hash.c +++ b/src/lib/ndpi_hash.c @@ -125,4 +125,31 @@ u_int32_t ndpi_hash_string_len(const char *str, u_int len) { return(hash); } +/* ******************************************************************** */ + +#define ROR64(x,r) (((x)>>(r))|((x)<<(64-(r)))) + +/* + 'in_16_bytes_long` points to some 16 byte memory data to be hashed; + two independent 64-bit linear congruential generators are applied + results are mixed, scrambled and cast to 32-bit +*/ +u_int32_t ndpi_quick_16_byte_hash(u_int8_t *in_16_bytes_long) { + u_int64_t a = *(u_int64_t*)(in_16_bytes_long + 0); + u_int64_t c = *(u_int64_t*)(in_16_bytes_long + 8); + // multipliers are taken from sprng.org, addends are prime + a = a * 0x2c6fe96ee78b6955 + 0x9af64480a3486659; + c = c * 0x369dea0f31a53f85 + 0xd0c6225445b76b5b; + + // mix results + a += c; + + // final scramble + a ^= ROR64(a, 13) ^ ROR64(a, 7); + + // down-casting, also taking advantage of upper half + a ^= a >> 32; + + return((u_int32_t)a); +} diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c index 5cdaa9f2b..eaffe2056 100644 --- a/src/lib/ndpi_main.c +++ b/src/lib/ndpi_main.c @@ -224,8 +224,6 @@ static int addDefaultPort(struct ndpi_detection_module_struct *ndpi_str, ndpi_port_range *range, ndpi_proto_defaults_t *def, u_int8_t customUserProto, ndpi_default_ports_tree_node_t **root, const char *_func, int _line); -static int removeDefaultPort(ndpi_port_range *range, ndpi_proto_defaults_t *def, - ndpi_default_ports_tree_node_t **root); static void ndpi_reset_packet_line_info(struct ndpi_packet_struct *packet); static void ndpi_int_change_protocol(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow, @@ -474,7 +472,6 @@ u_int8_t ndpi_is_subprotocol_informative(struct ndpi_detection_module_struct *nd /* All dissectors that have calls to ndpi_match_host_subprotocol() */ case NDPI_PROTOCOL_DNS: return(1); - break; default: return(0); @@ -683,37 +680,6 @@ static int addDefaultPort(struct ndpi_detection_module_struct *ndpi_str, /* ****************************************************** */ /* - NOTE - - This function must be called with a semaphore set, this in order to avoid - changing the datastructures while using them -*/ -static int removeDefaultPort(ndpi_port_range *range, ndpi_proto_defaults_t *def, - ndpi_default_ports_tree_node_t **root) { - ndpi_default_ports_tree_node_t node; - u_int16_t port; - - for(port = range->port_low; port <= range->port_high; port++) { - ndpi_default_ports_tree_node_t *ret; - - node.proto = def, node.default_port = port; - - ret = (ndpi_default_ports_tree_node_t *) - ndpi_tdelete(&node, (void *) root, - ndpi_default_ports_tree_node_t_cmp); /* Add it to the tree */ - - if(ret != NULL) { - ndpi_free((ndpi_default_ports_tree_node_t *) ret); - return(0); - } - } - - return(-1); -} - -/* ****************************************************** */ - -/* This is a function used to see if we need to add a trailer $ in case the string is complete or is a string that can be matched in the @@ -833,19 +799,6 @@ static int ndpi_add_host_url_subprotocol(struct ndpi_detection_module_struct *nd } -/* ****************************************************** */ - -/* - NOTE - - This function must be called with a semaphore set, this in order to avoid - changing the datastructures while using them -*/ -static int ndpi_remove_host_url_subprotocol(struct ndpi_detection_module_struct *ndpi_str, char *value, int protocol_id) { - NDPI_LOG_ERR(ndpi_str, "[NDPI] Missing implementation for proto %s/%d\n", value, protocol_id); - return(-1); -} - /* ******************************************************************** */ int ndpi_init_empty_app_protocol(ndpi_protocol_match const * const hostname_list, @@ -4014,15 +3967,8 @@ u_int16_t ndpi_guess_protocol_id(struct ndpi_detection_module_struct *ndpi_str, if(found != NULL) { u_int16_t guessed_proto = found->proto->protoId; - /* We need to check if the guessed protocol isn't excluded by nDPI */ - if(flow && (proto == IPPROTO_UDP) && - NDPI_COMPARE_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, guessed_proto) && - is_udp_not_guessable_protocol(guessed_proto)) - return(NDPI_PROTOCOL_UNKNOWN); - else { - *user_defined_proto = found->customUserProto; - return(guessed_proto); - } + *user_defined_proto = found->customUserProto; + return(guessed_proto); } } else { /* No TCP/UDP */ @@ -4264,8 +4210,8 @@ int ndpi_add_trusted_issuer_dn(struct ndpi_detection_module_struct *ndpi_str, ch } /* ******************************************************************** */ -int ndpi_handle_rule(struct ndpi_detection_module_struct *ndpi_str, - char *rule, u_int8_t do_add) { +static int ndpi_handle_rule(struct ndpi_detection_module_struct *ndpi_str, + char *rule) { char *at, *proto, *elem; ndpi_proto_defaults_t *def; u_int subprotocol_id, i; @@ -4330,11 +4276,6 @@ int ndpi_handle_rule(struct ndpi_detection_module_struct *ndpi_str, def = NULL; if(def == NULL) { - if(!do_add) { - /* We need to remove a rule */ - NDPI_LOG_ERR(ndpi_str, "Unable to find protocol '%s': skipping rule '%s'\n", proto, rule); - return(-3); - } else { ndpi_port_range ports_a[MAX_DEFAULT_PORTS], ports_b[MAX_DEFAULT_PORTS]; char *equal = strchr(proto, '='); u_int16_t user_proto_id = ndpi_str->ndpi_num_supported_protocols; @@ -4371,7 +4312,6 @@ int ndpi_handle_rule(struct ndpi_detection_module_struct *ndpi_str, def = &ndpi_str->proto_defaults[ndpi_str->ndpi_num_supported_protocols]; subprotocol_id = ndpi_str->ndpi_num_supported_protocols; ndpi_str->ndpi_num_supported_protocols++, ndpi_str->ndpi_num_custom_protocols++; - } } while((elem = strsep(&rule, ",")) != NULL) { @@ -4445,11 +4385,8 @@ int ndpi_handle_rule(struct ndpi_detection_module_struct *ndpi_str, else range.port_low = range.port_high = atoi(&elem[4]); - if(do_add) - rc = addDefaultPort(ndpi_str, &range, def, 1 /* Custom user proto */, + rc = addDefaultPort(ndpi_str, &range, def, 1 /* Custom user proto */, is_tcp ? &ndpi_str->tcpRoot : &ndpi_str->udpRoot, __FUNCTION__, __LINE__); - else - rc = removeDefaultPort(&range, def, is_tcp ? &ndpi_str->tcpRoot : &ndpi_str->udpRoot); if(rc != 0) ret = rc; } else if(is_ip) { @@ -4458,11 +4395,8 @@ int ndpi_handle_rule(struct ndpi_detection_module_struct *ndpi_str, if(rc != 0) return(rc); } else { - if(do_add) - ndpi_add_host_url_subprotocol(ndpi_str, value, subprotocol_id, NDPI_PROTOCOL_CATEGORY_UNSPECIFIED, - NDPI_PROTOCOL_ACCEPTABLE, 0); - else - ndpi_remove_host_url_subprotocol(ndpi_str, value, subprotocol_id); + ndpi_add_host_url_subprotocol(ndpi_str, value, subprotocol_id, NDPI_PROTOCOL_CATEGORY_UNSPECIFIED, + NDPI_PROTOCOL_ACCEPTABLE, 0); } } @@ -4971,7 +4905,7 @@ int ndpi_load_protocols_file_fd(struct ndpi_detection_module_struct *ndpi_str, F /* printf("Processing: \"%s\"\n", buffer); */ - if(ndpi_handle_rule(ndpi_str, buffer, 1) != 0) + if(ndpi_handle_rule(ndpi_str, buffer) != 0) NDPI_LOG_INFO(ndpi_str, "Discraded rule '%s'\n", buffer); } diff --git a/src/lib/ndpi_utils.c b/src/lib/ndpi_utils.c index 68c07fa6c..b41ec6706 100644 --- a/src/lib/ndpi_utils.c +++ b/src/lib/ndpi_utils.c @@ -2051,11 +2051,10 @@ const char* ndpi_risk2str(ndpi_risk_enum risk) { case NDPI_TLS_ALPN_SNI_MISMATCH: return("ALPN/SNI Mismatch"); - + case NDPI_MALWARE_HOST_CONTACTED: return("Client contacted a malware host"); - break; - + default: ndpi_snprintf(buf, sizeof(buf), "%d", (int)risk); return(buf); @@ -2201,35 +2200,6 @@ ndpi_http_method ndpi_http_str2method(const char* method, u_int16_t method_len) /* ******************************************************************** */ -#define ROR64(x,r) (((x)>>(r))|((x)<<(64-(r)))) - -/* - 'in_16_bytes_long` points to some 16 byte memory data to be hashed; - two independent 64-bit linear congruential generators are applied - results are mixed, scrambled and cast to 32-bit -*/ -u_int32_t ndpi_quick_16_byte_hash(u_int8_t *in_16_bytes_long) { - u_int64_t a = *(u_int64_t*)(in_16_bytes_long + 0); - u_int64_t c = *(u_int64_t*)(in_16_bytes_long + 8); - - // multipliers are taken from sprng.org, addends are prime - a = a * 0x2c6fe96ee78b6955 + 0x9af64480a3486659; - c = c * 0x369dea0f31a53f85 + 0xd0c6225445b76b5b; - - // mix results - a += c; - - // final scramble - a ^= ROR64(a, 13) ^ ROR64(a, 7); - - // down-casting, also taking advantage of upper half - a ^= a >> 32; - - return((u_int32_t)a); -} - -/* ******************************************************************** */ - int ndpi_hash_init(ndpi_str_hash **h) { if (h == NULL) diff --git a/tests/cfgs/default/pcap/stun.pcap b/tests/cfgs/default/pcap/stun.pcap Binary files differindex aceefec22..c7e645eea 100644 --- a/tests/cfgs/default/pcap/stun.pcap +++ b/tests/cfgs/default/pcap/stun.pcap diff --git a/tests/cfgs/default/result/stun.pcap.out b/tests/cfgs/default/result/stun.pcap.out index a396239ff..4c421c21e 100644 --- a/tests/cfgs/default/result/stun.pcap.out +++ b/tests/cfgs/default/result/stun.pcap.out @@ -1,13 +1,14 @@ Guessed flow protos: 0 DPI Packets (TCP): 9 (4.50 pkts/flow) -DPI Packets (UDP): 8 (2.67 pkts/flow) -Confidence DPI : 5 (flows) -Num dissector calls: 20 (4.00 diss/flow) +DPI Packets (UDP): 12 (3.00 pkts/flow) +DPI Packets (other): 1 (1.00 pkts/flow) +Confidence DPI : 7 (flows) +Num dissector calls: 22 (3.14 diss/flow) LRU cache ookla: 0/0/0 (insert/search/found) LRU cache bittorrent: 0/0/0 (insert/search/found) LRU cache zoom: 0/0/0 (insert/search/found) -LRU cache stun: 6/22/0 (insert/search/found) +LRU cache stun: 8/28/0 (insert/search/found) LRU cache tls_cert: 0/0/0 (insert/search/found) LRU cache mining: 0/0/0 (insert/search/found) LRU cache msteams: 0/0/0 (insert/search/found) @@ -17,16 +18,17 @@ Automa domain: 0/0 (search/found) Automa tls cert: 0/0 (search/found) Automa risk mask: 1/0 (search/found) Automa common alpns: 0/0 (search/found) -Patricia risk mask: 4/0 (search/found) +Patricia risk mask: 8/0 (search/found) Patricia risk mask IPv6: 2/0 (search/found) Patricia risk: 1/0 (search/found) Patricia risk IPv6: 1/0 (search/found) -Patricia protocols: 6/2 (search/found) +Patricia protocols: 8/4 (search/found) Patricia protocols IPv6: 2/0 (search/found) Skype_TeamsCall 15 2124 1 STUN 62 7620 2 -GoogleHangoutDuo 33 6292 1 +ICMP 1 122 1 +GoogleHangoutDuo 41 7228 2 FacebookVoip 75 10554 1 1 UDP 192.168.12.169:38123 <-> 31.13.86.54:40003 [proto: 78.268/STUN.FacebookVoip][IP: 119/Facebook][ClearText][Confidence: DPI][DPI packets: 2][cat: VoIP/10][40 pkts/6134 bytes <-> 35 pkts/4420 bytes][Goodput ratio: 73/67][10.09 sec][Hostname/SNI: turner.facebook][bytes ratio: 0.162 (Mixed)][IAT c2s/s2c min/avg/max/stddev: 0/0 260/331 6004/5997 1040/1126][Pkt Len c2s/s2c min/avg/max/stddev: 70/68 153/126 190/174 31/39][Risk: ** Known Proto on Non Std Port **][Risk Score: 50][PLAIN TEXT (unauthorized)][Plen Bins: 8,14,9,28,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] @@ -34,3 +36,5 @@ FacebookVoip 75 10554 1 3 UDP [3516:bf0b:fc53:75e7:70af:f67f:8e49:f603]:56880 <-> [2a38:e156:8167:a333:face:b00c::24d9]:3478 [proto: 78/STUN][IP: 0/Unknown][ClearText][Confidence: DPI][DPI packets: 5][cat: Network/14][21 pkts/1722 bytes <-> 21 pkts/2226 bytes][Goodput ratio: 24/41][191.49 sec][bytes ratio: -0.128 (Mixed)][IAT c2s/s2c min/avg/max/stddev: 2/2 9451/9451 10358/10358 2441/2441][Pkt Len c2s/s2c min/avg/max/stddev: 82/106 82/106 82/106 0/0][PLAIN TEXT (WOBTrOXR)][Plen Bins: 50,50,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] 4 TCP 87.47.100.17:3478 <-> 54.1.57.155:37257 [proto: 78/STUN][IP: 0/Unknown][ClearText][Confidence: DPI][DPI packets: 6][cat: Network/14][9 pkts/1494 bytes <-> 11 pkts/2178 bytes][Goodput ratio: 60/67][0.95 sec][Hostname/SNI: apps-host.com][bytes ratio: -0.186 (Mixed)][IAT c2s/s2c min/avg/max/stddev: 0/0 104/96 267/252 102/93][Pkt Len c2s/s2c min/avg/max/stddev: 74/94 166/198 234/354 41/65][PLAIN TEXT (Unauthorized)][Plen Bins: 10,0,15,21,42,5,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] 5 TCP 10.77.110.51:41588 <-> 10.206.50.239:42000 [VLAN: 1611][proto: 78.38/STUN.Skype_TeamsCall][IP: 0/Unknown][ClearText][Confidence: DPI][DPI packets: 3][cat: VoIP/10][7 pkts/1006 bytes <-> 8 pkts/1118 bytes][Goodput ratio: 58/57][1.05 sec][bytes ratio: -0.053 (Mixed)][IAT c2s/s2c min/avg/max/stddev: 0/0 189/134 369/399 144/153][Pkt Len c2s/s2c min/avg/max/stddev: 70/64 144/140 164/172 31/43][Plen Bins: 0,0,25,75,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] + 6 UDP 192.168.12.169:43016 <-> 74.125.247.128:3478 [proto: 78.201/STUN.GoogleHangoutDuo][IP: 126/Google][ClearText][Confidence: DPI][DPI packets: 4][cat: VoIP/10][4 pkts/528 bytes <-> 4 pkts/408 bytes][Goodput ratio: 68/59][1.25 sec][Hostname/SNI: turn.l.google.com][bytes ratio: 0.128 (Mixed)][IAT c2s/s2c min/avg/max/stddev: 9/23 342/409 974/1177 447/543][Pkt Len c2s/s2c min/avg/max/stddev: 62/74 132/102 198/122 61/19][PLAIN TEXT (BSnLfRxS6)][Plen Bins: 12,37,25,0,25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] + 7 ICMP 192.168.12.169:0 -> 74.125.247.128:0 [proto: 81/ICMP][IP: 126/Google][ClearText][Confidence: DPI][DPI packets: 1][cat: Network/14][1 pkts/122 bytes -> 0 pkts/0 bytes][Goodput ratio: 65/0][< 1 sec][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][PLAIN TEXT (62NfUD5)][Plen Bins: 0,0,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] |