Support http stat msg detection engine, fast pattern(mpm engine included). Fix http stat msg setup function. Fix pcre option for stat msg keyword

remotes/origin/HEAD
Anoop Saldanha 14 years ago committed by Victor Julien
parent 9dc153c8f4
commit 2007c2711c

@ -84,6 +84,7 @@ detect-engine-hrhd.c detect-engine-hrhd.h \
detect-engine-hmd.c detect-engine-hmd.h \
detect-engine-hcd.c detect-engine-hcd.h \
detect-engine-hrud.c detect-engine-hrud.h \
detect-engine-hsmd.c detect-engine-hsmd.h \
detect-engine-state.c detect-engine-state.h \
detect-engine-file.c detect-engine-file.h \
detect-parse.c detect-parse.h \

@ -52,15 +52,16 @@
#define DETECT_CONTENT_HMD_MPM 0x00040000
#define DETECT_CONTENT_HCD_MPM 0x00080000
#define DETECT_CONTENT_HRUD_MPM 0x00100000
#define DETECT_CONTENT_HSMD_MPM 0x00200000
/* BE - byte extract */
#define DETECT_CONTENT_OFFSET_BE 0x00200000
#define DETECT_CONTENT_DEPTH_BE 0x00400000
#define DETECT_CONTENT_DISTANCE_BE 0x00800000
#define DETECT_CONTENT_WITHIN_BE 0x01000000
#define DETECT_CONTENT_OFFSET_BE 0x00400000
#define DETECT_CONTENT_DEPTH_BE 0x00800000
#define DETECT_CONTENT_DISTANCE_BE 0x01000000
#define DETECT_CONTENT_WITHIN_BE 0x02000000
/* replace data */
#define DETECT_CONTENT_REPLACE 0x02000000
#define DETECT_CONTENT_REPLACE 0x04000000
#define DETECT_CONTENT_IS_SINGLE(c) (!((c)->flags & DETECT_CONTENT_DISTANCE || \
(c)->flags & DETECT_CONTENT_WITHIN || \

@ -86,7 +86,7 @@ static int DetectDepthSetup (DetectEngineCtx *de_ctx, Signature *s, char *depths
break;
default:
pm = SigMatchGetLastSMFromLists(s, 18,
pm = SigMatchGetLastSMFromLists(s, 20,
DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH],
DETECT_URICONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH],
DETECT_AL_HTTP_RAW_URI, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH],
@ -95,13 +95,14 @@ static int DetectDepthSetup (DetectEngineCtx *de_ctx, Signature *s, char *depths
DETECT_AL_HTTP_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH],
DETECT_AL_HTTP_RAW_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH],
DETECT_AL_HTTP_METHOD, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH],
DETECT_AL_HTTP_COOKIE, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH]);
DETECT_AL_HTTP_COOKIE, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH],
DETECT_AL_HTTP_STAT_MSG, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH]);
if (pm == NULL) {
SCLogError(SC_ERR_DEPTH_MISSING_CONTENT, "depth needs "
"preceeding content, uricontent option, http_client_body, "
"http_server_body, http_header option, http_raw_header option, "
"http_method option, http_cookie or "
"http_raw_uri option");
"http_method option, http_cookie, http_raw_uri or "
"http_stat_msg option");
if (dubbed)
SCFree(str);
return -1;
@ -503,6 +504,47 @@ static int DetectDepthSetup (DetectEngineCtx *de_ctx, Signature *s, char *depths
break;
case DETECT_AL_HTTP_STAT_MSG:
cd = (DetectContentData *)pm->ctx;
if (cd->flags & DETECT_CONTENT_NEGATED) {
if (cd->flags & DETECT_CONTENT_FAST_PATTERN) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "You can't have a relative "
"negated keyword set along with a fast_pattern");
goto error;
}
} else {
if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "You can't have a relative "
"keyword set along with a fast_pattern:only;");
goto error;
}
}
if (str[0] != '-' && isalpha(str[0])) {
SigMatch *bed_sm =
DetectByteExtractRetrieveSMVar(str, s,
SigMatchListSMBelongsTo(s, pm));
if (bed_sm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
"seen in depth - %s\n", str);
goto error;
}
cd->depth = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
cd->flags |= DETECT_CONTENT_DEPTH_BE;
} else {
cd->depth = (uint32_t)atoi(str);
if (cd->depth < cd->content_len) {
cd->depth = cd->content_len;
SCLogDebug("depth increased to %"PRIu32" to match pattern len ",
cd->depth);
}
/* Now update the real limit, as depth is relative to the offset */
cd->depth += cd->offset;
cd->flags |= DETECT_CONTENT_DEPTH;
}
break;
default:
SCLogError(SC_ERR_DEPTH_MISSING_CONTENT, "depth needs a preceeding "
"content (or uricontent) option");

@ -160,7 +160,7 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s,
}
}
} else {
pm = SigMatchGetLastSMFromLists(s, 18,
pm = SigMatchGetLastSMFromLists(s, 20,
DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH],
DETECT_URICONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH],
DETECT_AL_HTTP_RAW_URI, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH],
@ -169,12 +169,13 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s,
DETECT_AL_HTTP_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH],
DETECT_AL_HTTP_RAW_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH],
DETECT_AL_HTTP_METHOD, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH],
DETECT_AL_HTTP_COOKIE, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH]);
DETECT_AL_HTTP_COOKIE, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH],
DETECT_AL_HTTP_STAT_MSG, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH]);
if (pm == NULL) {
SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "within needs "
"preceeding content, uricontent option, http_client_body, "
"http_server_body, http_header, http_raw_header, http_method, "
"http_cookie or http_raw_uri option");
"http_cookie, http_raw_uri or http_stat_msg option");
if (dubbed)
SCFree(str);
return -1;
@ -832,6 +833,73 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s,
break;
case DETECT_AL_HTTP_STAT_MSG:
cd = (DetectContentData *)pm->ctx;
if (cd->flags & DETECT_CONTENT_NEGATED) {
if (cd->flags & DETECT_CONTENT_FAST_PATTERN) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "You can't have a relative "
"negated keyword set along with a fast_pattern");
goto error;
}
} else {
if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "You can't have a relative "
"keyword set along with a fast_pattern:only;");
goto error;
}
}
if (str[0] != '-' && isalpha(str[0])) {
SigMatch *bed_sm =
DetectByteExtractRetrieveSMVar(str, s,
SigMatchListSMBelongsTo(s, pm));
if (bed_sm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
"seen in distance - %s\n", str);
goto error;
}
cd->distance = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
cd->flags |= DETECT_CONTENT_DISTANCE_BE;
} else {
cd->distance = strtol(str, NULL, 10);
if (cd->flags & DETECT_CONTENT_WITHIN) {
if ((cd->distance + cd->content_len) > cd->within) {
cd->within = cd->distance + cd->content_len;
}
}
}
cd->flags |= DETECT_CONTENT_DISTANCE;
/* reassigning pm */
pm = SigMatchGetLastSMFromLists(s, 4,
DETECT_AL_HTTP_STAT_MSG, pm->prev,
DETECT_PCRE, pm->prev);
if (pm == NULL) {
SCLogError(SC_ERR_DISTANCE_MISSING_CONTENT, "distance for "
"http_stat_msg needs preceeding http_stat_msg "
"content");
goto error;
}
if (pm->type == DETECT_PCRE) {
DetectPcreData *tmp_pd = (DetectPcreData *)pm->ctx;
tmp_pd->flags |= DETECT_PCRE_RELATIVE_NEXT;
} else {
/* reassigning cd */
cd = (DetectContentData *)pm->ctx;
if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Previous keyword "
"has a fast_pattern:only; set. You can't "
"have relative keywords around a fast_pattern "
"only content");
goto error;
}
cd->flags |= DETECT_CONTENT_RELATIVE_NEXT;
}
break;
default:
SCLogError(SC_ERR_DISTANCE_MISSING_CONTENT, "distance needs two "
"preceeding content or uricontent options");

