support for http_raw_uri keyword + mpm engine

remotes/origin/master-1.1.x
Anoop Saldanha 15 years ago committed by Victor Julien
parent 663d03c0e9
commit 966119b6aa

@ -76,6 +76,7 @@ detect-engine-hhd.c detect-engine-hhd.h \
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-state.c detect-engine-state.h \
detect-parse.c detect-parse.h \
detect-ack.c detect-ack.h \
@ -129,6 +130,7 @@ detect-http-method.c detect-http-method.h \
detect-http-header.c detect-http-header.h \
detect-http-raw-header.c detect-http-raw-header.h \
detect-http-uri.c detect-http-uri.h \
detect-http-raw-uri.c detect-http-raw-uri.h \
detect-tls-version.c detect-tls-version.h \
detect-ssh-proto-version.c detect-ssh-proto-version.h \
detect-ssh-software-version.c detect-ssh-software-version.h \

@ -50,6 +50,7 @@
#define DETECT_CONTENT_HRHD_MPM 0x00010000
#define DETECT_CONTENT_HMD_MPM 0x00020000
#define DETECT_CONTENT_HCD_MPM 0x00040000
#define DETECT_CONTENT_HRUD_MPM 0x00080000
#define DETECT_CONTENT_IS_SINGLE(c) (!((c)->flags & DETECT_CONTENT_DISTANCE || \
(c)->flags & DETECT_CONTENT_WITHIN || \

@ -85,9 +85,10 @@ static int DetectDepthSetup (DetectEngineCtx *de_ctx, Signature *s, char *depths
break;
default:
pm = SigMatchGetLastSMFromLists(s, 14,
pm = SigMatchGetLastSMFromLists(s, 16,
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],
DETECT_AL_HTTP_CLIENT_BODY, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH],
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],
@ -96,8 +97,9 @@ static int DetectDepthSetup (DetectEngineCtx *de_ctx, Signature *s, char *depths
if (pm == NULL) {
SCLogError(SC_ERR_DEPTH_MISSING_CONTENT, "depth needs "
"preceeding content, uricontent option, http_client_body, "
"http_header option, http_raw_header option or "
"http_method option or http_cookie option");
"http_header option, http_raw_header option, "
"http_method option, http_cookie or "
"http_raw_uri option");
if (dubbed)
SCFree(str);
return -1;
@ -106,6 +108,8 @@ static int DetectDepthSetup (DetectEngineCtx *de_ctx, Signature *s, char *depths
break;
}
/* i swear we will clean this up :). Use a single version for all. Using
* separate versions for all now, to avoiding breaking any code */
switch (pm->type) {
case DETECT_URICONTENT:
ud = (DetectContentData *)pm->ctx;
@ -316,6 +320,34 @@ static int DetectDepthSetup (DetectEngineCtx *de_ctx, Signature *s, char *depths
break;
case DETECT_AL_HTTP_RAW_URI:
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;
}
}
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");

@ -168,9 +168,10 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s,
}
}
} else {
pm = SigMatchGetLastSMFromLists(s, 14,
pm = SigMatchGetLastSMFromLists(s, 16,
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],
DETECT_AL_HTTP_CLIENT_BODY, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH],
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],
@ -179,8 +180,8 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s,
if (pm == NULL) {
SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "within needs"
"preceeding content, uricontent option, http_client_body, "
"http_header, http_raw_header or http_method or "
"http_cookie option");
"http_header, http_raw_header, http_method, "
"http_cookie or http_raw_uri option");
if (dubbed)
SCFree(str);
return -1;
@ -638,6 +639,59 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s,
break;
case DETECT_AL_HTTP_RAW_URI:
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;
}
}
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_RAW_URI, pm->prev,
DETECT_PCRE, pm->prev);
if (pm == NULL) {
SCLogError(SC_ERR_DISTANCE_MISSING_CONTENT, "distance for "
"http_raw_uri needs preceeding http_raw_uri "
"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,35 @@
/* 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 <poonaatsoc@gmail.com>
*/
#ifndef __DETECT_ENGINE_HRUD_H__
#define __DETECT_ENGINE_HRUD_H__
#include "app-layer-htp.h"
int DetectEngineRunHttpRawUriMpm(DetectEngineThreadCtx *,
Flow *f, HtpState *);
int DetectEngineInspectHttpRawUri(DetectEngineCtx *, DetectEngineThreadCtx *,
Signature *, Flow *, uint8_t, void *);
void DetectEngineHttpRawUriRegisterTests(void);
#endif /* __DETECT_ENGINE_HRUD_H__ */

@ -381,6 +381,31 @@ uint32_t HttpCookiePatternSearch(DetectEngineThreadCtx *det_ctx,
SCReturnUInt(ret);
}
/**
* \brief Http raw uri match -- searches for one pattern per signature.
*
* \param det_ctx Detection engine thread ctx.
* \param uri Raw uri to inspect.
* \param uri_len Raw uri length.
*
* \retval ret Number of matches.
*/
uint32_t HttpRawUriPatternSearch(DetectEngineThreadCtx *det_ctx,
uint8_t *uri, uint32_t uri_len)
{
SCEnter();
if (det_ctx->sgh->mpm_hrud_ctx == NULL)
SCReturnUInt(0);
uint32_t ret;
ret = mpm_table[det_ctx->sgh->mpm_hrud_ctx->mpm_type].
Search(det_ctx->sgh->mpm_hrud_ctx, &det_ctx->mtcu,
&det_ctx->pmq, uri, uri_len);
SCReturnUInt(ret);
}
/** \brief Pattern match -- searches for only one pattern per signature.
*
* \param det_ctx detection engine thread ctx
@ -679,6 +704,7 @@ static void PopulateMpmAddPatternToMpm(DetectEngineCtx *de_ctx,
DetectContentData *hrhd = NULL;
DetectContentData *hmd = NULL;
DetectContentData *hcd = NULL;
DetectContentData *hrud = NULL;
switch (mpm_sm->type) {
case DETECT_CONTENT:
{
@ -1135,6 +1161,61 @@ static void PopulateMpmAddPatternToMpm(DetectEngineCtx *de_ctx,
break;
} /* case DETECT_AL_HTTP_COOKIE */
case DETECT_AL_HTTP_RAW_URI:
{
hrud = (DetectContentData *)mpm_sm->ctx;
if (hrud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) {
/* add the content to the "hrud" mpm */
if (hrud->flags & DETECT_CONTENT_NOCASE) {
mpm_table[sgh->mpm_hrud_ctx->mpm_type].
AddPatternNocase(sgh->mpm_hrud_ctx,
hrud->content + hrud->fp_chop_offset,
hrud->fp_chop_len,
0, 0, hrud->id, s->num, flags);
} else {
mpm_table[sgh->mpm_hrud_ctx->mpm_type].
AddPattern(sgh->mpm_hrud_ctx,
hrud->content + hrud->fp_chop_offset,
hrud->fp_chop_len,
0, 0, hrud->id, s->num, flags);
}
} else {
if (hrud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) {
if (DETECT_CONTENT_IS_SINGLE(hrud)) {
hrud->flags |= DETECT_CONTENT_HRUD_MPM;
}
/* see if we can bypass the match validation for this pattern */
} else {
if (DETECT_CONTENT_IS_SINGLE(hrud)) {
hrud->flags |= DETECT_CONTENT_HRUD_MPM;
}
} /* else - if (hrud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) */
/* add the content to the "hrud" mpm */
if (hrud->flags & DETECT_CONTENT_NOCASE) {
mpm_table[sgh->mpm_hrud_ctx->mpm_type].
AddPatternNocase(sgh->mpm_hrud_ctx,
hrud->content, hrud->content_len,
0, 0, hrud->id, s->num, flags);
} else {
mpm_table[sgh->mpm_hrud_ctx->mpm_type].
AddPattern(sgh->mpm_hrud_ctx,
hrud->content, hrud->content_len,
0, 0, hrud->id, s->num, flags);
}
}
/* tell matcher we are inspecting raw uri */
s->flags |= SIG_FLAG_MPM_HRUDCONTENT;
s->mpm_http_pattern_id = hrud->id;
if (hrud->flags & DETECT_CONTENT_NEGATED)
s->flags |= SIG_FLAG_MPM_HRUDCONTENT_NEG;
sgh->flags |= SIG_GROUP_HEAD_MPM_HRUD;
break;
} /* case DETECT_AL_HTTP_RAW_URI */
} /* switch (mpm_sm->type) */
SCLogDebug("%"PRIu32" adding cd->id %"PRIu32" to the mpm phase "
@ -1436,6 +1517,8 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
uint32_t has_co_hmd = 0;
/* used to indicate if sgh has atleast one sig with http_cookie */
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;
//uint32_t cnt = 0;
uint32_t sig = 0;
@ -1477,6 +1560,10 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
if (s->sm_lists[DETECT_SM_LIST_HCDMATCH] != NULL) {
has_co_hcd = 1;
}
if (s->sm_lists[DETECT_SM_LIST_HRUDMATCH] != NULL) {
has_co_hrud = 1;
}
}
if (has_co_packet > 0) {
@ -1503,6 +1590,9 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
if (has_co_hcd > 0) {
sh->flags |= SIG_GROUP_HAVEHCDCONTENT;
}
if (has_co_hrud > 0) {
sh->flags |= SIG_GROUP_HAVEHRUDCONTENT;
}
/* intialize contexes */
if (sh->flags & SIG_GROUP_HAVECONTENT) {
@ -1649,6 +1739,24 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
#endif
}
if (sh->flags & SIG_GROUP_HAVEHRUDCONTENT) {
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) {
sh->mpm_hrud_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx->sgh_mpm_context_hrud);
} else {
sh->mpm_hrud_ctx = MpmFactoryGetMpmCtxForProfile(MPM_CTX_FACTORY_UNIQUE_CONTEXT);
}
if (sh->mpm_hrud_ctx == NULL) {
SCLogDebug("sh->mpm_hrud_ctx == NULL. This should never happen");
exit(EXIT_FAILURE);
}
#ifndef __SC_CUDA_SUPPORT__
MpmInitCtx(sh->mpm_hrud_ctx, de_ctx->mpm_matcher, -1);
#else
MpmInitCtx(sh->mpm_hrud_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 ||
@ -1656,7 +1764,8 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
sh->flags & SIG_GROUP_HAVEHHDCONTENT ||
sh->flags & SIG_GROUP_HAVEHRHDCONTENT ||
sh->flags & SIG_GROUP_HAVEHMDCONTENT ||
sh->flags & SIG_GROUP_HAVEHCDCONTENT) {
sh->flags & SIG_GROUP_HAVEHCDCONTENT ||
sh->flags & SIG_GROUP_HAVEHRUDCONTENT) {
PatternMatchPreparePopulateMpm(de_ctx, sh);
@ -1749,6 +1858,17 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
}
}
}
if (sh->mpm_hrud_ctx != NULL) {
if (sh->mpm_hrud_ctx->pattern_cnt == 0) {
MpmFactoryReClaimMpmCtx(sh->mpm_hrud_ctx);
sh->mpm_hrud_ctx = NULL;
} else {
if (sh->flags & SIG_GROUP_HAVEHRUDCONTENT) {
if (mpm_table[sh->mpm_hrud_ctx->mpm_type].Prepare != NULL)
mpm_table[sh->mpm_hrud_ctx->mpm_type].Prepare(sh->mpm_hrud_ctx);
}
}
}
} /* if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) */
} else {
@ -1768,9 +1888,10 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
sh->mpm_hmd_ctx = NULL;
MpmFactoryReClaimMpmCtx(sh->mpm_hcd_ctx);
sh->mpm_hcd_ctx = NULL;
MpmFactoryReClaimMpmCtx(sh->mpm_hrud_ctx);
sh->mpm_hrud_ctx = NULL;
}
return 0;
}

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

