diff --git a/src/detect-http-raw-uri.c b/src/detect-http-raw-uri.c index f3db9e0f2f..9553df23f9 100644 --- a/src/detect-http-raw-uri.c +++ b/src/detect-http-raw-uri.c @@ -39,6 +39,7 @@ #include "detect-engine-mpm.h" #include "detect-content.h" #include "detect-pcre.h" +#include "detect-urilen.h" #include "flow.h" #include "flow-var.h" @@ -58,6 +59,7 @@ static int DetectHttpRawUriSetup(DetectEngineCtx *, Signature *, const char *); static void DetectHttpRawUriRegisterTests(void); static void DetectHttpRawUriSetupCallback(Signature *s); +static bool DetectHttpRawUriValidateCallback(const Signature *s); static int g_http_raw_uri_buffer_id = 0; /** @@ -87,6 +89,9 @@ void DetectHttpRawUriRegister(void) DetectBufferTypeRegisterSetupCallback("http_raw_uri", DetectHttpRawUriSetupCallback); + DetectBufferTypeRegisterValidateCallback("http_raw_uri", + DetectHttpRawUriValidateCallback); + g_http_raw_uri_buffer_id = DetectBufferTypeGetByName("http_raw_uri"); } @@ -108,10 +113,16 @@ static int DetectHttpRawUriSetup(DetectEngineCtx *de_ctx, Signature *s, const ch ALPROTO_HTTP); } +static bool DetectHttpRawUriValidateCallback(const Signature *s) +{ + return DetectUrilenValidateContent(s, g_http_raw_uri_buffer_id); +} + static void DetectHttpRawUriSetupCallback(Signature *s) { SCLogDebug("callback invoked by %u", s->id); s->mask |= SIG_MASK_REQUIRE_HTTP_STATE; + DetectUrilenApplyToContent(s, g_http_raw_uri_buffer_id); } /******************************** UNITESTS **********************************/ diff --git a/src/detect-http-uri.c b/src/detect-http-uri.c index 30bc5ea61c..6033887638 100644 --- a/src/detect-http-uri.c +++ b/src/detect-http-uri.c @@ -39,6 +39,7 @@ #include "detect-engine-mpm.h" #include "detect-content.h" #include "detect-pcre.h" +#include "detect-urilen.h" #include "flow.h" #include "flow-var.h" @@ -58,6 +59,7 @@ static void DetectHttpUriRegisterTests(void); static void DetectHttpUriSetupCallback(Signature *s); +static bool DetectHttpUriValidateCallback(const Signature *s); static int g_http_uri_buffer_id = 0; @@ -89,6 +91,9 @@ void DetectHttpUriRegister (void) DetectBufferTypeRegisterSetupCallback("http_uri", DetectHttpUriSetupCallback); + DetectBufferTypeRegisterValidateCallback("http_uri", + DetectHttpUriValidateCallback); + g_http_uri_buffer_id = DetectBufferTypeGetByName("http_uri"); } @@ -112,10 +117,16 @@ int DetectHttpUriSetup(DetectEngineCtx *de_ctx, Signature *s, const char *str) ALPROTO_HTTP); } +static bool DetectHttpUriValidateCallback(const Signature *s) +{ + return DetectUrilenValidateContent(s, g_http_uri_buffer_id); +} + static void DetectHttpUriSetupCallback(Signature *s) { SCLogDebug("callback invoked by %u", s->id); s->mask |= SIG_MASK_REQUIRE_HTTP_STATE; + DetectUrilenApplyToContent(s, g_http_uri_buffer_id); } /******************************** UNITESTS **********************************/ diff --git a/src/detect-urilen.c b/src/detect-urilen.c index 7959b9c644..cd24edbae6 100644 --- a/src/detect-urilen.c +++ b/src/detect-urilen.c @@ -34,6 +34,7 @@ #include "detect-parse.h" #include "detect-engine.h" #include "detect-engine-state.h" +#include "detect-content.h" #include "detect-urilen.h" #include "util-debug.h" @@ -285,6 +286,83 @@ void DetectUrilenFree(void *ptr) SCFree(urilend); } +/** \brief set prefilter dsize pair + * \param s signature to get dsize value from + */ +void DetectUrilenApplyToContent(Signature *s, int list) +{ + uint16_t high = 65535; + bool found = false; + + SigMatch *sm = s->init_data->smlists[list]; + for ( ; sm != NULL; sm = sm->next) { + if (sm->type != DETECT_AL_URILEN) + continue; + + DetectUrilenData *dd = (DetectUrilenData *)sm->ctx; + + switch (dd->mode) { + case DETECT_URILEN_LT: + high = dd->urilen1 + 1; + break; + case DETECT_URILEN_EQ: + high = dd->urilen1; + break; + case DETECT_URILEN_RA: + high = dd->urilen2 + 1; + break; + case DETECT_URILEN_GT: + high = 65535; + break; + } + found = true; + } + + // skip 65535 to avoid mismatch on uri > 64k + if (!found || high == 65535) + return; + + SCLogDebug("high %u", high); + + sm = s->init_data->smlists[list]; + for ( ; sm != NULL; sm = sm->next) { + if (sm->type != DETECT_CONTENT) { + continue; + } + DetectContentData *cd = (DetectContentData *)sm->ctx; + if (cd == NULL) { + continue; + } + + if (cd->depth == 0 || cd->depth > high) { + cd->depth = (uint16_t)high; + SCLogDebug("updated %u, content %u to have depth %u " + "because of urilen.", s->id, cd->id, cd->depth); + } + } +} + +bool DetectUrilenValidateContent(const Signature *s, int list) +{ + const SigMatch *sm = s->init_data->smlists[list]; + for ( ; sm != NULL; sm = sm->next) { + if (sm->type != DETECT_CONTENT) { + continue; + } + DetectContentData *cd = (DetectContentData *)sm->ctx; + if (cd == NULL) { + continue; + } + + if (cd->depth && cd->depth < cd->content_len) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "depth or urilen %u smaller " + "than content len %u", cd->depth, cd->content_len); + return false; + } + } + return true; +} + #ifdef UNITTESTS #include "stream.h" diff --git a/src/detect-urilen.h b/src/detect-urilen.h index c853011de8..b5fe79408f 100644 --- a/src/detect-urilen.h +++ b/src/detect-urilen.h @@ -36,6 +36,8 @@ typedef struct DetectUrilenData_ { uint8_t raw_buffer; }DetectUrilenData; +bool DetectUrilenValidateContent(const Signature *s, int list); +void DetectUrilenApplyToContent(Signature *s, int list); int DetectUrilenMatch (ThreadVars *, DetectEngineThreadCtx *, Flow *, uint8_t, void *, Signature *, SigMatch *); void DetectUrilenRegister(void);