File diff suppressed because it is too large Load Diff

@ -0,0 +1,34 @@
/* Copyright (C) 2007-2010 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 Anoop Saldanha <anoopsaldanha@gmail.com>
*/
#ifndef __DETECT_ENGINE_HSMD_H__
#define __DETECT_ENGINE_HSMD_H__
#include "app-layer-htp.h"
int DetectEngineRunHttpStatMsgMpm(DetectEngineThreadCtx *,
Flow *f, HtpState *);
int DetectEngineInspectHttpStatMsg(DetectEngineCtx *, DetectEngineThreadCtx *,
Signature *, Flow *, uint8_t, void *);
void DetectEngineHttpStatMsgRegisterTests(void);
#endif /* __DETECT_ENGINE_HSMD_H__ */

@ -524,6 +524,31 @@ uint32_t HttpRawUriPatternSearch(DetectEngineThreadCtx *det_ctx,
SCReturnUInt(ret);
}
/**
* \brief Http stat msg match -- searches for one pattern per signature.
*
* \param det_ctx Detection engine thread ctx.
* \param uri Stat msg to inspect.
* \param uri_len Stat msg length.
*
* \retval ret Number of matches.
*/
uint32_t HttpStatMsgPatternSearch(DetectEngineThreadCtx *det_ctx,
uint8_t *stat_msg, uint32_t stat_msg_len)
{
SCEnter();
if (det_ctx->sgh->mpm_hsmd_ctx == NULL)
SCReturnUInt(0);
uint32_t ret;
ret = mpm_table[det_ctx->sgh->mpm_hsmd_ctx->mpm_type].
Search(det_ctx->sgh->mpm_hsmd_ctx, &det_ctx->mtcu,
&det_ctx->pmq, stat_msg, stat_msg_len);
SCReturnUInt(ret);
}
/** \brief Pattern match -- searches for only one pattern per signature.
*
* \param det_ctx detection engine thread ctx
@ -1180,6 +1205,7 @@ static void PopulateMpmAddPatternToMpm(DetectEngineCtx *de_ctx,
case DETECT_AL_HTTP_RAW_HEADER:
case DETECT_AL_HTTP_METHOD:
case DETECT_AL_HTTP_COOKIE:
case DETECT_AL_HTTP_STAT_MSG:
{
MpmCtx *mpm_ctx_ts = NULL;
MpmCtx *mpm_ctx_tc = NULL;
@ -1242,6 +1268,10 @@ static void PopulateMpmAddPatternToMpm(DetectEngineCtx *de_ctx,
mpm_ctx_tc = sgh->mpm_hrud_ctx_tc;
sgh_flags = SIG_GROUP_HEAD_MPM_HRUD;
cd_flags = DETECT_CONTENT_HRUD_MPM;
} else if (mpm_sm->type == DETECT_AL_HTTP_STAT_MSG) {
mpm_ctx = sgh->mpm_hsmd_ctx;
sgh_flags = SIG_GROUP_HEAD_MPM_HSMD;
cd_flags = DETECT_CONTENT_HSMD_MPM;
}
cd = (DetectContentData *)mpm_sm->ctx;
@ -1534,6 +1564,8 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
uint32_t has_co_hcd = 0;
/* used to indicate if sgh has atleast one sig with http_raw_uri */
uint32_t has_co_hrud = 0;
/* used to indicate if sgh has atleast one sig with http_stat_msg */
uint32_t has_co_hsmd = 0;
//uint32_t cnt = 0;
uint32_t sig = 0;
@ -1583,6 +1615,10 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
if (s->sm_lists[DETECT_SM_LIST_HRUDMATCH] != NULL) {
has_co_hrud = 1;
}
if (s->sm_lists[DETECT_SM_LIST_HSMDMATCH] != NULL) {
has_co_hsmd = 1;
}
}
if (has_co_packet > 0) {
@ -1615,6 +1651,9 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
if (has_co_hrud > 0) {
sh->flags |= SIG_GROUP_HAVEHRUDCONTENT;
}
if (has_co_hsmd > 0) {
sh->flags |= SIG_GROUP_HAVEHSMDCONTENT;
}
/* intialize contexes */
if (sh->flags & SIG_GROUP_HAVECONTENT) {
@ -1872,6 +1911,24 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
#endif
}
if (sh->flags & SIG_GROUP_HAVEHSMDCONTENT) {
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) {
sh->mpm_hsmd_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx->sgh_mpm_context_hsmd);
} else {
sh->mpm_hsmd_ctx = MpmFactoryGetMpmCtxForProfile(MPM_CTX_FACTORY_UNIQUE_CONTEXT);
}
if (sh->mpm_hsmd_ctx == NULL) {
SCLogDebug("sh->mpm_hsmd_ctx == NULL. This should never happen");
exit(EXIT_FAILURE);
}
#ifndef __SC_CUDA_SUPPORT__
MpmInitCtx(sh->mpm_hsmd_ctx, de_ctx->mpm_matcher, -1);
#else
MpmInitCtx(sh->mpm_hsmd_ctx, de_ctx->mpm_matcher, de_ctx->cuda_rc_mod_handle);
#endif
}
if (sh->flags & SIG_GROUP_HAVECONTENT ||
sh->flags & SIG_GROUP_HAVESTREAMCONTENT ||
sh->flags & SIG_GROUP_HAVEURICONTENT ||
@ -1881,6 +1938,7 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
sh->flags & SIG_GROUP_HAVEHRHDCONTENT ||
sh->flags & SIG_GROUP_HAVEHMDCONTENT ||
sh->flags & SIG_GROUP_HAVEHCDCONTENT ||
sh->flags & SIG_GROUP_HAVEHSMDCONTENT ||
sh->flags & SIG_GROUP_HAVEHRUDCONTENT) {
PatternMatchPreparePopulateMpm(de_ctx, sh);
@ -2183,6 +2241,18 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
}
}
}
if (sh->mpm_hsmd_ctx != NULL) {
if (sh->mpm_hsmd_ctx->pattern_cnt == 0) {
MpmFactoryReClaimMpmCtx(sh->mpm_hsmd_ctx);
sh->mpm_hsmd_ctx = NULL;
} else {
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL &&
sh->flags & SIG_GROUP_HAVEHSMDCONTENT) {
if (mpm_table[sh->mpm_hsmd_ctx->mpm_type].Prepare != NULL)
mpm_table[sh->mpm_hsmd_ctx->mpm_type].Prepare(sh->mpm_hsmd_ctx);
}
}
}
//} /* if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) */
} else {
MpmFactoryReClaimMpmCtx(sh->mpm_proto_other_ctx);
@ -2208,6 +2278,8 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
sh->mpm_hcd_ctx_ts = NULL;
MpmFactoryReClaimMpmCtx(sh->mpm_hrud_ctx_ts);
sh->mpm_hrud_ctx_ts = NULL;
MpmFactoryReClaimMpmCtx(sh->mpm_hsmd_ctx_ts);
sh->mpm_hsmd_ctx_ts = NULL;
MpmFactoryReClaimMpmCtx(sh->mpm_proto_tcp_ctx_tc);
sh->mpm_proto_tcp_ctx_tc = NULL;
@ -2229,6 +2301,8 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
sh->mpm_hcd_ctx_tc = NULL;
MpmFactoryReClaimMpmCtx(sh->mpm_hrud_ctx_tc);
sh->mpm_hrud_ctx_tc = NULL;
MpmFactoryReClaimMpmCtx(sh->mpm_hsmd_ctx_tc);
sh->mpm_hsmd_ctx_tc = NULL;
}
return 0;

