dce stub content keywords support using dcepayload.c support for all dce related content keywords

remotes/origin/master-1.0.x
Anoop Saldanha 16 years ago committed by Victor Julien
parent 98433f407c
commit 45ea0d914e

@ -58,6 +58,7 @@ detect-engine-siggroup.c detect-engine-siggroup.h \
detect-engine-mpm.c detect-engine-mpm.h \
detect-engine-iponly.c detect-engine-iponly.h \
detect-engine-payload.c detect-engine-payload.h \
detect-engine-dcepayload.c detect-engine-dcepayload.h \
detect-engine-uri.c detect-engine-uri.h \
detect-engine-state.c detect-engine-state.h \
detect-parse.c detect-parse.h \

@ -28,6 +28,8 @@
#include "decode.h"
#include "detect.h"
#include "detect-parse.h"
#include "detect-engine.h"
#include "app-layer.h"
#include "detect-bytejump.h"
#include "detect-content.h"
@ -50,6 +52,7 @@
"(?:\\s*,\\s*((?:multiplier|post_offset)\\s+[^\\s,]+|[^\\s,]+))?" \
"(?:\\s*,\\s*((?:multiplier|post_offset)\\s+[^\\s,]+|[^\\s,]+))?" \
"(?:\\s*,\\s*((?:multiplier|post_offset)\\s+[^\\s,]+|[^\\s,]+))?" \
"(?:\\s*,\\s*((?:multiplier|post_offset)\\s+[^\\s,]+|[^\\s,]+))?" \
"\\s*$"
static pcre *parse_regex;
@ -431,6 +434,7 @@ DetectBytejumpData *DetectBytejumpParse(char *optstr)
if (data->flags & DETECT_BYTEJUMP_LITTLE) {
data->flags ^= DETECT_BYTEJUMP_LITTLE;
}
data->flags |= DETECT_BYTEJUMP_BIG;
} else if (strcasecmp("little", args[i]) == 0) {
data->flags |= DETECT_BYTEJUMP_LITTLE;
} else if (strcasecmp("from_beginning", args[i]) == 0) {
@ -453,6 +457,8 @@ DetectBytejumpData *DetectBytejumpParse(char *optstr)
SCLogError(SC_ERR_INVALID_VALUE, "Malformed post_offset: %s", optstr);
goto error;
}
} else if (strcasecmp("dce", args[i]) == 0) {
data->flags |= DETECT_BYTEJUMP_DCE;
} else {
SCLogError(SC_ERR_INVALID_VALUE, "Unknown option: \"%s\"", args[i]);
goto error;
@ -507,16 +513,52 @@ int DetectBytejumpSetup(DetectEngineCtx *de_ctx, Signature *s, char *optstr)
{
DetectBytejumpData *data = NULL;
SigMatch *sm = NULL;
SigMatch *match = NULL;
SigMatch *match_tail = NULL;
data = DetectBytejumpParse(optstr);
if (data == NULL) goto error;
if (data == NULL)
goto error;
/* check bytejump modifiers against the signature alproto. In case they conflict
* chuck out invalid signature */
if (data->flags & DETECT_BYTEJUMP_DCE) {
if (s->alproto != ALPROTO_DCERPC) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Non dce alproto sig has "
"bytetest with dce enabled");
goto error;
}
if ( (data->flags & DETECT_BYTEJUMP_STRING) ||
(data->flags & DETECT_BYTEJUMP_LITTLE) ||
(data->flags & DETECT_BYTEJUMP_BIG) ||
(data->flags & DETECT_BYTEJUMP_BEGIN) ||
(data->base == DETECT_BYTEJUMP_BASE_DEC) ||
(data->base == DETECT_BYTEJUMP_BASE_HEX) ||
(data->base == DETECT_BYTEJUMP_BASE_OCT) ) {
SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "Invalid option. "
"DCERPC rule holds an invalid modifier for bytejump.");
goto error;
}
}
if (data->flags & DETECT_BYTEJUMP_RELATIVE) {
/** Search for the first previous DetectContent
* SigMatch (it can be the same as this one) */
switch (s->alproto) {
case ALPROTO_DCERPC:
match = s->dmatch;
match_tail = s->dmatch_tail;
break;
default:
match = s->pmatch;
match_tail = s->pmatch_tail;
break;
}
/* Search for the first previous DetectContent SigMatch (it can be the
* same as this one) */
SigMatch *pm = NULL;
pm = SigMatchGetLastSM(s->pmatch_tail, DETECT_CONTENT);
if (pm != NULL) {
if ( (pm = SigMatchGetLastSM(match_tail, DETECT_CONTENT)) != NULL) {
DetectContentData *cd = (DetectContentData *)pm->ctx;
if (cd == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "relative bytejump match "
@ -524,7 +566,8 @@ int DetectBytejumpSetup(DetectEngineCtx *de_ctx, Signature *s, char *optstr)
goto error;
}
cd->flags |= DETECT_CONTENT_RELATIVE_NEXT;
} else if ((pm = SigMatchGetLastSM(s->pmatch_tail, DETECT_PCRE)) != NULL) {
} else if ( (pm = SigMatchGetLastSM(match_tail, DETECT_PCRE)) != NULL) {
DetectPcreData *pe = NULL;
pe = (DetectPcreData *) pm->ctx;
if (pe == NULL) {
@ -532,9 +575,8 @@ int DetectBytejumpSetup(DetectEngineCtx *de_ctx, Signature *s, char *optstr)
goto error;
}
pe->flags |= DETECT_PCRE_RELATIVE;
} else if ((pm = SigMatchGetLastSM(s->pmatch_tail, DETECT_BYTEJUMP)) !=
NULL)
{
} else if ( (pm = SigMatchGetLastSM(match_tail, DETECT_BYTEJUMP)) != NULL) {
DetectBytejumpData *data = NULL;
data = (DetectBytejumpData *)pm->ctx;
if (data == NULL) {
@ -542,6 +584,7 @@ int DetectBytejumpSetup(DetectEngineCtx *de_ctx, Signature *s, char *optstr)
goto error;
}
data->flags |= DETECT_BYTEJUMP_RELATIVE;
} else {
SCLogError(SC_ERR_INVALID_SIGNATURE, "relative bytejump match "
"needs a previous content option");
@ -556,7 +599,18 @@ int DetectBytejumpSetup(DetectEngineCtx *de_ctx, Signature *s, char *optstr)
sm->type = DETECT_BYTEJUMP;
sm->ctx = (void *)data;
SigMatchAppendPayload(s,sm);
switch (s->alproto) {
case ALPROTO_DCERPC:
/* If we have a signature that is related to dcerpc, then we add the
* sm to Signature->dmatch. All content inspections for a dce rpc
* alproto is done inside detect-engine-dcepayload.c */
SigMatchAppendDcePayload(s, sm);
break;
default:
SigMatchAppendPayload(s, sm);
break;
}
return 0;
@ -737,6 +791,218 @@ int DetectBytejumpTestParse08(void) {
return result;
}
/**
* \test Test dce option.
*/
int DetectBytejumpTestParse09(void) {
Signature *s = SigAlloc();
int result = 1;
s->alproto = ALPROTO_DCERPC;
result &= (DetectBytejumpSetup(NULL, s, "4,0, align, multiplier 2, "
"post_offset -16,dce") == 0);
result &= (DetectBytejumpSetup(NULL, s, "4,0, multiplier 2, "
"post_offset -16,dce") == 0);
result &= (DetectBytejumpSetup(NULL, s, "4,0,post_offset -16,dce") == 0);
result &= (DetectBytejumpSetup(NULL, s, "4,0,dce") == 0);
result &= (DetectBytejumpSetup(NULL, s, "4,0,dce") == 0);
result &= (DetectBytejumpSetup(NULL, s, "4,0, string, dce") == -1);
result &= (DetectBytejumpSetup(NULL, s, "4,0, big, dce") == -1);
result &= (DetectBytejumpSetup(NULL, s, "4,0, little, dce") == -1);
result &= (DetectBytejumpSetup(NULL, s, "4,0, string, dec, dce") == -1);
result &= (DetectBytejumpSetup(NULL, s, "4,0, string, oct, dce") == -1);
result &= (DetectBytejumpSetup(NULL, s, "4,0, string, hex, dce") == -1);
result &= (DetectBytejumpSetup(NULL, s, "4,0, from_beginning, dce") == -1);
SigFree(s);
return result;
}
int DetectBytejumpTestParse10(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 1;
Signature *s = NULL;
DetectBytejumpData *bd = NULL;
de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing bytejump_body\"; "
"dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
"content:one; byte_jump:4,0,align,multiplier 2, "
"post_offset -16,dce; sid:1;)");
if (de_ctx->sig_list == NULL) {
result = 0;
goto end;
}
s = de_ctx->sig_list;
if (s->dmatch_tail == NULL) {
result = 0;
goto end;
}
result &= (s->dmatch_tail->type == DETECT_BYTEJUMP);
bd = (DetectBytejumpData *)s->dmatch_tail->ctx;
if (!(bd->flags & DETECT_BYTEJUMP_DCE) &&
(bd->flags & DETECT_BYTEJUMP_RELATIVE) &&
(bd->flags & DETECT_BYTEJUMP_STRING) &&
(bd->flags & DETECT_BYTEJUMP_BIG) &&
(bd->flags & DETECT_BYTEJUMP_LITTLE) ) {
result = 0;
goto end;
}
s->next = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing bytejump_body\"; "
"dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
"content:one; byte_jump:4,0,align,multiplier 2, "
"post_offset -16,relative,dce; sid:1;)");
if (s->next == NULL) {
result = 0;
goto end;
}
s = s->next;
if (s->dmatch_tail == NULL) {
result = 0;
goto end;
}
result &= (s->dmatch_tail->type == DETECT_BYTEJUMP);
bd = (DetectBytejumpData *)s->dmatch_tail->ctx;
if (!(bd->flags & DETECT_BYTEJUMP_DCE) &&
!(bd->flags & DETECT_BYTEJUMP_RELATIVE) &&
(bd->flags & DETECT_BYTEJUMP_STRING) &&
(bd->flags & DETECT_BYTEJUMP_BIG) &&
(bd->flags & DETECT_BYTEJUMP_LITTLE) ) {
result = 0;
goto end;
}
s->next = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing bytejump_body\"; "
"dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
"content:one; byte_jump:4,0,align,multiplier 2, "
"post_offset -16; sid:1;)");
if (s->next == NULL) {
result = 0;
goto end;
}
s = s->next;
if (s->dmatch_tail == NULL) {
result = 0;
goto end;
}
result &= (s->dmatch_tail->type == DETECT_BYTEJUMP);
bd = (DetectBytejumpData *)s->dmatch_tail->ctx;
if ((bd->flags & DETECT_BYTEJUMP_DCE) &&
(bd->flags & DETECT_BYTEJUMP_RELATIVE) &&
(bd->flags & DETECT_BYTEJUMP_STRING) &&
(bd->flags & DETECT_BYTEJUMP_BIG) &&
(bd->flags & DETECT_BYTEJUMP_LITTLE) ) {
result = 0;
goto end;
}
end:
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineCtxFree(de_ctx);
return result;
}
int DetectBytejumpTestParse11(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 1;
Signature *s = NULL;
de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
s = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing bytejump_body\"; "
"dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
"content:one; byte_jump:4,0,align,multiplier 2, "
"post_offset -16,string,dce; sid:1;)");
if (s != NULL) {
result = 0;
goto end;
}
s = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing bytejump_body\"; "
"dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
"content:one; byte_jump:4,0,align,multiplier 2, "
"post_offset -16,big,dce; sid:1;)");
if (s != NULL) {
result = 0;
goto end;
}
s = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing bytejump_body\"; "
"dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
"content:one; byte_jump:4,0,align,multiplier 2, "
"post_offset -16,little,dce; sid:1;)");
if (s != NULL) {
result = 0;
goto end;
}
s = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing bytejump_body\"; "
"dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
"content:one; byte_jump:4,0,align,multiplier 2, "
"post_offset -16,string,hex,dce; sid:1;)");
if (s != NULL) {
result = 0;
goto end;
}
s = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing bytejump_body\"; "
"dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
"content:one; byte_jump:4,0,align,multiplier 2, "
"post_offset -16,string,dec,dce; sid:1;)");
if (s != NULL) {
result = 0;
goto end;
}
s = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing bytejump_body\"; "
"dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
"content:one; byte_jump:4,0,align,multiplier 2, "
"post_offset -16,string,oct,dce; sid:1;)");
if (s != NULL) {
result = 0;
goto end;
}
s = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing bytejump_body\"; "
"dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
"content:one; byte_jump:4,0,align,multiplier 2, "
"post_offset -16,from_beginning,dce; sid:1;)");
if (s != NULL) {
result = 0;
goto end;
}
end:
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineCtxFree(de_ctx);
return result;
}
/**
* \test DetectByteJumpTestPacket01 is a test to check matches of
* byte_jump and byte_jump relative works if the previous keyword is pcre
@ -815,6 +1081,9 @@ void DetectBytejumpRegisterTests(void) {
UtRegisterTest("DetectBytejumpTestParse06", DetectBytejumpTestParse06, 1);
UtRegisterTest("DetectBytejumpTestParse07", DetectBytejumpTestParse07, 1);
UtRegisterTest("DetectBytejumpTestParse08", DetectBytejumpTestParse08, 1);
UtRegisterTest("DetectBytejumpTestParse09", DetectBytejumpTestParse09, 1);
UtRegisterTest("DetectBytejumpTestParse10", DetectBytejumpTestParse10, 1);
UtRegisterTest("DetectBytejumpTestParse11", DetectBytejumpTestParse11, 1);
UtRegisterTest("DetectByteJumpTestPacket01", DetectByteJumpTestPacket01, 1);
UtRegisterTest("DetectByteJumpTestPacket02", DetectByteJumpTestPacket02, 1);
#endif /* UNITTESTS */

