Support http stat code detection engine, fast pattern(mpm engine included). Fix http stat code setup function. Fix pcre option for stat msg keyword. With this the pcre options for server_body is Q, for stat_msg is Y and for stat_code is S

remotes/origin/master
Anoop Saldanha 14 years ago committed by Victor Julien
parent 2007c2711c
commit 09313cf9bd

@ -85,6 +85,7 @@ 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-hscd.c detect-engine-hscd.h \
detect-engine-state.c detect-engine-state.h \
detect-engine-file.c detect-engine-file.h \
detect-parse.c detect-parse.h \

@ -53,15 +53,16 @@
#define DETECT_CONTENT_HCD_MPM 0x00080000
#define DETECT_CONTENT_HRUD_MPM 0x00100000
#define DETECT_CONTENT_HSMD_MPM 0x00200000
#define DETECT_CONTENT_HSCD_MPM 0x00400000
/* BE - byte extract */
#define DETECT_CONTENT_OFFSET_BE 0x00400000
#define DETECT_CONTENT_DEPTH_BE 0x00800000
#define DETECT_CONTENT_DISTANCE_BE 0x01000000
#define DETECT_CONTENT_WITHIN_BE 0x02000000
#define DETECT_CONTENT_OFFSET_BE 0x00800000
#define DETECT_CONTENT_DEPTH_BE 0x01000000
#define DETECT_CONTENT_DISTANCE_BE 0x02000000
#define DETECT_CONTENT_WITHIN_BE 0x04000000
/* replace data */
#define DETECT_CONTENT_REPLACE 0x04000000
#define DETECT_CONTENT_REPLACE 0x08000000
#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, 20,
pm = SigMatchGetLastSMFromLists(s, 22,
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],
@ -96,13 +96,14 @@ static int DetectDepthSetup (DetectEngineCtx *de_ctx, Signature *s, char *depths
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_CODE, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH],
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, http_raw_uri or "
"http_stat_msg option");
"http_method option, http_cookie, http_raw_uri, "
"http_stat_msg or http_stat_code option");
if (dubbed)
SCFree(str);
return -1;
@ -545,6 +546,47 @@ static int DetectDepthSetup (DetectEngineCtx *de_ctx, Signature *s, char *depths
break;
case DETECT_AL_HTTP_STAT_CODE:
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, 20,
pm = SigMatchGetLastSMFromLists(s, 22,
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],
@ -170,12 +170,14 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s,
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_CODE, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH],
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, http_raw_uri or http_stat_msg option");
"http_cookie, http_raw_uri, http_stat_msg or http_stat_code "
"option");
if (dubbed)
SCFree(str);
return -1;
@ -900,6 +902,73 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s,
break;
case DETECT_AL_HTTP_STAT_CODE:
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_CODE, pm->prev,
DETECT_PCRE, pm->prev);
if (pm == NULL) {
SCLogError(SC_ERR_DISTANCE_MISSING_CONTENT, "distance for "
"http_stat_code needs preceeding http_stat_code "
"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");

@ -2212,7 +2212,7 @@ static int DetectEngineHttpServerBodyTest14(void)
de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
"(msg:\"http server body test\"; "
"pcre:/ab/S; "
"pcre:/ab/Q; "
"content:\"ef\"; http_server_body; distance:2; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
@ -2331,7 +2331,7 @@ static int DetectEngineHttpServerBodyTest15(void)
de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
"(msg:\"http server body test\"; "
"pcre:/abc/S; "
"pcre:/abc/Q; "
"content:!\"xyz\"; http_server_body; distance:0; within:3; "
"sid:1;)");
if (de_ctx->sig_list == NULL)

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_HSCD_H__
#define __DETECT_ENGINE_HSCD_H__
#include "app-layer-htp.h"
int DetectEngineRunHttpStatCodeMpm(DetectEngineThreadCtx *,
Flow *f, HtpState *);
int DetectEngineInspectHttpStatCode(DetectEngineCtx *, DetectEngineThreadCtx *,
Signature *, Flow *, uint8_t, void *);
void DetectEngineHttpStatCodeRegisterTests(void);
#endif /* __DETECT_ENGINE_HSCD_H__ */