@ -45,6 +45,7 @@ uint32_t HttpRawHeaderPatternSearch(DetectEngineThreadCtx *, uint8_t *, uint32_t
uint32_t HttpMethodPatternSearch(DetectEngineThreadCtx *, uint8_t *, uint32_t, uint8_t);
uint32_t HttpCookiePatternSearch(DetectEngineThreadCtx *, uint8_t *, uint32_t, uint8_t);
uint32_t HttpRawUriPatternSearch(DetectEngineThreadCtx *, uint8_t *, uint32_t, uint8_t);
uint32_t HttpStatMsgPatternSearch(DetectEngineThreadCtx *, uint8_t *, uint32_t, uint8_t);
void PacketPatternCleanup(ThreadVars *, DetectEngineThreadCtx *);
void StreamPatternCleanup(ThreadVars *t, DetectEngineThreadCtx *det_ctx, StreamMsg *smsg);

@ -64,6 +64,7 @@
#include "detect-engine-hmd.h"
#include "detect-engine-hcd.h"
#include "detect-engine-hrud.h"
#include "detect-engine-hsmd.h"
#include "detect-engine-dcepayload.h"
#include "detect-engine-file.h"
@ -493,6 +494,10 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
SCLogDebug("skipping file inspection as we're not yet done with the other inspection");
}
}
/* not inspecting in toserver direction */
if (s->sm_lists[DETECT_SM_LIST_HSMDMATCH] != NULL) {
inspect_flags |= DE_STATE_FLAG_HSMD_INSPECT;
}
} else if (flags & STREAM_TOCLIENT) {
/* For to client set the flags in inspect so it can't match
* if the sig requires something only the request has. The rest
@ -562,6 +567,14 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
SCLogDebug("skipping file inspection as we're not yet done with the other inspection");
}
}
if (s->sm_lists[DETECT_SM_LIST_HSMDMATCH] != NULL) {
inspect_flags |= DE_STATE_FLAG_HSMD_INSPECT;
if (DetectEngineInspectHttpStatMsg(de_ctx, det_ctx, s, f,
flags, alstate) == 1) {
match_flags |= DE_STATE_FLAG_HSMD_MATCH;
}
SCLogDebug("inspecting http stat msg");
}
}
} else if (alproto == ALPROTO_DCERPC || alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) {
if (s->sm_lists[DETECT_SM_LIST_DMATCH] != NULL) {
@ -885,6 +898,12 @@ int DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, Dete
}
}
}
/* not inspecting in toserver direction */
if (s->sm_lists[DETECT_SM_LIST_HSMDMATCH] != NULL) {
if (!(item->flags & DE_STATE_FLAG_HSMD_MATCH)) {
inspect_flags |= DE_STATE_FLAG_HSMD_INSPECT;
}
}
} else if (alproto == ALPROTO_HTTP && (flags & STREAM_TOCLIENT)) {
/* For to client set the flags in inspect so it can't match
* if the sig requires something only the request has. The rest
@ -973,6 +992,18 @@ int DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, Dete
}
}
}
if (s->sm_lists[DETECT_SM_LIST_HSMDMATCH] != NULL) {
if (!(item->flags & DE_STATE_FLAG_HSMD_MATCH)) {
SCLogDebug("inspecting http stat msg data");
inspect_flags |= DE_STATE_FLAG_HSMD_INSPECT;
if (DetectEngineInspectHttpStatMsg(de_ctx, det_ctx, s, f,
flags, alstate) == 1) {
SCLogDebug("http stat msg matched");
match_flags |= DE_STATE_FLAG_HSMD_MATCH;
}
}
}
} else if (alproto == ALPROTO_DCERPC || alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) {
if (s->sm_lists[DETECT_SM_LIST_DMATCH] != NULL) {

@ -65,6 +65,7 @@
#define DE_STATE_FLAG_FILE_TS_MATCH 0x0800
#define DE_STATE_FLAG_FULL_MATCH 0x1000 /**< sig already fully matched */
#define DE_STATE_FLAG_SIG_CANT_MATCH 0x2000 /**< signature has no chance of matching */
#define DE_STATE_FLAG_HSMD_MATCH 0x4000 /**< hsmd payload inspection part matched */
#define DE_STATE_FLAG_URI_INSPECT DE_STATE_FLAG_URI_MATCH /**< uri part of the sig inspected */
#define DE_STATE_FLAG_DCE_INSPECT DE_STATE_FLAG_DCE_MATCH /**< dce payload inspection part inspected */
@ -77,6 +78,7 @@
#define DE_STATE_FLAG_HRUD_INSPECT DE_STATE_FLAG_HRUD_MATCH /**< hrud payload inspection part inspected */
#define DE_STATE_FLAG_FILE_TC_INSPECT DE_STATE_FLAG_FILE_TC_MATCH
#define DE_STATE_FLAG_FILE_TS_INSPECT DE_STATE_FLAG_FILE_TS_MATCH
#define DE_STATE_FLAG_HSMD_INSPECT DE_STATE_FLAG_HSMD_MATCH /**< hsmd payload inspection part inspected */
/* state flags */
#define DE_STATE_FILE_STORE_DISABLED 0x0001

File diff suppressed because it is too large Load Diff

@ -26,6 +26,7 @@
* \file
*
* \author Gurvinder Singh <gurvindersinghdahiya@gmail.com>
* \author Anoop Saldanha <anoopsaldanha@gmail.com>
*
* Implements the http_stat_msg keyword
*/
@ -39,6 +40,8 @@
#include "detect-parse.h"
#include "detect-engine.h"
#include "detect-content.h"
#include "detect-pcre.h"
#include "detect-engine-mpm.h"
#include "flow.h"
#include "flow-var.h"
@ -72,7 +75,7 @@ void DetectHttpStatMsgFree(void *);
void DetectHttpStatMsgRegister (void) {
sigmatch_table[DETECT_AL_HTTP_STAT_MSG].name = "http_stat_msg";
sigmatch_table[DETECT_AL_HTTP_STAT_MSG].Match = NULL;
sigmatch_table[DETECT_AL_HTTP_STAT_MSG].AppLayerMatch = DetectHttpStatMsgMatch;
sigmatch_table[DETECT_AL_HTTP_STAT_MSG].AppLayerMatch = NULL;
sigmatch_table[DETECT_AL_HTTP_STAT_MSG].alproto = ALPROTO_HTTP;
sigmatch_table[DETECT_AL_HTTP_STAT_MSG].Setup = DetectHttpStatMsgSetup;
sigmatch_table[DETECT_AL_HTTP_STAT_MSG].Free = DetectHttpStatMsgFree;
@ -96,7 +99,7 @@ void DetectHttpStatMsgRegister (void) {
* \retval 0 no match
* \retval 1 match
*/
int DetectHttpStatMsgMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx,
int DetectHttpStatMsgMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
Flow *f, uint8_t flags, void *state, Signature *s,
SigMatch *sm)
{
@ -204,92 +207,95 @@ void DetectHttpStatMsgFree(void *ptr)
* \retval -1 On failure
*/
static int DetectHttpStatMsgSetup (DetectEngineCtx *de_ctx, Signature *s, char *str)
static int DetectHttpStatMsgSetup (DetectEngineCtx *de_ctx, Signature *s, char *arg)
{
DetectContentData *hd = NULL;
DetectContentData *cd = NULL;
SigMatch *sm = NULL;
/** new sig match to replace previous content */
SigMatch *nm = NULL;
if (str != NULL && strcmp(str, "") != 0) {
SCLogError(SC_ERR_INVALID_ARGUMENT, "http_stat_msg shouldn't be supplied"
" with an argument");
if (arg != NULL && strcmp(arg, "") != 0) {
SCLogError(SC_ERR_INVALID_ARGUMENT, "http_client_body supplied with args");
return -1;
}
SigMatch *pm = DetectContentGetLastPattern(s->sm_lists_tail[DETECT_SM_LIST_PMATCH]);
if (pm == NULL) {
SCLogWarning(SC_ERR_INVALID_SIGNATURE, "http_stat_msg found inside "
"the rule, without a content context. Please use a "
"content keyword before using http_stat_msg");
sm = DetectContentGetLastPattern(s->sm_lists_tail[DETECT_SM_LIST_PMATCH]);
/* if still we are unable to find any content previous keywords, it is an
* invalid rule */
if (sm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "\"http_stat_msg\" keyword "
"found inside the rule without a content context. "
"Please use a \"content\" keyword before using the "
"\"http_stat_msg\" keyword");
return -1;
}
/* http_stat_msg should not be used with the fast_pattern rule */
if (((DetectContentData *)pm->ctx)->flags & DETECT_CONTENT_FAST_PATTERN) {
SCLogWarning(SC_WARN_COMPATIBILITY, "http_stat_msg rule can not "
"be used with the fast_pattern rule keyword. "
"Unsetting fast_pattern on this modifier. Signature ==> %s",
s->sig_str);
((DetectContentData *)pm->ctx)->flags &= ~DETECT_CONTENT_FAST_PATTERN;
cd = (DetectContentData *)sm->ctx;
/* http_stat_msg should not be used with the rawbytes rule */
} else if (((DetectContentData *)pm->ctx)->flags & DETECT_CONTENT_RAWBYTES) {
/* http_stat_msg should not be used with the rawbytes rule */
if (cd->flags & DETECT_CONTENT_RAWBYTES) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "http_stat_msg rule can not "
"be used with the rawbytes rule keyword");
"be used with the rawbytes rule keyword");
return -1;
}
nm = SigMatchAlloc();
if (nm == NULL) {
SCLogError(SC_ERR_MEM_ALLOC, "SigMatchAlloc failed");
if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_HTTP) {
SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains a non http "
"alproto set");
goto error;
}
/* Setup the HttpStatMsg data from Content data structure */
hd = SCMalloc(sizeof(DetectContentData));
if (hd == NULL)
goto error;
memset(hd, 0, sizeof(DetectContentData));
/* Setup the http_stat_msg keyword data */
hd->content_len = ((DetectContentData *)pm->ctx)->content_len;
hd->content = ((DetectContentData *)pm->ctx)->content;
hd->flags |= (((DetectContentData *)pm->ctx)->flags & DETECT_CONTENT_NOCASE) ?
DETECT_CONTENT_NOCASE : 0x00;
hd->flags |= (((DetectContentData *)pm->ctx)->flags & DETECT_CONTENT_NEGATED) ?
DETECT_CONTENT_NEGATED : 0x00;
nm->type = DETECT_AL_HTTP_STAT_MSG;
nm->ctx = (void *)hd;
/* pull the previous content from the pmatch list, append
* the new match to the match list */
SigMatchReplaceContent(s, pm, nm);
/* free the old content sigmatch, the content pattern memory
* is taken over by the new sigmatch */
BoyerMooreCtxDeInit(((DetectContentData *)pm->ctx)->bm_ctx);
SCFree(pm->ctx);
SCFree(pm);
/* Flagged the signature as to inspect the app layer data */
s->flags |= SIG_FLAG_APPLAYER;
if (cd->flags & DETECT_CONTENT_WITHIN || cd->flags & DETECT_CONTENT_DISTANCE) {
SigMatch *pm = SigMatchGetLastSMFromLists(s, 4,
DETECT_CONTENT, sm->prev,
DETECT_PCRE, sm->prev);
/* pm can be NULL now. To accomodate parsing sigs like -
* content:one; http_modifier; content:two; distance:0; http_modifier */
if (pm != NULL) {
if (pm->type == DETECT_CONTENT) {
DetectContentData *tmp_cd = (DetectContentData *)pm->ctx;
tmp_cd->flags &= ~DETECT_CONTENT_RELATIVE_NEXT;
} else {
DetectPcreData *tmp_pd = (DetectPcreData *)pm->ctx;
tmp_pd->flags &= ~ DETECT_PCRE_RELATIVE_NEXT;
}
if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_HTTP) {
SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting"
" keywords.");
goto error;
} /* if (pm != NULL) */
/* reassigning pm */
pm = SigMatchGetLastSMFromLists(s, 4,
DETECT_AL_HTTP_STAT_MSG, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH],
DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH]);
if (pm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "http_stat_msg seen with a "
"distance or within without a previous http_stat_msg "
"content. Invalidating signature.");
goto error;
}
if (pm->type == DETECT_PCRE) {
DetectPcreData *tmp_pd = (DetectPcreData *)pm->ctx;
tmp_pd->flags |= DETECT_PCRE_RELATIVE_NEXT;
} else {
DetectContentData *tmp_cd = (DetectContentData *)pm->ctx;
tmp_cd->flags |= DETECT_CONTENT_RELATIVE_NEXT;
}
}
cd->id = DetectPatternGetId(de_ctx->mpm_pattern_id_store, cd, DETECT_AL_HTTP_STAT_MSG);
sm->type = DETECT_AL_HTTP_STAT_MSG;
/* transfer the sm from the pmatch list to hcbdmatch list */
SigMatchTransferSigMatchAcrossLists(sm,
&s->sm_lists[DETECT_SM_LIST_PMATCH],
&s->sm_lists_tail[DETECT_SM_LIST_PMATCH],
&s->sm_lists[DETECT_SM_LIST_HSMDMATCH],
&s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH]);
/* flag the signature to indicate that we scan the app layer data */
s->flags |= SIG_FLAG_APPLAYER;
s->alproto = ALPROTO_HTTP;
return 0;
error:
if (hd != NULL)
DetectHttpStatMsgFree(hd);
if (sm != NULL)
SCFree(sm);
return -1;
}
@ -322,10 +328,11 @@ int DetectHttpStatMsgTest01(void)
de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing http_stat_msg\"; content:\"one\";"
"fast_pattern; http_stat_msg;sid:1;)");
if (de_ctx->sig_list == NULL ||
((DetectContentData *)de_ctx->sig_list->sm_lists[DETECT_SM_LIST_AMATCH]->ctx)->flags &
DETECT_CONTENT_FAST_PATTERN)
"fast_pattern; http_stat_msg; sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
if (!(((DetectContentData *)de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HSMDMATCH]->ctx)->flags &
DETECT_CONTENT_FAST_PATTERN))
{
goto end;
}
@ -362,7 +369,7 @@ int DetectHttpStatMsgTest02(void)
}
result = 0;
sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_AMATCH];
sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HSMDMATCH];
if (sm == NULL) {
printf("no sigmatch(es): ");
goto end;
@ -417,7 +424,7 @@ static int DetectHttpStatMsgSigTest01(void) {
f.flags |= FLOW_IPV4;
p->flow = &f;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_TOCLIENT;
p->flowflags |= FLOW_PKT_ESTABLISHED;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_HTTP;
@ -440,7 +447,7 @@ static int DetectHttpStatMsgSigTest01(void) {
s->next = SigInit(de_ctx,"alert http any any -> any any (msg:\"HTTP "
"Status message nocase\"; content:\"ok\"; nocase; "
"http_stat_msg; sid:2;)");
"http_stat_msg; sid:2;)");
if (s->next == NULL) {
goto end;
}
@ -523,7 +530,7 @@ static int DetectHttpStatMsgSigTest02(void) {
f.flags |= FLOW_IPV4;
p->flow = &f;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_TOCLIENT;
p->flowflags |= FLOW_PKT_ESTABLISHED;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_HTTP;
@ -619,7 +626,7 @@ static int DetectHttpStatMsgSigTest03(void) {
f.flags |= FLOW_IPV4;
p->flow = &f;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_TOCLIENT;
p->flowflags |= FLOW_PKT_ESTABLISHED;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_HTTP;

@ -351,7 +351,7 @@ int DetectIsdataatSetup (DetectEngineCtx *de_ctx, Signature *s, char *isdataatst
}
return 0;
}
pm = SigMatchGetLastSMFromLists(s, 50,
pm = SigMatchGetLastSMFromLists(s, 52,
DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], /* 1 */
DETECT_URICONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH],
DETECT_AL_HTTP_CLIENT_BODY, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH],
@ -361,6 +361,7 @@ int DetectIsdataatSetup (DetectEngineCtx *de_ctx, Signature *s, char *isdataatst
DETECT_AL_HTTP_METHOD, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH],
DETECT_AL_HTTP_COOKIE, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH],
DETECT_AL_HTTP_RAW_URI, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH],
DETECT_AL_HTTP_STAT_MSG, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH],
DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], /* 10 */
DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_UMATCH],
DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH],
@ -382,7 +383,8 @@ int DetectIsdataatSetup (DetectEngineCtx *de_ctx, Signature *s, char *isdataatst
"without a previous content uricontent, "
"http_client_body, http_header, http_raw_header, "
"http_method, http_cookie, http_raw_uri, "
"byte_test, byte_extract, byte_jump keyword");
"http_stat_msg, byte_test, byte_extract, byte_jump "
"keyword");
goto error;
} else {
int list_type = -1;
@ -418,6 +420,9 @@ int DetectIsdataatSetup (DetectEngineCtx *de_ctx, Signature *s, char *isdataatst
case DETECT_AL_HTTP_RAW_URI:
list_type = DETECT_SM_LIST_HRUDMATCH;
break;
case DETECT_AL_HTTP_STAT_MSG:
list_type = DETECT_SM_LIST_HSMDMATCH;
break;
default:
/* would never happen */
break;
@ -461,6 +466,7 @@ int DetectIsdataatSetup (DetectEngineCtx *de_ctx, Signature *s, char *isdataatst
case DETECT_AL_HTTP_METHOD:
case DETECT_AL_HTTP_COOKIE:
case DETECT_AL_HTTP_RAW_URI:
case DETECT_AL_HTTP_STAT_MSG:
/* Set the relative next flag on the prev sigmatch */
cd = (DetectContentData *)prev_pm->ctx;
if (cd == NULL) {

@ -180,7 +180,7 @@ static int DetectNocaseSetup (DetectEngineCtx *de_ctx, Signature *s, char *nulls
}
/* Search for the first previous SigMatch that supports nocase */
SigMatch *pm = SigMatchGetLastSMFromLists(s, 18,
SigMatch *pm = SigMatchGetLastSMFromLists(s, 20,
DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH],
DETECT_URICONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH],
DETECT_AL_HTTP_CLIENT_BODY, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH],
@ -189,12 +189,13 @@ static int DetectNocaseSetup (DetectEngineCtx *de_ctx, Signature *s, char *nulls
DETECT_AL_HTTP_RAW_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH],
DETECT_AL_HTTP_METHOD, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH],
DETECT_AL_HTTP_RAW_URI, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH],
DETECT_AL_HTTP_STAT_MSG, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH],
DETECT_AL_HTTP_COOKIE, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH]);
if (pm == NULL) {
SCLogError(SC_ERR_NOCASE_MISSING_PATTERN, "\"nocase\" needs a preceeding "
"content, uricontent, http_client_body, http_server_body, "
"http_header, http_method, http_uri, http_cookie or "
"http_raw_uri option");
"http_header, http_method, http_uri, http_cookie, "
"http_raw_uri or http_stat_msg option");
SCReturnInt(-1);
}
@ -210,6 +211,7 @@ static int DetectNocaseSetup (DetectEngineCtx *de_ctx, Signature *s, char *nulls
case DETECT_AL_HTTP_METHOD:
case DETECT_AL_HTTP_COOKIE:
case DETECT_AL_HTTP_RAW_URI:
case DETECT_AL_HTTP_STAT_MSG:
cd = (DetectContentData *)pm->ctx;
if (cd == NULL) {
SCLogError(SC_ERR_INVALID_ARGUMENT, "invalid argument");

@ -83,7 +83,7 @@ int DetectOffsetSetup (DetectEngineCtx *de_ctx, Signature *s, char *offsetstr)
break;
default:
pm = SigMatchGetLastSMFromLists(s, 18,
pm = SigMatchGetLastSMFromLists(s, 20,
DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH],
DETECT_URICONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH],
DETECT_AL_HTTP_CLIENT_BODY, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH],
@ -92,12 +92,13 @@ int DetectOffsetSetup (DetectEngineCtx *de_ctx, Signature *s, char *offsetstr)
DETECT_AL_HTTP_RAW_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH],
DETECT_AL_HTTP_METHOD, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH],
DETECT_AL_HTTP_COOKIE, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH],
DETECT_AL_HTTP_STAT_MSG, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH],
DETECT_AL_HTTP_RAW_URI, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]);
if (pm == NULL) {
SCLogError(SC_ERR_OFFSET_MISSING_CONTENT, "offset needs "
"preceeding content or uricontent option, http_client_body, "
"http_header, http_raw_header, http_method, "
"http_cookie or http_raw_uri option");
"http_cookie, http_raw_uri or http_stat_msg option");
if (dubbed)
SCFree(str);
return -1;
@ -520,6 +521,50 @@ int DetectOffsetSetup (DetectEngineCtx *de_ctx, Signature *s, char *offsetstr)
break;
case DETECT_AL_HTTP_STAT_MSG:
cd = (DetectContentData *)pm->ctx;
if (cd->flags & DETECT_CONTENT_NEGATED) {
if (cd->flags & DETECT_CONTENT_FAST_PATTERN) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "You can't have a relative "
"negated keyword set along with a fast_pattern");
goto error;
}
} else {
if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "You can't have a relative "
"keyword set along with a fast_pattern:only;");
goto error;
}
}
if (str[0] != '-' && isalpha(str[0])) {
SigMatch *bed_sm =
DetectByteExtractRetrieveSMVar(str, s,
SigMatchListSMBelongsTo(s, pm));
if (bed_sm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
"seen in offset - %s\n", str);
goto error;
}
cd->offset = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
cd->flags |= DETECT_CONTENT_OFFSET_BE;
} else {
cd->offset = (uint32_t)atoi(str);
if (cd->depth != 0) {
if (cd->depth < cd->content_len) {
SCLogDebug("depth increased to %"PRIu32" to match pattern len",
cd->content_len);
cd->depth = cd->content_len;
}
/* Updating the depth as is relative to the offset */
cd->depth += cd->offset;
}
}
cd->flags |= DETECT_CONTENT_OFFSET;
break;
default:
SCLogError(SC_ERR_OFFSET_MISSING_CONTENT, "offset needs a preceeding"
" content or uricontent option");

