From d1d5507679d329d54b24bfdd9f9d818f340ebb04 Mon Sep 17 00:00:00 2001 From: Anoop Saldanha Date: Wed, 8 Feb 2012 13:29:39 +0530 Subject: [PATCH] remove all old content inspection engines and references to them. We have cleaned the entire content inspection phase and improved alert accuracy --- src/detect-engine-dcepayload.c | 423 --------------------------------- src/detect-engine-hcbd.c | 253 -------------------- src/detect-engine-hcd.c | 254 -------------------- src/detect-engine-hhd.c | 254 -------------------- src/detect-engine-hmd.c | 254 -------------------- src/detect-engine-hrhd.c | 253 -------------------- src/detect-engine-hrud.c | 315 ------------------------ src/detect-engine-hsbd.c | 327 ------------------------- src/detect-engine-payload.c | 409 ------------------------------- src/detect-engine-uri.c | 372 ----------------------------- 10 files changed, 3114 deletions(-) diff --git a/src/detect-engine-dcepayload.c b/src/detect-engine-dcepayload.c index 7e558f4bde..82af29f0b1 100644 --- a/src/detect-engine-dcepayload.c +++ b/src/detect-engine-dcepayload.c @@ -29,7 +29,6 @@ #include "detect.h" #include "detect-engine.h" #include "detect-parse.h" -#include "detect-content.h" #include "detect-pcre.h" #include "detect-isdataat.h" #include "detect-bytetest.h" @@ -37,436 +36,14 @@ #include "detect-byte-extract.h" #include "detect-engine-content-inspection.h" -#include "util-spm.h" -#include "util-spm-bm.h" - -#include "stream-tcp-reassemble.h" -#include "stream-tcp.h" - #include "app-layer.h" #include "app-layer-dcerpc.h" -#include "decode-tcp.h" #include "flow-util.h" #include "util-debug.h" #include "util-unittest.h" #include "util-unittest-helper.h" -/** - * \brief Run the dce stub match functions for the dce stub based keywords. - * - * The following keywords are inspected: - * - content - * - isdaatat - * - pcre - * - bytejump - * - bytetest - * - * All keywords are evaluated against the dce stub data. - * - * For accounting the last match in relative matching, - * det_ctx->payload_offset var is used. - * - * \param de_ctx Detection engine context. - * \param det_ctx Detection engine thread context. - * \param s Signature to inspect. - * \param sm SigMatch to inspect. - * \param f Flow - * \param payload Pointer to the dce stub to inspect. - * \param payload_len Length of the payload - * - * \retval 0 No match. - * \retval 1 Match. - */ -static int DoInspectDcePayload(DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, Signature *s, - SigMatch *sm, Flow *f, uint8_t *stub, - uint32_t stub_len, DCERPCState *dcerpc_state) -{ - SCEnter(); - - det_ctx->inspection_recursion_counter++; - - if (det_ctx->inspection_recursion_counter == de_ctx->inspection_recursion_limit) { - det_ctx->discontinue_matching = 1; - SCReturnInt(0); - } - - if (sm == NULL || stub_len == 0) { - SCReturnInt(0); - } - - switch(sm->type) { - case DETECT_CONTENT: - { - DetectContentData *cd = NULL; - cd = (DetectContentData *)sm->ctx; - SCLogDebug("inspecting content %"PRIu32" stub_len %"PRIu32, - cd->id, stub_len); - - /* rule parsers should take care of this */ -#ifdef DEBUG - BUG_ON(cd->depth != 0 && cd->depth <= cd->offset); -#endif - - /* search for our pattern, checking the matches recursively. - * if we match we look for the next SigMatch as well */ - uint8_t *found = NULL; - uint32_t offset = 0; - uint32_t depth = stub_len; - uint32_t prev_offset = 0; /**< used in recursive searching */ - uint32_t prev_payload_offset = det_ctx->payload_offset; - - do { - if (cd->flags & DETECT_CONTENT_DISTANCE || - cd->flags & DETECT_CONTENT_WITHIN) { - SCLogDebug("prev_payload_offset %"PRIu32, - prev_payload_offset); - - offset = prev_payload_offset; - depth = stub_len; - - int distance = cd->distance; - if (cd->flags & DETECT_CONTENT_DISTANCE) { - if (cd->flags & DETECT_CONTENT_DISTANCE_BE) { - distance = det_ctx->bj_values[cd->distance]; - } - if (distance < 0 && (uint32_t)(abs(distance)) > offset) - offset = 0; - else - offset += distance; - - SCLogDebug("cd->distance %"PRIi32", offset %"PRIu32", depth %"PRIu32, - cd->distance, offset, depth); - } - - if (cd->flags & DETECT_CONTENT_WITHIN) { - if (cd->flags & DETECT_CONTENT_WITHIN_BE) { - if ((int32_t)depth > (int32_t)(prev_payload_offset + det_ctx->bj_values[cd->within] + distance)) { - depth = prev_payload_offset + det_ctx->bj_values[cd->within] + distance; - } - } else { - if ((int32_t)depth > (int32_t)(prev_payload_offset + cd->within + distance)) { - depth = prev_payload_offset + cd->within + distance; - } - - SCLogDebug("cd->within %"PRIi32", prev_payload_offset " - "%"PRIu32", depth %"PRIu32, cd->within, - prev_payload_offset, depth); - } - } - - if (cd->flags & DETECT_CONTENT_DEPTH_BE) { - if ((det_ctx->bj_values[cd->depth] + prev_payload_offset) < depth) { - depth = prev_payload_offset + det_ctx->bj_values[cd->depth]; - } - } else { - if (cd->depth != 0) { - if ((cd->depth + prev_payload_offset) < depth) { - depth = prev_payload_offset + cd->depth; - } - - SCLogDebug("cd->depth %"PRIu32", depth %"PRIu32, - cd->depth, depth); - } - } - - if (cd->flags & DETECT_CONTENT_OFFSET_BE) { - if (det_ctx->bj_values[cd->offset] > offset) - offset = det_ctx->bj_values[cd->offset]; - } else { - if (cd->offset > offset) { - offset = cd->offset; - SCLogDebug("setting offset %"PRIu32, offset); - } - } - - /* implied no relative matches */ - } else { - /* set depth */ - if (cd->flags & DETECT_CONTENT_DEPTH_BE) { - depth = det_ctx->bj_values[cd->depth]; - } else { - if (cd->depth != 0) { - depth = cd->depth; - } - } - - /* set offset */ - if (cd->flags & DETECT_CONTENT_OFFSET_BE) - offset = det_ctx->bj_values[cd->offset]; - else - offset = cd->offset; - prev_payload_offset = 0; - } - - /* update offset with prev_offset if we're searching for - * matches after the first occurence. */ - SCLogDebug("offset %"PRIu32", prev_offset %"PRIu32, offset, - prev_offset); - if (prev_offset != 0) - offset = prev_offset; - - SCLogDebug("offset %"PRIu32", depth %"PRIu32, offset, depth); - - if (depth > stub_len) - depth = stub_len; - - /* if offset is bigger than depth we can never match on a - * pattern. We can however, "match" on a negated pattern. */ - /* \todo why isn't it >= ?. Same question applies for - * detect-engine-dcepayload.c and detect-engine-uri.c */ - if (offset > depth || depth == 0) { - if (cd->flags & DETECT_CONTENT_NEGATED) { - goto match; - } else { - SCReturnInt(0); - } - } - - uint8_t *sstub = stub + offset; - uint32_t sstub_len = depth - offset; - uint32_t match_offset = 0; - SCLogDebug("sstub_len %"PRIu32, sstub_len); -#ifdef DEBUG - BUG_ON(sstub_len > stub_len); -#endif - - /* do the actual search */ - if (cd->flags & DETECT_CONTENT_NOCASE) { - found = BoyerMooreNocase(cd->content, cd->content_len, sstub, - sstub_len, cd->bm_ctx->bmGs, - cd->bm_ctx->bmBc); - } else { - found = BoyerMoore(cd->content, cd->content_len, sstub, - sstub_len, cd->bm_ctx->bmGs, - cd->bm_ctx->bmBc); - } - - /* next we evaluate the result in combination with the - * negation flag. */ - SCLogDebug("found %p cd negated %s", found, - cd->flags & DETECT_CONTENT_NEGATED ? "true" : "false"); - - if (found == NULL && !(cd->flags & DETECT_CONTENT_NEGATED)) { - SCReturnInt(0); - } else if (found == NULL && cd->flags & DETECT_CONTENT_NEGATED) { - goto match; - } else if (found != NULL && cd->flags & DETECT_CONTENT_NEGATED) { - SCLogDebug("content %"PRIu32" matched at offset %"PRIu32", but " - "negated so no match", cd->id, match_offset); - det_ctx->discontinue_matching = 1; - SCReturnInt(0); - } else { - match_offset = (uint32_t)((found - stub) + cd->content_len); - SCLogDebug("content %"PRIu32" matched at offset %"PRIu32"", - cd->id, match_offset); - det_ctx->payload_offset = match_offset; - - if (!(cd->flags & DETECT_CONTENT_RELATIVE_NEXT)) { - SCLogDebug("no relative match coming up, so this is a match"); - goto match; - } - - /* bail out if we have no next match. Technically this is an - * error, as the current cd has the DETECT_CONTENT_RELATIVE_NEXT - * flag set. */ - if (sm->next == NULL) { - SCReturnInt(0); - } - - SCLogDebug("content %"PRIu32, cd->id); - - /* see if the next payload keywords match. If not, we will - * search for another occurence of this content and see - * if the others match then until we run out of matches */ - int r = DoInspectDcePayload(de_ctx, det_ctx, s, sm->next, - f, stub, stub_len, dcerpc_state); - if (r == 1) { - SCReturnInt(1); - } - - if (det_ctx->discontinue_matching) - SCReturnInt(0); - - /* set the previous match offset to the start of this match + 1 */ - prev_offset = (match_offset - (cd->content_len - 1)); - SCLogDebug("trying to see if there is another match after " - "prev_offset %"PRIu32, prev_offset); - } - - } while(1); - } - - case DETECT_ISDATAAT: - { - SCLogDebug("inspecting isdataat"); - - DetectIsdataatData *id = (DetectIsdataatData *)sm->ctx; - if (id->flags & ISDATAAT_RELATIVE) { - if (det_ctx->payload_offset + id->dataat > stub_len) { - SCLogDebug("det_ctx->payload_offset + id->dataat " - "%"PRIu32" > %"PRIu32, - det_ctx->payload_offset + id->dataat, stub_len); - SCReturnInt(0); - } else { - SCLogDebug("relative isdataat match"); - goto match; - } - } else { - if (id->dataat < stub_len) { - SCLogDebug("absolute isdataat match"); - goto match; - } else { - SCLogDebug("absolute isdataat mismatch, id->isdataat %"PRIu32", " - "stub_len %"PRIu32"", id->dataat, stub_len); - SCReturnInt(0); - } - } - } - - case DETECT_PCRE: - { - SCLogDebug("inspecting pcre"); - DetectPcreData *pe = (DetectPcreData *)sm->ctx; - uint32_t prev_payload_offset = det_ctx->payload_offset; - uint32_t prev_offset = 0; - int r = 0; - - det_ctx->pcre_match_start_offset = 0; - do { - r = DetectPcrePayloadMatch(det_ctx, s, sm, NULL, f, - stub, stub_len); - if (r == 0) { - det_ctx->discontinue_matching = 1; - SCReturnInt(0); - } - - if (!(pe->flags & DETECT_PCRE_RELATIVE_NEXT)) { - SCLogDebug("no relative match coming up, so this is a match"); - goto match; - } - - /* save it, in case we need to do a pcre match once again */ - prev_offset = det_ctx->pcre_match_start_offset; - - /* see if the next payload keywords match. If not, we will - * search for another occurence of this pcre and see - * if the others match, until we run out of matches */ - r = DoInspectDcePayload(de_ctx, det_ctx, s, sm->next, f, stub, - stub_len, dcerpc_state); - if (r == 1) { - SCReturnInt(1); - } - - if (det_ctx->discontinue_matching) - SCReturnInt(0); - - det_ctx->payload_offset = prev_payload_offset; - det_ctx->pcre_match_start_offset = prev_offset; - } while (1); - } - case DETECT_BYTETEST: - { - DetectBytetestData *data = (DetectBytetestData *)sm->ctx; - uint8_t flags = data->flags; - int32_t offset = data->offset;; - uint64_t value = data->value; - if (flags & DETECT_BYTETEST_OFFSET_BE) { - offset = det_ctx->bj_values[offset]; - } - if (flags & DETECT_BYTETEST_VALUE_BE) { - value = det_ctx->bj_values[value]; - } - - /* if we have dce enabled we will have to use the endianness - * specified by the dce header */ - if (flags & DETECT_BYTETEST_DCE) { - /* enable the endianness flag temporarily. once we are done - * processing we reset the flags to the original value*/ - flags |= ((dcerpc_state->dcerpc.dcerpchdr.packed_drep[0] & 0x10) ? - DETECT_BYTETEST_LITTLE: 0); - } - - if (DetectBytetestDoMatch(det_ctx, s, sm, stub, stub_len, flags, offset, value) != 1) { - SCReturnInt(0); - } - - goto match; - } - - case DETECT_BYTEJUMP: - { - DetectBytejumpData *data = (DetectBytejumpData *)sm->ctx; - uint8_t flags = data->flags; - int32_t offset = data->offset;; - if (flags & DETECT_BYTEJUMP_OFFSET_BE) { - offset = det_ctx->bj_values[offset]; - } - - /* if we have dce enabled we will have to use the endianness - * specified by the dce header */ - if (flags & DETECT_BYTEJUMP_DCE) { - /* enable the endianness flag temporarily. once we are done - * processing we reset the flags to the original value*/ - flags |= ((dcerpc_state->dcerpc.dcerpchdr.packed_drep[0] & 0x10) ? - DETECT_BYTEJUMP_LITTLE : 0); - } - - if (DetectBytejumpDoMatch(det_ctx, s, sm, stub, stub_len, flags, offset) != 1) { - SCReturnInt(0); - } - - goto match; - } - - case DETECT_BYTE_EXTRACT: - { - DetectByteExtractData *bed = (DetectByteExtractData *)sm->ctx; - uint8_t endian = bed->endian; - - /* if we have dce enabled we will have to use the endianness - * specified by the dce header */ - if (bed->flags & DETECT_BYTE_EXTRACT_FLAG_ENDIAN && - endian == DETECT_BYTE_EXTRACT_ENDIAN_DCE) { - - /* enable the endianness flag temporarily. once we are done - * processing we reset the flags to the original value*/ - endian |= ((dcerpc_state->dcerpc.dcerpchdr.packed_drep[0] == 0x10) ? - DETECT_BYTE_EXTRACT_ENDIAN_LITTLE : DETECT_BYTE_EXTRACT_ENDIAN_BIG); - } - if (DetectByteExtractDoMatch(det_ctx, sm, s, stub, stub_len, - &det_ctx->bj_values[bed->local_id], endian) != 1) { - SCReturnInt(0); - } - - goto match; - } - - /* we should never get here, but bail out just in case */ - default: - { - SCLogDebug("sm->type %u", sm->type); -#ifdef DEBUG - BUG_ON(1); -#endif - } - } - - SCReturnInt(0); - -match: - /* this sigmatch matched, inspect the next one. If it was the last, - * the payload portion of the signature matched. */ - if (sm->next != NULL) { - int r = DoInspectDcePayload(de_ctx, det_ctx, s, sm->next, f, stub, - stub_len, dcerpc_state); - SCReturnInt(r); - } else { - SCReturnInt(1); - } -} - /** * \brief Do the content inspection & validation for a signature against dce stub. * diff --git a/src/detect-engine-hcbd.c b/src/detect-engine-hcbd.c index a351ef3cc6..63ea81c98e 100644 --- a/src/detect-engine-hcbd.c +++ b/src/detect-engine-hcbd.c @@ -40,24 +40,13 @@ #include "detect-engine-mpm.h" #include "detect-parse.h" #include "detect-engine-state.h" -#include "detect-pcre.h" -#include "detect-isdataat.h" -#include "detect-bytetest.h" -#include "detect-bytejump.h" #include "detect-engine-content-inspection.h" #include "flow-util.h" -#include "util-spm.h" #include "util-debug.h" #include "util-print.h" #include "flow.h" -#include "detect-flow.h" -#include "flow-var.h" -#include "threads.h" -#include "flow-alert-sid.h" -#include "stream-tcp.h" -#include "stream.h" #include "app-layer-parser.h" #include "util-unittest.h" @@ -66,248 +55,6 @@ #include "app-layer-htp.h" #include "app-layer-protos.h" -/** - * \brief Run the actual payload match function for http request body. - * - * For accounting the last match in relative matching the - * det_ctx->payload_offset int is used. - * - * \param de_ctx Detection engine context. - * \param det_ctx Detection engine thread context. - * \param s Signature to inspect. - * \param sm SigMatch to inspect. - * \param payload Ptr to the request body to inspect. - * \param payload_len Length of the request body. - * - * \retval 0 no match. - * \retval 1 match. - */ -static int DoInspectHttpClientBody(DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, SigMatch *sm, - uint8_t *payload, uint32_t payload_len) -{ - SCEnter(); - - det_ctx->inspection_recursion_counter++; - - if (det_ctx->inspection_recursion_counter == de_ctx->inspection_recursion_limit) { - det_ctx->discontinue_matching = 1; - SCReturnInt(0); - } - - if (sm == NULL) { - SCReturnInt(0); - } - - if (sm->type == DETECT_AL_HTTP_CLIENT_BODY) { - if (payload_len == 0) { - SCReturnInt(0); - } - - DetectContentData *cd = (DetectContentData *)sm->ctx; - SCLogDebug("inspecting content %"PRIu32" payload_len %"PRIu32, cd->id, payload_len); - - //if (cd->flags & DETECT_CONTENT_HCBD_MPM && !(cd->flags & DETECT_CONTENT_NEGATED)) - // goto match; - - /* rule parsers should take care of this */ -#ifdef DEBUG - BUG_ON(cd->depth != 0 && cd->depth <= cd->offset); -#endif - - /* search for our pattern, checking the matches recursively. - * if we match we look for the next SigMatch as well */ - uint8_t *found = NULL; - uint32_t offset = 0; - uint32_t depth = payload_len; - uint32_t prev_offset = 0; /**< used in recursive searching */ - uint32_t prev_payload_offset = det_ctx->payload_offset; - - do { - if (cd->flags & DETECT_CONTENT_DISTANCE || - cd->flags & DETECT_CONTENT_WITHIN) { - SCLogDebug("prev_payload_offset %"PRIu32, prev_payload_offset); - - offset = prev_payload_offset; - depth = payload_len; - - if (cd->flags & DETECT_CONTENT_DISTANCE) { - if (cd->distance < 0 && (uint32_t)(abs(cd->distance)) > offset) - offset = 0; - else - offset += cd->distance; - } - - if (cd->flags & DETECT_CONTENT_WITHIN) { - if ((int32_t)depth > (int32_t)(prev_payload_offset + cd->within + cd->distance)) { - depth = prev_payload_offset + cd->within + cd->distance; - } - } - - if (cd->depth != 0) { - if ((cd->depth + prev_payload_offset) < depth) { - depth = prev_payload_offset + cd->depth; - } - } - - if (cd->offset > offset) { - offset = cd->offset; - } - } else { /* implied no relative matches */ - /* set depth */ - if (cd->depth != 0) { - depth = cd->depth; - } - - /* set offset */ - offset = cd->offset; - prev_payload_offset = 0; - } - - /* update offset with prev_offset if we're searching for - * matches after the first occurence. */ - if (prev_offset != 0) - offset = prev_offset; - - if (depth > payload_len) - depth = payload_len; - - /* if offset is bigger than depth we can never match on a pattern. - * We can however, "match" on a negated pattern. */ - if (offset > depth || depth == 0) { - if (cd->flags & DETECT_CONTENT_NEGATED) { - goto match; - } else { - SCReturnInt(0); - } - } - - uint8_t *spayload = payload + offset; - uint32_t spayload_len = depth - offset; - uint32_t match_offset = 0; -#ifdef DEBUG - BUG_ON(spayload_len > payload_len); -#endif - - /* do the actual search with boyer moore precooked ctx */ - if (cd->flags & DETECT_CONTENT_NOCASE) { - found = BoyerMooreNocase(cd->content, cd->content_len, - spayload, spayload_len, - cd->bm_ctx->bmGs, cd->bm_ctx->bmBc); - } else { - found = BoyerMoore(cd->content, cd->content_len, - spayload, spayload_len, - cd->bm_ctx->bmGs, cd->bm_ctx->bmBc); - } - - /* next we evaluate the result in combination with the - * negation flag. */ - if (found == NULL && !(cd->flags & DETECT_CONTENT_NEGATED)) { - SCReturnInt(0); - } else if (found == NULL && cd->flags & DETECT_CONTENT_NEGATED) { - goto match; - } else if (found != NULL && cd->flags & DETECT_CONTENT_NEGATED) { - det_ctx->discontinue_matching = 1; - SCReturnInt(0); - } else { - match_offset = (uint32_t)((found - payload) + cd->content_len); - det_ctx->payload_offset = match_offset; - - if (!(cd->flags & DETECT_CONTENT_RELATIVE_NEXT)) { - SCLogDebug("no relative match coming up, so this is a match"); - goto match; - } - - /* bail out if we have no next match. Technically this is an - * error, as the current cd has the DETECT_CONTENT_RELATIVE_NEXT - * flag set. */ - if (sm->next == NULL) { - SCReturnInt(0); - } - - /* see if the next payload keywords match. If not, we will - * search for another occurence of this http client body content - * and see if the others match then until we run out of matches */ - int r = DoInspectHttpClientBody(de_ctx, det_ctx, s, sm->next, - payload, payload_len); - if (r == 1) { - SCReturnInt(1); - } - - if (det_ctx->discontinue_matching) - SCReturnInt(0); - - /* set the previous match offset to the start of this match + 1 */ - prev_offset = (match_offset - (cd->content_len - 1)); - SCLogDebug("trying to see if there is another match after " - "prev_offset %"PRIu32, prev_offset); - } - - } while(1); - - } else if (sm->type == DETECT_PCRE) { - SCLogDebug("inspecting pcre"); - DetectPcreData *pe = (DetectPcreData *)sm->ctx; - uint32_t prev_payload_offset = det_ctx->payload_offset; - uint32_t prev_offset = 0; - int r = 0; - - det_ctx->pcre_match_start_offset = 0; - do { - r = DetectPcrePayloadMatch(det_ctx, s, sm, NULL, NULL, - payload, payload_len); - - if (r == 0) { - det_ctx->discontinue_matching = 1; - SCReturnInt(0); - } - - if (!(pe->flags & DETECT_PCRE_RELATIVE_NEXT)) { - SCLogDebug("no relative match coming up, so this is a match"); - goto match; - } - - /* save it, in case we need to do a pcre match once again */ - prev_offset = det_ctx->pcre_match_start_offset; - - /* see if the next payload keywords match. If not, we will - * search for another occurence of this pcre and see - * if the others match, until we run out of matches */ - int r = DoInspectHttpClientBody(de_ctx, det_ctx, s, sm->next, - payload, payload_len); - if (r == 1) { - SCReturnInt(1); - } - - if (det_ctx->discontinue_matching) - SCReturnInt(0); - - det_ctx->payload_offset = prev_payload_offset; - det_ctx->pcre_match_start_offset = prev_offset; - } while (1); - } else { - /* we should never get here, but bail out just in case */ - SCLogDebug("sm->type %u", sm->type); -#ifdef DEBUG - BUG_ON(1); -#endif - } - - SCReturnInt(0); - -match: - /* this sigmatch matched, inspect the next one. If it was the last, - * the payload portion of the signature matched. */ - if (sm->next != NULL) { - int r = DoInspectHttpClientBody(de_ctx, det_ctx, s, sm->next, payload, - payload_len); - SCReturnInt(r); - } else { - SCReturnInt(1); - } -} - /** * \brief Helps buffer request bodies for different transactions and stores them * away in detection code. diff --git a/src/detect-engine-hcd.c b/src/detect-engine-hcd.c index d5e42a1e8e..49b2e016c2 100644 --- a/src/detect-engine-hcd.c +++ b/src/detect-engine-hcd.c @@ -40,24 +40,13 @@ #include "detect-engine-mpm.h" #include "detect-parse.h" #include "detect-engine-state.h" -#include "detect-pcre.h" -#include "detect-isdataat.h" -#include "detect-bytetest.h" -#include "detect-bytejump.h" #include "detect-engine-content-inspection.h" #include "flow-util.h" -#include "util-spm.h" #include "util-debug.h" #include "util-print.h" #include "flow.h" -#include "detect-flow.h" -#include "flow-var.h" -#include "threads.h" -#include "flow-alert-sid.h" -#include "stream-tcp.h" -#include "stream.h" #include "app-layer-parser.h" #include "util-unittest.h" @@ -66,249 +55,6 @@ #include "app-layer-htp.h" #include "app-layer-protos.h" -/** - * \brief Run the actual payload match function for http cookie. - * - * For accounting the last match in relative matching the - * det_ctx->payload_offset var is used. - * - * \param de_ctx Detection engine context. - * \param det_ctx Detection engine thread context. - * \param s Signature to inspect. - * \param sm SigMatch to inspect. - * \param payload Ptr to the http cookie buffer to inspect. - * \param payload_len Length of the http cookie buffer. - * - * \retval 0 no match. - * \retval 1 match. - */ -static int DoInspectHttpCookie(DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, SigMatch *sm, - uint8_t *payload, uint32_t payload_len) -{ - SCEnter(); - - det_ctx->inspection_recursion_counter++; - - if (det_ctx->inspection_recursion_counter == de_ctx->inspection_recursion_limit) { - det_ctx->discontinue_matching = 1; - SCReturnInt(0); - } - - if (sm == NULL) { - SCReturnInt(0); - } - - if (sm->type == DETECT_AL_HTTP_COOKIE) { - if (payload_len == 0) { - SCReturnInt(0); - } - - DetectContentData *cd = (DetectContentData *)sm->ctx; - SCLogDebug("inspecting http cookie %"PRIu32" payload_len %"PRIu32, - cd->id, payload_len); - - //if (cd->flags & DETECT_CONTENT_HCD_MPM && !(cd->flags & DETECT_CONTENT_NEGATED)) - // goto match; - - /* rule parsers should take care of this */ -#ifdef DEBUG - BUG_ON(cd->depth != 0 && cd->depth <= cd->offset); -#endif - - /* search for our pattern, checking the matches recursively. - * if we match we look for the next SigMatch as well */ - uint8_t *found = NULL; - uint32_t offset = 0; - uint32_t depth = payload_len; - uint32_t prev_offset = 0; /**< used in recursive searching */ - uint32_t prev_payload_offset = det_ctx->payload_offset; - - do { - if (cd->flags & DETECT_CONTENT_DISTANCE || - cd->flags & DETECT_CONTENT_WITHIN) { - SCLogDebug("prev_payload_offset %"PRIu32, prev_payload_offset); - - offset = prev_payload_offset; - depth = payload_len; - - if (cd->flags & DETECT_CONTENT_DISTANCE) { - if (cd->distance < 0 && (uint32_t)(abs(cd->distance)) > offset) - offset = 0; - else - offset += cd->distance; - } - - if (cd->flags & DETECT_CONTENT_WITHIN) { - if ((int32_t)depth > (int32_t)(prev_payload_offset + cd->within + cd->distance)) { - depth = prev_payload_offset + cd->within + cd->distance; - } - } - - if (cd->depth != 0) { - if ((cd->depth + prev_payload_offset) < depth) { - depth = prev_payload_offset + cd->depth; - } - } - - if (cd->offset > offset) { - offset = cd->offset; - } - } else { /* implied no relative matches */ - /* set depth */ - if (cd->depth != 0) { - depth = cd->depth; - } - - /* set offset */ - offset = cd->offset; - prev_payload_offset = 0; - } - - /* update offset with prev_offset if we're searching for - * matches after the first occurence. */ - if (prev_offset != 0) - offset = prev_offset; - - if (depth > payload_len) - depth = payload_len; - - /* if offset is bigger than depth we can never match on a pattern. - * We can however, "match" on a negated pattern. */ - if (offset > depth || depth == 0) { - if (cd->flags & DETECT_CONTENT_NEGATED) { - goto match; - } else { - SCReturnInt(0); - } - } - - uint8_t *spayload = payload + offset; - uint32_t spayload_len = depth - offset; - uint32_t match_offset = 0; -#ifdef DEBUG - BUG_ON(spayload_len > payload_len); -#endif - - /* do the actual search with boyer moore precooked ctx */ - if (cd->flags & DETECT_CONTENT_NOCASE) { - found = BoyerMooreNocase(cd->content, cd->content_len, - spayload, spayload_len, - cd->bm_ctx->bmGs, cd->bm_ctx->bmBc); - } else { - found = BoyerMoore(cd->content, cd->content_len, - spayload, spayload_len, - cd->bm_ctx->bmGs, cd->bm_ctx->bmBc); - } - - /* next we evaluate the result in combination with the - * negation flag. */ - if (found == NULL && !(cd->flags & DETECT_CONTENT_NEGATED)) { - SCReturnInt(0); - } else if (found == NULL && cd->flags & DETECT_CONTENT_NEGATED) { - goto match; - } else if (found != NULL && cd->flags & DETECT_CONTENT_NEGATED) { - det_ctx->discontinue_matching = 1; - SCReturnInt(0); - } else { - match_offset = (uint32_t)((found - payload) + cd->content_len); - det_ctx->payload_offset = match_offset; - - if (!(cd->flags & DETECT_CONTENT_RELATIVE_NEXT)) { - SCLogDebug("no relative match coming up, so this is a match"); - goto match; - } - - /* bail out if we have no next match. Technically this is an - * error, as the current cd has the DETECT_CONTENT_RELATIVE_NEXT - * flag set. */ - if (sm->next == NULL) { - SCReturnInt(0); - } - - /* see if the next payload keywords match. If not, we will - * search for another occurence of this http cookie content - * and see if the others match then until we run out of matches */ - int r = DoInspectHttpCookie(de_ctx, det_ctx, s, sm->next, - payload, payload_len); - if (r == 1) { - SCReturnInt(1); - } - - if (det_ctx->discontinue_matching) - SCReturnInt(0); - - /* set the previous match offset to the start of this match + 1 */ - prev_offset = (match_offset - (cd->content_len - 1)); - SCLogDebug("trying to see if there is another match after " - "prev_offset %"PRIu32, prev_offset); - } - - } while(1); - - } else if (sm->type == DETECT_PCRE_HTTPCOOKIE) { - SCLogDebug("inspecting pcre"); - DetectPcreData *pe = (DetectPcreData *)sm->ctx; - uint32_t prev_payload_offset = det_ctx->payload_offset; - uint32_t prev_offset = 0; - int r = 0; - - det_ctx->pcre_match_start_offset = 0; - do { - r = DetectPcrePayloadMatch(det_ctx, s, sm, NULL, NULL, - payload, payload_len); - - if (r == 0) { - det_ctx->discontinue_matching = 1; - SCReturnInt(0); - } - - if (!(pe->flags & DETECT_PCRE_RELATIVE_NEXT)) { - SCLogDebug("no relative match coming up, so this is a match"); - goto match; - } - - /* save it, in case we need to do a pcre match once again */ - prev_offset = det_ctx->pcre_match_start_offset; - - /* see if the next payload keywords match. If not, we will - * search for another occurence of this pcre and see - * if the others match, until we run out of matches */ - int r = DoInspectHttpCookie(de_ctx, det_ctx, s, sm->next, - payload, payload_len); - if (r == 1) { - SCReturnInt(1); - } - - if (det_ctx->discontinue_matching) - SCReturnInt(0); - - det_ctx->payload_offset = prev_payload_offset; - det_ctx->pcre_match_start_offset = prev_offset; - } while (1); - } else { - /* we should never get here, but bail out just in case */ - SCLogDebug("sm->type %u", sm->type); -#ifdef DEBUG - BUG_ON(1); -#endif - } - - SCReturnInt(0); - -match: - /* this sigmatch matched, inspect the next one. If it was the last, - * the payload portion of the signature matched. */ - if (sm->next != NULL) { - int r = DoInspectHttpCookie(de_ctx, det_ctx, s, sm->next, payload, - payload_len); - SCReturnInt(r); - } else { - SCReturnInt(1); - } -} - int DetectEngineRunHttpCookieMpm(DetectEngineThreadCtx *det_ctx, Flow *f, HtpState *htp_state, uint8_t flags) { diff --git a/src/detect-engine-hhd.c b/src/detect-engine-hhd.c index 431b116e66..4b89605551 100644 --- a/src/detect-engine-hhd.c +++ b/src/detect-engine-hhd.c @@ -40,24 +40,13 @@ #include "detect-engine-mpm.h" #include "detect-parse.h" #include "detect-engine-state.h" -#include "detect-pcre.h" -#include "detect-isdataat.h" -#include "detect-bytetest.h" -#include "detect-bytejump.h" #include "detect-engine-content-inspection.h" #include "flow-util.h" -#include "util-spm.h" #include "util-debug.h" #include "util-print.h" #include "flow.h" -#include "detect-flow.h" -#include "flow-var.h" -#include "threads.h" -#include "flow-alert-sid.h" -#include "stream-tcp.h" -#include "stream.h" #include "app-layer-parser.h" #include "util-unittest.h" @@ -66,249 +55,6 @@ #include "app-layer-htp.h" #include "app-layer-protos.h" -/** - * \brief Run the actual payload match function for http header. - * - * For accounting the last match in relative matching the - * det_ctx->payload_offset var is used. - * - * \param de_ctx Detection engine context. - * \param det_ctx Detection engine thread context. - * \param s Signature to inspect. - * \param sm SigMatch to inspect. - * \param payload Ptr to the http headers buffer to inspect. - * \param payload_len Length of the http headers buffer. - * - * \retval 0 no match. - * \retval 1 match. - */ -static int DoInspectHttpHeader(DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, SigMatch *sm, - uint8_t *payload, uint32_t payload_len) -{ - SCEnter(); - - det_ctx->inspection_recursion_counter++; - - if (det_ctx->inspection_recursion_counter == de_ctx->inspection_recursion_limit) { - det_ctx->discontinue_matching = 1; - SCReturnInt(0); - } - - if (sm == NULL) { - SCReturnInt(0); - } - - if (sm->type == DETECT_AL_HTTP_HEADER) { - if (payload_len == 0) { - SCReturnInt(0); - } - - DetectContentData *cd = (DetectContentData *)sm->ctx; - SCLogDebug("inspecting http headers %"PRIu32" payload_len %"PRIu32, - cd->id, payload_len); - - //if (cd->flags & DETECT_CONTENT_HHD_MPM && !(cd->flags & DETECT_CONTENT_NEGATED)) - // goto match; - - /* rule parsers should take care of this */ -#ifdef DEBUG - BUG_ON(cd->depth != 0 && cd->depth <= cd->offset); -#endif - - /* search for our pattern, checking the matches recursively. - * if we match we look for the next SigMatch as well */ - uint8_t *found = NULL; - uint32_t offset = 0; - uint32_t depth = payload_len; - uint32_t prev_offset = 0; /**< used in recursive searching */ - uint32_t prev_payload_offset = det_ctx->payload_offset; - - do { - if (cd->flags & DETECT_CONTENT_DISTANCE || - cd->flags & DETECT_CONTENT_WITHIN) { - SCLogDebug("prev_payload_offset %"PRIu32, prev_payload_offset); - - offset = prev_payload_offset; - depth = payload_len; - - if (cd->flags & DETECT_CONTENT_DISTANCE) { - if (cd->distance < 0 && (uint32_t)(abs(cd->distance)) > offset) - offset = 0; - else - offset += cd->distance; - } - - if (cd->flags & DETECT_CONTENT_WITHIN) { - if ((int32_t)depth > (int32_t)(prev_payload_offset + cd->within + cd->distance)) { - depth = prev_payload_offset + cd->within + cd->distance; - } - } - - if (cd->depth != 0) { - if ((cd->depth + prev_payload_offset) < depth) { - depth = prev_payload_offset + cd->depth; - } - } - - if (cd->offset > offset) { - offset = cd->offset; - } - } else { /* implied no relative matches */ - /* set depth */ - if (cd->depth != 0) { - depth = cd->depth; - } - - /* set offset */ - offset = cd->offset; - prev_payload_offset = 0; - } - - /* update offset with prev_offset if we're searching for - * matches after the first occurence. */ - if (prev_offset != 0) - offset = prev_offset; - - if (depth > payload_len) - depth = payload_len; - - /* if offset is bigger than depth we can never match on a pattern. - * We can however, "match" on a negated pattern. */ - if (offset > depth || depth == 0) { - if (cd->flags & DETECT_CONTENT_NEGATED) { - goto match; - } else { - SCReturnInt(0); - } - } - - uint8_t *spayload = payload + offset; - uint32_t spayload_len = depth - offset; - uint32_t match_offset = 0; -#ifdef DEBUG - BUG_ON(spayload_len > payload_len); -#endif - - /* do the actual search with boyer moore precooked ctx */ - if (cd->flags & DETECT_CONTENT_NOCASE) { - found = BoyerMooreNocase(cd->content, cd->content_len, - spayload, spayload_len, - cd->bm_ctx->bmGs, cd->bm_ctx->bmBc); - } else { - found = BoyerMoore(cd->content, cd->content_len, - spayload, spayload_len, - cd->bm_ctx->bmGs, cd->bm_ctx->bmBc); - } - - /* next we evaluate the result in combination with the - * negation flag. */ - if (found == NULL && !(cd->flags & DETECT_CONTENT_NEGATED)) { - SCReturnInt(0); - } else if (found == NULL && cd->flags & DETECT_CONTENT_NEGATED) { - goto match; - } else if (found != NULL && cd->flags & DETECT_CONTENT_NEGATED) { - det_ctx->discontinue_matching = 1; - SCReturnInt(0); - } else { - match_offset = (uint32_t)((found - payload) + cd->content_len); - det_ctx->payload_offset = match_offset; - - if (!(cd->flags & DETECT_CONTENT_RELATIVE_NEXT)) { - SCLogDebug("no relative match coming up, so this is a match"); - goto match; - } - - /* bail out if we have no next match. Technically this is an - * error, as the current cd has the DETECT_CONTENT_RELATIVE_NEXT - * flag set. */ - if (sm->next == NULL) { - SCReturnInt(0); - } - - /* see if the next payload keywords match. If not, we will - * search for another occurence of this http header content and - * see if the others match then until we run out of matches */ - int r = DoInspectHttpHeader(de_ctx, det_ctx, s, sm->next, - payload, payload_len); - if (r == 1) { - SCReturnInt(1); - } - - if (det_ctx->discontinue_matching) - SCReturnInt(0); - - /* set the previous match offset to the start of this match + 1 */ - prev_offset = (match_offset - (cd->content_len - 1)); - SCLogDebug("trying to see if there is another match after " - "prev_offset %"PRIu32, prev_offset); - } - - } while(1); - - } else if (sm->type == DETECT_PCRE) { - SCLogDebug("inspecting pcre"); - DetectPcreData *pe = (DetectPcreData *)sm->ctx; - uint32_t prev_payload_offset = det_ctx->payload_offset; - uint32_t prev_offset = 0; - int r = 0; - - det_ctx->pcre_match_start_offset = 0; - do { - r = DetectPcrePayloadMatch(det_ctx, s, sm, NULL, NULL, - payload, payload_len); - - if (r == 0) { - det_ctx->discontinue_matching = 1; - SCReturnInt(0); - } - - if (!(pe->flags & DETECT_PCRE_RELATIVE_NEXT)) { - SCLogDebug("no relative match coming up, so this is a match"); - goto match; - } - - /* save it, in case we need to do a pcre match once again */ - prev_offset = det_ctx->pcre_match_start_offset; - - /* see if the next payload keywords match. If not, we will - * search for another occurence of this pcre and see - * if the others match, until we run out of matches */ - int r = DoInspectHttpHeader(de_ctx, det_ctx, s, sm->next, - payload, payload_len); - if (r == 1) { - SCReturnInt(1); - } - - if (det_ctx->discontinue_matching) - SCReturnInt(0); - - det_ctx->payload_offset = prev_payload_offset; - det_ctx->pcre_match_start_offset = prev_offset; - } while (1); - } else { - /* we should never get here, but bail out just in case */ - SCLogDebug("sm->type %u", sm->type); -#ifdef DEBUG - BUG_ON(1); -#endif - } - - SCReturnInt(0); - -match: - /* this sigmatch matched, inspect the next one. If it was the last, - * the payload portion of the signature matched. */ - if (sm->next != NULL) { - int r = DoInspectHttpHeader(de_ctx, det_ctx, s, sm->next, payload, - payload_len); - SCReturnInt(r); - } else { - SCReturnInt(1); - } -} - /** * \brief Helps buffer http normalized headers from different transactions and * stores them away in detection context. diff --git a/src/detect-engine-hmd.c b/src/detect-engine-hmd.c index dd57e71ce3..153ee0088f 100644 --- a/src/detect-engine-hmd.c +++ b/src/detect-engine-hmd.c @@ -40,24 +40,13 @@ #include "detect-engine-mpm.h" #include "detect-parse.h" #include "detect-engine-state.h" -#include "detect-pcre.h" -#include "detect-isdataat.h" -#include "detect-bytetest.h" -#include "detect-bytejump.h" #include "detect-engine-content-inspection.h" #include "flow-util.h" -#include "util-spm.h" #include "util-debug.h" #include "util-print.h" #include "flow.h" -#include "detect-flow.h" -#include "flow-var.h" -#include "threads.h" -#include "flow-alert-sid.h" -#include "stream-tcp.h" -#include "stream.h" #include "app-layer-parser.h" #include "util-unittest.h" @@ -66,249 +55,6 @@ #include "app-layer-htp.h" #include "app-layer-protos.h" -/** - * \brief Run the actual payload match function for http method. - * - * For accounting the last match in relative matching the - * det_ctx->payload_offset var is used. - * - * \param de_ctx Detection engine context. - * \param det_ctx Detection engine thread context. - * \param s Signature to inspect. - * \param sm SigMatch to inspect. - * \param payload Ptr to the http method buffer to inspect. - * \param payload_len Length of the http raw headers buffer. - * - * \retval 0 no match. - * \retval 1 match. - */ -static int DoInspectHttpMethod(DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, SigMatch *sm, - uint8_t *payload, uint32_t payload_len) -{ - SCEnter(); - - det_ctx->inspection_recursion_counter++; - - if (det_ctx->inspection_recursion_counter == de_ctx->inspection_recursion_limit) { - det_ctx->discontinue_matching = 1; - SCReturnInt(0); - } - - if (sm == NULL) { - SCReturnInt(0); - } - - if (sm->type == DETECT_AL_HTTP_METHOD) { - if (payload_len == 0) { - SCReturnInt(0); - } - - DetectContentData *cd = (DetectContentData *)sm->ctx; - SCLogDebug("inspecting http method %"PRIu32" payload_len %"PRIu32, - cd->id, payload_len); - - //if (cd->flags & DETECT_CONTENT_HMD_MPM && !(cd->flags & DETECT_CONTENT_NEGATED)) - // goto match; - - /* rule parsers should take care of this */ -#ifdef DEBUG - BUG_ON(cd->depth != 0 && cd->depth <= cd->offset); -#endif - - /* search for our pattern, checking the matches recursively. - * if we match we look for the next SigMatch as well */ - uint8_t *found = NULL; - uint32_t offset = 0; - uint32_t depth = payload_len; - uint32_t prev_offset = 0; /**< used in recursive searching */ - uint32_t prev_payload_offset = det_ctx->payload_offset; - - do { - if (cd->flags & DETECT_CONTENT_DISTANCE || - cd->flags & DETECT_CONTENT_WITHIN) { - SCLogDebug("prev_payload_offset %"PRIu32, prev_payload_offset); - - offset = prev_payload_offset; - depth = payload_len; - - if (cd->flags & DETECT_CONTENT_DISTANCE) { - if (cd->distance < 0 && (uint32_t)(abs(cd->distance)) > offset) - offset = 0; - else - offset += cd->distance; - } - - if (cd->flags & DETECT_CONTENT_WITHIN) { - if ((int32_t)depth > (int32_t)(prev_payload_offset + cd->within + cd->distance)) { - depth = prev_payload_offset + cd->within + cd->distance; - } - } - - if (cd->depth != 0) { - if ((cd->depth + prev_payload_offset) < depth) { - depth = prev_payload_offset + cd->depth; - } - } - - if (cd->offset > offset) { - offset = cd->offset; - } - } else { /* implied no relative matches */ - /* set depth */ - if (cd->depth != 0) { - depth = cd->depth; - } - - /* set offset */ - offset = cd->offset; - prev_payload_offset = 0; - } - - /* update offset with prev_offset if we're searching for - * matches after the first occurence. */ - if (prev_offset != 0) - offset = prev_offset; - - if (depth > payload_len) - depth = payload_len; - - /* if offset is bigger than depth we can never match on a pattern. - * We can however, "match" on a negated pattern. */ - if (offset > depth || depth == 0) { - if (cd->flags & DETECT_CONTENT_NEGATED) { - goto match; - } else { - SCReturnInt(0); - } - } - - uint8_t *spayload = payload + offset; - uint32_t spayload_len = depth - offset; - uint32_t match_offset = 0; -#ifdef DEBUG - BUG_ON(spayload_len > payload_len); -#endif - - /* do the actual search with boyer moore precooked ctx */ - if (cd->flags & DETECT_CONTENT_NOCASE) { - found = BoyerMooreNocase(cd->content, cd->content_len, - spayload, spayload_len, - cd->bm_ctx->bmGs, cd->bm_ctx->bmBc); - } else { - found = BoyerMoore(cd->content, cd->content_len, - spayload, spayload_len, - cd->bm_ctx->bmGs, cd->bm_ctx->bmBc); - } - - /* next we evaluate the result in combination with the - * negation flag. */ - if (found == NULL && !(cd->flags & DETECT_CONTENT_NEGATED)) { - SCReturnInt(0); - } else if (found == NULL && cd->flags & DETECT_CONTENT_NEGATED) { - goto match; - } else if (found != NULL && cd->flags & DETECT_CONTENT_NEGATED) { - det_ctx->discontinue_matching = 1; - SCReturnInt(0); - } else { - match_offset = (uint32_t)((found - payload) + cd->content_len); - det_ctx->payload_offset = match_offset; - - if (!(cd->flags & DETECT_CONTENT_RELATIVE_NEXT)) { - SCLogDebug("no relative match coming up, so this is a match"); - goto match; - } - - /* bail out if we have no next match. Technically this is an - * error, as the current cd has the DETECT_CONTENT_RELATIVE_NEXT - * flag set. */ - if (sm->next == NULL) { - SCReturnInt(0); - } - - /* see if the next payload keywords match. If not, we will - * search for another occurence of this http raw header content - * and see if the others match then until we run out of matches */ - int r = DoInspectHttpMethod(de_ctx, det_ctx, s, sm->next, - payload, payload_len); - if (r == 1) { - SCReturnInt(1); - } - - if (det_ctx->discontinue_matching) - SCReturnInt(0); - - /* set the previous match offset to the start of this match + 1 */ - prev_offset = (match_offset - (cd->content_len - 1)); - SCLogDebug("trying to see if there is another match after " - "prev_offset %"PRIu32, prev_offset); - } - - } while(1); - - } else if (sm->type == DETECT_PCRE_HTTPMETHOD) { - SCLogDebug("inspecting pcre"); - DetectPcreData *pe = (DetectPcreData *)sm->ctx; - uint32_t prev_payload_offset = det_ctx->payload_offset; - uint32_t prev_offset = 0; - int r = 0; - - det_ctx->pcre_match_start_offset = 0; - do { - r = DetectPcrePayloadMatch(det_ctx, s, sm, NULL, NULL, - payload, payload_len); - - if (r == 0) { - det_ctx->discontinue_matching = 1; - SCReturnInt(0); - } - - if (!(pe->flags & DETECT_PCRE_RELATIVE_NEXT)) { - SCLogDebug("no relative match coming up, so this is a match"); - goto match; - } - - /* save it, in case we need to do a pcre match once again */ - prev_offset = det_ctx->pcre_match_start_offset; - - /* see if the next payload keywords match. If not, we will - * search for another occurence of this pcre and see - * if the others match, until we run out of matches */ - int r = DoInspectHttpMethod(de_ctx, det_ctx, s, sm->next, - payload, payload_len); - if (r == 1) { - SCReturnInt(1); - } - - if (det_ctx->discontinue_matching) - SCReturnInt(0); - - det_ctx->payload_offset = prev_payload_offset; - det_ctx->pcre_match_start_offset = prev_offset; - } while (1); - } else { - /* we should never get here, but bail out just in case */ - SCLogDebug("sm->type %u", sm->type); -#ifdef DEBUG - BUG_ON(1); -#endif - } - - SCReturnInt(0); - -match: - /* this sigmatch matched, inspect the next one. If it was the last, - * the payload portion of the signature matched. */ - if (sm->next != NULL) { - int r = DoInspectHttpMethod(de_ctx, det_ctx, s, sm->next, payload, - payload_len); - SCReturnInt(r); - } else { - SCReturnInt(1); - } -} - int DetectEngineRunHttpMethodMpm(DetectEngineThreadCtx *det_ctx, Flow *f, HtpState *htp_state, uint8_t flags) { diff --git a/src/detect-engine-hrhd.c b/src/detect-engine-hrhd.c index a223411067..1cee22e744 100644 --- a/src/detect-engine-hrhd.c +++ b/src/detect-engine-hrhd.c @@ -40,24 +40,13 @@ #include "detect-engine-mpm.h" #include "detect-parse.h" #include "detect-engine-state.h" -#include "detect-pcre.h" -#include "detect-isdataat.h" -#include "detect-bytetest.h" -#include "detect-bytejump.h" #include "detect-engine-content-inspection.h" #include "flow-util.h" -#include "util-spm.h" #include "util-debug.h" #include "util-print.h" #include "flow.h" -#include "detect-flow.h" -#include "flow-var.h" -#include "threads.h" -#include "flow-alert-sid.h" -#include "stream-tcp.h" -#include "stream.h" #include "app-layer-parser.h" #include "util-unittest.h" @@ -66,248 +55,6 @@ #include "app-layer-htp.h" #include "app-layer-protos.h" -/** - * \brief Run the actual payload match function for http raw header. - * - * For accounting the last match in relative matching the - * det_ctx->payload_offset var is used. - * - * \param de_ctx Detection engine context. - * \param det_ctx Detection engine thread context. - * \param s Signature to inspect. - * \param sm SigMatch to inspect. - * \param payload Ptr to the http raw headers buffer to inspect. - * \param payload_len Length of the http raw headers buffer. - * - * \retval 0 no match. - * \retval 1 match. - */ -static int DoInspectHttpRawHeader(DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, SigMatch *sm, - uint8_t *payload, uint32_t payload_len) -{ - SCEnter(); - - det_ctx->inspection_recursion_counter++; - - if (det_ctx->inspection_recursion_counter == de_ctx->inspection_recursion_limit) { - det_ctx->discontinue_matching = 1; - SCReturnInt(0); - } - - if (sm == NULL) { - SCReturnInt(0); - } - - if (sm->type == DETECT_AL_HTTP_RAW_HEADER) { - if (payload_len == 0) { - SCReturnInt(0); - } - - DetectContentData *cd = (DetectContentData *)sm->ctx; - SCLogDebug("inspecting http headers %"PRIu32" payload_len %"PRIu32, - cd->id, payload_len); - - //if (cd->flags & DETECT_CONTENT_HRHD_MPM && !(cd->flags & DETECT_CONTENT_NEGATED)) - // goto match; - - /* rule parsers should take care of this */ -#ifdef DEBUG - BUG_ON(cd->depth != 0 && cd->depth <= cd->offset); -#endif - - /* search for our pattern, checking the matches recursively. - * if we match we look for the next SigMatch as well */ - uint8_t *found = NULL; - uint32_t offset = 0; - uint32_t depth = payload_len; - uint32_t prev_offset = 0; /**< used in recursive searching */ - uint32_t prev_payload_offset = det_ctx->payload_offset; - - do { - if (cd->flags & DETECT_CONTENT_DISTANCE || - cd->flags & DETECT_CONTENT_WITHIN) { - SCLogDebug("prev_payload_offset %"PRIu32, prev_payload_offset); - - offset = prev_payload_offset; - depth = payload_len; - - if (cd->flags & DETECT_CONTENT_DISTANCE) { - if (cd->distance < 0 && (uint32_t)(abs(cd->distance)) > offset) - offset = 0; - else - offset += cd->distance; - } - - if (cd->flags & DETECT_CONTENT_WITHIN) { - if ((int32_t)depth > (int32_t)(prev_payload_offset + cd->within + cd->distance)) { - depth = prev_payload_offset + cd->within + cd->distance; - } - } - - if (cd->depth != 0) { - if ((cd->depth + prev_payload_offset) < depth) { - depth = prev_payload_offset + cd->depth; - } - } - - if (cd->offset > offset) { - offset = cd->offset; - } - } else { /* implied no relative matches */ - /* set depth */ - if (cd->depth != 0) { - depth = cd->depth; - } - - /* set offset */ - offset = cd->offset; - prev_payload_offset = 0; - } - - /* update offset with prev_offset if we're searching for - * matches after the first occurence. */ - if (prev_offset != 0) - offset = prev_offset; - - if (depth > payload_len) - depth = payload_len; - - /* if offset is bigger than depth we can never match on a pattern. - * We can however, "match" on a negated pattern. */ - if (offset > depth || depth == 0) { - if (cd->flags & DETECT_CONTENT_NEGATED) { - goto match; - } else { - SCReturnInt(0); - } - } - - uint8_t *spayload = payload + offset; - uint32_t spayload_len = depth - offset; - uint32_t match_offset = 0; -#ifdef DEBUG - BUG_ON(spayload_len > payload_len); -#endif - - /* do the actual search with boyer moore precooked ctx */ - if (cd->flags & DETECT_CONTENT_NOCASE) { - found = BoyerMooreNocase(cd->content, cd->content_len, - spayload, spayload_len, - cd->bm_ctx->bmGs, cd->bm_ctx->bmBc); - } else { - found = BoyerMoore(cd->content, cd->content_len, - spayload, spayload_len, - cd->bm_ctx->bmGs, cd->bm_ctx->bmBc); - } - - /* next we evaluate the result in combination with the - * negation flag. */ - if (found == NULL && !(cd->flags & DETECT_CONTENT_NEGATED)) { - SCReturnInt(0); - } else if (found == NULL && cd->flags & DETECT_CONTENT_NEGATED) { - goto match; - } else if (found != NULL && cd->flags & DETECT_CONTENT_NEGATED) { - det_ctx->discontinue_matching = 1; - SCReturnInt(0); - } else { - match_offset = (uint32_t)((found - payload) + cd->content_len); - det_ctx->payload_offset = match_offset; - - if (!(cd->flags & DETECT_CONTENT_RELATIVE_NEXT)) { - SCLogDebug("no relative match coming up, so this is a match"); - goto match; - } - - /* bail out if we have no next match. Technically this is an - * error, as the current cd has the DETECT_CONTENT_RELATIVE_NEXT - * flag set. */ - if (sm->next == NULL) { - SCReturnInt(0); - } - - /* see if the next payload keywords match. If not, we will - * search for another occurence of this http raw header content - * and see if the others match then until we run out of matches */ - int r = DoInspectHttpRawHeader(de_ctx, det_ctx, s, sm->next, - payload, payload_len); - if (r == 1) { - SCReturnInt(1); - } - - if (det_ctx->discontinue_matching) - SCReturnInt(0); - - /* set the previous match offset to the start of this match + 1 */ - prev_offset = (match_offset - (cd->content_len - 1)); - SCLogDebug("trying to see if there is another match after " - "prev_offset %"PRIu32, prev_offset); - } - - } while(1); - - } else if (sm->type == DETECT_PCRE) { - SCLogDebug("inspecting pcre"); - DetectPcreData *pe = (DetectPcreData *)sm->ctx; - uint32_t prev_payload_offset = det_ctx->payload_offset; - uint32_t prev_offset = 0; - int r = 0; - - det_ctx->pcre_match_start_offset = 0; - do { - r = DetectPcrePayloadMatch(det_ctx, s, sm, NULL, NULL, - payload, payload_len); - - if (r == 0) { - det_ctx->discontinue_matching = 1; - SCReturnInt(0); - } - - if (!(pe->flags & DETECT_PCRE_RELATIVE_NEXT)) { - SCLogDebug("no relative match coming up, so this is a match"); - goto match; - } - - /* save it, in case we need to do a pcre match once again */ - prev_offset = det_ctx->pcre_match_start_offset; - - /* see if the next payload keywords match. If not, we will - * search for another occurence of this pcre and see - * if the others match, until we run out of matches */ - int r = DoInspectHttpRawHeader(de_ctx, det_ctx, s, sm->next, - payload, payload_len); - if (r == 1) { - SCReturnInt(1); - } - - if (det_ctx->discontinue_matching) - SCReturnInt(0); - - det_ctx->payload_offset = prev_payload_offset; - det_ctx->pcre_match_start_offset = prev_offset; - } while (1); - } else { - /* we should never get here, but bail out just in case */ - SCLogDebug("sm->type %u", sm->type); -#ifdef DEBUG - BUG_ON(1); -#endif - } - - SCReturnInt(0); - -match: - /* this sigmatch matched, inspect the next one. If it was the last, - * the payload portion of the signature matched. */ - if (sm->next != NULL) { - int r = DoInspectHttpRawHeader(de_ctx, det_ctx, s, sm->next, payload, - payload_len); - SCReturnInt(r); - } else { - SCReturnInt(1); - } -} int DetectEngineRunHttpRawHeaderMpm(DetectEngineThreadCtx *det_ctx, Flow *f, HtpState *htp_state, uint8_t flags) diff --git a/src/detect-engine-hrud.c b/src/detect-engine-hrud.c index a9a61c1ecd..8d3a4edacd 100644 --- a/src/detect-engine-hrud.c +++ b/src/detect-engine-hrud.c @@ -39,25 +39,13 @@ #include "detect-engine-mpm.h" #include "detect-parse.h" #include "detect-engine-state.h" -#include "detect-urilen.h" -#include "detect-pcre.h" -#include "detect-isdataat.h" -#include "detect-bytetest.h" -#include "detect-bytejump.h" #include "detect-engine-content-inspection.h" #include "flow-util.h" -#include "util-spm.h" #include "util-debug.h" #include "util-print.h" #include "flow.h" -#include "detect-flow.h" -#include "flow-var.h" -#include "threads.h" -#include "flow-alert-sid.h" -#include "stream-tcp.h" -#include "stream.h" #include "app-layer-parser.h" #include "util-unittest.h" @@ -66,309 +54,6 @@ #include "app-layer-htp.h" #include "app-layer-protos.h" -/** - * \brief Run the actual payload match function for http raw uri. - * - * For accounting the last match in relative matching the - * det_ctx->payload_offset var is used. - * - * \param de_ctx Detection engine context. - * \param det_ctx Detection engine thread context. - * \param s Signature to inspect. - * \param sm SigMatch to inspect. - * \param payload Ptr to the http raw uri to inspect. - * \param payload_len Length of the http raw uri. - * - * \retval 0 no match. - * \retval 1 match. - */ -static int DoInspectHttpRawUri(DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, SigMatch *sm, - uint8_t *payload, uint32_t payload_len) -{ - SCEnter(); - - det_ctx->inspection_recursion_counter++; - - if (det_ctx->inspection_recursion_counter == de_ctx->inspection_recursion_limit) { - det_ctx->discontinue_matching = 1; - SCReturnInt(0); - } - - if (sm == NULL) { - SCReturnInt(0); - } - - if (sm->type == DETECT_AL_HTTP_RAW_URI) { - if (payload_len == 0) { - SCReturnInt(0); - } - - DetectContentData *cd = (DetectContentData *)sm->ctx; - - /* disabled to avoid the FP from inspecting multiple transactions */ - //if (cd->flags & DETECT_CONTENT_HRUD_MPM && !(cd->flags & DETECT_CONTENT_NEGATED)) - // goto match; - - /* rule parsers should take care of this */ -#ifdef DEBUG - BUG_ON(cd->depth != 0 && cd->depth <= cd->offset); -#endif - - /* search for our pattern, checking the matches recursively. - * if we match we look for the next SigMatch as well */ - uint8_t *found = NULL; - uint32_t offset = 0; - uint32_t depth = payload_len; - uint32_t prev_offset = 0; /**< used in recursive searching */ - uint32_t prev_payload_offset = det_ctx->payload_offset; - - do { - if (cd->flags & DETECT_CONTENT_DISTANCE || - cd->flags & DETECT_CONTENT_WITHIN) { - SCLogDebug("prev_payload_offset %"PRIu32, prev_payload_offset); - - offset = prev_payload_offset; - depth = payload_len; - - if (cd->flags & DETECT_CONTENT_DISTANCE) { - if (cd->distance < 0 && (uint32_t)(abs(cd->distance)) > offset) - offset = 0; - else - offset += cd->distance; - } - - if (cd->flags & DETECT_CONTENT_WITHIN) { - if ((int32_t)depth > (int32_t)(prev_payload_offset + cd->within + cd->distance)) { - depth = prev_payload_offset + cd->within + cd->distance; - } - } - - if (cd->depth != 0) { - if ((cd->depth + prev_payload_offset) < depth) { - depth = prev_payload_offset + cd->depth; - } - } - - if (cd->offset > offset) { - offset = cd->offset; - } - } else { /* implied no relative matches */ - /* set depth */ - if (cd->depth != 0) { - depth = cd->depth; - } - - /* set offset */ - offset = cd->offset; - prev_payload_offset = 0; - } - - /* update offset with prev_offset if we're searching for - * matches after the first occurence. */ - if (prev_offset != 0) - offset = prev_offset; - - if (depth > payload_len) - depth = payload_len; - - /* if offset is bigger than depth we can never match on a pattern. - * We can however, "match" on a negated pattern. */ - if (offset > depth || depth == 0) { - if (cd->flags & DETECT_CONTENT_NEGATED) { - goto match; - } else { - SCReturnInt(0); - } - } - - uint8_t *spayload = payload + offset; - uint32_t spayload_len = depth - offset; - uint32_t match_offset = 0; -#ifdef DEBUG - BUG_ON(spayload_len > payload_len); -#endif - - /* do the actual search with boyer moore precooked ctx */ - if (cd->flags & DETECT_CONTENT_NOCASE) { - found = BoyerMooreNocase(cd->content, cd->content_len, - spayload, spayload_len, - cd->bm_ctx->bmGs, cd->bm_ctx->bmBc); - } else { - found = BoyerMoore(cd->content, cd->content_len, - spayload, spayload_len, - cd->bm_ctx->bmGs, cd->bm_ctx->bmBc); - } - - /* next we evaluate the result in combination with the - * negation flag. */ - if (found == NULL && !(cd->flags & DETECT_CONTENT_NEGATED)) { - SCReturnInt(0); - } else if (found == NULL && cd->flags & DETECT_CONTENT_NEGATED) { - goto match; - } else if (found != NULL && cd->flags & DETECT_CONTENT_NEGATED) { - det_ctx->discontinue_matching = 1; - SCReturnInt(0); - } else { - match_offset = (uint32_t)((found - payload) + cd->content_len); - det_ctx->payload_offset = match_offset; - - if (!(cd->flags & DETECT_CONTENT_RELATIVE_NEXT)) { - SCLogDebug("no relative match coming up, so this is a match"); - goto match; - } - - /* bail out if we have no next match. Technically this is an - * error, as the current cd has the DETECT_CONTENT_RELATIVE_NEXT - * flag set. */ - if (sm->next == NULL) { - SCReturnInt(0); - } - - /* see if the next payload keywords match. If not, we will - * search for another occurence of this http header content and - * see if the others match then until we run out of matches */ - int r = DoInspectHttpRawUri(de_ctx, det_ctx, s, sm->next, - payload, payload_len); - if (r == 1) { - SCReturnInt(1); - } - - if (det_ctx->discontinue_matching) - SCReturnInt(0); - - /* set the previous match offset to the start of this match + 1 */ - prev_offset = (match_offset - (cd->content_len - 1)); - SCLogDebug("trying to see if there is another match after " - "prev_offset %"PRIu32, prev_offset); - } - - } while(1); - - } else if (sm->type == DETECT_PCRE) { - SCLogDebug("inspecting pcre"); - DetectPcreData *pe = (DetectPcreData *)sm->ctx; - uint32_t prev_payload_offset = det_ctx->payload_offset; - uint32_t prev_offset = 0; - int r = 0; - - det_ctx->pcre_match_start_offset = 0; - do { - r = DetectPcrePayloadMatch(det_ctx, s, sm, NULL, NULL, - payload, payload_len); - - if (r == 0) { - det_ctx->discontinue_matching = 1; - SCReturnInt(0); - } - - if (!(pe->flags & DETECT_PCRE_RELATIVE_NEXT)) { - SCLogDebug("no relative match coming up, so this is a match"); - goto match; - } - - /* save it, in case we need to do a pcre match once again */ - prev_offset = det_ctx->pcre_match_start_offset; - - /* see if the next payload keywords match. If not, we will - * search for another occurence of this pcre and see - * if the others match, until we run out of matches */ - int r = DoInspectHttpRawUri(de_ctx, det_ctx, s, sm->next, - payload, payload_len); - if (r == 1) { - SCReturnInt(1); - } - - if (det_ctx->discontinue_matching) - SCReturnInt(0); - - det_ctx->payload_offset = prev_payload_offset; - det_ctx->pcre_match_start_offset = prev_offset; - } while (1); - - } else if (sm->type == DETECT_ISDATAAT) { - SCLogDebug("inspecting isdataat"); - - DetectIsdataatData *id = (DetectIsdataatData *)sm->ctx; - if (id->flags & ISDATAAT_RELATIVE) { - if (det_ctx->payload_offset + id->dataat > payload_len) { - SCLogDebug("det_ctx->payload_offset + id->dataat %"PRIu32" > %"PRIu32, det_ctx->payload_offset + id->dataat, payload_len); - if (id->flags & ISDATAAT_NEGATED) - goto match; - SCReturnInt(0); - } else { - SCLogDebug("relative isdataat match"); - if (id->flags & ISDATAAT_NEGATED) - SCReturnInt(0); - goto match; - } - } else { - if (id->dataat < payload_len) { - SCLogDebug("absolute isdataat match"); - if (id->flags & ISDATAAT_NEGATED) - SCReturnInt(0); - goto match; - } else { - SCLogDebug("absolute isdataat mismatch, id->isdataat %"PRIu32", payload_len %"PRIu32"", id->dataat,payload_len); - if (id->flags & ISDATAAT_NEGATED) - goto match; - SCReturnInt(0); - } - } - } else if (sm->type == DETECT_AL_URILEN) { - SCLogDebug("inspecting uri len"); - - int r = 0; - DetectUrilenData *urilend = (DetectUrilenData *) sm->ctx; - - switch (urilend->mode) { - case DETECT_URILEN_EQ: - if (payload_len == urilend->urilen1) - r = 1; - break; - case DETECT_URILEN_LT: - if (payload_len < urilend->urilen1) - r = 1; - break; - case DETECT_URILEN_GT: - if (payload_len > urilend->urilen1) - r = 1; - break; - case DETECT_URILEN_RA: - if (payload_len > urilend->urilen1 && - payload_len < urilend->urilen2) { - r = 1; - } - break; - } - - if (r == 1) { - goto match; - } - - SCReturnInt(0); - } else { - /* we should never get here, but bail out just in case */ - SCLogDebug("sm->type %u", sm->type); -#ifdef DEBUG - BUG_ON(1); -#endif - } - - SCReturnInt(0); - -match: - /* this sigmatch matched, inspect the next one. If it was the last, - * the payload portion of the signature matched. */ - if (sm->next != NULL) { - int r = DoInspectHttpRawUri(de_ctx, det_ctx, s, sm->next, payload, - payload_len); - SCReturnInt(r); - } else { - SCReturnInt(1); - } -} /** * \brief Run the mpm against raw http uris. diff --git a/src/detect-engine-hsbd.c b/src/detect-engine-hsbd.c index 59598ebfa0..fee323183d 100644 --- a/src/detect-engine-hsbd.c +++ b/src/detect-engine-hsbd.c @@ -41,25 +41,13 @@ #include "detect-engine-mpm.h" #include "detect-parse.h" #include "detect-engine-state.h" -#include "detect-pcre.h" -#include "detect-isdataat.h" -#include "detect-bytetest.h" -#include "detect-bytejump.h" -#include "detect-byte-extract.h" #include "detect-engine-content-inspection.h" #include "flow-util.h" -#include "util-spm.h" #include "util-debug.h" #include "util-print.h" #include "flow.h" -#include "detect-flow.h" -#include "flow-var.h" -#include "threads.h" -#include "flow-alert-sid.h" -#include "stream-tcp.h" -#include "stream.h" #include "app-layer-parser.h" #include "util-unittest.h" @@ -68,321 +56,6 @@ #include "app-layer-htp.h" #include "app-layer-protos.h" -/** - * \brief Run the actual payload match function for http response body. - * - * For accounting the last match in relative matching the - * det_ctx->payload_offset int is used. - * - * \param de_ctx Detection engine context. - * \param det_ctx Detection engine thread context. - * \param s Signature to inspect. - * \param sm SigMatch to inspect. - * \param payload Ptr to the response body to inspect. - * \param payload_len Length of the response body. - * - * \retval 0 no match. - * \retval 1 match. - */ -static int DoInspectHttpServerBody(DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, SigMatch *sm, - uint8_t *payload, uint32_t payload_len) -{ - SCEnter(); - - det_ctx->inspection_recursion_counter++; - - if (det_ctx->inspection_recursion_counter == de_ctx->inspection_recursion_limit) { - det_ctx->discontinue_matching = 1; - SCReturnInt(0); - } - - if (sm == NULL) { - SCReturnInt(0); - } - - if (sm->type == DETECT_AL_HTTP_SERVER_BODY) { - if (payload_len == 0) { - SCReturnInt(0); - } - - DetectContentData *cd = (DetectContentData *)sm->ctx; - SCLogDebug("inspecting content %"PRIu32" payload_len %"PRIu32, cd->id, payload_len); - - //if (cd->flags & DETECT_CONTENT_HSBD_MPM && !(cd->flags & DETECT_CONTENT_NEGATED)) - // goto match; - - /* rule parsers should take care of this */ -#ifdef DEBUG - BUG_ON(cd->depth != 0 && cd->depth <= cd->offset); -#endif - - /* search for our pattern, checking the matches recursively. - * if we match we look for the next SigMatch as well */ - uint8_t *found = NULL; - uint32_t offset = 0; - uint32_t depth = payload_len; - uint32_t prev_offset = 0; /**< used in recursive searching */ - uint32_t prev_payload_offset = det_ctx->payload_offset; - - do { - if (cd->flags & DETECT_CONTENT_DISTANCE || - cd->flags & DETECT_CONTENT_WITHIN) { - SCLogDebug("prev_payload_offset %"PRIu32, prev_payload_offset); - - offset = prev_payload_offset; - depth = payload_len; - - if (cd->flags & DETECT_CONTENT_DISTANCE) { - if (cd->distance < 0 && (uint32_t)(abs(cd->distance)) > offset) - offset = 0; - else - offset += cd->distance; - } - - if (cd->flags & DETECT_CONTENT_WITHIN) { - if ((int32_t)depth > (int32_t)(prev_payload_offset + cd->within + cd->distance)) { - depth = prev_payload_offset + cd->within + cd->distance; - } - } - - if (cd->depth != 0) { - if ((cd->depth + prev_payload_offset) < depth) { - depth = prev_payload_offset + cd->depth; - } - } - - if (cd->offset > offset) { - offset = cd->offset; - } - } else { /* implied no relative matches */ - /* set depth */ - if (cd->depth != 0) { - depth = cd->depth; - } - - /* set offset */ - offset = cd->offset; - prev_payload_offset = 0; - } - - /* update offset with prev_offset if we're searching for - * matches after the first occurence. */ - if (prev_offset != 0) - offset = prev_offset; - - if (depth > payload_len) - depth = payload_len; - - /* if offset is bigger than depth we can never match on a pattern. - * We can however, "match" on a negated pattern. */ - if (offset > depth || depth == 0) { - if (cd->flags & DETECT_CONTENT_NEGATED) { - goto match; - } else { - SCReturnInt(0); - } - } - - uint8_t *spayload = payload + offset; - uint32_t spayload_len = depth - offset; - uint32_t match_offset = 0; -#ifdef DEBUG - BUG_ON(spayload_len > payload_len); -#endif - - /* do the actual search with boyer moore precooked ctx */ - if (cd->flags & DETECT_CONTENT_NOCASE) { - found = BoyerMooreNocase(cd->content, cd->content_len, - spayload, spayload_len, - cd->bm_ctx->bmGs, cd->bm_ctx->bmBc); - } else { - found = BoyerMoore(cd->content, cd->content_len, - spayload, spayload_len, - cd->bm_ctx->bmGs, cd->bm_ctx->bmBc); - } - - /* next we evaluate the result in combination with the - * negation flag. */ - if (found == NULL && !(cd->flags & DETECT_CONTENT_NEGATED)) { - SCReturnInt(0); - } else if (found == NULL && cd->flags & DETECT_CONTENT_NEGATED) { - goto match; - } else if (found != NULL && cd->flags & DETECT_CONTENT_NEGATED) { - det_ctx->discontinue_matching = 1; - SCReturnInt(0); - } else { - match_offset = (uint32_t)((found - payload) + cd->content_len); - det_ctx->payload_offset = match_offset; - - if (!(cd->flags & DETECT_CONTENT_RELATIVE_NEXT)) { - SCLogDebug("no relative match coming up, so this is a match"); - goto match; - } - - /* bail out if we have no next match. Technically this is an - * error, as the current cd has the DETECT_CONTENT_RELATIVE_NEXT - * flag set. */ - if (sm->next == NULL) { - SCReturnInt(0); - } - - /* see if the next payload keywords match. If not, we will - * search for another occurence of this http server body content - * and see if the others match then until we run out of matches */ - int r = DoInspectHttpServerBody(de_ctx, det_ctx, s, sm->next, - payload, payload_len); - if (r == 1) { - SCReturnInt(1); - } - - if (det_ctx->discontinue_matching) - SCReturnInt(0); - - /* set the previous match offset to the start of this match + 1 */ - prev_offset = (match_offset - (cd->content_len - 1)); - SCLogDebug("trying to see if there is another match after " - "prev_offset %"PRIu32, prev_offset); - } - - } while(1); - - } else if (sm->type == DETECT_ISDATAAT) { - { - SCLogDebug("inspecting isdataat"); - - DetectIsdataatData *id = (DetectIsdataatData *)sm->ctx; - if (id->flags & ISDATAAT_RELATIVE) { - if (det_ctx->payload_offset + id->dataat > payload_len) { - SCLogDebug("det_ctx->payload_offset + id->dataat %"PRIu32" > %"PRIu32, det_ctx->payload_offset + id->dataat, payload_len); - if (id->flags & ISDATAAT_NEGATED) - goto match; - SCReturnInt(0); - } else { - SCLogDebug("relative isdataat match"); - if (id->flags & ISDATAAT_NEGATED) - SCReturnInt(0); - goto match; - } - } else { - if (id->dataat < payload_len) { - SCLogDebug("absolute isdataat match"); - if (id->flags & ISDATAAT_NEGATED) - SCReturnInt(0); - goto match; - } else { - SCLogDebug("absolute isdataat mismatch, id->isdataat %"PRIu32", payload_len %"PRIu32"", id->dataat,payload_len); - if (id->flags & ISDATAAT_NEGATED) - goto match; - SCReturnInt(0); - } - } - } - } else if (sm->type == DETECT_PCRE) { - SCLogDebug("inspecting pcre"); - DetectPcreData *pe = (DetectPcreData *)sm->ctx; - uint32_t prev_payload_offset = det_ctx->payload_offset; - uint32_t prev_offset = 0; - int r = 0; - - det_ctx->pcre_match_start_offset = 0; - do { - r = DetectPcrePayloadMatch(det_ctx, s, sm, NULL, NULL, - payload, payload_len); - - if (r == 0) { - det_ctx->discontinue_matching = 1; - SCReturnInt(0); - } - - if (!(pe->flags & DETECT_PCRE_RELATIVE_NEXT)) { - SCLogDebug("no relative match coming up, so this is a match"); - goto match; - } - - /* save it, in case we need to do a pcre match once again */ - prev_offset = det_ctx->pcre_match_start_offset; - - /* see if the next payload keywords match. If not, we will - * search for another occurence of this pcre and see - * if the others match, until we run out of matches */ - int r = DoInspectHttpServerBody(de_ctx, det_ctx, s, sm->next, - payload, payload_len); - if (r == 1) { - SCReturnInt(1); - } - - if (det_ctx->discontinue_matching) - SCReturnInt(0); - - det_ctx->payload_offset = prev_payload_offset; - det_ctx->pcre_match_start_offset = prev_offset; - } while (1); - } else if (sm->type == DETECT_BYTETEST) { - DetectBytetestData *btd = (DetectBytetestData *)sm->ctx; - int32_t offset = btd->offset; - uint64_t value = btd->value; - if (btd->flags & DETECT_BYTETEST_OFFSET_BE) { - offset = det_ctx->bj_values[offset]; - } - if (btd->flags & DETECT_BYTETEST_VALUE_BE) { - value = det_ctx->bj_values[value]; - } - - if (DetectBytetestDoMatch(det_ctx,s,sm,payload,payload_len, btd->flags, - offset, value) != 1) { - SCReturnInt(0); - } - - goto match; - } else if (sm->type == DETECT_BYTEJUMP) { - DetectBytejumpData *bjd = (DetectBytejumpData *)sm->ctx; - int32_t offset = bjd->offset; - - if (bjd->flags & DETECT_BYTEJUMP_OFFSET_BE) { - offset = det_ctx->bj_values[offset]; - } - - if (DetectBytejumpDoMatch(det_ctx,s,sm,payload,payload_len, - bjd->flags, offset) != 1) { - SCReturnInt(0); - } - - goto match; - } else if (sm->type == DETECT_BYTE_EXTRACT) { - DetectByteExtractData *bed = (DetectByteExtractData *)sm->ctx; - - if (DetectByteExtractDoMatch(det_ctx, sm, s, payload, - payload_len, - &det_ctx->bj_values[bed->local_id], - bed->endian) != 1) { - SCReturnInt(0); - } - - goto match; - } else { - /* we should never get here, but bail out just in case */ - SCLogDebug("sm->type %u", sm->type); -#ifdef DEBUG - BUG_ON(1); -#endif - } - - SCReturnInt(0); - -match: - /* this sigmatch matched, inspect the next one. If it was the last, - * the payload portion of the signature matched. */ - if (sm->next != NULL) { - int r = DoInspectHttpServerBody(de_ctx, det_ctx, s, sm->next, payload, - payload_len); - SCReturnInt(r); - } else { - SCReturnInt(1); - } -} - /** * \brief Helps buffer response bodies for different transactions and stores them * away in detection code. diff --git a/src/detect-engine-payload.c b/src/detect-engine-payload.c index 3136fb6fa6..2b5819380d 100644 --- a/src/detect-engine-payload.c +++ b/src/detect-engine-payload.c @@ -31,423 +31,14 @@ #include "detect.h" #include "detect-engine.h" #include "detect-parse.h" -#include "detect-content.h" -#include "detect-pcre.h" -#include "detect-isdataat.h" -#include "detect-bytetest.h" -#include "detect-bytejump.h" -#include "detect-byte-extract.h" -#include "detect-replace.h" #include "detect-engine-content-inspection.h" -#include "util-spm.h" -#include "util-spm-bm.h" #include "util-debug.h" #include "util-print.h" #include "util-unittest.h" #include "util-unittest-helper.h" -/** \brief Run the actual payload match functions - * - * The follwing keywords are inspected: - * - content - * - isdaatat - * - pcre - * - bytejump - * - bytetest - * - * All keywords are evaluated against the payload with payload_len. - * - * For accounting the last match in relative matching the - * det_ctx->payload_offset int is used. - * - * \param de_ctx Detection engine context - * \param det_ctx Detection engine thread context - * \param s Signature to inspect - * \param sm SigMatch to inspect - * \param f flow (for pcre flowvar storage) - * \param payload ptr to the payload to inspect - * \param payload_len length of the payload - * - * \retval 0 no match - * \retval 1 match - */ -static int DoInspectPacketPayload(DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, Signature *s, SigMatch *sm, - Packet *p, Flow *f, uint8_t *payload, uint32_t payload_len) -{ - SCEnter(); - - det_ctx->inspection_recursion_counter++; - - if (det_ctx->inspection_recursion_counter == de_ctx->inspection_recursion_limit) { - det_ctx->discontinue_matching = 1; - SCReturnInt(0); - } - - if (sm == NULL || payload_len == 0) { - SCReturnInt(0); - } - - switch(sm->type) { - case DETECT_CONTENT: - { - - DetectContentData *cd = (DetectContentData *)sm->ctx; - SCLogDebug("inspecting content %"PRIu32" payload_len %"PRIu32, cd->id, payload_len); - - /* we might have already have this content matched by the mpm. - * (if there is any other reason why we'd want to avoid checking - * it here, please fill it in) */ - //if (det_ctx->flags & DETECT_ENGINE_THREAD_CTX_INSPECTING_PACKET) { - // if (cd->flags & DETECT_CONTENT_PACKET_MPM && !(cd->flags & DETECT_CONTENT_NEGATED)) { - // /* we will remove this check in the end */ - // if (!DETECT_CONTENT_IS_SINGLE(cd)) - // abort(); - // //goto match; - // } - //} else if (det_ctx->flags & DETECT_ENGINE_THREAD_CTX_INSPECTING_STREAM) { - if (det_ctx->flags & DETECT_ENGINE_THREAD_CTX_INSPECTING_STREAM) { - if (cd->flags & DETECT_CONTENT_STREAM_MPM && !(cd->flags & DETECT_CONTENT_NEGATED)) { - goto match; - } - } - - /* rule parsers should take care of this */ -#ifdef DEBUG - BUG_ON(cd->depth != 0 && cd->depth <= cd->offset); -#endif - - /* search for our pattern, checking the matches recursively. - * if we match we look for the next SigMatch as well */ - uint8_t *found = NULL; - uint32_t offset = 0; - uint32_t depth = payload_len; - uint32_t prev_offset = 0; /**< used in recursive searching */ - uint32_t prev_payload_offset = det_ctx->payload_offset; - - do { - if (cd->flags & DETECT_CONTENT_DISTANCE || - cd->flags & DETECT_CONTENT_WITHIN) { - SCLogDebug("det_ctx->payload_offset %"PRIu32, det_ctx->payload_offset); - - offset = prev_payload_offset; - depth = payload_len; - - int distance = cd->distance; - if (cd->flags & DETECT_CONTENT_DISTANCE) { - if (cd->flags & DETECT_CONTENT_DISTANCE_BE) { - distance = det_ctx->bj_values[cd->distance]; - } - if (distance < 0 && (uint32_t)(abs(distance)) > offset) - offset = 0; - else - offset += distance; - - SCLogDebug("cd->distance %"PRIi32", offset %"PRIu32", depth %"PRIu32, - distance, offset, depth); - } - - if (cd->flags & DETECT_CONTENT_WITHIN) { - if (cd->flags & DETECT_CONTENT_WITHIN_BE) { - if ((int32_t)depth > (int32_t)(prev_payload_offset + det_ctx->bj_values[cd->within] + distance)) { - depth = prev_payload_offset + det_ctx->bj_values[cd->within] + distance; - } - } else { - if ((int32_t)depth > (int32_t)(prev_payload_offset + cd->within + distance)) { - depth = prev_payload_offset + cd->within + distance; - } - - SCLogDebug("cd->within %"PRIi32", det_ctx->payload_offset %"PRIu32", depth %"PRIu32, - cd->within, prev_payload_offset, depth); - } - } - - if (cd->flags & DETECT_CONTENT_DEPTH_BE) { - if ((det_ctx->bj_values[cd->depth] + prev_payload_offset) < depth) { - depth = prev_payload_offset + det_ctx->bj_values[cd->depth]; - } - } else { - if (cd->depth != 0) { - if ((cd->depth + prev_payload_offset) < depth) { - depth = prev_payload_offset + cd->depth; - } - - SCLogDebug("cd->depth %"PRIu32", depth %"PRIu32, cd->depth, depth); - } - } - - if (cd->flags & DETECT_CONTENT_OFFSET_BE) { - if (det_ctx->bj_values[cd->offset] > offset) - offset = det_ctx->bj_values[cd->offset]; - } else { - if (cd->offset > offset) { - offset = cd->offset; - SCLogDebug("setting offset %"PRIu32, offset); - } - } - } else { /* implied no relative matches */ - /* set depth */ - if (cd->flags & DETECT_CONTENT_DEPTH_BE) { - depth = det_ctx->bj_values[cd->depth]; - } else { - if (cd->depth != 0) { - depth = cd->depth; - } - } - - /* set offset */ - if (cd->flags & DETECT_CONTENT_OFFSET_BE) - offset = det_ctx->bj_values[cd->offset]; - else - offset = cd->offset; - prev_payload_offset = 0; - } - - /* update offset with prev_offset if we're searching for - * matches after the first occurence. */ - SCLogDebug("offset %"PRIu32", prev_offset %"PRIu32, offset, prev_offset); - if (prev_offset != 0) - offset = prev_offset; - - SCLogDebug("offset %"PRIu32", depth %"PRIu32, offset, depth); - - if (depth > payload_len) - depth = payload_len; - - /* if offset is bigger than depth we can never match on a pattern. - * We can however, "match" on a negated pattern. */ - if (offset > depth || depth == 0) { - if (cd->flags & DETECT_CONTENT_NEGATED) { - goto match; - } else { - SCReturnInt(0); - } - } - - uint8_t *spayload = payload + offset; - uint32_t spayload_len = depth - offset; - uint32_t match_offset = 0; - SCLogDebug("spayload_len %"PRIu32, spayload_len); -#ifdef DEBUG - BUG_ON(spayload_len > payload_len); -#endif - - //PrintRawDataFp(stdout,cd->content,cd->content_len); - //PrintRawDataFp(stdout,spayload,spayload_len); - - /* \todo Add another optimization here. If cd->content_len is - * greater than spayload_len found is anyways NULL */ - - /* do the actual search */ - if (cd->flags & DETECT_CONTENT_NOCASE) - found = BoyerMooreNocase(cd->content, cd->content_len, spayload, spayload_len, cd->bm_ctx->bmGs, cd->bm_ctx->bmBc); - else - found = BoyerMoore(cd->content, cd->content_len, spayload, spayload_len, cd->bm_ctx->bmGs, cd->bm_ctx->bmBc); - - /* next we evaluate the result in combination with the - * negation flag. */ - SCLogDebug("found %p cd negated %s", found, cd->flags & DETECT_CONTENT_NEGATED ? "true" : "false"); - - if (found == NULL && !(cd->flags & DETECT_CONTENT_NEGATED)) { - SCReturnInt(0); - } else if (found == NULL && cd->flags & DETECT_CONTENT_NEGATED) { - goto match; - } else if (found != NULL && cd->flags & DETECT_CONTENT_NEGATED) { - SCLogDebug("content %"PRIu32" matched at offset %"PRIu32", but negated so no match", cd->id, match_offset); - /* don't bother carrying recursive matches now, for preceding - * relative keywords */ - det_ctx->discontinue_matching = 1; - SCReturnInt(0); - } else { - match_offset = (uint32_t)((found - payload) + cd->content_len); - SCLogDebug("content %"PRIu32" matched at offset %"PRIu32"", cd->id, match_offset); - det_ctx->payload_offset = match_offset; - - /* Match branch, add replace to the list if needed */ - if (cd->flags & DETECT_CONTENT_REPLACE) { - if (p) { - /* we will need to replace content if match is confirmed */ - det_ctx->replist = DetectReplaceAddToList(det_ctx->replist, found, cd); - } else - SCLogWarning(SC_ERR_INVALID_VALUE, "Can't modify payload without packet"); - } - if (!(cd->flags & DETECT_CONTENT_RELATIVE_NEXT)) { - SCLogDebug("no relative match coming up, so this is a match"); - goto match; - } - - /* bail out if we have no next match. Technically this is an - * error, as the current cd has the DETECT_CONTENT_RELATIVE_NEXT - * flag set. */ - if (sm->next == NULL) { - SCReturnInt(0); - } - - SCLogDebug("content %"PRIu32, cd->id); - - /* see if the next payload keywords match. If not, we will - * search for another occurence of this content and see - * if the others match then until we run out of matches */ - int r = DoInspectPacketPayload(de_ctx,det_ctx,s,sm->next, p, f, payload, payload_len); - if (r == 1) { - SCReturnInt(1); - } - - if (det_ctx->discontinue_matching) - SCReturnInt(0); - - /* set the previous match offset to the start of this match + 1 */ - prev_offset = (match_offset - (cd->content_len - 1)); - SCLogDebug("trying to see if there is another match after prev_offset %"PRIu32, prev_offset); - } - - } while(1); - } - case DETECT_ISDATAAT: - { - SCLogDebug("inspecting isdataat"); - - DetectIsdataatData *id = (DetectIsdataatData *)sm->ctx; - if (id->flags & ISDATAAT_RELATIVE) { - if (det_ctx->payload_offset + id->dataat > payload_len) { - SCLogDebug("det_ctx->payload_offset + id->dataat %"PRIu32" > %"PRIu32, det_ctx->payload_offset + id->dataat, payload_len); - if (id->flags & ISDATAAT_NEGATED) - goto match; - SCReturnInt(0); - } else { - SCLogDebug("relative isdataat match"); - if (id->flags & ISDATAAT_NEGATED) - SCReturnInt(0); - goto match; - } - } else { - if (id->dataat < payload_len) { - SCLogDebug("absolute isdataat match"); - if (id->flags & ISDATAAT_NEGATED) - SCReturnInt(0); - goto match; - } else { - SCLogDebug("absolute isdataat mismatch, id->isdataat %"PRIu32", payload_len %"PRIu32"", id->dataat,payload_len); - if (id->flags & ISDATAAT_NEGATED) - goto match; - SCReturnInt(0); - } - } - } - case DETECT_PCRE: - { - SCLogDebug("inspecting pcre"); - DetectPcreData *pe = (DetectPcreData *)sm->ctx; - uint32_t prev_payload_offset = det_ctx->payload_offset; - uint32_t prev_offset = 0; - int r = 0; - - det_ctx->pcre_match_start_offset = 0; - do { - r = DetectPcrePayloadMatch(det_ctx, s, sm, p, f, - payload, payload_len); - if (r == 0) { - det_ctx->discontinue_matching = 1; - SCReturnInt(0); - } - - if (!(pe->flags & DETECT_PCRE_RELATIVE_NEXT)) { - SCLogDebug("no relative match coming up, so this is a match"); - goto match; - } - - /* save it, in case we need to do a pcre match once again */ - prev_offset = det_ctx->pcre_match_start_offset; - - /* see if the next payload keywords match. If not, we will - * search for another occurence of this pcre and see - * if the others match, until we run out of matches */ - r = DoInspectPacketPayload(de_ctx, det_ctx, s, sm->next, p, - f, payload, payload_len); - if (r == 1) { - SCReturnInt(1); - } - - if (det_ctx->discontinue_matching) - SCReturnInt(0); - - det_ctx->payload_offset = prev_payload_offset; - det_ctx->pcre_match_start_offset = prev_offset; - } while (1); - } - case DETECT_BYTETEST: - { - DetectBytetestData *btd = (DetectBytetestData *)sm->ctx; - int32_t offset = btd->offset; - uint64_t value = btd->value; - if (btd->flags & DETECT_BYTETEST_OFFSET_BE) { - offset = det_ctx->bj_values[offset]; - } - if (btd->flags & DETECT_BYTETEST_VALUE_BE) { - value = det_ctx->bj_values[value]; - } - - if (DetectBytetestDoMatch(det_ctx,s,sm,payload,payload_len, btd->flags, - offset, value) != 1) { - SCReturnInt(0); - } - - goto match; - } - case DETECT_BYTEJUMP: - { - DetectBytejumpData *bjd = (DetectBytejumpData *)sm->ctx; - int32_t offset = bjd->offset; - - if (bjd->flags & DETECT_BYTEJUMP_OFFSET_BE) { - offset = det_ctx->bj_values[offset]; - } - - if (DetectBytejumpDoMatch(det_ctx,s,sm,payload,payload_len, - bjd->flags, offset) != 1) { - SCReturnInt(0); - } - - goto match; - } - case DETECT_BYTE_EXTRACT: - { - DetectByteExtractData *bed = (DetectByteExtractData *)sm->ctx; - - if (DetectByteExtractDoMatch(det_ctx, sm, s, payload, - payload_len, - &det_ctx->bj_values[bed->local_id], - bed->endian) != 1) { - SCReturnInt(0); - } - - goto match; - } - /* we should never get here, but bail out just in case */ - default: - { - SCLogDebug("sm->type %u", sm->type); -#ifdef DEBUG - BUG_ON(1); -#endif - } - } - - SCReturnInt(0); - -match: - /* this sigmatch matched, inspect the next one. If it was the last, - * the payload portion of the signature matched. */ - if (sm->next != NULL) { - int r = DoInspectPacketPayload(de_ctx,det_ctx,s,sm->next, p, f, payload, payload_len); - SCReturnInt(r); - } else { - SCReturnInt(1); - } -} - /** * \brief Do the content inspection & validation for a signature * diff --git a/src/detect-engine-uri.c b/src/detect-engine-uri.c index 8ec08df88d..3033820c07 100644 --- a/src/detect-engine-uri.c +++ b/src/detect-engine-uri.c @@ -31,27 +31,13 @@ #include "detect-engine.h" #include "detect-parse.h" #include "detect-engine-state.h" -#include "detect-uricontent.h" -#include "detect-urilen.h" -#include "detect-pcre.h" -#include "detect-isdataat.h" -#include "detect-bytetest.h" -#include "detect-bytejump.h" -#include "detect-byte-extract.h" #include "detect-engine-content-inspection.h" #include "flow-util.h" -#include "util-spm.h" #include "util-debug.h" #include "util-print.h" #include "flow.h" -#include "detect-flow.h" -#include "flow-var.h" -#include "threads.h" -#include "flow-alert-sid.h" -#include "stream-tcp.h" -#include "stream.h" #include "app-layer-parser.h" #include "util-unittest.h" @@ -60,364 +46,6 @@ #include "app-layer-htp.h" #include "app-layer-protos.h" -/** - * \brief Run the actual payload match function for uricontent. - * - * For accounting the last match in relative matching the - * det_ctx->payload_offset int is used. - * - * \param de_ctx Detection engine context. - * \param det_ctx Detection engine thread context. - * \param s Signature to inspect. - * \param sm SigMatch to inspect. - * \param payload Ptr to the uricontent payload to inspect. - * \param payload_len Length of the uricontent payload. - * - * \retval 0 no match. - * \retval 1 match. - */ -static int DoInspectPacketUri(DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, SigMatch *sm, - uint8_t *payload, uint32_t payload_len) -{ - SCEnter(); - - det_ctx->inspection_recursion_counter++; - - if (det_ctx->inspection_recursion_counter == de_ctx->inspection_recursion_limit) { - det_ctx->discontinue_matching = 1; - SCReturnInt(0); - } - - if (sm == NULL) { - SCReturnInt(0); - } - - if (sm->type == DETECT_URICONTENT) { - if (payload_len == 0) { - SCReturnInt(0); - } - - DetectContentData *ud = NULL; - ud = (DetectContentData *)sm->ctx; - SCLogDebug("inspecting content %"PRIu32" payload_len %"PRIu32, ud->id, payload_len); - - //if (ud->flags & DETECT_CONTENT_URI_MPM && !(ud->flags & DETECT_CONTENT_NEGATED)) - // goto match; - - /* rule parsers should take care of this */ -#ifdef DEBUG - BUG_ON(ud->depth != 0 && ud->depth <= ud->offset); -#endif - - /* search for our pattern, checking the matches recursively. - * if we match we look for the next SigMatch as well */ - uint8_t *found = NULL; - uint32_t offset = 0; - uint32_t depth = payload_len; - uint32_t prev_offset = 0; /**< used in recursive searching */ - uint32_t prev_payload_offset = det_ctx->payload_offset; - - do { - if (ud->flags & DETECT_CONTENT_DISTANCE || - ud->flags & DETECT_CONTENT_WITHIN) { - SCLogDebug("prev_payload_offset %"PRIu32, prev_payload_offset); - - offset = prev_payload_offset; - depth = payload_len; - - int distance = ud->distance; - if (ud->flags & DETECT_CONTENT_DISTANCE) { - if (ud->flags & DETECT_CONTENT_DISTANCE_BE) { - distance = det_ctx->bj_values[ud->distance]; - } - - if (distance < 0 && (uint32_t)(abs(distance)) > offset) - offset = 0; - else - offset += distance; - - SCLogDebug("ud->distance %"PRIi32", offset %"PRIu32", depth %"PRIu32, - distance, offset, depth); - } - - if (ud->flags & DETECT_CONTENT_WITHIN) { - if (ud->flags & DETECT_CONTENT_WITHIN_BE) { - if ((int32_t)depth > (int32_t)(prev_payload_offset + det_ctx->bj_values[ud->within] + distance)) { - depth = prev_payload_offset + det_ctx->bj_values[ud->within] + distance; - } - } else { - if ((int32_t)depth > (int32_t)(prev_payload_offset + ud->within + distance)) { - depth = prev_payload_offset + ud->within + distance; - } - SCLogDebug("ud->within %"PRIi32", prev_payload_offset %"PRIu32", depth %"PRIu32, - ud->within, prev_payload_offset, depth); - } - } - - if (ud->flags & DETECT_CONTENT_DEPTH_BE) { - if ((det_ctx->bj_values[ud->depth] + prev_payload_offset) < depth) { - depth = prev_payload_offset + det_ctx->bj_values[ud->depth]; - } - } else { - if (ud->depth != 0) { - if ((ud->depth + prev_payload_offset) < depth) { - depth = prev_payload_offset + ud->depth; - } - - SCLogDebug("ud->depth %"PRIu32", depth %"PRIu32, ud->depth, depth); - } - } - - if (ud->flags & DETECT_CONTENT_OFFSET_BE) { - if (det_ctx->bj_values[ud->offset] > offset) - offset = det_ctx->bj_values[ud->offset]; - } else { - if (ud->offset > offset) { - offset = ud->offset; - SCLogDebug("setting offset %"PRIu32, offset); - } - } - } else { /* implied no relative matches */ - /* set depth */ - if (ud->flags & DETECT_CONTENT_DEPTH_BE) { - depth = det_ctx->bj_values[ud->depth]; - } else { - if (ud->depth != 0) { - depth = ud->depth; - } - } - - /* set offset */ - if (ud->flags & DETECT_CONTENT_OFFSET_BE) - offset = det_ctx->bj_values[ud->offset]; - else - offset = ud->offset; - prev_payload_offset = 0; - } - - /* update offset with prev_offset if we're searching for - * matches after the first occurence. */ - SCLogDebug("offset %"PRIu32", prev_offset %"PRIu32, prev_offset, depth); - if (prev_offset != 0) - offset = prev_offset; - - SCLogDebug("offset %"PRIu32", depth %"PRIu32, offset, depth); - - if (depth > payload_len) - depth = payload_len; - - /* if offset is bigger than depth we can never match on a pattern. - * We can however, "match" on a negated pattern. */ - if (offset > depth || depth == 0) { - if (ud->flags & DETECT_CONTENT_NEGATED) { - goto match; - } else { - SCReturnInt(0); - } - } - - uint8_t *spayload = payload + offset; - uint32_t spayload_len = depth - offset; - uint32_t match_offset = 0; - SCLogDebug("spayload_len %"PRIu32, spayload_len); -#ifdef DEBUG - BUG_ON(spayload_len > payload_len); -#endif - - //PrintRawDataFp(stdout,ud->content,ud->content_len); - - /* If we got no matches from the mpm, avoid searching (just check if negated) */ - //if (det_ctx->de_have_httpuri == TRUE) { - /* do the actual search with boyer moore precooked ctx */ - if (ud->flags & DETECT_CONTENT_NOCASE) - found = BoyerMooreNocase(ud->content, ud->content_len, spayload, spayload_len, ud->bm_ctx->bmGs, ud->bm_ctx->bmBc); - else - found = BoyerMoore(ud->content, ud->content_len, spayload, spayload_len, ud->bm_ctx->bmGs, ud->bm_ctx->bmBc); - //} else { - // found = NULL; - //} - - /* next we evaluate the result in combination with the - * negation flag. */ - SCLogDebug("found %p ud negated %s", found, ud->flags & DETECT_CONTENT_NEGATED ? "true" : "false"); - - if (found == NULL && !(ud->flags & DETECT_CONTENT_NEGATED)) { - SCReturnInt(0); - } else if (found == NULL && ud->flags & DETECT_CONTENT_NEGATED) { - goto match; - } else if (found != NULL && ud->flags & DETECT_CONTENT_NEGATED) { - SCLogDebug("uricontent %"PRIu32" matched at offset %"PRIu32", but negated so no match", ud->id, match_offset); - det_ctx->discontinue_matching = 1; - SCReturnInt(0); - } else { - match_offset = (uint32_t)((found - payload) + ud->content_len); - SCLogDebug("uricontent %"PRIu32" matched at offset %"PRIu32"", ud->id, match_offset); - det_ctx->payload_offset = match_offset; - - if (!(ud->flags & DETECT_CONTENT_RELATIVE_NEXT)) { - SCLogDebug("no relative match coming up, so this is a match"); - goto match; - } - - /* bail out if we have no next match. Technically this is an - * error, as the current cd has the DETECT_CONTENT_RELATIVE_NEXT - * flag set. */ - if (sm->next == NULL) { - SCReturnInt(0); - } - - SCLogDebug("uricontent %"PRIu32, ud->id); - - /* see if the next payload keywords match. If not, we will - * search for another occurence of this uricontent and see - * if the others match then until we run out of matches */ - int r = DoInspectPacketUri(de_ctx,det_ctx,s,sm->next, payload, payload_len); - if (r == 1) { - SCReturnInt(1); - } - - if (det_ctx->discontinue_matching) - SCReturnInt(0); - - /* set the previous match offset to the start of this match + 1 */ - prev_offset = (match_offset - (ud->content_len - 1)); - SCLogDebug("trying to see if there is another match after prev_offset %"PRIu32, prev_offset); - } - - } while(1); - } else if (sm->type == DETECT_PCRE) { - SCLogDebug("inspecting pcre"); - DetectPcreData *pe = (DetectPcreData *)sm->ctx; - uint32_t prev_payload_offset = det_ctx->payload_offset; - uint32_t prev_offset = 0; - int r = 0; - - det_ctx->pcre_match_start_offset = 0; - do { - r = DetectPcrePayloadMatch(det_ctx, s, sm, NULL, NULL, - payload, payload_len); - if (r == 0) { - det_ctx->discontinue_matching = 1; - SCReturnInt(0); - } - - if (!(pe->flags & DETECT_PCRE_RELATIVE_NEXT)) { - SCLogDebug("no relative match coming up, so this is a match"); - goto match; - } - - /* save it, in case we need to do a pcre match once again */ - prev_offset = det_ctx->pcre_match_start_offset; - - /* see if the next payload keywords match. If not, we will - * search for another occurence of this pcre and see - * if the others match, until we run out of matches */ - r = DoInspectPacketUri(de_ctx, det_ctx, s, sm->next, - payload, payload_len); - if (r == 1) { - SCReturnInt(1); - } - - if (det_ctx->discontinue_matching) - SCReturnInt(0); - - det_ctx->payload_offset = prev_payload_offset; - det_ctx->pcre_match_start_offset = prev_offset; - } while (1); - } else if (sm->type == DETECT_ISDATAAT) { - SCLogDebug("inspecting isdataat"); - - DetectIsdataatData *id = (DetectIsdataatData *)sm->ctx; - if (id->flags & ISDATAAT_RELATIVE) { - if (det_ctx->payload_offset + id->dataat > payload_len) { - SCLogDebug("det_ctx->payload_offset + id->dataat %"PRIu32" > %"PRIu32, det_ctx->payload_offset + id->dataat, payload_len); - if (id->flags & ISDATAAT_NEGATED) - goto match; - SCReturnInt(0); - } else { - SCLogDebug("relative isdataat match"); - if (id->flags & ISDATAAT_NEGATED) - SCReturnInt(0); - goto match; - } - } else { - if (id->dataat < payload_len) { - SCLogDebug("absolute isdataat match"); - if (id->flags & ISDATAAT_NEGATED) - SCReturnInt(0); - goto match; - } else { - SCLogDebug("absolute isdataat mismatch, id->isdataat %"PRIu32", payload_len %"PRIu32"", id->dataat,payload_len); - if (id->flags & ISDATAAT_NEGATED) - goto match; - SCReturnInt(0); - } - } - } else if (sm->type == DETECT_AL_URILEN) { - SCLogDebug("inspecting uri len"); - - int r = 0; - DetectUrilenData *urilend = (DetectUrilenData *) sm->ctx; - - switch (urilend->mode) { - case DETECT_URILEN_EQ: - if (payload_len == urilend->urilen1) - r = 1; - break; - case DETECT_URILEN_LT: - if (payload_len < urilend->urilen1) - r = 1; - break; - case DETECT_URILEN_GT: - if (payload_len > urilend->urilen1) - r = 1; - break; - case DETECT_URILEN_RA: - if (payload_len > urilend->urilen1 && - payload_len < urilend->urilen2) { - r = 1; - } - break; - } - - if (r == 1) { - goto match; - } - - SCReturnInt(0); - } else if (sm->type == DETECT_BYTE_EXTRACT) { - DetectByteExtractData *bed = (DetectByteExtractData *)sm->ctx; - if (DetectByteExtractDoMatch(det_ctx, sm, s, payload, - payload_len, - &det_ctx->bj_values[bed->local_id], - bed->endian) != 1) { - SCReturnInt(0); - } - - goto match; - } else { - /* we should never get here, but bail out just in case */ - SCLogDebug("sm->type %u", sm->type); -#ifdef DEBUG - BUG_ON(1); -#endif - } - SCReturnInt(0); - -match: - /* this sigmatch matched, inspect the next one. If it was the last, - * the payload portion of the signature matched. */ - if (sm->next != NULL) { - int r = DoInspectPacketUri(de_ctx, det_ctx, s, sm->next, payload, - payload_len); - SCReturnInt(r); - } else { - SCReturnInt(1); - } -} - /** \brief Do the content inspection & validation for a signature * * \param de_ctx Detection engine context