From: Shravan Rangarajuvenkata (shrarang) Date: Tue, 13 Apr 2021 20:39:26 +0000 (+0000) Subject: Merge pull request #2836 in SNORT/snort3 from ~SHRARANG/snort3:appid_refactor_tp... X-Git-Tag: 3.1.4.0~12 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4c6948672261593e79df1daf4dc779f0b8bf31db;p=thirdparty%2Fsnort3.git Merge pull request #2836 in SNORT/snort3 from ~SHRARANG/snort3:appid_refactor_tp to master Squashed commit of the following: commit 826a256d28984cd56be15f6e93a95ef179be8eb9 Author: Shravan Rangaraju Date: Wed Apr 7 16:17:49 2021 -0400 appid: remove detectors which are available in odp commit 0e4d330ddcdfac8e0add3fcac0286034229d9271 Author: Shravan Rangaraju Date: Wed Apr 7 11:30:23 2021 -0400 appid: remove duplicate rtmp code commit a6d0a4b77c99662f65a67037a856bed547a1178a Author: Shravan Rangaraju Date: Wed Apr 7 10:41:22 2021 -0400 appid: refactor to set http scan flags in one place --- diff --git a/src/network_inspectors/appid/CMakeLists.txt b/src/network_inspectors/appid/CMakeLists.txt index eb725b67e..3e4d78d3b 100644 --- a/src/network_inspectors/appid/CMakeLists.txt +++ b/src/network_inspectors/appid/CMakeLists.txt @@ -41,8 +41,6 @@ set ( CP_APPID_SOURCES set ( SP_APPID_SOURCES service_plugins/dcerpc.cc service_plugins/dcerpc.h - service_plugins/service_battle_field.cc - service_plugins/service_battle_field.h service_plugins/service_bgp.cc service_plugins/service_bgp.h service_plugins/service_bit.cc @@ -53,8 +51,6 @@ set ( SP_APPID_SOURCES service_plugins/service_dcerpc.h service_plugins/service_detector.cc service_plugins/service_detector.h - service_plugins/service_direct_connect.cc - service_plugins/service_direct_connect.h service_plugins/service_discovery.cc service_plugins/service_discovery.h service_plugins/service_ftp.cc diff --git a/src/network_inspectors/appid/appid_http_event_handler.cc b/src/network_inspectors/appid/appid_http_event_handler.cc index 29549bfc6..efde26c26 100644 --- a/src/network_inspectors/appid/appid_http_event_handler.cc +++ b/src/network_inspectors/appid/appid_http_event_handler.cc @@ -114,25 +114,18 @@ void HttpEventHandler::handle(DataEvent& event, Flow* flow) { header_start = http_event->get_host(header_length); if (header_length > 0) - { hsession->set_field(REQ_HOST_FID, header_start, header_length, change_bits); - asd->scan_flags |= SCAN_HTTP_HOST_URL_FLAG; - } header_start = http_event->get_uri(header_length); if (header_length > 0) { hsession->set_field(REQ_URI_FID, header_start, header_length, change_bits); - asd->scan_flags |= SCAN_HTTP_URI_FLAG; hsession->update_url(change_bits); } header_start = http_event->get_user_agent(header_length); if (header_length > 0) - { hsession->set_field(REQ_AGENT_FID, header_start, header_length, change_bits); - asd->scan_flags |= SCAN_HTTP_USER_AGENT_FLAG; - } header_start = http_event->get_cookie(header_length); hsession->set_field(REQ_COOKIE_FID, header_start, header_length, change_bits); @@ -148,18 +141,13 @@ void HttpEventHandler::handle(DataEvent& event, Flow* flow) { header_start = http_event->get_content_type(header_length); if (header_length > 0) - { hsession->set_field(RSP_CONTENT_TYPE_FID, header_start, header_length, change_bits); - asd->scan_flags |= SCAN_HTTP_CONTENT_TYPE_FLAG; - } + header_start = http_event->get_location(header_length); hsession->set_field(RSP_LOCATION_FID, header_start, header_length, change_bits); header_start = http_event->get_server(header_length); if (header_length > 0) - { hsession->set_field(MISC_SERVER_FID, header_start, header_length, change_bits); - asd->scan_flags |= SCAN_HTTP_VENDOR_FLAG; - } int32_t responseCodeNum = http_event->get_response_code(); if (responseCodeNum > 0 && responseCodeNum < 700) @@ -179,18 +167,12 @@ void HttpEventHandler::handle(DataEvent& event, Flow* flow) header_start = http_event->get_x_working_with(header_length); if (header_length > 0) - { hsession->set_field(MISC_XWW_FID, header_start, header_length, change_bits); - asd->scan_flags |= SCAN_HTTP_XWORKINGWITH_FLAG; - } // The Via header can be in both the request and response. header_start = http_event->get_via(header_length); if (header_length > 0) - { hsession->set_field(MISC_VIA_FID, header_start, header_length, change_bits); - asd->scan_flags |= SCAN_HTTP_VIA_FLAG; - } if (http_event->get_is_http2()) { diff --git a/src/network_inspectors/appid/appid_http_session.cc b/src/network_inspectors/appid/appid_http_session.cc index 989b5e59b..def12f2f9 100644 --- a/src/network_inspectors/appid/appid_http_session.cc +++ b/src/network_inspectors/appid/appid_http_session.cc @@ -96,6 +96,37 @@ void AppIdHttpSession::set_http_change_bits(AppidChangeBits& change_bits, HttpFi } } +void AppIdHttpSession::set_scan_flags(HttpFieldIds id) +{ + switch (id) + { + case REQ_URI_FID: + asd.scan_flags |= SCAN_HTTP_URI_FLAG; + break; + case MISC_VIA_FID: + asd.scan_flags |= SCAN_HTTP_VIA_FLAG; + break; + case REQ_AGENT_FID: + asd.scan_flags |= SCAN_HTTP_USER_AGENT_FLAG; + break; + case RSP_CONTENT_TYPE_FID: + asd.scan_flags |= SCAN_HTTP_CONTENT_TYPE_FLAG; + break; + case MISC_SERVER_FID: + asd.scan_flags |= SCAN_HTTP_VENDOR_FLAG; + break; + case MISC_XWW_FID: + asd.scan_flags |= SCAN_HTTP_XWORKINGWITH_FLAG; + break; + case REQ_HOST_FID: + case MISC_URL_FID: + asd.scan_flags |= SCAN_HTTP_HOST_URL_FLAG; + break; + default: + break; + } +} + void AppIdHttpSession::set_tun_dest() { assert(meta_data[REQ_URI_FID]); @@ -747,6 +778,7 @@ void AppIdHttpSession::update_url(AppidChangeBits& change_bits) else meta_data[MISC_URL_FID] = new std::string(std::string("http://") + *host + *uri); change_bits.set(APPID_URL_BIT); + asd.scan_flags |= SCAN_HTTP_HOST_URL_FLAG; } } @@ -772,6 +804,7 @@ void AppIdHttpSession::set_field(HttpFieldIds id, const std::string* str, delete meta_data[id]; meta_data[id] = str; set_http_change_bits(change_bits, id); + set_scan_flags(id); if (appidDebug->is_active()) print_field(id, str); @@ -788,6 +821,7 @@ void AppIdHttpSession::set_field(HttpFieldIds id, const uint8_t* str, int32_t le delete meta_data[id]; meta_data[id] = new std::string((const char*)str, len); set_http_change_bits(change_bits, id); + set_scan_flags(id); if (appidDebug->is_active()) print_field(id, meta_data[id]); diff --git a/src/network_inspectors/appid/appid_http_session.h b/src/network_inspectors/appid/appid_http_session.h index 64ce1018a..f9abe6094 100644 --- a/src/network_inspectors/appid/appid_http_session.h +++ b/src/network_inspectors/appid/appid_http_session.h @@ -166,6 +166,7 @@ protected: void process_chp_buffers(AppidChangeBits&, HttpPatternMatchers&); void free_chp_matches(ChpMatchDescriptor& cmd, unsigned max_matches); void set_http_change_bits(AppidChangeBits& change_bits, HttpFieldIds id); + void set_scan_flags(HttpFieldIds id); void print_field(HttpFieldIds id, const std::string* str); AppIdSession& asd; diff --git a/src/network_inspectors/appid/appid_session.cc b/src/network_inspectors/appid/appid_session.cc index c7291f57e..511805338 100644 --- a/src/network_inspectors/appid/appid_session.cc +++ b/src/network_inspectors/appid/appid_session.cc @@ -568,6 +568,27 @@ void AppIdSession::examine_rtmp_metadata(AppidChangeBits& change_bits) if (!hsession) return; + const string* field; + if ((scan_flags & SCAN_HTTP_USER_AGENT_FLAG) and + hsession->client.get_id() <= APP_ID_NONE and + (field = hsession->get_field(REQ_AGENT_FID))) + { + char *version = nullptr; + HttpPatternMatchers& http_matchers = get_odp_ctxt().get_http_matchers(); + + http_matchers.identify_user_agent(field->c_str(), field->size(), service_id, + client_id, &version); + + hsession->set_client(client_id, change_bits, "User Agent", version); + + // do not overwrite a previously-set service + if ( api.service.get_id() <= APP_ID_NONE ) + set_service_appid_data(service_id, change_bits); + + scan_flags &= ~SCAN_HTTP_USER_AGENT_FLAG; + snort_free(version); + } + if (const char* url = hsession->get_cfield(MISC_URL_FID)) { HttpPatternMatchers& http_matchers = odp_ctxt.get_http_matchers(); diff --git a/src/network_inspectors/appid/service_plugins/service_battle_field.cc b/src/network_inspectors/appid/service_plugins/service_battle_field.cc deleted file mode 100644 index 5ca3c605a..000000000 --- a/src/network_inspectors/appid/service_plugins/service_battle_field.cc +++ /dev/null @@ -1,196 +0,0 @@ -//-------------------------------------------------------------------------- -// Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved. -// Copyright (C) 2005-2013 Sourcefire, Inc. -// -// This program is free software; you can redistribute it and/or modify it -// under the terms of the GNU General Public License Version 2 as published -// by the Free Software Foundation. You may not use, modify or distribute -// this program under any other version of the GNU General Public License. -// -// This program is distributed in the hope that it will be useful, but -// WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program; if not, write to the Free Software Foundation, Inc., -// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -//-------------------------------------------------------------------------- - -// service_battle_field.cc author Sourcefire Inc. - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "service_battle_field.h" - -#include "protocols/packet.h" - -enum CONNECTION_STATES -{ - CONN_STATE_INIT, - CONN_STATE_HELLO_DETECTED, - CONN_STATE_SERVICE_DETECTED, - CONN_STATE_MESSAGE_DETECTED, - CONN_STATE_MAX -}; - -static const unsigned MAX_PACKET_INSPECTION_COUNT = 10; - -struct ServiceData -{ - uint32_t state; - uint32_t messageId; - uint32_t packetCount; -}; - -static const char PATTERN_HELLO[] = "battlefield2\x00"; -static const char PATTERN_2[] = "\xfe\xfd"; -static const char PATTERN_3[] = "\x11\x20\x00\x01\x00\x00\x50\xb9\x10\x11"; -static const char PATTERN_4[] = "\x11\x20\x00\x01\x00\x00\x30\xb9\x10\x11"; -static const char PATTERN_5[] = "\x11\x20\x00\x01\x00\x00\xa0\x98\x00\x11"; -static const char PATTERN_6[] = "\xfe\xfd\x09\x00\x00\x00\x00"; - -BattleFieldServiceDetector::BattleFieldServiceDetector(ServiceDiscovery* sd) -{ - handler = sd; - name = "BattleField"; - proto = IpProtocol::TCP; - detectorType = DETECTOR_TYPE_DECODER; - - tcp_patterns = - { - { (const uint8_t*)PATTERN_HELLO, sizeof(PATTERN_HELLO) - 1, 5, 0, 0 }, - { (const uint8_t*)PATTERN_2, sizeof(PATTERN_2) - 1, 0, 0, 0 }, - { (const uint8_t*)PATTERN_3, sizeof(PATTERN_3) - 1, 0, 0, 0 }, - { (const uint8_t*)PATTERN_4, sizeof(PATTERN_4) - 1, 0, 0, 0 }, - { (const uint8_t*)PATTERN_5, sizeof(PATTERN_5) - 1, 0, 0, 0 }, - { (const uint8_t*)PATTERN_6, sizeof(PATTERN_6) - 1, 0, 0, 0 } - }; - - appid_registry = - { - { APP_ID_BATTLEFIELD, 0 } - }; - - service_ports = - { - { 4711, IpProtocol::TCP, false }, - { 16567, IpProtocol::UDP, false }, - { 27900, IpProtocol::UDP, false }, - { 27900, IpProtocol::TCP, false }, - { 29900, IpProtocol::UDP, false }, - { 29900, IpProtocol::TCP, false }, - { 27901, IpProtocol::TCP, false }, - { 28910, IpProtocol::UDP, false } - }; - - handler->register_detector(name, this, proto); -} - - -static inline uint32_t get_message_id(const uint8_t* msg) -{ - return (msg[2] << 8) | msg[3]; -} - -int BattleFieldServiceDetector::validate(AppIdDiscoveryArgs& args) -{ - ServiceData* fd; - - if (!args.size) - goto inprocess_nofd; - - fd = (ServiceData*)data_get(args.asd); - if (!fd) - { - fd = (ServiceData*)snort_calloc(sizeof(ServiceData)); - data_add(args.asd, fd, &snort_free); - } - - switch (fd->state) - { - case CONN_STATE_INIT: - if ((args.pkt->ptrs.sp >= 27000 || args.pkt->ptrs.dp >= 27000) && args.size >= 4) - { - if (args.data[0] == 0xfe && args.data[1] == 0xfd) - { - fd->messageId = get_message_id(args.data); - fd->state = CONN_STATE_MESSAGE_DETECTED; - goto inprocess; - } - } - - if (args.size == 18 && - memcmp(args.data + 5, PATTERN_HELLO, sizeof(PATTERN_HELLO) -1) == 0) - { - fd->state = CONN_STATE_HELLO_DETECTED; - goto inprocess; - } - break; - - case CONN_STATE_MESSAGE_DETECTED: - if (args.size > 8) - { - if ((uint32_t)(args.data[0] << 8 | args.data[1]) == fd->messageId) - { - goto success; - } - - if (args.data[0] == 0xfe && args.data[1] == 0xfd) - { - fd->messageId = get_message_id(args.data); - goto inprocess; - } - } - - fd->state = CONN_STATE_INIT; - goto inprocess; - break; - - case CONN_STATE_HELLO_DETECTED: - if ((args.size == 7) && (memcmp(args.data, PATTERN_6, sizeof(PATTERN_6) - 1) == 0)) - { - goto success; - } - - if ((args.size > 10) - && ((memcmp(args.data, PATTERN_3, sizeof(PATTERN_3) - 1) == 0) - || (memcmp(args.data, PATTERN_4, sizeof(PATTERN_4) - 1) == 0) - || (memcmp(args.data, PATTERN_5, sizeof(PATTERN_5) - 1) == 0))) - { - goto success; - } - break; - - case CONN_STATE_SERVICE_DETECTED: - goto success; - } - - fail_service(args.asd, args.pkt, args.dir); - return APPID_NOMATCH; - -inprocess: - fd->packetCount++; - if (fd->packetCount >= MAX_PACKET_INSPECTION_COUNT) - goto fail; - -inprocess_nofd: - service_inprocess(args.asd, args.pkt, args.dir); - return APPID_INPROCESS; - -success: - if (args.dir != APP_ID_FROM_RESPONDER) - { - fd->state = CONN_STATE_SERVICE_DETECTED; - goto inprocess; - } - - return add_service(args.change_bits, args.asd, args.pkt, args.dir, APP_ID_BATTLEFIELD); - -fail: - fail_service(args.asd, args.pkt, args.dir); - return APPID_NOMATCH; -} - diff --git a/src/network_inspectors/appid/service_plugins/service_battle_field.h b/src/network_inspectors/appid/service_plugins/service_battle_field.h deleted file mode 100644 index d10b82487..000000000 --- a/src/network_inspectors/appid/service_plugins/service_battle_field.h +++ /dev/null @@ -1,37 +0,0 @@ -//-------------------------------------------------------------------------- -// Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved. -// Copyright (C) 2005-2013 Sourcefire, Inc. -// -// This program is free software; you can redistribute it and/or modify it -// under the terms of the GNU General Public License Version 2 as published -// by the Free Software Foundation. You may not use, modify or distribute -// this program under any other version of the GNU General Public License. -// -// This program is distributed in the hope that it will be useful, but -// WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program; if not, write to the Free Software Foundation, Inc., -// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -//-------------------------------------------------------------------------- - -// service_battle_field.h author Sourcefire Inc. - -#ifndef SERVICE_BATTLEFIELD_H -#define SERVICE_BATTLEFIELD_H - -#include "service_detector.h" - -class ServiceDiscovery; - -class BattleFieldServiceDetector : public ServiceDetector -{ -public: - BattleFieldServiceDetector(ServiceDiscovery*); - - int validate(AppIdDiscoveryArgs&) override; -}; -#endif - diff --git a/src/network_inspectors/appid/service_plugins/service_direct_connect.cc b/src/network_inspectors/appid/service_plugins/service_direct_connect.cc deleted file mode 100644 index 5d05e3622..000000000 --- a/src/network_inspectors/appid/service_plugins/service_direct_connect.cc +++ /dev/null @@ -1,268 +0,0 @@ -//-------------------------------------------------------------------------- -// Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved. -// Copyright (C) 2005-2013 Sourcefire, Inc. -// -// This program is free software; you can redistribute it and/or modify it -// under the terms of the GNU General Public License Version 2 as published -// by the Free Software Foundation. You may not use, modify or distribute -// this program under any other version of the GNU General Public License. -// -// This program is distributed in the hope that it will be useful, but -// WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program; if not, write to the Free Software Foundation, Inc., -// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -//-------------------------------------------------------------------------- - -// service_direct_connect.cc author Sourcefire Inc. - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "service_direct_connect.h" - -using namespace snort; - -enum CONNECTION_STATES -{ - CONN_STATE_INIT, - CONN_STATE_1, - CONN_STATE_2, - CONN_STATE_SERVICE_DETECTED, - CONN_STATE_MAX -}; - -#define MAX_PACKET_INSPECTION_COUNT 10 - -struct ServiceData -{ - uint32_t state; - uint32_t packetCount; -}; - -#define PATTERN1 "$Lock " -#define PATTERN2 "$MyNick " -#define PATTERN3 "HSUP ADBAS0" -#define PATTERN4 "HSUP ADBASE" -#define PATTERN5 "CSUP ADBAS0" -#define PATTERN6 "CSUP ADBASE" -#define PATTERN7 "$SR " - -DirectConnectServiceDetector::DirectConnectServiceDetector(ServiceDiscovery* sd) -{ - handler = sd; - name = "DirectConnect"; - proto = IpProtocol::TCP; - detectorType = DETECTOR_TYPE_DECODER; - - tcp_patterns = - { - { (const uint8_t*)PATTERN1, sizeof(PATTERN1) - 1, 0, 0, 0 }, - { (const uint8_t*)PATTERN2, sizeof(PATTERN2) - 1, 0, 0, 0 }, - { (const uint8_t*)PATTERN3, sizeof(PATTERN3) - 1, 0, 0, 0 }, - { (const uint8_t*)PATTERN4, sizeof(PATTERN4) - 1, 0, 0, 0 }, - { (const uint8_t*)PATTERN5, sizeof(PATTERN5) - 1, 0, 0, 0 }, - { (const uint8_t*)PATTERN6, sizeof(PATTERN6) - 1, 0, 0, 0 }, - { (const uint8_t*)PATTERN7, sizeof(PATTERN7) - 1, 0, 0, 0 } - }; - - appid_registry = - { - { APP_ID_DIRECT_CONNECT, 0 } - }; - - service_ports = - { - { 411, IpProtocol::TCP, false }, - { 411, IpProtocol::UDP, false }, - { 412, IpProtocol::TCP, false }, - { 412, IpProtocol::UDP, false }, - { 413, IpProtocol::TCP, false }, - { 413, IpProtocol::UDP, false }, - { 414, IpProtocol::TCP, false }, - { 414, IpProtocol::UDP, false }, - }; - - handler->register_detector(name, this, proto); -} - - -int DirectConnectServiceDetector::validate(AppIdDiscoveryArgs& args) -{ - ServiceData* fd; - const uint8_t* data = args.data; - uint16_t size = args.size; - - if (!size) - { - service_inprocess(args.asd, args.pkt, args.dir); - return APPID_INPROCESS; - } - - fd = (ServiceData*)data_get(args.asd); - if (!fd) - { - fd = (ServiceData*)snort_calloc(sizeof(ServiceData)); - data_add(args.asd, fd, &snort_free); - } - - if (args.asd.protocol == IpProtocol::TCP) - return tcp_validate(data, size, args.dir, args.asd, args.pkt, fd, args.change_bits); - else - return udp_validate(data, size, args.dir, args.asd, args.pkt, fd, args.change_bits); -} - -int DirectConnectServiceDetector::tcp_validate(const uint8_t* data, uint16_t size, const AppidSessionDirection dir, - AppIdSession& asd, const Packet* pkt, ServiceData* serviceData, AppidChangeBits& change_bits) -{ - switch (serviceData->state) - { - case CONN_STATE_INIT: - if (size > 6 - && data[size-1] == '|' - /*&& data[size-1] == '$'*/) - { - if (memcmp(data, PATTERN1, sizeof(PATTERN1)-1) == 0) - { - serviceData->state = CONN_STATE_1; - goto inprocess; - } - - if (memcmp(data, PATTERN2, sizeof(PATTERN2)-1) == 0) - { - serviceData->state = CONN_STATE_2; - goto inprocess; - } - } - - if (size >= 11) - { - if (memcmp(data, PATTERN3, sizeof(PATTERN3)-1) == 0 - || memcmp(data, PATTERN4, sizeof(PATTERN4)-1) == 0 - || memcmp(data, PATTERN5, sizeof(PATTERN5)-1) == 0 - || memcmp(data, PATTERN6, sizeof(PATTERN6)-1) == 0) - { - goto success; - } - } - break; - - case CONN_STATE_1: - if (size >= 11) - { - if (memcmp(data, PATTERN3, sizeof(PATTERN3)-1) == 0 - || memcmp(data, PATTERN4, sizeof(PATTERN4)-1) == 0 - || memcmp(data, PATTERN5, sizeof(PATTERN5)-1) == 0 - || memcmp(data, PATTERN6, sizeof(PATTERN6)-1) == 0) - { - goto success; - } - } - - if (size > 6) - { - if ((data[0] == '$' || data[0] == '<') - && data[size-2] == '|' - && data[size-1] == '$') - { - goto success; - } - else - { - goto inprocess; - } - } - break; - - case CONN_STATE_2: - if (size > 6) - { - if (data[0] == '$' && data[size-2] == '|' && data[size-1] == '$') - { - goto success; - } - else - { - goto inprocess; - } - } - break; - - case CONN_STATE_SERVICE_DETECTED: - goto success; - } - -inprocess: - serviceData->packetCount++; - if (serviceData->packetCount >= MAX_PACKET_INSPECTION_COUNT) - goto fail; - - service_inprocess(asd, pkt, dir); - return APPID_INPROCESS; - -success: - if (dir != APP_ID_FROM_RESPONDER) - { - serviceData->state = CONN_STATE_SERVICE_DETECTED; - goto inprocess; - } - - return add_service(change_bits, asd, pkt, dir, APP_ID_DIRECT_CONNECT); - -fail: - fail_service(asd, pkt, dir); - return APPID_NOMATCH; -} - -int DirectConnectServiceDetector::udp_validate(const uint8_t* data, uint16_t size, const AppidSessionDirection dir, - AppIdSession& asd, const Packet* pkt, ServiceData* serviceData, AppidChangeBits& change_bits) -{ - if (dir == APP_ID_FROM_RESPONDER && serviceData->state == CONN_STATE_SERVICE_DETECTED) - { - goto reportSuccess; - } - - if (size > 58) - { - if (memcmp(data, PATTERN7, sizeof(PATTERN7)-1) == 0 - && data[size-3] == ')' - && data[size-2] == '|' - && data[size-1] == '$') - { - goto success; - } - serviceData->state += 1; - - if (serviceData->state != CONN_STATE_SERVICE_DETECTED) - goto inprocess; - else - goto fail; - } - -inprocess: - serviceData->packetCount++; - if (serviceData->packetCount >= MAX_PACKET_INSPECTION_COUNT) - goto fail; - - service_inprocess(asd, pkt, dir); - return APPID_INPROCESS; - -success: - if (dir != APP_ID_FROM_RESPONDER) - { - serviceData->state = CONN_STATE_SERVICE_DETECTED; - goto inprocess; - } - -reportSuccess: - return add_service(change_bits, asd, pkt, dir, APP_ID_DIRECT_CONNECT); - -fail: - fail_service(asd, pkt, dir); - return APPID_NOMATCH; -} - diff --git a/src/network_inspectors/appid/service_plugins/service_direct_connect.h b/src/network_inspectors/appid/service_plugins/service_direct_connect.h deleted file mode 100644 index f7df5649a..000000000 --- a/src/network_inspectors/appid/service_plugins/service_direct_connect.h +++ /dev/null @@ -1,46 +0,0 @@ -//-------------------------------------------------------------------------- -// Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved. -// Copyright (C) 2005-2013 Sourcefire, Inc. -// -// This program is free software; you can redistribute it and/or modify it -// under the terms of the GNU General Public License Version 2 as published -// by the Free Software Foundation. You may not use, modify or distribute -// this program under any other version of the GNU General Public License. -// -// This program is distributed in the hope that it will be useful, but -// WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program; if not, write to the Free Software Foundation, Inc., -// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -//-------------------------------------------------------------------------- - -// service_direct_connect.h author Sourcefire Inc. - -#ifndef SERVICE_DIRECTCONNECT_H -#define SERVICE_DIRECTCONNECT_H - -#include "service_detector.h" - -class ServiceDiscovery; -class AppIdSession; -struct ServiceData; - -class DirectConnectServiceDetector : public ServiceDetector -{ -public: - DirectConnectServiceDetector(ServiceDiscovery*); - - int validate(AppIdDiscoveryArgs&) override; - -private: - int tcp_validate(const uint8_t* data, uint16_t size, const AppidSessionDirection dir, AppIdSession&, - const snort::Packet*, ServiceData*, AppidChangeBits&); - int udp_validate(const uint8_t* data, uint16_t size, const AppidSessionDirection dir, AppIdSession&, - const snort::Packet*, ServiceData*, AppidChangeBits&); -}; - -#endif - diff --git a/src/network_inspectors/appid/service_plugins/service_discovery.cc b/src/network_inspectors/appid/service_plugins/service_discovery.cc index 9c2cc4cc5..b9678f047 100644 --- a/src/network_inspectors/appid/service_plugins/service_discovery.cc +++ b/src/network_inspectors/appid/service_plugins/service_discovery.cc @@ -45,12 +45,10 @@ #include "detector_plugins/detector_sip.h" #include "detector_plugins/detector_smtp.h" #include "lua_detector_api.h" -#include "service_battle_field.h" #include "service_bgp.h" #include "service_bit.h" #include "service_bootp.h" #include "service_dcerpc.h" -#include "service_direct_connect.h" #include "service_ftp.h" #include "service_irc.h" #include "service_lpr.h" @@ -87,12 +85,10 @@ static ServiceDetector* ftp_service; void ServiceDiscovery::initialize(AppIdInspector& inspector) { - new BattleFieldServiceDetector(this); new BgpServiceDetector(this); new BitServiceDetector(this); new BootpServiceDetector(this); new DceRpcServiceDetector(this); - new DirectConnectServiceDetector(this); new DnsTcpServiceDetector(this); new DnsUdpServiceDetector(this); new FtpServiceDetector(this); diff --git a/src/network_inspectors/appid/test/appid_http_event_test.cc b/src/network_inspectors/appid/test/appid_http_event_test.cc index a16d0695e..f51379bc1 100644 --- a/src/network_inspectors/appid/test/appid_http_event_test.cc +++ b/src/network_inspectors/appid/test/appid_http_event_test.cc @@ -107,11 +107,44 @@ void AppIdSession::delete_all_http_sessions() } void AppIdHttpSession::set_http_change_bits(AppidChangeBits&, HttpFieldIds) {} + +void AppIdHttpSession::set_scan_flags(HttpFieldIds id) +{ + switch (id) + { + case REQ_URI_FID: + asd.scan_flags |= SCAN_HTTP_URI_FLAG; + break; + case MISC_VIA_FID: + asd.scan_flags |= SCAN_HTTP_VIA_FLAG; + break; + case REQ_AGENT_FID: + asd.scan_flags |= SCAN_HTTP_USER_AGENT_FLAG; + break; + case RSP_CONTENT_TYPE_FID: + asd.scan_flags |= SCAN_HTTP_CONTENT_TYPE_FLAG; + break; + case MISC_SERVER_FID: + asd.scan_flags |= SCAN_HTTP_VENDOR_FLAG; + break; + case MISC_XWW_FID: + asd.scan_flags |= SCAN_HTTP_XWORKINGWITH_FLAG; + break; + case REQ_HOST_FID: + case MISC_URL_FID: + asd.scan_flags |= SCAN_HTTP_HOST_URL_FLAG; + break; + default: + break; + } +} + void AppIdHttpSession::set_field(HttpFieldIds id, const std::string* str, AppidChangeBits&) { delete meta_data[id]; meta_data[id] = str; + set_scan_flags(id); } void AppIdHttpSession::set_field(HttpFieldIds id, const uint8_t* str, int32_t len, @@ -119,7 +152,10 @@ void AppIdHttpSession::set_field(HttpFieldIds id, const uint8_t* str, int32_t le { delete meta_data[id]; if (str and len) + { meta_data[id] = new std::string((const char*)str, len); + set_scan_flags(id); + } else meta_data[id] = nullptr; } diff --git a/src/network_inspectors/appid/tp_appid_utils.cc b/src/network_inspectors/appid/tp_appid_utils.cc index 8e2882d9f..a588800c6 100644 --- a/src/network_inspectors/appid/tp_appid_utils.cc +++ b/src/network_inspectors/appid/tp_appid_utils.cc @@ -117,7 +117,6 @@ static inline void process_http_session(AppIdSession& asd, hsession->set_chp_finished(false); hsession->set_field(MISC_URL_FID, url, change_bits); - asd.scan_flags |= SCAN_HTTP_HOST_URL_FLAG; } if (spdyRequestHost) @@ -129,7 +128,6 @@ static inline void process_http_session(AppIdSession& asd, hsession->set_offset(REQ_HOST_FID, attribute_data.spdy_request_host_begin(), attribute_data.spdy_request_host_end()); - asd.scan_flags |= SCAN_HTTP_HOST_URL_FLAG; } if (spdyRequestPath) @@ -155,7 +153,6 @@ static inline void process_http_session(AppIdSession& asd, hsession->set_offset(REQ_HOST_FID, attribute_data.http_request_host_begin(), attribute_data.http_request_host_end()); - asd.scan_flags |= SCAN_HTTP_HOST_URL_FLAG; } if ( (field=attribute_data.http_request_url(own)) != nullptr ) @@ -177,7 +174,6 @@ static inline void process_http_session(AppIdSession& asd, field->insert(4, 1, 's'); } hsession->set_field(MISC_URL_FID, field, change_bits); - asd.scan_flags |= SCAN_HTTP_HOST_URL_FLAG; } if ( (field=attribute_data.http_request_uri(own)) != nullptr) @@ -190,7 +186,6 @@ static inline void process_http_session(AppIdSession& asd, hsession->set_offset(REQ_URI_FID, attribute_data.http_request_uri_begin(), attribute_data.http_request_uri_end()); - asd.scan_flags |= SCAN_HTTP_URI_FLAG; } } @@ -202,7 +197,6 @@ static inline void process_http_session(AppIdSession& asd, hsession->set_chp_finished(false); hsession->set_field(MISC_VIA_FID, field, change_bits); - asd.scan_flags |= SCAN_HTTP_VIA_FLAG; } else if ( (field=attribute_data.http_response_via(own)) != nullptr ) { @@ -211,7 +205,6 @@ static inline void process_http_session(AppIdSession& asd, hsession->set_chp_finished(false); hsession->set_field(MISC_VIA_FID, field, change_bits); - asd.scan_flags |= SCAN_HTTP_VIA_FLAG; } if ( (field=attribute_data.http_request_user_agent(own)) != nullptr ) @@ -224,7 +217,6 @@ static inline void process_http_session(AppIdSession& asd, hsession->set_offset(REQ_AGENT_FID, attribute_data.http_request_user_agent_begin(), attribute_data.http_request_user_agent_end()); - asd.scan_flags |= SCAN_HTTP_USER_AGENT_FLAG; } if ( (field=attribute_data.http_response_code(own)) != nullptr ) @@ -267,7 +259,6 @@ static inline void process_http_session(AppIdSession& asd, hsession->set_chp_finished(false); hsession->set_field(RSP_CONTENT_TYPE_FID, field, change_bits); - asd.scan_flags |= SCAN_HTTP_CONTENT_TYPE_FLAG; } if (hsession->get_ptype_scan_count(RSP_LOCATION_FID) && @@ -303,16 +294,10 @@ static inline void process_http_session(AppIdSession& asd, } if ( (field=attribute_data.http_response_server(own)) != nullptr) - { hsession->set_field(MISC_SERVER_FID, field, change_bits); - asd.scan_flags |= SCAN_HTTP_VENDOR_FLAG; - } if ( (field=attribute_data.http_request_x_working_with(own)) != nullptr ) - { hsession->set_field(MISC_XWW_FID, field, change_bits); - asd.scan_flags |= SCAN_HTTP_XWORKINGWITH_FLAG; - } } static inline void process_rtmp(AppIdSession& asd, @@ -321,22 +306,13 @@ static inline void process_rtmp(AppIdSession& asd, AppIdHttpSession* hsession = asd.get_http_session(); if (!hsession) hsession = asd.create_http_session(); - AppId service_id = 0; - AppId client_id = 0; - AppId payload_id = 0; - AppId referred_payload_app_id = APP_ID_NONE; bool own = true; - uint16_t size = 0; - - const string* field=nullptr; + const string* field = nullptr; if ( !hsession->get_field(MISC_URL_FID) ) { if ( ( field=attribute_data.http_request_url(own) ) != nullptr ) - { hsession->set_field(MISC_URL_FID, field, change_bits); - asd.scan_flags |= SCAN_HTTP_HOST_URL_FLAG; - } } if ( !asd.get_odp_ctxt().referred_appId_disabled && @@ -356,61 +332,14 @@ static inline void process_rtmp(AppIdSession& asd, hsession->set_offset(REQ_AGENT_FID, attribute_data.http_request_user_agent_begin(), attribute_data.http_request_user_agent_end()); - - asd.scan_flags |= SCAN_HTTP_USER_AGENT_FLAG; } } - if ( ( asd.scan_flags & SCAN_HTTP_USER_AGENT_FLAG ) and - asd.get_client_id() <= APP_ID_NONE and - ( field = hsession->get_field(REQ_AGENT_FID) ) and - ( size = attribute_data.http_request_user_agent_end() - - attribute_data.http_request_user_agent_begin() ) > 0 ) - { - char *version = nullptr; - HttpPatternMatchers& http_matchers = asd.get_odp_ctxt().get_http_matchers(); - - http_matchers.identify_user_agent(field->c_str(), size, service_id, - client_id, &version); - - hsession->set_client(client_id, change_bits, "User Agent", version); - - // do not overwrite a previously-set service - if ( asd.get_service_id() <= APP_ID_NONE ) - asd.set_service_appid_data(service_id, change_bits); - - asd.scan_flags |= ~SCAN_HTTP_USER_AGENT_FLAG; - snort_free(version); - } + asd.examine_rtmp_metadata(change_bits); if ( hsession->get_field(MISC_URL_FID) || (confidence == 100 && asd.session_packet_count > asd.get_odp_ctxt().rtmp_max_packets) ) { - const std::string* url; - if ( ( url = hsession->get_field(MISC_URL_FID) ) != nullptr ) - { - HttpPatternMatchers& http_matchers = asd.get_odp_ctxt().get_http_matchers(); - const char* referer = hsession->get_cfield(REQ_REFERER_FID); - if ( ( ( http_matchers.get_appid_from_url(nullptr, url->c_str(), - nullptr, referer, &client_id, &service_id, - &payload_id, &referred_payload_app_id, true, asd.get_odp_ctxt()) ) - || - ( http_matchers.get_appid_from_url(nullptr, url->c_str(), - nullptr, referer, &client_id, &service_id, - &payload_id, &referred_payload_app_id, false, asd.get_odp_ctxt()) ) ) == 1 ) - { - // do not overwrite a previously-set client or service - if ( hsession->client.get_id() <= APP_ID_NONE ) - hsession->set_client(client_id, change_bits, "URL"); - if ( asd.get_service_id() <= APP_ID_NONE ) - asd.set_service_appid_data(service_id, change_bits); - - // DO overwrite a previously-set payload - hsession->set_payload(payload_id, change_bits, "URL"); - hsession->set_referred_payload(referred_payload_app_id, change_bits); - } - } - asd.tpsession->disable_flags( TP_SESSION_FLAG_ATTRIBUTE | TP_SESSION_FLAG_TUNNELING | TP_SESSION_FLAG_FUTUREFLOW);