@ -32,10 +32,12 @@
/** Bytejump Flags */
#define DETECT_BYTEJUMP_BEGIN 0x01 /**< "from_beginning" jump */
#define DETECT_BYTEJUMP_LITTLE 0x02 /**< "little" endian value (default "big") */
#define DETECT_BYTEJUMP_STRING 0x04 /**< "string" value */
#define DETECT_BYTEJUMP_RELATIVE 0x08 /**< "relative" offset */
#define DETECT_BYTEJUMP_ALIGN 0x10 /**< "align" offset */
#define DETECT_BYTEJUMP_LITTLE 0x02 /**< "little" endian value */
#define DETECT_BYTEJUMP_BIG 0x04 /**< "big" endian value */
#define DETECT_BYTEJUMP_STRING 0x08 /**< "string" value */
#define DETECT_BYTEJUMP_RELATIVE 0x10 /**< "relative" offset */
#define DETECT_BYTEJUMP_ALIGN 0x20 /**< "align" offset */
#define DETECT_BYTEJUMP_DCE 0x40 /**< "dce" enabled */
typedef struct DetectBytejumpData_ {
uint8_t nbytes; /**< Number of bytes to compare */

@ -27,11 +27,13 @@
#include "debug.h"
#include "decode.h"
#include "detect.h"
#include "detect-engine.h"
#include "detect-parse.h"
#include "detect-content.h"
#include "detect-bytetest.h"
#include "detect-bytejump.h"
#include "app-layer.h"
#include "util-byte.h"
#include "util-unittest.h"
@ -52,6 +54,7 @@
"(?:\\s*,\\s*([^\\s,]+))?" \
"(?:\\s*,\\s*([^\\s,]+))?" \
"(?:\\s*,\\s*([^\\s,]+))?" \
"(?:\\s*,\\s*([^\\s,]+))?" \
"\\s*$"
static pcre *parse_regex;
@ -469,8 +472,11 @@ DetectBytetestData *DetectBytetestParse(char *optstr)
if (data->flags & DETECT_BYTETEST_LITTLE) {
data->flags ^= DETECT_BYTETEST_LITTLE;
}
data->flags |= DETECT_BYTETEST_BIG;
} else if (strcasecmp("little", args[i]) == 0) {
data->flags |= DETECT_BYTETEST_LITTLE;
} else if (strcasecmp("dce", args[i]) == 0) {
data->flags |= DETECT_BYTETEST_DCE;
} else {
SCLogError(SC_ERR_UNKNOWN_VALUE, "Unknown value: \"%s\"",
args[i]);
@ -524,18 +530,53 @@ int DetectBytetestSetup(DetectEngineCtx *de_ctx, Signature *s, char *optstr)
{
DetectBytetestData *data = NULL;
SigMatch *sm = NULL;
SigMatch *match = NULL;
SigMatch *match_tail = NULL;
//printf("DetectBytetestSetup: \'%s\'\n", optstr);
data = DetectBytetestParse(optstr);
if (data == NULL) goto error;
if (data == NULL)
goto error;
/* check bytetest modifiers against the signature alproto. In case they conflict
* chuck out invalid signature */
if (data-> flags & DETECT_BYTETEST_DCE) {
if (s->alproto != ALPROTO_DCERPC) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Non dce alproto sig has "
"bytetest with dce enabled");
goto error;
}
if ( (data->flags & DETECT_BYTETEST_STRING) ||
(data->flags & DETECT_BYTETEST_LITTLE) ||
(data->flags & DETECT_BYTETEST_BIG) ||
(data->base == DETECT_BYTETEST_BASE_DEC) ||
(data->base == DETECT_BYTETEST_BASE_HEX) ||
(data->base == DETECT_BYTETEST_BASE_OCT) ) {
SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "Invalid option. "
"a byte_test keyword with dce holds other invalid modifiers.");
goto error;
}
}
if (data->flags & DETECT_BYTETEST_RELATIVE) {
/** Search for the first previous DetectContent
* SigMatch (it can be the same as this one) */
switch (s->alproto) {
case ALPROTO_DCERPC:
match = s->dmatch;
match_tail = s->dmatch_tail;
break;
default:
match = s->pmatch;
match_tail = s->pmatch_tail;
break;
}
/* Search for the first previous DetectContent SigMatch (it can be the
* same as this one) */
SigMatch *pm = NULL;
pm = SigMatchGetLastSM(s->pmatch_tail, DETECT_CONTENT);
if (pm != NULL) {
if ( (pm = SigMatchGetLastSM(match_tail, DETECT_CONTENT)) != NULL) {
DetectContentData *cd = (DetectContentData *) pm->ctx;
if (cd == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "relative bytetest match "
@ -543,7 +584,8 @@ int DetectBytetestSetup(DetectEngineCtx *de_ctx, Signature *s, char *optstr)
goto error;
}
cd->flags |= DETECT_CONTENT_RELATIVE_NEXT;
} else if ((pm = SigMatchGetLastSM(s->pmatch_tail, DETECT_PCRE)) != NULL) {
} else if ( (pm = SigMatchGetLastSM(match_tail, DETECT_PCRE)) != NULL) {
DetectPcreData *pe = NULL;
pe = (DetectPcreData *) pm->ctx;
if (pe == NULL) {
@ -551,9 +593,8 @@ int DetectBytetestSetup(DetectEngineCtx *de_ctx, Signature *s, char *optstr)
goto error;
}
pe->flags |= DETECT_PCRE_RELATIVE;
} else if ((pm = SigMatchGetLastSM(s->pmatch_tail, DETECT_BYTEJUMP)) !=
NULL)
{
} else if ( (pm = SigMatchGetLastSM(match_tail, DETECT_BYTEJUMP)) != NULL) {
DetectBytejumpData *data = NULL;
data = (DetectBytejumpData *)pm->ctx;
if (data == NULL) {
@ -561,6 +602,7 @@ int DetectBytetestSetup(DetectEngineCtx *de_ctx, Signature *s, char *optstr)
goto error;
}
data->flags |= DETECT_BYTEJUMP_RELATIVE;
} else {
SCLogError(SC_ERR_INVALID_SIGNATURE, "relative bytetest match "
"needs a previous content option");
@ -575,7 +617,18 @@ int DetectBytetestSetup(DetectEngineCtx *de_ctx, Signature *s, char *optstr)
sm->type = DETECT_BYTETEST;
sm->ctx = (void *)data;
SigMatchAppendPayload(s,sm);
switch (s->alproto) {
case ALPROTO_DCERPC:
/* If we have a signature that is related to dcerpc, then we add the
* sm to Signature->dmatch. All content inspections for a dce rpc
* alproto is done inside detect-engine-dcepayload.c */
SigMatchAppendDcePayload(s, sm);
break;
default:
SigMatchAppendPayload(s, sm);
break;
}
return 0;
@ -745,7 +798,7 @@ int DetectBytetestTestParse07(void) {
&& (data->nbytes == 4)
&& (data->value == 5)
&& (data->offset == 0)
&& (data->flags == 0)
&& (data->flags == 4)
&& (data->base == DETECT_BYTETEST_BASE_UNSET))
{
result = 1;
@ -930,6 +983,282 @@ int DetectBytetestTestParse16(void) {
return result;
}
/**
* \test Test dce option.
*/
int DetectBytetestTestParse17(void) {
int result = 0;
DetectBytetestData *data = NULL;
data = DetectBytetestParse("4, <, 5, 0, dce");
if (data != NULL) {
if ( (data->op == DETECT_BYTETEST_OP_LT) &&
(data->nbytes == 4) &&
(data->value == 5) &&
(data->offset == 0) &&
(data->flags & DETECT_BYTETEST_DCE) ) {
result = 1;
}
DetectBytetestFree(data);
}
return result;
}
/**
* \test Test dce option.
*/
int DetectBytetestTestParse18(void) {
int result = 0;
DetectBytetestData *data = NULL;
data = DetectBytetestParse("4, <, 5, 0");
if (data != NULL) {
if ( (data->op == DETECT_BYTETEST_OP_LT) &&
(data->nbytes == 4) &&
(data->value == 5) &&
(data->offset == 0) &&
!(data->flags & DETECT_BYTETEST_DCE) ) {
result = 1;
}
DetectBytetestFree(data);
}
return result;
}
/**
* \test Test dce option.
*/
int DetectBytetestTestParse19(void) {
Signature *s = SigAlloc();
int result = 1;
s->alproto = ALPROTO_DCERPC;
result &= (DetectBytetestSetup(NULL, s, "1,=,1,6,dce") == 0);
result &= (DetectBytetestSetup(NULL, s, "1,=,1,6,string,dce") == -1);
result &= (DetectBytetestSetup(NULL, s, "1,=,1,6,big,dce") == -1);
result &= (DetectBytetestSetup(NULL, s, "1,=,1,6,little,dce") == -1);
result &= (DetectBytetestSetup(NULL, s, "1,=,1,6,hex,dce") == -1);
result &= (DetectBytetestSetup(NULL, s, "1,=,1,6,oct,dce") == -1);
result &= (DetectBytetestSetup(NULL, s, "1,=,1,6,dec,dce") == -1);
SigFree(s);
return result;
}
int DetectBytetestTestParse20(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 1;
Signature *s = NULL;
DetectBytetestData *bd = NULL;
de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing bytetest_body\"; "
"dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
"content:one; byte_test:1,=,1,6,dce; sid:1;)");
if (de_ctx->sig_list == NULL) {
result = 0;
goto end;
}
s = de_ctx->sig_list;
if (s->dmatch_tail == NULL) {
result = 0;
goto end;
}
result &= (s->dmatch_tail->type == DETECT_BYTETEST);
bd = (DetectBytetestData *)s->dmatch_tail->ctx;
if (!(bd->flags & DETECT_BYTETEST_DCE) &&
(bd->flags & DETECT_BYTETEST_RELATIVE) &&
(bd->flags & DETECT_BYTETEST_STRING) &&
(bd->flags & DETECT_BYTETEST_BIG) &&
(bd->flags & DETECT_BYTETEST_LITTLE) &&
(bd->flags & DETECT_BYTETEST_NEGOP) ) {
result = 0;
goto end;
}
s->next = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing bytetest_body\"; "
"dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
"content:one; byte_test:1,=,1,6,relative,dce; sid:1;)");
if (s->next == NULL) {
result = 0;
goto end;
}
s = s->next;
if (s->dmatch_tail == NULL) {
result = 0;
goto end;
}
result &= (s->dmatch_tail->type == DETECT_BYTETEST);
bd = (DetectBytetestData *)s->dmatch_tail->ctx;
if (!(bd->flags & DETECT_BYTETEST_DCE) &&
!(bd->flags & DETECT_BYTETEST_RELATIVE) &&
(bd->flags & DETECT_BYTETEST_STRING) &&
(bd->flags & DETECT_BYTETEST_BIG) &&
(bd->flags & DETECT_BYTETEST_LITTLE) &&
(bd->flags & DETECT_BYTETEST_NEGOP) ) {
result = 0;
goto end;
}
s->next = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing bytetest_body\"; "
"dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
"content:one; byte_test:1,=,1,6; sid:1;)");
if (s->next == NULL) {
result = 0;
goto end;
}
s = s->next;
if (s->dmatch_tail == NULL) {
result = 0;
goto end;
}
result &= (s->dmatch_tail->type == DETECT_BYTETEST);
bd = (DetectBytetestData *)s->dmatch_tail->ctx;
if ((bd->flags & DETECT_BYTETEST_DCE) &&
(bd->flags & DETECT_BYTETEST_RELATIVE) &&
(bd->flags & DETECT_BYTETEST_STRING) &&
(bd->flags & DETECT_BYTETEST_BIG) &&
(bd->flags & DETECT_BYTETEST_LITTLE) &&
(bd->flags & DETECT_BYTETEST_NEGOP) ) {
result = 0;
goto end;
}
end:
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineCtxFree(de_ctx);
return result;
}
int DetectBytetestTestParse21(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 1;
Signature *s = NULL;
de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
s = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing bytetest_body\"; "
"dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
"content:one; byte_test:1,=,1,6,string,dce; sid:1;)");
if (s != NULL) {
result = 0;
goto end;
}
s = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing bytetest_body\"; "
"dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
"content:one; byte_test:1,=,1,6,big,dce; sid:1;)");
if (s != NULL) {
result = 0;
goto end;
}
s = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing bytetest_body\"; "
"dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
"content:one; byte_test:1,=,1,6,little,dce; sid:1;)");
if (s != NULL) {
result = 0;
goto end;
}
s = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing bytetest_body\"; "
"dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
"content:one; byte_test:1,=,1,6,hex,dce; sid:1;)");
if (s != NULL) {
result = 0;
goto end;
}
s = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing bytetest_body\"; "
"dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
"content:one; byte_test:1,=,1,6,dec,dce; sid:1;)");
if (s != NULL) {
result = 0;
goto end;
}
s = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing bytetest_body\"; "
"dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
"content:one; byte_test:1,=,1,6,oct,dce; sid:1;)");
if (s != NULL) {
result = 0;
goto end;
}
s = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing bytetest_body\"; "
"dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
"content:one; byte_test:1,=,1,6,string,hex,dce; sid:1;)");
if (s != NULL) {
result = 0;
goto end;
}
s = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing bytetest_body\"; "
"dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
"content:one; byte_test:1,=,1,6,big,string,hex,dce; sid:1;)");
if (s != NULL) {
result = 0;
goto end;
}
s = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing bytetest_body\"; "
"dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
"content:one; byte_test:1,=,1,6,big,string,oct,dce; sid:1;)");
if (s != NULL) {
result = 0;
goto end;
}
s = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing bytetest_body\"; "
"dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
"content:one; byte_test:1,=,1,6,little,string,hex,dce; sid:1;)");
if (s != NULL) {
result = 0;
goto end;
}
s = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing bytetest_body\"; "
"dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
"content:one; byte_test:1,=,1,6,big,string,dec,dce; sid:1;)");
if (s != NULL) {
result = 0;
goto end;
}
end:
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineCtxFree(de_ctx);
return result;
}
/**
* \test DetectByteTestTestPacket01 is a test to check matches of
* byte_test and byte_test relative works if the previous keyword is pcre
@ -1014,6 +1343,11 @@ void DetectBytetestRegisterTests(void) {
UtRegisterTest("DetectBytetestTestParse13", DetectBytetestTestParse13, 1);
UtRegisterTest("DetectBytetestTestParse14", DetectBytetestTestParse14, 1);
UtRegisterTest("DetectBytetestTestParse15", DetectBytetestTestParse15, 1);
UtRegisterTest("DetectBytetestTestParse17", DetectBytetestTestParse17, 1);
UtRegisterTest("DetectBytetestTestParse18", DetectBytetestTestParse18, 1);
UtRegisterTest("DetectBytetestTestParse19", DetectBytetestTestParse19, 1);
UtRegisterTest("DetectBytetestTestParse20", DetectBytetestTestParse20, 1);
UtRegisterTest("DetectBytetestTestParse21", DetectBytetestTestParse21, 1);
UtRegisterTest("DetectByteTestTestPacket01", DetectByteTestTestPacket01, 1);
UtRegisterTest("DetectByteTestTestPacket02", DetectByteTestTestPacket02, 1);
#endif /* UNITTESTS */

