modify detection engine to carry out uri mpm run before build match array if alproto is http and if sgh has atleast one sig with uri mpm set

remotes/origin/master-1.1.x
Anoop Saldanha 15 years ago committed by Victor Julien
parent 6648d1faf0
commit 72b0fcf419

@ -191,14 +191,12 @@ uint16_t PatternMatchDefaultMatcher(void) {
/** \brief Pattern match -- searches for only one pattern per signature.
*
* \param tv threadvars
* \param det_ctx detection engine thread ctx
* \param p packet to inspect
*
* \retval ret number of matches
*/
uint32_t PacketPatternSearch(ThreadVars *tv, DetectEngineThreadCtx *det_ctx,
Packet *p)
uint32_t PacketPatternSearch(DetectEngineThreadCtx *det_ctx, Packet *p)
{
SCEnter();
@ -340,7 +338,6 @@ uint32_t HttpRawHeaderPatternSearch(DetectEngineThreadCtx *det_ctx,
/** \brief Pattern match -- searches for only one pattern per signature.
*
* \param tv threadvars
* \param det_ctx detection engine thread ctx
* \param p packet
* \param smsg stream msg (reassembled stream data)
@ -348,8 +345,8 @@ uint32_t HttpRawHeaderPatternSearch(DetectEngineThreadCtx *det_ctx,
*
* \retval ret number of matches
*/
uint32_t StreamPatternSearch(ThreadVars *tv, DetectEngineThreadCtx *det_ctx,
Packet *p, StreamMsg *smsg, uint8_t flags)
uint32_t StreamPatternSearch(DetectEngineThreadCtx *det_ctx, Packet *p,
StreamMsg *smsg, uint8_t flags)
{
SCEnter();
@ -751,6 +748,12 @@ static void PopulateMpmAddPatternToMpm(DetectEngineCtx *de_ctx,
}
}
}
if (SignatureHasPacketContent(s)) {
sgh->flags |= SIG_GROUP_HEAD_MPM_PACKET;
}
if (SignatureHasStreamContent(s)) {
sgh->flags |= SIG_GROUP_HEAD_MPM_STREAM;
}
break;
} /* case DETECT_CONTENT */
@ -804,6 +807,8 @@ static void PopulateMpmAddPatternToMpm(DetectEngineCtx *de_ctx,
if (ud->flags & DETECT_CONTENT_NEGATED)
s->flags |= SIG_FLAG_MPM_URICONTENT_NEG;
sgh->flags |= SIG_GROUP_HEAD_MPM_URI;
break;
} /* case DETECT_URICONTENT */
@ -857,6 +862,8 @@ static void PopulateMpmAddPatternToMpm(DetectEngineCtx *de_ctx,
if (hcbd->flags & DETECT_CONTENT_NEGATED)
s->mpm_flags |= SIG_FLAG_MPM_HCBDCONTENT_NEG;
sgh->flags |= SIG_GROUP_HEAD_MPM_HCBD;
break;
} /* case DETECT_AL_HTTP_CLIENT_BODY */
@ -910,6 +917,8 @@ static void PopulateMpmAddPatternToMpm(DetectEngineCtx *de_ctx,
if (hhd->flags & DETECT_CONTENT_NEGATED)
s->mpm_flags |= SIG_FLAG_MPM_HHDCONTENT_NEG;
sgh->flags |= SIG_GROUP_HEAD_MPM_HHD;
break;
} /* case DETECT_AL_HTTP_HEADER */
@ -963,6 +972,8 @@ static void PopulateMpmAddPatternToMpm(DetectEngineCtx *de_ctx,
if (hrhd->flags & DETECT_CONTENT_NEGATED)
s->mpm_flags |= SIG_FLAG_MPM_HRHDCONTENT_NEG;
sgh->flags |= SIG_GROUP_HEAD_MPM_HRHD;
break;
} /* case DETECT_AL_HTTP_RAW_HEADER */

@ -33,9 +33,9 @@
uint16_t PatternMatchDefaultMatcher(void);
uint32_t PacketPatternSearch(ThreadVars *, DetectEngineThreadCtx *, Packet *);
uint32_t PacketPatternSearch(DetectEngineThreadCtx *, Packet *);
uint32_t UriPatternSearch(DetectEngineThreadCtx *, uint8_t *, uint16_t);
uint32_t StreamPatternSearch(ThreadVars *, DetectEngineThreadCtx *, Packet *, StreamMsg *, uint8_t);
uint32_t StreamPatternSearch(DetectEngineThreadCtx *, Packet *, StreamMsg *, uint8_t);
uint32_t HttpClientBodyPatternSearch(DetectEngineThreadCtx *, uint8_t *, uint32_t);
uint32_t HttpHeaderPatternSearch(DetectEngineThreadCtx *, uint8_t *, uint32_t);
uint32_t HttpRawHeaderPatternSearch(DetectEngineThreadCtx *, uint8_t *, uint32_t);

@ -195,15 +195,15 @@ static int DoInspectPacketUri(DetectEngineCtx *de_ctx,
//PrintawDataFp(stdout,ud->content,ud->content_len);
/* If we got no matches from the mpm, avoid searching (just check if negated) */
if (det_ctx->de_have_httpuri == TRUE) {
//if (det_ctx->de_have_httpuri == TRUE) {
/* do the actual search with boyer moore precooked ctx */
if (ud->flags & DETECT_CONTENT_NOCASE)
found = BoyerMooreNocase(ud->content, ud->content_len, spayload, spayload_len, ud->bm_ctx->bmGs, ud->bm_ctx->bmBc);
else
found = BoyerMoore(ud->content, ud->content_len, spayload, spayload_len, ud->bm_ctx->bmGs, ud->bm_ctx->bmBc);
} else {
found = NULL;
}
//} else {
// found = NULL;
//}
/* next we evaluate the result in combination with the
* negation flag. */
@ -377,47 +377,47 @@ int DetectEngineInspectPacketUris(DetectEngineCtx *de_ctx,
goto end;
}
det_ctx->de_have_httpuri = TRUE;
/* If we have the uricontent multi pattern matcher signatures in
signature list, then search the received HTTP uri(s) in the htp
state against those patterns */
if (s->flags & SIG_FLAG_MPM_URICONTENT) {
if (det_ctx->de_mpm_scanned_uri == FALSE) {
uint32_t cnt = DetectUricontentInspectMpm(det_ctx, f, htp_state);
/* only consider uri sigs if we've seen at least one match */
/** \warning when we start supporting negated uri content matches
* we need to update this check as well */
if (cnt <= 0) {
det_ctx->de_have_httpuri = FALSE;
}
SCLogDebug("uricontent cnt %"PRIu32"", cnt);
/* make sure we don't inspect this mpm again */
det_ctx->de_mpm_scanned_uri = TRUE;
}
}
//det_ctx->de_have_httpuri = TRUE;
///* If we have the uricontent multi pattern matcher signatures in
// signature list, then search the received HTTP uri(s) in the htp
// state against those patterns */
//if (s->flags & SIG_FLAG_MPM_URICONTENT) {
// if (det_ctx->de_mpm_scanned_uri == FALSE) {
// uint32_t cnt = DetectUricontentInspectMpm(det_ctx, f, htp_state);
//
// /* only consider uri sigs if we've seen at least one match */
// /** \warning when we start supporting negated uri content matches
// * we need to update this check as well */
// if (cnt <= 0) {
// det_ctx->de_have_httpuri = FALSE;
// }
//
// SCLogDebug("uricontent cnt %"PRIu32"", cnt);
//
// /* make sure we don't inspect this mpm again */
// det_ctx->de_mpm_scanned_uri = TRUE;
//
// }
//}
/* if we don't have a uri, don't bother inspecting */
if (det_ctx->de_have_httpuri == FALSE && !(s->flags & SIG_FLAG_MPM_URICONTENT_NEG)) {
SCLogDebug("We don't have uri");
goto end;
}
if ((s->flags & SIG_FLAG_MPM_URICONTENT) && (det_ctx->de_mpm_scanned_uri == TRUE)) {
if (det_ctx->pmq.pattern_id_bitarray != NULL) {
/* filter out sigs that want pattern matches, but
* have no matches */
if (!(det_ctx->pmq.pattern_id_bitarray[(s->mpm_uripattern_id / 8)] & (1<<(s->mpm_uripattern_id % 8))) &&
(s->flags & SIG_FLAG_MPM_URICONTENT) && !(s->flags & SIG_FLAG_MPM_URICONTENT_NEG)) {
SCLogDebug("mpm sig without matches (pat id %"PRIu32
" check in uri).", s->mpm_uripattern_id);
goto end;
}
}
}
//if (det_ctx->de_have_httpuri == FALSE && !(s->flags & SIG_FLAG_MPM_URICONTENT_NEG)) {
// SCLogDebug("We don't have uri");
// goto end;
//}
//
//if ((s->flags & SIG_FLAG_MPM_URICONTENT) && (det_ctx->de_mpm_scanned_uri == TRUE)) {
// if (det_ctx->pmq.pattern_id_bitarray != NULL) {
// /* filter out sigs that want pattern matches, but
// * have no matches */
// if (!(det_ctx->pmq.pattern_id_bitarray[(s->mpm_uripattern_id / 8)] & (1<<(s->mpm_uripattern_id % 8))) &&
// (s->flags & SIG_FLAG_MPM_URICONTENT) && !(s->flags & SIG_FLAG_MPM_URICONTENT_NEG)) {
// SCLogDebug("mpm sig without matches (pat id %"PRIu32
// " check in uri).", s->mpm_uripattern_id);
// goto end;
// }
// }
//}
sm = s->sm_lists[DETECT_SM_LIST_UMATCH];

@ -527,7 +527,7 @@ int DetectFastPatternTest05(void)
/* start the search phase */
det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p);
if (PacketPatternSearch(&th_v, det_ctx, p) != 0)
if (PacketPatternSearch(det_ctx, p) != 0)
result = 1;
SigGroupCleanup(de_ctx);
@ -577,7 +577,7 @@ int DetectFastPatternTest06(void)
/* start the search phase */
det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p);
if (PacketPatternSearch(&th_v, det_ctx, p) != 0)
if (PacketPatternSearch(det_ctx, p) != 0)
result = 1;
SigGroupCleanup(de_ctx);
@ -628,7 +628,7 @@ int DetectFastPatternTest07(void)
/* start the search phase */
det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p);
if (PacketPatternSearch(&th_v, det_ctx, p) == 0)
if (PacketPatternSearch(det_ctx, p) == 0)
result = 1;
SigGroupCleanup(de_ctx);
@ -683,7 +683,7 @@ int DetectFastPatternTest08(void)
/* start the search phase */
det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p);
uint32_t r = PacketPatternSearch(&th_v, det_ctx, p);
uint32_t r = PacketPatternSearch(det_ctx, p);
if (r != 1) {
printf("expected 1, got %"PRIu32": ", r);
goto end;
@ -735,7 +735,7 @@ int DetectFastPatternTest09(void)
/* start the search phase */
det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p);
if (PacketPatternSearch(&th_v, det_ctx, p) == 0)
if (PacketPatternSearch(det_ctx, p) == 0)
result = 1;
SigGroupCleanup(de_ctx);
@ -791,7 +791,7 @@ int DetectFastPatternTest10(void)
/* start the search phase */
det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p);
uint32_t r = PacketPatternSearch(&th_v, det_ctx, p);
uint32_t r = PacketPatternSearch(det_ctx, p);
if (r != 1) {
printf("expected 1, got %"PRIu32": ", r);
goto end;
@ -845,7 +845,7 @@ int DetectFastPatternTest11(void)
/* start the search phase */
det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p);
if (PacketPatternSearch(&th_v, det_ctx, p) == 0)
if (PacketPatternSearch(det_ctx, p) == 0)
result = 1;
@ -897,7 +897,7 @@ int DetectFastPatternTest12(void)
/* start the search phase */
det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p);
if (PacketPatternSearch(&th_v, det_ctx, p) == 0)
if (PacketPatternSearch(det_ctx, p) == 0)
result = 1;
SigGroupCleanup(de_ctx);
@ -954,7 +954,7 @@ int DetectFastPatternTest13(void)
/* start the search phase */
det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p);
uint32_t r = PacketPatternSearch(&th_v, det_ctx, p);
uint32_t r = PacketPatternSearch(det_ctx, p);
if (r != 1) {
printf("expected 1 result, got %"PRIu32": ", r);
goto end;

@ -692,6 +692,15 @@ static void SigMatchSignaturesBuildMatchArray(DetectEngineCtx *de_ctx,
}
}
if (s->full_sig->flags & SIG_FLAG_MPM_URICONTENT) {
if (!(det_ctx->pmq.pattern_id_bitarray[(s->full_sig->mpm_uripattern_id / 8)] &
(1 << (s->full_sig->mpm_uripattern_id % 8)))) {
if (!(s->full_sig->flags & SIG_FLAG_MPM_URICONTENT_NEG)) {
continue;
}
}
}
/* de_state check, filter out all signatures that already had a match before
* or just partially match */
if (s->flags & SIG_FLAG_AMATCH || s->flags & SIG_FLAG_UMATCH ||
@ -863,6 +872,71 @@ end:
#define SMS_USED_PM 0x02
#define SMS_USED_STREAM_PM 0x04
static inline void RunMpmsOnFlow(DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx,
StreamMsg *smsg, Packet *p, uint8_t flags,
uint16_t alproto, void *alstate,
uint8_t *sms_runflags)
{
uint32_t cnt = 0;
/* have a look at the reassembled stream (if any) */
if (p->flowflags & FLOW_PKT_ESTABLISHED) {
SCLogDebug("p->flowflags & FLOW_PKT_ESTABLISHED");
if (smsg != NULL && det_ctx->sgh->mpm_stream_ctx != NULL) {
cnt = StreamPatternSearch(det_ctx, p, smsg, flags);
SCLogDebug("Stream Mpm cnt %u", cnt);
*sms_runflags |= SMS_USED_STREAM_PM;
} else {
SCLogDebug("smsg NULL (%p) or det_ctx->sgh->mpm_stream_ctx "
"NULL (%p)", smsg, det_ctx->sgh->mpm_stream_ctx);
}
} else {
SCLogDebug("NOT p->flowflags & FLOW_PKT_ESTABLISHED");
}
if (p->payload_len > 0 && det_ctx->sgh->mpm_ctx != NULL &&
(!(p->flags & PKT_NOPAYLOAD_INSPECTION) && !(p->flags & PKT_STREAM_ADD))) {
/* run the multi packet matcher against the payload of the packet */
if (det_ctx->sgh->mpm_content_maxlen > p->payload_len) {
SCLogDebug("not mpm-inspecting as pkt payload is smaller than "
"the largest content length we need to match");
} else {
SCLogDebug("search: (%p, maxlen %" PRIu32 ", sgh->sig_cnt %" PRIu32 ")",
det_ctx->sgh, det_ctx->sgh->mpm_content_maxlen, det_ctx->sgh->sig_cnt);
cnt = PacketPatternSearch(det_ctx, p);
SCLogDebug("post search: cnt %" PRIu32, cnt);
*sms_runflags |= SMS_USED_PM;
}
}
if (alproto == ALPROTO_HTTP && alstate != NULL) {
if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_URI) {
cnt = DetectUricontentInspectMpm(det_ctx, p->flow, alstate);
SCLogDebug("uri search: cnt %" PRIu32, cnt);
}
//if (sgh->flags & SIG_GROUP_HEAD_MPM_HCBD) {
// cnt = DetectEngineInspectHttpClientBodyMpmInspect(de_ctx, det_ctx,
// f, htp_state);
// SCLogDebug("hcbd search: cnt %" PRIu32, cnt);
//}
//if (sgh->flags & SIG_GROUP_HEAD_MPM_HHD) {
// cnt = DetectEngineInspectHttpHeaderMpmInspect(det_ctx, f,
// htp_state);
// SCLogDebug("hhd search: cnt %" PRIu32, cnt);
//}
//if (sgh->flags & SIG_GROUP_HEAD_MPM_HHD) {
// cnt = DetectEngineInspectHttpRawHeaderMpmInspect(det_ctx, f,
// htp_state);
// SCLogDebug("hrhd search: cnt %" PRIu32, cnt);
//}
}
return;
}
/**
* \brief Signature match function
*
@ -879,7 +953,6 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
int fmatch = 0;
uint32_t idx;
uint32_t cnt = 0;
uint8_t flags = 0; /* flow/state flags */
void *alstate = NULL;
@ -1007,35 +1080,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
goto end;
}
/* have a look at the reassembled stream (if any) */
if (p->flowflags & FLOW_PKT_ESTABLISHED) {
SCLogDebug("p->flowflags & FLOW_PKT_ESTABLISHED");
if (smsg != NULL && det_ctx->sgh->mpm_stream_ctx != NULL) {
cnt = StreamPatternSearch(th_v, det_ctx, p, smsg, flags);
SCLogDebug("cnt %u", cnt);
sms_runflags |= SMS_USED_STREAM_PM;
} else {
SCLogDebug("smsg NULL (%p) or det_ctx->sgh->mpm_stream_ctx NULL (%p)", smsg, det_ctx->sgh->mpm_stream_ctx);
}
} else {
SCLogDebug("NOT p->flowflags & FLOW_PKT_ESTABLISHED");
}
if (p->payload_len > 0 && det_ctx->sgh->mpm_ctx != NULL &&
(!(p->flags & PKT_NOPAYLOAD_INSPECTION) && !(p->flags & PKT_STREAM_ADD)))
{
/* run the multi packet matcher against the payload of the packet */
if (det_ctx->sgh->mpm_content_maxlen > p->payload_len) {
SCLogDebug("not mpm-inspecting as pkt payload is smaller than "
"the largest content length we need to match");
} else {
SCLogDebug("search: (%p, maxlen %" PRIu32 ", sgh->sig_cnt %" PRIu32 ")",
det_ctx->sgh, det_ctx->sgh->mpm_content_maxlen, det_ctx->sgh->sig_cnt);
cnt = PacketPatternSearch(th_v, det_ctx, p);
SCLogDebug("post search: cnt %" PRIu32, cnt);
sms_runflags |= SMS_USED_PM;
}
}
RunMpmsOnFlow(de_ctx, det_ctx, smsg, p, flags, alproto, alstate, &sms_runflags);
/* stateful app layer detection */
if (p->flags & PKT_HAS_FLOW && alstate != NULL) {

@ -797,17 +797,23 @@ typedef struct SigTableElmt_ {
char *name;
} SigTableElmt;
#define SIG_GROUP_HAVECONTENT 0x0001
#define SIG_GROUP_HAVEURICONTENT 0x0002
#define SIG_GROUP_HAVESTREAMCONTENT 0x0004
#define SIG_GROUP_HAVEHCBDCONTENT 0x0008
#define SIG_GROUP_HAVEHHDCONTENT 0x0010
#define SIG_GROUP_HAVEHRHDCONTENT 0x0020
#define SIG_GROUP_HEAD_MPM_COPY 0x0040
#define SIG_GROUP_HEAD_MPM_URI_COPY 0x0080
#define SIG_GROUP_HEAD_MPM_STREAM_COPY 0x0100
#define SIG_GROUP_HEAD_FREE 0x0200
#define SIG_GROUP_HEAD_REFERENCED 0x0400 /**< sgh is being referenced by others, don't clear */
#define SIG_GROUP_HAVECONTENT 0x00000001
#define SIG_GROUP_HAVEURICONTENT 0x00000002
#define SIG_GROUP_HAVESTREAMCONTENT 0x00000004
#define SIG_GROUP_HAVEHCBDCONTENT 0x00000008
#define SIG_GROUP_HAVEHHDCONTENT 0x00000010
#define SIG_GROUP_HAVEHRHDCONTENT 0x00000020
#define SIG_GROUP_HEAD_MPM_COPY 0x00000040
#define SIG_GROUP_HEAD_MPM_URI_COPY 0x00000080
#define SIG_GROUP_HEAD_MPM_STREAM_COPY 0x00000100
#define SIG_GROUP_HEAD_FREE 0x00000200
#define SIG_GROUP_HEAD_MPM_PACKET 0x00000400
#define SIG_GROUP_HEAD_MPM_STREAM 0x00000800
#define SIG_GROUP_HEAD_MPM_URI 0x00001000
#define SIG_GROUP_HEAD_MPM_HCBD 0x00002000
#define SIG_GROUP_HEAD_MPM_HHD 0x00004000
#define SIG_GROUP_HEAD_MPM_HRHD 0x00008000
#define SIG_GROUP_HEAD_REFERENCED 0x00010000 /**< sgh is being referenced by others, don't clear */
typedef struct SigGroupHeadInitData_ {
/* list of content containers
@ -833,12 +839,11 @@ typedef struct SigGroupHeadInitData_ {
/** \brief Container for matching data for a signature group */
typedef struct SigGroupHead_ {
uint16_t flags;
uint32_t flags;
/* number of sigs in this head */
SigIntId sig_cnt;
uint16_t mpm_content_maxlen;
uint16_t mpm_streamcontent_maxlen;
/** chunk of memory containing the "header" part of each
* signature ordered as an array. Used to pre-filter the
@ -852,8 +857,9 @@ typedef struct SigGroupHead_ {
MpmCtx *mpm_hcbd_ctx;
MpmCtx *mpm_hhd_ctx;
MpmCtx *mpm_hrhd_ctx;
uint16_t mpm_streamcontent_maxlen;
uint16_t mpm_uricontent_maxlen;
uint16_t pad1;
#if __WORDSIZE == 64
uint32_t pad2;
#endif

Loading…
Cancel
Save