@ -1425,6 +1425,7 @@ static int SigValidate(Signature *s) {
DETECT_REPLACE, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH],
DETECT_REPLACE, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH],
DETECT_REPLACE, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH],
DETECT_REPLACE, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH],
DETECT_REPLACE, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH]);
if (pm != NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Signature has"
@ -1441,6 +1442,7 @@ static int SigValidate(Signature *s) {
s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH] ||
s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH] ||
s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH] ||
s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH] ||
s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH])
{
SCLogError(SC_ERR_INVALID_SIGNATURE, "Signature combines packet "
@ -1567,6 +1569,8 @@ static Signature *SigInitHelper(DetectEngineCtx *de_ctx, char *sigstr,
sig->flags |= SIG_FLAG_STATE_MATCH;
if (sig->sm_lists[DETECT_SM_LIST_FILEMATCH])
sig->flags |= SIG_FLAG_STATE_MATCH;
if (sig->sm_lists[DETECT_SM_LIST_HSMDMATCH])
sig->flags |= SIG_FLAG_STATE_MATCH;
if (!(sig->init_flags & SIG_FLAG_INIT_FLOW)) {
sig->flags |= SIG_FLAG_TOSERVER;

@ -902,6 +902,10 @@ DetectPcreData *DetectPcreParse (char *regexstr)
/* suricata extension (http response body inspection) */
pd->flags |= DETECT_PCRE_HTTP_SERVER_BODY;
break;
case 'Y':
/* snort's option */
pd->flags |= DETECT_PCRE_HTTP_STAT_MSG;
break;
default:
SCLogError(SC_ERR_UNKNOWN_REGEX_MOD, "unknown regex modifier '%c'", *op);
goto error;
@ -1070,6 +1074,7 @@ static int DetectPcreSetup (DetectEngineCtx *de_ctx, Signature *s, char *regexst
(pd->flags & DETECT_PCRE_HEADER) ||
(pd->flags & DETECT_PCRE_RAW_HEADER) ||
(pd->flags & DETECT_PCRE_COOKIE) ||
(pd->flags & DETECT_PCRE_HTTP_STAT_MSG) ||
(pd->flags & DETECT_PCRE_HTTP_CLIENT_BODY) ||
(pd->flags & DETECT_PCRE_HTTP_SERVER_BODY) ||
(pd->flags & DETECT_PCRE_HTTP_RAW_URI) ) {
@ -1152,6 +1157,16 @@ static int DetectPcreSetup (DetectEngineCtx *de_ctx, Signature *s, char *regexst
s->alproto = ALPROTO_HTTP;
SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_HRUDMATCH);
} else if (pd->flags & DETECT_PCRE_HTTP_STAT_MSG) {
s->flags |= SIG_FLAG_APPLAYER;
if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_HTTP) {
SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting"
" keywords.");
goto error;
}
s->alproto = ALPROTO_HTTP;
SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_HSMDMATCH);
} else {
if (s->alproto == ALPROTO_DCERPC && pd->flags & DETECT_PCRE_RELATIVE) {
SigMatch *pm = NULL;
@ -1192,7 +1207,7 @@ static int DetectPcreSetup (DetectEngineCtx *de_ctx, Signature *s, char *regexst
SCReturnInt(0);
}
prev_sm = SigMatchGetLastSMFromLists(s, 24,
prev_sm = SigMatchGetLastSMFromLists(s, 26,
DETECT_CONTENT, sm->prev,
DETECT_URICONTENT, sm->prev,
DETECT_AL_HTTP_CLIENT_BODY, sm->prev,
@ -1204,7 +1219,8 @@ static int DetectPcreSetup (DetectEngineCtx *de_ctx, Signature *s, char *regexst
DETECT_AL_HTTP_METHOD, sm->prev,
DETECT_PCRE, sm->prev,
DETECT_PCRE_HTTPCOOKIE, sm->prev,
DETECT_PCRE_HTTPMETHOD, sm->prev);
DETECT_PCRE_HTTPMETHOD, sm->prev,
DETECT_AL_HTTP_STAT_MSG, sm->prev);
if (prev_sm == NULL) {
if (s->alproto == ALPROTO_DCERPC) {
SCLogDebug("No preceding content or pcre keyword. Possible "
@ -1233,6 +1249,7 @@ static int DetectPcreSetup (DetectEngineCtx *de_ctx, Signature *s, char *regexst
case DETECT_AL_HTTP_SERVER_BODY:
case DETECT_AL_HTTP_HEADER:
case DETECT_AL_HTTP_RAW_HEADER:
case DETECT_AL_HTTP_STAT_MSG:
case DETECT_AL_HTTP_RAW_URI:
case DETECT_AL_HTTP_COOKIE:
case DETECT_AL_HTTP_METHOD:

@ -43,8 +43,9 @@
#define DETECT_PCRE_COOKIE 0x0800
#define DETECT_PCRE_METHOD 0x1000
#define DETECT_PCRE_HTTP_RAW_URI 0x2000
#define DETECT_PCRE_HTTP_STAT_MSG 0x4000
#define DETECT_PCRE_NEGATE 0x4000
#define DETECT_PCRE_NEGATE 0x8000
typedef struct DetectPcreData_ {
/* pcre options */

@ -163,7 +163,7 @@ static int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, char *withi
}
}
} else {
pm = SigMatchGetLastSMFromLists(s, 18,
pm = SigMatchGetLastSMFromLists(s, 20,
DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH],
DETECT_URICONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH],
DETECT_AL_HTTP_CLIENT_BODY, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH],
@ -172,12 +172,14 @@ static int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, char *withi
DETECT_AL_HTTP_RAW_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH],
DETECT_AL_HTTP_METHOD, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH],
DETECT_AL_HTTP_COOKIE, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH],
DETECT_AL_HTTP_STAT_MSG, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH],
DETECT_AL_HTTP_RAW_URI, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]);
if (pm == NULL) {
SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "within needs"
"preceeding content, uricontent, http_client_body, "
"http_server_body, http_header, http_raw_header, "
"http_method, http_cookie or http_raw_uri option");
"http_method, http_cookie, http_raw_uri or "
"http_stat_msg option");
if (dubbed)
SCFree(str);
return -1;
@ -888,6 +890,74 @@ static int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, char *withi
break;
case DETECT_AL_HTTP_STAT_MSG:
cd = (DetectContentData *)pm->ctx;
if (cd->flags & DETECT_CONTENT_NEGATED) {
if (cd->flags & DETECT_CONTENT_FAST_PATTERN) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "You can't have a relative "
"negated keyword set along with a fast_pattern");
goto error;
}
} else {
if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "You can't have a relative "
"keyword set along with a fast_pattern:only;");
goto error;
}
}
if (str[0] != '-' && isalpha(str[0])) {
SigMatch *bed_sm =
DetectByteExtractRetrieveSMVar(str, s,
SigMatchListSMBelongsTo(s, pm));
if (bed_sm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
"seen in within - %s\n", str);
goto error;
}
cd->within = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
cd->flags |= DETECT_CONTENT_WITHIN_BE;
} else {
cd->within = strtol(str, NULL, 10);
if (cd->within < (int32_t)cd->content_len) {
SCLogError(SC_ERR_WITHIN_INVALID, "within argument \"%"PRIi32"\" is "
"less than the content length \"%"PRIu32"\" which is invalid, since "
"this will never match. Invalidating signature", cd->within,
cd->content_len);
goto error;
}
}
cd->flags |= DETECT_CONTENT_WITHIN;
/* reassigning pm */
pm = SigMatchGetLastSMFromLists(s, 4,
DETECT_AL_HTTP_STAT_MSG, pm->prev,
DETECT_PCRE, pm->prev);
if (pm == NULL) {
SCLogError(SC_ERR_DISTANCE_MISSING_CONTENT, "distance for http_stat_msg "
"needs preceeding http_stat_msg content");
goto error;
}
if (pm->type == DETECT_PCRE) {
DetectPcreData *tmp_pd = (DetectPcreData *)pm->ctx;
tmp_pd->flags |= DETECT_PCRE_RELATIVE_NEXT;
} else {
/* reassigning cd */
cd = (DetectContentData *)pm->ctx;
if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Previous keyword "
"has a fast_pattern:only; set. You can't "
"have relative keywords around a fast_pattern "
"only content");
goto error;
}
cd->flags |= DETECT_CONTENT_RELATIVE_NEXT;
}
break;
default:
SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "within needs two "
"preceeding content or uricontent options");

