summaryrefslogtreecommitdiff
path: root/src/SSl_ja3_fingerprint.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/SSl_ja3_fingerprint.cpp')
-rw-r--r--src/SSl_ja3_fingerprint.cpp170
1 files changed, 156 insertions, 14 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);