From 4c98b6cef3dc36e212d24efd335875888292f571 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Thu, 8 Sep 2016 12:35:44 +0200 Subject: [PATCH] http_request_line: implement keyword and mpm Implemented as 'stickybuffer'. Move all logic into the keyword file and remove bad tests that tested URI instead of request line. --- src/Makefile.am | 2 +- src/detect-engine-hrl.c | 4237 ----------------- src/detect-engine-state.h | 2 +- src/detect-engine.c | 9 +- src/detect-fast-pattern.c | 7 +- src/detect-http-request-line.c | 316 ++ ...ngine-hrl.h => detect-http-request-line.h} | 17 +- src/detect-lua.c | 2 +- src/detect-parse.c | 6 +- src/detect.c | 2 + src/detect.h | 3 +- 11 files changed, 345 insertions(+), 4258 deletions(-) delete mode 100644 src/detect-engine-hrl.c create mode 100644 src/detect-http-request-line.c rename src/{detect-engine-hrl.h => detect-http-request-line.h} (73%) diff --git a/src/Makefile.am b/src/Makefile.am index 89cc563f93..b950ad220a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -115,7 +115,6 @@ detect-engine-hmd.c detect-engine-hmd.h \ detect-engine-hrhd.c detect-engine-hrhd.h \ detect-engine-hrhhd.c detect-engine-hrhhd.h \ detect-engine-hrud.c detect-engine-hrud.h \ -detect-engine-hrl.c detect-engine-hrl.h \ detect-engine-hsbd.c detect-engine-hsbd.h \ detect-engine-hscd.c detect-engine-hscd.h \ detect-engine-hsmd.c detect-engine-hsmd.h \ @@ -165,6 +164,7 @@ detect-http-hrh.c detect-http-hrh.h \ detect-http-method.c detect-http-method.h \ detect-http-raw-header.c detect-http-raw-header.h \ detect-http-raw-uri.c detect-http-raw-uri.h \ +detect-http-request-line.c detect-http-request-line.h \ detect-http-server-body.c detect-http-server-body.h \ detect-http-stat-code.c detect-http-stat-code.h \ detect-http-stat-msg.c detect-http-stat-msg.h \ diff --git a/src/detect-engine-hrl.c b/src/detect-engine-hrl.c deleted file mode 100644 index 244f64436b..0000000000 --- a/src/detect-engine-hrl.c +++ /dev/null @@ -1,4237 +0,0 @@ -/* Copyright (C) 2015 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 - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** \file - * - * \author Victor Julien - * - * Based on detect-engine-uri.c - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "decode.h" - -#include "detect.h" -#include "detect-engine.h" -#include "detect-parse.h" -#include "detect-engine-state.h" -#include "detect-engine-content-inspection.h" - -#include "flow-util.h" -#include "util-debug.h" -#include "util-print.h" -#include "flow.h" - -#include "stream-tcp.h" - -#include "app-layer-parser.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "app-layer.h" -#include "app-layer-htp.h" -#include "app-layer-protos.h" - -/** - * \brief Do the content inspection & validation for a signature - * - * \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 flags app layer flags - * \param state App layer state - * - * \retval 0 no match. - * \retval 1 match. - * \retval 2 Sig can't match. - */ -int DetectEngineInspectHttpRequestLine(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, Flow *f, uint8_t flags, - void *alstate, - void *txv, uint64_t tx_id) -{ - htp_tx_t *tx = (htp_tx_t *)txv; - - if (tx->request_line == NULL) { - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, txv, flags) > HTP_REQUEST_LINE) - return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; - else - return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; - } - - det_ctx->discontinue_matching = 0; - det_ctx->buffer_offset = 0; - det_ctx->inspection_recursion_counter = 0; - -#if 0 - PrintRawDataFp(stdout, (uint8_t *)bstr_ptr(tx_ud->request_uri_normalized), - bstr_len(tx_ud->request_uri_normalized)); -#endif - - /* Inspect all the uricontents fetched on each - * transaction at the app layer */ - int r = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_HRLMATCH], - f, - bstr_ptr(tx->request_line), - bstr_len(tx->request_line), - 0, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL); - if (r == 1) { - return DETECT_ENGINE_INSPECT_SIG_MATCH; - } else { - return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; - } -} - -/***********************************Unittests**********************************/ - -#ifdef UNITTESTS -/** \test Test a simple uricontent option */ -static int UriTestSig01(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Test uricontent option\"; " - "uricontent:\"one\"; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - - FLOWLOCK_WRLOCK(&f); - r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test Test the pcre /U option */ -static int UriTestSig02(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /on HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /one HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Test pcre /U option\"; " - "pcre:/one/U; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted with payload2, but it should not: "); - goto end; - } - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - - FLOWLOCK_WRLOCK(&f); - r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didnt alert, but it should: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test Test the pcre /U option */ -static int UriTestSig03(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Test pcre /U option\"; " - "pcre:/blah/U; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - - FLOWLOCK_WRLOCK(&f); - r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test Test the urilen option */ -static int UriTestSig04(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Test urilen option\"; " - "urilen:>20; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - - FLOWLOCK_WRLOCK(&f); - r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test Test the urilen option */ -static int UriTestSig05(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Test urilen option\"; " - "urilen:>4; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - - FLOWLOCK_WRLOCK(&f); - r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didnt alert with payload2, but it should: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test Test the pcre /U option */ -static int UriTestSig06(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /oneoneoneone HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Test pcre /U option\"; " - "pcre:/(oneself)+/U; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - - FLOWLOCK_WRLOCK(&f); - r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didnt alert on payload2, but it should: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test Test the pcre /U option in combination with urilen */ -static int UriTestSig07(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /oneoneoneone HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /oneoneself HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Test pcre /U option with urilen \"; " - "pcre:/(one){2,}(self)?/U; urilen:3<>20; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didnt alert, but it should: "); - goto end; - } - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - - FLOWLOCK_WRLOCK(&f); - r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didnt alert with payload2, but it should: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test Test the pcre /U option in combination with urilen */ -static int UriTestSig08(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /oneoneoneone HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /oneoneself HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Test pcre /U option with urilen\"; " - "pcre:/(blabla){2,}(self)?/U; urilen:3<>20; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - - FLOWLOCK_WRLOCK(&f); - r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test Test the pcre /U option in combination with urilen */ -static int UriTestSig09(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /oneoneoneone HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /oneoneself HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Test pcre /U option with urilen \"; " - "pcre:/(one){2,}(self)?/U; urilen:<2; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - - FLOWLOCK_WRLOCK(&f); - r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test Test the uricontent option in combination with urilen */ -static int UriTestSig10(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /oneoneoneone HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /oneoneself HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Test uricontent with urilen option\"; " - "uricontent:\"one\"; urilen:<2; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - - FLOWLOCK_WRLOCK(&f); - r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test Test content, uricontent, urilen, pcre /U options */ -static int UriTestSig11(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /oneoneoneone HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /oneoneself HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Test content, uricontent, pcre /U and urilen options\"; " - "content:\"one\"; uricontent:\"one\"; pcre:/(one){2,}(self)?/U;" - "urilen:<2; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - - FLOWLOCK_WRLOCK(&f); - r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test Test uricontent, urilen, pcre /U options */ -static int UriTestSig12(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /oneoneoneone HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /oneoneself HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Test pcre /U, uricontent and urilen option\"; " - "uricontent:\"one\"; " - "pcre:/(one)+self/U; urilen:>2; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - - FLOWLOCK_WRLOCK(&f); - r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didnt alert with payload2, but it should: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test Test uricontent, urilen */ -static int UriTestSig13(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Test urilen option\"; " - "urilen:>2; uricontent:\"one\"; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didnt alert with pkt, but it should: "); - goto end; - } - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - - FLOWLOCK_WRLOCK(&f); - r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didnt alert with payload2, but it should: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test Test uricontent, pcre /U */ -static int UriTestSig14(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Test uricontent option\"; " - "uricontent:\"one\"; pcre:/one(self)?/U;sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didnt alert with pkt, but it should: "); - goto end; - } - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - - FLOWLOCK_WRLOCK(&f); - r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didnt alert with payload2, but it should: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test Test pcre /U with anchored regex (bug 155) */ -static int UriTestSig15(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Test uricontent option\"; " - "uricontent:\"one\"; pcre:/^\\/one(self)?$/U;sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didnt alert with pkt, but it should: "); - goto end; - } - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - - FLOWLOCK_WRLOCK(&f); - r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didnt alert with payload2, but it should: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test Test pcre /U with anchored regex (bug 155) */ -static int UriTestSig16(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /search?q=123&aq=7123abcee HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0/\r\n" - "Host: 1.2.3.4\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /search?q=123&aq=7123abcee HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "drop tcp any any -> any any (msg:\"ET TROJAN Downadup/Conficker A or B Worm reporting\"; flow:to_server,established; uricontent:\"/search?q=\"; pcre:\"/^\\/search\\?q=[0-9]{1,3}(&aq=7(\\?[0-9a-f]{8})?)?/U\"; pcre:\"/\\x0d\\x0aHost\\: \\d+\\.\\d+\\.\\d+\\.\\d+\\x0d\\x0a/\"; sid:2009024; rev:9;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 2009024)) { - printf("sig 1 didnt alert with pkt, but it should: "); - goto end; - } - p->alerts.cnt = 0; - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - p->payload = http_buf2; - p->payload_len = http_buf2_len; - - FLOWLOCK_WRLOCK(&f); - r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 2009024)) { - printf("sig 1 alerted, but it should not (host should not match): "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** - * \test Test multiple relative contents - */ -static int UriTestSig17(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /now_this_is_is_big_big_string_now HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "uricontent:\"this\"; uricontent:\"is\"; within:6; " - "uricontent:\"big\"; within:8; " - "uricontent:\"string\"; within:8; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** - * \test Test multiple relative contents - */ -static int UriTestSig18(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /now_this_is_is_is_big_big_big_string_now HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "uricontent:\"this\"; uricontent:\"is\"; within:9; " - "uricontent:\"big\"; within:12; " - "uricontent:\"string\"; within:8; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** - * \test Test multiple relative contents - */ -static int UriTestSig19(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /this_this_now_is_is_____big_string_now HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "uricontent:\"now\"; uricontent:\"this\"; " - "uricontent:\"is\"; within:12; " - "uricontent:\"big\"; within:8; " - "uricontent:\"string\"; within:8; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** - * \test Test multiple relative contents with offset - */ -static int UriTestSig20(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /_________thus_thus_is_a_big HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "uricontent:\"thus\"; offset:8; " - "uricontent:\"is\"; within:6; " - "uricontent:\"big\"; within:8; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** - * \test Test multiple relative contents with a negated content. - */ -static int UriTestSig21(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /we_need_to_fix_this_and_yes_fix_this_now HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "uricontent:\"fix\"; uricontent:\"this\"; within:6; " - "uricontent:!\"and\"; distance:0; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** - * \test Test relative pcre. - */ -static int UriTestSig22(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /this_is_a_super_duper_" - "nova_in_super_nova_now HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "pcre:/super/U; uricontent:\"nova\"; within:7; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert, but it should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** - * \test Test multiple relative contents with a negated content. - */ -static int UriTestSig23(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /we_need_to_fix_this_and_yes_fix_this_now HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "uricontent:!\"fix_this_now\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** - * \test Test multiple relative contents with a negated content. - */ -static int UriTestSig24(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /we_need_to_fix_this_and_yes_fix_this_now HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "uricontent:\"we_need_to\"; uricontent:!\"fix_this_now\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** - * \test Test normalized uricontents. - */ -static int UriTestSig25(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /normalized%20uri " - "HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, 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; - f.alproto = ALPROTO_HTTP; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "pcre:/normalized/U; uricontent:\"normalized uri\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert, but it should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** - * \test Test multiple relative contents with a negated content. - */ -static int UriTestSig26(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /we_need_to_fix_this_and_yes_fix_this_now HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "uricontent:\"fix_this\"; isdataat:4,relative; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert, but it should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** - * \test Test multiple relative contents with a negated content. - */ -static int UriTestSig27(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /we_need_to_fix_this_and_yes_fix_this_now HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "uricontent:\"fix_this\"; isdataat:!10,relative; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert, but it should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -static int UriTestSig28(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /this_b5ig_string_now_in_http HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any (msg:\"dummy\"; " - "uricontent:\"this\"; " - "byte_extract:1,2,one,string,dec,relative; " - "uricontent:\"ring\"; distance:one; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert, but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -static int UriTestSig29(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /this_b5ig_string_now_in_http HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any (msg:\"dummy\"; " - "uricontent:\"this\"; " - "byte_extract:1,2,one,string,dec,relative; " - "uricontent:\"ring\"; distance:one; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert, but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -static int UriTestSig30(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /this_b5ig_string_now_in_http HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any (msg:\"dummy\"; " - "uricontent:\"this\"; " - "byte_extract:1,2,one,string,dec,relative; " - "uricontent:\"_b5ig\"; offset:one; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert, but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -static int UriTestSig31(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /this_b5ig_string_now_in_http HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any (msg:\"dummy\"; " - "uricontent:\"this\"; " - "byte_extract:1,2,one,string,dec,relative; " - "uricontent:\"his\"; depth:one; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert, but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -static int UriTestSig32(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /this_b5ig_string_now_in_http HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any (msg:\"dummy\"; " - "uricontent:\"this\"; " - "byte_extract:1,2,one,string,dec,relative; " - "uricontent:\"g_st\"; within:one; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert, but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -static int UriTestSig33(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /normalized%20uri " - "HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, 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; - f.alproto = ALPROTO_HTTP; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "urilen:15; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert, but it should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -static int UriTestSig34(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /normalized%20uri " - "HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, 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; - f.alproto = ALPROTO_HTTP; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "urilen:15, norm; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert, but it should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -static int UriTestSig35(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /normalized%20uri " - "HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, 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; - f.alproto = ALPROTO_HTTP; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "urilen:16; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -static int UriTestSig36(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /normalized%20uri " - "HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, 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; - f.alproto = ALPROTO_HTTP; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "urilen:16, norm; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -static int UriTestSig37(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /normalized%20uri " - "HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, 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; - f.alproto = ALPROTO_HTTP; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "urilen:17, raw; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert, but it should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -static int UriTestSig38(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /normalized%20uri " - "HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, 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; - f.alproto = ALPROTO_HTTP; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "urilen:18, raw; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -#endif /* UNITTESTS */ - -void HttpRequestLineRegisterTests(void) -{ - -#ifdef UNITTESTS - UtRegisterTest("UriTestSig01", UriTestSig01); - UtRegisterTest("UriTestSig02", UriTestSig02); - UtRegisterTest("UriTestSig03", UriTestSig03); - UtRegisterTest("UriTestSig04", UriTestSig04); - UtRegisterTest("UriTestSig05", UriTestSig05); - UtRegisterTest("UriTestSig06", UriTestSig06); - UtRegisterTest("UriTestSig07", UriTestSig07); - UtRegisterTest("UriTestSig08", UriTestSig08); - UtRegisterTest("UriTestSig09", UriTestSig09); - UtRegisterTest("UriTestSig10", UriTestSig10); - UtRegisterTest("UriTestSig11", UriTestSig11); - UtRegisterTest("UriTestSig12", UriTestSig12); - UtRegisterTest("UriTestSig13", UriTestSig13); - UtRegisterTest("UriTestSig14", UriTestSig14); - UtRegisterTest("UriTestSig15", UriTestSig15); - UtRegisterTest("UriTestSig16", UriTestSig16); - UtRegisterTest("UriTestSig17", UriTestSig17); - UtRegisterTest("UriTestSig18", UriTestSig18); - UtRegisterTest("UriTestSig19", UriTestSig19); - UtRegisterTest("UriTestSig20", UriTestSig20); - UtRegisterTest("UriTestSig21", UriTestSig21); - UtRegisterTest("UriTestSig22", UriTestSig22); - UtRegisterTest("UriTestSig23", UriTestSig23); - UtRegisterTest("UriTestSig24", UriTestSig24); - UtRegisterTest("UriTestSig25", UriTestSig25); - UtRegisterTest("UriTestSig26", UriTestSig26); - UtRegisterTest("UriTestSig27", UriTestSig27); - - UtRegisterTest("UriTestSig28", UriTestSig28); - UtRegisterTest("UriTestSig29", UriTestSig29); - UtRegisterTest("UriTestSig30", UriTestSig30); - UtRegisterTest("UriTestSig31", UriTestSig31); - UtRegisterTest("UriTestSig32", UriTestSig32); - UtRegisterTest("UriTestSig33", UriTestSig33); - UtRegisterTest("UriTestSig34", UriTestSig34); - UtRegisterTest("UriTestSig35", UriTestSig35); - UtRegisterTest("UriTestSig36", UriTestSig36); - UtRegisterTest("UriTestSig37", UriTestSig37); - UtRegisterTest("UriTestSig38", UriTestSig38); -#endif /* UNITTESTS */ - - return; -} diff --git a/src/detect-engine-state.h b/src/detect-engine-state.h index e079bedbca..70d9d30fb4 100644 --- a/src/detect-engine-state.h +++ b/src/detect-engine-state.h @@ -83,7 +83,7 @@ #define DE_STATE_FLAG_DNSQUERYNAME_INSPECT BIT_U32(17) #define DE_STATE_FLAG_APP_EVENT_INSPECT BIT_U32(18) #define DE_STATE_FLAG_MODBUS_INSPECT BIT_U32(19) -#define DE_STATE_FLAG_HRL_INSPECT BIT_U32(20) +#define DE_STATE_FLAG_HTTP_REQLINE_INSPECT BIT_U32(20) #define DE_STATE_FLAG_FD_SMTP_INSPECT BIT_U32(21) #define DE_STATE_FLAG_DNSREQUEST_INSPECT BIT_U32(22) #define DE_STATE_FLAG_DNSRESPONSE_INSPECT BIT_U32(23) diff --git a/src/detect-engine.c b/src/detect-engine.c index cc64d2b4fa..e5e2957005 100644 --- a/src/detect-engine.c +++ b/src/detect-engine.c @@ -52,7 +52,6 @@ #include "detect-engine-hmd.h" #include "detect-engine-hcd.h" #include "detect-engine-hrud.h" -#include "detect-engine-hrl.h" #include "detect-engine-hsmd.h" #include "detect-engine-hscd.h" #include "detect-engine-hua.h" @@ -73,6 +72,8 @@ #include "detect-uricontent.h" #include "detect-engine-threshold.h" +#include "detect-http-request-line.h" + #include "detect-engine-loader.h" #include "util-classification-config.h" @@ -176,8 +177,8 @@ void DetectEngineRegisterAppInspectionEngines(void) DetectEngineInspectPacketUris }, { IPPROTO_TCP, ALPROTO_HTTP, - DETECT_SM_LIST_HRLMATCH, - DE_STATE_FLAG_HRL_INSPECT, + DETECT_SM_LIST_HTTP_REQLINEMATCH, + DE_STATE_FLAG_HTTP_REQLINE_INSPECT, 0, DetectEngineInspectHttpRequestLine }, { IPPROTO_TCP, @@ -2806,7 +2807,7 @@ const char *DetectSigmatchListEnumToString(enum DetectSigmatchListEnum type) return "http cookie"; case DETECT_SM_LIST_HUADMATCH: return "http user-agent"; - case DETECT_SM_LIST_HRLMATCH: + case DETECT_SM_LIST_HTTP_REQLINEMATCH: return "http request line"; case DETECT_SM_LIST_APP_EVENT: return "app layer events"; diff --git a/src/detect-fast-pattern.c b/src/detect-fast-pattern.c index dba0850f36..c890419377 100644 --- a/src/detect-fast-pattern.c +++ b/src/detect-fast-pattern.c @@ -180,14 +180,16 @@ static int DetectFastPatternSetup(DetectEngineCtx *de_ctx, Signature *s, char *a s->sm_lists_tail[DETECT_SM_LIST_DNSQUERYNAME_MATCH] == NULL && s->sm_lists_tail[DETECT_SM_LIST_TLSSNI_MATCH] == NULL && s->sm_lists_tail[DETECT_SM_LIST_TLSISSUER_MATCH] == NULL && - s->sm_lists_tail[DETECT_SM_LIST_TLSSUBJECT_MATCH] == NULL) { + s->sm_lists_tail[DETECT_SM_LIST_TLSSUBJECT_MATCH] == NULL && + s->sm_lists_tail[DETECT_SM_LIST_HTTP_REQLINEMATCH] == NULL) { SCLogWarning(SC_WARN_COMPATIBILITY, "fast_pattern found inside the " "rule, without a preceding content based keyword. " "Currently we provide fast_pattern support for content, " "uricontent, http_client_body, http_server_body, http_header, " "http_raw_header, http_method, http_cookie, " "http_raw_uri, http_stat_msg, http_stat_code, " - "http_user_agent, http_host, http_raw_host, dns_query, " + "http_user_agent, http_host, http_raw_host, " + "http_request_line, dns_query, " "tls_sni, tls_cert_issuer or tls_cert_subject option"); return -1; } @@ -207,6 +209,7 @@ static int DetectFastPatternSetup(DetectEngineCtx *de_ctx, Signature *s, char *a DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH], + DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HTTP_REQLINEMATCH], DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_DNSQUERYNAME_MATCH], DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_TLSSNI_MATCH], DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_TLSISSUER_MATCH], diff --git a/src/detect-http-request-line.c b/src/detect-http-request-line.c new file mode 100644 index 0000000000..0c43d9ae4b --- /dev/null +++ b/src/detect-http-request-line.c @@ -0,0 +1,316 @@ +/* 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 + * Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +/** + * \ingroup httplayer + * + * @{ + */ + + +/** + * \file + * + * \author Victor Julien + * + * Implements support for the http_request_line keyword. + */ + +#include "suricata-common.h" +#include "threads.h" +#include "decode.h" + +#include "detect.h" +#include "detect-parse.h" +#include "detect-engine.h" +#include "detect-engine-mpm.h" +#include "detect-engine-state.h" +#include "detect-engine-prefilter.h" +#include "detect-engine-content-inspection.h" +#include "detect-content.h" +#include "detect-pcre.h" + +#include "flow.h" +#include "flow-var.h" +#include "flow-util.h" + +#include "util-debug.h" +#include "util-unittest.h" +#include "util-unittest-helper.h" +#include "util-spm.h" + +#include "app-layer.h" +#include "app-layer-parser.h" + +#include "app-layer-htp.h" +#include "stream-tcp.h" +#include "detect-http-request-line.h" + +int DetectHttpRequestLineSetup(DetectEngineCtx *, Signature *, char *); +void DetectHttpRequestLineRegisterTests(void); +void DetectHttpRequestLineFree(void *); +static int PrefilterTxHttpRequestLineRegister(SigGroupHead *sgh, MpmCtx *mpm_ctx); + +/** + * \brief Registers the keyword handlers for the "http_request_line" keyword. + */ +void DetectHttpRequestLineRegister(void) +{ + sigmatch_table[DETECT_AL_HTTP_REQUEST_LINE].name = "http_request_line"; + sigmatch_table[DETECT_AL_HTTP_REQUEST_LINE].desc = "content modifier to match only on the HTTP request line"; + sigmatch_table[DETECT_AL_HTTP_REQUEST_LINE].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/HTTP-keywords#http_request_line"; + sigmatch_table[DETECT_AL_HTTP_REQUEST_LINE].Match = NULL; + sigmatch_table[DETECT_AL_HTTP_REQUEST_LINE].AppLayerMatch = NULL; + sigmatch_table[DETECT_AL_HTTP_REQUEST_LINE].Setup = DetectHttpRequestLineSetup; + sigmatch_table[DETECT_AL_HTTP_REQUEST_LINE].RegisterTests = DetectHttpRequestLineRegisterTests; + + sigmatch_table[DETECT_AL_HTTP_REQUEST_LINE].flags |= SIGMATCH_NOOPT; + sigmatch_table[DETECT_AL_HTTP_REQUEST_LINE].flags |= SIGMATCH_PAYLOAD ; + + DetectMpmAppLayerRegister("http_request_line", SIG_FLAG_TOSERVER, + DETECT_SM_LIST_HTTP_REQLINEMATCH, 2, + PrefilterTxHttpRequestLineRegister); + + return; +} + +/** + * \brief The setup function for the http_request_line keyword for a signature. + * + * \param de_ctx Pointer to the detection engine context. + * \param s Pointer to the signature for the current Signature being + * parsed from the rules. + * \param m Pointer to the head of the SigMatch for the current rule + * being parsed. + * \param arg Pointer to the string holding the keyword value. + * + * \retval 0 On success + * \retval -1 On failure + */ +int DetectHttpRequestLineSetup(DetectEngineCtx *de_ctx, Signature *s, char *arg) +{ + s->list = DETECT_SM_LIST_HTTP_REQLINEMATCH; + s->alproto = ALPROTO_HTTP; + return 0; +} + +/** \brief HTTP request line 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 PrefilterTxHttpRequestLine(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; + + if (tx->request_line == NULL) + return; + + const uint32_t buffer_len = bstr_len(tx->request_line); + const uint8_t *buffer = bstr_ptr(tx->request_line); + + 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); + } +} + +static int PrefilterTxHttpRequestLineRegister(SigGroupHead *sgh, MpmCtx *mpm_ctx) +{ + SCEnter(); + + return PrefilterAppendTxEngine(sgh, PrefilterTxHttpRequestLine, + ALPROTO_HTTP, HTP_REQUEST_LINE, + mpm_ctx, NULL, "http_request_line"); +} + +/** + * \brief Do the content inspection & validation for a signature + * + * \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 flags app layer flags + * \param state App layer state + * + * \retval 0 no match. + * \retval 1 match. + * \retval 2 Sig can't match. + */ +int DetectEngineInspectHttpRequestLine(ThreadVars *tv, + DetectEngineCtx *de_ctx, + DetectEngineThreadCtx *det_ctx, + Signature *s, Flow *f, uint8_t flags, + void *alstate, + void *txv, uint64_t tx_id) +{ + htp_tx_t *tx = (htp_tx_t *)txv; + + if (tx->request_line == NULL) { + if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, txv, flags) > HTP_REQUEST_LINE) + return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; + else + return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; + } + + det_ctx->discontinue_matching = 0; + det_ctx->buffer_offset = 0; + det_ctx->inspection_recursion_counter = 0; + + /* Inspect all the uricontents fetched on each + * transaction at the app layer */ + int r = DetectEngineContentInspection(de_ctx, det_ctx, + s, s->sm_lists[DETECT_SM_LIST_HTTP_REQLINEMATCH], + f, + bstr_ptr(tx->request_line), + bstr_len(tx->request_line), + 0, + DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL); + if (r == 1) { + return DETECT_ENGINE_INSPECT_SIG_MATCH; + } else { + return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; + } +} + +/************************************Unittests*********************************/ + +#ifdef UNITTESTS + +#include "stream-tcp-reassemble.h" + +/** + * \test Test that a signature containting a http_request_line is correctly parsed + * and the keyword is registered. + */ +static int DetectHttpRequestLineTest01(void) +{ + DetectEngineCtx *de_ctx = DetectEngineCtxInit(); + FAIL_IF_NULL(de_ctx); + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " + "(http_request_line; content:\"GET /\"; sid:1;)"); + FAIL_IF_NULL(de_ctx->sig_list); + + DetectEngineCtxFree(de_ctx); + PASS; +} + + +/** + *\test Test that the http_request_line content matches against a http request + * which holds the content. + */ +static int DetectHttpRequestLineTest02(void) +{ + TcpSession ssn; + Packet *p = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http_buf[] = + "GET /index.html HTTP/1.0\r\n" + "Host: www.openinfosecfoundation.org\r\n" + "User-Agent: This is dummy message body\r\n" + "Content-Type: text/html\r\n" + "\r\n"; + uint32_t http_len = sizeof(http_buf) - 1; + + AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); + FAIL_IF_NULL(alp_tctx); + + memset(&th_v, 0, sizeof(th_v)); + memset(&f, 0, sizeof(f)); + memset(&ssn, 0, sizeof(ssn)); + + p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + FAIL_IF_NULL(p); + + 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(); + FAIL_IF_NULL(de_ctx); + + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(http_request_line; content:\"GET /index.html HTTP/1.0\"; " + "sid:1;)"); + FAIL_IF_NULL(de_ctx->sig_list); + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + int r = AppLayerParserParse(&th_v, alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); + FAIL_IF(r != 0); + + http_state = f.alstate; + FAIL_IF_NULL(http_state); + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p); + + FAIL_IF(!(PacketAlertCheck(p, 1))); + + AppLayerParserThreadCtxFree(alp_tctx); + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p, 1); + PASS; +} + +#endif /* UNITTESTS */ + +void DetectHttpRequestLineRegisterTests(void) +{ +#ifdef UNITTESTS + UtRegisterTest("DetectHttpRequestLineTest01", DetectHttpRequestLineTest01); + UtRegisterTest("DetectHttpRequestLineTest02", DetectHttpRequestLineTest02); +#endif /* UNITTESTS */ + + return; +} +/** + * @} + */ diff --git a/src/detect-engine-hrl.h b/src/detect-http-request-line.h similarity index 73% rename from src/detect-engine-hrl.h rename to src/detect-http-request-line.h index cb5360d9a0..0c47f5fa5e 100644 --- a/src/detect-engine-hrl.h +++ b/src/detect-http-request-line.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2015 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 @@ -15,20 +15,21 @@ * 02110-1301, USA. */ -/** \file +/** + * \file * - * \author Victor Julien + * \author Victor Julien */ -#ifndef __DETECT_ENGINE_HRL_H__ -#define __DETECT_ENGINE_HRL_H__ +#ifndef __DETECT_HTTP_REQUEST_LINE_H__ +#define __DETECT_HTTP_REQUEST_LINE_H__ int DetectEngineInspectHttpRequestLine(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Signature *s, Flow *f, uint8_t flags, void *alstate, - void *tx, uint64_t tx_id); -void HttpRequestLineRegisterTests(void); + void *txv, uint64_t tx_id); +void DetectHttpRequestLineRegister(void); -#endif /* __DETECT_ENGINE_HRL_H__ */ +#endif /* __DETECT_HTTP_REQUEST_LINE_H__ */ diff --git a/src/detect-lua.c b/src/detect-lua.c index a4716d44ee..ab04434739 100644 --- a/src/detect-lua.c +++ b/src/detect-lua.c @@ -1109,7 +1109,7 @@ static int DetectLuaSetup (DetectEngineCtx *de_ctx, Signature *s, char *str) else if (luajit->flags & DATATYPE_HTTP_RESPONSE_COOKIE) SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_HCDMATCH); else - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_HRLMATCH); + SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_HTTP_REQLINEMATCH); } else if (luajit->alproto == ALPROTO_DNS) { if (luajit->flags & DATATYPE_DNS_RRNAME) { SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_DNSQUERYNAME_MATCH); diff --git a/src/detect-parse.c b/src/detect-parse.c index 1215d56211..639c5aad90 100644 --- a/src/detect-parse.c +++ b/src/detect-parse.c @@ -155,7 +155,7 @@ const char *DetectListToHumanString(int list) CASE_CODE_STRING(DETECT_SM_LIST_HMDMATCH, "http_method"); CASE_CODE_STRING(DETECT_SM_LIST_HCDMATCH, "http_cookie"); CASE_CODE_STRING(DETECT_SM_LIST_HUADMATCH, "http_user_agent"); - CASE_CODE_STRING(DETECT_SM_LIST_HRLMATCH, "http_request_line"); + CASE_CODE_STRING(DETECT_SM_LIST_HTTP_REQLINEMATCH, "http_request_line"); CASE_CODE_STRING(DETECT_SM_LIST_APP_EVENT, "app-layer-event"); CASE_CODE_STRING(DETECT_SM_LIST_AMATCH, "app-layer"); CASE_CODE_STRING(DETECT_SM_LIST_DMATCH, "dcerpc"); @@ -199,7 +199,7 @@ const char *DetectListToString(int list) CASE_CODE(DETECT_SM_LIST_HMDMATCH); CASE_CODE(DETECT_SM_LIST_HCDMATCH); CASE_CODE(DETECT_SM_LIST_HUADMATCH); - CASE_CODE(DETECT_SM_LIST_HRLMATCH); + CASE_CODE(DETECT_SM_LIST_HTTP_REQLINEMATCH); CASE_CODE(DETECT_SM_LIST_APP_EVENT); CASE_CODE(DETECT_SM_LIST_AMATCH); CASE_CODE(DETECT_SM_LIST_DMATCH); @@ -1561,7 +1561,7 @@ static Signature *SigInitHelper(DetectEngineCtx *de_ctx, char *sigstr, sig->flags |= SIG_FLAG_STATE_MATCH; if (sig->sm_lists[DETECT_SM_LIST_AMATCH]) sig->flags |= SIG_FLAG_STATE_MATCH; - if (sig->sm_lists[DETECT_SM_LIST_HRLMATCH]) + if (sig->sm_lists[DETECT_SM_LIST_HTTP_REQLINEMATCH]) sig->flags |= SIG_FLAG_STATE_MATCH; if (sig->sm_lists[DETECT_SM_LIST_HCBDMATCH]) sig->flags |= SIG_FLAG_STATE_MATCH; diff --git a/src/detect.c b/src/detect.c index 1f5a22d5ae..160feb323d 100644 --- a/src/detect.c +++ b/src/detect.c @@ -142,6 +142,7 @@ #include "detect-http-uri.h" #include "detect-http-raw-uri.h" #include "detect-http-stat-msg.h" +#include "detect-http-request-line.h" #include "detect-engine-hcbd.h" #include "detect-engine-hsbd.h" #include "detect-engine-hhd.h" @@ -4225,6 +4226,7 @@ void SigTableSetup(void) DetectTemplateRegister(); DetectTemplateBufferRegister(); DetectBypassRegister(); + DetectHttpRequestLineRegister(); } void SigTableRegisterTests(void) diff --git a/src/detect.h b/src/detect.h index f0bae5ccb0..ba154d11a0 100644 --- a/src/detect.h +++ b/src/detect.h @@ -114,7 +114,7 @@ enum DetectSigmatchListEnum { /* list for http_user_agent keyword and the ones relative to it */ DETECT_SM_LIST_HUADMATCH, /* list for http_request_line keyword and the ones relative to it */ - DETECT_SM_LIST_HRLMATCH, + DETECT_SM_LIST_HTTP_REQLINEMATCH, /* app event engine sm list */ DETECT_SM_LIST_APP_EVENT, @@ -1230,6 +1230,7 @@ enum { DETECT_AL_HTTP_USER_AGENT, DETECT_AL_HTTP_HOST, DETECT_AL_HTTP_RAW_HOST, + DETECT_AL_HTTP_REQUEST_LINE, DETECT_AL_SSH_PROTOVERSION, DETECT_AL_SSH_SOFTWAREVERSION, DETECT_AL_SSL_VERSION,