add pcre with U modifiers to the umatch sigmatch list. fix for bug 155

remotes/origin/master-1.0.x
Anoop Saldanha 15 years ago committed by Victor Julien
parent 8852b83fa7
commit 36e4b1830e

@ -28,12 +28,16 @@
#include "decode.h" #include "decode.h"
#include "detect.h" #include "detect.h"
#include "detect-engine.h"
#include "detect-parse.h"
#include "detect-engine-state.h"
#include "detect-uricontent.h" #include "detect-uricontent.h"
#include "detect-pcre.h" #include "detect-pcre.h"
#include "detect-isdataat.h" #include "detect-isdataat.h"
#include "detect-bytetest.h" #include "detect-bytetest.h"
#include "detect-bytejump.h" #include "detect-bytejump.h"
#include "flow-util.h"
#include "util-spm.h" #include "util-spm.h"
#include "util-debug.h" #include "util-debug.h"
#include "util-print.h" #include "util-print.h"
@ -53,24 +57,26 @@
#include "app-layer-htp.h" #include "app-layer-htp.h"
#include "app-layer-protos.h" #include "app-layer-protos.h"
/** \brief Run the actual payload match function for uricontent /**
* \brief Run the actual payload match function for uricontent.
* *
* For accounting the last match in relative matching the * For accounting the last match in relative matching the
* det_ctx->uricontent_payload_offset int is used. * det_ctx->payload_offset int is used.
* *
* \param de_ctx Detection engine context * \param de_ctx Detection engine context.
* \param det_ctx Detection engine thread context * \param det_ctx Detection engine thread context.
* \param s Signature to inspect * \param s Signature to inspect.
* \param sm SigMatch to inspect * \param sm SigMatch to inspect.
* \param payload ptr to the uricontent payload to inspect * \param payload Ptr to the uricontent payload to inspect.
* \param payload_len length of the uricontent payload * \param payload_len Length of the uricontent payload.
* *
* \retval 0 no match * \retval 0 no match.
* \retval 1 match * \retval 1 match.
*/ */
static int DoInspectPacketUri(DetectEngineCtx *de_ctx, static int DoInspectPacketUri(DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx, Signature *s, SigMatch *sm, DetectEngineThreadCtx *det_ctx,
uint8_t *payload, uint32_t payload_len) Signature *s, SigMatch *sm,
uint8_t *payload, uint32_t payload_len)
{ {
SCEnter(); SCEnter();
@ -102,7 +108,7 @@ static int DoInspectPacketUri(DetectEngineCtx *de_ctx,
ud->flags & DETECT_URICONTENT_WITHIN) { ud->flags & DETECT_URICONTENT_WITHIN) {
SCLogDebug("det_ctx->uricontent_payload_offset %"PRIu32, det_ctx->uricontent_payload_offset); SCLogDebug("det_ctx->uricontent_payload_offset %"PRIu32, det_ctx->uricontent_payload_offset);
offset = det_ctx->uricontent_payload_offset; offset = det_ctx->payload_offset;
depth = payload_len; depth = payload_len;
if (ud->flags & DETECT_URICONTENT_DISTANCE) { if (ud->flags & DETECT_URICONTENT_DISTANCE) {
@ -116,17 +122,17 @@ static int DoInspectPacketUri(DetectEngineCtx *de_ctx,
} }
if (ud->flags & DETECT_URICONTENT_WITHIN) { if (ud->flags & DETECT_URICONTENT_WITHIN) {
if ((int32_t)depth > (int32_t)(det_ctx->uricontent_payload_offset + ud->within)) { if ((int32_t)depth > (int32_t)(det_ctx->payload_offset + ud->within)) {
depth = det_ctx->uricontent_payload_offset + ud->within; depth = det_ctx->payload_offset + ud->within;
} }
SCLogDebug("ud->within %"PRIi32", det_ctx->uricontent_payload_offset %"PRIu32", depth %"PRIu32, SCLogDebug("ud->within %"PRIi32", det_ctx->payload_offset %"PRIu32", depth %"PRIu32,
ud->within, det_ctx->uricontent_payload_offset, depth); ud->within, det_ctx->payload_offset, depth);
} }
if (ud->depth != 0) { if (ud->depth != 0) {
if ((ud->depth + det_ctx->uricontent_payload_offset) < depth) { if ((ud->depth + det_ctx->payload_offset) < depth) {
depth = det_ctx->uricontent_payload_offset + ud->depth; depth = det_ctx->payload_offset + ud->depth;
} }
SCLogDebug("ud->depth %"PRIu32", depth %"PRIu32, ud->depth, depth); SCLogDebug("ud->depth %"PRIu32", depth %"PRIu32, ud->depth, depth);
@ -196,7 +202,7 @@ static int DoInspectPacketUri(DetectEngineCtx *de_ctx,
} else { } else {
match_offset = (uint32_t)((found - payload) + ud->uricontent_len); match_offset = (uint32_t)((found - payload) + ud->uricontent_len);
SCLogDebug("uricontent %"PRIu32" matched at offset %"PRIu32"", ud->id, match_offset); SCLogDebug("uricontent %"PRIu32" matched at offset %"PRIu32"", ud->id, match_offset);
det_ctx->uricontent_payload_offset = match_offset; det_ctx->payload_offset = match_offset;
if (!(ud->flags & DETECT_URICONTENT_RELATIVE_NEXT)) { if (!(ud->flags & DETECT_URICONTENT_RELATIVE_NEXT)) {
SCLogDebug("no relative match coming up, so this is a match"); SCLogDebug("no relative match coming up, so this is a match");
@ -220,6 +226,16 @@ static int DoInspectPacketUri(DetectEngineCtx *de_ctx,
} }
} while(1); } while(1);
} else if (sm->type == DETECT_PCRE) {
SCLogDebug("inspecting pcre");
int r = DetectPcrePayloadMatch(det_ctx, s, sm, /* no packet */NULL,
NULL, payload, payload_len);
if (r == 1) {
goto match;
}
SCReturnInt(0);
} else { } else {
/* we should never get here, but bail out just in case */ /* we should never get here, but bail out just in case */
BUG_ON(1); BUG_ON(1);
@ -230,7 +246,8 @@ match:
/* this sigmatch matched, inspect the next one. If it was the last, /* this sigmatch matched, inspect the next one. If it was the last,
* the payload portion of the signature matched. */ * the payload portion of the signature matched. */
if (sm->next != NULL) { if (sm->next != NULL) {
int r = DoInspectPacketUri(de_ctx,det_ctx,s,sm->next, payload, payload_len); int r = DoInspectPacketUri(de_ctx, det_ctx, s, sm->next, payload,
payload_len);
SCReturnInt(r); SCReturnInt(r);
} else { } else {
SCReturnInt(1); SCReturnInt(1);
@ -259,11 +276,6 @@ int DetectEngineInspectPacketUris(DetectEngineCtx *de_ctx,
int r = 0; int r = 0;
HtpState *htp_state = NULL; HtpState *htp_state = NULL;
if (!(det_ctx->sgh->flags & SIG_GROUP_HAVEURICONTENT)) {
SCLogDebug("no uricontent in sgh");
SCReturnInt(0);
}
htp_state = (HtpState *)alstate; htp_state = (HtpState *)alstate;
if (htp_state == NULL) { if (htp_state == NULL) {
SCLogDebug("no HTTP state"); SCLogDebug("no HTTP state");
@ -278,6 +290,7 @@ int DetectEngineInspectPacketUris(DetectEngineCtx *de_ctx,
goto end; goto end;
} }
det_ctx->de_have_httpuri = TRUE;
/* If we have the uricontent multi pattern matcher signatures in /* If we have the uricontent multi pattern matcher signatures in
signature list, then search the received HTTP uri(s) in the htp signature list, then search the received HTTP uri(s) in the htp
state against those patterns */ state against those patterns */
@ -288,8 +301,8 @@ int DetectEngineInspectPacketUris(DetectEngineCtx *de_ctx,
/* only consider uri sigs if we've seen at least one match */ /* only consider uri sigs if we've seen at least one match */
/** \warning when we start supporting negated uri content matches /** \warning when we start supporting negated uri content matches
* we need to update this check as well */ * we need to update this check as well */
if (cnt > 0) { if (cnt <= 0) {
det_ctx->de_have_httpuri = TRUE; det_ctx->de_have_httpuri = FALSE;
} }
SCLogDebug("uricontent cnt %"PRIu32"", cnt); SCLogDebug("uricontent cnt %"PRIu32"", cnt);
@ -306,7 +319,7 @@ int DetectEngineInspectPacketUris(DetectEngineCtx *de_ctx,
goto end; goto end;
} }
if (det_ctx->de_mpm_scanned_uri == TRUE) { if ((s->flags & SIG_FLAG_MPM_URI) && (det_ctx->de_mpm_scanned_uri == TRUE)) {
if (det_ctx->pmq.pattern_id_bitarray != NULL) { if (det_ctx->pmq.pattern_id_bitarray != NULL) {
/* filter out sigs that want pattern matches, but /* filter out sigs that want pattern matches, but
* have no matches */ * have no matches */
@ -321,7 +334,7 @@ int DetectEngineInspectPacketUris(DetectEngineCtx *de_ctx,
sm = s->umatch; sm = s->umatch;
det_ctx->uricontent_payload_offset = 0; det_ctx->payload_offset = 0;
#ifdef DEBUG #ifdef DEBUG
DetectUricontentData *co = (DetectUricontentData *)sm->ctx; DetectUricontentData *co = (DetectUricontentData *)sm->ctx;
@ -356,3 +369,133 @@ end:
SCReturnInt(r); SCReturnInt(r);
} }
/***********************************Unittests**********************************/
#ifdef UNITTESTS
static int UriTestSig01(void)
{
int result = 1;
Flow f;
HtpState *http_state = NULL;
uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n"
"User-Agent: Mozilla/1.0\r\n"
"Cookie: hellocatch\r\n\r\n";
uint32_t http_buf1_len = sizeof(http_buf1) - 1;
uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n"
"User-Agent: Mozilla/1.0\r\n"
"Cookie: hellocatch\r\n\r\n";
uint32_t http_buf2_len = sizeof(http_buf2) - 1;
TcpSession ssn;
Packet p;
Signature *s = NULL;
ThreadVars tv;
DetectEngineThreadCtx *det_ctx = NULL;
memset(&tv, 0, sizeof(ThreadVars));
memset(&p, 0, sizeof(Packet));
memset(&f, 0, sizeof(Flow));
memset(&ssn, 0, sizeof(TcpSession));
p.src.family = AF_INET;
p.dst.family = AF_INET;
p.payload = http_buf1;
p.payload_len = http_buf1_len;
p.proto = IPPROTO_TCP;
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.src.family = AF_INET;
f.dst.family = AF_INET;
p.flow = &f;
p.flowflags |= FLOW_PKT_TOSERVER;
p.flowflags |= FLOW_PKT_ESTABLISHED;
f.alproto = ALPROTO_HTTP;
StreamTcpInitConfig(TRUE);
FlowL7DataPtrInit(&f);
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL) {
goto end;
}
de_ctx->mpm_matcher = MPM_B2G;
de_ctx->flags |= DE_QUIET;
s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Test pcre U option\"; "
"uricontent:one; sid:1;)");
if (s == NULL) {
goto end;
}
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
goto end;
}
http_state = f.aldata[AlpGetStateIdx(ALPROTO_HTTP)];
if (http_state == NULL) {
printf("no http state: ");
goto end;
}
/* do detect */
SigMatchSignatures(&tv, de_ctx, det_ctx, &p);
if (!PacketAlertCheck(&p, 1)) {
printf("sig 1 alerted, but it should not: ");
goto end;
}
r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
goto end;
}
http_state = f.aldata[AlpGetStateIdx(ALPROTO_HTTP)];
if (http_state == NULL) {
printf("no http state: ");
goto end;
}
if (!PacketAlertCheck(&p, 1)) {
printf("sig 1 alerted, but it should not: ");
goto end;
}
/* do detect */
SigMatchSignatures(&tv, de_ctx, det_ctx, &p);
result = 1;
end:
if (det_ctx != NULL)
DetectEngineThreadCtxDeinit(&tv, det_ctx);
if (de_ctx != NULL)
SigGroupCleanup(de_ctx);
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
StreamTcpFreeConfig(TRUE);
FLOW_DESTROY(&f);
return result;
}
#endif /* UNITTESTS */
void UriRegisterTests(void)
{
#ifdef UNITTESTS
UtRegisterTest("UriTestSig01", UriTestSig01, 1);
#endif /* UNITTESTS */
return;
}

@ -24,9 +24,9 @@
#ifndef __DETECT_ENGINE_URICONTENT_H__ #ifndef __DETECT_ENGINE_URICONTENT_H__
#define __DETECT_ENGINE_URICONTENT_H__ #define __DETECT_ENGINE_URICONTENT_H__
int DetectEngineInspectPacketUris(DetectEngineCtx *, int DetectEngineInspectPacketUris(DetectEngineCtx *, DetectEngineThreadCtx *,
DetectEngineThreadCtx *, Signature *, Flow *, uint8_t, Signature *, Flow *, uint8_t, void *);
void *); void UriRegisterTests(void);
#endif /* __DETECT_ENGINE_URICONTENT_H__ */ #endif /* __DETECT_ENGINE_URICONTENT_H__ */

@ -840,6 +840,18 @@ static int DetectPcreSetup (DetectEngineCtx *de_ctx, Signature *s, char *regexst
AppLayerHtpEnableRequestBodyCallback(); AppLayerHtpEnableRequestBodyCallback();
SigMatchAppendAppLayer(s, sm); SigMatchAppendAppLayer(s, sm);
} else if (pd->flags & DETECT_PCRE_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;
SigMatchAppendUricontent(s, sm);
} else { } else {
switch (s->alproto) { switch (s->alproto) {
case ALPROTO_DCERPC: case ALPROTO_DCERPC:
@ -1180,6 +1192,7 @@ static int DetectPcreTestSig01Real(int mpm_type) {
"Host: two.example.org\r\n" "Host: two.example.org\r\n"
"\r\n\r\n"; "\r\n\r\n";
uint16_t buflen = strlen((char *)buf); uint16_t buflen = strlen((char *)buf);
TcpSession ssn;
Packet p; Packet p;
ThreadVars th_v; ThreadVars th_v;
DetectEngineThreadCtx *det_ctx; DetectEngineThreadCtx *det_ctx;
@ -1190,13 +1203,25 @@ static int DetectPcreTestSig01Real(int mpm_type) {
memset(&th_v, 0, sizeof(th_v)); memset(&th_v, 0, sizeof(th_v));
memset(&p, 0, sizeof(p)); memset(&p, 0, sizeof(p));
memset(&ssn, 0, sizeof(TcpSession));
FLOW_INITIALIZE(&f); FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.src.family = AF_INET;
f.dst.family = AF_INET;
f.alproto = ALPROTO_HTTP;
p.src.family = AF_INET; p.src.family = AF_INET;
p.dst.family = AF_INET; p.dst.family = AF_INET;
p.payload = buf; p.payload = buf;
p.payload_len = buflen; p.payload_len = buflen;
p.proto = IPPROTO_TCP; p.proto = IPPROTO_TCP;
p.flow = &f; p.flow = &f;
p.flowflags |= FLOW_PKT_TOSERVER;
p.flowflags |= FLOW_PKT_ESTABLISHED;
StreamTcpInitConfig(TRUE);
FlowL7DataPtrInit(&f);
DetectEngineCtx *de_ctx = DetectEngineCtxInit(); DetectEngineCtx *de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL) { if (de_ctx == NULL) {
@ -1215,18 +1240,28 @@ static int DetectPcreTestSig01Real(int mpm_type) {
SigGroupBuild(de_ctx); SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START, buf, buflen);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
goto end;
}
SigMatchSignatures(&th_v, de_ctx, det_ctx, &p); SigMatchSignatures(&th_v, de_ctx, det_ctx, &p);
if (PacketAlertCheck(&p, 1) == 1) { if (PacketAlertCheck(&p, 1) == 1) {
result = 1; result = 1;
} }
end:
SigGroupCleanup(de_ctx); SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx); SigCleanSignatures(de_ctx);
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
DetectEngineCtxFree(de_ctx); DetectEngineCtxFree(de_ctx);
FlowL7DataPtrFree(&f);
StreamTcpFreeConfig(TRUE);
FLOW_DESTROY(&f); FLOW_DESTROY(&f);
end:
return result; return result;
} }

@ -51,6 +51,7 @@
#include "detect-engine-sigorder.h" #include "detect-engine-sigorder.h"
#include "detect-engine-payload.h" #include "detect-engine-payload.h"
#include "detect-engine-dcepayload.h" #include "detect-engine-dcepayload.h"
#include "detect-engine-uri.h"
#include "detect-engine-state.h" #include "detect-engine-state.h"
#include "detect-engine-tag.h" #include "detect-engine-tag.h"
@ -880,6 +881,7 @@ int main(int argc, char **argv)
#endif #endif
PayloadRegisterTests(); PayloadRegisterTests();
DcePayloadRegisterTests(); DcePayloadRegisterTests();
UriRegisterTests();
#ifdef PROFILING #ifdef PROFILING
SCProfilingRegisterTests(); SCProfilingRegisterTests();
#endif #endif

Loading…
Cancel
Save