From 4fb3de31f525f59c1fa34bcb244342d2a967dc51 Mon Sep 17 00:00:00 2001 From: "Oleh Poluianskyi -X (opoluian - SOFTSERVE INC at Cisco)" Date: Wed, 23 Oct 2024 19:11:17 +0000 Subject: [PATCH] Pull request #4312: appid: add tls_version captured in appid_session Merge in SNORT/snort3 from ~OPOLUIAN/snort3:appid_navl_opoluian_ssl_version to master Squashed commit of the following: commit d3328cd520f27cf01735a851b48e9fbac29f488f Author: Oleh Poluianskyi Date: Thu May 2 03:27:15 2024 +0300 appid: add tls_version capture in appid_session --- src/network_inspectors/appid/appid_discovery.h | 1 + src/network_inspectors/appid/appid_session.h | 12 ++++++++++++ src/network_inspectors/appid/appid_session_api.cc | 9 +++++++++ src/network_inspectors/appid/appid_session_api.h | 1 + src/network_inspectors/appid/test/appid_api_test.cc | 12 ++++++------ .../appid/test/appid_discovery_test.cc | 8 ++++---- .../appid/test/appid_session_api_test.cc | 12 ++++++++++++ src/network_inspectors/appid/tp_appid_types.h | 5 +++++ src/network_inspectors/appid/tp_appid_utils.cc | 10 ++++++++++ src/pub_sub/appid_events.h | 3 +++ 10 files changed, 63 insertions(+), 10 deletions(-) diff --git a/src/network_inspectors/appid/appid_discovery.h b/src/network_inspectors/appid/appid_discovery.h index 9248cdbb5..5bc207f1f 100644 --- a/src/network_inspectors/appid/appid_discovery.h +++ b/src/network_inspectors/appid/appid_discovery.h @@ -60,6 +60,7 @@ struct Packet; #define SCAN_HTTP_URI_FLAG (1<<9) #define SCAN_CERTVIZ_ENABLED_FLAG (1<<10) #define SCAN_SPOOFED_SNI_FLAG (1<<11) +#define SCAN_SSL_VERSION_FLAG (1<<12) enum FirstPktAppIdDiscovered { diff --git a/src/network_inspectors/appid/appid_session.h b/src/network_inspectors/appid/appid_session.h index fce06c554..827bf0bad 100644 --- a/src/network_inspectors/appid/appid_session.h +++ b/src/network_inspectors/appid/appid_session.h @@ -167,6 +167,8 @@ public: bool get_tls_handshake_done() const { return tls_handshake_done; } + uint16_t get_tls_version() const { return tls_version; } + // Duplicate only if len > 0, otherwise simply set (i.e., own the argument) void set_tls_host(const char* new_tls_host, uint32_t len, bool published=false) { @@ -244,6 +246,15 @@ public: bool is_tls_host_unpublished() const { return tls_host_unpublished; } + void set_tls_version(const char* value, uint32_t length, AppidChangeBits& change_bits) + { + if (value and length == sizeof(uint16_t)) + { + tls_version = *reinterpret_cast(value); + change_bits.set(AppidChangeBit::APPID_TLS_VERSION_BIT); + } + } + private: char* tls_host = nullptr; char* tls_host_mismatch = nullptr; @@ -252,6 +263,7 @@ private: char* tls_org_unit = nullptr; bool tls_handshake_done = false; bool tls_host_unpublished = false; + uint16_t tls_version = 0; MatchedTlsType matched_tls_type = MATCHED_TLS_NONE; }; diff --git a/src/network_inspectors/appid/appid_session_api.cc b/src/network_inspectors/appid/appid_session_api.cc index 8ebda18dc..ce106837d 100644 --- a/src/network_inspectors/appid/appid_session_api.cc +++ b/src/network_inspectors/appid/appid_session_api.cc @@ -325,6 +325,15 @@ const char* AppIdSessionApi::get_tls_host() const return tls_host; } +uint16_t AppIdSessionApi::get_tls_version() const +{ + if (asd and asd->tsession) + { + return asd->tsession->get_tls_version(); + } + return 0; +} + const SfIp* AppIdSessionApi::get_initiator_ip() const { return &initiator_ip; diff --git a/src/network_inspectors/appid/appid_session_api.h b/src/network_inspectors/appid/appid_session_api.h index f5bf28bfc..454802134 100644 --- a/src/network_inspectors/appid/appid_session_api.h +++ b/src/network_inspectors/appid/appid_session_api.h @@ -128,6 +128,7 @@ public: const AppIdHttpSession* get_http_session(uint32_t stream_index = 0) const; const AppIdHttpSession* get_matching_http_session(int64_t stream_id) const; const char* get_tls_host() const; + uint16_t get_tls_version() const; bool is_http_inspection_done() const; const char* get_netbios_name() const; const char* get_netbios_domain() const; diff --git a/src/network_inspectors/appid/test/appid_api_test.cc b/src/network_inspectors/appid/test/appid_api_test.cc index 8bd858870..4b81e00aa 100644 --- a/src/network_inspectors/appid/test/appid_api_test.cc +++ b/src/network_inspectors/appid/test/appid_api_test.cc @@ -274,7 +274,7 @@ TEST(appid_api, ssl_app_group_id_lookup) CHECK_EQUAL(service, APPID_UT_ID); CHECK_EQUAL(client, APPID_UT_ID); CHECK_EQUAL(payload, APPID_UT_ID); - STRCMP_EQUAL("Published change_bits == 00000000000000000000", test_log); + STRCMP_EQUAL("Published change_bits == 000000000000000000000", test_log); // Server name based detection service = APP_ID_NONE; @@ -289,7 +289,7 @@ TEST(appid_api, ssl_app_group_id_lookup) STRCMP_EQUAL(mock_session->tsession->get_tls_first_alt_name(), APPID_UT_TLS_HOST); STRCMP_EQUAL(mock_session->tsession->get_tls_cname(), APPID_UT_TLS_HOST); STRCMP_EQUAL(mock_session->tsession->get_tls_sni(), APPID_UT_TLS_HOST); - STRCMP_EQUAL("Published change_bits == 00000000000100011000", test_log); + STRCMP_EQUAL("Published change_bits == 000000000000100011000", test_log); // Common name based detection mock_session->tsession->set_tls_host("www.cisco.com", 13, change_bits); @@ -306,7 +306,7 @@ TEST(appid_api, ssl_app_group_id_lookup) STRCMP_EQUAL(mock_session->tsession->get_tls_host(), APPID_UT_TLS_HOST); STRCMP_EQUAL(mock_session->tsession->get_tls_cname(), APPID_UT_TLS_HOST); STRCMP_EQUAL(mock_session->tsession->get_tls_org_unit(), "Cisco"); - STRCMP_EQUAL("Published change_bits == 00000000000100011000", test_log); + STRCMP_EQUAL("Published change_bits == 000000000000100011000", test_log); // First alt name based detection change_bits.reset(); @@ -318,7 +318,7 @@ TEST(appid_api, ssl_app_group_id_lookup) CHECK_EQUAL(payload, APPID_UT_ID + 1); STRCMP_EQUAL(mock_session->tsession->get_tls_host(), APPID_UT_TLS_HOST); STRCMP_EQUAL(mock_session->tsession->get_tls_first_alt_name(), APPID_UT_TLS_HOST); - STRCMP_EQUAL("Published change_bits == 00000000000100011000", test_log); + STRCMP_EQUAL("Published change_bits == 000000000000100011000", test_log); // Org unit based detection string host = ""; @@ -330,7 +330,7 @@ TEST(appid_api, ssl_app_group_id_lookup) CHECK_EQUAL(client, APPID_UT_ID + 3); CHECK_EQUAL(payload, APPID_UT_ID + 3); STRCMP_EQUAL(mock_session->tsession->get_tls_org_unit(), APPID_UT_ORG_UNIT); - STRCMP_EQUAL("Published change_bits == 00000000000000011000", test_log); + STRCMP_EQUAL("Published change_bits == 000000000000000011000", test_log); // Override client id found by SSL pattern matcher with the client id provided by // Encrypted Visibility Engine if available @@ -349,7 +349,7 @@ TEST(appid_api, ssl_app_group_id_lookup) STRCMP_EQUAL(mock_session->tsession->get_tls_host(), APPID_UT_TLS_HOST); STRCMP_EQUAL(mock_session->tsession->get_tls_first_alt_name(), APPID_UT_TLS_HOST); STRCMP_EQUAL(mock_session->tsession->get_tls_cname(), APPID_UT_TLS_HOST); - STRCMP_EQUAL("Published change_bits == 00000000000100011000", test_log); + STRCMP_EQUAL("Published change_bits == 000000000000100011000", test_log); //check for sni mismatch being stored in sni field change_bits.reset(); diff --git a/src/network_inspectors/appid/test/appid_discovery_test.cc b/src/network_inspectors/appid/test/appid_discovery_test.cc index 4e8e577b6..a5d11364b 100644 --- a/src/network_inspectors/appid/test/appid_discovery_test.cc +++ b/src/network_inspectors/appid/test/appid_discovery_test.cc @@ -413,7 +413,7 @@ TEST(appid_discovery_tests, event_published_when_ignoring_flow) // Detect changes in service, client, payload, and misc appid mock().checkExpectations(); - STRCMP_EQUAL("Published change_bits == 00000000000001111100", test_log); + STRCMP_EQUAL("Published change_bits == 000000000000001111100", test_log); delete &asd->get_api(); delete asd; @@ -452,7 +452,7 @@ TEST(appid_discovery_tests, event_published_when_processing_flow) // Detect changes in service, client, payload, and misc appid mock().checkExpectations(); - STRCMP_EQUAL("Published change_bits == 00000000000001111100", test_log); + STRCMP_EQUAL("Published change_bits == 000000000000001111100", test_log); delete &asd->get_api(); delete asd; delete flow; @@ -560,10 +560,10 @@ TEST(appid_discovery_tests, change_bits_to_string) change_bits_to_string(change_bits, str); STRCMP_EQUAL(str.c_str(), "created, reset, service, client, payload, misc, referred, host," " tls-host, url, user-agent, response, referrer, dns-host, service-info, client-info," - " user-info, netbios-name, netbios-domain, finished"); + " user-info, netbios-name, netbios-domain, finished, tls-version"); // Failure of this test is a reminder that enum is changed, hence translator needs update - CHECK_EQUAL(APPID_MAX_BIT, 20); + CHECK_EQUAL(APPID_MAX_BIT, 21); } int main(int argc, char** argv) diff --git a/src/network_inspectors/appid/test/appid_session_api_test.cc b/src/network_inspectors/appid/test/appid_session_api_test.cc index cb1bf8c4a..7b94f9cee 100644 --- a/src/network_inspectors/appid/test/appid_session_api_test.cc +++ b/src/network_inspectors/appid/test/appid_session_api_test.cc @@ -368,6 +368,18 @@ TEST(appid_session_api, get_tls_host) STRCMP_EQUAL(val, APPID_UT_TLS_HOST); } +TEST(appid_session_api, get_tls_version) +{ + AppidChangeBits change_bits; + mock_session->tsession->set_tls_version(nullptr, 0, change_bits); + CHECK_EQUAL(mock_session->get_api().get_tls_version(), 0); + CHECK_FALSE(change_bits.test(AppidChangeBit::APPID_TLS_VERSION_BIT)); + const char tls_version[] = {0x03, 0x02}; + mock_session->tsession->set_tls_version(tls_version, sizeof(tls_version), change_bits); + CHECK_EQUAL(mock_session->get_api().get_tls_version(), 0x0203); + CHECK_TRUE(change_bits.test(AppidChangeBit::APPID_TLS_VERSION_BIT)); +} + TEST(appid_session_api, get_initiator_ip) { SfIp expected_ip; diff --git a/src/network_inspectors/appid/tp_appid_types.h b/src/network_inspectors/appid/tp_appid_types.h index d120d237a..070fa8927 100644 --- a/src/network_inspectors/appid/tp_appid_types.h +++ b/src/network_inspectors/appid/tp_appid_types.h @@ -130,6 +130,7 @@ class ThirdPartyAppIDAttributeData string* tls_host_buf = nullptr; string* tls_cname_buf = nullptr; string* tls_org_unit_buf = nullptr; + string* tls_version_buf = nullptr; string* http_request_referer_buf = nullptr; string* ftp_command_user_buf = nullptr; string* quic_sni_buf = nullptr; @@ -155,6 +156,7 @@ class ThirdPartyAppIDAttributeData bool tls_host_flush = true; bool tls_cname_flush = true; bool tls_org_unit_flush = true; + bool tls_version_flush = true; bool http_request_referer_flush = true; bool ftp_command_user_flush = true; bool quic_sni_flush = true; @@ -187,6 +189,7 @@ public: if (tls_host_buf) delete tls_host_buf; if (tls_cname_buf) delete tls_cname_buf; if (tls_org_unit_buf) delete tls_org_unit_buf; + if (tls_version_buf) delete tls_version_buf; if (http_request_referer_buf) delete http_request_referer_buf; if (ftp_command_user_buf) delete ftp_command_user_buf; if (quic_sni_buf) delete quic_sni_buf; @@ -213,6 +216,7 @@ public: TPAD_GET(tls_host) TPAD_GET(tls_cname) TPAD_GET(tls_org_unit) + TPAD_GET(tls_version) TPAD_GET(http_request_referer) TPAD_GET(ftp_command_user) TPAD_GET(quic_sni) @@ -238,6 +242,7 @@ public: TPAD_SET(tls_host) TPAD_SET(tls_cname) TPAD_SET(tls_org_unit) + TPAD_SET(tls_version) TPAD_SET(http_request_referer) TPAD_SET(ftp_command_user) TPAD_SET(quic_sni) diff --git a/src/network_inspectors/appid/tp_appid_utils.cc b/src/network_inspectors/appid/tp_appid_utils.cc index cd87f16ca..69d620f32 100644 --- a/src/network_inspectors/appid/tp_appid_utils.cc +++ b/src/network_inspectors/appid/tp_appid_utils.cc @@ -387,6 +387,16 @@ static inline void process_ssl(AppIdSession& asd, asd.tsession->set_tls_org_unit(field->c_str(), field->size()); } } + + if (asd.tsession->get_tls_version() == 0 and + (field = attribute_data.tls_version(false)) != nullptr) + { + asd.tsession->set_tls_version(field->c_str(), field->size(), change_bits); + if (reinspect_ssl_appid) + { + asd.scan_flags |= SCAN_SSL_VERSION_FLAG; + } + } } static inline void process_ftp_control(AppIdSession& asd, diff --git a/src/pub_sub/appid_events.h b/src/pub_sub/appid_events.h index 900073e64..d3ef38b5c 100644 --- a/src/pub_sub/appid_events.h +++ b/src/pub_sub/appid_events.h @@ -63,6 +63,7 @@ enum AppidChangeBit APPID_NETBIOS_NAME_BIT, APPID_NETBIOS_DOMAIN_BIT, APPID_DISCOVERY_FINISHED_BIT, + APPID_TLS_VERSION_BIT, APPID_MAX_BIT }; @@ -113,6 +114,8 @@ inline void change_bits_to_string(const AppidChangeBits& change_bits, std::strin --n? str.append("netbios-domain, ") : str.append("netbios-domain"); if (change_bits.test(APPID_DISCOVERY_FINISHED_BIT)) --n? str.append("finished, ") : str.append("finished"); + if (change_bits.test(APPID_TLS_VERSION_BIT)) + --n? str.append("tls-version, ") : str.append("tls-version"); if (n != 0) // make sure all bits from AppidChangeBit enum get translated str.append("change_bits_to_string error!"); } -- 2.47.3