@ -527,9 +527,9 @@ uint32_t HttpRawUriPatternSearch(DetectEngineThreadCtx *det_ctx,
/**
* \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.
* \param det_ctx Detection engine thread ctx.
* \param stat_msg Stat msg to inspect.
* \param stat_msg_len Stat msg length.
*
* \retval ret Number of matches.
*/
@ -549,6 +549,31 @@ uint32_t HttpStatMsgPatternSearch(DetectEngineThreadCtx *det_ctx,
SCReturnUInt(ret);
}
/**
* \brief Http stat code match -- searches for one pattern per signature.
*
* \param det_ctx Detection engine thread ctx.
* \param stat_code Stat code to inspect.
* \param stat_code_len Stat code length.
*
* \retval ret Number of matches.
*/
uint32_t HttpStatCodePatternSearch(DetectEngineThreadCtx *det_ctx,
uint8_t *stat_code, uint32_t stat_code_len)
{
SCEnter();
if (det_ctx->sgh->mpm_hscd_ctx == NULL)
SCReturnUInt(0);
uint32_t ret;
ret = mpm_table[det_ctx->sgh->mpm_hscd_ctx->mpm_type].
Search(det_ctx->sgh->mpm_hscd_ctx, &det_ctx->mtcu,
&det_ctx->pmq, stat_code, stat_code_len);
SCReturnUInt(ret);
}
/** \brief Pattern match -- searches for only one pattern per signature.
*
* \param det_ctx detection engine thread ctx
@ -1206,6 +1231,7 @@ static void PopulateMpmAddPatternToMpm(DetectEngineCtx *de_ctx,
case DETECT_AL_HTTP_METHOD:
case DETECT_AL_HTTP_COOKIE:
case DETECT_AL_HTTP_STAT_MSG:
case DETECT_AL_HTTP_STAT_CODE:
{
MpmCtx *mpm_ctx_ts = NULL;
MpmCtx *mpm_ctx_tc = NULL;
@ -1272,6 +1298,10 @@ static void PopulateMpmAddPatternToMpm(DetectEngineCtx *de_ctx,
mpm_ctx = sgh->mpm_hsmd_ctx;
sgh_flags = SIG_GROUP_HEAD_MPM_HSMD;
cd_flags = DETECT_CONTENT_HSMD_MPM;
} else if (mpm_sm->type == DETECT_AL_HTTP_STAT_CODE) {
mpm_ctx = sgh->mpm_hscd_ctx;
sgh_flags = SIG_GROUP_HEAD_MPM_HSCD;
cd_flags = DETECT_CONTENT_HSCD_MPM;
}
cd = (DetectContentData *)mpm_sm->ctx;
@ -1566,6 +1596,8 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
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;
/* used to indicate if sgh has atleast one sig with http_stat_code */
uint32_t has_co_hscd = 0;
//uint32_t cnt = 0;
uint32_t sig = 0;
@ -1619,6 +1651,10 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
if (s->sm_lists[DETECT_SM_LIST_HSMDMATCH] != NULL) {
has_co_hsmd = 1;
}
if (s->sm_lists[DETECT_SM_LIST_HSCDMATCH] != NULL) {
has_co_hscd = 1;
}
}
if (has_co_packet > 0) {
@ -1654,6 +1690,9 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
if (has_co_hsmd > 0) {
sh->flags |= SIG_GROUP_HAVEHSMDCONTENT;
}
if (has_co_hscd > 0) {
sh->flags |= SIG_GROUP_HAVEHSCDCONTENT;
}
/* intialize contexes */
if (sh->flags & SIG_GROUP_HAVECONTENT) {
@ -1929,6 +1968,24 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
#endif
}
if (sh->flags & SIG_GROUP_HAVEHSCDCONTENT) {
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) {
sh->mpm_hscd_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx->sgh_mpm_context_hscd);
} else {
sh->mpm_hscd_ctx = MpmFactoryGetMpmCtxForProfile(MPM_CTX_FACTORY_UNIQUE_CONTEXT);
}
if (sh->mpm_hscd_ctx == NULL) {
SCLogDebug("sh->mpm_hscd_ctx == NULL. This should never happen");
exit(EXIT_FAILURE);
}
#ifndef __SC_CUDA_SUPPORT__
MpmInitCtx(sh->mpm_hscd_ctx, de_ctx->mpm_matcher, -1);
#else
MpmInitCtx(sh->mpm_hscd_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 ||
@ -1939,6 +1996,7 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
sh->flags & SIG_GROUP_HAVEHMDCONTENT ||
sh->flags & SIG_GROUP_HAVEHCDCONTENT ||
sh->flags & SIG_GROUP_HAVEHSMDCONTENT ||
sh->flags & SIG_GROUP_HAVEHSCDCONTENT ||
sh->flags & SIG_GROUP_HAVEHRUDCONTENT) {
PatternMatchPreparePopulateMpm(de_ctx, sh);
@ -2253,6 +2311,18 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
}
}
}
if (sh->mpm_hscd_ctx != NULL) {
if (sh->mpm_hscd_ctx->pattern_cnt == 0) {
MpmFactoryReClaimMpmCtx(sh->mpm_hscd_ctx);
sh->mpm_hscd_ctx = NULL;
} else {
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL &&
sh->flags & SIG_GROUP_HAVEHSCDCONTENT) {
if (mpm_table[sh->mpm_hscd_ctx->mpm_type].Prepare != NULL)
mpm_table[sh->mpm_hscd_ctx->mpm_type].Prepare(sh->mpm_hscd_ctx);
}
}
}
//} /* if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) */
} else {
MpmFactoryReClaimMpmCtx(sh->mpm_proto_other_ctx);
@ -2280,6 +2350,8 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
sh->mpm_hrud_ctx_ts = NULL;
MpmFactoryReClaimMpmCtx(sh->mpm_hsmd_ctx_ts);
sh->mpm_hsmd_ctx_ts = NULL;
MpmFactoryReClaimMpmCtx(sh->mpm_hscd_ctx_ts);
sh->mpm_hscd_ctx_ts = NULL;
MpmFactoryReClaimMpmCtx(sh->mpm_proto_tcp_ctx_tc);
sh->mpm_proto_tcp_ctx_tc = NULL;
@ -2303,6 +2375,8 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
sh->mpm_hrud_ctx_tc = NULL;
MpmFactoryReClaimMpmCtx(sh->mpm_hsmd_ctx_tc);
sh->mpm_hsmd_ctx_tc = NULL;
MpmFactoryReClaimMpmCtx(sh->mpm_hscd_ctx_tc);
sh->mpm_hscd_ctx_tc = NULL;
}
return 0;

