From 936a487d221f7f84aa27dee40407b81ce10064f8 Mon Sep 17 00:00:00 2001 From: "Shravan Rangarajuvenkata (shrarang)" Date: Tue, 24 Sep 2019 17:59:12 -0400 Subject: [PATCH] Merge pull request #1748 in SNORT/snort3 from ~KAMURTHI/snort3:BT_Proxy to master Squashed commit of the following: commit a4cef99d25b3cc5b4cf06e22175dcebafc7781b9 Author: kani Date: Sun Sep 15 20:58:30 2019 -0400 appid: extract forward ip from http tunneled traffic and use it for dynamic host cache lookup --- .../appid/appid_discovery.cc | 40 ++++++++--- .../appid/appid_discovery.h | 1 + .../appid/appid_http_session.cc | 71 +++++++++++++++++++ .../appid/appid_http_session.h | 20 ++++++ .../appid/test/appid_discovery_test.cc | 2 +- .../appid/test/appid_http_session_test.cc | 15 +++- .../appid/tp_appid_utils.cc | 1 + 7 files changed, 138 insertions(+), 12 deletions(-) diff --git a/src/network_inspectors/appid/appid_discovery.cc b/src/network_inspectors/appid/appid_discovery.cc index 797303325..9ee0405a1 100644 --- a/src/network_inspectors/appid/appid_discovery.cc +++ b/src/network_inspectors/appid/appid_discovery.cc @@ -50,7 +50,6 @@ #include "tp_lib_handler.h" #include "tp_appid_utils.h" #endif - using namespace snort; AppIdDiscovery::AppIdDiscovery() @@ -868,18 +867,27 @@ bool AppIdDiscovery::do_host_port_based_discovery(Packet* p, AppIdSession& asd, uint16_t port; const SfIp* ip; - - if (direction == APP_ID_FROM_INITIATOR) + AppIdHttpSession* hsession = asd.get_http_session(); + + const TunnelDest* tun_dest = hsession->get_tun_dest(); + if(tun_dest) { - ip = p->ptrs.ip_api.get_dst(); - port = p->ptrs.dp; + ip = &(tun_dest->ip); + port = tun_dest->port; } else { - ip = p->ptrs.ip_api.get_src(); - port = p->ptrs.sp; + if (direction == APP_ID_FROM_INITIATOR) + { + ip = p->ptrs.ip_api.get_dst(); + port = p->ptrs.dp; + } + else + { + ip = p->ptrs.ip_api.get_src(); + port = p->ptrs.sp; + } } - HostPortVal* hv = nullptr; if (check_static and @@ -1035,9 +1043,21 @@ bool AppIdDiscovery::do_discovery(Packet* p, AppIdSession& asd, IpProtocol proto client_id = asd.pick_client_app_id(); misc_id = asd.pick_misc_app_id();; - if ((service_id == APP_ID_UNKNOWN_UI or service_id <= APP_ID_NONE ) and - (client_id <= APP_ID_NONE and payload_id <= APP_ID_NONE and misc_id <= APP_ID_NONE)) + bool is_http_tunnel = ((asd.payload.get_id() == APP_ID_HTTP_TUNNEL) || (asd.payload.get_id() == APP_ID_HTTP_SSL_TUNNEL)) ? true:false; + if ((is_http_tunnel) or ((service_id == APP_ID_UNKNOWN_UI or service_id <= APP_ID_NONE ) and + (client_id <= APP_ID_NONE and payload_id <= APP_ID_NONE and misc_id <= APP_ID_NONE))) { + if(is_http_tunnel) + { + AppIdHttpSession* hsession = asd.get_http_session(); + if(hsession and (asd.scan_flags & SCAN_HTTP_URI_FLAG)) + { + if(hsession->get_tun_dest()) + hsession->free_tun_dest(); + hsession->set_tun_dest(); + asd.scan_flags &= ~SCAN_HTTP_URI_FLAG; + } + } if (do_host_port_based_discovery(p, asd, protocol, direction)) { service_id = asd.pick_service_app_id(); diff --git a/src/network_inspectors/appid/appid_discovery.h b/src/network_inspectors/appid/appid_discovery.h index 3e7d8f597..04e5b18ef 100644 --- a/src/network_inspectors/appid/appid_discovery.h +++ b/src/network_inspectors/appid/appid_discovery.h @@ -54,6 +54,7 @@ struct Packet; #define SCAN_HTTP_VENDOR_FLAG (1<<6) #define SCAN_HTTP_XWORKINGWITH_FLAG (1<<7) #define SCAN_HTTP_CONTENT_TYPE_FLAG (1<<8) +#define SCAN_HTTP_URI_FLAG (1<<9) class AppIdPatternMatchNode { diff --git a/src/network_inspectors/appid/appid_http_session.cc b/src/network_inspectors/appid/appid_http_session.cc index 953625870..584b73444 100644 --- a/src/network_inspectors/appid/appid_http_session.cc +++ b/src/network_inspectors/appid/appid_http_session.cc @@ -36,6 +36,7 @@ #ifdef ENABLE_APPID_THIRD_PARTY #include "tp_lib_handler.h" #endif +#define PORT_MAX 65535 using namespace snort; @@ -70,6 +71,8 @@ AppIdHttpSession::~AppIdHttpSession() for ( int i = 0; i < NUM_METADATA_FIELDS; i++) delete meta_data[i]; + if (tun_dest) + delete tun_dest; } void AppIdHttpSession::free_chp_matches(ChpMatchDescriptor& cmd, unsigned num_matches) @@ -103,6 +106,74 @@ void AppIdHttpSession::set_http_change_bits(AppidChangeBits& change_bits, HttpFi } } +void AppIdHttpSession::set_tun_dest() +{ + assert(meta_data[REQ_URI_FID]); + char *host = nullptr, *host_start, *host_end = nullptr, *url_end; + char *port_str = nullptr; + uint16_t port = 0; + int is_IPv6 = 0; + char* url = strdup(meta_data[REQ_URI_FID]->c_str()); + url_end = url + strlen(url) - 1; + host_start = url; + + if (url[0] == '[') + { + is_IPv6 = 1; + port_str = strchr(url, ']'); + if (port_str && port_str < url_end) + { + if (*(++port_str) != ':') + { + port_str = nullptr; + } + } + } + else if(isdigit(url[0])) + { + port_str = strrchr(url, ':'); + } + + if (port_str && port_str < url_end ) + { + host_end = port_str; + if (*(++port_str) != '\0') + { + char *end = NULL; + long ret = strtol(port_str, &end, 10); + if (end != port_str && *end == '\0' && ret >= 1 && ret <= PORT_MAX) + { + port = (uint16_t)ret; + } + } + } + + if (port) + { + if (is_IPv6) + { + host_start++; + host_end--; + } + + if (host_start <= host_end) + { + char tmp = *host_end; + *host_end = '\0'; + host = strdup(host_start); + *host_end = tmp; + } + } + if (host) + { + if(tun_dest) + delete tun_dest; + tun_dest= new TunnelDest(host, port); + free(host); + } + free(url ); +} + int AppIdHttpSession::initial_chp_sweep(ChpMatchDescriptor& cmd) { CHPApp* cah = nullptr; diff --git a/src/network_inspectors/appid/appid_http_session.h b/src/network_inspectors/appid/appid_http_session.h index e507f0c54..fa3ed46ce 100644 --- a/src/network_inspectors/appid/appid_http_session.h +++ b/src/network_inspectors/appid/appid_http_session.h @@ -80,6 +80,17 @@ enum HttpFieldIds : uint8_t #define APP_TYPE_CLIENT 0x2 #define APP_TYPE_PAYLOAD 0x4 +struct TunnelDest +{ + snort::SfIp ip; + uint16_t port; + TunnelDest(const char* string_srcip, uint16_t tun_port) + { + ip.set(string_srcip); + port = tun_port; + } +}; + class AppIdHttpSession { public: @@ -180,6 +191,14 @@ public: void set_chp_finished(bool chpFinished = false) { chp_finished = chpFinished; } + void set_tun_dest(); + + const TunnelDest* get_tun_dest() + { return tun_dest; } + + void free_tun_dest() + { delete tun_dest; } + void reset_ptype_scan_counts(); int get_ptype_scan_count(enum HttpFieldIds type) @@ -227,6 +246,7 @@ protected: unsigned numXffFields = 0; int ptype_req_counts[NUM_HTTP_FIELDS] = { 0 }; int ptype_scan_counts[NUM_HTTP_FIELDS] = { 0 }; + const TunnelDest* tun_dest = nullptr; #if RESPONSE_CODE_PACKET_THRESHHOLD unsigned response_code_packets = 0; #endif diff --git a/src/network_inspectors/appid/test/appid_discovery_test.cc b/src/network_inspectors/appid/test/appid_discovery_test.cc index d94b6592c..d46606f2e 100644 --- a/src/network_inspectors/appid/test/appid_discovery_test.cc +++ b/src/network_inspectors/appid/test/appid_discovery_test.cc @@ -190,6 +190,7 @@ AppIdSession* AppIdSession::allocate_session(const Packet*, IpProtocol, { return nullptr; } +void AppIdHttpSession::set_tun_dest(){} // Stubs for ServiceDiscovery void ServiceDiscovery::initialize() {} @@ -307,7 +308,6 @@ TEST_GROUP(appid_discovery_tests) AppIdPegCounts::cleanup_peg_info(); } }; - TEST(appid_discovery_tests, event_published_when_ignoring_flow) { // Testing event from do_pre_discovery() path diff --git a/src/network_inspectors/appid/test/appid_http_session_test.cc b/src/network_inspectors/appid/test/appid_http_session_test.cc index 77a2891c0..1b3473081 100644 --- a/src/network_inspectors/appid/test/appid_http_session_test.cc +++ b/src/network_inspectors/appid/test/appid_http_session_test.cc @@ -42,7 +42,6 @@ #include #include - using namespace snort; void ApplicationDescriptor::set_id(const snort::Packet&, AppIdSession&, AppidSessionDirection, AppId, AppidChangeBits&) { } @@ -267,6 +266,20 @@ TEST(appid_http_session, http_field_ids_enum_order) CHECK_EQUAL(change_bits.test(APPID_REFERER_BIT), true); } +TEST(appid_http_session, set_tun_dest) +{ + const TunnelDest* tun_dest = nullptr; + SfIp tun_des, ipv6; + ipv6.set("2001:db8:85a3::8a2e:370:7334"); + AppidChangeBits change_bits; + hsession.set_field(REQ_URI_FID, new std::string("[2001:db8:85a3::8a2e:370:7334]:51413"), change_bits); + hsession.set_tun_dest(); + tun_dest = hsession.get_tun_dest(); + CHECK(tun_dest != nullptr); + CHECK_EQUAL(tun_dest->port, 51413); + CHECK_EQUAL((ipv6 == tun_dest->ip), true); +} + TEST(appid_http_session, change_bits_for_referred_appid) { // Testing set_referred_payload_app_id_data diff --git a/src/network_inspectors/appid/tp_appid_utils.cc b/src/network_inspectors/appid/tp_appid_utils.cc index 1a205ec4a..78abc01fd 100644 --- a/src/network_inspectors/appid/tp_appid_utils.cc +++ b/src/network_inspectors/appid/tp_appid_utils.cc @@ -210,6 +210,7 @@ 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; if (appidDebug->is_active()) LogMessage("AppIdDbg %s URI (%u-%u) is %s\n", appidDebug->get_debug_session(), attribute_data.http_request_uri_begin(), -- 2.47.3