diff options
author | Ravi Kerur <ravi.kerur@viasat.com> | 2019-09-20 10:54:58 -0700 |
---|---|---|
committer | Ravi Kerur <ravi.kerur@viasat.com> | 2019-09-20 10:54:58 -0700 |
commit | e2e05cd499d9f3c71dbe3ef15a59d3ad1befdd84 (patch) | |
tree | 9db7de3d0891cc421a80634bb643458d5e34e57c /src/lib/protocols | |
parent | 7e3fd16b0d3945ef6ba2f58c23f54639ea71538c (diff) | |
parent | bdcc6dc173c52d17a1d4b5b7f16e7e4454a91044 (diff) |
Merge branch 'dev' of https://github.com/ntop/nDPI into ndpi_icmp
Diffstat (limited to 'src/lib/protocols')
-rw-r--r-- | src/lib/protocols/line.c | 32 | ||||
-rw-r--r-- | src/lib/protocols/stun.c | 172 | ||||
-rw-r--r-- | src/lib/protocols/tls.c | 63 |
3 files changed, 135 insertions, 132 deletions
diff --git a/src/lib/protocols/line.c b/src/lib/protocols/line.c index 0e624ab7d..b6e676c55 100644 --- a/src/lib/protocols/line.c +++ b/src/lib/protocols/line.c @@ -36,31 +36,35 @@ void ndpi_search_line(struct ndpi_detection_module_struct *ndpi_struct, struct n NDPI_LOG_DBG(ndpi_struct, "search line\n"); - if(packet->iph) { + if (packet->iph) { /* 125.209.252.xxx */ - if(((ntohl(packet->iph->saddr) & 0xFFFFFF00 /* 255.255.255.0 */) == 0x7DD1FC00) - || ((ntohl(packet->iph->daddr) & 0xFFFFFF00 /* 255.255.255.0 */) == 0x7DD1FC00)) { - if((packet->payload_packet_len == 110) - && (flow->packet.payload[0] == 0xB6) && (flow->packet.payload[1] == 0x18) - && (flow->packet.payload[2] == 0x00) && (flow->packet.payload[3] == 0x6A)) { - ndpi_line_report_protocol(ndpi_struct, flow); - return; + if (((ntohl(packet->iph->saddr) & 0xFFFFFF00 /* 255.255.255.0 */) == 0x7DD1FC00) || + ((ntohl(packet->iph->daddr) & 0xFFFFFF00 /* 255.255.255.0 */) == 0x7DD1FC00)) { + if ((packet->payload_packet_len == 110) && (flow->packet.payload[0] == 0xB6) && + (flow->packet.payload[1] == 0x18) && (flow->packet.payload[2] == 0x00) && + (flow->packet.payload[3] == 0x6A)) { + ndpi_line_report_protocol(ndpi_struct, flow); + return; } } } + if ((packet->payload_packet_len == 46 && ntohl(get_u_int32_t(packet->payload, 0)) == 0xb6130006) || + (packet->payload_packet_len == 8 && ntohl(get_u_int32_t(packet->payload, 0)) == 0xb6070004) || + (packet->payload_packet_len == 16 && ntohl(get_u_int32_t(packet->payload, 0)) == 0xb609000c)) { + ndpi_line_report_protocol(ndpi_struct, flow); + return; + } + NDPI_EXCLUDE_PROTO(ndpi_struct, flow); } void init_line_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { - ndpi_set_bitmask_protocol_detection("Line", ndpi_struct, detection_bitmask, *id, - NDPI_PROTOCOL_LINE, - ndpi_search_line, - NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); + ndpi_set_bitmask_protocol_detection("Line", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_LINE, + ndpi_search_line, NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; } diff --git a/src/lib/protocols/stun.c b/src/lib/protocols/stun.c index 76a75fb8d..77ddf6ca0 100644 --- a/src/lib/protocols/stun.c +++ b/src/lib/protocols/stun.c @@ -41,6 +41,23 @@ struct stun_packet_header { /* ************************************************************ */ +static u_int8_t is_stun_based_proto(u_int16_t proto) { + + switch(proto) { + case NDPI_PROTOCOL_WHATSAPP_CALL: + case NDPI_PROTOCOL_MESSENGER: + case NDPI_PROTOCOL_HANGOUT_DUO: + case NDPI_PROTOCOL_SKYPE_CALL: + case NDPI_PROTOCOL_SIGNAL: + case NDPI_PROTOCOL_STUN: + return(1); + } + + return(0); +} + +/* ************************************************************ */ + u_int32_t get_stun_lru_key(struct ndpi_flow_struct *flow, u_int8_t rev) { if(rev) return(flow->packet.iph->daddr + flow->packet.udp->dest); @@ -52,7 +69,7 @@ u_int32_t get_stun_lru_key(struct ndpi_flow_struct *flow, u_int8_t rev) { void ndpi_int_stun_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, - u_int app_proto, u_int proto) { + u_int proto, u_int app_proto) { if(ndpi_struct->stun_cache == NULL) ndpi_struct->stun_cache = ndpi_lru_cache_init(1024); @@ -71,24 +88,25 @@ void ndpi_int_stun_add_connection(struct ndpi_detection_module_struct *ndpi_stru #endif app_proto = cached_proto, proto = NDPI_PROTOCOL_STUN; } else { - u_int32_t key1 = get_stun_lru_key(flow, 1); + u_int32_t key_rev = get_stun_lru_key(flow, 1); - if(ndpi_lru_find_cache(ndpi_struct->stun_cache, key1, + if(ndpi_lru_find_cache(ndpi_struct->stun_cache, key_rev, &cached_proto, 0 /* Don't remove it as it can be used for other connections */)) { #ifdef DEBUG_LRU - printf("[LRU] FOUND %u / %u: no need to cache %u.%u\n", key1, cached_proto, proto, app_proto); + printf("[LRU] FOUND %u / %u: no need to cache %u.%u\n", key_rev, cached_proto, proto, app_proto); #endif app_proto = cached_proto, proto = NDPI_PROTOCOL_STUN; } else { if(app_proto != NDPI_PROTOCOL_STUN) { /* No sense to ass STUN, but only subprotocols */ - + #ifdef DEBUG_LRU printf("[LRU] ADDING %u / %u.%u [%u -> %u]\n", key, proto, app_proto, ntohs(flow->packet.udp->source), ntohs(flow->packet.udp->dest)); #endif - + ndpi_lru_add_to_cache(ndpi_struct->stun_cache, key, app_proto); + ndpi_lru_add_to_cache(ndpi_struct->stun_cache, key_rev, app_proto); } } } @@ -140,11 +158,7 @@ static int is_messenger_ip_address(u_int32_t host) { static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, const u_int8_t * payload, - const u_int16_t payload_length, - u_int8_t *is_whatsapp, - u_int8_t *is_messenger, - u_int8_t *is_duo - ) { + const u_int16_t payload_length) { u_int16_t msg_type, msg_len; struct stun_packet_header *h = (struct stun_packet_header*)payload; u_int8_t can_this_be_whatsapp_voice = 1; @@ -152,15 +166,13 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct * /* STUN over TCP does not look good */ if(flow->packet.tcp) return(NDPI_IS_NOT_STUN); - *is_whatsapp = 0, *is_messenger = 0, *is_duo = 0; - if(payload_length >= 512) { return(NDPI_IS_NOT_STUN); } else if(payload_length < sizeof(struct stun_packet_header)) { /* This looks like an invalid packet */ if(flow->protos.stun_ssl.stun.num_udp_pkts > 0) { - *is_whatsapp = 1; + flow->guessed_host_protocol_id = NDPI_PROTOCOL_WHATSAPP_CALL; return(NDPI_IS_STUN); /* This is WhatsApp Voice */ } else return(NDPI_IS_NOT_STUN); @@ -179,6 +191,19 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct * #ifdef DEBUG_STUN printf("[STUN] msg_type = %04X\n", msg_type); #endif + + if(is_stun_based_proto(flow->guessed_host_protocol_id)) { + /* + In this case we have the detected the typical STUN pattern + of modern protocols where the flow starts as STUN and becomes + something else that has nothing to do with STUN anymore + */ + ndpi_int_stun_add_connection(ndpi_struct, flow, + flow->guessed_protocol_id, + flow->guessed_host_protocol_id); + return(NDPI_IS_STUN); + } + return(NDPI_IS_NOT_STUN); } @@ -214,21 +239,6 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct * flow->guessed_host_protocol_id = proto, flow->guessed_protocol_id = NDPI_PROTOCOL_STUN; - switch(proto) { - case NDPI_PROTOCOL_WHATSAPP: - *is_whatsapp = 1; - break; - case NDPI_PROTOCOL_MESSENGER: - *is_messenger = 1; - break; - case NDPI_PROTOCOL_HANGOUT_DUO: - *is_duo = 1; - break; - case NDPI_PROTOCOL_SKYPE_CALL: - flow->protos.stun_ssl.stun.is_skype = 1; - break; - } - return(NDPI_IS_STUN); } else { #ifdef DEBUG_LRU @@ -247,10 +257,10 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct * if((msg_len == 0) && (flow->guessed_host_protocol_id == NDPI_PROTOCOL_GOOGLE)) flow->guessed_host_protocol_id = NDPI_PROTOCOL_HANGOUT_DUO; else - flow->guessed_host_protocol_id = NDPI_PROTOCOL_STUN; + flow->guessed_protocol_id = NDPI_PROTOCOL_STUN; if(msg_len == 0) { - flow->protos.stun_ssl.stun.num_udp_pkts++; + /* flow->protos.stun_ssl.stun.num_udp_pkts++; */ return(NDPI_IS_NOT_STUN); /* This to keep analyzing STUN instead of giving up */ } } @@ -270,12 +280,12 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct * if(((payload[0] == 0x80) && (payload_length < 512) && ((msg_len+20) <= payload_length)) /* WhatsApp Voice */) { - *is_whatsapp = 1; + flow->guessed_host_protocol_id = NDPI_PROTOCOL_WHATSAPP_CALL; return(NDPI_IS_STUN); /* This is WhatsApp Voice */ } else if((payload[0] == 0x90) && (((msg_len+11) == payload_length) /* WhatsApp Video */ || (flow->protos.stun_ssl.stun.num_binding_requests >= 4))) { - *is_whatsapp = 2; + flow->guessed_host_protocol_id = NDPI_PROTOCOL_WHATSAPP_CALL; return(NDPI_IS_STUN); /* This is WhatsApp Video */ } @@ -285,7 +295,7 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct * switch(flow->guessed_protocol_id) { case NDPI_PROTOCOL_HANGOUT_DUO: case NDPI_PROTOCOL_MESSENGER: - case NDPI_PROTOCOL_WHATSAPP_VOICE: + case NDPI_PROTOCOL_WHATSAPP_CALL: /* Don't overwrite the protocol with sub-STUN protocols */ break; @@ -323,8 +333,8 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct * #endif switch(attribute) { - case 0x0008: /* Message Integrity */ - case 0x0020: /* XOR-MAPPED-ADDRESSES */ + // case 0x0008: /* Message Integrity */ + // case 0x0020: /* XOR-MAPPED-ADDRESSES */ case 0x4000: case 0x4001: case 0x4002: @@ -349,7 +359,6 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct * #endif if(strstr((char*)flow->host_server_name, "google.com") != NULL) { - *is_duo = 1; flow->guessed_host_protocol_id = NDPI_PROTOCOL_HANGOUT_DUO, flow->guessed_protocol_id = NDPI_PROTOCOL_STUN; return(NDPI_IS_STUN); } else if(strstr((char*)flow->host_server_name, "whispersystems.org") != NULL) { @@ -363,12 +372,10 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct * case 0xC057: /* Messeger */ if(msg_type == 0x0001) { if((msg_len == 100) || (msg_len == 104)) { - *is_messenger = 1; + flow->guessed_host_protocol_id = NDPI_PROTOCOL_MESSENGER, flow->guessed_protocol_id = NDPI_PROTOCOL_STUN; return(NDPI_IS_STUN); } else if(msg_len == 76) { #if 0 - *is_duo = 1; - if(1) { flow->guessed_host_protocol_id = NDPI_PROTOCOL_HANGOUT_DUO, flow->guessed_protocol_id = NDPI_PROTOCOL_STUN; return(NDPI_IS_NOT_STUN); /* This case is found also with signal traffic */ @@ -390,7 +397,6 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct * printf("==> Skype found\n"); #endif flow->guessed_protocol_id = NDPI_PROTOCOL_SKYPE_CALL; - flow->protos.stun_ssl.stun.is_skype = 1; return(NDPI_IS_STUN); } break; @@ -411,7 +417,6 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct * #endif flow->guessed_protocol_id = NDPI_PROTOCOL_SKYPE_CALL; - flow->protos.stun_ssl.stun.is_skype = 1; return(NDPI_IS_STUN); break; @@ -424,7 +429,6 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct * && ((payload[offset+7] == 0x02) || (payload[offset+7] == 0x03)) ) { flow->guessed_protocol_id = NDPI_PROTOCOL_SKYPE_CALL; - flow->protos.stun_ssl.stun.is_skype = 1; #ifdef DEBUG_STUN printf("==> Skype (3) found\n"); #endif @@ -451,13 +455,13 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct * } goto udp_stun_found; } else if(msg_type == 0x0800) { - *is_whatsapp = 1; + flow->guessed_host_protocol_id = NDPI_PROTOCOL_WHATSAPP_CALL; return(NDPI_IS_STUN); /* This is WhatsApp */ } } if((flow->protos.stun_ssl.stun.num_udp_pkts > 0) && (msg_type <= 0x00FF)) { - *is_whatsapp = 1; + flow->guessed_host_protocol_id = NDPI_PROTOCOL_WHATSAPP_CALL; return(NDPI_IS_STUN); /* This is WhatsApp Voice */ } else return(NDPI_IS_NOT_STUN); @@ -466,23 +470,25 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct * if(can_this_be_whatsapp_voice) { struct ndpi_packet_struct *packet = &flow->packet; int rc; - + flow->protos.stun_ssl.stun.num_processed_pkts++; #ifdef DEBUG_STUN - printf("==>> NDPI_PROTOCOL_WHATSAPP_VOICE\n"); + printf("==>> NDPI_PROTOCOL_WHATSAPP_CALL\n"); #endif if((ntohs(packet->udp->source) == 3478) || (ntohs(packet->udp->dest) == 3478)) { flow->guessed_host_protocol_id = (is_messenger_ip_address(ntohl(packet->iph->saddr)) || is_messenger_ip_address(ntohl(packet->iph->daddr))) ? - NDPI_PROTOCOL_MESSENGER : NDPI_PROTOCOL_WHATSAPP_VOICE; + NDPI_PROTOCOL_MESSENGER : NDPI_PROTOCOL_WHATSAPP_CALL; } else flow->guessed_host_protocol_id = (is_google_ip_address(ntohl(packet->iph->saddr)) || is_google_ip_address(ntohl(packet->iph->daddr))) - ? NDPI_PROTOCOL_HANGOUT_DUO : NDPI_PROTOCOL_WHATSAPP_VOICE; + ? NDPI_PROTOCOL_HANGOUT_DUO : NDPI_PROTOCOL_WHATSAPP_CALL; rc = (flow->protos.stun_ssl.stun.num_udp_pkts < MAX_NUM_STUN_PKTS) ? NDPI_IS_NOT_STUN : NDPI_IS_STUN; if(rc == NDPI_IS_STUN) - ndpi_int_stun_add_connection(ndpi_struct, flow, flow->guessed_host_protocol_id, NDPI_IS_STUN); + ndpi_int_stun_add_connection(ndpi_struct, flow, + NDPI_IS_STUN, + flow->guessed_host_protocol_id); return(rc); } else { @@ -498,7 +504,6 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct * void ndpi_search_stun(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; - u_int8_t is_whatsapp = 0, is_messenger = 0, is_duo = 0; NDPI_LOG_DBG(ndpi_struct, "search stun\n"); @@ -517,64 +522,27 @@ void ndpi_search_stun(struct ndpi_detection_module_struct *ndpi_struct, struct n * improved by checking only the STUN packet of given length */ if(ndpi_int_check_stun(ndpi_struct, flow, packet->payload + 2, - packet->payload_packet_len - 2, - &is_whatsapp, &is_messenger, &is_duo) == NDPI_IS_STUN) { - if(flow->guessed_protocol_id == NDPI_PROTOCOL_UNKNOWN) flow->guessed_protocol_id = NDPI_PROTOCOL_STUN; - - if(is_messenger) { - ndpi_int_stun_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_MESSENGER, NDPI_PROTOCOL_STUN); - return; - } else if(is_duo) { - ndpi_int_stun_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HANGOUT_DUO, NDPI_PROTOCOL_STUN); - return; - } else if(flow->guessed_host_protocol_id == NDPI_PROTOCOL_SIGNAL) { - ndpi_int_stun_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SIGNAL, NDPI_PROTOCOL_STUN); - return; - } else if(flow->protos.stun_ssl.stun.is_skype || (flow->guessed_host_protocol_id = NDPI_PROTOCOL_SKYPE_CALL)) { - NDPI_LOG_INFO(ndpi_struct, "found Skype\n"); - - // if((flow->protos.stun_ssl.stun.num_processed_pkts >= 8) || (flow->protos.stun_ssl.stun.num_binding_requests >= 4)) - ndpi_int_stun_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SKYPE_CALL, NDPI_PROTOCOL_SKYPE); - } else { - NDPI_LOG_INFO(ndpi_struct, "found UDP stun\n"); /* Ummmmm we're in the TCP branch. This code looks bad */ - ndpi_int_stun_add_connection(ndpi_struct, flow, - is_whatsapp ? (is_whatsapp == 1 ? NDPI_PROTOCOL_WHATSAPP_VOICE : NDPI_PROTOCOL_WHATSAPP_VIDEO) : NDPI_PROTOCOL_STUN, - NDPI_PROTOCOL_UNKNOWN); - } - - return; + packet->payload_packet_len - 2) == NDPI_IS_STUN) { + goto udp_stun_match; } } } /* UDP */ if(ndpi_int_check_stun(ndpi_struct, flow, packet->payload, - packet->payload_packet_len, - &is_whatsapp, &is_messenger, &is_duo) == NDPI_IS_STUN) { - if(flow->guessed_protocol_id == NDPI_PROTOCOL_UNKNOWN) flow->guessed_protocol_id = NDPI_PROTOCOL_STUN; - - if(is_messenger) { - ndpi_int_stun_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_MESSENGER, NDPI_PROTOCOL_STUN); - return; - } else if(is_duo) { - ndpi_int_stun_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HANGOUT_DUO, NDPI_PROTOCOL_STUN); - return; - } else if(flow->guessed_host_protocol_id == NDPI_PROTOCOL_SIGNAL) { - ndpi_int_stun_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SIGNAL, NDPI_PROTOCOL_STUN); - return; - } else if(flow->protos.stun_ssl.stun.is_skype) { - NDPI_LOG_INFO(ndpi_struct, "Found Skype\n"); - - /* flow->protos.stun_ssl.stun.num_binding_requests < 4) ? NDPI_PROTOCOL_SKYPE_CALL_IN : NDPI_PROTOCOL_SKYPE_CALL_OUT */ - // if((flow->protos.stun_ssl.stun.num_udp_pkts >= 6) || (flow->protos.stun_ssl.stun.num_binding_requests >= 3)) - ndpi_int_stun_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SKYPE_CALL, NDPI_PROTOCOL_SKYPE); - } else { - NDPI_LOG_INFO(ndpi_struct, "found UDP stun\n"); - ndpi_int_stun_add_connection(ndpi_struct, flow, - is_whatsapp ? (is_whatsapp == 1 ? NDPI_PROTOCOL_WHATSAPP_VOICE : NDPI_PROTOCOL_WHATSAPP_VIDEO) - : NDPI_PROTOCOL_STUN, NDPI_PROTOCOL_UNKNOWN); - } + packet->payload_packet_len) == NDPI_IS_STUN) { + udp_stun_match: + if(flow->guessed_protocol_id == NDPI_PROTOCOL_UNKNOWN) + flow->guessed_protocol_id = NDPI_PROTOCOL_STUN; + if(flow->guessed_host_protocol_id == NDPI_PROTOCOL_UNKNOWN) { + flow->guessed_host_protocol_id = flow->guessed_protocol_id; + flow->guessed_protocol_id = NDPI_PROTOCOL_STUN; + } + + ndpi_int_stun_add_connection(ndpi_struct, flow, + flow->guessed_protocol_id, + flow->guessed_host_protocol_id); return; } diff --git a/src/lib/protocols/tls.c b/src/lib/protocols/tls.c index 8a4d0c3ac..f63da2067 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 @@ -176,7 +176,7 @@ static void stripCertificateTrailer(char *buffer, int buffer_len) { #define MAX_NUM_JA3 128 struct ja3_info { - u_int16_t tls_version; + u_int16_t tls_handshake_version; u_int16_t num_cipher, cipher[MAX_NUM_JA3]; u_int16_t num_tls_extension, tls_extension[MAX_NUM_JA3]; u_int16_t num_elliptic_curve, elliptic_curve[MAX_NUM_JA3]; @@ -263,7 +263,7 @@ int getTLScertificate(struct ndpi_detection_module_struct *ndpi_struct, else tls_version = ntohs(*((u_int16_t*)&packet->payload[header_len+12])); - ja3.tls_version = tls_version; + ja3.tls_handshake_version = tls_version; if(handshake_protocol == 0x02) { u_int16_t offset = base_offset, extension_len, j; @@ -291,36 +291,49 @@ int getTLScertificate(struct ndpi_detection_module_struct *ndpi_struct, flow->protos.stun_ssl.ssl.server_cipher = ja3.cipher[0]; #ifdef DEBUG_TLS - printf("SSL [server][session_id_len: %u][cipher: %04X]\n", session_id_len, ja3.cipher[0]); + printf("TLS [server][session_id_len: %u][cipher: %04X]\n", session_id_len, ja3.cipher[0]); #endif offset += 2 + 1; extension_len = ntohs(*((u_int16_t*)&packet->payload[offset])); #ifdef DEBUG_TLS - printf("SSL [server][extension_len: %u]\n", extension_len); + printf("TLS [server][extension_len: %u]\n", extension_len); #endif offset += 2; for(i=0; i<extension_len; ) { - u_int16_t id, len; + u_int16_t extension_id, extension_len; if(offset >= (packet->payload_packet_len+4)) break; - id = ntohs(*((u_int16_t*)&packet->payload[offset])); - len = ntohs(*((u_int16_t*)&packet->payload[offset+2])); + extension_id = ntohs(*((u_int16_t*)&packet->payload[offset])); + extension_len = ntohs(*((u_int16_t*)&packet->payload[offset+2])); if(ja3.num_tls_extension < MAX_NUM_JA3) - ja3.tls_extension[ja3.num_tls_extension++] = id; + ja3.tls_extension[ja3.num_tls_extension++] = extension_id; #ifdef DEBUG_TLS - printf("SSL [server][extension_id: %u/0x%04X]\n", id, id); + printf("TLS [server][extension_id: %u/0x%04X][len: %u]\n", + extension_id, extension_id, extension_len); #endif - i += 4 + len, offset += 4 + len; + if(extension_id == 43 /* supported versions */) { + if(extension_len >= 2) { + u_int16_t tls_version = ntohs(*((u_int16_t*)&packet->payload[offset+4])); + +#ifdef DEBUG_TLS + printf("TLS [server] [TLS version: 0x%04X]\n", tls_version); +#endif + + flow->protos.stun_ssl.ssl.ssl_version = tls_version; + } + } + + i += 4 + extension_len, offset += 4 + extension_len; } - ja3_str_len = snprintf(ja3_str, sizeof(ja3_str), "%u,", ja3.tls_version); + ja3_str_len = snprintf(ja3_str, sizeof(ja3_str), "%u,", ja3.tls_handshake_version); for(i=0; i<ja3.num_cipher; i++) ja3_str_len += snprintf(&ja3_str[ja3_str_len], sizeof(ja3_str)-ja3_str_len, "%s%u", (i > 0) ? "-" : "", ja3.cipher[i]); @@ -333,7 +346,7 @@ int getTLScertificate(struct ndpi_detection_module_struct *ndpi_struct, ja3_str_len += snprintf(&ja3_str[ja3_str_len], sizeof(ja3_str)-ja3_str_len, "%s%u", (i > 0) ? "-" : "", ja3.tls_extension[i]); #ifdef DEBUG_TLS - printf("SSL [server] %s\n", ja3_str); + printf("TLS [server] %s\n", ja3_str); #endif #ifdef DEBUG_TLS @@ -426,7 +439,7 @@ int getTLScertificate(struct ndpi_detection_module_struct *ndpi_struct, session_id_len = packet->payload[base_offset]; - ja3.tls_version = tls_version; + ja3.tls_handshake_version = tls_version; if((session_id_len+base_offset+2) <= total_len) { u_int16_t cipher_len, cipher_offset; @@ -533,7 +546,7 @@ int getTLScertificate(struct ndpi_detection_module_struct *ndpi_struct, #endif } } - + if(extension_id == 0 /* server name */) { u_int16_t len; @@ -611,6 +624,20 @@ int getTLScertificate(struct ndpi_detection_module_struct *ndpi_struct, printf("Client SSL Invalid len %u vs %u\n", s_offset+extension_len, total_len); #endif } + } else if(extension_id == 43 /* supported versions */) { + u_int8_t version_len = packet->payload[offset+4]; + + if(version_len == (extension_len-1)) { +#ifdef DEBUG_TLS + u_int8_t j; + + for(j=0; j<version_len; j += 2) { + u_int16_t tls_version = ntohs(*((u_int16_t*)&packet->payload[offset+5+j])); + + printf("Client SSL [TLS version: 0x%04X]\n", tls_version); + } +#endif + } } extension_offset += extension_len; @@ -621,7 +648,8 @@ int getTLScertificate(struct ndpi_detection_module_struct *ndpi_struct, } /* while */ if(!invalid_ja3) { - ja3_str_len = snprintf(ja3_str, sizeof(ja3_str), "%u,", ja3.tls_version); + compute_ja3c: + ja3_str_len = snprintf(ja3_str, sizeof(ja3_str), "%u,", ja3.tls_handshake_version); for(i=0; i<ja3.num_cipher; i++) { ja3_str_len += snprintf(&ja3_str[ja3_str_len], sizeof(ja3_str)-ja3_str_len, "%s%u", @@ -670,6 +698,9 @@ int getTLScertificate(struct ndpi_detection_module_struct *ndpi_struct, return(2 /* Client Certificate */); } + } else if(offset == total_len) { + /* SSL does not have extensions etc */ + goto compute_ja3c; } } } |