]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #1748 in SNORT/snort3 from ~KAMURTHI/snort3:BT_Proxy to master
authorShravan Rangarajuvenkata (shrarang) <shrarang@cisco.com>
Tue, 24 Sep 2019 21:59:12 +0000 (17:59 -0400)
committerShravan Rangarajuvenkata (shrarang) <shrarang@cisco.com>
Tue, 24 Sep 2019 21:59:12 +0000 (17:59 -0400)
Squashed commit of the following:

commit a4cef99d25b3cc5b4cf06e22175dcebafc7781b9
Author: kani <kamurthi@cisco.com>
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

src/network_inspectors/appid/appid_discovery.cc
src/network_inspectors/appid/appid_discovery.h
src/network_inspectors/appid/appid_http_session.cc
src/network_inspectors/appid/appid_http_session.h
src/network_inspectors/appid/test/appid_discovery_test.cc
src/network_inspectors/appid/test/appid_http_session_test.cc
src/network_inspectors/appid/tp_appid_utils.cc

index 797303325ab343a430eb79d932e45c816fc76ebc..9ee0405a106ef5d544dd1b23bf17d73bfd9a6821 100644 (file)
@@ -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();
index 3e7d8f5972a017d8f18351c1126f75f99f975852..04e5b18efeb8f90a0b453e7e1aaebeaf16ba58a1 100644 (file)
@@ -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
 {
index 953625870871a4421533edeecaed30054547d349..584b73444808368659ba5fda9200d08c9cbaa61d 100644 (file)
@@ -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;
index e507f0c545585ac22b7d9a6f410c4322b66c99bb..fa3ed46ce0219beaff7d2e7a033e32aeee478e88 100644 (file)
@@ -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
index d94b6592cde76ca1dd5d9551da008990492859b8..d46606f2e2e897422741f2985822a4093ebafdfb 100644 (file)
@@ -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
index 77a2891c09726b33dcd1c632437603e736ecb916..1b34730812b4945aaf747ff08bb935c176f4060a 100644 (file)
@@ -42,7 +42,6 @@
 
 #include <CppUTest/CommandLineTestRunner.h>
 #include <CppUTest/TestHarness.h>
-
 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
index 1a205ec4afaea58482d509f360747daef9afd359..78abc01fd347e24b81783c371b81b5770b7ddcd6 100644 (file)
@@ -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(),