}
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);
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;
#include "http_common.h"
#include "http_enum.h"
+#include "http_module.h"
using namespace HttpEnums;
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);
}
}
}
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)
{
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;
}
#include <cassert>
#include <zlib.h>
+#include "helpers/literal_search.h"
+
#include "http_enum.h"
#include "http_event.h"
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;
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;
#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",
#include <bitset>
#include "framework/module.h"
+#include "helpers/literal_search.h"
#include "profiler/profiler.h"
#include "http_enum.h"
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;
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()
#include "config.h"
#endif
+#include "helpers/literal_search.h"
#include "log/messages.h"
#include "service_inspectors/http_inspect/http_js_norm.h"
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*) { }
#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"
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*) { }