Bug #155 » 0001-add-pcre-with-U-modifiers-to-the-umatch-sigmatch-lis.patch
src/detect-engine-uri.c | ||
---|---|---|
#include "decode.h"
|
||
#include "detect.h"
|
||
#include "detect-engine.h"
|
||
#include "detect-parse.h"
|
||
#include "detect-engine-state.h"
|
||
#include "detect-uricontent.h"
|
||
#include "detect-pcre.h"
|
||
#include "detect-isdataat.h"
|
||
#include "detect-bytetest.h"
|
||
#include "detect-bytejump.h"
|
||
#include "flow-util.h"
|
||
#include "util-spm.h"
|
||
#include "util-debug.h"
|
||
#include "util-print.h"
|
||
... | ... | |
#include "app-layer-htp.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
|
||
* det_ctx->uricontent_payload_offset int is used.
|
||
* For accounting the last match in relative matching the
|
||
* det_ctx->payload_offset int is used.
|
||
*
|
||
* \param de_ctx Detection engine context
|
||
* \param det_ctx Detection engine thread context
|
||
* \param s Signature to inspect
|
||
* \param sm SigMatch to inspect
|
||
* \param payload ptr to the uricontent payload to inspect
|
||
* \param payload_len length of the uricontent payload
|
||
* \param de_ctx Detection engine context.
|
||
* \param det_ctx Detection engine thread context.
|
||
* \param s Signature to inspect.
|
||
* \param sm SigMatch to inspect.
|
||
* \param payload Ptr to the uricontent payload to inspect.
|
||
* \param payload_len Length of the uricontent payload.
|
||
*
|
||
* \retval 0 no match
|
||
* \retval 1 match
|
||
* \retval 0 no match.
|
||
* \retval 1 match.
|
||
*/
|
||
static int DoInspectPacketUri(DetectEngineCtx *de_ctx,
|
||
DetectEngineThreadCtx *det_ctx, Signature *s, SigMatch *sm,
|
||
uint8_t *payload, uint32_t payload_len)
|
||
DetectEngineThreadCtx *det_ctx,
|
||
Signature *s, SigMatch *sm,
|
||
uint8_t *payload, uint32_t payload_len)
|
||
{
|
||
SCEnter();
|
||
... | ... | |
ud->flags & DETECT_URICONTENT_WITHIN) {
|
||
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;
|
||
if (ud->flags & DETECT_URICONTENT_DISTANCE) {
|
||
... | ... | |
}
|
||
if (ud->flags & DETECT_URICONTENT_WITHIN) {
|
||
if ((int32_t)depth > (int32_t)(det_ctx->uricontent_payload_offset + ud->within)) {
|
||
depth = det_ctx->uricontent_payload_offset + ud->within;
|
||
if ((int32_t)depth > (int32_t)(det_ctx->payload_offset + ud->within)) {
|
||
depth = det_ctx->payload_offset + ud->within;
|
||
}
|
||
SCLogDebug("ud->within %"PRIi32", det_ctx->uricontent_payload_offset %"PRIu32", depth %"PRIu32,
|
||
ud->within, det_ctx->uricontent_payload_offset, depth);
|
||
SCLogDebug("ud->within %"PRIi32", det_ctx->payload_offset %"PRIu32", depth %"PRIu32,
|
||
ud->within, det_ctx->payload_offset, depth);
|
||
}
|
||
if (ud->depth != 0) {
|
||
if ((ud->depth + det_ctx->uricontent_payload_offset) < depth) {
|
||
depth = det_ctx->uricontent_payload_offset + ud->depth;
|
||
if ((ud->depth + det_ctx->payload_offset) < depth) {
|
||
depth = det_ctx->payload_offset + ud->depth;
|
||
}
|
||
SCLogDebug("ud->depth %"PRIu32", depth %"PRIu32, ud->depth, depth);
|
||
... | ... | |
} else {
|
||
match_offset = (uint32_t)((found - payload) + ud->uricontent_len);
|
||
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)) {
|
||
SCLogDebug("no relative match coming up, so this is a match");
|
||
... | ... | |
}
|
||
} 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 {
|
||
/* we should never get here, but bail out just in case */
|
||
BUG_ON(1);
|
||
... | ... | |
/* this sigmatch matched, inspect the next one. If it was the last,
|
||
* the payload portion of the signature matched. */
|
||
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);
|
||
} else {
|
||
SCReturnInt(1);
|
||
... | ... | |
int r = 0;
|
||
HtpState *htp_state = NULL;
|
||
if (!(det_ctx->sgh->flags & SIG_GROUP_HAVEURICONTENT)) {
|
||
SCLogDebug("no uricontent in sgh");
|
||
SCReturnInt(0);
|
||
}
|
||
htp_state = (HtpState *)alstate;
|
||
if (htp_state == NULL) {
|
||
SCLogDebug("no HTTP state");
|
||
... | ... | |
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 */
|
||
... | ... | |
/* 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 = TRUE;
|
||
if (cnt <= 0) {
|
||
det_ctx->de_have_httpuri = FALSE;
|
||
}
|
||
SCLogDebug("uricontent cnt %"PRIu32"", cnt);
|
||
... | ... | |
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) {
|
||
/* filter out sigs that want pattern matches, but
|
||
* have no matches */
|
||
... | ... | |
sm = s->umatch;
|
||
det_ctx->uricontent_payload_offset = 0;
|
||
det_ctx->payload_offset = 0;
|
||
#ifdef DEBUG
|
||
DetectUricontentData *co = (DetectUricontentData *)sm->ctx;
|
||
... | ... | |
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;
|
||
}
|
src/detect-engine-uri.h | ||
---|---|---|
#ifndef __DETECT_ENGINE_URICONTENT_H__
|
||
#define __DETECT_ENGINE_URICONTENT_H__
|
||
int DetectEngineInspectPacketUris(DetectEngineCtx *,
|
||
DetectEngineThreadCtx *, Signature *, Flow *, uint8_t,
|
||
void *);
|
||
int DetectEngineInspectPacketUris(DetectEngineCtx *, DetectEngineThreadCtx *,
|
||
Signature *, Flow *, uint8_t, void *);
|
||
void UriRegisterTests(void);
|
||
#endif /* __DETECT_ENGINE_URICONTENT_H__ */
|
||
src/detect-pcre.c | ||
---|---|---|
AppLayerHtpEnableRequestBodyCallback();
|
||
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 {
|
||
switch (s->alproto) {
|
||
case ALPROTO_DCERPC:
|
||
... | ... | |
"Host: two.example.org\r\n"
|
||
"\r\n\r\n";
|
||
uint16_t buflen = strlen((char *)buf);
|
||
TcpSession ssn;
|
||
Packet p;
|
||
ThreadVars th_v;
|
||
DetectEngineThreadCtx *det_ctx;
|
||
... | ... | |
memset(&th_v, 0, sizeof(th_v));
|
||
memset(&p, 0, sizeof(p));
|
||
memset(&ssn, 0, sizeof(TcpSession));
|
||
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.dst.family = AF_INET;
|
||
p.payload = buf;
|
||
p.payload_len = buflen;
|
||
p.proto = IPPROTO_TCP;
|
||
p.flow = &f;
|
||
p.flowflags |= FLOW_PKT_TOSERVER;
|
||
p.flowflags |= FLOW_PKT_ESTABLISHED;
|
||
StreamTcpInitConfig(TRUE);
|
||
FlowL7DataPtrInit(&f);
|
||
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
|
||
if (de_ctx == NULL) {
|
||
... | ... | |
SigGroupBuild(de_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);
|
||
if (PacketAlertCheck(&p, 1) == 1) {
|
||
result = 1;
|
||
}
|
||
end:
|
||
SigGroupCleanup(de_ctx);
|
||
SigCleanSignatures(de_ctx);
|
||
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
|
||
DetectEngineCtxFree(de_ctx);
|
||
FlowL7DataPtrFree(&f);
|
||
StreamTcpFreeConfig(TRUE);
|
||
FLOW_DESTROY(&f);
|
||
end:
|
||
return result;
|
||
}
|
||
src/suricata.c | ||
---|---|---|
#include "detect-engine-sigorder.h"
|
||
#include "detect-engine-payload.h"
|
||
#include "detect-engine-dcepayload.h"
|
||
#include "detect-engine-uri.h"
|
||
#include "detect-engine-state.h"
|
||
#include "tm-queuehandlers.h"
|
||
... | ... | |
#endif
|
||
PayloadRegisterTests();
|
||
DcePayloadRegisterTests();
|
||
UriRegisterTests();
|
||
#ifdef PROFILING
|
||
SCProfilingRegisterTests();
|
||
#endif
|
- « Previous
- 1
- 2
- Next »