From: Masud Hasan (mashasan) Date: Thu, 7 Jan 2021 20:23:36 +0000 (+0000) Subject: Merge pull request #2684 in SNORT/snort3 from ~ARMANDAV/snort3:rnafilter to master X-Git-Tag: 3.1.0.0~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=209b58b9b18589facc55121035a86bd1a552e687;p=thirdparty%2Fsnort3.git Merge pull request #2684 in SNORT/snort3 from ~ARMANDAV/snort3:rnafilter to master Squashed commit of the following: commit f4e3ff89854a11ff6d1cf3acd9bb7f99c2445314 Author: Arun Mandava Date: Tue Dec 22 15:49:13 2020 -0500 rna: Perform appropriate filter check based on the event type --- diff --git a/src/helpers/discovery_filter.cc b/src/helpers/discovery_filter.cc index a3e3a3602..b8230ae0f 100644 --- a/src/helpers/discovery_filter.cc +++ b/src/helpers/discovery_filter.cc @@ -203,11 +203,12 @@ bool DiscoveryFilter::is_app_monitored(const Packet* p, uint8_t* flag) return is_monitored(p, DF_APP, *flag, DF_APP_CHECKED, DF_APP_MONITORED); } -bool DiscoveryFilter::is_host_monitored(const Packet* p, uint8_t* flag, const SfIp* ip) +bool DiscoveryFilter::is_host_monitored(const Packet* p, uint8_t* flag, const SfIp* ip, + FlowCheckDirection flowdir) { if ( flag == nullptr ) - return is_monitored(p, DF_HOST, ip); - return is_monitored(p, DF_HOST, *flag, DF_HOST_CHECKED, DF_HOST_MONITORED, ip); + return is_monitored(p, DF_HOST, ip, flowdir); + return is_monitored(p, DF_HOST, *flag, DF_HOST_CHECKED, DF_HOST_MONITORED, ip, flowdir); } bool DiscoveryFilter::is_user_monitored(const Packet* p, uint8_t* flag) @@ -218,14 +219,14 @@ bool DiscoveryFilter::is_user_monitored(const Packet* p, uint8_t* flag) } bool DiscoveryFilter::is_monitored(const Packet* p, FilterType type, uint8_t& flag, - uint8_t checked, uint8_t monitored, const SfIp* ip) + uint8_t checked, uint8_t monitored, const SfIp* ip, FlowCheckDirection flowdir) { if ( flag & checked ) return flag & monitored; flag |= checked; - if ( is_monitored(p, type, ip) ) + if ( is_monitored(p, type, ip, flowdir) ) { flag |= monitored; return true; @@ -235,7 +236,8 @@ bool DiscoveryFilter::is_monitored(const Packet* p, FilterType type, uint8_t& fl return false; } -bool DiscoveryFilter::is_monitored(const Packet* p, FilterType type, const SfIp* ip) +bool DiscoveryFilter::is_monitored(const Packet* p, FilterType type, const SfIp* ip, + FlowCheckDirection flowdir) { if ( !vartable ) return true; // when not configured, 'any' ip/port/interface are monitored by default @@ -245,20 +247,39 @@ bool DiscoveryFilter::is_monitored(const Packet* p, FilterType type, const SfIp* return false; // check interface - if (intf_ip_list[type].empty()) + if ( intf_ip_list[type].empty() ) return false; // the configuration did not have this type of rule - auto intf = (int32_t)p->pkth->ingress_index; + int32_t intf; + const SfIp* host_ip; + if ( flowdir == FlowCheckDirection::DF_SERVER ) + { + intf = (int32_t)p->flow->server_intf; + host_ip = &p->flow->server_ip; + } + else if ( flowdir == FlowCheckDirection::DF_CLIENT ) + { + intf = (int32_t)p->flow->client_intf; + host_ip = &p->flow->client_ip; + } + else + { + intf = (int32_t)p->pkth->ingress_index; + host_ip = p->ptrs.ip_api.get_src(); + } + if ( intf == DAQ_PKTHDR_UNKNOWN or intf < 0 ) intf = DF_ANY_INTF; + if ( ip ) + host_ip = ip; + auto varip = get_list(type, intf, true); - if (!varip and intf != DF_ANY_INTF) + if ( !varip and intf != DF_ANY_INTF ) varip = get_list(type, DF_ANY_INTF, true); - if (!p->ptrs.ip_api.get_src() and !ip) + if ( !host_ip ) return true; // Don't check for non-IP, non ARP - const SfIp* host_ip = (ip) ? ip : p->ptrs.ip_api.get_src(); return sfvar_ip_in(varip, host_ip); } diff --git a/src/helpers/discovery_filter.h b/src/helpers/discovery_filter.h index 0c1c2e9f0..0652d1d4a 100644 --- a/src/helpers/discovery_filter.h +++ b/src/helpers/discovery_filter.h @@ -28,6 +28,7 @@ #include "sfip/sf_vartable.h" enum FilterType { DF_APP, DF_HOST, DF_USER, DF_MAX }; +enum FlowCheckDirection { DF_NONE, DF_CLIENT, DF_SERVER }; typedef int32_t IntfType; // matching daq header #define DF_ANY_INTF INT32_MAX @@ -42,7 +43,7 @@ public: // If flag is provided (preferable), results are stored in flag to avoid future lookups bool is_app_monitored(const snort::Packet* p, uint8_t* flag = nullptr); bool is_host_monitored(const snort::Packet* p, uint8_t* flag = nullptr, - const snort::SfIp* ip = nullptr); + const snort::SfIp* ip = nullptr, FlowCheckDirection flowdir = FlowCheckDirection::DF_NONE); bool is_user_monitored(const snort::Packet* p, uint8_t* flag = nullptr); private: @@ -50,8 +51,10 @@ private: enum Direction { CLIENT, SERVER, NUM_DIRECTIONS }; bool is_monitored(const snort::Packet* p, FilterType type, uint8_t& flag, - uint8_t checked, uint8_t monitored, const snort::SfIp* ip = nullptr); - bool is_monitored(const snort::Packet* p, FilterType type, const snort::SfIp* ip = nullptr); + uint8_t checked, uint8_t monitored, const snort::SfIp* ip = nullptr, + FlowCheckDirection flowdir = FlowCheckDirection::DF_NONE); + bool is_monitored(const snort::Packet* p, FilterType type, const snort::SfIp* ip = nullptr, + FlowCheckDirection flowdir = FlowCheckDirection::DF_NONE); void add_ip(FilterType type, IntfType intf, std::string& ip); sfip_var_t* get_list(FilterType type, IntfType intf, bool exclude_empty = false); diff --git a/src/network_inspectors/rna/rna_app_discovery.cc b/src/network_inspectors/rna/rna_app_discovery.cc index e59949a7d..18151a49d 100644 --- a/src/network_inspectors/rna/rna_app_discovery.cc +++ b/src/network_inspectors/rna/rna_app_discovery.cc @@ -41,13 +41,13 @@ RnaTracker RnaAppDiscovery::get_client_rna_tracker(const Packet* p, RNAFlow*) return host_cache.find(p->flow->client_ip); } -void RnaAppDiscovery::process(AppidEvent* appid_event, DiscoveryFilter& filter, - RnaConfig* conf, RnaLogger& logger) +void RnaAppDiscovery::process(AppidEvent* appid_event, DiscoveryFilter& filter, RnaConfig* conf, + RnaLogger& logger) { const Packet* p = DetectionEngine::get_current_packet(); // Published appid events may be on rebuilt packets - if ( !p->flow or !filter.is_host_monitored(p) ) + if ( !p->flow ) return; IpProtocol proto; @@ -77,14 +77,14 @@ void RnaAppDiscovery::process(AppidEvent* appid_event, DiscoveryFilter& filter, if ( appid_change_bits[APPID_SERVICE_BIT] and service > APP_ID_NONE ) { - if (service == APP_ID_DHCP) + if ( service == APP_ID_DHCP ) { const SfIp& service_ip = appid_session_api.get_service_ip(); - if (p->flow->client_ip.fast_eq6(service_ip)) + if ( p->flow->client_ip.fast_eq6(service_ip) ) is_client = true; port = appid_session_api.get_service_port(); } - newservice = discover_service(p, rna_flow, proto, conf, logger, + newservice = discover_service(p, filter, rna_flow, proto, conf, logger, port, service, is_client); } @@ -92,13 +92,13 @@ void RnaAppDiscovery::process(AppidEvent* appid_event, DiscoveryFilter& filter, and service > APP_ID_NONE ) { const char* version = appid_session_api.get_client_info(); - discover_client(p, rna_flow, conf, logger, version, client, service); + discover_client(p, filter, rna_flow, conf, logger, version, client, service); } if ( appid_change_bits[APPID_PAYLOAD_BIT] and payload > APP_ID_NONE and service > APP_ID_NONE ) { - discover_payload(p, rna_flow, proto, conf, logger, service, payload, client); + discover_payload(p, filter, rna_flow, proto, conf, logger, service, payload, client); } } @@ -108,12 +108,14 @@ void RnaAppDiscovery::process(AppidEvent* appid_event, DiscoveryFilter& filter, const char* version; const AppIdServiceSubtype* subtype; appid_session_api.get_service_info(vendor, version, subtype); - update_service_info(p, rna_flow, proto, port, vendor, version, logger, conf, service, is_client); + update_service_info(p, filter, rna_flow, proto, port, vendor, version, logger, conf, + service, is_client); } else if ( newservice and appid_change_bits[APPID_SERVICE_BIT] and service > APP_ID_NONE ) { - update_service_info(p, rna_flow, proto, port, nullptr, nullptr, logger, conf, service, is_client); + update_service_info(p, filter, rna_flow, proto, port, nullptr, nullptr, logger, conf, + service, is_client); } if ( conf->enable_banner_grab and p->is_from_server() and @@ -121,7 +123,7 @@ void RnaAppDiscovery::process(AppidEvent* appid_event, DiscoveryFilter& filter, appid_change_bits[APPID_SERVICE_INFO_BIT] or appid_change_bits[APPID_SERVICE_BIT]) ) { - discover_banner(p, rna_flow, proto, logger, service); + discover_banner(p, filter, rna_flow, proto, logger, service); } // Appid supports login success/failure events, but not logoff event. @@ -130,7 +132,8 @@ void RnaAppDiscovery::process(AppidEvent* appid_event, DiscoveryFilter& filter, bool login_success; const char* username = appid_session_api.get_user_info(service, login_success); if ( service > APP_ID_NONE and username and *username ) - discover_user(p, rna_flow, logger, username, service, proto, conf, login_success); + discover_user(p, filter, rna_flow, logger, username, service, proto, conf, + login_success); } if ( p->is_from_client() and ( appid_change_bits[APPID_HOST_BIT] or appid_change_bits[APPID_USERAGENT_BIT] ) ) @@ -150,23 +153,32 @@ void RnaAppDiscovery::process(AppidEvent* appid_event, DiscoveryFilter& filter, { const char* host = hsession->get_cfield(REQ_HOST_FID); const char* uagent = hsession->get_cfield(REQ_AGENT_FID); - analyze_user_agent_fingerprint(p, rna_flow, host, uagent, logger, *processor); + analyze_user_agent_fingerprint(p, filter, rna_flow, host, uagent, logger, + *processor); } } } } -bool RnaAppDiscovery::discover_service(const Packet* p, RNAFlow* rna_flow, IpProtocol proto, - RnaConfig* conf, RnaLogger& logger, uint16_t port, AppId service, bool is_client) +bool RnaAppDiscovery::discover_service(const Packet* p, DiscoveryFilter& filter, RNAFlow* rna_flow, + IpProtocol proto, RnaConfig* conf, RnaLogger& logger, uint16_t port, AppId service, + bool is_client) { RnaTracker htp; SfIp ip = p->flow->server_ip; + if (!is_client) + { + if ( !filter.is_host_monitored(p, nullptr, nullptr, FlowCheckDirection::DF_SERVER) ) + return false; htp = get_server_rna_tracker(p, rna_flow); + } else { - htp = get_client_rna_tracker(p, rna_flow); + if ( !filter.is_host_monitored(p, nullptr, nullptr, FlowCheckDirection::DF_CLIENT) ) + return false; ip = p->flow->client_ip; + htp = get_client_rna_tracker(p, rna_flow); } if ( !htp or !htp->is_visible() ) @@ -196,8 +208,9 @@ bool RnaAppDiscovery::discover_service(const Packet* p, RNAFlow* rna_flow, IpPro return is_new; } -void RnaAppDiscovery::discover_payload(const Packet* p, RNAFlow* rna_flow, IpProtocol proto, - RnaConfig* conf, RnaLogger& logger, AppId service, AppId payload, AppId client) +void RnaAppDiscovery::discover_payload(const Packet* p, DiscoveryFilter& filter, RNAFlow* rna_flow, + IpProtocol proto, RnaConfig* conf, RnaLogger& logger, AppId service, AppId payload, + AppId client) { uint16_t lookup_port; size_t max_payloads = 0; @@ -218,6 +231,9 @@ void RnaAppDiscovery::discover_payload(const Packet* p, RNAFlow* rna_flow, IpPro // Add server payload if ( p->is_from_server() ) { + if ( !filter.is_host_monitored(p, nullptr, nullptr, FlowCheckDirection::DF_SERVER) ) + return; + HostApplication local_ha; bool new_pld = srt->add_payload(local_ha, lookup_port, proto, payload, service, max_payloads); @@ -236,6 +252,9 @@ void RnaAppDiscovery::discover_payload(const Packet* p, RNAFlow* rna_flow, IpPro } // Add client payloads + if ( !filter.is_host_monitored(p, nullptr, nullptr, FlowCheckDirection::DF_CLIENT) ) + return; + RnaTracker crt = get_client_rna_tracker(p, rna_flow); if ( !crt or !crt->is_visible() ) return; @@ -252,17 +271,24 @@ void RnaAppDiscovery::discover_payload(const Packet* p, RNAFlow* rna_flow, IpPro crt->get_last_seen_mac(), &hc); } -void RnaAppDiscovery::update_service_info(const Packet* p, RNAFlow* rna_flow, IpProtocol proto, uint16_t port, - const char* vendor, const char* version, RnaLogger& logger, RnaConfig* conf, AppId service, bool is_client) +void RnaAppDiscovery::update_service_info(const Packet* p, DiscoveryFilter& filter, + RNAFlow* rna_flow, IpProtocol proto, uint16_t port, const char* vendor, + const char* version, RnaLogger& logger, RnaConfig* conf, AppId service, bool is_client) { RnaTracker htp; SfIp ip = p->flow->server_ip; if (!is_client) + { + if ( !filter.is_host_monitored(p, nullptr, nullptr, FlowCheckDirection::DF_SERVER) ) + return; htp = get_server_rna_tracker(p, rna_flow); + } else { - htp = get_client_rna_tracker(p, rna_flow); + if ( !filter.is_host_monitored(p, nullptr, nullptr, FlowCheckDirection::DF_CLIENT) ) + return; ip = p->flow->client_ip; + htp = get_client_rna_tracker(p, rna_flow); } if ( !htp or !htp->is_visible() ) @@ -288,9 +314,12 @@ void RnaAppDiscovery::update_service_info(const Packet* p, RNAFlow* rna_flow, Ip htp->update_service(ha); } -void RnaAppDiscovery::discover_banner(const Packet* p, RNAFlow* rna_flow, IpProtocol proto, - RnaLogger& logger, AppId service) +void RnaAppDiscovery::discover_banner(const Packet* p, DiscoveryFilter& filter, RNAFlow* rna_flow, + IpProtocol proto, RnaLogger& logger, AppId service) { + if ( !filter.is_host_monitored(p, nullptr, nullptr, FlowCheckDirection::DF_SERVER) ) + return; + RnaTracker rt = get_server_rna_tracker(p, rna_flow); if ( !rt or !rt->is_visible() ) return; @@ -305,9 +334,12 @@ void RnaAppDiscovery::discover_banner(const Packet* p, RNAFlow* rna_flow, IpProt (const struct in6_addr*) p->flow->server_ip.get_ip6_ptr(), rt->get_last_seen_mac(), &ha); } -void RnaAppDiscovery::discover_client(const Packet* p, RNAFlow* rna_flow, RnaConfig* conf, - RnaLogger& logger, const char* version, AppId client, AppId service) +void RnaAppDiscovery::discover_client(const Packet* p, DiscoveryFilter& filter, RNAFlow* rna_flow, + RnaConfig* conf, RnaLogger& logger, const char* version, AppId client, AppId service) { + if ( !filter.is_host_monitored(p, nullptr, nullptr, FlowCheckDirection::DF_CLIENT) ) + return; + RnaTracker rt = get_client_rna_tracker(p, rna_flow); if ( !rt or !rt->is_visible() ) return; @@ -340,15 +372,24 @@ void RnaAppDiscovery::discover_client(const Packet* p, RNAFlow* rna_flow, RnaCon (const struct in6_addr*) p->flow->client_ip.get_ip6_ptr(), mac, &hc); } -void RnaAppDiscovery::discover_user(const Packet* p, RNAFlow* rna_flow, RnaLogger& logger, - const char* username, AppId service, IpProtocol proto, RnaConfig* conf, bool login_success) +void RnaAppDiscovery::discover_user(const Packet* p, DiscoveryFilter& filter, RNAFlow* rna_flow, + RnaLogger& logger, const char* username, AppId service, IpProtocol proto, RnaConfig* conf, + bool login_success) { RnaTracker rt; if ( p->is_from_server() ) + { + if ( !filter.is_host_monitored(p, nullptr, nullptr, FlowCheckDirection::DF_SERVER) ) + return; rt = get_server_rna_tracker(p, rna_flow); + } else + { + if ( !filter.is_host_monitored(p, nullptr, nullptr, FlowCheckDirection::DF_CLIENT) ) + return; rt = get_client_rna_tracker(p, rna_flow); - + } + if ( !rt or !rt->is_visible() ) return; rt->update_last_seen(); @@ -362,10 +403,12 @@ void RnaAppDiscovery::discover_user(const Packet* p, RNAFlow* rna_flow, RnaLogge } } -void RnaAppDiscovery::analyze_user_agent_fingerprint(const Packet* p, RNAFlow* rna_flow, - const char* host, const char* uagent, RnaLogger& logger, UaFpProcessor& processor) +void RnaAppDiscovery::analyze_user_agent_fingerprint(const Packet* p, DiscoveryFilter& filter, + RNAFlow* rna_flow, const char* host, const char* uagent, RnaLogger& logger, + UaFpProcessor& processor) { - if ( !host or !uagent ) + if ( !host or !uagent or + !filter.is_host_monitored(p, nullptr, nullptr, FlowCheckDirection::DF_CLIENT)) return; RnaTracker rt = get_client_rna_tracker(p, rna_flow); diff --git a/src/network_inspectors/rna/rna_app_discovery.h b/src/network_inspectors/rna/rna_app_discovery.h index b9b18e4d1..aa9e74139 100644 --- a/src/network_inspectors/rna/rna_app_discovery.h +++ b/src/network_inspectors/rna/rna_app_discovery.h @@ -28,25 +28,27 @@ class RnaAppDiscovery public: static void process(AppidEvent*, DiscoveryFilter&, RnaConfig*, RnaLogger&); - static bool discover_service(const snort::Packet*, RNAFlow*, IpProtocol, RnaConfig*, - RnaLogger&, uint16_t, AppId service = APP_ID_NONE, bool is_client = false); + static bool discover_service(const snort::Packet*, DiscoveryFilter&, RNAFlow*, IpProtocol, + RnaConfig*, RnaLogger&, uint16_t, AppId service = APP_ID_NONE, bool is_client = false); - static void discover_payload(const snort::Packet*, RNAFlow*, IpProtocol, RnaConfig*, - RnaLogger&, AppId service, AppId payload, AppId client); + static void discover_payload(const snort::Packet*, DiscoveryFilter&, RNAFlow*, IpProtocol, + RnaConfig*, RnaLogger&, AppId service, AppId payload, AppId client); - static void discover_client(const snort::Packet*, RNAFlow*, RnaConfig*, RnaLogger&, - const char*, AppId client, AppId service); + static void discover_client(const snort::Packet*, DiscoveryFilter&, RNAFlow*, RnaConfig*, + RnaLogger&, const char*, AppId client, AppId service); - static void discover_user(const snort::Packet*, RNAFlow*, RnaLogger&, const char*, - AppId, IpProtocol, RnaConfig*, bool); + static void discover_user(const snort::Packet*, DiscoveryFilter&, RNAFlow*, RnaLogger&, + const char*, AppId, IpProtocol, RnaConfig*, bool); - static void discover_banner(const snort::Packet*, RNAFlow*, IpProtocol, RnaLogger&, AppId); + static void discover_banner(const snort::Packet*, DiscoveryFilter&, RNAFlow*, IpProtocol, + RnaLogger&, AppId); private: - static void update_service_info(const snort::Packet*, RNAFlow*, IpProtocol, uint16_t, - const char* vendor, const char* version, RnaLogger&, RnaConfig*, AppId service, bool is_client = false); + static void update_service_info(const snort::Packet*, DiscoveryFilter&, RNAFlow*, IpProtocol, + uint16_t, const char* vendor, const char* version, RnaLogger&, RnaConfig*, AppId service, + bool is_client = false); - static void analyze_user_agent_fingerprint(const snort::Packet*, RNAFlow*, const char* host, - const char* uagent, RnaLogger&, snort::UaFpProcessor&); + static void analyze_user_agent_fingerprint(const snort::Packet*, DiscoveryFilter&, RNAFlow*, + const char* host, const char* uagent, RnaLogger&, snort::UaFpProcessor&); static RnaTracker get_server_rna_tracker(const snort::Packet*, RNAFlow*); static RnaTracker get_client_rna_tracker(const snort::Packet*, RNAFlow*);