From 659f75138c2a95e5823608a545b9a3d3ced223bc Mon Sep 17 00:00:00 2001 From: Luca Deri Date: Sat, 14 Sep 2019 12:38:58 +0200 Subject: TLS cerficate hash calculation --- src/include/ndpi_typedefs.h | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'src/include/ndpi_typedefs.h') diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h index b67a22a14..0f3aee9f2 100644 --- a/src/include/ndpi_typedefs.h +++ b/src/include/ndpi_typedefs.h @@ -602,12 +602,17 @@ struct ndpi_flow_tcp_struct { /* NDPI_PROTOCOL_TELNET */ u_int32_t telnet_stage:2; // 0 - 2 + void* tls_srv_cert_fingerprint_ctx; + /* NDPI_PROTOCOL_TLS */ - u_int8_t ssl_seen_client_cert:1, - ssl_seen_server_cert:1, - ssl_seen_certificate:1, - ssl_stage:2; // 0 - 5 - + u_int8_t tls_seen_client_cert:1, + tls_seen_server_cert:1, + tls_seen_certificate:1, + tls_srv_cert_fingerprint_found:1, + tls_srv_cert_fingerprint_processed:1, + tls_stage:2, _pad:1; // 0 - 5 + int16_t tls_record_offset, tls_fingerprint_len; /* Need to be signed */ + /* NDPI_PROTOCOL_POSTGRES */ u_int32_t postgres_stage:3; @@ -793,7 +798,7 @@ struct ndpi_packet_struct { u_int8_t tcp_retransmission; u_int8_t l4_protocol; - u_int8_t ssl_certificate_detected:4, ssl_certificate_num_checks:4; + u_int8_t tls_certificate_detected:4, tls_certificate_num_checks:4; u_int8_t packet_lines_parsed_complete:1, packet_direction:1, empty_line_position_set:1, pad:5; }; -- cgit v1.2.3 From 00e639d51301ccbaa2c14a47e829bdfe1831e226 Mon Sep 17 00:00:00 2001 From: Luca Deri Date: Sat, 14 Sep 2019 15:00:52 +0200 Subject: TLS certificate hash is not reported --- example/ndpiReader.c | 17 +++++++++++++++++ example/reader_util.c | 2 ++ example/reader_util.h | 5 +++-- src/include/ndpi_typedefs.h | 1 + src/lib/ndpi_main.c | 4 ++++ src/lib/protocols/tls.c | 13 ++++++++----- 6 files changed, 35 insertions(+), 7 deletions(-) (limited to 'src/include/ndpi_typedefs.h') diff --git a/example/ndpiReader.c b/example/ndpiReader.c index 2dde10182..782e62fb8 100644 --- a/example/ndpiReader.c +++ b/example/ndpiReader.c @@ -1024,6 +1024,8 @@ static void printFlow(u_int16_t id, struct ndpi_flow_info *flow, u_int16_t threa return; if(!json_flag) { + u_int i; + fprintf(out, "\t%u", id); fprintf(out, "\t%s ", ipProto2Name(flow->protocol)); @@ -1101,6 +1103,7 @@ static void printFlow(u_int16_t id, struct ndpi_flow_info *flow, u_int16_t threa if(flow->ssh_tls.ja3_client[0] != '\0') fprintf(out, "[JA3C: %s%s]", flow->ssh_tls.ja3_client, print_cipher(flow->ssh_tls.client_unsafe_cipher)); + if(flow->ssh_tls.server_info[0] != '\0') fprintf(out, "[Server: %s]", flow->ssh_tls.server_info); if(flow->ssh_tls.server_hassh[0] != '\0') fprintf(out, "[HASSH-S: %s]", flow->ssh_tls.server_hassh); @@ -1108,6 +1111,20 @@ static void printFlow(u_int16_t id, struct ndpi_flow_info *flow, u_int16_t threa print_cipher(flow->ssh_tls.server_unsafe_cipher)); if(flow->ssh_tls.server_organization[0] != '\0') fprintf(out, "[Organization: %s]", flow->ssh_tls.server_organization); + if(flow->detected_protocol.master_protocol == NDPI_PROTOCOL_TLS) { + if((flow->ssh_tls.sha1_cert_fingerprint[0] == 0) + && (flow->ssh_tls.sha1_cert_fingerprint[1] == 0) + && (flow->ssh_tls.sha1_cert_fingerprint[2] == 0)) + ; /* Looks empty */ + else { + fprintf(out, "[Certificate SHA-1: "); + for(i=0; i<20; i++) + fprintf(out, "%s%02X", (i > 0) ? ":" : "", + flow->ssh_tls.sha1_cert_fingerprint[i] & 0xFF); + fprintf(out, "]"); + } + } + if(flow->ssh_tls.notBefore && flow->ssh_tls.notAfter) { char notBefore[32], notAfter[32]; struct tm a, b; diff --git a/example/reader_util.c b/example/reader_util.c index 9ec50486c..2564f4ffd 100644 --- a/example/reader_util.c +++ b/example/reader_util.c @@ -985,6 +985,8 @@ void process_ndpi_collected_info(struct ndpi_workflow * workflow, struct ndpi_fl flow->ndpi_flow->protos.stun_ssl.ssl.ja3_server); flow->ssh_tls.server_unsafe_cipher = flow->ndpi_flow->protos.stun_ssl.ssl.server_unsafe_cipher; flow->ssh_tls.server_cipher = flow->ndpi_flow->protos.stun_ssl.ssl.server_cipher; + memcpy(flow->ssh_tls.sha1_cert_fingerprint, + flow->ndpi_flow->l4.tcp.tls_sha1_certificate_fingerprint, 20); } } diff --git a/example/reader_util.h b/example/reader_util.h index 95eac67e8..0a847e3de 100644 --- a/example/reader_util.h +++ b/example/reader_util.h @@ -161,10 +161,11 @@ typedef struct ndpi_flow_info { char client_info[64], server_info[64], client_hassh[33], server_hassh[33], server_organization[64], - ja3_client[33], ja3_server[33]; + ja3_client[33], ja3_server[33], + sha1_cert_fingerprint[20]; time_t notBefore, notAfter; u_int16_t server_cipher; - ndpi_cipher_weakness client_unsafe_cipher, server_unsafe_cipher; + ndpi_cipher_weakness client_unsafe_cipher, server_unsafe_cipher; } ssh_tls; void *src_id, *dst_id; diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h index 0f3aee9f2..cb790ad40 100644 --- a/src/include/ndpi_typedefs.h +++ b/src/include/ndpi_typedefs.h @@ -612,6 +612,7 @@ struct ndpi_flow_tcp_struct { tls_srv_cert_fingerprint_processed:1, tls_stage:2, _pad:1; // 0 - 5 int16_t tls_record_offset, tls_fingerprint_len; /* Need to be signed */ + u_int8_t tls_sha1_certificate_fingerprint[20]; /* NDPI_PROTOCOL_POSTGRES */ u_int32_t postgres_stage:3; diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c index b485fe631..8eb9f2260 100644 --- a/src/lib/ndpi_main.c +++ b/src/lib/ndpi_main.c @@ -6119,6 +6119,10 @@ void ndpi_free_flow(struct ndpi_flow_struct *flow) { if(flow) { if(flow->http.url) ndpi_free(flow->http.url); if(flow->http.content_type) ndpi_free(flow->http.content_type); + + if(flow->l4.tcp.tls_srv_cert_fingerprint_ctx) + ndpi_free(flow->l4.tcp.tls_srv_cert_fingerprint_ctx); + ndpi_free(flow); } } diff --git a/src/lib/protocols/tls.c b/src/lib/protocols/tls.c index a6d510160..f5957b1ba 100644 --- a/src/lib/protocols/tls.c +++ b/src/lib/protocols/tls.c @@ -710,7 +710,6 @@ int getSSCertificateFingerprint(struct ndpi_detection_module_struct *ndpi_struct return(0); /* We're good */ if(flow->l4.tcp.tls_fingerprint_len > 0) { - unsigned char sha1[20]; unsigned int i, avail = packet->payload_packet_len - flow->l4.tcp.tls_record_offset; if(avail > flow->l4.tcp.tls_fingerprint_len) @@ -738,12 +737,12 @@ int getSSCertificateFingerprint(struct ndpi_detection_module_struct *ndpi_struct flow->l4.tcp.tls_fingerprint_len -= avail; if(flow->l4.tcp.tls_fingerprint_len == 0) { - SHA1Final(sha1, flow->l4.tcp.tls_srv_cert_fingerprint_ctx); + SHA1Final(flow->l4.tcp.tls_sha1_certificate_fingerprint, flow->l4.tcp.tls_srv_cert_fingerprint_ctx); #ifdef DEBUG_TLS printf("=>> [TLS] SHA-1: "); for(i=0;i<20;i++) - printf("%s%02X", (i > 0) ? ":" : "", sha1[i]); + printf("%s%02X", (i > 0) ? ":" : "", flow->l4.tcp.tls_sha1_certificate_fingerprint[i]); printf("\n"); #endif @@ -772,8 +771,12 @@ int getSSCertificateFingerprint(struct ndpi_detection_module_struct *ndpi_struct #ifdef DEBUG_TLS printf("=>> [TLS] Certificate found\n"); #endif - flow->l4.tcp.tls_srv_cert_fingerprint_ctx = (void*)ndpi_malloc(sizeof(SHA1_CTX)); - + + if(flow->l4.tcp.tls_srv_cert_fingerprint_ctx == NULL) + flow->l4.tcp.tls_srv_cert_fingerprint_ctx = (void*)ndpi_malloc(sizeof(SHA1_CTX)); + else + printf("[TLS] Internal error: double allocation\n:"); + if(flow->l4.tcp.tls_srv_cert_fingerprint_ctx) { SHA1Init(flow->l4.tcp.tls_srv_cert_fingerprint_ctx); flow->l4.tcp.tls_srv_cert_fingerprint_found = 1; -- cgit v1.2.3 From 2b0945b88dc30430e2e40bd422fffc92308147c0 Mon Sep 17 00:00:00 2001 From: Luca Deri Date: Sun, 15 Sep 2019 10:56:08 +0200 Subject: TLS disection improvements --- src/include/ndpi_typedefs.h | 2 +- src/lib/ndpi_main.c | 29 +++++++++++++---------------- src/lib/protocols/tls.c | 41 +++++++++++++++++++++++++++++------------ 3 files changed, 43 insertions(+), 29 deletions(-) (limited to 'src/include/ndpi_typedefs.h') diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h index cb790ad40..1f14cb2ad 100644 --- a/src/include/ndpi_typedefs.h +++ b/src/include/ndpi_typedefs.h @@ -1116,7 +1116,7 @@ struct ndpi_flow_struct { /* init parameter, internal used to set up timestamp,... */ u_int16_t guessed_protocol_id, guessed_host_protocol_id, guessed_category, guessed_header_category; - u_int8_t protocol_id_already_guessed:1, host_already_guessed:1, init_finished:1, setup_packet_direction:1, packet_direction:1, check_extra_packets:1; + u_int8_t l4_proto, protocol_id_already_guessed:1, host_already_guessed:1, init_finished:1, setup_packet_direction:1, packet_direction:1, check_extra_packets:1; /* if ndpi_struct->direction_detect_disable == 1 diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c index 8eb9f2260..d456cdada 100644 --- a/src/lib/ndpi_main.c +++ b/src/lib/ndpi_main.c @@ -3532,8 +3532,7 @@ void ndpi_apply_flow_protocol_to_packet(struct ndpi_flow_struct *flow, static int ndpi_init_packet_header(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, - unsigned short packetlen) -{ + unsigned short packetlen) { const struct ndpi_iphdr *decaps_iph = NULL; u_int16_t l3len; u_int16_t l4len; @@ -3541,17 +3540,15 @@ static int ndpi_init_packet_header(struct ndpi_detection_module_struct *ndpi_str u_int8_t l4protocol; u_int8_t l4_result; - if (!flow) { - return 1; - } + if (!flow) + return 1; /* reset payload_packet_len, will be set if ipv4 tcp or udp */ flow->packet.payload_packet_len = 0; flow->packet.l4_packet_len = 0; flow->packet.l3_packet_len = packetlen; - flow->packet.tcp = NULL; - flow->packet.udp = NULL; + flow->packet.tcp = NULL, flow->packet.udp = NULL; flow->packet.generic_l4_ptr = NULL; #ifdef NDPI_DETECTION_SUPPORT_IPV6 flow->packet.iphv6 = NULL; @@ -3587,14 +3584,12 @@ static int ndpi_init_packet_header(struct ndpi_detection_module_struct *ndpi_str return 1; } - /* needed: * - unfragmented packets * - ip header <= packet len * - ip total length >= packet len */ - l4ptr = NULL; l4len = 0; l4protocol = 0; @@ -3608,12 +3603,12 @@ static int ndpi_init_packet_header(struct ndpi_detection_module_struct *ndpi_str flow->packet.l4_protocol = l4protocol; flow->packet.l4_packet_len = l4len; - + flow->l4_proto = l4protocol; + /* tcp / udp detection */ if(l4protocol == IPPROTO_TCP && flow->packet.l4_packet_len >= 20 /* min size of tcp */ ) { /* tcp */ flow->packet.tcp = (struct ndpi_tcphdr *) l4ptr; - if(flow->packet.l4_packet_len >=flow->packet.tcp->doff * 4) { flow->packet.payload_packet_len = flow->packet.l4_packet_len -flow->packet.tcp->doff * 4; @@ -3863,6 +3858,7 @@ void check_ndpi_udp_flow_func(struct ndpi_detection_module_struct *ndpi_struct, && NDPI_BITMASK_COMPARE(ndpi_struct->callback_buffer_udp[a].detection_bitmask, detection_bitmask) != 0) { ndpi_struct->callback_buffer_udp[a].func(ndpi_struct, flow); + // NDPI_LOG_DBG(ndpi_struct, "[UDP,CALL] dissector of protocol as callback_buffer idx = %d\n",a); if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN) break; /* Stop after detecting the first protocol */ @@ -6120,9 +6116,11 @@ void ndpi_free_flow(struct ndpi_flow_struct *flow) { if(flow->http.url) ndpi_free(flow->http.url); if(flow->http.content_type) ndpi_free(flow->http.content_type); - if(flow->l4.tcp.tls_srv_cert_fingerprint_ctx) - ndpi_free(flow->l4.tcp.tls_srv_cert_fingerprint_ctx); - + if(flow->l4_proto == IPPROTO_TCP) { + if(flow->l4.tcp.tls_srv_cert_fingerprint_ctx) + ndpi_free(flow->l4.tcp.tls_srv_cert_fingerprint_ctx); + } + ndpi_free(flow); } } @@ -6136,8 +6134,7 @@ char* ndpi_revision() { return(NDPI_GIT_RELEASE); } #ifdef WIN32 /* https://stackoverflow.com/questions/10905892/equivalent-of-gettimeday-for-windows */ -int gettimeofday(struct timeval * tp, struct timezone * tzp) -{ +int gettimeofday(struct timeval * tp, struct timezone * tzp) { // Note: some broken versions only have 8 trailing zero's, the correct epoch has 9 trailing zero's // This magic number is the number of 100 nanosecond intervals since January 1, 1601 (UTC) // until 00:00:00 January 1, 1970 diff --git a/src/lib/protocols/tls.c b/src/lib/protocols/tls.c index f5957b1ba..991b0be44 100644 --- a/src/lib/protocols/tls.c +++ b/src/lib/protocols/tls.c @@ -31,7 +31,7 @@ extern char *strptime(const char *s, const char *format, struct tm *tm); -/* #define DEBUG_TLS 1 */ +// #define DEBUG_TLS 1 #define DEBUG_FINGERPRINT 1 @@ -696,6 +696,9 @@ int getSSCertificateFingerprint(struct ndpi_detection_module_struct *ndpi_struct struct ndpi_packet_struct *packet = &flow->packet; u_int8_t multiple_messages; + if(flow->l4.tcp.tls_srv_cert_fingerprint_processed) + return(0); /* We're good */ + #ifdef DEBUG_TLS printf("=>> [TLS] %s() [tls_record_offset=%d][payload_packet_len=%u][direction: %u][%02X %02X %02X...]\n", __FUNCTION__, flow->l4.tcp.tls_record_offset, packet->payload_packet_len, @@ -710,7 +713,7 @@ int getSSCertificateFingerprint(struct ndpi_detection_module_struct *ndpi_struct return(0); /* We're good */ if(flow->l4.tcp.tls_fingerprint_len > 0) { - unsigned int i, avail = packet->payload_packet_len - flow->l4.tcp.tls_record_offset; + unsigned int avail = packet->payload_packet_len - flow->l4.tcp.tls_record_offset; if(avail > flow->l4.tcp.tls_fingerprint_len) avail = flow->l4.tcp.tls_fingerprint_len; @@ -740,10 +743,14 @@ int getSSCertificateFingerprint(struct ndpi_detection_module_struct *ndpi_struct SHA1Final(flow->l4.tcp.tls_sha1_certificate_fingerprint, flow->l4.tcp.tls_srv_cert_fingerprint_ctx); #ifdef DEBUG_TLS - printf("=>> [TLS] SHA-1: "); - for(i=0;i<20;i++) - printf("%s%02X", (i > 0) ? ":" : "", flow->l4.tcp.tls_sha1_certificate_fingerprint[i]); - printf("\n"); + { + int i; + + printf("=>> [TLS] SHA-1: "); + for(i=0;i<20;i++) + printf("%s%02X", (i > 0) ? ":" : "", flow->l4.tcp.tls_sha1_certificate_fingerprint[i]); + printf("\n"); + } #endif flow->l4.tcp.tls_srv_cert_fingerprint_processed = 1; @@ -800,13 +807,23 @@ int getSSCertificateFingerprint(struct ndpi_detection_module_struct *ndpi_struct printf("=>> [TLS] Found record %02X [len: %u]\n", packet->payload[flow->l4.tcp.tls_record_offset+5], len); #endif - - flow->l4.tcp.tls_record_offset += len + 9; - if(flow->l4.tcp.tls_record_offset < packet->payload_packet_len) - return(getSSCertificateFingerprint(ndpi_struct, flow)); - else { - flow->l4.tcp.tls_record_offset -= packet->payload_packet_len; + if(len > 4096) { + /* This looks an invalid len: we giveup */ + flow->l4.tcp.tls_record_offset = 0, flow->l4.tcp.tls_srv_cert_fingerprint_processed = 1; +#ifdef DEBUG_TLS + printf("=>> [TLS] Invalid fingerprint processing %u <-> %u\n", + ntohs(packet->tcp->source), ntohs(packet->tcp->dest)); +#endif + return(0); + } else { + flow->l4.tcp.tls_record_offset += len + 9; + + if(flow->l4.tcp.tls_record_offset < packet->payload_packet_len) + return(getSSCertificateFingerprint(ndpi_struct, flow)); + else { + flow->l4.tcp.tls_record_offset -= packet->payload_packet_len; + } } } -- cgit v1.2.3