implement relative pcre matching in detect-engine-(payload|uri|dcepayload).c. Also fix within/distance handling of RELATIVE_NEXT flag for uricontent

remotes/origin/master-1.0.x
Anoop Saldanha 15 years ago committed by Victor Julien
parent 3a375aa43a
commit b94eaec7c2

@ -173,40 +173,74 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s,
DetectUricontentData *ud = NULL;
DetectContentData *cd = NULL;
DetectPcreData *pe = NULL;
switch (pm->type) {
case DETECT_URICONTENT:
ud = (DetectUricontentData *)pm->ctx;
if (ud == NULL) {
SCLogError(SC_ERR_DISTANCE_MISSING_CONTENT, "distance needs two "
"preceeding content or uricontent options");
"preceeding content or uricontent options");
goto error;
}
ud->distance = strtol(str, NULL, 10);
ud->flags |= DETECT_URICONTENT_DISTANCE;
if (ud->flags & DETECT_URICONTENT_WITHIN) {
if ((ud->distance + ud->uricontent_len) > ud->within) {
ud->within = ud->distance + ud->uricontent_len;
}
}
pm = DetectUricontentGetLastPattern(s->umatch_tail->prev);
ud->flags |= DETECT_URICONTENT_DISTANCE;
pm = SigMatchGetLastSMFromLists(s, 6,
DETECT_URICONTENT, pm->prev,
DETECT_PCRE, pm->prev,
DETECT_BYTEJUMP, pm->prev);
if (pm == NULL) {
SCLogError(SC_ERR_DISTANCE_MISSING_CONTENT, "distance needs two"
" preceeding content or uricontent options");
SCLogError(SC_ERR_DISTANCE_MISSING_CONTENT, "within needs two "
"preceeding content or uricontent options");
goto error;
}
if (pm->type == DETECT_URICONTENT) {
ud = (DetectUricontentData *)pm->ctx;
ud->flags |= DETECT_URICONTENT_RELATIVE_NEXT;
} else {
SCLogError(SC_ERR_RULE_KEYWORD_UNKNOWN, "Unknown previous"
" keyword!");
goto error;
switch (pm->type) {
case DETECT_URICONTENT:
/* Set the relative next flag on the prev sigmatch */
ud = (DetectUricontentData *)pm->ctx;
if (ud == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-"
"previous keyword!");
goto error;
}
ud->flags |= DETECT_URICONTENT_RELATIVE_NEXT;
break;
case DETECT_PCRE:
pe = (DetectPcreData *) pm->ctx;
if (pe == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-"
"previous keyword!");
goto error;
}
pe->flags |= DETECT_PCRE_RELATIVE_NEXT;
break;
case DETECT_BYTEJUMP:
SCLogDebug("No setting relative_next for bytejump. We "
"have no use for it");
break;
default:
/* this will never hit */
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-"
"previous keyword!");
break;
}
break;
break;
case DETECT_CONTENT:
cd = (DetectContentData *)pm->ctx;
@ -228,8 +262,6 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s,
DETECT_CONTENT, pm->prev,
DETECT_PCRE, pm->prev,
DETECT_BYTEJUMP, pm->prev);
DetectPcreData *pe = NULL;
if (pm == NULL) {
if (s->alproto == ALPROTO_DCERPC) {
SCLogDebug("content relative without a previous content based "

@ -82,17 +82,13 @@ static int DoInspectDcePayload(DetectEngineCtx *de_ctx,
{
SCEnter();
if (sm == NULL) {
if (sm == NULL || stub_len == 0) {
SCReturnInt(0);
}
switch(sm->type) {
case DETECT_CONTENT:
{
if (stub_len == 0) {
SCReturnInt(0);
}
DetectContentData *cd = NULL;
cd = (DetectContentData *)sm->ctx;
SCLogDebug("inspecting content %"PRIu32" stub_len %"PRIu32,
@ -285,16 +281,41 @@ static int DoInspectDcePayload(DetectEngineCtx *de_ctx,
case DETECT_PCRE:
{
SCLogDebug("inspecting pcre");
DetectPcreData *pe = (DetectPcreData *)sm->ctx;
uint32_t prev_payload_offset = det_ctx->payload_offset;
uint32_t prev_offset = 0;
int r = 0;
int r = DetectPcrePayloadMatch(det_ctx, s, sm, /* no packet */NULL,
f, stub, stub_len);
if (r == 1) {
goto match;
}
det_ctx->pcre_match_start_offset = 0;
do {
r = DetectPcrePayloadMatch(det_ctx, s, sm, NULL, f,
stub, stub_len);
if (r == 0) {
det_ctx->discontinue_matching = 1;
SCReturnInt(0);
}
SCReturnInt(0);
}
if (!(pe->flags & DETECT_PCRE_RELATIVE_NEXT)) {
SCLogDebug("no relative match coming up, so this is a match");
goto match;
}
/* save it, in case we need to do a pcre match once again */
prev_offset = det_ctx->pcre_match_start_offset;
/* see if the next payload keywords match. If not, we will
* search for another occurence of this pcre and see
* if the others match, until we run out of matches */
r = DoInspectDcePayload(de_ctx, det_ctx, s, sm->next, f, stub,
stub_len, dcerpc_state);
if (r == 1) {
SCReturnInt(1);
}
det_ctx->payload_offset = prev_payload_offset;
det_ctx->pcre_match_start_offset = prev_offset;
} while (1);
}
case DETECT_BYTETEST:
{
DetectBytetestData *data = (DetectBytetestData *)sm->ctx;
@ -10014,6 +10035,107 @@ end:
return result;
}
/**
* \test Test the working of consecutive relative pcres.
*/
int DcePayloadTest43(void)
{
int result = 0;
uint8_t request1[] = {
0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00,
0x68, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00,
0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20,
0x61, 0x20, 0x73, 0x75, 0x70, 0x65, 0x72, 0x20,
0x64, 0x75, 0x70, 0x65, 0x72, 0x20, 0x6e, 0x6f,
0x76, 0x61, 0x20, 0x69, 0x6e, 0x20, 0x73, 0x75,
0x70, 0x65, 0x72, 0x20, 0x6e, 0x6f, 0x76, 0x61,
0x20, 0x6e, 0x6f, 0x77
};
uint32_t request1_len = sizeof(request1);
TcpSession ssn;
Packet p;
ThreadVars tv;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
Flow f;
int r;
char *sig1 = "alert tcp any any -> any any "
"(msg:\"testing dce consecutive relative matches\"; dce_stub_data; "
"pcre:/super/R; content:nova; within:7; sid:1;)";
Signature *s;
memset(&tv, 0, sizeof(ThreadVars));
memset(&f, 0, sizeof(Flow));
memset(&ssn, 0, sizeof(TcpSession));
memset(&p, 0, sizeof(Packet));
p.src.family = AF_INET;
p.dst.family = AF_INET;
p.payload = NULL;
p.payload_len = 0;
p.proto = IPPROTO_TCP;
p.flow = &f;
p.flowflags |= FLOW_PKT_TOSERVER;
p.flowflags |= FLOW_PKT_ESTABLISHED;
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.src.family = AF_INET;
f.dst.family = AF_INET;
f.alproto = ALPROTO_DCERPC;
StreamTcpInitConfig(TRUE);
FlowL7DataPtrInit(&f);
de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, sig1);
s = de_ctx->sig_list;
if (s == NULL)
goto end;
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
/* request 1 */
r = AppLayerParse(&f, ALPROTO_DCERPC, STREAM_TOSERVER, request1, request1_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
goto end;
}
/* detection phase */
SigMatchSignatures(&tv, de_ctx, det_ctx, &p);
if ( !(PacketAlertCheck(&p, 1))) {
printf("sid 1 didn't match but should have: ");
goto end;
}
result = 1;
end:
if (de_ctx != NULL) {
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineThreadCtxDeinit(&tv, (void *)det_ctx);
DetectEngineCtxFree(de_ctx);
}
FlowL7DataPtrFree(&f);
StreamTcpFreeConfig(TRUE);
return result;
}
#endif /* UNITTESTS */
void DcePayloadRegisterTests(void)
@ -10064,6 +10186,7 @@ void DcePayloadRegisterTests(void)
UtRegisterTest("DcePayloadParseTest41", DcePayloadParseTest41, 1);
UtRegisterTest("DcePayloadTest42", DcePayloadTest42, 1);
UtRegisterTest("DcePayloadTest43", DcePayloadTest43, 1);
#endif /* UNITTESTS */
return;

@ -74,17 +74,13 @@ static int DoInspectPacketPayload(DetectEngineCtx *de_ctx,
{
SCEnter();
if (sm == NULL) {
if (sm == NULL || payload_len == 0) {
SCReturnInt(0);
}
switch(sm->type) {
case DETECT_CONTENT:
{
if (payload_len == 0) {
SCReturnInt(0);
}
DetectContentData *cd = NULL;
cd = (DetectContentData *)sm->ctx;
SCLogDebug("inspecting content %"PRIu32" payload_len %"PRIu32, cd->id, payload_len);
@ -260,13 +256,40 @@ static int DoInspectPacketPayload(DetectEngineCtx *de_ctx,
case DETECT_PCRE:
{
SCLogDebug("inspecting pcre");
DetectPcreData *pe = (DetectPcreData *)sm->ctx;
uint32_t prev_payload_offset = det_ctx->payload_offset;
uint32_t prev_offset = 0;
int r = 0;
int r = DetectPcrePayloadMatch(det_ctx, s, sm, p, f, payload, payload_len);
if (r == 1) {
goto match;
}
det_ctx->pcre_match_start_offset = 0;
do {
r = DetectPcrePayloadMatch(det_ctx, s, sm, p, f,
payload, payload_len);
if (r == 0) {
det_ctx->discontinue_matching = 1;
SCReturnInt(0);
}
SCReturnInt(0);
if (!(pe->flags & DETECT_PCRE_RELATIVE_NEXT)) {
SCLogDebug("no relative match coming up, so this is a match");
goto match;
}
/* save it, in case we need to do a pcre match once again */
prev_offset = det_ctx->pcre_match_start_offset;
/* see if the next payload keywords match. If not, we will
* search for another occurence of this pcre and see
* if the others match, until we run out of matches */
r = DoInspectPacketPayload(de_ctx, det_ctx, s, sm->next, p,
f, payload, payload_len);
if (r == 1) {
SCReturnInt(1);
}
det_ctx->payload_offset = prev_payload_offset;
det_ctx->pcre_match_start_offset = prev_offset;
} while (1);
}
case DETECT_BYTETEST:
{
@ -570,6 +593,31 @@ end:
return result;
}
/**
* \test Test pcre recursive matching.
*/
static int PayloadTestSig09(void)
{
uint8_t *buf = (uint8_t *)"this is a super duper nova in super nova now";
uint16_t buflen = strlen((char *)buf);
Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP);
int result = 0;
char sig[] = "alert tcp any any -> any any (msg:\"dummy\"; "
"pcre:/super/; content:nova; within:7; sid:1;)";
if (UTHPacketMatchSigMpm(p, sig, MPM_B2G) == 0) {
result = 0;
goto end;
}
result = 1;
end:
if (p != NULL)
UTHFreePacket(p);
return result;
}
#endif /* UNITTESTS */
void PayloadRegisterTests(void) {
@ -582,5 +630,6 @@ void PayloadRegisterTests(void) {
UtRegisterTest("PayloadTestSig06", PayloadTestSig06, 1);
UtRegisterTest("PayloadTestSig07", PayloadTestSig07, 1);
UtRegisterTest("PayloadTestSig08", PayloadTestSig08, 1);
UtRegisterTest("PayloadTestSig09", PayloadTestSig09, 1);
#endif /* UNITTESTS */
}

@ -239,15 +239,40 @@ static int DoInspectPacketUri(DetectEngineCtx *de_ctx,
} while(1);
} else if (sm->type == DETECT_PCRE) {
SCLogDebug("inspecting pcre");
DetectPcreData *pe = (DetectPcreData *)sm->ctx;
uint32_t prev_payload_offset = det_ctx->payload_offset;
uint32_t prev_offset = 0;
int r = 0;
int r = DetectPcrePayloadMatch(det_ctx, s, sm, /* no packet */NULL,
NULL, payload, payload_len);
/* PrintRawDataFp(stdout, payload, payload_len); */
if (r == 1) {
goto match;
}
det_ctx->pcre_match_start_offset = 0;
do {
r = DetectPcrePayloadMatch(det_ctx, s, sm, NULL, NULL,
payload, payload_len);
if (r == 0) {
det_ctx->discontinue_matching = 1;
SCReturnInt(0);
}
SCReturnInt(0);
if (!(pe->flags & DETECT_PCRE_RELATIVE_NEXT)) {
SCLogDebug("no relative match coming up, so this is a match");
goto match;
}
/* save it, in case we need to do a pcre match once again */
prev_offset = det_ctx->pcre_match_start_offset;
/* see if the next payload keywords match. If not, we will
* search for another occurence of this pcre and see
* if the others match, until we run out of matches */
r = DoInspectPacketUri(de_ctx, det_ctx, s, sm->next,
payload, payload_len);
if (r == 1) {
SCReturnInt(1);
}
det_ctx->payload_offset = prev_payload_offset;
det_ctx->pcre_match_start_offset = prev_offset;
} while (1);
} else if (sm->type == DETECT_AL_URILEN) {
SCLogDebug("inspecting uri len");
@ -377,8 +402,6 @@ int DetectEngineInspectPacketUris(DetectEngineCtx *de_ctx,
sm = s->umatch;
det_ctx->payload_offset = 0;
#ifdef DEBUG
DetectUricontentData *co = (DetectUricontentData *)sm->ctx;
SCLogDebug("co->id %"PRIu32, co->id);
@ -394,6 +417,7 @@ int DetectEngineInspectPacketUris(DetectEngineCtx *de_ctx,
continue;
det_ctx->discontinue_matching = 0;
det_ctx->payload_offset = 0;
/* Inspect all the uricontents fetched on each
* transaction at the app layer */
@ -2784,6 +2808,99 @@ end:
return result;
}
/**
* \test Test relative pcre.
*/
static int UriTestSig22(void)
{
int result = 0;
uint8_t *http_buf = (uint8_t *)"POST /this_is_a_super_duper_"
"nova_in_super_nova_now HTTP/1.0\r\n"
"User-Agent: Mozilla/1.0\r\n";
uint32_t http_buf_len = strlen((char *)http_buf);
Flow f;
TcpSession ssn;
HtpState *http_state = NULL;
Packet p;
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_buf;
p.payload_len = http_buf_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;
de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"test multiple relative uricontents\"; "
"pcre:/super/U; uricontent:nova; within:7; sid:1;)");
if (de_ctx->sig_list == NULL) {
goto end;
}
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_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 didn't alert, but it should have: ");
goto end;
}
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)
@ -2811,6 +2928,7 @@ void UriRegisterTests(void)
UtRegisterTest("UriTestSig19", UriTestSig19, 1);
UtRegisterTest("UriTestSig20", UriTestSig20, 1);
UtRegisterTest("UriTestSig21", UriTestSig21, 1);
UtRegisterTest("UriTestSig22", UriTestSig22, 1);
#endif /* UNITTESTS */
return;

@ -264,22 +264,22 @@ int DetectPcreALMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow *f,
}
/**
* \brief match a regex on a single payload'
* \brief Match a regex on a single payload.
*
* \param det_ctx thread detection ctx
* \param s signature
* \param sm sig match to match against
* \param p packet to set PktVars if any
* \param f flow to set FlowVars if any
* \param payload payload to inspect
* \param payload_len lenght of the payload
* \param det_ctx Thread detection ctx.
* \param s Signature.
* \param sm Sig match to match against.
* \param p Packet to set PktVars if any.
* \param f Flow to set FlowVars if any.
* \param payload Payload to inspect.
* \param payload_len Length of the payload.
*
* \retval 1 match
* \retval 0 no match
* \retval 1 Match.
* \retval 0 No match.
*/
int DetectPcrePayloadMatch(DetectEngineThreadCtx *det_ctx, Signature *s,
SigMatch *sm, Packet *p, Flow *f, uint8_t *payload,
uint32_t payload_len)
SigMatch *sm, Packet *p, Flow *f, uint8_t *payload,
uint32_t payload_len)
{
SCEnter();
#define MAX_SUBSTRINGS 30
@ -288,9 +288,6 @@ int DetectPcrePayloadMatch(DetectEngineThreadCtx *det_ctx, Signature *s,
uint8_t *ptr = NULL;
uint16_t len = 0;
if (payload_len == 0)
SCReturnInt(0);
DetectPcreData *pe = (DetectPcreData *)sm->ctx;
/* If we want to inspect the http body, we will use HTP L7 parser */
@ -303,13 +300,16 @@ int DetectPcrePayloadMatch(DetectEngineThreadCtx *det_ctx, Signature *s,
} else if (pe->flags & DETECT_PCRE_RELATIVE) {
ptr = payload + det_ctx->payload_offset;
len = payload_len - det_ctx->payload_offset;
if (ptr == NULL || len == 0)
SCReturnInt(0);
} else {
ptr = payload;
len = payload_len;
}
if (det_ctx->pcre_match_start_offset != 0) {
ptr = payload + det_ctx->pcre_match_start_offset;
len = payload_len - det_ctx->pcre_match_start_offset;
}
/* run the actual pcre detection */
ret = pcre_exec(pe->re, pe->sd, (char *)ptr, len, 0, 0, ov, MAX_SUBSTRINGS);
SCLogDebug("ret %d (negating %s)", ret, pe->negate ? "set" : "not set");
@ -350,7 +350,8 @@ int DetectPcrePayloadMatch(DetectEngineThreadCtx *det_ctx, Signature *s,
}
/* update offset for pcre RELATIVE */
det_ctx->payload_offset = (ptr+ov[1]) - payload;
det_ctx->payload_offset = (ptr + ov[1]) - payload;
det_ctx->pcre_match_start_offset = (ptr + ov[0] + 1) - payload;
ret = 1;
}
@ -800,6 +801,7 @@ static int DetectPcreSetup (DetectEngineCtx *de_ctx, Signature *s, char *regexst
SCEnter();
DetectPcreData *pd = NULL;
SigMatch *sm = NULL;
SigMatch *prev_sm = NULL;
pd = DetectPcreParse(regexstr);
if (pd == NULL)
@ -881,6 +883,73 @@ static int DetectPcreSetup (DetectEngineCtx *de_ctx, Signature *s, char *regexst
}
}
if ( !(pd->flags & DETECT_PCRE_RELATIVE)) {
SCReturnInt(0);
}
prev_sm = SigMatchGetLastSMFromLists(s, 6,
DETECT_CONTENT, sm->prev,
DETECT_URICONTENT, sm->prev,
DETECT_PCRE, sm->prev);
if (prev_sm == NULL) {
if (s->alproto == ALPROTO_DCERPC) {
SCLogDebug("No preceding content or pcre keyword. Possible "
"since this is an alproto sig.");
SCReturnInt(0);
} else {
SCLogError(SC_ERR_INVALID_SIGNATURE, "No preceding content "
"or uricontent or pcre option");
goto error;
}
}
DetectContentData *cd = NULL;
DetectUricontentData *ud = NULL;
DetectPcreData *pe = NULL;
switch (prev_sm->type) {
case DETECT_CONTENT:
/* Set the relative next flag on the prev sigmatch */
cd = (DetectContentData *)prev_sm->ctx;
if (cd == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-"
"previous keyword!");
goto error;
}
cd->flags |= DETECT_CONTENT_RELATIVE_NEXT;
break;
case DETECT_URICONTENT:
/* Set the relative next flag on the prev sigmatch */
ud = (DetectUricontentData *)prev_sm->ctx;
if (ud == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-"
"previous keyword!");
goto error;
}
ud->flags |= DETECT_URICONTENT_RELATIVE_NEXT;
break;
case DETECT_PCRE:
pe = (DetectPcreData *) prev_sm->ctx;
if (pe == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-"
"previous keyword!");
goto error;
}
pe->flags |= DETECT_PCRE_RELATIVE_NEXT;
break;
default:
/* this will never hit */
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-"
"previous keyword!");
break;
} /* switch (prev_sm->type) */
SCReturnInt(0);
error:

@ -176,6 +176,7 @@ static int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, char *withi
DetectUricontentData *ud = NULL;
DetectContentData *cd = NULL;
DetectPcreData *pe = NULL;
switch (pm->type) {
case DETECT_URICONTENT:
@ -188,9 +189,9 @@ static int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, char *withi
ud->within = strtol(str, NULL, 10);
if (ud->within < (int32_t)ud->uricontent_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", ud->within,
ud->uricontent_len);
"less than the content length \"%"PRIu32"\" which is invalid, since "
"this will never match. Invalidating signature", ud->within,
ud->uricontent_len);
goto error;
}
@ -202,24 +203,56 @@ static int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, char *withi
}
}
pm = DetectUricontentGetLastPattern(s->umatch_tail->prev);
pm = SigMatchGetLastSMFromLists(s, 6,
DETECT_URICONTENT, pm->prev,
DETECT_PCRE, pm->prev,
DETECT_BYTEJUMP, pm->prev);
if (pm == NULL) {
SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "within needs two"
" preceeding content or uricontent options");
SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "within needs two "
"preceeding content or uricontent options");
goto error;
}
/* Set the relative next flag on the prev sigmatch */
if (pm->type == DETECT_URICONTENT) {
ud = (DetectUricontentData *)pm->ctx;
ud->flags |= DETECT_URICONTENT_RELATIVE_NEXT;
} else {
SCLogError(SC_ERR_RULE_KEYWORD_UNKNOWN, "Unknown previous-previous keyword!\n");
goto error;
switch (pm->type) {
case DETECT_URICONTENT:
/* Set the relative next flag on the prev sigmatch */
ud = (DetectUricontentData *)pm->ctx;
if (ud == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-"
"previous keyword!");
goto error;
}
ud->flags |= DETECT_URICONTENT_RELATIVE_NEXT;
break;
case DETECT_PCRE:
pe = (DetectPcreData *) pm->ctx;
if (pe == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-"
"previous keyword!");
goto error;
}
pe->flags |= DETECT_PCRE_RELATIVE_NEXT;
break;
case DETECT_BYTEJUMP:
SCLogDebug("No setting relative_next for bytejump. We "
"have no use for it");
break;
default:
/* this will never hit */
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-"
"previous keyword!");
break;
}
DetectUricontentPrint(ud);
break;
break;
case DETECT_CONTENT:
cd = (DetectContentData *)pm->ctx;
@ -249,8 +282,6 @@ static int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, char *withi
DETECT_CONTENT, pm->prev,
DETECT_PCRE, pm->prev,
DETECT_BYTEJUMP, pm->prev);
DetectPcreData *pe = NULL;
if (pm == NULL) {
if (s->alproto == ALPROTO_DCERPC) {
SCLogDebug("content relative without a previous content based "

@ -543,6 +543,8 @@ typedef struct DetectionEngineThreadCtx_ {
/** offset into the payload of the last match by:
* content, pcre, etc */
uint32_t payload_offset;
/* used by pcre match function alone */
uint32_t pcre_match_start_offset;
/** offset into the uri payload of the last match by
* uricontent */

Loading…
Cancel
Save