@ -36,6 +36,7 @@
#include "detect-engine-hrhd.h"
#include "detect-engine-hmd.h"
#include "detect-engine-hcd.h"
#include "detect-engine-hrud.h"
#include "detect-engine-dcepayload.h"
#include "stream-tcp.h"
@ -213,7 +214,8 @@ int DeStateUpdateInspectTransactionId(Flow *f, char direction) {
*/
static void DeStateSignatureAppend(DetectEngineState *state, Signature *s,
SigMatch *sm, char uri, char dce, char hcbd,
char hhd, char hrhd, char hmd, char hcd) {
char hhd, char hrhd, char hmd, char hcd,
char hrud) {
DeStateStore *store = state->tail;
if (store == NULL) {
@ -260,6 +262,9 @@ static void DeStateSignatureAppend(DetectEngineState *state, Signature *s,
if (hcd) {
store->store[idx].flags |= DE_STATE_FLAG_HCD_MATCH;
}
if (hrud) {
store->store[idx].flags |= DE_STATE_FLAG_HRUD_MATCH;
}
store->store[idx].nm = sm;
state->cnt++;
@ -329,6 +334,8 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
char hmdmatch = 0;
char hcdinspect = 0;
char hcdmatch = 0;
char hrudinspect = 0;
char hrudmatch = 0;
char dmatch = 0;
char dinspect = 0;
char appinspect = 0;
@ -396,6 +403,14 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
}
SCLogDebug("inspecting http cookie");
}
if (s->sm_lists[DETECT_SM_LIST_HRUDMATCH] != NULL) {
hrudinspect = 1;
if (DetectEngineInspectHttpRawUri(de_ctx, det_ctx, s, f,
flags, alstate) == 1) {
hrudmatch = 1;
}
SCLogDebug("inspecting http raw uri");
}
} else if (alproto == ALPROTO_DCERPC || alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) {
if (s->sm_lists[DETECT_SM_LIST_DMATCH] != NULL) {
@ -427,8 +442,10 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
}
}
appinspect = uinspect + dinspect + hcbdinspect + hhdinspect + hrhdinspect + hmdinspect + hcdinspect;
appmatch = umatch + dmatch + hcbdmatch + hhdmatch + hrhdmatch + hmdmatch + hcdmatch;
appinspect = uinspect + dinspect + hcbdinspect + hhdinspect +
hrhdinspect + hmdinspect + hcdinspect + hrudinspect;
appmatch = umatch + dmatch + hcbdmatch + hhdmatch + hrhdmatch
+ hmdmatch + hcdmatch + hrudmatch;
if (s->sm_lists[DETECT_SM_LIST_AMATCH] != NULL) {
for ( ; sm != NULL; sm = sm->next) {
@ -471,8 +488,8 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
}
SCLogDebug("detection done, store results: sm %p, uri %d, dce %d, hcbd %d, "
"hhd %d, hrhd %d hmd %d hcd %d", sm, umatch, dmatch, hcbdmatch,
hhdmatch, hrhdmatch, hmdmatch, hcdmatch);
"hhd %d, hrhd %d hmd %d hcd %d hrud %d", sm, umatch, dmatch,
hcbdmatch, hhdmatch, hrhdmatch, hmdmatch, hcdmatch, hrudmatch);
SCMutexLock(&f->de_state_m);
/* match or no match, we store the state anyway
@ -484,7 +501,7 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
if (f->de_state != NULL) {
/* \todo shift to an array to transfer these match values*/
DeStateSignatureAppend(f->de_state, s, sm, umatch, dmatch, hcbdmatch,
hhdmatch, hrhdmatch, hmdmatch, hcdmatch);
hhdmatch, hrhdmatch, hmdmatch, hcdmatch, hrudmatch);
}
SCMutexUnlock(&f->de_state_m);
@ -515,6 +532,8 @@ int DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, Dete
char hmdinspect = 0;
char hcdmatch = 0;
char hcdinspect = 0;
char hrudmatch = 0;
char hrudinspect = 0;
char dmatch = 0;
char dinspect = 0;
char appinspect = 0;
@ -551,6 +570,8 @@ int DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, Dete
hmdinspect = 0;
hcdmatch = 0;
hcdinspect = 0;
hrudmatch = 0;
hrudinspect = 0;
dmatch = 0;
dinspect = 0;
appinspect = 0;
@ -659,6 +680,19 @@ int DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, Dete
}
}
}
if (s->sm_lists[DETECT_SM_LIST_HRUDMATCH] != NULL) {
if (!(item->flags & DE_STATE_FLAG_HRUD_MATCH)) {
SCLogDebug("inspecting http raw uri data");
hrudinspect = 1;
if (DetectEngineInspectHttpRawUri(de_ctx, det_ctx, s, f,
flags, alstate) == 1) {
SCLogDebug("http raw uri matched");
item->flags |= DE_STATE_FLAG_HRUD_MATCH;
hrudmatch = 1;
}
}
}
} else if (alproto == ALPROTO_DCERPC || alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) {
if (s->sm_lists[DETECT_SM_LIST_DMATCH] != NULL) {
@ -697,8 +731,10 @@ int DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, Dete
}
appinspect = uinspect + dinspect + hcbdinspect + hhdinspect + hrhdinspect + hmdinspect + hcdinspect;
appmatch = umatch + dmatch + hcbdmatch + hhdmatch + hrhdmatch + hmdmatch + hcdmatch;
appinspect = uinspect + dinspect + hcbdinspect + hhdinspect +
hrhdinspect + hmdinspect + hcdinspect + hrudinspect;
appmatch = umatch + dmatch + hcbdmatch + hhdmatch + hrhdmatch +
hmdmatch + hcdmatch + hrudmatch;
SCLogDebug("appinspect %d, appmatch %d", appinspect, appmatch);
/* next, check the other sig matches */
@ -838,39 +874,39 @@ static int DeStateTest02(void) {
memset(&s, 0x00, sizeof(s));
s.num = 0;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0, 0);
s.num = 11;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0, 0);
s.num = 22;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0, 0);
s.num = 33;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0, 0);
s.num = 44;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0, 0);
s.num = 55;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0, 0);
s.num = 66;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0, 0);
s.num = 77;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0, 0);
s.num = 88;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0, 0);
s.num = 99;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0, 0);
s.num = 100;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0, 0);
s.num = 111;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0, 0);
s.num = 122;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0, 0);
s.num = 133;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0, 0);
s.num = 144;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0, 0);
s.num = 155;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0, 0);
s.num = 166;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0, 0);
if (state->head == NULL) {
goto end;
@ -913,9 +949,9 @@ static int DeStateTest03(void) {
memset(&s, 0x00, sizeof(s));
s.num = 11;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0, 0, 0, 0);
s.num = 22;
DeStateSignatureAppend(state, &s, NULL, 1, 0, 0, 0, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 1, 0, 0, 0, 0, 0, 0, 0);
if (state->head == NULL) {
goto end;

@ -52,7 +52,8 @@
#define DE_STATE_FLAG_HRHD_MATCH 0x0020 /**< hrhd payload inspection part matched */
#define DE_STATE_FLAG_HMD_MATCH 0x0040 /**< hmd payload inspection part matched */
#define DE_STATE_FLAG_HCD_MATCH 0x0080 /**< hcd payload inspection part matched */
#define DE_STATE_FLAG_FULL_MATCH 0x0100 /**< sig already fully matched */
#define DE_STATE_FLAG_HRUD_MATCH 0x0100 /**< hrud payload inspection part matched */
#define DE_STATE_FLAG_FULL_MATCH 0x0200 /**< sig already fully matched */
/** per signature detection engine state */
typedef enum {

File diff suppressed because it is too large Load Diff

@ -0,0 +1,905 @@
/* 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 <poonaatsoc@gmail.com>
*/
#include "suricata-common.h"
#include "threads.h"
#include "debug.h"
#include "decode.h"
#include "detect.h"
#include "detect-parse.h"
#include "detect-engine.h"
#include "detect-engine-mpm.h"
#include "detect-content.h"
#include "detect-pcre.h"
#include "flow.h"
#include "flow-var.h"
#include "util-debug.h"
#include "util-unittest.h"
#include "util-spm.h"
#include "util-print.h"
#include "app-layer.h"
#include <htp/htp.h>
#include "app-layer-htp.h"
#include "detect-http-raw-uri.h"
#include "stream-tcp.h"
static int DetectHttpRawUriSetup(DetectEngineCtx *, Signature *, char *);
static void DetectHttpRawUriRegisterTests(void);
/**
* \brief Registration function for keyword http_raw_uri.
*/
void DetectHttpRawUriRegister(void)
{
sigmatch_table[DETECT_AL_HTTP_RAW_URI].name = "http_raw_uri";
sigmatch_table[DETECT_AL_HTTP_RAW_URI].Match = NULL;
sigmatch_table[DETECT_AL_HTTP_RAW_URI].AppLayerMatch = NULL;
sigmatch_table[DETECT_AL_HTTP_RAW_URI].alproto = ALPROTO_HTTP;
sigmatch_table[DETECT_AL_HTTP_RAW_URI].Setup = DetectHttpRawUriSetup;
sigmatch_table[DETECT_AL_HTTP_RAW_URI].Free = NULL;
sigmatch_table[DETECT_AL_HTTP_RAW_URI].RegisterTests = DetectHttpRawUriRegisterTests;
sigmatch_table[DETECT_AL_HTTP_RAW_URI].flags |= SIGMATCH_PAYLOAD;
return;
}
/**
* \brief Sets up the http_raw_uri modifier keyword.
*
* \param de_ctx Pointer to the Detection Engine Context.
* \param s Pointer to the Signature to which the current keyword belongs.
* \param arg Should hold an empty string always.
*
* \retval 0 On success.
* \retval -1 On failure.
*/
static int DetectHttpRawUriSetup(DetectEngineCtx *de_ctx, Signature *s, char *arg)
{
DetectContentData *cd = NULL;
SigMatch *sm = NULL;
if (arg != NULL && strcmp(arg, "") != 0) {
SCLogError(SC_ERR_INVALID_ARGUMENT, "http_raw_uri shouldn't be "
"supplied with an argument");
goto error;
}
sm = DetectContentGetLastPattern(s->sm_lists_tail[DETECT_SM_LIST_PMATCH]);
if (sm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "\"http_raw_uri\" keyword "
"found inside the rule without a content context. "
"Please use a \"content\" keyword before using the "
"\"http_raw_uri\" keyword");
goto error;
}
cd = (DetectContentData *)sm->ctx;
/* http_raw_uri should not be used with the rawbytes rule */
if (cd->flags & DETECT_CONTENT_RAWBYTES) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "http_raw_uri rule can not "
"be used with the rawbytes rule keyword");
goto error;
}
if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_HTTP) {
SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains a non http "
"alproto set");
goto error;
}
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 (pm != NULL) */
/* reassigning pm */
pm = SigMatchGetLastSMFromLists(s, 4,
DETECT_AL_HTTP_RAW_URI,
s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH],
DETECT_PCRE,
s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]);
if (pm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "rawuricontent seen with a "
"distance or within without a previous http_raw_uri "
"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_RAW_URI);
sm->type = DETECT_AL_HTTP_RAW_URI;
/* transfer the sm from the pmatch list to hrudmatch list */
SigMatchTransferSigMatchAcrossLists(sm,
&s->sm_lists[DETECT_SM_LIST_PMATCH],
&s->sm_lists_tail[DETECT_SM_LIST_PMATCH],
&s->sm_lists[DETECT_SM_LIST_HRUDMATCH],
&s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]);
/* Flagged the signature as to inspect the app layer data */
s->flags |= SIG_FLAG_APPLAYER;
s->alproto = ALPROTO_HTTP;
return 0;
error:
return -1;
}
/******************************** UNITESTS **********************************/
#ifdef UNITTESTS
#include "stream-tcp-reassemble.h"
/**
* \test Checks if a http_raw_uri is registered in a Signature, if content is not
* specified in the signature.
*/
int DetectHttpRawUriTest01(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
if ( (de_ctx = DetectEngineCtxInit()) == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing http_raw_uri\"; http_raw_uri; sid:1;)");
if (de_ctx->sig_list == NULL)
result = 1;
end:
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
return result;
}
/**
* \test Checks if a http_raw_uri is registered in a Signature, if some parameter
* is specified with http_raw_uri in the signature.
*/
int DetectHttpRawUriTest02(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
if ( (de_ctx = DetectEngineCtxInit()) == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing http_raw_uri\"; content:\"one\"; "
"http_raw_uri:wrong; sid:1;)");
if (de_ctx->sig_list == NULL)
result = 1;
end:
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
return result;
}
/**
* \test Checks if a http_raw_uri is registered in a Signature.
*/
int DetectHttpRawUriTest03(void)
{
SigMatch *sm = NULL;
DetectEngineCtx *de_ctx = NULL;
int result = 0;
if ( (de_ctx = DetectEngineCtxInit()) == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing http_raw_uri\"; "
"content:\"one\"; http_raw_uri; "
"content:\"two\"; http_raw_uri; "
"content:\"three\"; http_raw_uri; "
"sid:1;)");
if (de_ctx->sig_list == NULL) {
printf("sig parse failed: ");
goto end;
}
sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH];
if (sm == NULL) {
printf("no sigmatch(es): ");
goto end;
}
while (sm != NULL) {
if (sm->type == DETECT_AL_HTTP_RAW_URI) {
result = 1;
} else {
printf("expected DETECT_AL_HTTP_RAW_URI(%d), got %d: ",
DETECT_AL_HTTP_RAW_URI, sm->type);
goto end;
}
sm = sm->next;
}
end:
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
return result;
}
/**
* \test Checks if a http_raw_uri is registered in a Signature, when rawbytes is
* also specified in the signature.
*/
int DetectHttpRawUriTest04(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
if ( (de_ctx = DetectEngineCtxInit()) == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing http_raw_uri\"; "
"content:\"one\"; rawbytes; http_raw_uri; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
result = 1;
end:
if (de_ctx != NULL)
SigCleanSignatures(de_ctx);
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
return result;
}
/**
* \test Checks if a http_raw_uri is successfully converted to a rawuricontent.
*
*/
int DetectHttpRawUriTest05(void)
{
DetectEngineCtx *de_ctx = NULL;
Signature *s = NULL;
int result = 0;
if ((de_ctx = DetectEngineCtxInit()) == NULL)
goto end;
s = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing http_raw_uri\"; "
"content:\"we are testing http_raw_uri keyword\"; http_raw_uri; "
"sid:1;)");
if (s == NULL) {
printf("sig failed to parse\n");
goto end;
}
if (s->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL)
goto end;
if (s->sm_lists[DETECT_SM_LIST_HRUDMATCH]->type != DETECT_AL_HTTP_RAW_URI) {
printf("wrong type\n");
goto end;
}
char *str = "we are testing http_raw_uri keyword";
int uricomp = memcmp((const char *)
((DetectContentData*)s->sm_lists[DETECT_SM_LIST_HRUDMATCH]->ctx)->content,
str,
strlen(str) - 1);
int urilen = ((DetectContentData*)s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->ctx)->content_len;
if (uricomp != 0 ||
urilen != strlen("we are testing http_raw_uri keyword")) {
printf("sig failed to parse, content not setup properly\n");
goto end;
}
result = 1;
end:
if (de_ctx != NULL)
SigCleanSignatures(de_ctx);
if (de_ctx != NULL)
SigGroupCleanup(de_ctx);
return result;
}
int DetectHttpRawUriTest06(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
if ( (de_ctx = DetectEngineCtxInit()) == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
"(content:one; content:one; http_raw_uri; sid:1;)");
if (de_ctx->sig_list == NULL) {
printf("de_ctx->sig_list == NULL\n");
goto end;
}
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n");
goto end;
}
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL\n");
goto end;
}
DetectContentData *cd =
de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
DetectContentData *ud =
de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->ctx;
if (cd->id == ud->id)
goto end;
result = 1;
end:
SigCleanSignatures(de_ctx);
DetectEngineCtxFree(de_ctx);
return result;
}
int DetectHttpRawUriTest07(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
if ( (de_ctx = DetectEngineCtxInit()) == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
"(content:one; http_raw_uri; "
"content:one; sid:1;)");
if (de_ctx->sig_list == NULL) {
printf("de_ctx->sig_list == NULL\n");
goto end;
}
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n");
goto end;
}
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL\n");
goto end;
}
DetectContentData *cd =
de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
DetectContentData *ud =
de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->ctx;
if (cd->id == ud->id)
goto end;
result = 1;
end:
SigCleanSignatures(de_ctx);
DetectEngineCtxFree(de_ctx);
return result;
}
int DetectHttpRawUriTest08(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
if ( (de_ctx = DetectEngineCtxInit()) == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
"(content:one; "
"content:one; "
"content:one; http_raw_uri; content:one; "
"sid:1;)");
if (de_ctx->sig_list == NULL) {
printf("de_ctx->sig_list == NULL\n");
goto end;
}
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n");
goto end;
}
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL\n");
goto end;
}
DetectContentData *cd =
de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
DetectContentData *ud =
de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->ctx;
if (cd->id != 0 || ud->id != 1)
goto end;
result = 1;
end:
SigCleanSignatures(de_ctx);
DetectEngineCtxFree(de_ctx);
return result;
}
int DetectHttpRawUriTest09(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
if ( (de_ctx = DetectEngineCtxInit()) == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
"(content:one; http_raw_uri; "
"content:one; "
"content:one; "
"content:one; sid:1;)");
if (de_ctx->sig_list == NULL) {
printf("de_ctx->sig_list == NULL\n");
goto end;
}
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n");
goto end;
}
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL\n");
goto end;
}
DetectContentData *cd =
de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
DetectContentData *ud =
de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->ctx;
if (cd->id != 1 || ud->id != 0)
goto end;
result = 1;
end:
SigCleanSignatures(de_ctx);
DetectEngineCtxFree(de_ctx);
return result;
}
int DetectHttpRawUriTest10(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
if ( (de_ctx = DetectEngineCtxInit()) == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
"(content:one; http_raw_uri; "
"content:one; "
"content:one; http_raw_uri; "
"content:one; sid:1;)");
if (de_ctx->sig_list == NULL) {
printf("de_ctx->sig_list == NULL\n");
goto end;
}
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n");
goto end;
}
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL\n");
goto end;
}
DetectContentData *cd =
de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
DetectContentData *ud1 =
de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->ctx;
DetectContentData *ud2 =
de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->prev->ctx;
if (cd->id != 1 || ud1->id != 0 || ud2->id != 0)
goto end;
result = 1;
end:
SigCleanSignatures(de_ctx);
DetectEngineCtxFree(de_ctx);
return result;
}
int DetectHttpRawUriTest11(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
if ( (de_ctx = DetectEngineCtxInit()) == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
"(content:one; http_raw_uri; "
"content:one; "
"content:one; http_raw_uri; "
"content:two; sid:1;)");
if (de_ctx->sig_list == NULL) {
printf("de_ctx->sig_list == NULL\n");
goto end;
}
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n");
goto end;
}
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL\n");
goto end;
}
DetectContentData *cd =
de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
DetectContentData *ud1 =
de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->ctx;
DetectContentData *ud2 =
de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->prev->ctx;
if (cd->id != 2 || ud1->id != 0 || ud2->id != 0)
goto end;
result = 1;
end:
SigCleanSignatures(de_ctx);
DetectEngineCtxFree(de_ctx);
return result;
}
int DetectHttpRawUriTest12(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
if ( (de_ctx = DetectEngineCtxInit()) == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
"(content:one; http_raw_uri; "
"content:two; distance:0; http_raw_uri; sid:1;)");
if (de_ctx->sig_list == NULL) {
printf("de_ctx->sig_list == NULL\n");
goto end;
}
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
goto end;
}
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL\n");
goto end;
}
DetectContentData *ud1 =
de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->prev->ctx;
DetectContentData *ud2 =
de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->ctx;
if (ud1->flags != DETECT_CONTENT_RELATIVE_NEXT ||
memcmp(ud1->content, "one", ud1->content_len) != 0 ||
ud2->flags != DETECT_CONTENT_DISTANCE ||
memcmp(ud2->content, "two", ud1->content_len) != 0) {
/* inside body */
goto end;
}
result = 1;
end:
SigCleanSignatures(de_ctx);
DetectEngineCtxFree(de_ctx);
return result;
}
int DetectHttpRawUriTest13(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
if ( (de_ctx = DetectEngineCtxInit()) == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
"(content:one; http_raw_uri; "
"content:two; within:5; http_raw_uri; sid:1;)");
if (de_ctx->sig_list == NULL) {
printf("de_ctx->sig_list == NULL\n");
goto end;
}
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
goto end;
}
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL\n");
goto end;
}
DetectContentData *ud1 =
de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->prev->ctx;
DetectContentData *ud2 =
de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->ctx;
if (ud1->flags != DETECT_CONTENT_RELATIVE_NEXT ||
memcmp(ud1->content, "one", ud1->content_len) != 0 ||
ud2->flags != DETECT_CONTENT_WITHIN ||
memcmp(ud2->content, "two", ud1->content_len) != 0) {
/* inside the body */
goto end;
}
result = 1;
end:
SigCleanSignatures(de_ctx);
DetectEngineCtxFree(de_ctx);
return result;
}
int DetectHttpRawUriTest14(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
if ( (de_ctx = DetectEngineCtxInit()) == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
"(content:one; within:5; http_raw_uri; sid:1;)");
if (de_ctx->sig_list != NULL) {
printf("de_ctx->sig_list != NULL\n");
goto end;
}
result = 1;
end:
SigCleanSignatures(de_ctx);
DetectEngineCtxFree(de_ctx);
return result;
}
int DetectHttpRawUriTest15(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
if ( (de_ctx = DetectEngineCtxInit()) == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
"(content:one; http_raw_uri; within:5; sid:1;)");
if (de_ctx->sig_list != NULL) {
printf("de_ctx->sig_list != NULL\n");
goto end;
}
result = 1;
end:
SigCleanSignatures(de_ctx);
DetectEngineCtxFree(de_ctx);
return result;
}
int DetectHttpRawUriTest16(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
if ( (de_ctx = DetectEngineCtxInit()) == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
"(content:one; within:5; sid:1;)");
if (de_ctx->sig_list != NULL) {
printf("de_ctx->sig_list != NULL\n");
goto end;
}
result = 1;
end:
SigCleanSignatures(de_ctx);
DetectEngineCtxFree(de_ctx);
return result;
}
int DetectHttpRawUriTest17(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
if ( (de_ctx = DetectEngineCtxInit()) == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
"(content:one; http_raw_uri; "
"content:two; distance:0; http_raw_uri; sid:1;)");
if (de_ctx->sig_list == NULL) {
printf("de_ctx->sig_list == NULL\n");
goto end;
}
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
goto end;
}
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL\n");
goto end;
}
DetectContentData *ud1 =
de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->prev->ctx;
DetectContentData *ud2 =
de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->ctx;
if (ud1->flags != DETECT_CONTENT_RELATIVE_NEXT ||
memcmp(ud1->content, "one", ud1->content_len) != 0 ||
ud2->flags != DETECT_CONTENT_DISTANCE ||
memcmp(ud2->content, "two", ud1->content_len) != 0) {
/* inside body */
goto end;
}
result = 1;
end:
SigCleanSignatures(de_ctx);
DetectEngineCtxFree(de_ctx);
return result;
}
int DetectHttpRawUriTest18(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
if ( (de_ctx = DetectEngineCtxInit()) == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
"(content:one; http_raw_uri; "
"content:two; within:5; http_raw_uri; "
"sid:1;)");
if (de_ctx->sig_list == NULL) {
printf("de_ctx->sig_list == NULL\n");
goto end;
}
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
goto end;
}
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL\n");
goto end;
}
DetectContentData *ud1 =
de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->prev->ctx;
DetectContentData *ud2 =
de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->ctx;
if (ud1->flags != DETECT_CONTENT_RELATIVE_NEXT ||
memcmp(ud1->content, "one", ud1->content_len) != 0 ||
ud2->flags != DETECT_CONTENT_WITHIN ||
memcmp(ud2->content, "two", ud1->content_len) != 0) {
/* inside body */
goto end;
}
result = 1;
end:
SigCleanSignatures(de_ctx);
DetectEngineCtxFree(de_ctx);
return result;
}
#endif /* UNITTESTS */
/**
* \brief Register the UNITTESTS for the http_uri keyword
*/
static void DetectHttpRawUriRegisterTests (void)
{
#ifdef UNITTESTS /* UNITTESTS */
UtRegisterTest("DetectHttpRawUriTest01", DetectHttpRawUriTest01, 1);
UtRegisterTest("DetectHttpRawUriTest02", DetectHttpRawUriTest02, 1);
UtRegisterTest("DetectHttpRawUriTest03", DetectHttpRawUriTest03, 1);
UtRegisterTest("DetectHttpRawUriTest04", DetectHttpRawUriTest04, 1);
UtRegisterTest("DetectHttpRawUriTest05", DetectHttpRawUriTest05, 1);
UtRegisterTest("DetectHttpRawUriTest06", DetectHttpRawUriTest06, 1);
UtRegisterTest("DetectHttpRawUriTest07", DetectHttpRawUriTest07, 1);
UtRegisterTest("DetectHttpRawUriTest08", DetectHttpRawUriTest08, 1);
UtRegisterTest("DetectHttpRawUriTest09", DetectHttpRawUriTest09, 1);
UtRegisterTest("DetectHttpRawUriTest10", DetectHttpRawUriTest10, 1);
UtRegisterTest("DetectHttpRawUriTest11", DetectHttpRawUriTest11, 1);
UtRegisterTest("DetectHttpRawUriTest12", DetectHttpRawUriTest12, 1);
UtRegisterTest("DetectHttpRawUriTest13", DetectHttpRawUriTest13, 1);
UtRegisterTest("DetectHttpRawUriTest14", DetectHttpRawUriTest14, 1);
UtRegisterTest("DetectHttpRawUriTest15", DetectHttpRawUriTest15, 1);
UtRegisterTest("DetectHttpRawUriTest16", DetectHttpRawUriTest16, 1);
UtRegisterTest("DetectHttpRawUriTest17", DetectHttpRawUriTest17, 1);
UtRegisterTest("DetectHttpRawUriTest18", DetectHttpRawUriTest18, 1);
#endif /* UNITTESTS */
return;
}