@ -39,9 +39,11 @@
/** Bytetest Flags */
#define DETECT_BYTETEST_NEGOP 0x01 /**< "!" negated operator */
#define DETECT_BYTETEST_LITTLE 0x02 /**< "little" endian value (default "big") */
#define DETECT_BYTETEST_STRING 0x04 /**< "string" value */
#define DETECT_BYTETEST_RELATIVE 0x08 /**< "relative" offset */
#define DETECT_BYTETEST_LITTLE 0x02 /**< "little" endian value */
#define DETECT_BYTETEST_BIG 0x04 /**< "bi" endian value */
#define DETECT_BYTETEST_STRING 0x08 /**< "string" value */
#define DETECT_BYTETEST_RELATIVE 0x10 /**< "relative" offset */
#define DETECT_BYTETEST_DCE 0x20 /**< dce enabled */
typedef struct DetectBytetestData_ {
uint8_t nbytes; /**< Number of bytes to compare */

@ -35,6 +35,7 @@
#include "flow.h"
#include "flow-var.h"
#include "detect-flow.h"
#include "app-layer.h"
#include "util-unittest.h"
#include "util-print.h"
#include "util-debug.h"
@ -434,7 +435,19 @@ static int DetectContentSetup (DetectEngineCtx *de_ctx, Signature *s, char *cont
DetectContentPrint(cd);
SigMatchAppendPayload(s,sm);
switch (s->alproto) {
case ALPROTO_DCERPC:
/* If we have a signature that is related to dcerpc, then we add the
* sm to Signature->dmatch. All content inspections for a dce rpc
* alproto is done inside detect-engine-dcepayload.c */
SigMatchAppendDcePayload(s, sm);
break;
default:
SigMatchAppendPayload(s, sm);
break;
}
return 0;
error:
@ -1060,6 +1073,296 @@ end:
return result;
}
int DetectContentParseTest18(void)
{
Signature *s = SigAlloc();
int result = 1;
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL) {
result = 0;
goto end;
}
s->alproto = ALPROTO_DCERPC;
result &= (DetectContentSetup(de_ctx, s, "one") == 0);
result &= (s->dmatch != NULL);
SigFree(s);
s = SigAlloc();
/* failure since we have no preceding content/pcre/bytejump */
result &= (DetectContentSetup(de_ctx, s, "one") == 0);
result &= (s->dmatch == NULL);
result &= (s->pmatch != NULL);
end:
SigFree(s);
DetectEngineCtxFree(de_ctx);
return result;
}
int DetectContentParseTest19(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 1;
Signature *s = NULL;
DetectContentData *data = NULL;
de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing bytejump_body\"; "
"dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
"content:one; sid:1;)");
if (de_ctx->sig_list == NULL) {
result = 0;
goto end;
}
s = de_ctx->sig_list;
if (s->dmatch_tail == NULL) {
result = 0;
goto end;
}
result &= (s->dmatch_tail->type == DETECT_CONTENT);
result &= (s->pmatch == NULL);
data = (DetectContentData *)s->dmatch_tail->ctx;
if (data->flags & DETECT_CONTENT_RAWBYTES ||
data->flags & DETECT_CONTENT_NOCASE ||
data->flags & DETECT_CONTENT_WITHIN ||
data->flags & DETECT_CONTENT_DISTANCE ||
data->flags & DETECT_CONTENT_FAST_PATTERN ||
data->flags & DETECT_CONTENT_NEGATED ) {
result = 0;
goto end;
}
s->next = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing bytejump_body\"; "
"dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
"content:one; content:two; within:10; sid:1;)");
if (s->next == NULL) {
result = 0;
goto end;
}
s = s->next;
if (s->dmatch_tail == NULL) {
result = 0;
goto end;
}
result &= (s->dmatch_tail->type == DETECT_CONTENT);
result &= (s->pmatch == NULL);
data = (DetectContentData *)s->dmatch_tail->ctx;
if (data->flags & DETECT_CONTENT_RAWBYTES ||
data->flags & DETECT_CONTENT_NOCASE ||
!(data->flags & DETECT_CONTENT_WITHIN) ||
data->flags & DETECT_CONTENT_DISTANCE ||
data->flags & DETECT_CONTENT_FAST_PATTERN ||
data->flags & DETECT_CONTENT_NEGATED ) {
result = 0;
goto end;
}
result &= (data->within == 10);
s->next = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing bytejump_body\"; "
"dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
"content:one; offset:5; depth:9; content:two; within:10; offset:10; depth:13; sid:1;)");
if (s->next == NULL) {
result = 0;
goto end;
}
s = s->next;
if (s->dmatch_tail == NULL) {
result = 0;
goto end;
}
result &= (s->dmatch_tail->type == DETECT_CONTENT);
result &= (s->pmatch == NULL);
data = (DetectContentData *)s->dmatch_tail->ctx;
if (data->flags & DETECT_CONTENT_RAWBYTES ||
data->flags & DETECT_CONTENT_NOCASE ||
!(data->flags & DETECT_CONTENT_WITHIN) ||
data->flags & DETECT_CONTENT_DISTANCE ||
data->flags & DETECT_CONTENT_FAST_PATTERN ||
data->flags & DETECT_CONTENT_NEGATED ) {
result = 0;
goto end;
}
result &= (data->within == 10 && data->offset == 10 && data->depth == 13);
data = (DetectContentData *)s->dmatch->ctx;
if (data->flags & DETECT_CONTENT_RAWBYTES ||
data->flags & DETECT_CONTENT_NOCASE ||
data->flags & DETECT_CONTENT_WITHIN ||
data->flags & DETECT_CONTENT_DISTANCE ||
data->flags & DETECT_CONTENT_FAST_PATTERN ||
data->flags & DETECT_CONTENT_NEGATED ) {
result = 0;
goto end;
}
result &= (data->offset == 5 && data->depth == 9);
s->next = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing bytejump_body\"; "
"dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
"content:one; content:two; distance:2; sid:1;)");
if (s->next == NULL) {
result = 0;
goto end;
}
s = s->next;
if (s->dmatch_tail == NULL) {
result = 0;
goto end;
}
result &= (s->dmatch_tail->type == DETECT_CONTENT);
result &= (s->pmatch == NULL);
data = (DetectContentData *)s->dmatch_tail->ctx;
if (data->flags & DETECT_CONTENT_RAWBYTES ||
data->flags & DETECT_CONTENT_NOCASE ||
data->flags & DETECT_CONTENT_WITHIN ||
!(data->flags & DETECT_CONTENT_DISTANCE) ||
data->flags & DETECT_CONTENT_FAST_PATTERN ||
data->flags & DETECT_CONTENT_NEGATED ) {
result = 0;
goto end;
}
result &= (data->distance == 2);
s->next = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing bytejump_body\"; "
"dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
"content:one; content:two; within:10; distance:2; sid:1;)");
if (s->next == NULL) {
result = 0;
goto end;
}
s = s->next;
if (s->dmatch_tail == NULL) {
result = 0;
goto end;
}
result &= (s->dmatch_tail->type == DETECT_CONTENT);
result &= (s->pmatch == NULL);
data = (DetectContentData *)s->dmatch_tail->ctx;
if (data->flags & DETECT_CONTENT_RAWBYTES ||
data->flags & DETECT_CONTENT_NOCASE ||
!(data->flags & DETECT_CONTENT_WITHIN) ||
!(data->flags & DETECT_CONTENT_DISTANCE) ||
data->flags & DETECT_CONTENT_FAST_PATTERN ||
data->flags & DETECT_CONTENT_NEGATED ) {
result = 0;
goto end;
}
result &= (data->within == 10 && data->distance == 2);
s->next = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing bytejump_body\"; "
"dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
"content:one; offset:10; sid:1;)");
if (s->next == NULL) {
result = 0;
goto end;
}
s = s->next;
if (s->dmatch_tail == NULL) {
result = 0;
goto end;
}
result &= (s->dmatch_tail->type == DETECT_CONTENT);
result &= (s->pmatch == NULL);
data = (DetectContentData *)s->dmatch_tail->ctx;
if (data->flags & DETECT_CONTENT_RAWBYTES ||
data->flags & DETECT_CONTENT_NOCASE ||
data->flags & DETECT_CONTENT_WITHIN ||
data->flags & DETECT_CONTENT_DISTANCE ||
data->flags & DETECT_CONTENT_FAST_PATTERN ||
data->flags & DETECT_CONTENT_NEGATED ) {
result = 0;
goto end;
}
result &= (data->offset == 10);
s->next = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing bytejump_body\"; "
"dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
"content:one; depth:10; sid:1;)");
if (s->next == NULL) {
result = 0;
goto end;
}
s = s->next;
if (s->dmatch_tail == NULL) {
result = 0;
goto end;
}
result &= (s->dmatch_tail->type == DETECT_CONTENT);
result &= (s->pmatch == NULL);
data = (DetectContentData *)s->dmatch_tail->ctx;
if (data->flags & DETECT_CONTENT_RAWBYTES ||
data->flags & DETECT_CONTENT_NOCASE ||
data->flags & DETECT_CONTENT_WITHIN ||
data->flags & DETECT_CONTENT_DISTANCE ||
data->flags & DETECT_CONTENT_FAST_PATTERN ||
data->flags & DETECT_CONTENT_NEGATED ) {
result = 0;
goto end;
}
result &= (data->depth == 10);
s->next = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing bytejump_body\"; "
"dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
"content:one; offset:10; depth:2; sid:1;)");
if (s->next == NULL) {
result = 0;
goto end;
}
s = s->next;
if (s->dmatch_tail == NULL) {
result = 0;
goto end;
}
result &= (s->dmatch_tail->type == DETECT_CONTENT);
result &= (s->pmatch == NULL);
data = (DetectContentData *)s->dmatch_tail->ctx;
if (data->flags & DETECT_CONTENT_RAWBYTES ||
data->flags & DETECT_CONTENT_NOCASE ||
data->flags & DETECT_CONTENT_WITHIN ||
data->flags & DETECT_CONTENT_DISTANCE ||
data->flags & DETECT_CONTENT_FAST_PATTERN ||
data->flags & DETECT_CONTENT_NEGATED ) {
result = 0;
goto end;
}
result &= (data->offset == 10 && data->depth == 13);
s->next = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing bytejump_body\"; "
"content:one; sid:1;)");
if (s->next == NULL) {
result = 0;
goto end;
}
s = s->next;
if (s->dmatch_tail != NULL) {
result = 0;
goto end;
}
result &= (s->pmatch != NULL);
end:
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineCtxFree(de_ctx);
return result;
}
static int SigTestPositiveTestContent(char *rule, uint8_t *buf)
{
uint16_t buflen = strlen((char *)buf);
@ -1502,6 +1805,8 @@ void DetectContentRegisterTests(void)
UtRegisterTest("DetectContentParseTest15", DetectContentParseNegTest15, 1);
UtRegisterTest("DetectContentParseTest16", DetectContentParseNegTest16, 1);
UtRegisterTest("DetectContentParseTest17", DetectContentParseTest17, 1);
UtRegisterTest("DetectContentParseTest18", DetectContentParseTest18, 1);
UtRegisterTest("DetectContentParseTest19", DetectContentParseTest19, 1);
/* The reals */
UtRegisterTest("DetectContentLongPatternMatchTest01", DetectContentLongPatternMatchTest01, 1);

@ -98,16 +98,19 @@ int DetectDceStubDataMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow *
dcerpc_state->dcerpc.dcerpcrequest.stub_data_processed == 1) {
return 0;
}
dcerpc_state->dcerpc.dcerpcrequest.stub_data_processed = 1;
//dcerpc_state->dcerpc.dcerpcrequest.stub_data_processed = 1;
det_ctx->dce_stub_data = dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer;
det_ctx->dce_stub_data_len = dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer_len;
} else {
if (dcerpc_state->dcerpc.dcerpcresponse.stub_data_buffer == NULL ||
dcerpc_state->dcerpc.dcerpcresponse.stub_data_processed == 1) {
return 0;
}
dcerpc_state->dcerpc.dcerpcresponse.stub_data_processed = 1;
//dcerpc_state->dcerpc.dcerpcresponse.stub_data_processed = 1;
det_ctx->dce_stub_data = dcerpc_state->dcerpc.dcerpcresponse.stub_data_buffer;
det_ctx->dce_stub_data_len = dcerpc_state->dcerpc.dcerpcresponse.stub_data_buffer_len;
}
return 1;
}

