From: Shravan Rangarajuvenkata (shrarang) Date: Thu, 10 Dec 2020 20:39:29 +0000 (+0000) Subject: Merge pull request #2657 in SNORT/snort3 from ~SATHIRKA/snort3:dhcp_fp_unified to... X-Git-Tag: 3.0.3-6~15 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=afe0a782b4ad4640f7dc66e111dfcc8f9d5555cb;p=thirdparty%2Fsnort3.git Merge pull request #2657 in SNORT/snort3 from ~SATHIRKA/snort3:dhcp_fp_unified to master Squashed commit of the following: commit d37742db24cf3a3aae8e30d0df0a310347911d97 Author: Sreeja Athirkandathil Narayanan Date: Thu Dec 3 12:58:16 2020 -0500 rna: Use service ip and port provided by appid for DHCP discovery events --- diff --git a/src/network_inspectors/appid/appid_app_descriptor.h b/src/network_inspectors/appid/appid_app_descriptor.h index 89b5d2701..3124435ce 100644 --- a/src/network_inspectors/appid/appid_app_descriptor.h +++ b/src/network_inspectors/appid/appid_app_descriptor.h @@ -103,7 +103,11 @@ struct AppIdServiceSubtype class ServiceAppDescriptor : public ApplicationDescriptor { public: - ServiceAppDescriptor() = default; + ServiceAppDescriptor() + { + service_ip.clear(); + } + ~ServiceAppDescriptor() override { AppIdServiceSubtype* tmp_subtype = subtype; @@ -130,6 +134,9 @@ public: delete tmp_subtype; tmp_subtype = subtype; } + service_ip.clear(); + service_port = 0; + service_group = DAQ_PKTHDR_UNKNOWN; } void update_stats(AppId id, bool increment = true) override; @@ -175,12 +182,50 @@ public: return subtype; } + void set_service_ip(const snort::SfIp& ip) + { + service_ip = ip; + } + + const snort::SfIp& get_service_ip() const + { + return service_ip; + } + + bool is_service_ip_set() const + { + return service_ip.is_set(); + } + + void set_service_port(uint16_t port) + { + service_port = port; + } + + uint16_t get_service_port() const + { + return service_port; + } + + void set_service_group(int16_t group) + { + service_group = group; + } + + int16_t get_service_group() const + { + return service_group; + } + private: AppId port_service_id = APP_ID_NONE; bool deferred = false; using ApplicationDescriptor::set_id; std::string my_vendor; AppIdServiceSubtype* subtype = nullptr; + snort::SfIp service_ip; + uint16_t service_port = 0; + int16_t service_group = DAQ_PKTHDR_UNKNOWN; }; class ClientAppDescriptor : public ApplicationDescriptor diff --git a/src/network_inspectors/appid/appid_discovery.cc b/src/network_inspectors/appid/appid_discovery.cc index b6c4caef0..0a53fc23d 100644 --- a/src/network_inspectors/appid/appid_discovery.cc +++ b/src/network_inspectors/appid/appid_discovery.cc @@ -501,7 +501,7 @@ bool AppIdDiscovery::do_pre_discovery(Packet* p, AppIdSession*& asd, AppIdInspec asd->set_session_flags(APPID_SESSION_SYN_RST); if (asd->is_service_ip_set()) - std::tie(ip, port, group) = asd->get_service_info(); + std::tie(ip, port, group) = asd->get_server_info(); else { ip = p->ptrs.ip_api.get_src(); diff --git a/src/network_inspectors/appid/appid_session.cc b/src/network_inspectors/appid/appid_session.cc index bd1c4561e..ba1b793c0 100644 --- a/src/network_inspectors/appid/appid_session.cc +++ b/src/network_inspectors/appid/appid_session.cc @@ -101,8 +101,6 @@ AppIdSession::AppIdSession(IpProtocol proto, const SfIp* ip, uint16_t port, odp_ctxt_version(odp_ctxt.get_version()), tp_appid_ctxt(pkt_thread_tp_appid_ctxt) { - service_ip.clear(); - appid_stats.total_sessions++; } @@ -118,12 +116,13 @@ AppIdSession::~AppIdSession() APPID_SESSION_UDP_REVERSED | APPID_SESSION_MID | APPID_SESSION_OOO) and flow) { + const SfIp& svc_ip = api.service.get_service_ip(); ServiceDiscoveryState* sds = - AppIdServiceState::get(&service_ip, protocol, service_port, service_group, - asid, is_decrypted()); + AppIdServiceState::get(&svc_ip, protocol, api.service.get_service_port(), + api.service.get_service_group(), asid, is_decrypted()); if (sds) { - if (flow->server_ip.fast_eq6(service_ip)) + if (flow->server_ip.fast_eq6(svc_ip)) sds->set_service_id_failed(*this, &flow->client_ip, STATE_ID_INCONCLUSIVE_SERVICE_WEIGHT); else @@ -281,8 +280,6 @@ void AppIdSession::reinit_session_data(AppidChangeBits& change_bits, { api.service.reset(); tp_app_id = APP_ID_NONE; - service_ip.clear(); - service_port = 0; service_disco_state = APPID_DISCO_STATE_NONE; service_detector = nullptr; service_search_state = SESSION_SERVICE_SEARCH_STATE::START; @@ -420,8 +417,6 @@ void AppIdSession::check_tunnel_detection_restart() api.service.set_id(APP_ID_NONE, odp_ctxt); api.service.set_port_service_id(APP_ID_NONE); api.service.reset(); - service_ip.clear(); - service_port = 0; service_disco_state = APPID_DISCO_STATE_NONE; service_detector = nullptr; free_flow_data_by_mask(APPID_SESSION_DATA_SERVICE_MODSTATE_BIT); @@ -720,7 +715,7 @@ int AppIdSession::add_flow_data_id(uint16_t port, ServiceDetector* service) if (service_detector) return -1; service_detector = service; - service_port = port; + set_service_port(port); return 0; } @@ -728,13 +723,13 @@ void AppIdSession::stop_service_inspection(Packet* p, AppidSessionDirection dire { if (direction == APP_ID_FROM_INITIATOR) { - service_ip = *p->ptrs.ip_api.get_dst(); - service_port = p->ptrs.dp; + set_service_ip(*p->ptrs.ip_api.get_dst()); + set_service_port(p->ptrs.dp); } else { - service_ip = *p->ptrs.ip_api.get_src(); - service_port = p->ptrs.sp; + set_service_ip(*p->ptrs.ip_api.get_src()); + set_service_port(p->ptrs.sp); } service_disco_state = APPID_DISCO_STATE_FINISHED; diff --git a/src/network_inspectors/appid/appid_session.h b/src/network_inspectors/appid/appid_session.h index f55d6f134..4e4fd5344 100644 --- a/src/network_inspectors/appid/appid_session.h +++ b/src/network_inspectors/appid/appid_session.h @@ -546,6 +546,16 @@ public: api.initiator_ip = ip; } + void set_service_ip(const snort::SfIp& ip) + { + api.service.set_service_ip(ip); + } + + void set_service_port(uint16_t port) + { + api.service.set_service_port(port); + } + void set_tls_host(const AppidChangeBits& change_bits) { if (tsession and change_bits[APPID_TLSHOST_BIT]) @@ -567,26 +577,27 @@ public: return tp_appid_ctxt; } - void set_service_info(const snort::SfIp& ip, uint16_t port, int16_t group = DAQ_PKTHDR_UNKNOWN) + void set_server_info(const snort::SfIp& ip, uint16_t port, int16_t group = DAQ_PKTHDR_UNKNOWN) { - service_ip = ip; - service_port = port; - service_group = group; + api.service.set_service_ip(ip); + api.service.set_service_port(port); + api.service.set_service_group(group); } - std::tuple get_service_info() const + std::tuple get_server_info() const { - return std::make_tuple(&service_ip, service_port, service_group); + return std::make_tuple(&api.service.get_service_ip(), api.service.get_service_port(), + api.service.get_service_group()); } uint16_t get_service_port() const { - return service_port; + return api.service.get_service_port(); } bool is_service_ip_set() const { - return service_ip.is_set(); + return api.service.is_service_ip_set(); } void set_user_logged_in() @@ -612,10 +623,6 @@ private: AppId tp_app_id = APP_ID_NONE; AppId tp_payload_app_id = APP_ID_NONE; - snort::SfIp service_ip; - uint16_t service_port = 0; - int16_t service_group = DAQ_PKTHDR_UNKNOWN; - uint16_t my_inferred_svcs_ver = 0; snort::AppIdSessionApi& api; static uint16_t inferred_svcs_ver; diff --git a/src/network_inspectors/appid/appid_session_api.cc b/src/network_inspectors/appid/appid_session_api.cc index bf3593d14..aed49b888 100644 --- a/src/network_inspectors/appid/appid_session_api.cc +++ b/src/network_inspectors/appid/appid_session_api.cc @@ -280,6 +280,16 @@ const SfIp* AppIdSessionApi::get_initiator_ip() const return &initiator_ip; } +const SfIp& AppIdSessionApi::get_service_ip() const +{ + return service.get_service_ip(); +} + +uint16_t AppIdSessionApi::get_service_port() const +{ + return service.get_service_port(); +} + const AppIdDnsSession* AppIdSessionApi::get_dns_session() const { return dsession; diff --git a/src/network_inspectors/appid/appid_session_api.h b/src/network_inspectors/appid/appid_session_api.h index 0e896a666..19a800bf4 100644 --- a/src/network_inspectors/appid/appid_session_api.h +++ b/src/network_inspectors/appid/appid_session_api.h @@ -120,6 +120,8 @@ public: const char* get_client_info(uint32_t stream_index = 0) const; uint64_t get_appid_session_attribute(uint64_t flag) const; const SfIp* get_initiator_ip() const; + const SfIp& get_service_ip() const; + uint16_t get_service_port() const; const AppIdDnsSession* get_dns_session() const; const AppIdHttpSession* get_http_session(uint32_t stream_index = 0) const; const char* get_tls_host() const; diff --git a/src/network_inspectors/appid/service_plugins/service_detector.cc b/src/network_inspectors/appid/service_plugins/service_detector.cc index b697c8cd8..547c9efcf 100644 --- a/src/network_inspectors/appid/service_plugins/service_detector.cc +++ b/src/network_inspectors/appid/service_plugins/service_detector.cc @@ -73,7 +73,7 @@ int ServiceDetector::service_inprocess(AppIdSession& asd, const Packet* pkt, App if (!asd.is_service_ip_set()) { uint16_t port = asd.get_service_port(); - asd.set_service_info(*(pkt->ptrs.ip_api.get_src()), + asd.set_server_info(*(pkt->ptrs.ip_api.get_src()), port ? port : pkt->ptrs.sp, pkt->get_ingress_group()); } return APPID_SUCCESS; @@ -131,7 +131,7 @@ int ServiceDetector::update_service_data(AppIdSession& asd, const Packet* pkt, } } - asd.set_service_info(*ip, port, group); + asd.set_server_info(*ip, port, group); ServiceDiscoveryState* sds = AppIdServiceState::add(ip, asd.protocol, port, group, asd.asid, asd.is_decrypted()); diff --git a/src/network_inspectors/appid/service_plugins/service_discovery.cc b/src/network_inspectors/appid/service_plugins/service_discovery.cc index 8a8030a71..d8f10d118 100644 --- a/src/network_inspectors/appid/service_plugins/service_discovery.cc +++ b/src/network_inspectors/appid/service_plugins/service_discovery.cc @@ -403,7 +403,7 @@ int ServiceDiscovery::identify_service(AppIdSession& asd, Packet* p, /* Get packet info. */ auto proto = asd.protocol; if ( asd.is_service_ip_set() ) - std::tie(ip, port, group) = asd.get_service_info(); + std::tie(ip, port, group) = asd.get_server_info(); else { if ( dir == APP_ID_FROM_RESPONDER ) @@ -418,7 +418,7 @@ int ServiceDiscovery::identify_service(AppIdSession& asd, Packet* p, port = p->ptrs.dp; group = p->get_egress_group(); } - asd.set_service_info(*ip, port, group); + asd.set_server_info(*ip, port, group); } if ( asd.service_search_state == SESSION_SERVICE_SEARCH_STATE::START ) @@ -766,7 +766,7 @@ int ServiceDiscovery::incompatible_data(AppIdSession& asd, const Packet* pkt, Ap sds->set_service(service); sds->set_reset_time(0); if ( !asd.is_service_ip_set() ) - asd.set_service_info(*ip, port, group); + asd.set_server_info(*ip, port, group); return APPID_SUCCESS; } @@ -808,7 +808,7 @@ int ServiceDiscovery::fail_service(AppIdSession& asd, const Packet* pkt, AppidSe port = pkt->ptrs.sp; if (!asd.is_service_ip_set()) - asd.set_service_info(*ip, port, group); + asd.set_server_info(*ip, port, group); if ( !sds ) { diff --git a/src/network_inspectors/appid/test/appid_mock_session.h b/src/network_inspectors/appid/test/appid_mock_session.h index f2be49fb9..b5cdc4076 100644 --- a/src/network_inspectors/appid/test/appid_mock_session.h +++ b/src/network_inspectors/appid/test/appid_mock_session.h @@ -84,7 +84,7 @@ AppIdSession::AppIdSession(IpProtocol proto, const SfIp* ip, uint16_t, AppIdInsp protocol(proto), api(*(new AppIdSessionApi(this, *ip))), odp_ctxt(stub_odp_ctxt) { odp_ctxt_version = odp_ctxt.get_version(); - service_port = APPID_UT_SERVICE_PORT; + set_service_port(APPID_UT_SERVICE_PORT); AppidChangeBits change_bits; set_client_user(APPID_UT_ID, APPID_UT_USERNAME, change_bits); @@ -96,7 +96,9 @@ AppIdSession::AppIdSession(IpProtocol proto, const SfIp* ip, uint16_t, AppIdInsp tsession = new TlsSession; - service_ip.pton(AF_INET, APPID_UT_SERVICE_IP_ADDR); + SfIp svc_ip; + svc_ip.pton(AF_INET, APPID_UT_SERVICE_IP_ADDR); + set_service_ip(svc_ip); api.initiator_ip.pton(AF_INET, APPID_UT_INITIATOR_IP_ADDR); netbios_name = snort_strdup(APPID_UT_NETBIOS_NAME); diff --git a/src/network_inspectors/appid/tp_appid_utils.cc b/src/network_inspectors/appid/tp_appid_utils.cc index 3b13cb2d1..8640ca368 100644 --- a/src/network_inspectors/appid/tp_appid_utils.cc +++ b/src/network_inspectors/appid/tp_appid_utils.cc @@ -754,10 +754,10 @@ bool do_tp_discovery(ThirdPartyAppIdContext& tp_appid_ctxt, AppIdSession& asd, I APPID_SESSION_SERVICE_DETECTED); asd.clear_session_flags(APPID_SESSION_CONTINUE); if (direction == APP_ID_FROM_INITIATOR) - asd.set_service_info(*(p->ptrs.ip_api.get_dst()), p->ptrs.dp, + asd.set_server_info(*(p->ptrs.ip_api.get_dst()), p->ptrs.dp, p->get_egress_group()); else - asd.set_service_info(*(p->ptrs.ip_api.get_src()), p->ptrs.sp, + asd.set_server_info(*(p->ptrs.ip_api.get_src()), p->ptrs.sp, p->get_ingress_group()); } } diff --git a/src/network_inspectors/rna/rna_app_discovery.cc b/src/network_inspectors/rna/rna_app_discovery.cc index 7a72a6b53..70e55160e 100644 --- a/src/network_inspectors/rna/rna_app_discovery.cc +++ b/src/network_inspectors/rna/rna_app_discovery.cc @@ -70,6 +70,8 @@ void RnaAppDiscovery::process(AppidEvent* appid_event, DiscoveryFilter& filter, const auto& appid_session_api = appid_event->get_appid_session_api(); AppId service = appid_session_api.get_service_app_id(); bool newservice = false; + bool is_client = false; + uint16_t port = p->flow->server_port; if ( appid_change_bits[APPID_SERVICE_BIT] or appid_change_bits[APPID_CLIENT_BIT] or appid_change_bits[APPID_PAYLOAD_BIT] ) @@ -78,8 +80,17 @@ void RnaAppDiscovery::process(AppidEvent* appid_event, DiscoveryFilter& filter, appid_session_api.get_app_id(nullptr, &client, &payload, nullptr, nullptr); if ( appid_change_bits[APPID_SERVICE_BIT] and service > APP_ID_NONE ) + { + if (service == APP_ID_DHCP) + { + const SfIp& service_ip = appid_session_api.get_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, - p->flow->server_port, service); + port, service, is_client); + } if ( appid_change_bits[APPID_CLIENT_BIT] and client > APP_ID_NONE and service > APP_ID_NONE ) @@ -101,12 +112,12 @@ 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, vendor, version, logger, conf, service); + update_service_info(p, 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, nullptr, nullptr, logger, conf, service); + update_service_info(p, rna_flow, proto, port, nullptr, nullptr, logger, conf, service, is_client); } if ( conf->enable_banner_grab and p->is_from_server() and @@ -150,9 +161,17 @@ void RnaAppDiscovery::process(AppidEvent* appid_event, DiscoveryFilter& filter, } bool RnaAppDiscovery::discover_service(const Packet* p, RNAFlow* rna_flow, IpProtocol proto, - RnaConfig* conf, RnaLogger& logger, uint16_t port, AppId service) + RnaConfig* conf, RnaLogger& logger, uint16_t port, AppId service, bool is_client) { - RnaTracker htp = get_server_rna_tracker(p, rna_flow); + RnaTracker htp; + SfIp ip = p->flow->server_ip; + if (!is_client) + htp = get_server_rna_tracker(p, rna_flow); + else + { + htp = get_client_rna_tracker(p, rna_flow); + ip = p->flow->client_ip; + } if ( !htp or !htp->is_visible() ) return false; @@ -170,12 +189,10 @@ bool RnaAppDiscovery::discover_service(const Packet* p, RNAFlow* rna_flow, IpPro { if ( proto == IpProtocol::TCP ) logger.log(RNA_EVENT_NEW, NEW_TCP_SERVICE, p, &htp, - (const struct in6_addr*) p->flow->server_ip.get_ip6_ptr(), - htp->get_last_seen_mac(), &ha); + (const struct in6_addr*) ip.get_ip6_ptr(), htp->get_last_seen_mac(), &ha); else logger.log(RNA_EVENT_NEW, NEW_UDP_SERVICE, p, &htp, - (const struct in6_addr*) p->flow->server_ip.get_ip6_ptr(), - htp->get_last_seen_mac(), &ha); + (const struct in6_addr*) ip.get_ip6_ptr(), htp->get_last_seen_mac(), &ha); ha.hits = 0; // hit count is reset after logs are written htp->update_service(ha); @@ -239,16 +256,25 @@ 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, - const char* vendor, const char* version, RnaLogger& logger, RnaConfig* conf, AppId service) +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) { - RnaTracker htp = get_server_rna_tracker(p, rna_flow); + RnaTracker htp; + SfIp ip = p->flow->server_ip; + if (!is_client) + htp = get_server_rna_tracker(p, rna_flow); + else + { + htp = get_client_rna_tracker(p, rna_flow); + ip = p->flow->client_ip; + } + if ( !htp or !htp->is_visible() ) return; htp->update_last_seen(); - HostApplication ha(p->flow->server_port, proto, service, false); + HostApplication ha(port, proto, service, false); if ( !htp->update_service_info(ha, vendor, version, conf->max_host_service_info) ) return; @@ -257,12 +283,10 @@ void RnaAppDiscovery::update_service_info(const Packet* p, RNAFlow* rna_flow, Ip if ( proto == IpProtocol::TCP ) logger.log(RNA_EVENT_CHANGE, CHANGE_TCP_SERVICE_INFO, p, &htp, - (const struct in6_addr*) p->flow->server_ip.get_ip6_ptr(), htp->get_last_seen_mac(), - &ha); + (const struct in6_addr*) ip.get_ip6_ptr(), htp->get_last_seen_mac(), &ha); else logger.log(RNA_EVENT_CHANGE, CHANGE_UDP_SERVICE_INFO, p, &htp, - (const struct in6_addr*) p->flow->server_ip.get_ip6_ptr(), htp->get_last_seen_mac(), - &ha); + (const struct in6_addr*) ip.get_ip6_ptr(), htp->get_last_seen_mac(), &ha); ha.hits = 0; htp->update_service(ha); diff --git a/src/network_inspectors/rna/rna_app_discovery.h b/src/network_inspectors/rna/rna_app_discovery.h index 7ae0dc9fc..b9b18e4d1 100644 --- a/src/network_inspectors/rna/rna_app_discovery.h +++ b/src/network_inspectors/rna/rna_app_discovery.h @@ -29,7 +29,7 @@ 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); + 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); @@ -42,8 +42,8 @@ public: static void discover_banner(const snort::Packet*, RNAFlow*, IpProtocol, RnaLogger&, AppId); private: - static void update_service_info(const snort::Packet*, RNAFlow*, IpProtocol, - const char* vendor, const char* version, RnaLogger&, RnaConfig*, AppId service); + 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 analyze_user_agent_fingerprint(const snort::Packet*, RNAFlow*, const char* host, const char* uagent, RnaLogger&, snort::UaFpProcessor&);