@ -128,6 +128,7 @@
#include "detect-engine-hmd.h"
#include "detect-engine-hcd.h"
#include "detect-engine-hrud.h"
#include "detect-engine-hsmd.h"
#include "detect-byte-extract.h"
#include "detect-file-data.h"
#include "detect-replace.h"
@ -1208,6 +1209,11 @@ static inline void DetectMpmPrefilter(DetectEngineCtx *de_ctx,
DetectEngineRunHttpRawUriMpm(det_ctx, p->flow, alstate, flags);
PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HRUD);
}
if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HSMD) {
PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HSMD);
DetectEngineRunHttpStatMsgMpm(det_ctx, p->flow, alstate);
PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HSMD);
}
}
} else {
SCLogDebug("NOT p->flowflags & FLOW_PKT_ESTABLISHED");
@ -1944,6 +1950,9 @@ int SignatureIsIPOnly(DetectEngineCtx *de_ctx, Signature *s) {
if (s->sm_lists[DETECT_SM_LIST_HRUDMATCH] != NULL)
return 0;
if (s->sm_lists[DETECT_SM_LIST_HSMDMATCH] != NULL)
return 0;
if (s->sm_lists[DETECT_SM_LIST_AMATCH] != NULL)
return 0;
@ -2022,6 +2031,7 @@ static int SignatureIsDEOnly(DetectEngineCtx *de_ctx, Signature *s) {
s->sm_lists[DETECT_SM_LIST_HRHDMATCH] != NULL ||
s->sm_lists[DETECT_SM_LIST_HMDMATCH] != NULL ||
s->sm_lists[DETECT_SM_LIST_HCDMATCH] != NULL ||
s->sm_lists[DETECT_SM_LIST_HSMDMATCH] != NULL ||
s->sm_lists[DETECT_SM_LIST_HRUDMATCH] != NULL)
{
SCReturnInt(0);
@ -2163,6 +2173,11 @@ static int SignatureCreateMask(Signature *s) {
SCLogDebug("sig requires http app state");
}
if (s->sm_lists[DETECT_SM_LIST_HSMDMATCH] != NULL) {
s->mask |= SIG_MASK_REQUIRE_HTTP_STATE;
SCLogDebug("sig requires http app state");
}
SigMatch *sm;
for (sm = s->sm_lists[DETECT_SM_LIST_AMATCH] ; sm != NULL; sm = sm->next) {
switch(sm->type) {
@ -2324,6 +2339,9 @@ static void SigInitStandardMpmFactoryContexts(DetectEngineCtx *de_ctx)
de_ctx->sgh_mpm_context_hrud =
MpmFactoryRegisterMpmCtxProfile("hrud",
MPM_CTX_FACTORY_FLAGS_PREPARE_WITH_SIG_GROUP_BUILD);
de_ctx->sgh_mpm_context_hsmd =
MpmFactoryRegisterMpmCtxProfile("hsmd",
MPM_CTX_FACTORY_FLAGS_PREPARE_WITH_SIG_GROUP_BUILD);
de_ctx->sgh_mpm_context_app_proto_detect =
MpmFactoryRegisterMpmCtxProfile("app_proto_detect", 0);
@ -4359,6 +4377,18 @@ int SigGroupBuild (DetectEngineCtx *de_ctx) {
mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx);
}
//printf("stream- %d\n", mpm_ctx->pattern_cnt);
mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx->sgh_mpm_context_hsmd, 0);
if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) {
mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx);
}
//printf("hsmd- %d\n", mpm_ctx->pattern_cnt);
mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx->sgh_mpm_context_hsmd, 1);
if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) {
mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx);
}
//printf("hsmd- %d\n", mpm_ctx->pattern_cnt);
}
// SigAddressPrepareStage5(de_ctx);