@ -0,0 +1,30 @@
/* 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 <poonaatsoc@gmail.com>
*
*/
#ifndef __DETECT_HTTP_URI_H__
#define __DETECT_HTTP_URI_H__
void DetectHttpRawUriRegister(void);
#endif /* __DETECT_HTTP_URI_H__ */

@ -280,28 +280,30 @@ int DetectIsdataatSetup (DetectEngineCtx *de_ctx, Signature *s, char *isdataatst
DETECT_BYTEJUMP, sm->prev,
DETECT_PCRE, sm->prev);
} else {
pm = SigMatchGetLastSMFromLists(s, 30,
DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH],
pm = SigMatchGetLastSMFromLists(s, 34,
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],
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_RAW_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], /* 5 */
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_PCRE, s->sm_lists_tail[DETECT_SM_LIST_PMATCH],
DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_UMATCH],
DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], /* 10 */
DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH],
DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH],
DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH],
DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH],
DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH],
DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], /* 15 */
DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH],
DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_PMATCH]);
if (pm == NULL) {
if (idad->flags & ISDATAAT_RELATIVE) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "isdataat relative seen "
"without a previous content uricontent, "
"http_client_body, http_header, http_raw_header, "
"http_method or http_cookie keyword");
"http_method, http_cookie or http_raw_uri keyword");
goto error;
} else {
SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_PMATCH);
@ -333,6 +335,9 @@ int DetectIsdataatSetup (DetectEngineCtx *de_ctx, Signature *s, char *isdataatst
case DETECT_AL_HTTP_COOKIE:
list_type = DETECT_SM_LIST_HCDMATCH;
break;
case DETECT_AL_HTTP_RAW_URI:
list_type = DETECT_SM_LIST_HRUDMATCH;
break;
default:
/* would never happen */
break;
@ -360,7 +365,8 @@ int DetectIsdataatSetup (DetectEngineCtx *de_ctx, Signature *s, char *isdataatst
} else {
SCLogError(SC_ERR_INVALID_SIGNATURE, "No preceding content, pcre, "
"uricontent, http_client_body, http_header, "
"http_raw_header, http_method or http_cookie keyword");
"http_raw_header, http_method, http_cookie or "
"http_raw_uri keyword");
goto error;
}
}
@ -376,6 +382,7 @@ int DetectIsdataatSetup (DetectEngineCtx *de_ctx, Signature *s, char *isdataatst
case DETECT_AL_HTTP_RAW_HEADER:
case DETECT_AL_HTTP_METHOD:
case DETECT_AL_HTTP_COOKIE:
case DETECT_AL_HTTP_RAW_URI:
/* Set the relative next flag on the prev sigmatch */
cd = (DetectContentData *)prev_pm->ctx;
if (cd == NULL) {

@ -181,17 +181,19 @@ static int DetectNocaseSetup (DetectEngineCtx *de_ctx, Signature *s, char *nulls
/* Search for the first previous SigMatch that supports nocase */
//SigMatch *pm = SigMatchGetLastNocasePattern(s);
SigMatch *pm = SigMatchGetLastSMFromLists(s, 14,
SigMatch *pm = SigMatchGetLastSMFromLists(s, 16,
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],
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_RAW_URI, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH],
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_header, http_method, http_uri, http_cookie option");
SCLogError(SC_ERR_NOCASE_MISSING_PATTERN, "\"nocase\" needs a preceeding "
"content, uricontent, http_client_body, http_header, "
"http_method, http_uri, http_cookie or http_raw_uri option");
SCReturnInt(-1);
}
@ -202,6 +204,7 @@ static int DetectNocaseSetup (DetectEngineCtx *de_ctx, Signature *s, char *nulls
DetectContentData *dhhd = NULL;
DetectContentData *dhrhd = NULL;
DetectContentData *dhmd = NULL;
DetectContentData *dhrud = NULL;
switch (pm->type) {
case DETECT_URICONTENT:
@ -247,10 +250,16 @@ static int DetectNocaseSetup (DetectEngineCtx *de_ctx, Signature *s, char *nulls
dhcd = (DetectContentData *) pm->ctx;
dhcd->flags |= DETECT_CONTENT_NOCASE;
break;
case DETECT_AL_HTTP_RAW_URI:
dhrud = (DetectContentData *) pm->ctx;
dhrud->flags |= DETECT_CONTENT_NOCASE;
break;
/* should never happen */
default:
SCLogError(SC_ERR_NOCASE_MISSING_PATTERN, "\"nocase\" needs a"
" preceeding content, uricontent, http_client_body or http_cookie option");
" preceeding content, uricontent, http_client_body "
"http_header, http_raw_header, http_method, "
"http_cookie, http_raw_uri option");
SCReturnInt(-1);
break;
}

@ -82,19 +82,20 @@ int DetectOffsetSetup (DetectEngineCtx *de_ctx, Signature *s, char *offsetstr)
break;
default:
pm = SigMatchGetLastSMFromLists(s, 14,
pm = SigMatchGetLastSMFromLists(s, 16,
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],
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_RAW_URI, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]);
if (pm == NULL) {
SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "offset needs"
"preceeding content or uricontent option, http_client_body "
"http_header, http_raw_header, http_method or "
"http_cookie option");
"http_header, http_raw_header, http_method, "
"http_cookie or http_raw_uri option");
if (dubbed)
SCFree(str);
return -1;
@ -338,6 +339,37 @@ int DetectOffsetSetup (DetectEngineCtx *de_ctx, Signature *s, char *offsetstr)
break;
case DETECT_AL_HTTP_RAW_URI:
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;
}
}
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");

