From 603d4a719ac39f418e59fbfb0563fb2ed1a8b303 Mon Sep 17 00:00:00 2001 From: Anoop Saldanha Date: Wed, 15 Feb 2012 20:48:07 +0530 Subject: [PATCH] remove det_ctx->payload_offset and use det_ctx->buffer_offset. Update hscd and hsmd to use the new generic content inspection engine --- src/detect-byte-extract.c | 10 +- src/detect-bytejump.c | 12 +- src/detect-bytetest.c | 8 +- src/detect-engine-content-inspection.c | 55 ++++- src/detect-engine-content-inspection.h | 2 + src/detect-engine-dcepayload.c | 4 +- src/detect-engine-hcbd.c | 4 + src/detect-engine-hcd.c | 4 + src/detect-engine-hhd.c | 4 + src/detect-engine-hmd.c | 4 + src/detect-engine-hrhd.c | 3 + src/detect-engine-hrud.c | 2 +- src/detect-engine-hsbd.c | 4 + src/detect-engine-hscd.c | 296 +------------------------ src/detect-engine-hsmd.c | 296 +------------------------ src/detect-engine-payload.c | 4 +- src/detect-engine-uri.c | 2 +- src/detect-pcre.c | 30 +-- src/detect.h | 9 - 19 files changed, 123 insertions(+), 630 deletions(-) diff --git a/src/detect-byte-extract.c b/src/detect-byte-extract.c index af8f92ee7f..7140ed41a5 100644 --- a/src/detect-byte-extract.c +++ b/src/detect-byte-extract.c @@ -152,11 +152,11 @@ int DetectByteExtractDoMatch(DetectEngineThreadCtx *det_ctx, SigMatch *sm, * the packet from that point. */ if (data->flags & DETECT_BYTE_EXTRACT_FLAG_RELATIVE) { - SCLogDebug("relative, working with det_ctx->payload_offset %"PRIu32", " - "data->offset %"PRIu32"", det_ctx->payload_offset, data->offset); + SCLogDebug("relative, working with det_ctx->buffer_offset %"PRIu32", " + "data->offset %"PRIu32"", det_ctx->buffer_offset, data->offset); - ptr = payload + det_ctx->payload_offset; - len = payload_len - det_ctx->payload_offset; + ptr = payload + det_ctx->buffer_offset; + len = payload_len - det_ctx->buffer_offset; /* No match if there is no relative base */ if (len == 0) { @@ -217,7 +217,7 @@ int DetectByteExtractDoMatch(DetectEngineThreadCtx *det_ctx, SigMatch *sm, ptr += extbytes; - det_ctx->payload_offset = ptr - payload; + det_ctx->buffer_offset = ptr - payload; *value = val; diff --git a/src/detect-bytejump.c b/src/detect-bytejump.c index 0108a7f9a0..7a44393491 100644 --- a/src/detect-bytejump.c +++ b/src/detect-bytejump.c @@ -126,8 +126,8 @@ int DetectBytejumpDoMatch(DetectEngineThreadCtx *det_ctx, Signature *s, * the packet from that point. */ if (flags & DETECT_BYTEJUMP_RELATIVE) { - ptr = payload + det_ctx->payload_offset; - len = payload_len - det_ctx->payload_offset; + ptr = payload + det_ctx->buffer_offset; + len = payload_len - det_ctx->buffer_offset; /* No match if there is no relative base */ if (ptr == NULL || len == 0) { @@ -211,7 +211,7 @@ int DetectBytejumpDoMatch(DetectEngineThreadCtx *det_ctx, Signature *s, #endif /* DEBUG */ /* Adjust the detection context to the jump location. */ - det_ctx->payload_offset = jumpptr - payload; + det_ctx->buffer_offset = jumpptr - payload; SCReturnInt(1); } @@ -234,8 +234,8 @@ int DetectBytejumpMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, * the packet from that point. */ if (data->flags & DETECT_BYTEJUMP_RELATIVE) { - ptr = p->payload + det_ctx->payload_offset; - len = p->payload_len - det_ctx->payload_offset; + ptr = p->payload + det_ctx->buffer_offset; + len = p->payload_len - det_ctx->buffer_offset; /* No match if there is no relative base */ if (ptr == NULL || len == 0) { @@ -320,7 +320,7 @@ int DetectBytejumpMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, #endif /* DEBUG */ /* Adjust the detection context to the jump location. */ - det_ctx->payload_offset = jumpptr - p->payload; + det_ctx->buffer_offset = jumpptr - p->payload; return 1; } diff --git a/src/detect-bytetest.c b/src/detect-bytetest.c index 2c1385524f..354bd1a18a 100644 --- a/src/detect-bytetest.c +++ b/src/detect-bytetest.c @@ -130,11 +130,11 @@ int DetectBytetestDoMatch(DetectEngineThreadCtx *det_ctx, Signature *s, SigMatch * the packet from that point. */ if (flags & DETECT_BYTETEST_RELATIVE) { - SCLogDebug("relative, working with det_ctx->payload_offset %"PRIu32", " - "data->offset %"PRIu32"", det_ctx->payload_offset, data->offset); + SCLogDebug("relative, working with det_ctx->buffer_offset %"PRIu32", " + "data->offset %"PRIu32"", det_ctx->buffer_offset, data->offset); - ptr = payload + det_ctx->payload_offset; - len = payload_len - det_ctx->payload_offset; + ptr = payload + det_ctx->buffer_offset; + len = payload_len - det_ctx->buffer_offset; /* No match if there is no relative base */ if (ptr == NULL || len == 0) { diff --git a/src/detect-engine-content-inspection.c b/src/detect-engine-content-inspection.c index 24347efa82..6bc2d29661 100644 --- a/src/detect-engine-content-inspection.c +++ b/src/detect-engine-content-inspection.c @@ -52,6 +52,41 @@ #include "util-unittest.h" #include "util-unittest-helper.h" +/** + * \brief Run the actual payload match functions + * + * The following keywords are inspected: + * - content, including all the http and dce modified contents + * - isdaatat + * - pcre + * - bytejump + * - bytetest + * - byte_extract + * - urilen + * - + * + * All keywords are evaluated against the buffer with buffer_len. + * + * For accounting the last match in relative matching the + * det_ctx->buffer_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 buffer Ptr to the buffer to inspect + * \param buffer_len Length of the payload + * \param inspection_mode Refers to the engine inspection mode we are currently + * inspecting. Can be payload, stream, one of the http + * buffer inspection modes or dce inspection mode. + * \param data Used to send some custom data. For example in + * payload inspection mode, data contains packet ptr, + * and under dce inspection mode, contains dce state. + * + * \retval 0 no match + * \retval 1 match + */ int DetectEngineContentInspection(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Signature *s, SigMatch *sm, Flow *f, @@ -80,7 +115,9 @@ int DetectEngineContentInspection(DetectEngineCtx *de_ctx, DetectEngineThreadCtx sm->type == DETECT_AL_HTTP_CLIENT_BODY || sm->type == DETECT_AL_HTTP_SERVER_BODY || sm->type == DETECT_AL_HTTP_COOKIE || - sm->type == DETECT_AL_HTTP_METHOD) { + sm->type == DETECT_AL_HTTP_METHOD || + sm->type == DETECT_AL_HTTP_STAT_CODE || + sm->type == DETECT_AL_HTTP_STAT_MSG) { DetectContentData *cd = (DetectContentData *)sm->ctx; SCLogDebug("inspecting content %"PRIu32" buffer_len %"PRIu32, cd->id, buffer_len); @@ -105,12 +142,12 @@ int DetectEngineContentInspection(DetectEngineCtx *de_ctx, DetectEngineThreadCtx uint32_t offset = 0; uint32_t depth = buffer_len; uint32_t prev_offset = 0; /**< used in recursive searching */ - uint32_t prev_buffer_offset = det_ctx->payload_offset; + uint32_t prev_buffer_offset = det_ctx->buffer_offset; do { if (cd->flags & DETECT_CONTENT_DISTANCE || cd->flags & DETECT_CONTENT_WITHIN) { - SCLogDebug("det_ctx->payload_offset %"PRIu32, det_ctx->payload_offset); + SCLogDebug("det_ctx->buffer_offset %"PRIu32, det_ctx->buffer_offset); offset = prev_buffer_offset; depth = buffer_len; @@ -139,7 +176,7 @@ int DetectEngineContentInspection(DetectEngineCtx *de_ctx, DetectEngineThreadCtx depth = prev_buffer_offset + cd->within + distance; } - SCLogDebug("cd->within %"PRIi32", det_ctx->payload_offset %"PRIu32", depth %"PRIu32, + SCLogDebug("cd->within %"PRIi32", det_ctx->buffer_offset %"PRIu32", depth %"PRIu32, cd->within, prev_buffer_offset, depth); } } @@ -240,7 +277,7 @@ int DetectEngineContentInspection(DetectEngineCtx *de_ctx, DetectEngineThreadCtx } else { match_offset = (uint32_t)((found - buffer) + cd->content_len); SCLogDebug("content %"PRIu32" matched at offset %"PRIu32"", cd->id, match_offset); - det_ctx->payload_offset = match_offset; + det_ctx->buffer_offset = match_offset; /* Match branch, add replace to the list if needed */ if (cd->flags & DETECT_CONTENT_REPLACE) { @@ -288,8 +325,8 @@ int DetectEngineContentInspection(DetectEngineCtx *de_ctx, DetectEngineThreadCtx DetectIsdataatData *id = (DetectIsdataatData *)sm->ctx; if (id->flags & ISDATAAT_RELATIVE) { - if (det_ctx->payload_offset + id->dataat > buffer_len) { - SCLogDebug("det_ctx->payload_offset + id->dataat %"PRIu32" > %"PRIu32, det_ctx->payload_offset + id->dataat, buffer_len); + if (det_ctx->buffer_offset + id->dataat > buffer_len) { + SCLogDebug("det_ctx->buffer_offset + id->dataat %"PRIu32" > %"PRIu32, det_ctx->buffer_offset + id->dataat, buffer_len); if (id->flags & ISDATAAT_NEGATED) goto match; SCReturnInt(0); @@ -316,7 +353,7 @@ int DetectEngineContentInspection(DetectEngineCtx *de_ctx, DetectEngineThreadCtx } else if (sm->type == DETECT_PCRE) { SCLogDebug("inspecting pcre"); DetectPcreData *pe = (DetectPcreData *)sm->ctx; - uint32_t prev_buffer_offset = det_ctx->payload_offset; + uint32_t prev_buffer_offset = det_ctx->buffer_offset; uint32_t prev_offset = 0; int r = 0; @@ -352,7 +389,7 @@ int DetectEngineContentInspection(DetectEngineCtx *de_ctx, DetectEngineThreadCtx if (det_ctx->discontinue_matching) SCReturnInt(0); - det_ctx->payload_offset = prev_buffer_offset; + det_ctx->buffer_offset = prev_buffer_offset; det_ctx->pcre_match_start_offset = prev_offset; } while (1); diff --git a/src/detect-engine-content-inspection.h b/src/detect-engine-content-inspection.h index d7d4e249b6..21c94743c6 100644 --- a/src/detect-engine-content-inspection.h +++ b/src/detect-engine-content-inspection.h @@ -36,6 +36,8 @@ enum { DETECT_ENGINE_CONTENT_INSPECTION_MODE_HSBD, DETECT_ENGINE_CONTENT_INSPECTION_MODE_HCD, DETECT_ENGINE_CONTENT_INSPECTION_MODE_HMD, + DETECT_ENGINE_CONTENT_INSPECTION_MODE_HSCD, + DETECT_ENGINE_CONTENT_INSPECTION_MODE_HSMD, }; int DetectEngineContentInspection(DetectEngineCtx *, diff --git a/src/detect-engine-dcepayload.c b/src/detect-engine-dcepayload.c index 82af29f0b1..63c3ec238e 100644 --- a/src/detect-engine-dcepayload.c +++ b/src/detect-engine-dcepayload.c @@ -78,7 +78,7 @@ int DetectEngineInspectDcePayload(DetectEngineCtx *de_ctx, dce_stub_data = dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer; dce_stub_data_len = dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer_len; - det_ctx->payload_offset = 0; + det_ctx->buffer_offset = 0; det_ctx->discontinue_matching = 0; det_ctx->inspection_recursion_counter = 0; @@ -100,7 +100,7 @@ int DetectEngineInspectDcePayload(DetectEngineCtx *de_ctx, dce_stub_data = dcerpc_state->dcerpc.dcerpcresponse.stub_data_buffer; dce_stub_data_len = dcerpc_state->dcerpc.dcerpcresponse.stub_data_buffer_len; - det_ctx->payload_offset = 0; + det_ctx->buffer_offset = 0; det_ctx->discontinue_matching = 0; det_ctx->inspection_recursion_counter = 0; diff --git a/src/detect-engine-hcbd.c b/src/detect-engine-hcbd.c index 63ea81c98e..a6785fc832 100644 --- a/src/detect-engine-hcbd.c +++ b/src/detect-engine-hcbd.c @@ -253,6 +253,10 @@ int DetectEngineInspectHttpClientBody(DetectEngineCtx *de_ctx, if (hcbd_buffer == NULL) continue; + det_ctx->buffer_offset = 0; + det_ctx->discontinue_matching = 0; + det_ctx->inspection_recursion_counter = 0; + r = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_HCBDMATCH], f, hcbd_buffer, diff --git a/src/detect-engine-hcd.c b/src/detect-engine-hcd.c index 49b2e016c2..9d53e842b7 100644 --- a/src/detect-engine-hcd.c +++ b/src/detect-engine-hcd.c @@ -160,6 +160,10 @@ int DetectEngineInspectHttpCookie(DetectEngineCtx *de_ctx, continue; } + det_ctx->buffer_offset = 0; + det_ctx->discontinue_matching = 0; + det_ctx->inspection_recursion_counter = 0; + r = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_HCDMATCH], f, (uint8_t *)bstr_ptr(h->value), diff --git a/src/detect-engine-hhd.c b/src/detect-engine-hhd.c index 4b89605551..4bb077f07d 100644 --- a/src/detect-engine-hhd.c +++ b/src/detect-engine-hhd.c @@ -274,6 +274,10 @@ int DetectEngineInspectHttpHeader(DetectEngineCtx *de_ctx, if (hhd_buffer == NULL) continue; + det_ctx->buffer_offset = 0; + det_ctx->discontinue_matching = 0; + det_ctx->inspection_recursion_counter = 0; + r = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_HHDMATCH], f, hhd_buffer, diff --git a/src/detect-engine-hmd.c b/src/detect-engine-hmd.c index 153ee0088f..8de8f6d824 100644 --- a/src/detect-engine-hmd.c +++ b/src/detect-engine-hmd.c @@ -148,6 +148,10 @@ int DetectEngineInspectHttpMethod(DetectEngineCtx *de_ctx, if (tx == NULL || tx->request_method == NULL) continue; + det_ctx->buffer_offset = 0; + det_ctx->discontinue_matching = 0; + det_ctx->inspection_recursion_counter = 0; + r = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_HMDMATCH], f, (uint8_t *)bstr_ptr(tx->request_method), diff --git a/src/detect-engine-hrhd.c b/src/detect-engine-hrhd.c index 1cee22e744..174446a3cf 100644 --- a/src/detect-engine-hrhd.c +++ b/src/detect-engine-hrhd.c @@ -169,6 +169,9 @@ int DetectEngineInspectHttpRawHeader(DetectEngineCtx *de_ctx, if (raw_headers == NULL) continue; + det_ctx->buffer_offset = 0; + det_ctx->discontinue_matching = 0; + det_ctx->inspection_recursion_counter = 0; r = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_HRHDMATCH], f, (uint8_t *)bstr_ptr(raw_headers), diff --git a/src/detect-engine-hrud.c b/src/detect-engine-hrud.c index 8d3a4edacd..b29e7ec16b 100644 --- a/src/detect-engine-hrud.c +++ b/src/detect-engine-hrud.c @@ -160,7 +160,7 @@ int DetectEngineInspectHttpRawUri(DetectEngineCtx *de_ctx, continue; det_ctx->discontinue_matching = 0; - det_ctx->payload_offset = 0; + det_ctx->buffer_offset = 0; det_ctx->inspection_recursion_counter = 0; /* Inspect all the uricontents fetched on each diff --git a/src/detect-engine-hsbd.c b/src/detect-engine-hsbd.c index fee323183d..0fb94f41b7 100644 --- a/src/detect-engine-hsbd.c +++ b/src/detect-engine-hsbd.c @@ -254,6 +254,10 @@ int DetectEngineInspectHttpServerBody(DetectEngineCtx *de_ctx, if (hsbd_buffer == NULL) continue; + det_ctx->buffer_offset = 0; + det_ctx->discontinue_matching = 0; + det_ctx->inspection_recursion_counter = 0; + r = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_HSBDMATCH], f, hsbd_buffer, diff --git a/src/detect-engine-hscd.c b/src/detect-engine-hscd.c index 016395a372..2c0e4e5142 100644 --- a/src/detect-engine-hscd.c +++ b/src/detect-engine-hscd.c @@ -37,23 +37,13 @@ #include "detect-engine-hscd.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" @@ -62,278 +52,6 @@ #include "app-layer-htp.h" #include "app-layer-protos.h" -/** - * \brief Run the actual payload match function for http stat code. - * - * 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 stat code to inspect. - * \param payload_len Length of the http stat code. - * - * \retval 0 no match. - * \retval 1 match. - */ -static int DoInspectHttpStatCode(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_STAT_CODE) { - 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 = DoInspectHttpStatCode(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 = DoInspectHttpStatCode(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 { - /* 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 = DoInspectHttpStatCode(de_ctx, det_ctx, s, sm->next, payload, - payload_len); - SCReturnInt(r); - } else { - SCReturnInt(1); - } -} - /** * \brief Run the mpm against http stat code. * @@ -439,13 +157,15 @@ int DetectEngineInspectHttpStatCode(DetectEngineCtx *de_ctx, continue; det_ctx->discontinue_matching = 0; - det_ctx->payload_offset = 0; + det_ctx->buffer_offset = 0; det_ctx->inspection_recursion_counter = 0; - r = DoInspectHttpStatCode(de_ctx, det_ctx, s, - s->sm_lists[DETECT_SM_LIST_HSCDMATCH], - (uint8_t *)bstr_ptr(tx->response_status), - bstr_len(tx->response_status)); + r = DetectEngineContentInspection(de_ctx, det_ctx, s, + s->sm_lists[DETECT_SM_LIST_HSCDMATCH], + f, + (uint8_t *)bstr_ptr(tx->response_status), + bstr_len(tx->response_status), + DETECT_ENGINE_CONTENT_INSPECTION_MODE_HSCD, NULL); if (r == 1) { goto end; } diff --git a/src/detect-engine-hsmd.c b/src/detect-engine-hsmd.c index fb7ed6a228..06b8338f92 100644 --- a/src/detect-engine-hsmd.c +++ b/src/detect-engine-hsmd.c @@ -37,23 +37,13 @@ #include "detect-engine-hsmd.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" @@ -62,278 +52,6 @@ #include "app-layer-htp.h" #include "app-layer-protos.h" -/** - * \brief Run the actual payload match function for http stat msg. - * - * 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 stat msg to inspect. - * \param payload_len Length of the http stat msg. - * - * \retval 0 no match. - * \retval 1 match. - */ -static int DoInspectHttpStatMsg(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_STAT_MSG) { - 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 = DoInspectHttpStatMsg(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 = DoInspectHttpStatMsg(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 { - /* 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 = DoInspectHttpStatMsg(de_ctx, det_ctx, s, sm->next, payload, - payload_len); - SCReturnInt(r); - } else { - SCReturnInt(1); - } -} - /** * \brief Run the mpm against http stat msg. * @@ -439,13 +157,15 @@ int DetectEngineInspectHttpStatMsg(DetectEngineCtx *de_ctx, continue; det_ctx->discontinue_matching = 0; - det_ctx->payload_offset = 0; + det_ctx->buffer_offset = 0; det_ctx->inspection_recursion_counter = 0; - r = DoInspectHttpStatMsg(de_ctx, det_ctx, s, - s->sm_lists[DETECT_SM_LIST_HSMDMATCH], - (uint8_t *)bstr_ptr(tx->response_message), - bstr_len(tx->response_message)); + r = DetectEngineContentInspection(de_ctx, det_ctx, s, + s->sm_lists[DETECT_SM_LIST_HSMDMATCH], + f, + (uint8_t *)bstr_ptr(tx->response_message), + bstr_len(tx->response_message), + DETECT_ENGINE_CONTENT_INSPECTION_MODE_HSMD, NULL); if (r == 1) { goto end; } diff --git a/src/detect-engine-payload.c b/src/detect-engine-payload.c index 2b5819380d..d1774c28f7 100644 --- a/src/detect-engine-payload.c +++ b/src/detect-engine-payload.c @@ -64,7 +64,7 @@ int DetectEngineInspectPacketPayload(DetectEngineCtx *de_ctx, SCReturnInt(0); } - det_ctx->payload_offset = 0; + det_ctx->buffer_offset = 0; det_ctx->discontinue_matching = 0; det_ctx->inspection_recursion_counter = 0; det_ctx->replist = NULL; @@ -109,7 +109,7 @@ int DetectEngineInspectStreamPayload(DetectEngineCtx *de_ctx, SCReturnInt(0); } - det_ctx->payload_offset = 0; + det_ctx->buffer_offset = 0; det_ctx->discontinue_matching = 0; det_ctx->inspection_recursion_counter = 0; //det_ctx->flags |= DETECT_ENGINE_THREAD_CTX_INSPECTING_STREAM; diff --git a/src/detect-engine-uri.c b/src/detect-engine-uri.c index 3033820c07..dbf47f2ea4 100644 --- a/src/detect-engine-uri.c +++ b/src/detect-engine-uri.c @@ -102,7 +102,7 @@ int DetectEngineInspectPacketUris(DetectEngineCtx *de_ctx, continue; det_ctx->discontinue_matching = 0; - det_ctx->payload_offset = 0; + det_ctx->buffer_offset = 0; det_ctx->inspection_recursion_counter = 0; //PrintRawDataFp(stdout, (uint8_t *)bstr_ptr(tx->request_uri_normalized), diff --git a/src/detect-pcre.c b/src/detect-pcre.c index b63bb3428d..af7a748fb0 100644 --- a/src/detect-pcre.c +++ b/src/detect-pcre.c @@ -491,11 +491,11 @@ int DetectPcrePayloadMatch(DetectEngineThreadCtx *det_ctx, Signature *s, // SCReturnInt(0); if (s->flags & SIG_FLAG_RECURSIVE) { - ptr = payload + det_ctx->payload_offset; - len = payload_len - det_ctx->payload_offset; + ptr = payload + det_ctx->buffer_offset; + len = payload_len - det_ctx->buffer_offset; } else if (pe->flags & DETECT_PCRE_RELATIVE) { - ptr = payload + det_ctx->payload_offset; - len = payload_len - det_ctx->payload_offset; + ptr = payload + det_ctx->buffer_offset; + len = payload_len - det_ctx->buffer_offset; } else { ptr = payload; len = payload_len; @@ -546,7 +546,7 @@ int DetectPcrePayloadMatch(DetectEngineThreadCtx *det_ctx, Signature *s, } /* update offset for pcre RELATIVE */ - det_ctx->payload_offset = (ptr + ov[1]) - payload; + det_ctx->buffer_offset = (ptr + ov[1]) - payload; det_ctx->pcre_match_start_offset = (ptr + ov[0] + 1) - payload; ret = 1; @@ -588,11 +588,11 @@ int DetectPcrePacketPayloadMatch(DetectEngineThreadCtx *det_ctx, Packet *p, Sign SCReturnInt(0); if (s->flags & SIG_FLAG_RECURSIVE) { - ptr = p->payload + det_ctx->payload_offset; - len = p->payload_len - det_ctx->payload_offset; + ptr = p->payload + det_ctx->buffer_offset; + len = p->payload_len - det_ctx->buffer_offset; } else if (pe->flags & DETECT_PCRE_RELATIVE) { - ptr = p->payload + det_ctx->payload_offset; - len = p->payload_len - det_ctx->payload_offset; + ptr = p->payload + det_ctx->buffer_offset; + len = p->payload_len - det_ctx->buffer_offset; if (ptr == NULL || len == 0) SCReturnInt(0); } else { @@ -635,7 +635,7 @@ int DetectPcrePacketPayloadMatch(DetectEngineThreadCtx *det_ctx, Packet *p, Sign } /* update offset for pcre RELATIVE */ - det_ctx->payload_offset = (ptr+ov[1]) - p->payload; + det_ctx->buffer_offset = (ptr+ov[1]) - p->payload; ret = 1; } @@ -681,11 +681,11 @@ int DetectPcrePayloadDoMatch(DetectEngineThreadCtx *det_ctx, Signature *s, SCReturnInt(0); if (s->flags & SIG_FLAG_RECURSIVE) { - ptr = data + det_ctx->payload_offset; - len = data_len - det_ctx->payload_offset; + ptr = data + det_ctx->buffer_offset; + len = data_len - det_ctx->buffer_offset; } else if (pe->flags & DETECT_PCRE_RELATIVE) { - ptr = data + det_ctx->payload_offset; - len = data_len - det_ctx->payload_offset; + ptr = data + det_ctx->buffer_offset; + len = data_len - det_ctx->buffer_offset; if (ptr == NULL || len == 0) SCReturnInt(0); } else { @@ -728,7 +728,7 @@ int DetectPcrePayloadDoMatch(DetectEngineThreadCtx *det_ctx, Signature *s, } /* update offset for pcre RELATIVE */ - det_ctx->payload_offset = (ptr + ov[1]) - data; + det_ctx->buffer_offset = (ptr + ov[1]) - data; ret = 1; } diff --git a/src/detect.h b/src/detect.h index 717f603cc3..d2790f4874 100644 --- a/src/detect.h +++ b/src/detect.h @@ -695,7 +695,6 @@ typedef struct DetectionEngineThreadCtx_ { /** offset into the payload of the last match by: * content, pcre, etc */ uint32_t buffer_offset; - uint32_t payload_offset; /* used by pcre match function alone */ uint32_t pcre_match_start_offset; @@ -724,14 +723,6 @@ typedef struct DetectionEngineThreadCtx_ { /* holds the current recursion depth on content inspection */ int inspection_recursion_counter; - /* dce stub data */ - uint8_t *dce_stub_data; - /* dce stub data len */ - uint32_t dce_stub_data_len; - /* offset into the payload of the last match for dce related sigmatches, - * stored in s->sm_lists[DETECT_SM_LIST_DMATCH], by content, pcre, etc */ - uint32_t dce_payload_offset; - /** array of signature pointers we're going to inspect in the detection * loop. */ Signature **match_array;