]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #2445 in SNORT/snort3 from ~THOPETER/snort3:lit_script to master
authorMike Stepanek (mstepane) <mstepane@cisco.com>
Wed, 9 Sep 2020 21:20:07 +0000 (21:20 +0000)
committerMike Stepanek (mstepane) <mstepane@cisco.com>
Wed, 9 Sep 2020 21:20:07 +0000 (21:20 +0000)
Squashed commit of the following:

commit 4f9f4879a38c0b385d012088b0fc05b9b2909fc0
Author: russ <rucombs@cisco.com>
Date:   Wed Aug 26 20:31:17 2020 -0400

    http_inspect: support hyperscan literal search for accelerated blocking

src/helpers/literal_search.cc
src/helpers/literal_search.h
src/service_inspectors/http_inspect/http_cutter.cc
src/service_inspectors/http_inspect/http_cutter.h
src/service_inspectors/http_inspect/http_module.cc
src/service_inspectors/http_inspect/http_module.h
src/service_inspectors/http_inspect/test/http_module_test.cc
src/service_inspectors/http_inspect/test/http_uri_norm_test.cc

index 4f245ce2e3698cb34e4e105aa3825b1dda96b637..fb5df2504bc5849d9c18d49d7871a63f18dde5fd 100644 (file)
@@ -56,13 +56,14 @@ void LiteralSearch::cleanup(LiteralSearch::Handle* h)
 }
 
 LiteralSearch* LiteralSearch::instantiate(
-    LiteralSearch::Handle* h, const uint8_t* pattern, unsigned pattern_len, bool no_case)
+    LiteralSearch::Handle* h, const uint8_t* pattern, unsigned pattern_len, bool no_case, bool hs)
 {
 #ifdef HAVE_HYPERSCAN
-    if ( SnortConfig::get_conf()->hyperscan_literals )
+    if ( hs or SnortConfig::get_conf()->hyperscan_literals )
         return new HyperSearch(h, pattern, pattern_len, no_case);
 #else
     UNUSED(h);
+    UNUSED(hs);
 #endif
     if ( no_case )
         return new snort::BoyerMooreSearchNoCase(pattern, pattern_len);
index 1dc4c8886f40a78990b068c5f3aeb4f3c0add43a..4d285ebf270deab47451bd3f0962ca40ba5d650f 100644 (file)
@@ -36,7 +36,8 @@ public:
     static Handle* setup();        // call from module ctor
     static void cleanup(Handle*);  // call from module dtor
 
-    static LiteralSearch* instantiate(Handle*, const uint8_t* pattern, unsigned pattern_len, bool no_case = false);
+    static LiteralSearch* instantiate(
+            Handle*, const uint8_t* pattern, unsigned pattern_len, bool no_case = false, bool hs = false);
     virtual ~LiteralSearch() { }
 
     virtual int search(Handle*, const uint8_t* buffer, unsigned buffer_len) const = 0;
index c30854dff98c551365f42c5d130d3f90a732bd72..a173b21f237195aa7a00de6b9499b195aa1be3e4 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "http_common.h"
 #include "http_enum.h"
+#include "http_module.h"
 
 using namespace HttpEnums;
 
@@ -285,12 +286,14 @@ HttpBodyCutter::HttpBodyCutter(AcceleratedBlocking accelerated_blocking_, Compre
             match_string = detain_string;
             match_string_upper = detain_upper;
             string_length = sizeof(detain_string);
+            HttpModule::get_detain_finder(finder, handle);
         }
         else
         {
             match_string = inspect_string;
             match_string_upper = inspect_upper;
             string_length = sizeof(inspect_string);
+            HttpModule::get_script_finder(finder, handle);
         }
     }
 }
@@ -818,6 +821,30 @@ bool HttpBodyCutter::need_accelerated_blocking(const uint8_t* data, uint32_t len
     return false;
 }
 
