diff options
-rw-r--r-- | src/include/ndpi_define.h.in | 2 | ||||
-rw-r--r-- | src/include/ndpi_typedefs.h | 6 | ||||
-rw-r--r-- | src/lib/ndpi_main.c | 4 | ||||
-rw-r--r-- | src/lib/protocols/tls.c | 82 | ||||
-rw-r--r-- | tests/result/KakaoTalk_talk.pcap.out | 2 |
5 files changed, 63 insertions, 33 deletions
diff --git a/src/include/ndpi_define.h.in b/src/include/ndpi_define.h.in index edac6f53b..9c1c0c169 100644 --- a/src/include/ndpi_define.h.in +++ b/src/include/ndpi_define.h.in @@ -353,6 +353,8 @@ #define NDPI_OPTIMAL_HLL_NUM_BUCKETS 16 +#define NDPI_MAX_NUM_DISSECTED_TLS_BLOCKS 32 + #ifdef __APPLE__ #include <libkern/OSByteOrder.h> diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h index 6d1a1719d..58d7b4885 100644 --- a/src/include/ndpi_typedefs.h +++ b/src/include/ndpi_typedefs.h @@ -669,7 +669,8 @@ struct ndpi_flow_tcp_struct { /* NDPI_PROTOCOL_TLS */ u_int8_t hello_processed:1, certificate_processed:1, subprotocol_detected:1, fingerprint_set:1, _pad:4; - u_int8_t sha1_certificate_fingerprint[20]; + u_int8_t sha1_certificate_fingerprint[20], num_tls_blocks; + u_int16_t tls_blocks_len[NDPI_MAX_NUM_DISSECTED_TLS_BLOCKS]; } tls; /* NDPI_PROTOCOL_POSTGRES */ @@ -1006,7 +1007,8 @@ struct ndpi_detection_module_struct { u_int32_t current_ts; u_int32_t ticks_per_second; - + u_int16_t num_tls_blocks_to_follow; + #ifdef NDPI_ENABLE_DEBUG_MESSAGES void *user_data; #endif diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c index b497bbaf8..3ca766772 100644 --- a/src/lib/ndpi_main.c +++ b/src/lib/ndpi_main.c @@ -6368,8 +6368,10 @@ u_int8_t ndpi_extra_dissection_possible(struct ndpi_detection_module_struct *ndp switch(proto) { case NDPI_PROTOCOL_TLS: - if(!flow->l4.tcp.tls.certificate_processed) + if((!flow->l4.tcp.tls.certificate_processed) + || (flow->l4.tcp.tls.num_tls_blocks <= ndpi_str->num_tls_blocks_to_follow)) { return(1); /* TODO: add check for TLS 1.3 */ + } break; case NDPI_PROTOCOL_HTTP: diff --git a/src/lib/protocols/tls.c b/src/lib/protocols/tls.c index ed0823547..20ac8c542 100644 --- a/src/lib/protocols/tls.c +++ b/src/lib/protocols/tls.c @@ -35,7 +35,7 @@ extern int processClientServerHello(struct ndpi_detection_module_struct *ndpi_st // #define DEBUG_TLS_MEMORY 1 // #define DEBUG_TLS 1 - +// #define DEBUG_TLS_BLOCKS 1 // #define DEBUG_CERTIFICATE_HASH /* #define DEBUG_FINGERPRINT 1 */ @@ -512,14 +512,14 @@ int processCertificate(struct ndpi_detection_module_struct *ndpi_struct, NDPI_SET_BIT(flow->risk, NDPI_MALFORMED_PACKET); return(-1); /* Invalid length */ } - + certificates_length = (packet->payload[4] << 16) + (packet->payload[5] << 8) + packet->payload[6]; if((packet->payload[4] != 0x0) || ((certificates_length+3) != length)) { NDPI_SET_BIT(flow->risk, NDPI_MALFORMED_PACKET); return(-2); /* Invalid length */ } - + if(!flow->l4.tcp.tls.srv_cert_fingerprint_ctx) { if((flow->l4.tcp.tls.srv_cert_fingerprint_ctx = (void*)ndpi_malloc(sizeof(SHA1_CTX))) == NULL) return(-3); /* Not enough memory */ @@ -592,7 +592,10 @@ int processCertificate(struct ndpi_detection_module_struct *ndpi_struct, certificates_offset += certificate_len; } - flow->extra_packets_func = NULL; /* We're good now */ + if(flow->l4.tcp.tls.num_tls_blocks >= ndpi_struct->num_tls_blocks_to_follow) { + flow->extra_packets_func = NULL; /* We're good now */ + } + return(1); } @@ -634,7 +637,7 @@ static int ndpi_search_tls_tcp(struct ndpi_detection_module_struct *ndpi_struct, u_int8_t something_went_wrong = 0; #ifdef DEBUG_TLS_MEMORY - printf("[TLS Mem] ndpi_search_tls_tcp() [payload_packet_len: %u]\n", + printf("[TLS Mem] ndpi_search_tls_tcp() Processing new packet [payload_packet_len: %u]\n", packet->payload_packet_len); #endif @@ -677,34 +680,53 @@ static int ndpi_search_tls_tcp(struct ndpi_detection_module_struct *ndpi_struct, /* Overwriting packet payload */ p = packet->payload, p_len = packet->payload_packet_len; /* Backup */ - /* Split the element in blocks */ - u_int16_t processed = 5; + if((len > 9) && (!flow->l4.tcp.tls.certificate_processed)) { + /* Split the element in blocks */ + u_int16_t processed = 5; - while((processed+4) < len) { - const u_int8_t *block = (const u_int8_t *)&flow->l4.tcp.tls.message.buffer[processed]; - u_int32_t block_len = (block[1] << 16) + (block[2] << 8) + block[3]; + while((processed+4) <= len) { + const u_int8_t *block = (const u_int8_t *)&flow->l4.tcp.tls.message.buffer[processed]; + u_int32_t block_len = (block[1] << 16) + (block[2] << 8) + block[3]; - if((block_len == 0) || (block_len > len) || ((block[1] != 0x0))) { - something_went_wrong = 1; - break; - } + if(/* (block_len == 0) || */ /* Note blocks can have zero lenght */ + (block_len > len) || ((block[1] != 0x0))) { + something_went_wrong = 1; + break; + } - packet->payload = block, packet->payload_packet_len = ndpi_min(block_len+4, flow->l4.tcp.tls.message.buffer_used); + packet->payload = block, packet->payload_packet_len = ndpi_min(block_len+4, flow->l4.tcp.tls.message.buffer_used); - if((processed+packet->payload_packet_len) > len) { - something_went_wrong = 1; - break; - } + if((processed+packet->payload_packet_len) > len) { + something_went_wrong = 1; + break; + } #ifdef DEBUG_TLS_MEMORY - printf("*** [TLS Mem] Processing %u bytes block [%02X %02X %02X %02X %02X]\n", - packet->payload_packet_len, - packet->payload[0], packet->payload[1], packet->payload[2], packet->payload[3], packet->payload[4]); + printf("*** [TLS Mem] Processing %u bytes block [%02X %02X %02X %02X %02X]\n", + packet->payload_packet_len, + packet->payload[0], packet->payload[1], packet->payload[2], packet->payload[3], packet->payload[4]); #endif + processTLSBlock(ndpi_struct, flow); + if(flow->l4.tcp.tls.num_tls_blocks < ndpi_struct->num_tls_blocks_to_follow) + flow->l4.tcp.tls.tls_blocks_len[flow->l4.tcp.tls.num_tls_blocks++] = packet->payload_packet_len; + +#ifdef DEBUG_TLS_BLOCKS + printf("*** [TLS Block] [len: %u][num_tls_blocks: %u]\n", + packet->payload_packet_len, flow->l4.tcp.tls.num_tls_blocks); +#endif - processTLSBlock(ndpi_struct, flow); - processed += packet->payload_packet_len; + processed += packet->payload_packet_len; + } + } else { + /* Process element as a whole */ + if(flow->l4.tcp.tls.num_tls_blocks < ndpi_struct->num_tls_blocks_to_follow) + flow->l4.tcp.tls.tls_blocks_len[flow->l4.tcp.tls.num_tls_blocks++] = len-5; + +#ifdef DEBUG_TLS_BLOCKS + printf("*** [TLS Block] [len: %u][num_tls_blocks: %u]\n", + len-5, flow->l4.tcp.tls.num_tls_blocks); +#endif } packet->payload = p, packet->payload_packet_len = p_len; /* Restore */ @@ -723,7 +745,8 @@ static int ndpi_search_tls_tcp(struct ndpi_detection_module_struct *ndpi_struct, } if(something_went_wrong) { - flow->check_extra_packets = 0, flow->extra_packets_func = NULL; + flow->check_extra_packets = 0; + flow->extra_packets_func = NULL; return(0); /* That's all */ } else return(1); @@ -781,11 +804,12 @@ static int ndpi_search_tls_udp(struct ndpi_detection_module_struct *ndpi_struct, /* **************************************** */ -static void tlsInitExtraPacketProcessing(struct ndpi_flow_struct *flow) { +static void tlsInitExtraPacketProcessing(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow) { flow->check_extra_packets = 1; /* At most 12 packets should almost always be enough to find the server certificate if it's there */ - flow->max_extra_packets_to_check = 12; + flow->max_extra_packets_to_check = 12 + (ndpi_struct->num_tls_blocks_to_follow*2); flow->extra_packets_func = (flow->packet.udp != NULL) ? ndpi_search_tls_udp : ndpi_search_tls_tcp; } @@ -800,7 +824,7 @@ static void ndpi_int_tls_add_connection(struct ndpi_detection_module_struct *ndp if((flow->detected_protocol_stack[0] == protocol) || (flow->detected_protocol_stack[1] == protocol)) { if(!flow->check_extra_packets) - tlsInitExtraPacketProcessing(flow); + tlsInitExtraPacketProcessing(ndpi_struct, flow); return; } @@ -810,7 +834,7 @@ static void ndpi_int_tls_add_connection(struct ndpi_detection_module_struct *ndp protocol = ndpi_tls_refine_master_protocol(ndpi_struct, flow, protocol); ndpi_set_detected_protocol(ndpi_struct, flow, protocol, NDPI_PROTOCOL_TLS); - tlsInitExtraPacketProcessing(flow); + tlsInitExtraPacketProcessing(ndpi_struct, flow); } /* **************************************** */ diff --git a/tests/result/KakaoTalk_talk.pcap.out b/tests/result/KakaoTalk_talk.pcap.out index 2a4881ba5..1a8c070bc 100644 --- a/tests/result/KakaoTalk_talk.pcap.out +++ b/tests/result/KakaoTalk_talk.pcap.out @@ -16,7 +16,7 @@ JA3 Host Stats: 1 UDP 10.24.82.188:11320 <-> 1.201.1.174:23044 [proto: 87/RTP][cat: Media/1][757 pkts/106335 bytes <-> 746 pkts/93906 bytes][Goodput ratio: 69/65][45.42 sec][bytes ratio: 0.062 (Mixed)][IAT c2s/s2c min/avg/max/stddev: 0/0 57/48 202/340 49/48][Pkt Len c2s/s2c min/avg/max/stddev: 99/99 140/126 234/236 43/33][PLAIN TEXT (46yOXQ)][Plen Bins: 0,60,19,16,3,1,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] 2 UDP 10.24.82.188:10268 <-> 1.201.1.174:23046 [proto: 87/RTP][cat: Media/1][746 pkts/93906 bytes <-> 742 pkts/104604 bytes][Goodput ratio: 65/69][45.02 sec][bytes ratio: -0.054 (Mixed)][IAT c2s/s2c min/avg/max/stddev: 5/0 58/49 112/476 23/54][Pkt Len c2s/s2c min/avg/max/stddev: 99/99 126/141 236/234 33/43][PLAIN TEXT (46yOXQ)][Plen Bins: 0,61,18,16,3,1,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] 3 TCP 10.24.82.188:58857 <-> 110.76.143.50:9001 [proto: 91/TLS][cat: Web/5][22 pkts/5326 bytes <-> 18 pkts/5212 bytes][Goodput ratio: 72/76][51.59 sec][bytes ratio: 0.011 (Mixed)][IAT c2s/s2c min/avg/max/stddev: 14/0 2358/3528 20472/21237 5098/5912][Pkt Len c2s/s2c min/avg/max/stddev: 68/68 242/290 878/920 254/276][Risk: ** Self-signed Certificate **** Obsolete TLS version (< 1.1) **** Weak TLS cipher **][TLSv1][JA3C: 4b79ae67eb3b2cf1c75e68ea0100ca1b][JA3S: 4ea82b75038dd27e8a1cb69d8b839b26 (WEAK)][Issuer: C=KR, L=Seoul, O=Kakao, CN=Kakao.com][Subject: C=KR, L=Seoul, O=Kakao, CN=Kakao.com][Certificate SHA-1: 65:88:37:51:01:AA:1F:12:E4:44:27:52:F9:32:FD:40:94:C1:08:D9][Validity: 2011-12-05 09:19:25 - 2021-12-02 09:19:25][Cipher: TLS_RSA_WITH_AES_128_CBC_SHA][Plen Bins: 0,0,0,0,5,35,0,5,0,15,5,5,0,0,0,0,0,0,0,0,5,5,0,0,10,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] - 4 TCP 10.24.82.188:32968 <-> 110.76.143.50:8080 [proto: 91/TLS][cat: Web/5][23 pkts/4380 bytes <-> 22 pkts/5728 bytes][Goodput ratio: 64/73][52.84 sec][bytes ratio: -0.133 (Mixed)][IAT c2s/s2c min/avg/max/stddev: 2/0 691/1317 6069/10226 1399/2632][Pkt Len c2s/s2c min/avg/max/stddev: 68/68 190/260 814/920 164/241][Risk: ** Self-signed Certificate **** Obsolete TLS version (< 1.1) **** Weak TLS cipher **][TLSv1][JA3C: 4b79ae67eb3b2cf1c75e68ea0100ca1b][JA3S: 4ea82b75038dd27e8a1cb69d8b839b26 (WEAK)][Issuer: C=KR, L=Seoul, O=Kakao, CN=Kakao.com][Subject: C=KR, L=Seoul, O=Kakao, CN=Kakao.com][Certificate SHA-1: 65:88:37:51:01:AA:1F:12:E4:44:27:52:F9:32:FD:40:94:C1:08:D9][Validity: 2011-12-05 09:19:25 - 2021-12-02 09:19:25][Cipher: TLS_RSA_WITH_AES_128_CBC_SHA][Plen Bins: 0,0,0,0,4,48,0,4,0,17,4,4,0,0,0,4,0,0,0,0,0,0,4,4,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] + 4 TCP 10.24.82.188:32968 <-> 110.76.143.50:8080 [proto: 131.91/HTTP_Proxy.TLS][cat: Web/5][23 pkts/4380 bytes <-> 22 pkts/5728 bytes][Goodput ratio: 64/73][52.84 sec][bytes ratio: -0.133 (Mixed)][IAT c2s/s2c min/avg/max/stddev: 2/0 691/1317 6069/10226 1399/2632][Pkt Len c2s/s2c min/avg/max/stddev: 68/68 190/260 814/920 164/241][Risk: ** Self-signed Certificate **** Obsolete TLS version (< 1.1) **** Weak TLS cipher **][TLSv1][JA3C: 4b79ae67eb3b2cf1c75e68ea0100ca1b][JA3S: 4ea82b75038dd27e8a1cb69d8b839b26 (WEAK)][Issuer: C=KR, L=Seoul, O=Kakao, CN=Kakao.com][Subject: C=KR, L=Seoul, O=Kakao, CN=Kakao.com][Certificate SHA-1: 65:88:37:51:01:AA:1F:12:E4:44:27:52:F9:32:FD:40:94:C1:08:D9][Validity: 2011-12-05 09:19:25 - 2021-12-02 09:19:25][Cipher: TLS_RSA_WITH_AES_128_CBC_SHA][Plen Bins: 0,0,0,0,4,48,0,4,0,17,4,4,0,0,0,4,0,0,0,0,0,0,4,4,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] 5 TCP 10.24.82.188:59954 <-> 173.252.88.128:443 [proto: 91.119/TLS.Facebook][cat: SocialNetwork/6][15 pkts/2932 bytes <-> 14 pkts/1092 bytes][Goodput ratio: 71/27][1.96 sec][bytes ratio: 0.457 (Upload)][IAT c2s/s2c min/avg/max/stddev: 2/0 141/117 494/295 163/92][Pkt Len c2s/s2c min/avg/max/stddev: 56/56 195/78 735/189 228/35][Risk: ** Obsolete TLS version (< 1.1) **][TLSv1][JA3C: dff8a0aa1c904aaea76c5bf624e88333][JA3S: 07dddc59e60135c7b479d39c3ae686af][Cipher: TLS_ECDHE_ECDSA_WITH_RC4_128_SHA][Plen Bins: 30,23,0,0,15,0,7,0,7,0,0,0,0,0,0,0,0,0,0,0,0,15,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 10.24.82.188:10269 <-> 1.201.1.174:23047 [proto: 194/KakaoTalk_Voice][cat: VoIP/10][12 pkts/1692 bytes <-> 10 pkts/1420 bytes][Goodput ratio: 69/69][45.10 sec][bytes ratio: 0.087 (Mixed)][IAT c2s/s2c min/avg/max/stddev: 1062/3176 4203/4247 4716/5160 1131/719][Pkt Len c2s/s2c min/avg/max/stddev: 122/142 141/142 150/142 6/0][Plen Bins: 0,0,4,95,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 UDP 10.24.82.188:11321 <-> 1.201.1.174:23045 [proto: 194/KakaoTalk_Voice][cat: VoIP/10][11 pkts/1542 bytes <-> 11 pkts/1542 bytes][Goodput ratio: 69/69][43.84 sec][bytes ratio: 0.000 (Mixed)][IAT c2s/s2c min/avg/max/stddev: 1105/1052 4266/3766 4903/4991 1245/1144][Pkt Len c2s/s2c min/avg/max/stddev: 122/122 140/140 142/142 6/6][Plen Bins: 0,0,9,90,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] |