@ -31,8 +31,10 @@
#include "detect-parse.h"
#include "detect-content.h"
#include "detect-uricontent.h"
#include "detect-parse.h"
#include "flow-var.h"
#include "app-layer.h"
#include "util-debug.h"
@ -52,6 +54,7 @@ static int DetectDepthSetup (DetectEngineCtx *de_ctx, Signature *s, char *depths
{
char *str = depthstr;
char dubbed = 0;
SigMatch *pm = NULL;
/* strip "'s */
if (depthstr[0] == '\"' && depthstr[strlen(depthstr)-1] == '\"') {
@ -60,14 +63,35 @@ static int DetectDepthSetup (DetectEngineCtx *de_ctx, Signature *s, char *depths
dubbed = 1;
}
/** Search for the first previous DetectContent or uricontent
* SigMatch (it can be the same as this one) */
SigMatch *pm = SigMatchGetLastPattern(s);
if (pm == NULL) {
SCLogError(SC_ERR_DEPTH_MISSING_CONTENT, "depth needs a preceeding "
"content or uricontent option");
if (dubbed) SCFree(str);
return -1;
switch (s->alproto) {
case ALPROTO_DCERPC:
/* If we have a signature that is related to dcerpc, then we add the
* sm to Signature->dmatch. All content inspections for a dce rpc
* alproto is done inside detect-engine-dcepayload.c */
pm = SigMatchGetLastSMFromLists(s, 2, DETECT_CONTENT, s->dmatch_tail);
if (pm == NULL) {
SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "depth needs"
"preceeding content option for dcerpc sig");
if (dubbed)
SCFree(str);
return -1;
}
break;
default:
pm = SigMatchGetLastSMFromLists(s, 4,
DETECT_CONTENT, s->pmatch_tail,
DETECT_URICONTENT, s->umatch_tail);
if (pm == NULL) {
SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "distance needs"
"preceeding content or uricontent option");
if (dubbed)
SCFree(str);
return -1;
}
break;
}
switch (pm->type) {

@ -30,6 +30,8 @@
#include "detect.h"
#include "detect-parse.h"
#include "detect-engine.h"
#include "app-layer.h"
#include "detect-parse.h"
#include "detect-content.h"
#include "detect-uricontent.h"
@ -59,6 +61,8 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s,
{
char *str = distancestr;
char dubbed = 0;
SigMatch *pm = NULL;
SigMatch *match_tail = NULL;
/* strip "'s */
if (distancestr[0] == '\"' && distancestr[strlen(distancestr)-1] == '\"') {
@ -67,14 +71,35 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s,
dubbed = 1;
}
/** Search for the first previous DetectContent
* SigMatch (it can be the same as this one) */
SigMatch *pm = SigMatchGetLastPattern(s);
if (pm == NULL) {
SCLogError(SC_ERR_DISTANCE_MISSING_CONTENT, "distance needs two "
"preceeding content or uricontent options");
if (dubbed) SCFree(str);
return -1;
switch (s->alproto) {
case ALPROTO_DCERPC:
/* If we have a signature that is related to dcerpc, then we add the
* sm to Signature->dmatch. All content inspections for a dce rpc
* alproto is done inside detect-engine-dcepayload.c */
pm = SigMatchGetLastSMFromLists(s, 2, DETECT_CONTENT, s->dmatch_tail);
if (pm == NULL) {
SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "distance needs"
"preceeding content option for dcerpc sig");
if (dubbed)
SCFree(str);
return -1;
}
break;
default:
pm = SigMatchGetLastSMFromLists(s, 4,
DETECT_CONTENT, s->pmatch_tail,
DETECT_URICONTENT, s->umatch_tail);
if (pm == NULL) {
SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "distance needs"
"preceeding content or uricontent option");
if (dubbed)
SCFree(str);
return -1;
}
break;
}
DetectUricontentData *ud = NULL;
@ -130,8 +155,17 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s,
}
}
pm = SigMatchGetLastSM(s->pmatch_tail->prev, DETECT_CONTENT);
if (pm != NULL) {
switch (s->alproto) {
case ALPROTO_DCERPC:
match_tail = s->dmatch_tail;
break;
default:
match_tail = s->pmatch_tail;
break;
}
if ( (pm = SigMatchGetLastSM(match_tail->prev, DETECT_CONTENT)) != NULL) {
/* Set the relative next flag on the prev sigmatch */
cd = (DetectContentData *)pm->ctx;
if (cd == NULL) {
@ -140,9 +174,8 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s,
goto error;
}
cd->flags |= DETECT_CONTENT_RELATIVE_NEXT;
} else if ((pm = SigMatchGetLastSM(s->pmatch_tail, DETECT_BYTEJUMP))
!= NULL)
{
} else if ( (pm = SigMatchGetLastSM(match_tail->prev, DETECT_BYTEJUMP)) != NULL) {
DetectBytejumpData *data = NULL;
data = (DetectBytejumpData *) pm->ctx;
if (data == NULL) {
@ -150,9 +183,10 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s,
goto error;
}
data->flags |= DETECT_BYTEJUMP_RELATIVE;
} else {
SCLogError(SC_ERR_DISTANCE_MISSING_CONTENT, "distance needs two"
" preceeding content or uricontent options");
SCLogError(SC_ERR_DISTANCE_MISSING_CONTENT, "distance needs two "
"preceeding content or uricontent options");
goto error;
}
@ -160,7 +194,7 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s,
default:
SCLogError(SC_ERR_DISTANCE_MISSING_CONTENT, "distance needs two "
"preceeding content or uricontent options");
"preceeding content or uricontent options");
if (dubbed) SCFree(str);
return -1;
break;

File diff suppressed because it is too large Load Diff

@ -0,0 +1,31 @@
/* Copyright (C) 2007-2010 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
/**
* \file
*
* \author Victor Julien <victor@inliniac.net>
*/
#ifndef __DETECT_ENGINE_DCEPAYLOAD_H__
#define __DETECT_ENGINE_DCEPAYLOAD_H__
int DetectEngineInspectDcePayload(DetectEngineCtx *, DetectEngineThreadCtx *,
Signature *, Flow *, uint8_t, void *, Packet *);
void DcePayloadRegisterTests(void);
#endif /* __DETECT_ENGINE_DCEPAYLOAD_H__ */

@ -27,7 +27,9 @@
#include "debug.h"
#include "decode.h"
#include "detect.h"
#include "detect-engine.h"
#include "detect-parse.h"
#include "app-layer.h"
#include "util-unittest.h"
#include "util-unittest-helper.h"
@ -217,8 +219,8 @@ error:
}
/**
* \brief this function is used to add the parsed isdataatdata into the current signature
*
* \brief This function is used to add the parsed isdataatdata into the current
* signature.
* \param de_ctx pointer to the Detection Engine Context
* \param s pointer to the Current Signature
* \param isdataatstr pointer to the user provided isdataat options
@ -230,55 +232,70 @@ int DetectIsdataatSetup (DetectEngineCtx *de_ctx, Signature *s, char *isdataatst
{
DetectIsdataatData *idad = NULL;
SigMatch *sm = NULL;
SigMatch *match = NULL;
SigMatch *match_tail = NULL;
DetectContentData *cd = NULL;
idad = DetectIsdataatParse(isdataatstr);
if (idad == NULL) goto error;
if(idad->flags & ISDATAAT_RELATIVE) {
/** Set it in the last parsed contet because it is relative to that content match */
SCLogDebug("set it in the last parsed content because it is relative to that content match");
if (idad->flags & ISDATAAT_RELATIVE) {
/* Set it in the last parsed contet because it is relative to that
* content match */
SCLogDebug("set it in the last parsed content because it is relative "
"to that content match");
switch (s->alproto) {
case ALPROTO_DCERPC:
match = s->dmatch;
match_tail = s->dmatch_tail;
break;
default:
match = s->pmatch;
match_tail = s->pmatch_tail;
break;
}
if (s->pmatch_tail == NULL) {
if (match_tail == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "No previous content, the flag "
"'relative' cant be used without content");
"'relative' cant be used without content");
goto error;
}
SigMatch *pm = NULL;
/** Search for the first previous DetectContent
* SigMatch (it can be the same as this one) */
pm = SigMatchGetLastSM(s->pmatch_tail, DETECT_CONTENT);
if (pm != NULL) {
cd = (DetectContentData *)pm->ctx;
SigMatch *m = NULL;
/* Search for the first previous DetectContent SigMatch (it can be the
* same as this one) */
if ( (m = SigMatchGetLastSM(match_tail, DETECT_CONTENT)) != NULL) {
cd = (DetectContentData *)m->ctx;
if (cd == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous keyword!");
goto error;
}
cd->flags |= DETECT_CONTENT_RELATIVE_NEXT;
} else if ((pm = SigMatchGetLastSM(s->pmatch_tail, DETECT_PCRE)) != NULL) {
} else if ( (m = SigMatchGetLastSM(match_tail, DETECT_PCRE)) != NULL) {
DetectPcreData *pe = NULL;
pe = (DetectPcreData *) pm->ctx;
pe = (DetectPcreData *)m->ctx;
if (pe == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous keyword!");
goto error;
}
pe->flags |= DETECT_PCRE_RELATIVE;
} else if ((pm = SigMatchGetLastSM(s->pmatch_tail, DETECT_BYTEJUMP)) !=
NULL)
{
} else if ( (m = SigMatchGetLastSM(match_tail, DETECT_BYTEJUMP)) != NULL) {
DetectBytejumpData *data = NULL;
data = (DetectBytejumpData *)pm->ctx;
data = (DetectBytejumpData *)m->ctx;
if (data == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous keyword!");
goto error;
}
data->flags |= DETECT_BYTEJUMP_RELATIVE;
} else {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous keyword!");
goto error;
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous keyword!");
goto error;
}
}
@ -289,15 +306,27 @@ int DetectIsdataatSetup (DetectEngineCtx *de_ctx, Signature *s, char *isdataatst
sm->type = DETECT_ISDATAAT;
sm->ctx = (void *)idad;
SigMatchAppendPayload(s, sm);
switch (s->alproto) {
case ALPROTO_DCERPC:
/* If we have a signature that is related to dcerpc, then we add the
* sm to Signature->dmatch. All content inspections for a dce rpc
* alproto is done inside detect-engine-dcepayload.c */
SigMatchAppendDcePayload(s, sm);
break;
default:
SigMatchAppendPayload(s, sm);
break;
}
return 0;
error:
if (idad != NULL) DetectIsdataatFree(idad);
if (sm != NULL) SCFree(sm);
if (idad != NULL)
DetectIsdataatFree(idad);
if (sm != NULL)
SCFree(sm);
return -1;
}
/**
@ -361,6 +390,119 @@ int DetectIsdataatTestParse03 (void) {
return result;
}
int DetectIsdataatTestParse04(void)
{
Signature *s = SigAlloc();
int result = 1;
s->alproto = ALPROTO_DCERPC;
result &= (DetectIsdataatSetup(NULL, s, "30") == 0);
result &= (s->dmatch != NULL);
/* failure since we have no preceding content/pcre/bytejump */
result &= (DetectIsdataatSetup(NULL, s, "30,relative") == -1);
SigFree(s);
return result;
}
int DetectIsdataatTestParse05(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 1;
Signature *s = NULL;
DetectIsdataatData *data = NULL;
de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing bytejump_body\"; "
"dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
"content:one; isdataat:4; sid:1;)");
if (de_ctx->sig_list == NULL) {
result = 0;
goto end;
}
s = de_ctx->sig_list;
if (s->dmatch_tail == NULL) {
result = 0;
goto end;
}
result &= (s->dmatch_tail->type == DETECT_ISDATAAT);
data = (DetectIsdataatData *)s->dmatch_tail->ctx;
if ( !(!(data->flags & ISDATAAT_RELATIVE) &&
!(data->flags & ISDATAAT_RAWBYTES)) ) {
result = 0;
goto end;
}
s->next = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing bytejump_body\"; "
"dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
"content:one; isdataat:4,relative; sid:1;)");
if (s->next == NULL) {
result = 0;
goto end;
}
s = s->next;
if (s->dmatch_tail == NULL) {
result = 0;
goto end;
}
result &= (s->dmatch_tail->type == DETECT_ISDATAAT);
data = (DetectIsdataatData *)s->dmatch_tail->ctx;
if ( !((data->flags & ISDATAAT_RELATIVE) &&
!(data->flags & ISDATAAT_RAWBYTES)) ) {
result = 0;
goto end;
}
s->next = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing bytejump_body\"; "
"dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
"content:one; isdataat:4,relative,rawbytes; sid:1;)");
if (s->next == NULL) {
result = 0;
goto end;
}
s = s->next;
if (s->dmatch_tail == NULL) {
result = 0;
goto end;
}
result &= (s->dmatch_tail->type == DETECT_ISDATAAT);
data = (DetectIsdataatData *)s->dmatch_tail->ctx;
if ( !((data->flags & ISDATAAT_RELATIVE) &&
(data->flags & ISDATAAT_RAWBYTES)) ) {
result = 0;
goto end;
}
s->next = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing bytejump_body\"; "
"content:one; isdataat:4,relative,rawbytes; sid:1;)");
if (s->next == NULL) {
result = 0;
goto end;
}
s = s->next;
if (s->dmatch_tail != NULL) {
result = 0;
goto end;
}
end:
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineCtxFree(de_ctx);
return result;
}
/**
* \test DetectIsdataatTestPacket01 is a test to check matches of
* isdataat, and isdataat relative
@ -472,6 +614,8 @@ void DetectIsdataatRegisterTests(void) {
UtRegisterTest("DetectIsdataatTestParse01", DetectIsdataatTestParse01, 1);
UtRegisterTest("DetectIsdataatTestParse02", DetectIsdataatTestParse02, 1);
UtRegisterTest("DetectIsdataatTestParse03", DetectIsdataatTestParse03, 1);
UtRegisterTest("DetectIsdataatTestParse04", DetectIsdataatTestParse04, 1);
UtRegisterTest("DetectIsdataatTestParse05", DetectIsdataatTestParse05, 1);
UtRegisterTest("DetectIsdataatTestPacket01", DetectIsdataatTestPacket01, 1);
UtRegisterTest("DetectIsdataatTestPacket02", DetectIsdataatTestPacket02, 1);
UtRegisterTest("DetectIsdataatTestPacket03", DetectIsdataatTestPacket03, 1);

@ -31,6 +31,7 @@
#include "detect-parse.h"
#include "detect-content.h"
#include "detect-uricontent.h"
#include "app-layer.h"
#include "flow-var.h"
@ -52,6 +53,7 @@ int DetectOffsetSetup (DetectEngineCtx *de_ctx, Signature *s, char *offsetstr)
{
char *str = offsetstr;
char dubbed = 0;
SigMatch *pm = NULL;
/* strip "'s */
if (offsetstr[0] == '\"' && offsetstr[strlen(offsetstr)-1] == '\"') {
@ -60,14 +62,35 @@ int DetectOffsetSetup (DetectEngineCtx *de_ctx, Signature *s, char *offsetstr)
dubbed = 1;
}
/* Search for the first previous DetectContent or uricontent
* SigMatch (it can be the same as this one) */
SigMatch *pm = SigMatchGetLastPattern(s);
if (pm == NULL) {
SCLogError(SC_ERR_OFFSET_MISSING_CONTENT, "offset needs a preceeding "
"content or uricontent option");
if (dubbed) SCFree(str);
return -1;
switch (s->alproto) {
case ALPROTO_DCERPC:
/* If we have a signature that is related to dcerpc, then we add the
* sm to Signature->dmatch. All content inspections for a dce rpc
* alproto is done inside detect-engine-dcepayload.c */
pm = SigMatchGetLastSMFromLists(s, 2, DETECT_CONTENT, s->dmatch_tail);
if (pm == NULL) {
SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "offset needs"
"preceeding content option for dcerpc sig");
if (dubbed)
SCFree(str);
return -1;
}
break;
default:
pm = SigMatchGetLastSMFromLists(s, 4,
DETECT_CONTENT, s->pmatch_tail,
DETECT_URICONTENT, s->umatch_tail);
if (pm == NULL) {
SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "distance needs"
"preceeding content or uricontent option");
if (dubbed)
SCFree(str);
return -1;
}
break;
}
DetectUricontentData *ud = NULL;