@ -100,6 +100,8 @@ enum {
DETECT_SM_LIST_HCDMATCH,
/* list for http_raw_uri keyword and the ones relative to it */
DETECT_SM_LIST_HRUDMATCH,
/* list for http_stat_msg keyword and the ones relative to it */
DETECT_SM_LIST_HSMDMATCH,
DETECT_SM_LIST_FILEMATCH,
@ -651,6 +653,7 @@ typedef struct DetectEngineCtx_ {
int32_t sgh_mpm_context_hmd;
int32_t sgh_mpm_context_hcd;
int32_t sgh_mpm_context_hrud;
int32_t sgh_mpm_context_hsmd;
int32_t sgh_mpm_context_app_proto_detect;
/** sgh for signatures that match against invalid packets. In those cases
@ -838,6 +841,8 @@ typedef struct SigTableElmt_ {
#define SIG_GROUP_HEAD_HAVEFILEMAGIC 0x00800000
#define SIG_GROUP_HAVEHSBDCONTENT 0x01000000
#define SIG_GROUP_HEAD_MPM_HSBD 0x02000000
#define SIG_GROUP_HAVEHSMDCONTENT 0x04000000
#define SIG_GROUP_HEAD_MPM_HSMD 0x08000000
typedef struct SigGroupHeadInitData_ {
/* list of content containers
@ -893,6 +898,7 @@ typedef struct SigGroupHead_ {
MpmCtx *mpm_hmd_ctx_ts;
MpmCtx *mpm_hcd_ctx_ts;
MpmCtx *mpm_hrud_ctx_ts;
MpmCtx *mpm_hsmd_ctx_ts;
MpmCtx *mpm_proto_tcp_ctx_tc;
MpmCtx *mpm_proto_udp_ctx_tc;
@ -905,6 +911,7 @@ typedef struct SigGroupHead_ {
MpmCtx *mpm_hmd_ctx_tc;
MpmCtx *mpm_hcd_ctx_tc;
MpmCtx *mpm_hrud_ctx_tc;
MpmCtx *mpm_hsmd_ctx_tc;
uint16_t mpm_uricontent_maxlen;

@ -64,6 +64,7 @@
#include "detect-engine-hmd.h"
#include "detect-engine-hcd.h"
#include "detect-engine-hrud.h"
#include "detect-engine-hsmd.h"
#include "detect-engine-state.h"
#include "detect-engine-tag.h"
#include "detect-fast-pattern.h"
@ -1437,6 +1438,7 @@ int main(int argc, char **argv)
DetectEngineHttpMethodRegisterTests();
DetectEngineHttpCookieRegisterTests();
DetectEngineHttpRawUriRegisterTests();
DetectEngineHttpStatMsgRegisterTests();
DetectEngineRegisterTests();
SCLogRegisterTests();
SMTPParserRegisterTests();

Loading…
Cancel
Save