From 484cb7a71951b32e353ba649aa77f636699e8e4e Mon Sep 17 00:00:00 2001 From: liuxueli Date: Tue, 12 Mar 2024 18:20:30 +0800 Subject: Bugfix: tcp ack contains payload and the payload length is less than 6 (ssl header), ec_point_format has multiple values --- src/SSL_Message.c | 127 +++++++++++---------- test/CMakeLists.txt | 1 + ...ment.36.251.161.167.39777-143.92.57.79.443.pcap | Bin 0 -> 4708 bytes .../ssl_client_hello_fragment_result.json | 8 ++ .../1-tcp_ack_contains_payload.pcap | Bin 0 -> 21756 bytes .../ssl_tcp_ack_contians_payload_result.json | 114 ++++++++++++++++++ 6 files changed, 190 insertions(+), 60 deletions(-) create mode 100644 test/pcap/client_hello_fragment/3-ssl.client.hello.fragment.36.251.161.167.39777-143.92.57.79.443.pcap create mode 100644 test/pcap/tcp_ack_contians_payload/1-tcp_ack_contains_payload.pcap create mode 100644 test/pcap/tcp_ack_contians_payload/ssl_tcp_ack_contians_payload_result.json diff --git a/src/SSL_Message.c b/src/SSL_Message.c index bbc9033..86f9713 100644 --- a/src/SSL_Message.c +++ b/src/SSL_Message.c @@ -157,6 +157,11 @@ void ssl_trunk_free(struct ssl_runtime_context *ssl_context, int thread_seq) int ssl_trunk_cache(struct ssl_runtime_context *ssl_context, char *payload, int payload_len, int thread_seq) { + if(payload==NULL || payload_len<=0) + { + return 0; + } + if(ssl_context->record.cache_buff==NULL) { ssl_context->record.cache_buff=(char *)dictator_malloc(thread_seq, g_ssl_runtime_para.max_cache_len); @@ -334,20 +339,10 @@ int ssl_parse_encrypt_server_name(struct ssl_client_hello *chello, struct ssl_l2 int ssl_parse_client_hello(struct ssl_client_hello *chello, unsigned char *payload, int payload_len) { int offset=0,one_ltv=0; - unsigned int ec_point_format=0; - - UT_string *ja3_string,*cipher_suite_string,*ec_string,*ex_string; - utstring_new(ja3_string); - utstring_new(cipher_suite_string); - utstring_printf(cipher_suite_string, ","); - utstring_new(ec_string); - utstring_printf(ec_string, ","); - utstring_new(ex_string); - utstring_printf(ex_string, ","); - chello->total_len=BtoL3BytesNum((const char *)(payload+1)); if(chello->total_len<0) /*CLIENT_HELLO_HDRLEN: 4 means client_type+len*/ { + return SSL_FLASE; } @@ -361,8 +356,6 @@ int ssl_parse_client_hello(struct ssl_client_hello *chello, unsigned char *paylo { return SSL_FLASE; } - - utstring_printf(ja3_string, "%u", chello->version); offset+=(CLIENT_HELLO_HDRLEN+sizeof(chello->version)); /*get client hello random*/ @@ -393,18 +386,6 @@ int ssl_parse_client_hello(struct ssl_client_hello *chello, unsigned char *paylo return SSL_FLASE; } - if(chello->ciphersuites.len>0) - { - for(unsigned short i=0; iciphersuites.len; i+=2) - { - unsigned short cipher_suite=BtoL2BytesNum((const char *)(chello->ciphersuites.value+i)); - if(ssl_is_grease_value(cipher_suite)==0) - { - utstring_printf(cipher_suite_string, "%u-", cipher_suite); - } - } - } - offset+=one_ltv; /*get client hello compress*/ @@ -415,6 +396,13 @@ int ssl_parse_client_hello(struct ssl_client_hello *chello, unsigned char *paylo } offset+=one_ltv; + + UT_string *ex_string; + utstring_new(ex_string); + utstring_printf(ex_string, ","); + + struct ssl_l2tv *ec=NULL; + struct ssl_l2tv *ec_point_format=NULL; if(offset < payload_len) { /*get extension*/ @@ -427,6 +415,7 @@ int ssl_parse_client_hello(struct ssl_client_hello *chello, unsigned char *paylo one_ltv=ssl_parse_ltv2(&(chello->extensions.extension[ex_offset]), payload+offset, payload_len-offset); if(one_ltv==-1) { + utstring_free(ex_string); return SSL_FLASE; } @@ -455,42 +444,10 @@ int ssl_parse_client_hello(struct ssl_client_hello *chello, unsigned char *paylo chello->alpn=&(chello->extensions.extension[ex_offset++]); break; case EC_POINT_FORMATS_EXT_TYPE: - // parse ec point formats - { - char length=BtoL1BytesNum((const char*)(chello->extensions.extension[ex_offset].value)); - switch(length) - { - case 1: - ec_point_format=BtoL1BytesNum((const char*)(chello->extensions.extension[ex_offset].value+1)); - break; - case 2: - ec_point_format=BtoL2BytesNum((const char*)(chello->extensions.extension[ex_offset].value+1)); - break; - case 3: - ec_point_format=BtoL3BytesNum((const char*)(chello->extensions.extension[ex_offset].value+1)); - break; - case 4: - ec_point_format=BtoL4BytesNum((const char*)(chello->extensions.extension[ex_offset].value+1)); - break; - default: - ec_point_format=0; - break; - } - } + ec_point_format=&(chello->extensions.extension[ex_offset++]); break; case SUPPORTED_GROUPS_EXT_TYPE: - // parse supported groups - { - unsigned short length=BtoL2BytesNum((const char*)(chello->extensions.extension[ex_offset].value)); - for(unsigned short j=0; jextensions.extension[ex_offset].value+j+2)); - if(ssl_is_grease_value(group)==0) - { - utstring_printf(ec_string, "%u-", group); - } - } - } + ec=&(chello->extensions.extension[ex_offset++]); break; default: break; @@ -499,11 +456,59 @@ int ssl_parse_client_hello(struct ssl_client_hello *chello, unsigned char *paylo chello->extensions.num=ex_offset; } + + UT_string *ja3_string; + utstring_new(ja3_string); + utstring_printf(ja3_string, "%u", chello->version); + + UT_string *cipher_suite_string; + utstring_new(cipher_suite_string); + utstring_printf(cipher_suite_string, ","); + if(chello->ciphersuites.len>0) + { + for(unsigned short i=0; iciphersuites.len; i+=2) + { + unsigned short cipher_suite=BtoL2BytesNum((const char *)(chello->ciphersuites.value+i)); + if(ssl_is_grease_value(cipher_suite)==0) + { + utstring_printf(cipher_suite_string, "%u-", cipher_suite); + } + } + } utstring_bincpy(ja3_string, utstring_body(cipher_suite_string), (utstring_len(cipher_suite_string)==1 ? utstring_len(cipher_suite_string) : utstring_len(cipher_suite_string)-1)); + utstring_bincpy(ja3_string, utstring_body(ex_string), (utstring_len(ex_string)==1 ? utstring_len(ex_string) : utstring_len(ex_string)-1)); + + UT_string *ec_string; + utstring_new(ec_string); + utstring_printf(ec_string, ","); + if(ec!=NULL) + { + unsigned short length=BtoL2BytesNum((const char*)(ec->value)); + for(unsigned short j=0; jvalue+j+2)); + if(ssl_is_grease_value(group)==0) + { + utstring_printf(ec_string, "%u-", group); + } + } + } utstring_bincpy(ja3_string, utstring_body(ec_string), (utstring_len(ec_string)==1 ? utstring_len(ec_string) : utstring_len(ec_string)-1)); - utstring_printf(ja3_string, ",%u", ec_point_format); + + UT_string *ec_point_format_string; + utstring_new(ec_point_format_string); + utstring_printf(ec_point_format_string, ","); + if(ec_point_format!=NULL) + { + char length=BtoL1BytesNum((const char*)(ec_point_format->value)); + for(char j=0; jvalue[j+1]); + } + } + utstring_bincpy(ja3_string, utstring_body(ec_point_format_string), (utstring_len(ec_point_format_string)==1 ? utstring_len(ec_point_format_string) : utstring_len(ec_point_format_string)-1)); chello->ja3.md5_len=ja3_md5sum(utstring_body(ja3_string), utstring_len(ja3_string), chello->ja3.md5, sizeof(chello->ja3.md5)); chello->ja3.md5[chello->ja3.md5_len]='\0'; @@ -512,6 +517,7 @@ int ssl_parse_client_hello(struct ssl_client_hello *chello, unsigned char *paylo utstring_free(cipher_suite_string); utstring_free(ec_string); utstring_free(ex_string); + utstring_free(ec_point_format_string); return SSL_TRUE; } @@ -1095,6 +1101,7 @@ int ssl_parse_stream(const struct streaminfo *a_tcp, struct ssl_runtime_context /**validaty check**/ if(NULL==payload || payload_len143.92.57.79.443", + "ssl_sni": "a.ywgyuv.cn", + "ssl_ech": "1", + "ssl_client_version": "TLS1.2", + "ssl_ja3_hash": "c3db97da3b30171e5cf9de314584b555", + "name": "SSL_RESULT_3" } ] \ No newline at end of file diff --git a/test/pcap/tcp_ack_contians_payload/1-tcp_ack_contains_payload.pcap b/test/pcap/tcp_ack_contians_payload/1-tcp_ack_contains_payload.pcap new file mode 100644 index 0000000..199f7ee Binary files /dev/null and b/test/pcap/tcp_ack_contians_payload/1-tcp_ack_contains_payload.pcap differ diff --git a/test/pcap/tcp_ack_contians_payload/ssl_tcp_ack_contians_payload_result.json b/test/pcap/tcp_ack_contians_payload/ssl_tcp_ack_contians_payload_result.json new file mode 100644 index 0000000..9632ce8 --- /dev/null +++ b/test/pcap/tcp_ack_contians_payload/ssl_tcp_ack_contians_payload_result.json @@ -0,0 +1,114 @@ +[ + { + "Tuple4": "36.251.161.167.39018>143.92.57.79.443", + "ssl_sni": "a.ywgyuv.cn", + "ssl_ech": "1", + "ssl_client_version": "TLS1.2", + "ssl_ja3_hash": "6f7971785f5cbbcb21819b6639f0e8f7", + "name": "SSL_RESULT_1" + }, + { + "Tuple4": "36.251.161.167.39025>143.92.57.79.443", + "ssl_sni": "a.ywgyuv.cn", + "ssl_ech": "1", + "ssl_client_version": "TLS1.2", + "ssl_ja3_hash": "0ac1d260c0b1f0e3bf645d6580ea6343", + "name": "SSL_RESULT_2" + }, + { + "Tuple4": "36.251.161.167.39112>143.92.57.79.443", + "ssl_sni": "a.ywgyuv.cn", + "ssl_ech": "1", + "ssl_client_version": "TLS1.2", + "ssl_ja3_hash": "ca54aeeb513ecacf4d7bc22c5d8f0b75", + "name": "SSL_RESULT_3" + }, + { + "Tuple4": "36.251.161.167.39423>143.92.57.79.443", + "ssl_sni": "a.ywgyuv.cn", + "ssl_ech": "1", + "ssl_client_version": "TLS1.2", + "ssl_ja3_hash": "9e41793e6f0a1696bedc0876465e1f42", + "name": "SSL_RESULT_4" + }, + { + "Tuple4": "36.251.161.167.39680>143.92.57.79.443", + "ssl_sni": "a.ywgyuv.cn", + "ssl_ech": "1", + "ssl_client_version": "TLS1.2", + "ssl_ja3_hash": "47c3fabcf1bc65a32a9d3fb8e70ab79d", + "name": "SSL_RESULT_5" + }, + { + "Tuple4": "36.251.161.167.39809>143.92.57.79.443", + "ssl_sni": "a.ywgyuv.cn", + "ssl_ech": "1", + "ssl_client_version": "TLS1.2", + "ssl_ja3_hash": "04331a57b3e122e689c373712edf42c0", + "name": "SSL_RESULT_6" + }, + { + "Tuple4": "36.251.161.167.39816>143.92.57.79.443", + "ssl_sni": "a.ywgyuv.cn", + "ssl_ech": "1", + "ssl_client_version": "TLS1.2", + "ssl_ja3_hash": "34c3efe4e6565e8eef2eaaeb7c12a1a6", + "name": "SSL_RESULT_7" + }, + { + "Tuple4": "36.251.161.167.39820>143.92.57.79.443", + "ssl_sni": "a.ywgyuv.cn", + "ssl_ech": "1", + "ssl_client_version": "TLS1.2", + "ssl_ja3_hash": "cc97290a5bb4651489fe7a88e93ace90", + "name": "SSL_RESULT_8" + }, + { + "Tuple4": "36.251.161.167.39825>143.92.57.79.443", + "ssl_sni": "a.ywgyuv.cn", + "ssl_ech": "1", + "ssl_client_version": "TLS1.2", + "ssl_ja3_hash": "4e6ae21ce8b876dc7cad2f5ca9a60b23", + "name": "SSL_RESULT_9" + }, + { + "Tuple4": "36.251.161.167.39832>143.92.57.79.443", + "ssl_sni": "a.ywgyuv.cn", + "ssl_ech": "1", + "ssl_client_version": "TLS1.2", + "ssl_ja3_hash": "89cb560e9ee2d33728756a2d4d7b2900", + "name": "SSL_RESULT_10" + }, + { + "Tuple4": "36.251.161.167.39850>143.92.57.79.443", + "ssl_sni": "a.ywgyuv.cn", + "ssl_ech": "1", + "ssl_client_version": "TLS1.2", + "ssl_ja3_hash": "7324d30178b21f4c3a60550ef43d5ab0", + "name": "SSL_RESULT_11" + }, + { + "Tuple4": "36.251.161.167.39867>143.92.57.79.443", + "ssl_sni": "a.ywgyuv.cn", + "ssl_ech": "1", + "ssl_client_version": "TLS1.2", + "ssl_ja3_hash": "53fed08198669268c271fc320627c0c4", + "name": "SSL_RESULT_12" + }, + { + "Tuple4": "36.251.161.167.39777>143.92.57.79.443", + "ssl_sni": "a.ywgyuv.cn", + "ssl_ech": "1", + "ssl_client_version": "TLS1.2", + "ssl_ja3_hash": "c3db97da3b30171e5cf9de314584b555", + "name": "SSL_RESULT_13" + }, + { + "Tuple4": "36.251.161.167.39810>143.92.57.79.443", + "ssl_sni": "a.ywgyuv.cn", + "ssl_ech": "1", + "ssl_client_version": "TLS1.2", + "ssl_ja3_hash": "ff194650bab04e7b4cd55e66fd91c010", + "name": "SSL_RESULT_14" + } +] \ No newline at end of file -- cgit v1.2.3