@ -195,6 +195,27 @@ void SigMatchAppendPayload(Signature *s, SigMatch *new) {
s->sm_cnt++;
}
void SigMatchAppendDcePayload(Signature *s, SigMatch *new) {
SCLogDebug("Append SigMatch against Sigature->dmatch(dce) list");
if (s->dmatch == NULL) {
s->dmatch = new;
s->dmatch_tail = new;
new->next = NULL;
new->prev = NULL;
} else {
SigMatch *cur = s->dmatch_tail;
cur->next = new;
new->prev = cur;
new->next = NULL;
s->dmatch_tail = new;
}
new->idx = s->sm_cnt;
s->sm_cnt++;
return;
}
/** \brief Append a sig match to the signatures non-payload match list
*
* \param s signature
@ -399,6 +420,63 @@ SigMatch *SigMatchGetLastSM(SigMatch *sm, uint8_t type)
return NULL;
}
SigMatch *SigMatchGetLastSMFromLists(Signature *s, int args, ...)
{
if (args % 2 != 0) {
SCLogError(SC_ERR_INVALID_ARGUMENTS, "You need to send an even no of args "
"to this function, since we need a SigMatch list for every "
"SigMatch type(send a map of sm_type and sm_list) sent");
return NULL;
}
SigMatch *sm_list[args / 2];
int sm_type[args / 2];
int list_index = 0;
va_list ap;
int i = 0, j = 0;
va_start(ap, args);
for (i = 0; i < args; i += 2) {
sm_type[list_index] = va_arg(ap, int);
sm_list[list_index] = va_arg(ap, SigMatch *);
if (sm_list[list_index] != NULL)
list_index++;
}
va_end(ap);
SigMatch *sm[list_index];
int sm_entries = 0;
for (i = 0; sm_entries < list_index; i++) {
sm[sm_entries] = SigMatchGetLastSM(sm_list[i], sm_type[i]);
if (sm[sm_entries] != NULL)
sm_entries++;
}
if (sm_entries == 0)
return NULL;
SigMatch *temp_sm = NULL;
for (i = 1; i < sm_entries; i++) {
for (j = i - 1; j >= 0; j--) {
if (sm[j + 1]->idx > sm[j]->idx) {
temp_sm = sm[j + 1];
sm[j + 1] = sm[j];
sm[j] = temp_sm;
continue;
}
break;
}
}
return sm[0];
}
void SigParsePrepare(void) {
char *regexstr = CONFIG_PCRE;
const char *eb;

@ -45,6 +45,7 @@ Signature *SigAlloc(void);
void SigFree(Signature *s);
Signature *SigInit(DetectEngineCtx *,char *sigstr);
SigMatch *SigMatchGetLastSM(SigMatch *, uint8_t);
SigMatch *SigMatchGetLastSMFromLists(Signature *, int, ...);
void SigParsePrepare(void);
void SigParseRegisterTests(void);
@ -55,6 +56,7 @@ void SigMatchReplaceContent(Signature *, SigMatch *, SigMatch *);
void SigMatchReplaceContentToUricontent(Signature *, SigMatch *, SigMatch *);
void SigMatchAppendPayload(Signature *, SigMatch *);
void SigMatchAppendDcePayload(Signature *, SigMatch *);
void SigMatchAppendPacket(Signature *, SigMatch *);
void SigMatchAppendUricontent(Signature *, SigMatch *);
void SigMatchAppendAppLayer(Signature *, SigMatch *);

@ -449,6 +449,99 @@ int DetectPcrePacketPayloadMatch(DetectEngineThreadCtx *det_ctx, Packet *p, Sign
SCReturnInt(ret);
}
/**
* \brief Match a regex on data sent as arg.
*
* \param det_ctx Thread detection ctx.
* \param s Signature.
* \param sm SigMatch to match against.
* \param data Data to match against.
* \param data_len Data length.
*
* \retval 1: match
* \retval 0: no match
*/
int DetectPcrePayloadDoMatch(DetectEngineThreadCtx *det_ctx, Signature *s,
SigMatch *sm, Packet *p, uint8_t *data,
uint16_t data_len)
{
SCEnter();
#define MAX_SUBSTRINGS 30
int ret = 0;
int ov[MAX_SUBSTRINGS];
uint8_t *ptr = NULL;
uint16_t len = 0;
if (data_len == 0)
SCReturnInt(0);
DetectPcreData *pe = (DetectPcreData *)sm->ctx;
/* If we want to inspect the http body, we will use HTP L7 parser */
if (pe->flags & DETECT_PCRE_HTTP_BODY_AL)
SCReturnInt(0);
if (s->flags & SIG_FLAG_RECURSIVE) {
ptr = data + det_ctx->payload_offset;
len = data_len - det_ctx->payload_offset;
} else if (pe->flags & DETECT_PCRE_RELATIVE) {
ptr = data + det_ctx->payload_offset;
len = data_len - det_ctx->payload_offset;
if (ptr == NULL || len == 0)
SCReturnInt(0);
} else {
ptr = data;
len = data_len;
}
/* 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");
if (ret == PCRE_ERROR_NOMATCH) {
if (pe->negate == 1) {
/* regex didn't match with negate option means we
* consider it a match */
ret = 1;
} else {
ret = 0;
}
} else if (ret >= 0) {
if (pe->negate == 1) {
/* regex matched but we're negated, so not
* considering it a match */
ret = 0;
} else {
/* regex matched and we're not negated,
* considering it a match */
/* see if we need to do substring capturing. */
if (ret > 1 && pe->capidx != 0) {
const char *str_ptr;
ret = pcre_get_substring((char *)ptr, ov, MAX_SUBSTRINGS, 1, &str_ptr);
if (ret) {
if (pe->flags & DETECT_PCRE_CAPTURE_PKT) {
PktVarAdd(p, pe->capname, (uint8_t *)str_ptr, ret);
} else if (pe->flags & DETECT_PCRE_CAPTURE_FLOW) {
FlowVarAddStr(p->flow, pe->capidx, (uint8_t *)str_ptr, ret);
}
}
}
/* update offset for pcre RELATIVE */
det_ctx->payload_offset = (ptr + ov[1]) - data;
ret = 1;
}
} else {
SCLogDebug("pcre had matching error");
ret = 0;
}
SCReturnInt(ret);
}
/**
* \brief DetectPcreMatch will try to match a regex on a single packet;
* DetectPcreALMatch is used if we parse the option 'P'
@ -494,7 +587,8 @@ DetectPcreData *DetectPcreParse (char *regexstr)
pos++;
}
ret = pcre_exec(parse_regex, parse_regex_study, regexstr+pos, slen-pos, 0, 0, ov, MAX_SUBSTRINGS);
ret = pcre_exec(parse_regex, parse_regex_study, regexstr + pos, slen-pos,
0, 0, ov, MAX_SUBSTRINGS);
if (ret < 0) {
SCLogError(SC_ERR_PCRE_MATCH, "parse error");
goto error;
@ -502,7 +596,8 @@ DetectPcreData *DetectPcreParse (char *regexstr)
if (ret > 1) {
const char *str_ptr;
res = pcre_get_substring((char *)regexstr+pos, ov, MAX_SUBSTRINGS, 1, &str_ptr);
res = pcre_get_substring((char *)regexstr + pos, ov, MAX_SUBSTRINGS,
1, &str_ptr);
if (res < 0) {
SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
return NULL;
@ -510,7 +605,8 @@ DetectPcreData *DetectPcreParse (char *regexstr)
re = (char *)str_ptr;
if (ret > 2) {
res = pcre_get_substring((char *)regexstr+pos, ov, MAX_SUBSTRINGS, 2, &str_ptr);
res = pcre_get_substring((char *)regexstr + pos, ov, MAX_SUBSTRINGS,
2, &str_ptr);
if (res < 0) {
SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
return NULL;
@ -705,10 +801,28 @@ static int DetectPcreSetup (DetectEngineCtx *de_ctx, Signature *s, char *regexst
SigMatch *sm = NULL;
pd = DetectPcreParse(regexstr);
if (pd == NULL) goto error;
if (pd == NULL)
goto error;
/* check pcre modifiers against the signature alproto. In case they conflict
* chuck out invalid signature */
switch (s->alproto) {
case ALPROTO_DCERPC:
if ( (pd->flags & DETECT_PCRE_URI) ||
(pd->flags & DETECT_PCRE_HTTP_BODY_AL) ) {
SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "Invalid option. "
"DCERPC rule has pcre keyword with http related modifier.");
goto error;
}
break;
default:
break;
}
pd = DetectPcreParseCapture(regexstr, de_ctx, pd);
if (pd == NULL) goto error;
if (pd == NULL)
goto error;
sm = SigMatchAlloc();
if (sm == NULL)
@ -726,9 +840,19 @@ static int DetectPcreSetup (DetectEngineCtx *de_ctx, Signature *s, char *regexst
SigMatchAppendAppLayer(s, sm);
} else {
SigMatchAppendPayload(s, sm);
}
switch (s->alproto) {
case ALPROTO_DCERPC:
/* If we have a signature that is related to dcerpc, then we add the
* sm to Signature->dmatch. All content inspections for a dce rpc
* alproto is done inside detect-engine-dcepayload.c */
SigMatchAppendDcePayload(s, sm);
break;
default:
SigMatchAppendPayload(s, sm);
break;
}
}
SCReturnInt(0);
@ -911,6 +1035,135 @@ static int DetectPcreParseTest09 (void) {
return result;
}
int DetectPcreParseTest10(void)
{
Signature *s = SigAlloc();
int result = 1;
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL) {
result = 0;
goto end;
}
s->alproto = ALPROTO_DCERPC;
result &= (DetectPcreSetup(de_ctx, s, "/bamboo/") == 0);
result &= (s->dmatch != NULL);
SigFree(s);
s = SigAlloc();
/* failure since we have no preceding content/pcre/bytejump */
result &= (DetectPcreSetup(de_ctx, s, "/bamboo/") == 0);
result &= (s->dmatch == NULL);
result &= (s->pmatch != NULL);
end:
SigFree(s);
DetectEngineCtxFree(de_ctx);
return result;
}
int DetectPcreParseTest11(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 1;
Signature *s = NULL;
DetectPcreData *data = NULL;
de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing bytejump_body\"; "
"dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
"pcre:/bamboo/; sid:1;)");
if (de_ctx->sig_list == NULL) {
result = 0;
goto end;
}
s = de_ctx->sig_list;
if (s->dmatch_tail == NULL) {
result = 0;
goto end;
}
result &= (s->dmatch_tail->type == DETECT_PCRE);
data = (DetectPcreData *)s->dmatch_tail->ctx;
if (data->flags & DETECT_PCRE_RAWBYTES ||
data->flags & DETECT_PCRE_RELATIVE ||
data->flags & DETECT_PCRE_URI) {
result = 0;
goto end;
}
s->next = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing bytejump_body\"; "
"dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
"pcre:/bamboo/R; sid:1;)");
if (s->next == NULL) {
result = 0;
goto end;
}
s = s->next;
if (s->dmatch_tail == NULL) {
result = 0;
goto end;
}
result &= (s->dmatch_tail->type == DETECT_PCRE);
data = (DetectPcreData *)s->dmatch_tail->ctx;
if (data->flags & DETECT_PCRE_RAWBYTES ||
!(data->flags & DETECT_PCRE_RELATIVE) ||
data->flags & DETECT_PCRE_URI) {
result = 0;
goto end;
}
s->next = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing bytejump_body\"; "
"dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
"pcre:/bamboo/RB; sid:1;)");
if (s->next == NULL) {
result = 0;
goto end;
}
s = s->next;
if (s->dmatch_tail == NULL) {
result = 0;
goto end;
}
result &= (s->dmatch_tail->type == DETECT_PCRE);
data = (DetectPcreData *)s->dmatch_tail->ctx;
if (!(data->flags & DETECT_PCRE_RAWBYTES) ||
!(data->flags & DETECT_PCRE_RELATIVE) ||
data->flags & DETECT_PCRE_URI) {
result = 0;
goto end;
}
s->next = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing bytejump_body\"; "
"content:one; pcre:/bamboo/; sid:1;)");
if (s->next == NULL) {
result = 0;
goto end;
}
s = s->next;
if (s->dmatch_tail != NULL) {
result = 0;
goto end;
}
end:
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineCtxFree(de_ctx);
return result;
}
static int DetectPcreTestSig01Real(int mpm_type) {
uint8_t *buf = (uint8_t *)
"GET /one/ HTTP/1.1\r\n"
@ -1435,6 +1688,8 @@ void DetectPcreRegisterTests(void) {
UtRegisterTest("DetectPcreParseTest07", DetectPcreParseTest07, 1);
UtRegisterTest("DetectPcreParseTest08", DetectPcreParseTest08, 1);
UtRegisterTest("DetectPcreParseTest09", DetectPcreParseTest09, 1);
UtRegisterTest("DetectPcreParseTest10", DetectPcreParseTest10, 1);
UtRegisterTest("DetectPcreParseTest11", DetectPcreParseTest11, 1);
UtRegisterTest("DetectPcreTestSig01B2g -- pcre test", DetectPcreTestSig01B2g, 1);
UtRegisterTest("DetectPcreTestSig01B3g -- pcre test", DetectPcreTestSig01B3g, 1);
UtRegisterTest("DetectPcreTestSig01Wm -- pcre test", DetectPcreTestSig01Wm, 1);

@ -50,6 +50,9 @@ typedef struct DetectPcreData_ {
/* prototypes */
int DetectPcrePayloadMatch(DetectEngineThreadCtx *, Signature *, SigMatch *, Packet *, Flow *, uint8_t *, uint32_t);
int DetectPcrePacketPayloadMatch(DetectEngineThreadCtx *, Packet *, Signature *, SigMatch *);
//int DetectPcrePayloadMatch(DetectEngineThreadCtx *, Packet *, Signature *, SigMatch *);
int DetectPcrePayloadDoMatch(DetectEngineThreadCtx *, Signature *, SigMatch *,
Packet *, uint8_t *, uint16_t);
void DetectPcreRegister (void);
#endif /* __DETECT_PCRE_H__ */

@ -333,6 +333,12 @@ int DetectUricontentSetup (DetectEngineCtx *de_ctx, Signature *s, char *contents
SCEnter();
SigMatch *sm = NULL;
if (s->alproto == ALPROTO_DCERPC) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "uri content specified in a dcerpc sig");
goto error;
}
DetectUricontentData *cd = DoDetectUricontentSetup(contentstr);
if (cd == NULL)
goto error;
@ -1132,7 +1138,7 @@ static int DetectUriSigTest04(void) {
s->pmatch == NULL ||
((DetectContentData*) s->pmatch->ctx)->depth != 10 ||
((DetectContentData*) s->pmatch->ctx)->offset != 5 ||
((DetectContentData*) s->umatch_tail->ctx)->within != 30 ||
((DetectUricontentData*) s->umatch_tail->ctx)->within != 30 ||
s->match != NULL)
{
printf("sig 8 failed to parse: ");

@ -32,6 +32,8 @@
#include "detect-content.h"
#include "detect-uricontent.h"
#include "detect-bytejump.h"
#include "app-layer.h"
#include "detect-parse.h"
#include "flow-var.h"
@ -63,6 +65,8 @@ static int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, char *withi
{
char *str = withinstr;
char dubbed = 0;
SigMatch *match_tail = NULL;
SigMatch *pm = NULL;
/* strip "'s */
if (withinstr[0] == '\"' && withinstr[strlen(withinstr)-1] == '\"') {
@ -71,14 +75,35 @@ static int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, char *withi
dubbed = 1;
}
/** Search for the first previous DetectContent
* SigMatch (it can be the same as this one) */
SigMatch *pm = SigMatchGetLastPattern(s);
if (pm == NULL) {
SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "depth needs"
"two preceeding content or uricontent options");
if (dubbed) SCFree(str);
return -1;
switch (s->alproto) {
case ALPROTO_DCERPC:
/* If we have a signature that is related to dcerpc, then we add the
* sm to Signature->dmatch. All content inspections for a dce rpc
* alproto is done inside detect-engine-dcepayload.c */
pm = SigMatchGetLastSMFromLists(s, 2, DETECT_CONTENT, s->dmatch_tail);
if (pm == NULL) {
SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "within needs"
"preceeding content options for this dcerpc sig");
if (dubbed)
SCFree(str);
return -1;
}
break;
default:
pm = SigMatchGetLastSMFromLists(s, 4,
DETECT_CONTENT, s->pmatch_tail,
DETECT_URICONTENT, s->umatch_tail);
if (pm == NULL) {
SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "within needs"
"preceeding content or uricontent option");
if (dubbed)
SCFree(str);
return -1;
}
break;
}
DetectUricontentData *ud = NULL;
@ -152,17 +177,27 @@ static int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, char *withi
}
}
pm = SigMatchGetLastSM(s->pmatch_tail->prev, DETECT_CONTENT);
if (pm != NULL) {
switch (s->alproto) {
case ALPROTO_DCERPC:
match_tail = s->dmatch_tail;
break;
default:
match_tail = s->pmatch_tail;
break;
}
if ( (pm = SigMatchGetLastSM(match_tail->prev, DETECT_CONTENT)) != NULL) {
/* Set the relative next flag on the prev sigmatch */
cd = (DetectContentData *)pm->ctx;
if (cd == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous-"
"previous keyword!");
"previous keyword!");
goto error;
}
cd->flags |= DETECT_CONTENT_RELATIVE_NEXT;
} else if ((pm = SigMatchGetLastSM(s->pmatch_tail, DETECT_PCRE)) != NULL) {
} else if ( (pm = SigMatchGetLastSM(match_tail->prev, DETECT_PCRE)) != NULL) {
DetectPcreData *pe = NULL;
pe = (DetectPcreData *) pm->ctx;
if (pe == NULL) {
@ -170,9 +205,8 @@ static int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, char *withi
goto error;
}
pe->flags |= DETECT_PCRE_RELATIVE;
} else if ((pm = SigMatchGetLastSM(s->pmatch_tail, DETECT_BYTEJUMP))
!= NULL)
{
} else if ( (pm = SigMatchGetLastSM(match_tail->prev, DETECT_BYTEJUMP)) != NULL) {
DetectBytejumpData *data = NULL;
data = (DetectBytejumpData *) pm->ctx;
if (data == NULL) {
@ -180,25 +214,31 @@ static int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, char *withi
goto error;
}
data->flags |= DETECT_BYTEJUMP_RELATIVE;
} else {
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;
}
break;
default:
SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "within needs two preceeding content or uricontent options");
if (dubbed) SCFree(str);
SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "within needs two "
"preceeding content or uricontent options");
if (dubbed)
SCFree(str);
return -1;
break;
}
if (dubbed) SCFree(str);
if (dubbed)
SCFree(str);
return 0;
error:
if (dubbed) SCFree(str);
if (dubbed)
SCFree(str);
return -1;
}
@ -234,10 +274,33 @@ end:
return result;
}
int DetectWithinTestPacket02 (void) {
int result = 0;
uint8_t *buf = (uint8_t *)"Zero Five Ten Fourteen";
uint16_t buflen = strlen((char *)buf);
Packet *p;
p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
if (p == NULL)
goto end;
char sig[] = "alert tcp any any -> any any (msg:\"pcre with within "
"modifier\"; content:Five; content:Ten; within:3; distance:1; sid:1;)";
result = UTHPacketMatchSig(p, sig);
UTHFreePacket(p);
end:
return result;
}
#endif /* UNITTESTS */
void DetectWithinRegisterTests(void) {
#ifdef UNITTESTS
UtRegisterTest("DetectWithinTestPacket01", DetectWithinTestPacket01, 1);
UtRegisterTest("DetectWithinTestPacket02", DetectWithinTestPacket02, 1);
#endif /* UNITTESTS */
}

