Project

General

Profile

Bug #155 » 0001-add-pcre-with-U-modifiers-to-the-umatch-sigmatch-lis.patch

Anoop Saldanha, 06/23/2010 10:46 AM

View differences:

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
(2-2/2)