summaryrefslogtreecommitdiff
path: root/src/ssl_decoder.cpp
diff options
context:
space:
mode:
authorliuxueli <[email protected]>2024-08-06 00:59:57 +0000
committerliuxueli <[email protected]>2024-08-06 00:59:57 +0000
commit91ec4d1ee31278133881094501a03ed11d9fa839 (patch)
tree5067ffcc7c9cd57e1e09fd5704b85c6eaa217a4c /src/ssl_decoder.cpp
parent97107b1b0a5bfbd7206a345f1a123aa019bf696d (diff)
Feature: server hello decode
Diffstat (limited to 'src/ssl_decoder.cpp')
-rw-r--r--src/ssl_decoder.cpp163
1 files changed, 133 insertions, 30 deletions
diff --git a/src/ssl_decoder.cpp b/src/ssl_decoder.cpp
index 92c048e..3d86e50 100644
--- a/src/ssl_decoder.cpp
+++ b/src/ssl_decoder.cpp
@@ -240,10 +240,6 @@ void ssl_handshake_server_key_exchange_decode()
}
-void ssl_handshake_server_hello_decode()
-{
-
-}
int32_t ssl_read_u8(uint8_t *pdata, size_t pdata_sz, size_t *pdata_offset, uint8_t *value)
{
@@ -261,22 +257,6 @@ int32_t ssl_read_u8(uint8_t *pdata, size_t pdata_sz, size_t *pdata_offset, uint8
return SSL_DECODER_TRUE;
}
-int32_t ssl_read_le_u16(uint8_t *pdata, size_t pdata_sz, size_t *pdata_offset, uint16_t *value)
-{
- if(pdata_sz<(*pdata_offset)+2)
- {
- return SSL_DECODER_FALSE;
- }
-
- if(value!=NULL)
- {
- memcpy((uint8_t *)value, pdata+(*pdata_offset), 2);
- }
-
- (*pdata_offset)+=2;
- return SSL_DECODER_TRUE;
-}
-
int32_t ssl_read_be_u16(uint8_t *pdata, size_t pdata_sz, size_t *pdata_offset, uint16_t *value)
{
if(pdata_sz<(*pdata_offset)+2)
@@ -420,6 +400,85 @@ int32_t ssl_server_name_decode(struct ssl_decoder_ltv *sni, uint8_t *pdata, uint
return SSL_DECODER_TRUE;
}
+struct ssl_server_hello *ssl_handshake_server_hello_decode(uint8_t *pdata, size_t pdata_sz, size_t *pdata_offset)
+{
+ int32_t total_len; //3
+ int32_t ret=ssl_read_be_u24(pdata, pdata_sz, pdata_offset, (uint8_t *)&(total_len));
+ if(total_len<0) /*CLIENT_HELLO_HDRLEN: 4 means client_type+len*/
+ {
+ return NULL;
+ }
+
+ struct ssl_server_hello *shello=(struct ssl_server_hello *)CALLOC(struct ssl_server_hello, 1);
+ ssl_read_be_u16(pdata, pdata_sz, pdata_offset, &(shello->version));
+ ssl_read_be_u32(pdata, pdata_sz, pdata_offset, &(shello->random_gmt_time));
+
+ for(int i=1; i<SSL_HELLO_LTV_MAX; i++)
+ {
+ struct ssl_decoder_ltv *ltv=&(shello->ltv[i]);
+ switch(i)
+ {
+ case SSL_HELLO_LTV_RANDOM_BYTES:
+ ret=ssl_decoder_random_bytes_get(ltv, SSL_DECODER_NONE, pdata, pdata_sz, pdata_offset);
+ break;
+ case SSL_HELLO_LTV_SESSION:
+ ret=ssl_decoder_ltv_get(ltv, SSL_DECODER_L1V, pdata, pdata_sz, pdata_offset);
+ break;
+ case SSL_HELLO_LTV_CIPERSUITES:
+ shello->ltv[i].lv_u16=2;
+ shello->ltv[i].value=pdata+(*pdata_offset);
+ (*pdata_offset)+=2;
+ break;
+ case SSL_HELLO_LTV_COMPRESS_METHOD:
+ shello->ltv[i].lv_u16=1;
+ shello->ltv[i].value=pdata+(*pdata_offset);
+ (*pdata_offset)+=1;
+ break;
+ default:
+ break;
+ }
+
+ if(ret==SSL_DECODER_FALSE)
+ {
+ FREE(shello);
+ return NULL;
+ }
+ }
+
+ /*get extension*/
+ uint16_t extension_len=0;
+ ret=ssl_read_be_u16(pdata, pdata_sz, pdata_offset, &extension_len);
+ if(ret==SSL_DECODER_FALSE || (extension_len+(*pdata_offset)>pdata_sz))
+ {
+ FREE(shello);
+ return NULL;
+ }
+
+ if(extension_len==0)
+ {
+ return shello;
+ }
+
+ size_t offset=(*pdata_offset);
+ utarray_new(shello->extensions, &UT_ssl_hello_extension_icd);
+
+ for(size_t i=0; pdata_sz>offset && (offset-(*pdata_offset))<extension_len; i++) // min len of ext is 4 byte
+ {
+ struct ssl_decoder_ltv ltv={0};
+ ret=ssl_decoder_ltv_get(&ltv, SSL_DECODER_L2TV, pdata, pdata_sz, &offset);
+ if(ret==SSL_DECODER_FALSE)
+ {
+ break;
+ }
+
+ utarray_push_back(shello->extensions, &ltv);
+ }
+
+ (*pdata_offset)=offset;
+
+ return shello;
+}
+
struct ssl_client_hello *ssl_handshake_client_hello_decode(uint8_t *pdata, size_t pdata_sz, size_t *pdata_offset)
{
int32_t total_len; //3
@@ -464,7 +523,7 @@ struct ssl_client_hello *ssl_handshake_client_hello_decode(uint8_t *pdata, size_
/*get extension*/
uint16_t extension_len=0;
ret=ssl_read_be_u16(pdata, pdata_sz, pdata_offset, &extension_len);
- if(ret==SSL_DECODER_FALSE)
+ if(ret==SSL_DECODER_FALSE || (extension_len+(*pdata_offset)>pdata_sz))
{
FREE(chello);
return NULL;
@@ -475,12 +534,6 @@ struct ssl_client_hello *ssl_handshake_client_hello_decode(uint8_t *pdata, size_
return chello;
}
- if(extension_len+(*pdata_offset)>pdata_sz)
- {
- FREE(chello);
- return NULL;
- }
-
utarray_new(chello->extensions, &UT_ssl_hello_extension_icd);
for(size_t i=0; pdata_sz>(*pdata_offset); i++) // min len of ext is 4 byte
@@ -523,6 +576,54 @@ struct ssl_client_hello *ssl_handshake_client_hello_decode(uint8_t *pdata, size_
return chello;
}
+int32_t ssl_server_hello_ja3s_generate(struct ssl_server_hello *shello)
+{
+ if(shello==NULL)
+ {
+ return SSL_DECODER_FALSE;
+ }
+
+ UT_string *ja3s_string;
+ utstring_new(ja3s_string);
+ utstring_printf(ja3s_string, "%u,", shello->version);
+
+ int32_t flag=SSL_DECODER_FALSE;
+ size_t offset=0;
+ struct ssl_decoder_ltv *cipher_suites=&(shello->ltv[SSL_HELLO_LTV_CIPERSUITES]);
+ for(; offset<cipher_suites->lv_u16; )
+ {
+ uint16_t cipher_suite=0;
+ ssl_read_be_u16(cipher_suites->value, cipher_suites->lv_u16, &offset, &cipher_suite);
+ if(ssl_is_grease_value(cipher_suite))
+ {
+ continue;
+ }
+
+ utstring_printf(ja3s_string, "%s%u", ((flag==SSL_DECODER_FALSE) ? "" : "-"), cipher_suite);
+ flag=SSL_DECODER_TRUE;
+ }
+
+ utstring_printf(ja3s_string, "%s", ",");
+
+ flag=SSL_DECODER_FALSE;
+ for(uint32_t i=0; i<utarray_len(shello->extensions); i++)
+ {
+ struct ssl_decoder_ltv *ext=(struct ssl_decoder_ltv *)utarray_eltptr(shello->extensions, i);
+ if(ext==NULL || ssl_is_grease_value(ext->vtype))
+ {
+ continue;
+ }
+
+ utstring_printf(ja3s_string, "%s%u", ((flag==SSL_DECODER_FALSE) ? "" : "-"), ext->vtype);
+ flag=SSL_DECODER_TRUE;
+ }
+
+ ssl_hello_md5sum(&(shello->ja3s), utstring_body(ja3s_string), utstring_len(ja3s_string));
+ utstring_free(ja3s_string);
+
+ return SSL_DECODER_TRUE;
+}
+
int32_t ssl_client_hello_ja3_generate(struct ssl_client_hello *chello)
{
if(chello==NULL)
@@ -631,6 +732,7 @@ void ssl_handshake_decode(struct ssl_decoder_plugin_env *plugin_env, struct sess
}
struct ssl_client_hello *chello=NULL;
+ struct ssl_server_hello *shello=NULL;
struct ssl_handshake_type *handshake_type=(struct ssl_handshake_type *)(segment_buff+(*segment_buff_offset));
(*segment_buff_offset)+=sizeof(struct ssl_handshake_type);
switch(handshake_type->content_type)
@@ -640,13 +742,14 @@ void ssl_handshake_decode(struct ssl_decoder_plugin_env *plugin_env, struct sess
ssl_client_hello_ja3_generate(chello);
break;
case SSL_HANDSHAKE_SERVER_HELLO:
- ssl_handshake_server_hello_decode();
+ shello=ssl_handshake_server_hello_decode(segment_buff, segment_buff_sz, segment_buff_offset);
+ ssl_server_hello_ja3s_generate(shello);
break;
case SSL_HANDSHAKE_CERTIFICATE:
- ssl_handshake_certificate_decode();
+ // ssl_handshake_certificate_decode();
break;
case SSL_HANDSHAKE_SERVER_KEY_EXCHANGE:
- ssl_handshake_server_key_exchange_decode();
+ // ssl_handshake_server_key_exchange_decode();
break;
default:
break;