diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/SSl_ja3_fingerprint.cpp | 170 | ||||
| -rw-r--r-- | src/ssl.h | 27 |
2 files changed, 173 insertions, 24 deletions
diff --git a/src/SSl_ja3_fingerprint.cpp b/src/SSl_ja3_fingerprint.cpp index f5fdb84..cc6be0c 100644 --- a/src/SSl_ja3_fingerprint.cpp +++ b/src/SSl_ja3_fingerprint.cpp @@ -380,6 +380,12 @@ typedef struct bsb unsigned char *end; } BSB; +typedef struct _ssl_fingerprint +{ + struct _ssl_ja3_info_t *ja3_info; + struct _ssl_ja3s_info_t *ja3s_info; +}ssl_fingerprint_t; + static int ja3_md5sum(const char *str, int len, char *buf, int size) { @@ -597,16 +603,30 @@ static int ssl_generate_ja3_fingerprint(const unsigned char *data, int len, char static void free_ja3_fingerprint_label(int thread_seq, void *value) { - struct _ssl_ja3_info_t *ja3_info=(struct _ssl_ja3_info_t *)value; + ssl_fingerprint_t *fingerprint_info=(ssl_fingerprint_t *)value; if(value!=NULL) { - dictator_free(thread_seq, (void *)ja3_info->sni); - ja3_info->sni=NULL; + if (fingerprint_info->ja3_info != NULL) + { + dictator_free(thread_seq, (void *)fingerprint_info->ja3_info->sni); + fingerprint_info->ja3_info->sni = NULL; - dictator_free(thread_seq, (void *)ja3_info->fp); - ja3_info->sni=NULL; + dictator_free(thread_seq, (void *)fingerprint_info->ja3_info->fp); + fingerprint_info->ja3_info->fp = NULL; - dictator_free(thread_seq, value); + dictator_free(thread_seq, fingerprint_info->ja3_info); + fingerprint_info->ja3_info = NULL; + } + + if (fingerprint_info->ja3s_info != NULL) + { + dictator_free(thread_seq, (void *)fingerprint_info->ja3s_info->fp); + fingerprint_info->ja3s_info->fp = NULL; + dictator_free(thread_seq, fingerprint_info->ja3s_info); + fingerprint_info->ja3s_info = NULL; + } + + dictator_free(thread_seq, value); value=NULL; } @@ -616,19 +636,27 @@ static void free_ja3_fingerprint_label(int thread_seq, void *value) struct _ssl_ja3_info_t *ssl_get_ja3_fingerprint(struct streaminfo *stream, unsigned char *payload, int payload_len, int thread_seq) { int ret=0; - char ja3_fp[30000]={0}; + char ja3_fp[8192]={0}; char sni_buff[1024]={0}; + _ssl_ja3_info_t *ja3_info = NULL; - struct _ssl_ja3_info_t *ja3_info=(struct _ssl_ja3_info_t *)project_req_get_struct(stream, g_ssl_ja3_fingerprint_label_id); - if(ja3_info!=NULL) + ssl_fingerprint_t *fingerprint_info=(ssl_fingerprint_t *)project_req_get_struct(stream, g_ssl_ja3_fingerprint_label_id); + if (fingerprint_info == NULL) + { + fingerprint_info = (ssl_fingerprint_t *)dictator_malloc(thread_seq, sizeof(ssl_fingerprint_t)); + memset(fingerprint_info, 0, sizeof(ssl_fingerprint_t)); + project_req_add_struct(stream, g_ssl_ja3_fingerprint_label_id, (void *)fingerprint_info); + } + else if(fingerprint_info->ja3_info!=NULL) { - return ja3_info; + return fingerprint_info->ja3_info; } ret=ssl_generate_ja3_fingerprint(payload, payload_len, ja3_fp, sizeof(ja3_fp), sni_buff, sizeof(sni_buff)); if(ret==1) { - ja3_info=(struct _ssl_ja3_info_t *)dictator_malloc(thread_seq, sizeof(struct _ssl_ja3_info_t)); + fingerprint_info->ja3_info=(struct _ssl_ja3_info_t *)dictator_malloc(thread_seq, sizeof(struct _ssl_ja3_info_t)); + ja3_info = fingerprint_info->ja3_info; if(strlen(sni_buff)>0 && strlen(sni_buff)<sizeof(sni_buff)) { @@ -643,7 +671,7 @@ struct _ssl_ja3_info_t *ssl_get_ja3_fingerprint(struct streaminfo *stream, unsig ja3_info->sni_len=0; } - if(strlen(ja3_fp)>0 && strlen(ja3_fp)<sizeof(ja3_fp)) + if(strlen(ja3_fp)>0) { ja3_info->fp=(char *)dictator_malloc(thread_seq, MD5_DIGEST_LENGTH*2+1); ja3_info->fp_len=ja3_md5sum(ja3_fp, strlen(ja3_fp), ja3_info->fp, MD5_DIGEST_LENGTH*2+1); @@ -654,8 +682,6 @@ struct _ssl_ja3_info_t *ssl_get_ja3_fingerprint(struct streaminfo *stream, unsig ja3_info->fp=NULL; ja3_info->fp_len=0; } - - project_req_add_struct(stream, g_ssl_ja3_fingerprint_label_id, (void *)ja3_info); return ja3_info; } @@ -663,6 +689,122 @@ struct _ssl_ja3_info_t *ssl_get_ja3_fingerprint(struct streaminfo *stream, unsig return NULL; } +static int ssl_generate_ja3s_fingerprint(const unsigned char *data, int len, char *ja3_fp, int ja3_fp_len) +{ + BSB bsb; + BSB_INIT(bsb, data, len); + + if (BSB_REMAINING(bsb) <= 9) + { + return 0; + } + + BSB_IMPORT_skip(bsb, 5); // Message Header + BSB_IMPORT_skip(bsb, 4); // Handshake Type + message len + uint16_t ver = 0; + BSB_IMPORT_u16(bsb, ver); + BSB_IMPORT_skip(bsb, 32); // Random + + if(BSB_IS_ERROR(bsb)) + return 0; + + /* Parse sessionid, only for SSLv3 - TLSv1.2 */ + if (ver >= 0x0300 && ver <= 0x0303) { + int skiplen = 0; + BSB_IMPORT_u08(bsb, skiplen); // Session Id Length + BSB_IMPORT_skip(bsb, skiplen); // Session Id + } + + uint16_t cipher = 0; + BSB_IMPORT_u16(bsb, cipher); + BSB_IMPORT_skip(bsb, 1); + + + BSB ja3bsb; + char eja3[10000]; + BSB eja3bsb; + + BSB_INIT(ja3bsb, ja3_fp, ja3_fp_len); + BSB_INIT(eja3bsb, eja3, sizeof(eja3)); + + if (BSB_REMAINING(bsb) > 2) { + int etotlen = 0; + BSB_IMPORT_u16(bsb, etotlen); // Extensions Length + + etotlen = MIN(etotlen, BSB_REMAINING(bsb)); + + BSB ebsb; + BSB_INIT(ebsb, BSB_WORK_PTR(bsb), etotlen); + + while (BSB_REMAINING(ebsb) > 0) { + int etype = 0, elen = 0; + + BSB_IMPORT_u16 (ebsb, etype); + BSB_IMPORT_u16 (ebsb, elen); + + BSB_EXPORT_sprintf(eja3bsb, "%d-", etype); + + if (elen > BSB_REMAINING(ebsb)) + break; + + // if (etype == 0x2b && elen == 2) { // etype 0x2b is supported version + // uint16_t supported_version = 0; + // BSB_IMPORT_u16(ebsb, supported_version); + // } + + BSB_IMPORT_skip (ebsb, elen); + } + BSB_EXPORT_rewind(eja3bsb, 1); // Remove last - + } + + BSB_EXPORT_sprintf(ja3bsb, "%d,%d,%.*s", ver, cipher, (int)BSB_LENGTH(eja3bsb), eja3); + + return 1; +} + +struct _ssl_ja3s_info_t *ssl_get_ja3s_fingerprint(struct streaminfo *stream, unsigned char *payload, int payload_len, int thread_seq) +{ + int ret=0; + char ja3s_fp[8192]={0}; + _ssl_ja3s_info_t *ja3s_info = NULL; + + ssl_fingerprint_t *fingerprint_info=(ssl_fingerprint_t *)project_req_get_struct(stream, g_ssl_ja3_fingerprint_label_id); + if (fingerprint_info == NULL) + { + fingerprint_info = (ssl_fingerprint_t *)dictator_malloc(thread_seq, sizeof(ssl_fingerprint_t)); + memset(fingerprint_info, 0, sizeof(ssl_fingerprint_t)); + project_req_add_struct(stream, g_ssl_ja3_fingerprint_label_id, (void *)fingerprint_info); + } + else if(fingerprint_info->ja3s_info!=NULL) + { + return fingerprint_info->ja3s_info; + } + + ret=ssl_generate_ja3s_fingerprint(payload, payload_len, ja3s_fp, sizeof(ja3s_fp)); + if(ret==1) + { + fingerprint_info->ja3s_info=(struct _ssl_ja3s_info_t *)dictator_malloc(thread_seq, sizeof(struct _ssl_ja3s_info_t)); + ja3s_info = fingerprint_info->ja3s_info; + + if(strlen(ja3s_fp)>0) + { + ja3s_info->fp=(char *)dictator_malloc(thread_seq, MD5_DIGEST_LENGTH*2+1); + ja3s_info->fp_len=ja3_md5sum(ja3s_fp, strlen(ja3s_fp), ja3s_info->fp, MD5_DIGEST_LENGTH*2+1); + ja3s_info->fp[ja3s_info->fp_len]='\0'; + } + else + { + ja3s_info->fp=NULL; + ja3s_info->fp_len=0; + } + + return ja3s_info; + } + + return NULL; +} + + int ssl_ja3_init(void) { g_ssl_ja3_fingerprint_label_id=project_producer_register("JA3_FINGERPRINT_LABEL", "struct", free_ja3_fingerprint_label); @@ -188,7 +188,7 @@ typedef struct _san_t typedef struct _st_san_t { int count; - san_t* san_array; //ָ������ + san_t* san_array; //ָ������ }st_san_t; typedef struct _st_cert_t @@ -266,34 +266,34 @@ typedef struct _ssl_stream_t unsigned char first_pkt_flag; }ssl_stream; -/*ssl_read_all_cert�еĽṹ��*/ +/*ssl_read_all_cert�еĽṹ��*/ typedef struct cert_chain_s { char* cert; uint32_t cert_len; }cert_chain_t; -/*ssl_get_alpn_list?D��??��11��?*/ +/*ssl_get_alpn_list?D��??��11��?*/ typedef struct alpn_list_s { char* alpn; //pointer to exts uint32_t alpn_len; }alpn_list_t; -/*ssl_read_specific_cert��cert_type�IJ���*/ -#define CERT_TYPE_INDIVIDUAL 0 //����֤�� -#define CERT_TYPE_ROOT 1 //��֤�� -#define CERT_TYPE_MIDDLE 2 //�м�֤�飬����֤����ϼ�֤�� -#define CERT_TYPE_CHAIN 3 //����: ��ʽ[len(3bytes)+cert+len(3bytes)+certlen(3bytes)+cert......] +/*ssl_read_specific_cert��cert_type�IJ���*/ +#define CERT_TYPE_INDIVIDUAL 0 //����֤�� +#define CERT_TYPE_ROOT 1 //��֤�� +#define CERT_TYPE_MIDDLE 2 //�м�֤�飬����֤����ϼ�֤�� +#define CERT_TYPE_CHAIN 3 //����: ��ʽ[len(3bytes)+cert+len(3bytes)+certlen(3bytes)+cert......] #ifdef __cplusplus extern "C" { #endif -/*return : chain ����, ���մӸ���֤�鵽��֤���˳��洢*/ +/*return : chain ����, ���մӸ���֤�鵽��֤���˳��洢*/ int ssl_read_all_cert(const char* conj_cert_buf, uint32_t conj_buflen, cert_chain_t* cert_unit, uint32_t unit_size); -/*return : 1 ���ڣ�0 ������*/ +/*return : 1 ���ڣ�0 ������*/ int ssl_read_specific_cert(const char* conj_cert_buf, uint32_t conj_buflen, uint8_t cert_type, char** cert, uint32_t* cert_len); /*Obtain suite name like "TLS_RSA_WITH_AES_128_CBC_SHA" by suite_value; Each suite should be 2 bytes*/ @@ -320,8 +320,15 @@ struct _ssl_ja3_info_t char *fp; }; +struct _ssl_ja3s_info_t +{ + int fp_len; + char *fp; +}; + int ssl_ja3_init(void); struct _ssl_ja3_info_t *ssl_get_ja3_fingerprint(struct streaminfo *stream, unsigned char *payload, int payload_len, int thread_seq); +struct _ssl_ja3s_info_t *ssl_get_ja3s_fingerprint(struct streaminfo *stream, unsigned char *payload, int payload_len, int thread_seq); #ifdef __cplusplus } |