@ -46,6 +46,7 @@ uint32_t HttpMethodPatternSearch(DetectEngineThreadCtx *, uint8_t *, uint32_t, u
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);
uint32_t HttpStatCodePatternSearch(DetectEngineThreadCtx *, uint8_t *, uint32_t, uint8_t);
void PacketPatternCleanup(ThreadVars *, DetectEngineThreadCtx *);
void StreamPatternCleanup(ThreadVars *t, DetectEngineThreadCtx *det_ctx, StreamMsg *smsg);

@ -65,6 +65,7 @@
#include "detect-engine-hcd.h"
#include "detect-engine-hrud.h"
#include "detect-engine-hsmd.h"
#include "detect-engine-hscd.h"
#include "detect-engine-dcepayload.h"
#include "detect-engine-file.h"
@ -498,6 +499,10 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
if (s->sm_lists[DETECT_SM_LIST_HSMDMATCH] != NULL) {
inspect_flags |= DE_STATE_FLAG_HSMD_INSPECT;
}
/* not inspecting in toserver direction */
if (s->sm_lists[DETECT_SM_LIST_HSCDMATCH] != NULL) {
inspect_flags |= DE_STATE_FLAG_HSCD_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
@ -575,6 +580,14 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
}
SCLogDebug("inspecting http stat msg");
}
if (s->sm_lists[DETECT_SM_LIST_HSCDMATCH] != NULL) {
inspect_flags |= DE_STATE_FLAG_HSCD_INSPECT;
if (DetectEngineInspectHttpStatCode(de_ctx, det_ctx, s, f,
flags, alstate) == 1) {
match_flags |= DE_STATE_FLAG_HSCD_MATCH;
}
SCLogDebug("inspecting http stat code");
}
}
} else if (alproto == ALPROTO_DCERPC || alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) {
if (s->sm_lists[DETECT_SM_LIST_DMATCH] != NULL) {
@ -904,6 +917,12 @@ int DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, Dete
inspect_flags |= DE_STATE_FLAG_HSMD_INSPECT;
}
}
/* not inspecting in toserver direction */
if (s->sm_lists[DETECT_SM_LIST_HSCDMATCH] != NULL) {
if (!(item->flags & DE_STATE_FLAG_HSCD_MATCH)) {
inspect_flags |= DE_STATE_FLAG_HSCD_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
@ -1004,6 +1023,18 @@ int DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, Dete
}
}
}
if (s->sm_lists[DETECT_SM_LIST_HSCDMATCH] != NULL) {
if (!(item->flags & DE_STATE_FLAG_HSCD_MATCH)) {
SCLogDebug("inspecting http stat code data");
inspect_flags |= DE_STATE_FLAG_HSCD_INSPECT;
if (DetectEngineInspectHttpStatCode(de_ctx, det_ctx, s, f,
flags, alstate) == 1) {
SCLogDebug("http stat code matched");
match_flags |= DE_STATE_FLAG_HSCD_MATCH;
}
}
}
} else if (alproto == ALPROTO_DCERPC || alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) {
if (s->sm_lists[DETECT_SM_LIST_DMATCH] != NULL) {

@ -66,6 +66,7 @@
#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_HSCD_MATCH 0x8000 /**< hscd 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 */
@ -79,6 +80,7 @@
#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 */
#define DE_STATE_FLAG_HSCD_INSPECT DE_STATE_FLAG_HSCD_MATCH /**< hscd payload inspection part inspected */
/* state flags */
#define DE_STATE_FILE_STORE_DISABLED 0x0001

File diff suppressed because it is too large Load Diff

@ -2460,7 +2460,7 @@ int DetectHttpServerBodyTest34(void)
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
"(pcre:/one/S; "
"(pcre:/one/Q; "
"content:\"two\"; within:5; http_server_body; sid:1;)");
if (de_ctx->sig_list == NULL) {
printf("de_ctx->sig_list == NULL\n");
@ -2512,7 +2512,7 @@ int DetectHttpServerBodyTest35(void)
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
"(content:\"two\"; http_server_body; "
"pcre:/one/SR; sid:1;)");
"pcre:/one/QR; sid:1;)");
if (de_ctx->sig_list == NULL) {
printf("de_ctx->sig_list == NULL\n");
goto end;
@ -2562,7 +2562,7 @@ int DetectHttpServerBodyTest36(void)
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
"(pcre:/one/S; "
"(pcre:/one/Q; "
"content:\"two\"; distance:5; http_server_body; sid:1;)");
if (de_ctx->sig_list == NULL) {
printf("de_ctx->sig_list == NULL\n");

@ -26,6 +26,7 @@
* \file
*
* \author Gurvinder Singh <gurvindersinghdahiya@gmail.com>
* \author Anoop Saldanha <anoopsaldanha@gmail.com>
*
* Implements the http_stat_code 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"
@ -59,10 +62,10 @@
#include "stream-tcp-private.h"
#include "stream-tcp.h"
int DetectHttpStatCodeMatch (ThreadVars *, DetectEngineThreadCtx *,
Flow *, uint8_t , void *, Signature *,
SigMatch *);
static int DetectHttpStatCodeSetup (DetectEngineCtx *, Signature *, char *);
int DetectHttpStatCodeMatch(ThreadVars *, DetectEngineThreadCtx *,
Flow *, uint8_t , void *, Signature *,
SigMatch *);
static int DetectHttpStatCodeSetup(DetectEngineCtx *, Signature *, char *);
void DetectHttpStatCodeRegisterTests(void);
void DetectHttpStatCodeFree(void *);
@ -72,7 +75,7 @@ void DetectHttpStatCodeFree(void *);
void DetectHttpStatCodeRegister (void) {
sigmatch_table[DETECT_AL_HTTP_STAT_CODE].name = "http_stat_code";
sigmatch_table[DETECT_AL_HTTP_STAT_CODE].Match = NULL;
sigmatch_table[DETECT_AL_HTTP_STAT_CODE].AppLayerMatch = DetectHttpStatCodeMatch;
sigmatch_table[DETECT_AL_HTTP_STAT_CODE].AppLayerMatch = NULL;
sigmatch_table[DETECT_AL_HTTP_STAT_CODE].alproto = ALPROTO_HTTP;
sigmatch_table[DETECT_AL_HTTP_STAT_CODE].Setup = DetectHttpStatCodeSetup;
sigmatch_table[DETECT_AL_HTTP_STAT_CODE].Free = DetectHttpStatCodeFree;
@ -96,9 +99,9 @@ void DetectHttpStatCodeRegister (void) {
* \retval 0 no match
* \retval 1 match
*/
int DetectHttpStatCodeMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx,
Flow *f, uint8_t flags, void *state, Signature *s,
SigMatch *sm)
int DetectHttpStatCodeMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
Flow *f, uint8_t flags, void *state, Signature *s,
SigMatch *sm)
{
SCEnter();
@ -210,96 +213,96 @@ void DetectHttpStatCodeFree(void *ptr)
* \retval -1 On failure
*/
static int DetectHttpStatCodeSetup (DetectEngineCtx *de_ctx, Signature *s, char *str)
static int DetectHttpStatCodeSetup (DetectEngineCtx *de_ctx, Signature *s, char *arg)
{
SCEnter();
DetectHttpStatCodeData *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_code shouldn't be supplied"
" with an argument");
SCReturnInt(-1);
if (arg != NULL && strcmp(arg, "") != 0) {
SCLogError(SC_ERR_INVALID_ARGUMENT, "http_stat_code 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_code found inside "
"the rule, without a content context. Please use a "
"content keyword before using http_stat_code");
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_code\" keyword "
"found inside the rule without a content context. "
"Please use a \"content\" keyword before using the "
"\"http_stat_code\" keyword");
return -1;
}
/* http_stat_code should not be used with the fast_pattern rule */
if (((DetectContentData *)pm->ctx)->flags & DETECT_CONTENT_FAST_PATTERN) {
SCLogWarning(SC_WARN_COMPATIBILITY, "http_stat_code 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_code 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_code rule can not "
"be used with the rawbytes rule keyword");
SCReturnInt(-1);
"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 HttpStatCode data from Content data structure */
hd = SCMalloc(sizeof(DetectHttpStatCodeData));
if (hd == NULL)
goto error;
memset(hd, 0, sizeof(DetectHttpStatCodeData));
/* Setup the http_stat_code keyword data */
hd->data_len = ((DetectContentData *)pm->ctx)->content_len;
hd->data = ((DetectContentData *)pm->ctx)->content;
hd->flags |= (((DetectContentData *)pm->ctx)->flags & DETECT_CONTENT_NOCASE) ?
DETECT_AL_HTTP_STAT_CODE_NOCASE : 0x00;
hd->flags |= (((DetectContentData *)pm->ctx)->flags & DETECT_CONTENT_NEGATED) ?
DETECT_AL_HTTP_STAT_CODE_NEGATED : 0;
hd->code = htp_parse_positive_integer_whitespace((unsigned char *)hd->data,
hd->data_len, 10);
nm->type = DETECT_AL_HTTP_STAT_CODE;
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_CODE, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH],
DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH]);
if (pm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "http_stat_code seen with a "
"distance or within without a previous http_stat_code "
"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_CODE);
sm->type = DETECT_AL_HTTP_STAT_CODE;
/* 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_HSCDMATCH],
&s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH]);
/* flag the signature to indicate that we scan the app layer data */
s->flags |= SIG_FLAG_APPLAYER;
s->alproto = ALPROTO_HTTP;
SCReturnInt(0);
return 0;
error:
if (hd != NULL)
DetectHttpStatCodeFree(hd);
if(sm !=NULL)
SCFree(sm);
SCReturnInt(-1);
return -1;
}
#ifdef UNITTESTS
@ -342,6 +345,11 @@ int DetectHttpStatCodeTest01(void)
printf("sid 3 parse failed: ");
goto end;
}
if (!(((DetectContentData *)de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HSCDMATCH]->ctx)->flags &
DETECT_CONTENT_FAST_PATTERN))
{
goto end;
}
result = 1;
end:
@ -375,7 +383,7 @@ int DetectHttpStatCodeTest02(void)
}
result = 0;
sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_AMATCH];
sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HSCDMATCH];
if (sm == NULL) {
printf("no sigmatch(es): ");
goto end;
@ -393,8 +401,8 @@ int DetectHttpStatCodeTest02(void)
sm = sm->next;
}
if (! (((DetectHttpStatCodeData *)prev->ctx)->flags &
DETECT_AL_HTTP_STAT_CODE_NOCASE))
if (! (((DetectContentData *)prev->ctx)->flags &
DETECT_CONTENT_NOCASE))
{
result = 0;
}
@ -430,7 +438,7 @@ static int DetectHttpStatCodeSigTest01(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;
@ -523,7 +531,7 @@ static int DetectHttpStatCodeSigTest02(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;
@ -630,7 +638,7 @@ static int DetectHttpStatCodeSigTest03(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;
@ -737,7 +745,7 @@ static int DetectHttpStatCodeSigTest04(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;

@ -213,7 +213,7 @@ static int DetectHttpStatMsgSetup (DetectEngineCtx *de_ctx, Signature *s, char *
SigMatch *sm = NULL;
if (arg != NULL && strcmp(arg, "") != 0) {
SCLogError(SC_ERR_INVALID_ARGUMENT, "http_client_body supplied with args");
SCLogError(SC_ERR_INVALID_ARGUMENT, "http_stat_msg supplied with args");
return -1;
}

@ -351,7 +351,7 @@ int DetectIsdataatSetup (DetectEngineCtx *de_ctx, Signature *s, char *isdataatst
}
return 0;
}
pm = SigMatchGetLastSMFromLists(s, 52,
pm = SigMatchGetLastSMFromLists(s, 54,
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],
@ -362,6 +362,7 @@ int DetectIsdataatSetup (DetectEngineCtx *de_ctx, Signature *s, char *isdataatst
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_AL_HTTP_STAT_CODE, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH],
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],
@ -383,8 +384,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, "
"http_stat_msg, byte_test, byte_extract, byte_jump "
"keyword");
"http_stat_msg, http_stat_code, byte_test, "
"byte_extract, byte_jump keyword");
goto error;
} else {
int list_type = -1;
@ -423,6 +424,9 @@ int DetectIsdataatSetup (DetectEngineCtx *de_ctx, Signature *s, char *isdataatst
case DETECT_AL_HTTP_STAT_MSG:
list_type = DETECT_SM_LIST_HSMDMATCH;
break;
case DETECT_AL_HTTP_STAT_CODE:
list_type = DETECT_SM_LIST_HSCDMATCH;
break;
default:
/* would never happen */
break;
@ -467,6 +471,7 @@ int DetectIsdataatSetup (DetectEngineCtx *de_ctx, Signature *s, char *isdataatst
case DETECT_AL_HTTP_COOKIE:
case DETECT_AL_HTTP_RAW_URI:
case DETECT_AL_HTTP_STAT_MSG:
case DETECT_AL_HTTP_STAT_CODE:
/* 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, 20,
SigMatch *pm = SigMatchGetLastSMFromLists(s, 22,
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],
@ -190,12 +190,13 @@ static int DetectNocaseSetup (DetectEngineCtx *de_ctx, Signature *s, char *nulls
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_STAT_CODE, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH],
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, "
"http_raw_uri or http_stat_msg option");
"http_raw_uri, http_stat_msg or http_stat_code option");
SCReturnInt(-1);
}
@ -212,6 +213,7 @@ static int DetectNocaseSetup (DetectEngineCtx *de_ctx, Signature *s, char *nulls
case DETECT_AL_HTTP_COOKIE:
case DETECT_AL_HTTP_RAW_URI:
case DETECT_AL_HTTP_STAT_MSG:
case DETECT_AL_HTTP_STAT_CODE:
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, 20,
pm = SigMatchGetLastSMFromLists(s, 22,
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],
@ -93,12 +93,14 @@ int DetectOffsetSetup (DetectEngineCtx *de_ctx, Signature *s, char *offsetstr)
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_STAT_CODE, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH],
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, http_raw_uri or http_stat_msg option");
"http_cookie, http_raw_uri, http_stat_msg or "
"http_stat_code option");
if (dubbed)
SCFree(str);
return -1;
@ -565,6 +567,50 @@ int DetectOffsetSetup (DetectEngineCtx *de_ctx, Signature *s, char *offsetstr)
break;
case DETECT_AL_HTTP_STAT_CODE:
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");

@ -1426,6 +1426,7 @@ static int SigValidate(Signature *s) {
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_HSCDMATCH],
DETECT_REPLACE, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH]);
if (pm != NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Signature has"
@ -1443,6 +1444,7 @@ static int SigValidate(Signature *s) {
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_HSCDMATCH] ||
s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH])
{
SCLogError(SC_ERR_INVALID_SIGNATURE, "Signature combines packet "
@ -1571,6 +1573,8 @@ static Signature *SigInitHelper(DetectEngineCtx *de_ctx, char *sigstr,
sig->flags |= SIG_FLAG_STATE_MATCH;
if (sig->sm_lists[DETECT_SM_LIST_HSMDMATCH])
sig->flags |= SIG_FLAG_STATE_MATCH;
if (sig->sm_lists[DETECT_SM_LIST_HSCDMATCH])
sig->flags |= SIG_FLAG_STATE_MATCH;
if (!(sig->init_flags & SIG_FLAG_INIT_FLOW)) {
sig->flags |= SIG_FLAG_TOSERVER;

@ -898,7 +898,7 @@ DetectPcreData *DetectPcreParse (char *regexstr)
/* snort's option (http request body inspection) */
pd->flags |= DETECT_PCRE_HTTP_CLIENT_BODY;
break;
case 'S':
case 'Q':
/* suricata extension (http response body inspection) */
pd->flags |= DETECT_PCRE_HTTP_SERVER_BODY;
break;
@ -906,6 +906,10 @@ DetectPcreData *DetectPcreParse (char *regexstr)
/* snort's option */
pd->flags |= DETECT_PCRE_HTTP_STAT_MSG;
break;
case 'S':
/* snort's option */
pd->flags |= DETECT_PCRE_HTTP_STAT_CODE;
break;
default:
SCLogError(SC_ERR_UNKNOWN_REGEX_MOD, "unknown regex modifier '%c'", *op);
goto error;
@ -1075,6 +1079,7 @@ static int DetectPcreSetup (DetectEngineCtx *de_ctx, Signature *s, char *regexst
(pd->flags & DETECT_PCRE_RAW_HEADER) ||
(pd->flags & DETECT_PCRE_COOKIE) ||
(pd->flags & DETECT_PCRE_HTTP_STAT_MSG) ||
(pd->flags & DETECT_PCRE_HTTP_STAT_CODE) ||
(pd->flags & DETECT_PCRE_HTTP_CLIENT_BODY) ||
(pd->flags & DETECT_PCRE_HTTP_SERVER_BODY) ||
(pd->flags & DETECT_PCRE_HTTP_RAW_URI) ) {
@ -1167,6 +1172,16 @@ static int DetectPcreSetup (DetectEngineCtx *de_ctx, Signature *s, char *regexst
s->alproto = ALPROTO_HTTP;
SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_HSMDMATCH);
} else if (pd->flags & DETECT_PCRE_HTTP_STAT_CODE) {
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_HSCDMATCH);
} else {
if (s->alproto == ALPROTO_DCERPC && pd->flags & DETECT_PCRE_RELATIVE) {
SigMatch *pm = NULL;
@ -1207,7 +1222,7 @@ static int DetectPcreSetup (DetectEngineCtx *de_ctx, Signature *s, char *regexst
SCReturnInt(0);
}
prev_sm = SigMatchGetLastSMFromLists(s, 26,
prev_sm = SigMatchGetLastSMFromLists(s, 28,
DETECT_CONTENT, sm->prev,
DETECT_URICONTENT, sm->prev,
DETECT_AL_HTTP_CLIENT_BODY, sm->prev,
@ -1220,7 +1235,8 @@ static int DetectPcreSetup (DetectEngineCtx *de_ctx, Signature *s, char *regexst
DETECT_PCRE, sm->prev,
DETECT_PCRE_HTTPCOOKIE, sm->prev,
DETECT_PCRE_HTTPMETHOD, sm->prev,
DETECT_AL_HTTP_STAT_MSG, sm->prev);
DETECT_AL_HTTP_STAT_MSG, sm->prev,
DETECT_AL_HTTP_STAT_CODE, sm->prev);
if (prev_sm == NULL) {
if (s->alproto == ALPROTO_DCERPC) {
SCLogDebug("No preceding content or pcre keyword. Possible "
@ -1250,6 +1266,7 @@ static int DetectPcreSetup (DetectEngineCtx *de_ctx, Signature *s, char *regexst
case DETECT_AL_HTTP_HEADER:
case DETECT_AL_HTTP_RAW_HEADER:
case DETECT_AL_HTTP_STAT_MSG:
case DETECT_AL_HTTP_STAT_CODE:
case DETECT_AL_HTTP_RAW_URI:
case DETECT_AL_HTTP_COOKIE:
case DETECT_AL_HTTP_METHOD:

@ -24,35 +24,36 @@
#ifndef __DETECT_PCRE_H__
#define __DETECT_PCRE_H__
#define DETECT_PCRE_RELATIVE 0x0001
#define DETECT_PCRE_RAWBYTES 0x0002
#define DETECT_PCRE_URI 0x0004
#define DETECT_PCRE_RELATIVE 0x00001
#define DETECT_PCRE_RAWBYTES 0x00002
#define DETECT_PCRE_URI 0x00004
#define DETECT_PCRE_CAPTURE_PKT 0x0008
#define DETECT_PCRE_CAPTURE_FLOW 0x0010
#define DETECT_PCRE_MATCH_LIMIT 0x0020
#define DETECT_PCRE_CAPTURE_PKT 0x00008
#define DETECT_PCRE_CAPTURE_FLOW 0x00010
#define DETECT_PCRE_MATCH_LIMIT 0x00020
#define DETECT_PCRE_HTTP_CLIENT_BODY 0x0040
#define DETECT_PCRE_HTTP_SERVER_BODY 0x0080
#define DETECT_PCRE_HTTP_CLIENT_BODY 0x00040
#define DETECT_PCRE_HTTP_SERVER_BODY 0x00080
#define DETECT_PCRE_RELATIVE_NEXT 0x0100
#define DETECT_PCRE_RELATIVE_NEXT 0x00100
/* new modifiers 2.8.5.3 support */
#define DETECT_PCRE_HEADER 0x0200
#define DETECT_PCRE_RAW_HEADER 0x0400
#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_HEADER 0x00200
#define DETECT_PCRE_RAW_HEADER 0x00400
#define DETECT_PCRE_COOKIE 0x00800
#define DETECT_PCRE_METHOD 0x01000
#define DETECT_PCRE_HTTP_RAW_URI 0x02000
#define DETECT_PCRE_HTTP_STAT_MSG 0x04000
#define DETECT_PCRE_HTTP_STAT_CODE 0x08000
#define DETECT_PCRE_NEGATE 0x8000
#define DETECT_PCRE_NEGATE 0x10000
typedef struct DetectPcreData_ {
/* pcre options */
pcre *re;
pcre_extra *sd;
int opts;
uint16_t flags;
uint32_t flags;
uint16_t capidx;
char *capname;
} DetectPcreData;

@ -163,7 +163,7 @@ static int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, char *withi
}
}
} else {
pm = SigMatchGetLastSMFromLists(s, 20,
pm = SigMatchGetLastSMFromLists(s, 22,
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],
@ -173,13 +173,14 @@ static int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, char *withi
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_STAT_CODE, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH],
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, http_raw_uri or "
"http_stat_msg option");
"http_method, http_cookie, http_raw_uri, "
"http_stat_msg or http_stat_code option");
if (dubbed)
SCFree(str);
return -1;
@ -958,6 +959,74 @@ static int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, char *withi
break;
case DETECT_AL_HTTP_STAT_CODE:
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_CODE, pm->prev,
DETECT_PCRE, pm->prev);
if (pm == NULL) {
SCLogError(SC_ERR_DISTANCE_MISSING_CONTENT, "distance for http_stat_code "
"needs preceeding http_stat_code 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");

@ -129,6 +129,7 @@
#include "detect-engine-hcd.h"
#include "detect-engine-hrud.h"
#include "detect-engine-hsmd.h"
#include "detect-engine-hscd.h"
#include "detect-byte-extract.h"
#include "detect-file-data.h"
#include "detect-replace.h"
@ -1214,6 +1215,11 @@ static inline void DetectMpmPrefilter(DetectEngineCtx *de_ctx,
DetectEngineRunHttpStatMsgMpm(det_ctx, p->flow, alstate);
PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HSMD);
}
if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HSCD) {
PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HSCD);
DetectEngineRunHttpStatCodeMpm(det_ctx, p->flow, alstate);
PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HSCD);
}
}
} else {
SCLogDebug("NOT p->flowflags & FLOW_PKT_ESTABLISHED");
@ -1953,6 +1959,9 @@ int SignatureIsIPOnly(DetectEngineCtx *de_ctx, Signature *s) {
if (s->sm_lists[DETECT_SM_LIST_HSMDMATCH] != NULL)
return 0;
if (s->sm_lists[DETECT_SM_LIST_HSCDMATCH] != NULL)
return 0;
if (s->sm_lists[DETECT_SM_LIST_AMATCH] != NULL)
return 0;
@ -2032,6 +2041,7 @@ static int SignatureIsDEOnly(DetectEngineCtx *de_ctx, Signature *s) {
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_HSCDMATCH] != NULL ||
s->sm_lists[DETECT_SM_LIST_HRUDMATCH] != NULL)
{
SCReturnInt(0);
@ -2178,6 +2188,11 @@ static int SignatureCreateMask(Signature *s) {
SCLogDebug("sig requires http app state");
}
if (s->sm_lists[DETECT_SM_LIST_HSCDMATCH] != 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) {
@ -2342,6 +2357,9 @@ static void SigInitStandardMpmFactoryContexts(DetectEngineCtx *de_ctx)
de_ctx->sgh_mpm_context_hsmd =
MpmFactoryRegisterMpmCtxProfile("hsmd",
MPM_CTX_FACTORY_FLAGS_PREPARE_WITH_SIG_GROUP_BUILD);
de_ctx->sgh_mpm_context_hscd =
MpmFactoryRegisterMpmCtxProfile("hscd",
MPM_CTX_FACTORY_FLAGS_PREPARE_WITH_SIG_GROUP_BUILD);
de_ctx->sgh_mpm_context_app_proto_detect =
MpmFactoryRegisterMpmCtxProfile("app_proto_detect", 0);
@ -4389,6 +4407,18 @@ int SigGroupBuild (DetectEngineCtx *de_ctx) {
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_hscd, 0);
if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) {
mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx);
}
//printf("hscd- %d\n", mpm_ctx->pattern_cnt);
mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx->sgh_mpm_context_hscd, 1);
if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) {
mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx);
}
//printf("hscd- %d\n", mpm_ctx->pattern_cnt);
}
// SigAddressPrepareStage5(de_ctx);