@ -43,6 +43,7 @@
#include "detect-engine-threshold.h"
#include "detect-engine-payload.h"
#include "detect-engine-dcepayload.h"
#include "detect-engine-uri.h"
#include "detect-engine-state.h"
@ -817,6 +818,12 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
goto next;
}
}
/* Check the dce keywords here */
if (s->dmatch != NULL) {
if (DetectEngineInspectDcePayload(de_ctx, det_ctx, s, p->flow, flags, alstate, p) != 1)
goto next;
}
/* if we get here but have no sigmatches to match against,
* we consider the sig matched. */

@ -258,6 +258,8 @@ typedef struct Signature_ {
struct SigMatch_ *umatch_tail; /* uricontent payload matches, tail of the list */
struct SigMatch_ *amatch; /* general app layer matches */
struct SigMatch_ *amatch_tail; /* general app layer matches, tail of the list */
struct SigMatch_ *dmatch; /* dce app layer matches */
struct SigMatch_ *dmatch_tail; /* dce app layer matches, tail of the list */
/** ptr to the next sig in the list */
struct Signature_ *next;
@ -466,6 +468,14 @@ typedef struct DetectionEngineThreadCtx_ {
* uricontent */
uint32_t uricontent_payload_offset;
/* dce stub data */
uint8_t *dce_stub_data;
/* dce stub data len */
uint32_t dce_stub_data_len;
/* offset into the payload of the last match for dce related sigmatches,
* stored in Signature->dmatch, by content, pcre, etc */
uint32_t dce_payload_offset;
/** recursive counter */
uint8_t pkt_cnt;

@ -28,6 +28,7 @@
#include "stream-tcp-private.h"
#include "stream.h"
#include "app-layer-detect-proto.h"
#include "stream-tcp-private.h"
/** Supported OS list and default OS policy is BSD */
enum

@ -55,16 +55,6 @@
//#define DEBUG
typedef struct StreamTcpThread_ {
uint64_t pkts;
uint16_t counter_tcp_sessions;
/** sessions not picked up because memcap was reached */
uint16_t counter_tcp_ssn_memcap;
TcpReassemblyThreadCtx *ra_ctx; /**< tcp reassembly thread data */
} StreamTcpThread;
TmEcode StreamTcp (ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *);
TmEcode StreamTcpThreadInit(ThreadVars *, void *, void **);
TmEcode StreamTcpThreadDeinit(ThreadVars *, void *);
@ -2520,7 +2510,7 @@ static int StreamTcpPacketStateTimeWait(ThreadVars *tv, Packet *p,
}
/* flow is and stays locked */
static int StreamTcpPacket (ThreadVars *tv, Packet *p, StreamTcpThread *stt)
int StreamTcpPacket (ThreadVars *tv, Packet *p, StreamTcpThread *stt)
{
SCEnter();
TcpSession *ssn = (TcpSession *)p->flow->protoctx;

@ -29,6 +29,11 @@
#define COUNTER_STREAMTCP_STREAMS 1
#include "app-layer-detect-proto.h"
#include "util-mpm.h"
#include "stream.h"
#include "stream-tcp-reassemble.h"
#define STREAM_VERBOSE FALSE
/*global flow data*/
typedef struct TcpStreamCnf_ {
@ -39,6 +44,16 @@ typedef struct TcpStreamCnf_ {
int async_oneside;
} TcpStreamCnf;
typedef struct StreamTcpThread_ {
uint64_t pkts;
uint16_t counter_tcp_sessions;
/** sessions not picked up because memcap was reached */
uint16_t counter_tcp_ssn_memcap;
TcpReassemblyThreadCtx *ra_ctx; /**< tcp reassembly thread data */
} StreamTcpThread;
TcpStreamCnf stream_config;
void TmModuleStreamTcpRegister (void);
void StreamTcpInitConfig (char);
@ -49,5 +64,7 @@ void StreamTcpIncrMemuse(uint32_t);
void StreamTcpDecrMemuse(uint32_t);
int StreamTcpCheckMemcap(uint32_t);
int StreamTcpPacket (ThreadVars *, Packet *, StreamTcpThread *);
#endif /* __STREAM_TCP_H__ */

@ -34,6 +34,7 @@
#include <stdio.h>
#include <stdint.h>
#include <stdarg.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>

@ -50,6 +50,7 @@
#include "detect-engine-mpm.h"
#include "detect-engine-sigorder.h"
#include "detect-engine-payload.h"
#include "detect-engine-dcepayload.h"
#include "detect-engine-state.h"
#include "tm-queuehandlers.h"
@ -875,6 +876,7 @@ int main(int argc, char **argv)
SCCudaRegisterTests();
#endif
PayloadRegisterTests();
DcePayloadRegisterTests();
#ifdef PROFILING
SCProfilingRegisterTests();
#endif

Loading…
Cancel
Save