diff options
Diffstat (limited to 'src/lib/protocols/ssl.c')
-rw-r--r-- | src/lib/protocols/ssl.c | 65 |
1 files changed, 46 insertions, 19 deletions
diff --git a/src/lib/protocols/ssl.c b/src/lib/protocols/ssl.c index 4e53d22fb..20721142a 100644 --- a/src/lib/protocols/ssl.c +++ b/src/lib/protocols/ssl.c @@ -341,15 +341,15 @@ static void stripCertificateTrailer(char *buffer, int buffer_len) { /* https://engineering.salesforce.com/tls-fingerprinting-with-ja3-and-ja3s-247362855967 */ -#define JA3_STR_LEN 256 -#define MAX_NUM_JA3 24 +#define JA3_STR_LEN 512 +#define MAX_NUM_JA3 128 struct ja3_info { u_int16_t ssl_version; u_int16_t num_cipher, cipher[MAX_NUM_JA3]; u_int16_t num_ssl_extension, ssl_extension[MAX_NUM_JA3]; u_int16_t num_elliptic_curve, elliptic_curve[MAX_NUM_JA3]; - u_int16_t num_elliptic_curve_point_format, elliptic_curve_point_format; + u_int8_t num_elliptic_curve_point_format, elliptic_curve_point_format[MAX_NUM_JA3]; }; /* code fixes courtesy of Alexsandro Brahm <alex@digistar.com.br> */ @@ -373,8 +373,6 @@ int getSSLcertificate(struct ndpi_detection_module_struct *ndpi_struct, } #endif - ja3.ssl_version = ssl_version; - /* Nothing matched so far: let's decode the certificate with some heuristics Patches courtesy of Denys Fedoryshchenko <nuclearcat@nuclearcat.com> @@ -400,6 +398,9 @@ int getSSLcertificate(struct ndpi_detection_module_struct *ndpi_struct, if((handshake_protocol == 0x02) || (handshake_protocol == 0xb) /* Server Hello and Certificate message types are interesting for us */) { u_int num_found = 0; + u_int16_t ssl_version = ntohs(*((u_int16_t*)&packet->payload[9])); + + ja3.ssl_version = ssl_version; if(handshake_protocol == 0x02) { u_int16_t offset = 43, extension_len; @@ -506,6 +507,10 @@ int getSSLcertificate(struct ndpi_detection_module_struct *ndpi_struct, sizeof(flow->protos.stun_ssl.ssl.server_certificate), "%s", buffer); } +#ifdef CERTIFICATE_DEBUG + printf("[JA3] Server: %s \n", ja3_str); +#endif + MD5Init(&ctx); MD5Update(&ctx, (const unsigned char *)ja3_str, strlen(ja3_str)); MD5Final(md5_hash, &ctx); @@ -528,7 +533,10 @@ int getSSLcertificate(struct ndpi_detection_module_struct *ndpi_struct, if(base_offset + 2 <= packet->payload_packet_len) { u_int16_t session_id_len = packet->payload[base_offset]; - + u_int16_t ssl_version = ntohs(*((u_int16_t*)&packet->payload[9])); + + ja3.ssl_version = ssl_version; + if((session_id_len+base_offset+2) <= total_len) { u_int16_t cypher_len = packet->payload[session_id_len+base_offset+2] + (packet->payload[session_id_len+base_offset+1] << 8); u_int16_t i, cypher_offset = base_offset + session_id_len + 3; @@ -537,17 +545,17 @@ int getSSLcertificate(struct ndpi_detection_module_struct *ndpi_struct, printf("SSL [client cypher_len: %u]\n", cypher_len); #endif - for(i=0; i<cypher_len; i++) { + for(i=0; i<cypher_len;) { u_int16_t *id = (u_int16_t*)&packet->payload[cypher_offset+i]; #ifdef CERTIFICATE_DEBUG - printf("SSL [cypher suite: %u]\n", ntohs(*id)); + printf("SSL [cypher suite: %u] [%u/%u]\n", ntohs(*id), i, cypher_len); #endif if(ja3.num_cipher < MAX_NUM_JA3) ja3.cipher[ja3.num_cipher++] = ntohs(*id); - - i++; + + i += 2; } offset = base_offset + session_id_len + cypher_len + 2; @@ -616,7 +624,11 @@ int getSSLcertificate(struct ndpi_detection_module_struct *ndpi_struct, } else if(extension_id == 10 /* supported groups */) { u_int16_t i, s_offset = offset+extension_offset + 2; - for(i=0; i<extension_len; i++) { +#ifdef CERTIFICATE_DEBUG + printf("SSL [EllipticCurve: len=%u]\n", extension_len); +#endif + + for(i=0; i<extension_len-2;) { u_int16_t s_group = ntohs(*((u_int16_t*)&packet->payload[s_offset+i])); #ifdef CERTIFICATE_DEBUG @@ -626,22 +638,33 @@ int getSSLcertificate(struct ndpi_detection_module_struct *ndpi_struct, if(ja3.num_elliptic_curve < MAX_NUM_JA3) ja3.elliptic_curve[ja3.num_elliptic_curve++] = s_group; - i++; + i += 2; } } else if(extension_id == 11 /* ec_point_formats groups */) { + u_int16_t i, s_offset = offset+extension_offset + 1; + #ifdef CERTIFICATE_DEBUG - printf("SSL [EllipticCurveFormat: %u]\n", packet->payload[offset+extension_offset+1]); + printf("SSL [EllipticCurveFormat: len=%u]\n", extension_len); #endif - ja3.elliptic_curve_point_format = packet->payload[offset+extension_offset+1], - ja3.num_elliptic_curve_point_format = 1; + + for(i=0; i<extension_len-1;i++) { + u_int8_t s_group = packet->payload[s_offset+i]; + +#ifdef CERTIFICATE_DEBUG + printf("SSL [EllipticCurveFormat: %u]\n", s_group); +#endif + + if(ja3.num_elliptic_curve_point_format < MAX_NUM_JA3) + ja3.elliptic_curve_point_format[ja3.num_elliptic_curve_point_format++] = s_group; + } } extension_offset += extension_len; #ifdef CERTIFICATE_DEBUG - // printf("SSL [extension_offset/len: %u/%u]\n", extension_offset, extension_len); + printf("SSL [extension_offset/len: %u/%u]\n", extension_offset, extension_len); #endif - } + } /* while */ ja3_str_len = snprintf(ja3_str, sizeof(ja3_str), "%u,", ja3.ssl_version); @@ -663,9 +686,13 @@ int getSSLcertificate(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.elliptic_curve[i]); ja3_str_len += snprintf(&ja3_str[ja3_str_len], sizeof(ja3_str)-ja3_str_len, ","); + + for(i=0; i<ja3.num_elliptic_curve_point_format; i++) + ja3_str_len += snprintf(&ja3_str[ja3_str_len], sizeof(ja3_str)-ja3_str_len, "%s%u", (i > 0) ? "-" : "", ja3.elliptic_curve_point_format[i]); - if(ja3.num_elliptic_curve_point_format) - ja3_str_len += snprintf(&ja3_str[ja3_str_len], sizeof(ja3_str)-ja3_str_len, "%u", ja3.elliptic_curve_point_format); +#ifdef CERTIFICATE_DEBUG + printf("[JA3] Client: %s \n", ja3_str); +#endif MD5Init(&ctx); MD5Update(&ctx, (const unsigned char *)ja3_str, strlen(ja3_str)); |