From: Bhumika Sachdeva (bsachdev) Date: Tue, 25 Feb 2025 17:37:00 +0000 (+0000) Subject: Pull request #4632: appid: fixed functionality for domain fronting for shadow traffic X-Git-Tag: 3.7.1.0~13 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d3a191579131d23a52285815cf30d408261e291f;p=thirdparty%2Fsnort3.git Pull request #4632: appid: fixed functionality for domain fronting for shadow traffic Merge in SNORT/snort3 from ~BSACHDEV/snort3:domain_fronting_more_changes to master Squashed commit of the following: commit d627b1cb893d5a0ab4bfeff381c5062b9196b69e Author: bsachdev Date: Fri Feb 21 15:20:58 2025 -0500 appid: fixed functionality for domain fronting for shadow traffic --- diff --git a/src/network_inspectors/appid/appid_api.cc b/src/network_inspectors/appid/appid_api.cc index b485df4c3..eadd2b00f 100644 --- a/src/network_inspectors/appid/appid_api.cc +++ b/src/network_inspectors/appid/appid_api.cc @@ -302,19 +302,6 @@ void AppIdApi::update_shadow_traffic_status(bool status) void AppIdApi::set_ssl_certificate_key(const Flow& flow, const std::string& cert_key) { AppIdSession* asd = get_appid_session(flow); - if (asd != nullptr and !cert_key.empty()) + if (asd != nullptr and asd->get_odp_ctxt().get_appid_shadow_traffic_status() and !cert_key.empty()) asd->set_cert_key(cert_key); } - -void AppIdApi::ssl_hostname_cert_lookup_verdict(const snort::Flow &flow, DomainFrontingStatus status) -{ - AppIdSession* asd = get_appid_session(flow); - if (asd != nullptr and status == DomainFrontingStatus::MISMATCH) - { - uint32_t shadow_bits = asd->get_shadow_traffic_bits(); - shadow_bits |= ShadowTraffic_Type_Domain_Fronting; - asd->set_shadow_traffic_bits(shadow_bits); - AppId payload_id = asd->get_api().get_payload_app_id(); - asd->set_shadow_traffic_publishing_appid(payload_id); - } -} diff --git a/src/network_inspectors/appid/appid_api.h b/src/network_inspectors/appid/appid_api.h index f9d585759..310687007 100644 --- a/src/network_inspectors/appid/appid_api.h +++ b/src/network_inspectors/appid/appid_api.h @@ -57,7 +57,6 @@ public: void reset_appid_cpu_profiler_stats(); void update_shadow_traffic_status(bool status); void set_ssl_certificate_key(const Flow& flow, const std::string& cert_key); - void ssl_hostname_cert_lookup_verdict(const snort::Flow &flow, DomainFrontingStatus status); bool is_service_http_type(AppId service_id) const { diff --git a/src/network_inspectors/appid/appid_session.cc b/src/network_inspectors/appid/appid_session.cc index ae3db22f7..17b281fa0 100644 --- a/src/network_inspectors/appid/appid_session.cc +++ b/src/network_inspectors/appid/appid_session.cc @@ -160,12 +160,8 @@ AppIdSession::~AppIdSession() if ((pkt_thread_odp_ctxt->get_version() == api.asd->get_odp_ctxt_version()) and api.asd->get_odp_ctxt().get_appid_shadow_traffic_status()) { check_domain_fronting_status(); - - if (get_shadow_traffic_publishing_appid() > APP_ID_NONE) - { - if (api.asd->appid_shadow_traffic_bits != 0) - api.asd->publish_shadow_traffic_event(api.asd->appid_shadow_traffic_bits, api.asd->flow); - } + if (api.asd->appid_shadow_traffic_bits != 0) + api.asd->publish_shadow_traffic_event(api.asd->appid_shadow_traffic_bits, api.asd->flow); } if (!in_expected_cache) @@ -1222,7 +1218,7 @@ void AppIdSession::publish_shadow_traffic_event(const uint32_t &shadow_traffic_b app_name = api.asd->get_odp_ctxt().get_app_info_mgr().get_app_name(publishing_appid); if (app_name == nullptr) { - APPID_LOG(nullptr, TRACE_ERROR_LEVEL, "Appname is invalid, not publishing shadow traffic event without appname\n"); + APPID_LOG(CURRENT_PACKET, TRACE_DEBUG_LEVEL,"Appname is invalid, not publishing shadow traffic event without appname\n"); return; } @@ -1361,15 +1357,22 @@ void AppIdSession::check_domain_fronting_status() if (api.asd->get_session_flags(APPID_SESSION_DECRYPTED) or api.asd->get_session_flags(APPID_SESSION_APP_REINSPECT)) { AppIdHttpSession* hsession = api.asd->get_http_session(); - Packet* p = DetectionEngine::get_current_packet(); if (hsession) - { - const char* host = hsession->get_cfield(REQ_HOST_FID); - if (host) + { + const std::string* host = hsession->get_field(REQ_HOST_FID); + if (host) { - TLSDomainFrontCheckEvent domain_front_event(p, api.asd->get_cert_key(), host); - DataBus::publish(AppIdInspector::get_pub_id(), AppIdEventIds::DOMAIN_FRONTING, domain_front_event, p->flow); - } + TLSDomainFrontCheckEvent domain_front_event(api.asd->get_cert_key(), *host); + DataBus::publish(AppIdInspector::get_pub_id(), AppIdEventIds::DOMAIN_FRONTING, domain_front_event); + if (DomainFrontingStatus::MISMATCH == domain_front_event.get_cert_lookup_verdict()) + { + uint32_t shadow_bits = get_shadow_traffic_bits(); + shadow_bits |= ShadowTraffic_Type_Domain_Fronting; + set_shadow_traffic_bits(shadow_bits); + AppId payload_id = api.asd->get_api().get_payload_app_id(); + set_shadow_traffic_publishing_appid(payload_id); + } + } } } } diff --git a/src/network_inspectors/appid/test/appid_api_test.cc b/src/network_inspectors/appid/test/appid_api_test.cc index b45e57c65..da27f3221 100644 --- a/src/network_inspectors/appid/test/appid_api_test.cc +++ b/src/network_inspectors/appid/test/appid_api_test.cc @@ -277,32 +277,6 @@ TEST(appid_api, set_ssl_certificate_key) delete &asd.get_api(); } -TEST(appid_api, ssl_hostname_cert_lookup_verdict) -{ - AppIdConfig config; - OdpContext odpctxt(config, nullptr); - SfIp ip{}; - AppIdSession asd(IpProtocol::TCP, &ip, 1492, dummy_appid_inspector, odpctxt, 0 -#ifndef DISABLE_TENANT_ID - ,0 -#endif - ); - AppidChangeBits change_bits; - asd.set_ss_application_ids(APPID_UT_ID, APPID_UT_ID, APPID_UT_ID, - APPID_UT_ID, APPID_UT_ID, change_bits); - DomainFrontingStatus status = DomainFrontingStatus::MISMATCH; - appid_api.ssl_hostname_cert_lookup_verdict(*flow, status); - - AppId id = asd.get_api().get_payload_app_id(); - asd.set_shadow_traffic_publishing_appid(id); - CHECK_EQUAL(asd.get_shadow_traffic_publishing_appid(), APPID_UT_ID); - - uint32_t expected_shadow_bits = ShadowTraffic_Type_Domain_Fronting; - asd.set_shadow_traffic_bits(expected_shadow_bits); - CHECK_EQUAL(asd.get_shadow_traffic_bits(), expected_shadow_bits); - delete &asd.get_api(); -} - TEST(appid_api, ssl_app_group_id_lookup) { mock().expectNCalls(7, "publish"); diff --git a/src/pub_sub/domain_fronting.h b/src/pub_sub/domain_fronting.h index 3bb033afd..c0fb641d4 100644 --- a/src/pub_sub/domain_fronting.h +++ b/src/pub_sub/domain_fronting.h @@ -21,28 +21,33 @@ #define DOMAIN_FRONTING_H #include "framework/data_bus.h" +#include "pub_sub/appid_events.h" #include enum class DomainFrontingStatus { + UNDEFINED, MISMATCH, MATCHES, CERT_NOT_IN_CACHE }; -class TLSDomainFrontCheckEvent : public snort::DataEvent +class SO_PUBLIC TLSDomainFrontCheckEvent : public snort::DataEvent { public: - TLSDomainFrontCheckEvent(const snort::Packet& packet, const std::string& certificate_id, - const std::string& hostname): cert_id(certificate_id), hostname(hostname), pkt(&packet) {} + TLSDomainFrontCheckEvent(const std::string& certificate_id, + const std::string& hostname) + : cert_id(certificate_id), hostname(hostname) {} - const snort::Packet* get_packet() const override - { return pkt; } + const std::string& get_cert_id() { return cert_id; } + const std::string& get_hostname () { return hostname; } + void set_cert_lookup_verdict(DomainFrontingStatus status) { this->df_status = status; } + DomainFrontingStatus get_cert_lookup_verdict() const { return df_status; } private: - const std::string cert_id; - const std::string hostname; - const snort::Packet* pkt; + const std::string &cert_id; + const std::string &hostname; + DomainFrontingStatus df_status = DomainFrontingStatus::UNDEFINED; }; #endif