@ -102,6 +102,8 @@ enum {
DETECT_SM_LIST_HRUDMATCH,
/* list for http_stat_msg keyword and the ones relative to it */
DETECT_SM_LIST_HSMDMATCH,
/* list for http_stat_code keyword and the ones relative to it */
DETECT_SM_LIST_HSCDMATCH,
DETECT_SM_LIST_FILEMATCH,
@ -654,6 +656,7 @@ typedef struct DetectEngineCtx_ {
int32_t sgh_mpm_context_hcd;
int32_t sgh_mpm_context_hrud;
int32_t sgh_mpm_context_hsmd;
int32_t sgh_mpm_context_hscd;
int32_t sgh_mpm_context_app_proto_detect;
/** sgh for signatures that match against invalid packets. In those cases
@ -843,6 +846,8 @@ typedef struct SigTableElmt_ {
#define SIG_GROUP_HEAD_MPM_HSBD 0x02000000
#define SIG_GROUP_HAVEHSMDCONTENT 0x04000000
#define SIG_GROUP_HEAD_MPM_HSMD 0x08000000
#define SIG_GROUP_HAVEHSCDCONTENT 0x10000000
#define SIG_GROUP_HEAD_MPM_HSCD 0x20000000
typedef struct SigGroupHeadInitData_ {
/* list of content containers
@ -899,6 +904,7 @@ typedef struct SigGroupHead_ {
MpmCtx *mpm_hcd_ctx_ts;
MpmCtx *mpm_hrud_ctx_ts;
MpmCtx *mpm_hsmd_ctx_ts;
MpmCtx *mpm_hscd_ctx_ts;
MpmCtx *mpm_proto_tcp_ctx_tc;
MpmCtx *mpm_proto_udp_ctx_tc;
@ -912,6 +918,7 @@ typedef struct SigGroupHead_ {
MpmCtx *mpm_hcd_ctx_tc;
MpmCtx *mpm_hrud_ctx_tc;
MpmCtx *mpm_hsmd_ctx_tc;
MpmCtx *mpm_hscd_ctx_tc;
uint16_t mpm_uricontent_maxlen;

@ -184,6 +184,8 @@ typedef enum PacketProfileDetectId_ {
PROF_DETECT_MPM_HMD,
PROF_DETECT_MPM_HCD,
PROF_DETECT_MPM_HRUD,
PROF_DETECT_MPM_HSMD,
PROF_DETECT_MPM_HSCD,
PROF_DETECT_IPONLY,
PROF_DETECT_RULES,
PROF_DETECT_STATEFUL,

@ -65,6 +65,7 @@
#include "detect-engine-hcd.h"
#include "detect-engine-hrud.h"
#include "detect-engine-hsmd.h"
#include "detect-engine-hscd.h"
#include "detect-engine-state.h"
#include "detect-engine-tag.h"
#include "detect-fast-pattern.h"
@ -1439,6 +1440,7 @@ int main(int argc, char **argv)
DetectEngineHttpCookieRegisterTests();
DetectEngineHttpRawUriRegisterTests();
DetectEngineHttpStatMsgRegisterTests();
DetectEngineHttpStatCodeRegisterTests();
DetectEngineRegisterTests();
SCLogRegisterTests();
SMTPParserRegisterTests();

Loading…
Cancel
Save