summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
author彭宣正 <[email protected]>2022-10-08 10:28:27 +0000
committer刘学利 <[email protected]>2022-10-08 10:28:27 +0000
commitd55819b624a06fabe8729524b8e8b6aca3e0e92f (patch)
treefea8e0b48efb0716a0e49ef1990244bce3f834a3 /src
parentd67f09990712f90e736cbc03f2674a151338a502 (diff)
✨ feat(TSG-12086): 增加ja3s 生成方式v2.0.12
Diffstat (limited to 'src')
-rw-r--r--src/SSl_ja3_fingerprint.cpp170
-rw-r--r--src/ssl.h27
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);
diff --git a/src/ssl.h b/src/ssl.h
index 87a2a52..4448115 100644
--- a/src/ssl.h
+++ b/src/ssl.h
@@ -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
}