diff --git a/src/detect-engine-hrhd.c b/src/detect-engine-hrhd.c index 496f9b5b4f..c20135c0f0 100644 --- a/src/detect-engine-hrhd.c +++ b/src/detect-engine-hrhd.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation +/* Copyright (C) 2007-2016 Open Information Security Foundation * * You can copy, redistribute or modify this Program under the terms of * the GNU General Public License version 2 as published by the Free @@ -25,6 +25,7 @@ /** \file * * \author Anoop Saldanha + * \author Victor Julien * * \brief Handle HTTP raw header match. * @@ -41,6 +42,7 @@ #include "detect-parse.h" #include "detect-engine-state.h" #include "detect-engine-content-inspection.h" +#include "detect-engine-prefilter.h" #include "flow-util.h" #include "util-debug.h" @@ -59,75 +61,92 @@ #include "util-validate.h" -/** - * \brief Http raw header match -- searches for one pattern per signature. - * - * \param det_ctx Detection engine thread ctx. - * \param raw_headers Raw headers to inspect. - * \param raw_headers_len Raw headers length. +/** \brief HTTP Raw Header Mpm prefilter callback * - * \retval ret Number of matches. + * \param det_ctx detection engine thread ctx + * \param p packet to inspect + * \param f flow to inspect + * \param txv tx to inspect + * \param pectx inspection context */ -static inline uint32_t HttpRawHeaderPatternSearch(DetectEngineThreadCtx *det_ctx, - const uint8_t *raw_headers, const uint32_t raw_headers_len, - const uint8_t flags) +static void PrefilterTxRequestHeadersRaw(DetectEngineThreadCtx *det_ctx, + const void *pectx, + Packet *p, Flow *f, void *txv, + const uint64_t idx, const uint8_t flags) { SCEnter(); - uint32_t ret = 0; - - if (flags & STREAM_TOSERVER) { - DEBUG_VALIDATE_BUG_ON(det_ctx->sgh->mpm_hrhd_ctx_ts == NULL); + const MpmCtx *mpm_ctx = (MpmCtx *)pectx; + htp_tx_t *tx = (htp_tx_t *)txv; + HtpTxUserData *tx_ud = htp_tx_get_user_data(tx); + if (tx_ud == NULL || tx_ud->request_headers_raw == NULL) + return; - if (raw_headers_len >= det_ctx->sgh->mpm_hrhd_ctx_ts->minlen) { - ret = mpm_table[det_ctx->sgh->mpm_hrhd_ctx_ts->mpm_type]. - Search(det_ctx->sgh->mpm_hrhd_ctx_ts, &det_ctx->mtcu, - &det_ctx->pmq, raw_headers, raw_headers_len); - } - } else { - DEBUG_VALIDATE_BUG_ON(det_ctx->sgh->mpm_hrhd_ctx_tc == NULL); + const uint32_t buffer_len = tx_ud->request_headers_raw_len; + const uint8_t *buffer = tx_ud->request_headers_raw; - if (raw_headers_len >= det_ctx->sgh->mpm_hrhd_ctx_tc->minlen) { - ret = mpm_table[det_ctx->sgh->mpm_hrhd_ctx_tc->mpm_type]. - Search(det_ctx->sgh->mpm_hrhd_ctx_tc, &det_ctx->mtcu, - &det_ctx->pmq, raw_headers, raw_headers_len); - } + if (buffer_len >= mpm_ctx->minlen) { + (void)mpm_table[mpm_ctx->mpm_type].Search(mpm_ctx, + &det_ctx->mtcu, &det_ctx->pmq, buffer, buffer_len); } - - SCReturnUInt(ret); } -int DetectEngineRunHttpRawHeaderMpm(DetectEngineThreadCtx *det_ctx, Flow *f, - HtpState *htp_state, uint8_t flags, - void *txv, uint64_t idx) +int PrefilterTxRequestHeadersRawRegister(SigGroupHead *sgh, MpmCtx *mpm_ctx) { SCEnter(); - uint32_t cnt = 0; + int r = PrefilterAppendTxEngine(sgh, PrefilterTxRequestHeadersRaw, + ALPROTO_HTTP, HTP_REQUEST_HEADERS+1, /* inspect when headers complete */ + mpm_ctx, NULL); + if (r != 0) + return r; + return PrefilterAppendTxEngine(sgh, PrefilterTxRequestHeadersRaw, + ALPROTO_HTTP, HTP_REQUEST_TRAILER+1, /* inspect when trailer complete */ + mpm_ctx, NULL); +} + +/** \brief HTTP Raw Header Mpm prefilter callback + * + * \param det_ctx detection engine thread ctx + * \param p packet to inspect + * \param f flow to inspect + * \param txv tx to inspect + * \param pectx inspection context + */ +static void PrefilterTxResponseHeadersRaw(DetectEngineThreadCtx *det_ctx, + const void *pectx, + Packet *p, Flow *f, void *txv, + const uint64_t idx, const uint8_t flags) +{ + SCEnter(); + const MpmCtx *mpm_ctx = (MpmCtx *)pectx; htp_tx_t *tx = (htp_tx_t *)txv; HtpTxUserData *tx_ud = htp_tx_get_user_data(tx); - if (tx_ud == NULL) { - SCReturnInt(0); - } + if (tx_ud == NULL || tx_ud->response_headers_raw == NULL) + return; - if (flags & STREAM_TOSERVER) { - if (tx_ud->request_headers_raw != NULL) { - cnt = HttpRawHeaderPatternSearch(det_ctx, - tx_ud->request_headers_raw, - tx_ud->request_headers_raw_len, - flags); - } - } else { - if (tx_ud->response_headers_raw != NULL) { - cnt = HttpRawHeaderPatternSearch(det_ctx, - tx_ud->response_headers_raw, - tx_ud->response_headers_raw_len, - flags); - } + const uint32_t buffer_len = tx_ud->response_headers_raw_len; + const uint8_t *buffer = tx_ud->response_headers_raw; + + if (buffer_len >= mpm_ctx->minlen) { + (void)mpm_table[mpm_ctx->mpm_type].Search(mpm_ctx, + &det_ctx->mtcu, &det_ctx->pmq, buffer, buffer_len); } +} - SCReturnInt(cnt); +int PrefilterTxResponseHeadersRawRegister(SigGroupHead *sgh, MpmCtx *mpm_ctx) +{ + SCEnter(); + + int r = PrefilterAppendTxEngine(sgh, PrefilterTxResponseHeadersRaw, + ALPROTO_HTTP, HTP_RESPONSE_HEADERS+1, /* inspect when headers complete */ + mpm_ctx, NULL); + if (r != 0) + return r; + return PrefilterAppendTxEngine(sgh, PrefilterTxResponseHeadersRaw, + ALPROTO_HTTP, HTP_RESPONSE_TRAILER+1, /* inspect when trailer complete */ + mpm_ctx, NULL); } /** @@ -1851,156 +1870,6 @@ end: return result; } -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpRawHeaderTest18(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - uint8_t http_buf[] = - "Host: www.onetwothreefourfivesixsevenfive.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; flow:to_server; " - "content:\"one\"; http_raw_header; content:\"five\"; http_raw_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - /* start the search phase */ - det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - uint32_t r = HttpRawHeaderPatternSearch(det_ctx, http_buf, http_len, STREAM_TOSERVER); - if (r < 1) { - printf("expected result >= 1, got %"PRIu32": ", r); - goto end; - } - - result = 1; - -end: - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpRawHeaderTest19(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - uint8_t http_buf[] = - "Host: www.onetwothreefourfivesixsevenfive.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; flow:to_server; " - "content:\"one\"; http_raw_header; fast_pattern; content:\"five\"; http_raw_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - /* start the search phase */ - det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - uint32_t r = HttpRawHeaderPatternSearch(det_ctx, http_buf, http_len, STREAM_TOSERVER); - if (r != 1) { - printf("expected result 1, got %"PRIu32": ", r); - goto end; - } - - result = 1; - -end: - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - static int DetectEngineHttpRawHeaderTest20(void) { TcpSession ssn; @@ -3577,10 +3446,6 @@ void DetectEngineHttpRawHeaderRegisterTests(void) DetectEngineHttpRawHeaderTest16); UtRegisterTest("DetectEngineHttpRawHeaderTest17", DetectEngineHttpRawHeaderTest17); - UtRegisterTest("DetectEngineHttpRawHeaderTest18", - DetectEngineHttpRawHeaderTest18); - UtRegisterTest("DetectEngineHttpRawHeaderTest19", - DetectEngineHttpRawHeaderTest19); UtRegisterTest("DetectEngineHttpRawHeaderTest20", DetectEngineHttpRawHeaderTest20); UtRegisterTest("DetectEngineHttpRawHeaderTest21", diff --git a/src/detect-engine-hrhd.h b/src/detect-engine-hrhd.h index c33d57e7d7..6d043f3cf0 100644 --- a/src/detect-engine-hrhd.h +++ b/src/detect-engine-hrhd.h @@ -25,15 +25,15 @@ #include "app-layer-htp.h" +int PrefilterTxRequestHeadersRawRegister(SigGroupHead *sgh, MpmCtx *mpm_ctx); +int PrefilterTxResponseHeadersRawRegister(SigGroupHead *sgh, MpmCtx *mpm_ctx); + int DetectEngineInspectHttpRawHeader(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Signature *s, Flow *f, uint8_t flags, void *alstate, void *tx, uint64_t tx_id); -int DetectEngineRunHttpRawHeaderMpm(DetectEngineThreadCtx *det_ctx, Flow *f, - HtpState *htp_state, uint8_t flags, - void *tx, uint64_t idx); void DetectEngineHttpRawHeaderRegisterTests(void); #endif /* __DETECT_ENGINE_HHD_H__ */ diff --git a/src/detect-engine-mpm.c b/src/detect-engine-mpm.c index c6f7ef70ff..d142872e82 100644 --- a/src/detect-engine-mpm.c +++ b/src/detect-engine-mpm.c @@ -53,6 +53,7 @@ #include "detect-engine-hrud.h" #include "detect-engine-hmd.h" #include "detect-engine-hhd.h" +#include "detect-engine-hrhd.h" #include "detect-engine-hcd.h" #include "detect-engine-hua.h" #include "detect-engine-hhhd.h" @@ -107,8 +108,10 @@ AppLayerMpms app_mpms[] = { { "http_user_agent", 0, SIG_FLAG_TOSERVER, DETECT_SM_LIST_HUADMATCH, SIG_GROUP_HEAD_MPM_HUAD, PrefilterTxUARegister, 4}, - { "http_raw_header", 0, SIG_FLAG_TOSERVER, DETECT_SM_LIST_HRHDMATCH, SIG_GROUP_HEAD_MPM_HRHD, NULL, 5}, - { "http_raw_header", 0, SIG_FLAG_TOCLIENT, DETECT_SM_LIST_HRHDMATCH, SIG_GROUP_HEAD_MPM_HRHD, NULL, 6}, + { "http_raw_header", 0, SIG_FLAG_TOSERVER, DETECT_SM_LIST_HRHDMATCH, + SIG_GROUP_HEAD_MPM_HRHD, PrefilterTxRequestHeadersRawRegister, 5}, + { "http_raw_header", 0, SIG_FLAG_TOCLIENT, DETECT_SM_LIST_HRHDMATCH, + SIG_GROUP_HEAD_MPM_HRHD, PrefilterTxResponseHeadersRawRegister, 6}, { "http_method", 0, SIG_FLAG_TOSERVER, DETECT_SM_LIST_HMDMATCH, SIG_GROUP_HEAD_MPM_HMD, PrefilterTxMethodRegister, 7}, diff --git a/src/detect.c b/src/detect.c index 4fc038683b..1e72d65656 100644 --- a/src/detect.c +++ b/src/detect.c @@ -877,52 +877,7 @@ static inline void DetectMpmPrefilter(DetectEngineCtx *de_ctx, if (p->flowflags & FLOW_PKT_ESTABLISHED) { SCLogDebug("p->flowflags & FLOW_PKT_ESTABLISHED"); - /* all http based mpms */ - if (has_state && alproto == ALPROTO_HTTP) { - void *alstate = FlowGetAppState(p->flow); - if (alstate == NULL) { - SCLogDebug("no alstate"); - return; - } - - HtpState *htp_state = (HtpState *)alstate; - if (htp_state->connp == NULL) { - SCLogDebug("no HTTP connp"); - return; - } - - int tx_progress = 0; - uint64_t idx = AppLayerParserGetTransactionInspectId(p->flow->alparser, flags); - uint64_t total_txs = AppLayerParserGetTxCnt(IPPROTO_TCP, ALPROTO_HTTP, alstate); - for (; idx < total_txs; idx++) { - htp_tx_t *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, htp_state, idx); - if (tx == NULL) - continue; - - if (p->flowflags & FLOW_PKT_TOSERVER) { - tx_progress = AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags); - - if (tx_progress > HTP_REQUEST_HEADERS) { - if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HRHD) { - PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HRHD); - DetectEngineRunHttpRawHeaderMpm(det_ctx, p->flow, alstate, flags, tx, idx); - PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HRHD); - } - } - - } else { /* implied FLOW_PKT_TOCLIENT */ - tx_progress = AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags); - - if (tx_progress > HTP_RESPONSE_HEADERS) { - if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HRHD) { - PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HRHD); - DetectEngineRunHttpRawHeaderMpm(det_ctx, p->flow, alstate, flags, tx, idx); - PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HRHD); - } - } - } - } /* for */ - } else if (alproto == ALPROTO_TLS && has_state) { + if (alproto == ALPROTO_TLS && has_state) { void *alstate = FlowGetAppState(p->flow); if (alstate == NULL) { SCLogDebug("no alstate");