+bool HttpBodyCutter::find_partial(const uint8_t* input_buf, uint32_t input_length, bool end)
+{
+    for (uint32_t k = 0; k < input_length; k++)
+    {
+        // partial_match is persistent, enabling matches that cross data boundaries
+        if ((input_buf[k] == match_string[partial_match]) ||
+            (input_buf[k] == match_string_upper[partial_match]))
+        {
+            if (++partial_match == string_length)
+            {
+                partial_match = 0;
+                return true;
+            }
+        }
+        else
+        {
+            partial_match = 0;
+            if ( end )
+                return false;
+        }
+    }
+    return false;
+}
+
 // Currently we do accelerated blocking when we see a javascript
 bool HttpBodyCutter::dangerous(const uint8_t* data, uint32_t length)
 {
@@ -856,25 +883,24 @@ bool HttpBodyCutter::dangerous(const uint8_t* data, uint32_t length)
         input_length = decomp_buffer_size - compress_stream->avail_out;
     }
 
-    for (uint32_t k = 0; k < input_length; k++)
+    std::unique_ptr<uint8_t[]> uniq(decomp_output);
+
+    if ( input_length > string_length )
     {
-        // partial_match is persistent, enabling matches that cross data boundaries
-        if ((input_buf[k] == match_string[partial_match]) ||
-            (input_buf[k] == match_string_upper[partial_match]))
-        {
-            if (++partial_match == string_length)
-            {
-                partial_match = 0;
-                delete[] decomp_output;
-                return true;
-            }
-        }
-        else
-        {
-            partial_match = 0;
-        }
+        if ( partial_match and find_partial(input_buf, input_length, true) )
+            return true;
+
+        if ( finder->search(handle, input_buf, input_length) >= 0 )
+            return true;
+
+        uint32_t delta = input_length - string_length + 1;
+        input_buf += delta;
+        input_length -= delta;
     }
-    delete[] decomp_output;
+
+    if ( find_partial(input_buf, input_length, false) )
+        return true;
+
     return false;
 }
 
index f512f860d9ccf6bc13bf4a89f5a4835de57f986f..7d55b9353757edd30402afcb5af264459aded910 100644 (file)
@@ -23,6 +23,8 @@
 #include <cassert>
 #include <zlib.h>
 
+#include "helpers/literal_search.h"
+
 #include "http_enum.h"
 #include "http_event.h"
 
@@ -110,6 +112,7 @@ protected:
 
 private:
     bool dangerous(const uint8_t* data, uint32_t length);
+    bool find_partial(const uint8_t*, uint32_t, bool);
 
     const HttpEnums::AcceleratedBlocking accelerated_blocking;
     bool packet_detained = false;
@@ -118,6 +121,8 @@ private:
     HttpEnums::CompressId compression;
     z_stream* compress_stream = nullptr;
     bool decompress_failed = false;
+    snort::LiteralSearch* finder = nullptr;
+    snort::LiteralSearch::Handle* handle = nullptr;
     const uint8_t* match_string;
     const uint8_t* match_string_upper;
     uint8_t string_length;
index 4746276e87fbe20e6b1d7b50c8eef69f4a2fc76b..af6016b68cbdfb86a22629ec0e40cfb97d9b23f7 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "http_module.h"
 
+#include "helpers/literal_search.h"
 #include "log/messages.h"
 
 #include "http_enum.h"
 using namespace snort;
 using namespace HttpEnums;
 
