From f2e6ec737436429e0b4dca5b4649d88cb8a85dc3 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Mon, 1 Nov 2010 17:56:59 +0100 Subject: [PATCH] Fix http_method not inspecting all http transactions all the time. Fix proper nocase setting. Switch to pattern scanning only, no more numeric compares as it turned to be incompatible with how the keyword is used (nocase, etc). --- src/detect-http-method.c | 98 +++++++++++++++++++++++++++++----------- src/detect-http-method.h | 1 - 2 files changed, 71 insertions(+), 28 deletions(-) diff --git a/src/detect-http-method.c b/src/detect-http-method.c index 9cf3254e0b..8f11857135 100644 --- a/src/detect-http-method.c +++ b/src/detect-http-method.c @@ -92,6 +92,7 @@ int DetectHttpMethodMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, Signature *s, SigMatch *sm) { SCEnter(); + size_t idx; DetectHttpMethodData *data = (DetectHttpMethodData *)sm->ctx; HtpState *hs = (HtpState *)state; @@ -108,37 +109,33 @@ int DetectHttpMethodMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, idx < list_size(hs->connp->conn->transactions); idx++) { tx = list_get(hs->connp->conn->transactions, idx); - if (tx == NULL) + if (tx == NULL || tx->request_method == NULL) continue; - /* Compare the numeric methods if they are known, otherwise compare - * the raw values. */ - if (data->method != M_UNKNOWN) { - if (data->method == tx->request_method_number) { - SCLogDebug("Matched numeric HTTP method values."); - ret = 1; + const uint8_t *meth_str = (const uint8_t *)bstr_ptr(tx->request_method); + if (meth_str != NULL) { + /* + printf("Method buffer: ");PrintRawUriFp(stdout, meth_str, bstr_size(tx->request_method));printf("\n"); + printf("Pattern: ");PrintRawUriFp(stdout, data->content, data->content_len);printf("\n"); + */ + + if (data->flags & DETECT_AL_HTTP_METHOD_NOCASE) { + SCLogDebug("no case inspection"); + ret = (SpmNocaseSearch((uint8_t *)meth_str, bstr_size(tx->request_method), + data->content, data->content_len) != NULL); + } else { + SCLogDebug("case sensitive inspection"); + ret = (SpmSearch((uint8_t *)meth_str, bstr_size(tx->request_method), + data->content, data->content_len) != NULL); } - } else if (tx->request_method != NULL) { - const uint8_t *meth_str = (const uint8_t *) - bstr_ptr(tx->request_method); - if (meth_str != NULL) { - if (data->flags & DETECT_AL_HTTP_METHOD_NOCASE) { - ret = (SpmNocaseSearch((uint8_t *)meth_str, bstr_size(tx->request_method), - data->content, data->content_len) != NULL); - } else { - ret = (SpmSearch((uint8_t*) meth_str, bstr_size(tx->request_method), - data->content, data->content_len) != NULL); - } - if (ret == 1) { - SCLogDebug("Matched raw HTTP method values."); - } + if (ret == 1) { + SCLogDebug("matched HTTP method."); break; } } } SCMutexUnlock(&f->m); - //SCReturnInt(ret); SCReturnInt(ret ^ ((data->flags & DETECT_AL_HTTP_METHOD_NEGATED) ? 1 : 0)); } @@ -157,7 +154,6 @@ static int DetectHttpMethodSetup(DetectEngineCtx *de_ctx, Signature *s, char *st { SCEnter(); DetectHttpMethodData *data = NULL; - bstr *method; /** new sig match to replace previous content */ SigMatch *nm = NULL; @@ -210,12 +206,12 @@ static int DetectHttpMethodSetup(DetectEngineCtx *de_ctx, Signature *s, char *st data->content_len = ((DetectContentData *)pm->ctx)->content_len; data->content = ((DetectContentData *)pm->ctx)->content; + /* transfer the nocase flag if it has already been set */ + if (((DetectContentData *)pm->ctx)->flags & DETECT_CONTENT_NOCASE) { + data->flags |= DETECT_AL_HTTP_METHOD_NOCASE; + } - method = bstr_memdup((char *)data->content, data->content_len); - /** \todo error check */ - data->method = htp_convert_method_to_number(method); data->id = DetectPatternGetId(de_ctx->mpm_pattern_id_store, data, DETECT_AL_HTTP_METHOD); - bstr_free(method); nm->type = DETECT_AL_HTTP_METHOD; nm->ctx = (void *)data; @@ -637,6 +633,53 @@ int DetectHttpMethodTest11(void) return result; } +/** \test setting the nocase flag */ +static int DetectHttpMethodTest12(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + if ( (de_ctx = DetectEngineCtxInit()) == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + + if (DetectEngineAppendSig(de_ctx, "alert http any any -> any any " + "(content:one; http_method; nocase; sid:1;)") == NULL) { + printf("DetectEngineAppend == NULL: "); + goto end; + } + if (DetectEngineAppendSig(de_ctx, "alert http any any -> any any " + "(content:one; nocase; http_method; sid:2;)") == NULL) { + printf("DetectEngineAppend == NULL: "); + goto end; + } + + if (de_ctx->sig_list->amatch == NULL) { + printf("de_ctx->sig_list->amatch == NULL: "); + goto end; + } + + DetectHttpMethodData *hmd1 = de_ctx->sig_list->amatch_tail->ctx; + DetectHttpMethodData *hmd2 = de_ctx->sig_list->next->amatch_tail->ctx; + + if (!(hmd1->flags & DETECT_AL_HTTP_METHOD_NOCASE)) { + printf("nocase flag not set on sig 1: "); + goto end; + } + + if (!(hmd2->flags & DETECT_AL_HTTP_METHOD_NOCASE)) { + printf("nocase flag not set on sig 2: "); + goto end; + } + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + /** \test Check a signature with an known request method */ static int DetectHttpMethodSigTest01(void) { @@ -944,6 +987,7 @@ void DetectHttpMethodRegisterTests(void) { UtRegisterTest("DetectHttpMethodTest09", DetectHttpMethodTest09, 1); UtRegisterTest("DetectHttpMethodTest10", DetectHttpMethodTest10, 1); UtRegisterTest("DetectHttpMethodTest11", DetectHttpMethodTest11, 1); + UtRegisterTest("DetectHttpMethodTest12 -- nocase flag", DetectHttpMethodTest12, 1); UtRegisterTest("DetectHttpMethodSigTest01", DetectHttpMethodSigTest01, 1); UtRegisterTest("DetectHttpMethodSigTest02", DetectHttpMethodSigTest02, 1); UtRegisterTest("DetectHttpMethodSigTest03", DetectHttpMethodSigTest03, 1); diff --git a/src/detect-http-method.h b/src/detect-http-method.h index f194e94c1a..05c3f59236 100644 --- a/src/detect-http-method.h +++ b/src/detect-http-method.h @@ -34,7 +34,6 @@ typedef struct DetectHttpMethodData_ { uint8_t *content; /**< Raw HTTP method content to match */ uint8_t content_len; /**< Raw HTTP method content length */ PatIntId id; - int method; /**< Numeric HTTP method to match */ uint8_t flags; } DetectHttpMethodData;