@ -1441,6 +1441,8 @@ Signature *SigInit(DetectEngineCtx *de_ctx, char *sigstr) {
sig->flags |= SIG_FLAG_STATE_MATCH;
if (sig->sm_lists[DETECT_SM_LIST_HCDMATCH])
sig->flags |= SIG_FLAG_STATE_MATCH;
if (sig->sm_lists[DETECT_SM_LIST_HRUDMATCH])
sig->flags |= SIG_FLAG_STATE_MATCH;
SCLogDebug("sig %"PRIu32" SIG_FLAG_APPLAYER: %s, SIG_FLAG_PACKET: %s",
sig->id, sig->flags & SIG_FLAG_APPLAYER ? "set" : "not set",

@ -842,6 +842,9 @@ DetectPcreData *DetectPcreParse (char *regexstr)
case 'H': /* snort's option */
pd->flags |= DETECT_PCRE_HEADER;
break;
case 'I': /* snort's option */
pd->flags |= DETECT_PCRE_HTTP_RAW_URI;
break;
case 'D': /* snort's option */
pd->flags |= DETECT_PCRE_RAW_HEADER;
break;
@ -1004,7 +1007,8 @@ 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_BODY_AL) ) {
(pd->flags & DETECT_PCRE_HTTP_BODY_AL) ||
(pd->flags & DETECT_PCRE_HTTP_RAW_URI) ) {
SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "Invalid option. "
"DCERPC rule has pcre keyword with http related modifier.");
goto error;
@ -1068,6 +1072,16 @@ static int DetectPcreSetup (DetectEngineCtx *de_ctx, Signature *s, char *regexst
s->alproto = ALPROTO_HTTP;
SigMatchAppendUricontent(s, sm);
} else if (pd->flags & DETECT_PCRE_HTTP_RAW_URI) {
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_HRUDMATCH);
} else {
if (s->alproto == ALPROTO_DCERPC && pd->flags & DETECT_PCRE_RELATIVE) {
SigMatch *pm = NULL;
@ -1100,12 +1114,13 @@ static int DetectPcreSetup (DetectEngineCtx *de_ctx, Signature *s, char *regexst
SCReturnInt(0);
}
prev_sm = SigMatchGetLastSMFromLists(s, 12,
prev_sm = SigMatchGetLastSMFromLists(s, 14,
DETECT_CONTENT, sm->prev,
DETECT_URICONTENT, sm->prev,
DETECT_AL_HTTP_CLIENT_BODY, sm->prev,
DETECT_AL_HTTP_HEADER, sm->prev,
DETECT_AL_HTTP_RAW_HEADER, sm->prev,
DETECT_AL_HTTP_RAW_URI, sm->prev,
DETECT_PCRE, sm->prev);
if (prev_sm == NULL) {
if (s->alproto == ALPROTO_DCERPC) {
@ -1128,6 +1143,7 @@ static int DetectPcreSetup (DetectEngineCtx *de_ctx, Signature *s, char *regexst
case DETECT_AL_HTTP_CLIENT_BODY:
case DETECT_AL_HTTP_HEADER:
case DETECT_AL_HTTP_RAW_HEADER:
case DETECT_AL_HTTP_RAW_URI:
/* Set the relative next flag on the prev sigmatch */
cd = (DetectContentData *)prev_sm->ctx;
if (cd == NULL) {

@ -40,8 +40,9 @@
#define DETECT_PCRE_RAW_HEADER 0x0200
#define DETECT_PCRE_COOKIE 0x0400
#define DETECT_PCRE_METHOD 0x0800
#define DETECT_PCRE_HTTP_RAW_URI 0x1000
#define DETECT_PCRE_NEGATE 0x1000
#define DETECT_PCRE_NEGATE 0x2000
typedef struct DetectPcreData_ {
/* pcre options */

@ -171,19 +171,20 @@ static int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, char *withi
}
}
} else {
pm = SigMatchGetLastSMFromLists(s, 14,
pm = SigMatchGetLastSMFromLists(s, 16,
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],
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_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_header, http_raw_header, http_method or "
"http_cookie option");
"http_header, http_raw_header, http_method, "
"http_cookie or http_raw_uri option");
if (dubbed)
SCFree(str);
return -1;
@ -665,6 +666,60 @@ static int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, char *withi
break;
case DETECT_AL_HTTP_RAW_URI:
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;
}
}
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_RAW_URI, pm->prev,
DETECT_PCRE, pm->prev);
if (pm == NULL) {
SCLogError(SC_ERR_DISTANCE_MISSING_CONTENT, "distance for http_raw_uri "
"needs preceeding http_cookie 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");

@ -114,12 +114,14 @@
#include "detect-http-header.h"
#include "detect-http-raw-header.h"
#include "detect-http-uri.h"
#include "detect-http-raw-uri.h"
#include "detect-http-stat-msg.h"
#include "detect-engine-hcbd.h"
#include "detect-engine-hhd.h"
#include "detect-engine-hrhd.h"
#include "detect-engine-hmd.h"
#include "detect-engine-hcd.h"
#include "detect-engine-hrud.h"
#include "util-rule-vars.h"
@ -831,6 +833,16 @@ static void SigMatchSignaturesBuildMatchArray(DetectEngineCtx *de_ctx,
}
}
}
if (s->flags & SIG_FLAG_MPM_HRUDCONTENT) {
if (!(det_ctx->pmq.pattern_id_bitarray[(s->mpm_http_pattern_id / 8)] &
(1 << (s->mpm_http_pattern_id % 8)))) {
if (!(s->flags & SIG_FLAG_MPM_HRUDCONTENT_NEG)) {
continue;
}
}
}
/* de_state check, filter out all signatures that already had a match before
* or just partially match */
if (s->flags & SIG_FLAG_STATE_MATCH) {
@ -1073,6 +1085,10 @@ static inline void DetectMpmPrefilter(DetectEngineCtx *de_ctx,
cnt = DetectEngineRunHttpCookieMpm(det_ctx, p->flow, alstate);
SCLogDebug("hcd search: cnt %" PRIu32, cnt);
}
if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HRUD) {
cnt = DetectEngineRunHttpRawUriMpm(det_ctx, p->flow, alstate);
SCLogDebug("hrud search: cnt %" PRIu32, cnt);
}
}
} else {
SCLogDebug("NOT p->flowflags & FLOW_PKT_ESTABLISHED");
@ -1719,6 +1735,9 @@ int SignatureIsIPOnly(DetectEngineCtx *de_ctx, Signature *s) {
if (s->sm_lists[DETECT_SM_LIST_HCDMATCH] != NULL)
return 0;
if (s->sm_lists[DETECT_SM_LIST_HRUDMATCH] != NULL)
return 0;
if (s->sm_lists[DETECT_SM_LIST_AMATCH] != NULL)
return 0;
@ -1789,7 +1808,8 @@ static int SignatureIsDEOnly(DetectEngineCtx *de_ctx, Signature *s) {
s->sm_lists[DETECT_SM_LIST_HHDMATCH] != NULL ||
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_HCDMATCH] != NULL ||
s->sm_lists[DETECT_SM_LIST_HRUDMATCH] != NULL)
{
SCReturnInt(0);
}
@ -1901,6 +1921,11 @@ static int SignatureCreateMask(Signature *s) {
SCLogDebug("sig requires http app state");
}
if (s->sm_lists[DETECT_SM_LIST_HRUDMATCH] != 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) {
@ -1909,7 +1934,9 @@ static int SignatureCreateMask(Signature *s) {
case DETECT_AL_URILEN:
case DETECT_AL_HTTP_CLIENT_BODY:
case DETECT_AL_HTTP_HEADER:
case DETECT_AL_HTTP_RAW_HEADER:
case DETECT_AL_HTTP_URI:
case DETECT_AL_HTTP_RAW_URI:
case DETECT_PCRE_HTTPBODY:
case DETECT_PCRE_HTTPCOOKIE:
case DETECT_PCRE_HTTPHEADER:
@ -1995,6 +2022,9 @@ static void SigInitStandardMpmFactoryContexts(DetectEngineCtx *de_ctx)
de_ctx->sgh_mpm_context_hcd =
MpmFactoryRegisterMpmCtxProfile("hcd",
MPM_CTX_FACTORY_FLAGS_PREPARE_WITH_SIG_GROUP_BUILD);
de_ctx->sgh_mpm_context_hrud =
MpmFactoryRegisterMpmCtxProfile("hrud",
MPM_CTX_FACTORY_FLAGS_PREPARE_WITH_SIG_GROUP_BUILD);
de_ctx->sgh_mpm_context_app_proto_detect =
MpmFactoryRegisterMpmCtxProfile("app_proto_detect", 0);
@ -3892,6 +3922,12 @@ int SigGroupBuild (DetectEngineCtx *de_ctx) {
}
//printf("hcd- %d\n", mpm_ctx->pattern_cnt);
mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx->sgh_mpm_context_hrud);
if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) {
mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx);
}
//printf("hrud- %d\n", mpm_ctx->pattern_cnt);
mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx->sgh_mpm_context_stream);
if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) {
mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx);
@ -3985,6 +4021,7 @@ void SigTableSetup(void) {
DetectHttpRawHeaderRegister();
DetectHttpClientBodyRegister();
DetectHttpUriRegister();
DetectHttpRawUriRegister();
DetectAsn1Register();
DetectSshVersionRegister();
DetectSslStateRegister();

@ -83,6 +83,7 @@ struct SCSigSignatureWrapper_;
enum {
DETECT_SM_LIST_MATCH = 0,
DETECT_SM_LIST_PMATCH,
/* list for http_uri keyword and the ones relative to it */
DETECT_SM_LIST_UMATCH,
DETECT_SM_LIST_AMATCH,
DETECT_SM_LIST_DMATCH,
@ -97,6 +98,8 @@ enum {
DETECT_SM_LIST_HMDMATCH,
/* list for http_cookie keyword and the ones relative to it */
DETECT_SM_LIST_HCDMATCH,
/* list for http_raw_uri keyword and the ones relative to it */
DETECT_SM_LIST_HRUDMATCH,
DETECT_SM_LIST_MAX,
};
@ -253,7 +256,10 @@ typedef struct DetectPort_ {
#define SIG_FLAG_MPM_HCDCONTENT 0x08000000
#define SIG_FLAG_MPM_HCDCONTENT_NEG 0x10000000
#define SIG_FLAG_REQUIRE_FLOWVAR 0x20000000 /**< signature can only match if a flowbit, flowvar or flowint is available. */
#define SIG_FLAG_MPM_HRUDCONTENT 0x20000000
#define SIG_FLAG_MPM_HRUDCONTENT_NEG 0x40000000
#define SIG_FLAG_REQUIRE_FLOWVAR 0x80000000 /**< signature can only match if a flowbit, flowvar or flowint is available. */
/* signature init flags */
#define SIG_FLAG_DEONLY 0x00000001 /**< decode event only signature */
@ -661,6 +667,7 @@ typedef struct DetectEngineCtx_ {
int32_t sgh_mpm_context_hrhd;
int32_t sgh_mpm_context_hmd;
int32_t sgh_mpm_context_hcd;
int32_t sgh_mpm_context_hrud;
int32_t sgh_mpm_context_app_proto_detect;
/** sgh for signatures that match against invalid packets. In those cases
@ -819,19 +826,21 @@ typedef struct SigTableElmt_ {
#define SIG_GROUP_HAVEHRHDCONTENT 0x00000020
#define SIG_GROUP_HAVEHMDCONTENT 0x00000040
#define SIG_GROUP_HAVEHCDCONTENT 0x00000080
#define SIG_GROUP_HEAD_MPM_COPY 0x00000100
#define SIG_GROUP_HEAD_MPM_URI_COPY 0x00000200
#define SIG_GROUP_HEAD_MPM_STREAM_COPY 0x00000400
#define SIG_GROUP_HEAD_FREE 0x00000800
#define SIG_GROUP_HEAD_MPM_PACKET 0x00001000
#define SIG_GROUP_HEAD_MPM_STREAM 0x00002000
#define SIG_GROUP_HEAD_MPM_URI 0x00004000
#define SIG_GROUP_HEAD_MPM_HCBD 0x00008000
#define SIG_GROUP_HEAD_MPM_HHD 0x00010000
#define SIG_GROUP_HEAD_MPM_HRHD 0x00020000
#define SIG_GROUP_HEAD_MPM_HMD 0x00040000
#define SIG_GROUP_HEAD_MPM_HCD 0x00080000
#define SIG_GROUP_HEAD_REFERENCED 0x00100000 /**< sgh is being referenced by others, don't clear */
#define SIG_GROUP_HAVEHRUDCONTENT 0x00000100
#define SIG_GROUP_HEAD_MPM_COPY 0x00000200
#define SIG_GROUP_HEAD_MPM_URI_COPY 0x00000400
#define SIG_GROUP_HEAD_MPM_STREAM_COPY 0x00000800
#define SIG_GROUP_HEAD_FREE 0x00001000
#define SIG_GROUP_HEAD_MPM_PACKET 0x00002000
#define SIG_GROUP_HEAD_MPM_STREAM 0x00004000
#define SIG_GROUP_HEAD_MPM_URI 0x00008000
#define SIG_GROUP_HEAD_MPM_HCBD 0x00010000
#define SIG_GROUP_HEAD_MPM_HHD 0x00020000
#define SIG_GROUP_HEAD_MPM_HRHD 0x00040000
#define SIG_GROUP_HEAD_MPM_HMD 0x00080000
#define SIG_GROUP_HEAD_MPM_HCD 0x00100000
#define SIG_GROUP_HEAD_MPM_HRUD 0x00200000
#define SIG_GROUP_HEAD_REFERENCED 0x00400000 /**< sgh is being referenced by others, don't clear */
typedef struct SigGroupHeadInitData_ {
/* list of content containers
@ -877,6 +886,7 @@ typedef struct SigGroupHead_ {
MpmCtx *mpm_hrhd_ctx;
MpmCtx *mpm_hmd_ctx;
MpmCtx *mpm_hcd_ctx;
MpmCtx *mpm_hrud_ctx;
uint16_t mpm_streamcontent_maxlen;
uint16_t mpm_uricontent_maxlen;
@ -980,6 +990,7 @@ enum {
DETECT_AL_HTTP_HEADER,
DETECT_AL_HTTP_RAW_HEADER,
DETECT_AL_HTTP_URI,
DETECT_AL_HTTP_RAW_URI,
DETECT_AL_HTTP_STAT_MSG,
DETECT_AL_HTTP_STAT_CODE,
DETECT_AL_SSH_PROTOVERSION,

@ -59,6 +59,7 @@
#include "detect-engine-hrhd.h"
#include "detect-engine-hmd.h"
#include "detect-engine-hcd.h"
#include "detect-engine-hrud.h"
#include "detect-engine-state.h"
#include "detect-engine-tag.h"
#include "detect-fast-pattern.h"
@ -1168,6 +1169,7 @@ int main(int argc, char **argv)
DetectEngineHttpRawHeaderRegisterTests();
DetectEngineHttpMethodRegisterTests();
DetectEngineHttpCookieRegisterTests();
DetectEngineHttpRawUriRegisterTests();
DetectEngineRegisterTests();
SCLogRegisterTests();
if (list_unittests) {

Loading…
Cancel
Save