+LiteralSearch::Handle* s_handle = nullptr;
+LiteralSearch* s_detain = nullptr;
+LiteralSearch* s_script = nullptr;
+
+HttpModule::HttpModule() : Module(HTTP_NAME, HTTP_HELP, http_params)
+{
+    s_handle = LiteralSearch::setup();
+    s_detain = LiteralSearch::instantiate(s_handle, (const uint8_t*)"<SCRIPT", 7, true, true);
+    s_script = LiteralSearch::instantiate(s_handle, (const uint8_t*)"</SCRIPT>", 9, true, true);
+}
+
+HttpModule::~HttpModule()
+{
+    delete params;
+    delete s_detain;
+    delete s_script;
+    LiteralSearch::cleanup(s_handle);
+}
+
+void HttpModule::get_detain_finder(LiteralSearch*& finder, LiteralSearch::Handle*& handle)
+{
+    finder = s_detain;
+    handle = s_handle;
+}
+
+void HttpModule::get_script_finder(LiteralSearch*& finder, LiteralSearch::Handle*& handle)
+{
+    finder = s_script;
+    handle = s_handle;
+}
+
 const Parameter HttpModule::http_params[] =
 {
     { "request_depth", Parameter::PT_INT, "-1:max53", "-1",
index e81e6aa974eb91b339ed1b41ff407c8dfff753fc..24d4834ffddac4c13956f4602ce793ef0460a974 100644 (file)
@@ -24,6 +24,7 @@
 #include <bitset>
 
 #include "framework/module.h"
+#include "helpers/literal_search.h"
 #include "profiler/profiler.h"
 
 #include "http_enum.h"
@@ -95,8 +96,8 @@ public:
 class HttpModule : public snort::Module
 {
 public:
-    HttpModule() : Module(HTTP_NAME, HTTP_HELP, http_params) { }
-    ~HttpModule() override { delete params; }
+    HttpModule();
+    ~HttpModule() override;
     bool begin(const char*, int, snort::SnortConfig*) override;
     bool end(const char*, int, snort::SnortConfig*) override;
     bool set(const char*, snort::Value&, snort::SnortConfig*) override;
@@ -118,6 +119,9 @@ public:
     static PegCount get_peg_counts(HttpEnums::PEG_COUNT counter)
         { return peg_counts[counter]; }
 
+    static void get_detain_finder(snort::LiteralSearch*&, snort::LiteralSearch::Handle*&);
+    static void get_script_finder(snort::LiteralSearch*&, snort::LiteralSearch::Handle*&);
+
     snort::ProfileStats* get_profile() const override;
 
     static snort::ProfileStats& get_profile_stats()
index f5f1e86ce2edfbd7accdc432e992e67933b5a3c3..03667238c3b89007b04e7640ee2a4951f209fdd8 100644 (file)
@@ -23,6 +23,7 @@
 #include "config.h"
 #endif
 
+#include "helpers/literal_search.h"
 #include "log/messages.h"
 
 #include "service_inspectors/http_inspect/http_js_norm.h"
@@ -45,6 +46,10 @@ void ParseError(const char*, ...) {}
 
 void Value::get_bits(std::bitset<256ul>&) const {}
 int DetectionEngine::queue_event(unsigned int, unsigned int, Actions::Type) { return 0; }
+LiteralSearch::Handle* LiteralSearch::setup() { return nullptr; }
+void LiteralSearch::cleanup(LiteralSearch::Handle*) {}
+LiteralSearch* LiteralSearch::instantiate(LiteralSearch::Handle*, const uint8_t*, unsigned, bool,
+    bool) { return nullptr; }
 }
 
 void show_stats(PegCount*, const PegInfo*, unsigned, const char*) { }
index 5d095a146d3fe14689877b99081c01cae39e598b..c1db2a57e1addfedbd8780767b4fbd899f09c3ab 100644 (file)
@@ -23,7 +23,9 @@
 #include "config.h"
 #endif
 
+#include "helpers/literal_search.h"
 #include "log/messages.h"
+
 #include "service_inspectors/http_inspect/http_js_norm.h"
 #include "service_inspectors/http_inspect/http_uri_norm.h"
 
@@ -40,6 +42,10 @@ void ParseWarning(WarningGroup, const char*, ...) {}
 void ParseError(const char*, ...) {}
 void Value::get_bits(std::bitset<256ul>&) const {}
 int DetectionEngine::queue_event(unsigned int, unsigned int, Actions::Type) { return 0; }
+LiteralSearch::Handle* LiteralSearch::setup() { return nullptr; }
+void LiteralSearch::cleanup(LiteralSearch::Handle*) {}
+LiteralSearch* LiteralSearch::instantiate(LiteralSearch::Handle*, const uint8_t*, unsigned, bool,
+    bool) { return nullptr; }
 }
 
 void show_stats(PegCount*, const PegInfo*, unsigned, const char*) { }