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-mpm.c detect-engine-mpm.h \
detect-engine-iponly.c detect-engine-iponly.h \ detect-engine-iponly.c detect-engine-iponly.h \
detect-engine-payload.c detect-engine-payload.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-uri.c detect-engine-uri.h \
detect-engine-state.c detect-engine-state.h \ detect-engine-state.c detect-engine-state.h \
detect-parse.c detect-parse.h \ detect-parse.c detect-parse.h \

@ -28,6 +28,8 @@
#include "decode.h" #include "decode.h"
#include "detect.h" #include "detect.h"
#include "detect-parse.h" #include "detect-parse.h"
#include "detect-engine.h"
#include "app-layer.h"
#include "detect-bytejump.h" #include "detect-bytejump.h"
#include "detect-content.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*,\\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*$"
static pcre *parse_regex; static pcre *parse_regex;
@ -431,6 +434,7 @@ DetectBytejumpData *DetectBytejumpParse(char *optstr)
if (data->flags & DETECT_BYTEJUMP_LITTLE) { if (data->flags & DETECT_BYTEJUMP_LITTLE) {
data->flags ^= DETECT_BYTEJUMP_LITTLE; data->flags ^= DETECT_BYTEJUMP_LITTLE;
} }
data->flags |= DETECT_BYTEJUMP_BIG;
} else if (strcasecmp("little", args[i]) == 0) { } else if (strcasecmp("little", args[i]) == 0) {
data->flags |= DETECT_BYTEJUMP_LITTLE; data->flags |= DETECT_BYTEJUMP_LITTLE;
} else if (strcasecmp("from_beginning", args[i]) == 0) { } 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); SCLogError(SC_ERR_INVALID_VALUE, "Malformed post_offset: %s", optstr);
goto error; goto error;
} }
} else if (strcasecmp("dce", args[i]) == 0) {
data->flags |= DETECT_BYTEJUMP_DCE;
} else { } else {
SCLogError(SC_ERR_INVALID_VALUE, "Unknown option: \"%s\"", args[i]); SCLogError(SC_ERR_INVALID_VALUE, "Unknown option: \"%s\"", args[i]);
goto error; goto error;
@ -507,16 +513,52 @@ int DetectBytejumpSetup(DetectEngineCtx *de_ctx, Signature *s, char *optstr)
{ {
DetectBytejumpData *data = NULL; DetectBytejumpData *data = NULL;
SigMatch *sm = NULL; SigMatch *sm = NULL;
SigMatch *match = NULL;
SigMatch *match_tail = NULL;
data = DetectBytejumpParse(optstr); 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) { 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; SigMatch *pm = NULL;
pm = SigMatchGetLastSM(s->pmatch_tail, DETECT_CONTENT); if ( (pm = SigMatchGetLastSM(match_tail, DETECT_CONTENT)) != NULL) {
if (pm != NULL) {
DetectContentData *cd = (DetectContentData *)pm->ctx; DetectContentData *cd = (DetectContentData *)pm->ctx;
if (cd == NULL) { if (cd == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "relative bytejump match " SCLogError(SC_ERR_INVALID_SIGNATURE, "relative bytejump match "
@ -524,7 +566,8 @@ int DetectBytejumpSetup(DetectEngineCtx *de_ctx, Signature *s, char *optstr)
goto error; goto error;
} }
cd->flags |= DETECT_CONTENT_RELATIVE_NEXT; 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; DetectPcreData *pe = NULL;
pe = (DetectPcreData *) pm->ctx; pe = (DetectPcreData *) pm->ctx;
if (pe == NULL) { if (pe == NULL) {
@ -532,9 +575,8 @@ int DetectBytejumpSetup(DetectEngineCtx *de_ctx, Signature *s, char *optstr)
goto error; goto error;
} }
pe->flags |= DETECT_PCRE_RELATIVE; 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; DetectBytejumpData *data = NULL;
data = (DetectBytejumpData *)pm->ctx; data = (DetectBytejumpData *)pm->ctx;
if (data == NULL) { if (data == NULL) {
@ -542,6 +584,7 @@ int DetectBytejumpSetup(DetectEngineCtx *de_ctx, Signature *s, char *optstr)
goto error; goto error;
} }
data->flags |= DETECT_BYTEJUMP_RELATIVE; data->flags |= DETECT_BYTEJUMP_RELATIVE;
} else { } else {
SCLogError(SC_ERR_INVALID_SIGNATURE, "relative bytejump match " SCLogError(SC_ERR_INVALID_SIGNATURE, "relative bytejump match "
"needs a previous content option"); "needs a previous content option");
@ -556,7 +599,18 @@ int DetectBytejumpSetup(DetectEngineCtx *de_ctx, Signature *s, char *optstr)
sm->type = DETECT_BYTEJUMP; sm->type = DETECT_BYTEJUMP;
sm->ctx = (void *)data; 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; return 0;
@ -737,6 +791,218 @@ int DetectBytejumpTestParse08(void) {
return result; 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 * \test DetectByteJumpTestPacket01 is a test to check matches of
* byte_jump and byte_jump relative works if the previous keyword is pcre * 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("DetectBytejumpTestParse06", DetectBytejumpTestParse06, 1);
UtRegisterTest("DetectBytejumpTestParse07", DetectBytejumpTestParse07, 1); UtRegisterTest("DetectBytejumpTestParse07", DetectBytejumpTestParse07, 1);
UtRegisterTest("DetectBytejumpTestParse08", DetectBytejumpTestParse08, 1); UtRegisterTest("DetectBytejumpTestParse08", DetectBytejumpTestParse08, 1);
UtRegisterTest("DetectBytejumpTestParse09", DetectBytejumpTestParse09, 1);
UtRegisterTest("DetectBytejumpTestParse10", DetectBytejumpTestParse10, 1);
UtRegisterTest("DetectBytejumpTestParse11", DetectBytejumpTestParse11, 1);
UtRegisterTest("DetectByteJumpTestPacket01", DetectByteJumpTestPacket01, 1); UtRegisterTest("DetectByteJumpTestPacket01", DetectByteJumpTestPacket01, 1);
UtRegisterTest("DetectByteJumpTestPacket02", DetectByteJumpTestPacket02, 1); UtRegisterTest("DetectByteJumpTestPacket02", DetectByteJumpTestPacket02, 1);
#endif /* UNITTESTS */ #endif /* UNITTESTS */

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

@ -27,11 +27,13 @@
#include "debug.h" #include "debug.h"
#include "decode.h" #include "decode.h"
#include "detect.h" #include "detect.h"
#include "detect-engine.h"
#include "detect-parse.h" #include "detect-parse.h"
#include "detect-content.h" #include "detect-content.h"
#include "detect-bytetest.h" #include "detect-bytetest.h"
#include "detect-bytejump.h" #include "detect-bytejump.h"
#include "app-layer.h"
#include "util-byte.h" #include "util-byte.h"
#include "util-unittest.h" #include "util-unittest.h"
@ -52,6 +54,7 @@
"(?:\\s*,\\s*([^\\s,]+))?" \ "(?:\\s*,\\s*([^\\s,]+))?" \
"(?:\\s*,\\s*([^\\s,]+))?" \ "(?:\\s*,\\s*([^\\s,]+))?" \
"(?:\\s*,\\s*([^\\s,]+))?" \ "(?:\\s*,\\s*([^\\s,]+))?" \
"(?:\\s*,\\s*([^\\s,]+))?" \
"\\s*$" "\\s*$"
static pcre *parse_regex; static pcre *parse_regex;
@ -469,8 +472,11 @@ DetectBytetestData *DetectBytetestParse(char *optstr)
if (data->flags & DETECT_BYTETEST_LITTLE) { if (data->flags & DETECT_BYTETEST_LITTLE) {
data->flags ^= DETECT_BYTETEST_LITTLE; data->flags ^= DETECT_BYTETEST_LITTLE;
} }
data->flags |= DETECT_BYTETEST_BIG;
} else if (strcasecmp("little", args[i]) == 0) { } else if (strcasecmp("little", args[i]) == 0) {
data->flags |= DETECT_BYTETEST_LITTLE; data->flags |= DETECT_BYTETEST_LITTLE;
} else if (strcasecmp("dce", args[i]) == 0) {
data->flags |= DETECT_BYTETEST_DCE;
} else { } else {
SCLogError(SC_ERR_UNKNOWN_VALUE, "Unknown value: \"%s\"", SCLogError(SC_ERR_UNKNOWN_VALUE, "Unknown value: \"%s\"",
args[i]); args[i]);
@ -524,18 +530,53 @@ int DetectBytetestSetup(DetectEngineCtx *de_ctx, Signature *s, char *optstr)
{ {
DetectBytetestData *data = NULL; DetectBytetestData *data = NULL;
SigMatch *sm = NULL; SigMatch *sm = NULL;
SigMatch *match = NULL;
SigMatch *match_tail = NULL;
//printf("DetectBytetestSetup: \'%s\'\n", optstr); //printf("DetectBytetestSetup: \'%s\'\n", optstr);
data = DetectBytetestParse(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) { 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; SigMatch *pm = NULL;
pm = SigMatchGetLastSM(s->pmatch_tail, DETECT_CONTENT); if ( (pm = SigMatchGetLastSM(match_tail, DETECT_CONTENT)) != NULL) {
if (pm != NULL) {
DetectContentData *cd = (DetectContentData *) pm->ctx; DetectContentData *cd = (DetectContentData *) pm->ctx;
if (cd == NULL) { if (cd == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "relative bytetest match " SCLogError(SC_ERR_INVALID_SIGNATURE, "relative bytetest match "
@ -543,7 +584,8 @@ int DetectBytetestSetup(DetectEngineCtx *de_ctx, Signature *s, char *optstr)
goto error; goto error;
} }
cd->flags |= DETECT_CONTENT_RELATIVE_NEXT; 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; DetectPcreData *pe = NULL;
pe = (DetectPcreData *) pm->ctx; pe = (DetectPcreData *) pm->ctx;
if (pe == NULL) { if (pe == NULL) {
@ -551,9 +593,8 @@ int DetectBytetestSetup(DetectEngineCtx *de_ctx, Signature *s, char *optstr)
goto error; goto error;
} }
pe->flags |= DETECT_PCRE_RELATIVE; 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; DetectBytejumpData *data = NULL;
data = (DetectBytejumpData *)pm->ctx; data = (DetectBytejumpData *)pm->ctx;
if (data == NULL) { if (data == NULL) {
@ -561,6 +602,7 @@ int DetectBytetestSetup(DetectEngineCtx *de_ctx, Signature *s, char *optstr)
goto error; goto error;
} }
data->flags |= DETECT_BYTEJUMP_RELATIVE; data->flags |= DETECT_BYTEJUMP_RELATIVE;
} else { } else {
SCLogError(SC_ERR_INVALID_SIGNATURE, "relative bytetest match " SCLogError(SC_ERR_INVALID_SIGNATURE, "relative bytetest match "
"needs a previous content option"); "needs a previous content option");
@ -575,7 +617,18 @@ int DetectBytetestSetup(DetectEngineCtx *de_ctx, Signature *s, char *optstr)
sm->type = DETECT_BYTETEST; sm->type = DETECT_BYTETEST;
sm->ctx = (void *)data; 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; return 0;
@ -745,7 +798,7 @@ int DetectBytetestTestParse07(void) {
&& (data->nbytes == 4) && (data->nbytes == 4)
&& (data->value == 5) && (data->value == 5)
&& (data->offset == 0) && (data->offset == 0)
&& (data->flags == 0) && (data->flags == 4)
&& (data->base == DETECT_BYTETEST_BASE_UNSET)) && (data->base == DETECT_BYTETEST_BASE_UNSET))
{ {
result = 1; result = 1;
@ -930,6 +983,282 @@ int DetectBytetestTestParse16(void) {
return result; 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 * \test DetectByteTestTestPacket01 is a test to check matches of
* byte_test and byte_test relative works if the previous keyword is pcre * 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("DetectBytetestTestParse13", DetectBytetestTestParse13, 1);
UtRegisterTest("DetectBytetestTestParse14", DetectBytetestTestParse14, 1); UtRegisterTest("DetectBytetestTestParse14", DetectBytetestTestParse14, 1);
UtRegisterTest("DetectBytetestTestParse15", DetectBytetestTestParse15, 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("DetectByteTestTestPacket01", DetectByteTestTestPacket01, 1);
UtRegisterTest("DetectByteTestTestPacket02", DetectByteTestTestPacket02, 1); UtRegisterTest("DetectByteTestTestPacket02", DetectByteTestTestPacket02, 1);
#endif /* UNITTESTS */ #endif /* UNITTESTS */

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

@ -35,6 +35,7 @@
#include "flow.h" #include "flow.h"
#include "flow-var.h" #include "flow-var.h"
#include "detect-flow.h" #include "detect-flow.h"
#include "app-layer.h"
#include "util-unittest.h" #include "util-unittest.h"
#include "util-print.h" #include "util-print.h"
#include "util-debug.h" #include "util-debug.h"
@ -434,7 +435,19 @@ static int DetectContentSetup (DetectEngineCtx *de_ctx, Signature *s, char *cont
DetectContentPrint(cd); 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; return 0;
error: error:
@ -1060,6 +1073,296 @@ end:
return result; 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) static int SigTestPositiveTestContent(char *rule, uint8_t *buf)
{ {
uint16_t buflen = strlen((char *)buf); uint16_t buflen = strlen((char *)buf);
@ -1502,6 +1805,8 @@ void DetectContentRegisterTests(void)
UtRegisterTest("DetectContentParseTest15", DetectContentParseNegTest15, 1); UtRegisterTest("DetectContentParseTest15", DetectContentParseNegTest15, 1);
UtRegisterTest("DetectContentParseTest16", DetectContentParseNegTest16, 1); UtRegisterTest("DetectContentParseTest16", DetectContentParseNegTest16, 1);
UtRegisterTest("DetectContentParseTest17", DetectContentParseTest17, 1); UtRegisterTest("DetectContentParseTest17", DetectContentParseTest17, 1);
UtRegisterTest("DetectContentParseTest18", DetectContentParseTest18, 1);
UtRegisterTest("DetectContentParseTest19", DetectContentParseTest19, 1);
/* The reals */ /* The reals */
UtRegisterTest("DetectContentLongPatternMatchTest01", DetectContentLongPatternMatchTest01, 1); UtRegisterTest("DetectContentLongPatternMatchTest01", DetectContentLongPatternMatchTest01, 1);

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

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

@ -30,6 +30,8 @@
#include "detect.h" #include "detect.h"
#include "detect-parse.h" #include "detect-parse.h"
#include "detect-engine.h" #include "detect-engine.h"
#include "app-layer.h"
#include "detect-parse.h"
#include "detect-content.h" #include "detect-content.h"
#include "detect-uricontent.h" #include "detect-uricontent.h"
@ -59,6 +61,8 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s,
{ {
char *str = distancestr; char *str = distancestr;
char dubbed = 0; char dubbed = 0;
SigMatch *pm = NULL;
SigMatch *match_tail = NULL;
/* strip "'s */ /* strip "'s */
if (distancestr[0] == '\"' && distancestr[strlen(distancestr)-1] == '\"') { if (distancestr[0] == '\"' && distancestr[strlen(distancestr)-1] == '\"') {
@ -67,14 +71,35 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s,
dubbed = 1; dubbed = 1;
} }
/** Search for the first previous DetectContent switch (s->alproto) {
* SigMatch (it can be the same as this one) */ case ALPROTO_DCERPC:
SigMatch *pm = SigMatchGetLastPattern(s); /* If we have a signature that is related to dcerpc, then we add the
if (pm == NULL) { * sm to Signature->dmatch. All content inspections for a dce rpc
SCLogError(SC_ERR_DISTANCE_MISSING_CONTENT, "distance needs two " * alproto is done inside detect-engine-dcepayload.c */
"preceeding content or uricontent options"); pm = SigMatchGetLastSMFromLists(s, 2, DETECT_CONTENT, s->dmatch_tail);
if (dubbed) SCFree(str); if (pm == NULL) {
return -1; 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; DetectUricontentData *ud = NULL;
@ -130,8 +155,17 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s,
} }
} }
pm = SigMatchGetLastSM(s->pmatch_tail->prev, DETECT_CONTENT); switch (s->alproto) {
if (pm != NULL) { 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 */ /* Set the relative next flag on the prev sigmatch */
cd = (DetectContentData *)pm->ctx; cd = (DetectContentData *)pm->ctx;
if (cd == NULL) { if (cd == NULL) {
@ -140,9 +174,8 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s,
goto error; goto error;
} }
cd->flags |= DETECT_CONTENT_RELATIVE_NEXT; 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; DetectBytejumpData *data = NULL;
data = (DetectBytejumpData *) pm->ctx; data = (DetectBytejumpData *) pm->ctx;
if (data == NULL) { if (data == NULL) {
@ -150,9 +183,10 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s,
goto error; goto error;
} }
data->flags |= DETECT_BYTEJUMP_RELATIVE; data->flags |= DETECT_BYTEJUMP_RELATIVE;
} else { } else {
SCLogError(SC_ERR_DISTANCE_MISSING_CONTENT, "distance needs two" SCLogError(SC_ERR_DISTANCE_MISSING_CONTENT, "distance needs two "
" preceeding content or uricontent options"); "preceeding content or uricontent options");
goto error; goto error;
} }
@ -160,7 +194,7 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s,
default: default:
SCLogError(SC_ERR_DISTANCE_MISSING_CONTENT, "distance needs two " SCLogError(SC_ERR_DISTANCE_MISSING_CONTENT, "distance needs two "
"preceeding content or uricontent options"); "preceeding content or uricontent options");
if (dubbed) SCFree(str); if (dubbed) SCFree(str);
return -1; return -1;
break; 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 "debug.h"
#include "decode.h" #include "decode.h"
#include "detect.h" #include "detect.h"
#include "detect-engine.h"
#include "detect-parse.h" #include "detect-parse.h"
#include "app-layer.h"
#include "util-unittest.h" #include "util-unittest.h"
#include "util-unittest-helper.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 de_ctx pointer to the Detection Engine Context
* \param s pointer to the Current Signature * \param s pointer to the Current Signature
* \param isdataatstr pointer to the user provided isdataat options * \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; DetectIsdataatData *idad = NULL;
SigMatch *sm = NULL; SigMatch *sm = NULL;
SigMatch *match = NULL;
SigMatch *match_tail = NULL;
DetectContentData *cd = NULL; DetectContentData *cd = NULL;
idad = DetectIsdataatParse(isdataatstr); idad = DetectIsdataatParse(isdataatstr);
if (idad == NULL) goto error; if (idad == NULL) goto error;
if(idad->flags & ISDATAAT_RELATIVE) { if (idad->flags & ISDATAAT_RELATIVE) {
/** Set it in the last parsed contet because it is relative to that content match */ /* Set it in the last parsed contet because it is relative to that
SCLogDebug("set it in the last parsed content because it is relative to that content match"); * 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 " SCLogError(SC_ERR_INVALID_SIGNATURE, "No previous content, the flag "
"'relative' cant be used without content"); "'relative' cant be used without content");
goto error; goto error;
} }
SigMatch *pm = NULL; SigMatch *m = NULL;
/** Search for the first previous DetectContent /* Search for the first previous DetectContent SigMatch (it can be the
* SigMatch (it can be the same as this one) */ * same as this one) */
pm = SigMatchGetLastSM(s->pmatch_tail, DETECT_CONTENT); if ( (m = SigMatchGetLastSM(match_tail, DETECT_CONTENT)) != NULL) {
if (pm != NULL) { cd = (DetectContentData *)m->ctx;
cd = (DetectContentData *)pm->ctx;
if (cd == NULL) { if (cd == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous keyword!"); SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous keyword!");
goto error; goto error;
} }
cd->flags |= DETECT_CONTENT_RELATIVE_NEXT; 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; DetectPcreData *pe = NULL;
pe = (DetectPcreData *) pm->ctx; pe = (DetectPcreData *)m->ctx;
if (pe == NULL) { if (pe == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous keyword!"); SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous keyword!");
goto error; goto error;
} }
pe->flags |= DETECT_PCRE_RELATIVE; 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; DetectBytejumpData *data = NULL;
data = (DetectBytejumpData *)pm->ctx; data = (DetectBytejumpData *)m->ctx;
if (data == NULL) { if (data == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous keyword!"); SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous keyword!");
goto error; goto error;
} }
data->flags |= DETECT_BYTEJUMP_RELATIVE; data->flags |= DETECT_BYTEJUMP_RELATIVE;
} else { } else {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous keyword!"); SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous keyword!");
goto error; goto error;
} }
} }
@ -289,15 +306,27 @@ int DetectIsdataatSetup (DetectEngineCtx *de_ctx, Signature *s, char *isdataatst
sm->type = DETECT_ISDATAAT; sm->type = DETECT_ISDATAAT;
sm->ctx = (void *)idad; 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; return 0;
error: error:
if (idad != NULL) DetectIsdataatFree(idad); if (idad != NULL)
if (sm != NULL) SCFree(sm); DetectIsdataatFree(idad);
if (sm != NULL)
SCFree(sm);
return -1; return -1;
} }
/** /**
@ -361,6 +390,119 @@ int DetectIsdataatTestParse03 (void) {
return result; 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 * \test DetectIsdataatTestPacket01 is a test to check matches of
* isdataat, and isdataat relative * isdataat, and isdataat relative
@ -472,6 +614,8 @@ void DetectIsdataatRegisterTests(void) {
UtRegisterTest("DetectIsdataatTestParse01", DetectIsdataatTestParse01, 1); UtRegisterTest("DetectIsdataatTestParse01", DetectIsdataatTestParse01, 1);
UtRegisterTest("DetectIsdataatTestParse02", DetectIsdataatTestParse02, 1); UtRegisterTest("DetectIsdataatTestParse02", DetectIsdataatTestParse02, 1);
UtRegisterTest("DetectIsdataatTestParse03", DetectIsdataatTestParse03, 1); UtRegisterTest("DetectIsdataatTestParse03", DetectIsdataatTestParse03, 1);
UtRegisterTest("DetectIsdataatTestParse04", DetectIsdataatTestParse04, 1);
UtRegisterTest("DetectIsdataatTestParse05", DetectIsdataatTestParse05, 1);
UtRegisterTest("DetectIsdataatTestPacket01", DetectIsdataatTestPacket01, 1); UtRegisterTest("DetectIsdataatTestPacket01", DetectIsdataatTestPacket01, 1);
UtRegisterTest("DetectIsdataatTestPacket02", DetectIsdataatTestPacket02, 1); UtRegisterTest("DetectIsdataatTestPacket02", DetectIsdataatTestPacket02, 1);
UtRegisterTest("DetectIsdataatTestPacket03", DetectIsdataatTestPacket03, 1); UtRegisterTest("DetectIsdataatTestPacket03", DetectIsdataatTestPacket03, 1);

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

@ -195,6 +195,27 @@ void SigMatchAppendPayload(Signature *s, SigMatch *new) {
s->sm_cnt++; 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 /** \brief Append a sig match to the signatures non-payload match list
* *
* \param s signature * \param s signature
@ -399,6 +420,63 @@ SigMatch *SigMatchGetLastSM(SigMatch *sm, uint8_t type)
return NULL; 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) { void SigParsePrepare(void) {
char *regexstr = CONFIG_PCRE; char *regexstr = CONFIG_PCRE;
const char *eb; const char *eb;

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

@ -449,6 +449,99 @@ int DetectPcrePacketPayloadMatch(DetectEngineThreadCtx *det_ctx, Packet *p, Sign
SCReturnInt(ret); 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; * \brief DetectPcreMatch will try to match a regex on a single packet;
* DetectPcreALMatch is used if we parse the option 'P' * DetectPcreALMatch is used if we parse the option 'P'
@ -494,7 +587,8 @@ DetectPcreData *DetectPcreParse (char *regexstr)
pos++; 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) { if (ret < 0) {
SCLogError(SC_ERR_PCRE_MATCH, "parse error"); SCLogError(SC_ERR_PCRE_MATCH, "parse error");
goto error; goto error;
@ -502,7 +596,8 @@ DetectPcreData *DetectPcreParse (char *regexstr)
if (ret > 1) { if (ret > 1) {
const char *str_ptr; 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) { if (res < 0) {
SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
return NULL; return NULL;
@ -510,7 +605,8 @@ DetectPcreData *DetectPcreParse (char *regexstr)
re = (char *)str_ptr; re = (char *)str_ptr;
if (ret > 2) { 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) { if (res < 0) {
SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
return NULL; return NULL;
@ -705,10 +801,28 @@ static int DetectPcreSetup (DetectEngineCtx *de_ctx, Signature *s, char *regexst
SigMatch *sm = NULL; SigMatch *sm = NULL;
pd = DetectPcreParse(regexstr); 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); pd = DetectPcreParseCapture(regexstr, de_ctx, pd);
if (pd == NULL) goto error; if (pd == NULL)
goto error;
sm = SigMatchAlloc(); sm = SigMatchAlloc();
if (sm == NULL) if (sm == NULL)
@ -726,9 +840,19 @@ static int DetectPcreSetup (DetectEngineCtx *de_ctx, Signature *s, char *regexst
SigMatchAppendAppLayer(s, sm); SigMatchAppendAppLayer(s, sm);
} else { } 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); SCReturnInt(0);
@ -911,6 +1035,135 @@ static int DetectPcreParseTest09 (void) {
return result; 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) { static int DetectPcreTestSig01Real(int mpm_type) {
uint8_t *buf = (uint8_t *) uint8_t *buf = (uint8_t *)
"GET /one/ HTTP/1.1\r\n" "GET /one/ HTTP/1.1\r\n"
@ -1435,6 +1688,8 @@ void DetectPcreRegisterTests(void) {
UtRegisterTest("DetectPcreParseTest07", DetectPcreParseTest07, 1); UtRegisterTest("DetectPcreParseTest07", DetectPcreParseTest07, 1);
UtRegisterTest("DetectPcreParseTest08", DetectPcreParseTest08, 1); UtRegisterTest("DetectPcreParseTest08", DetectPcreParseTest08, 1);
UtRegisterTest("DetectPcreParseTest09", DetectPcreParseTest09, 1); UtRegisterTest("DetectPcreParseTest09", DetectPcreParseTest09, 1);
UtRegisterTest("DetectPcreParseTest10", DetectPcreParseTest10, 1);
UtRegisterTest("DetectPcreParseTest11", DetectPcreParseTest11, 1);
UtRegisterTest("DetectPcreTestSig01B2g -- pcre test", DetectPcreTestSig01B2g, 1); UtRegisterTest("DetectPcreTestSig01B2g -- pcre test", DetectPcreTestSig01B2g, 1);
UtRegisterTest("DetectPcreTestSig01B3g -- pcre test", DetectPcreTestSig01B3g, 1); UtRegisterTest("DetectPcreTestSig01B3g -- pcre test", DetectPcreTestSig01B3g, 1);
UtRegisterTest("DetectPcreTestSig01Wm -- pcre test", DetectPcreTestSig01Wm, 1); UtRegisterTest("DetectPcreTestSig01Wm -- pcre test", DetectPcreTestSig01Wm, 1);

@ -50,6 +50,9 @@ typedef struct DetectPcreData_ {
/* prototypes */ /* prototypes */
int DetectPcrePayloadMatch(DetectEngineThreadCtx *, Signature *, SigMatch *, Packet *, Flow *, uint8_t *, uint32_t); int DetectPcrePayloadMatch(DetectEngineThreadCtx *, Signature *, SigMatch *, Packet *, Flow *, uint8_t *, uint32_t);
int DetectPcrePacketPayloadMatch(DetectEngineThreadCtx *, Packet *, Signature *, SigMatch *); 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); void DetectPcreRegister (void);
#endif /* __DETECT_PCRE_H__ */ #endif /* __DETECT_PCRE_H__ */

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

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

@ -43,6 +43,7 @@
#include "detect-engine-threshold.h" #include "detect-engine-threshold.h"
#include "detect-engine-payload.h" #include "detect-engine-payload.h"
#include "detect-engine-dcepayload.h"
#include "detect-engine-uri.h" #include "detect-engine-uri.h"
#include "detect-engine-state.h" #include "detect-engine-state.h"
@ -817,6 +818,12 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
goto next; 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, /* if we get here but have no sigmatches to match against,
* we consider the sig matched. */ * 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_ *umatch_tail; /* uricontent payload matches, tail of the list */
struct SigMatch_ *amatch; /* general app layer matches */ struct SigMatch_ *amatch; /* general app layer matches */
struct SigMatch_ *amatch_tail; /* general app layer matches, tail of the list */ 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 */ /** ptr to the next sig in the list */
struct Signature_ *next; struct Signature_ *next;
@ -466,6 +468,14 @@ typedef struct DetectionEngineThreadCtx_ {
* uricontent */ * uricontent */
uint32_t uricontent_payload_offset; 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 */ /** recursive counter */
uint8_t pkt_cnt; uint8_t pkt_cnt;

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

@ -55,16 +55,6 @@
//#define DEBUG //#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 StreamTcp (ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *);
TmEcode StreamTcpThreadInit(ThreadVars *, void *, void **); TmEcode StreamTcpThreadInit(ThreadVars *, void *, void **);
TmEcode StreamTcpThreadDeinit(ThreadVars *, void *); TmEcode StreamTcpThreadDeinit(ThreadVars *, void *);
@ -2520,7 +2510,7 @@ static int StreamTcpPacketStateTimeWait(ThreadVars *tv, Packet *p,
} }
/* flow is and stays locked */ /* flow is and stays locked */
static int StreamTcpPacket (ThreadVars *tv, Packet *p, StreamTcpThread *stt) int StreamTcpPacket (ThreadVars *tv, Packet *p, StreamTcpThread *stt)
{ {
SCEnter(); SCEnter();
TcpSession *ssn = (TcpSession *)p->flow->protoctx; TcpSession *ssn = (TcpSession *)p->flow->protoctx;

@ -29,6 +29,11 @@
#define COUNTER_STREAMTCP_STREAMS 1 #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 #define STREAM_VERBOSE FALSE
/*global flow data*/ /*global flow data*/
typedef struct TcpStreamCnf_ { typedef struct TcpStreamCnf_ {
@ -39,6 +44,16 @@ typedef struct TcpStreamCnf_ {
int async_oneside; int async_oneside;
} TcpStreamCnf; } 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; TcpStreamCnf stream_config;
void TmModuleStreamTcpRegister (void); void TmModuleStreamTcpRegister (void);
void StreamTcpInitConfig (char); void StreamTcpInitConfig (char);
@ -49,5 +64,7 @@ void StreamTcpIncrMemuse(uint32_t);
void StreamTcpDecrMemuse(uint32_t); void StreamTcpDecrMemuse(uint32_t);
int StreamTcpCheckMemcap(uint32_t); int StreamTcpCheckMemcap(uint32_t);
int StreamTcpPacket (ThreadVars *, Packet *, StreamTcpThread *);
#endif /* __STREAM_TCP_H__ */ #endif /* __STREAM_TCP_H__ */

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

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

Loading…
Cancel
Save