From 5ccd9a83470f2cb87cb0d59e53ba0787d8e9f257 Mon Sep 17 00:00:00 2001 From: Anoop Saldanha Date: Mon, 13 Jun 2011 20:16:53 +0530 Subject: [PATCH] byte_extract support for isdataat added --- src/detect-byte-extract.c | 577 +++++++++++++++++++++++++++++++++++++- src/detect-isdataat.c | 169 ++++++----- src/detect-isdataat.h | 1 + 3 files changed, 681 insertions(+), 66 deletions(-) diff --git a/src/detect-byte-extract.c b/src/detect-byte-extract.c index 2d8da23cb6..ff00110aee 100644 --- a/src/detect-byte-extract.c +++ b/src/detect-byte-extract.c @@ -35,6 +35,7 @@ #include "detect-bytejump.h" #include "detect-bytetest.h" #include "detect-byte-extract.h" +#include "detect-isdataat.h" #include "app-layer-protos.h" @@ -605,13 +606,22 @@ int DetectByteExtractSetup(DetectEngineCtx *de_ctx, Signature *s, char *arg) } else { if (data->flags & DETECT_BYTE_EXTRACT_FLAG_RELATIVE) { SigMatch *pm = - SigMatchGetLastSMFromLists(s, 12, + SigMatchGetLastSMFromLists(s, 30, DETECT_URICONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], + DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], + DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_PMATCH]); + DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], + DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], + DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], + DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_DMATCH], + DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_DMATCH], + DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_DMATCH], + DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_DMATCH], + DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_DMATCH]); if (pm == NULL) { SCLogError(SC_ERR_INVALID_SIGNATURE, "No preceding content " "or uricontent or pcre option"); @@ -4330,6 +4340,564 @@ int DetectByteExtractTest57(void) return result; } +int DetectByteExtractTest58(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + Signature *s = NULL; + SigMatch *sm = NULL; + DetectContentData *cd = NULL; + DetectByteExtractData *bed1 = NULL; + DetectByteExtractData *bed2 = NULL; + DetectBytejumpData *bjd = NULL; + DetectIsdataatData *isdd = NULL; + + de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " + "(msg:\"Testing bytejump_body\"; " + "content:one; " + "byte_extract:4,0,two,string,hex; " + "byte_extract:4,0,three,string,hex; " + "byte_jump: 2,two; " + "byte_jump: 3,three; " + "isdataat: three; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) { + result = 0; + goto end; + } + + if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { + result = 0; + goto end; + } + + sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; + if (sm->type != DETECT_CONTENT) { + result = 0; + goto end; + } + cd = (DetectContentData *)sm->ctx; + if (cd->flags & DETECT_CONTENT_RAWBYTES || + strncmp((char *)cd->content, "one", cd->content_len) != 0 || + cd->flags & DETECT_CONTENT_NOCASE || + cd->flags & DETECT_CONTENT_WITHIN || + cd->flags & DETECT_CONTENT_DISTANCE || + cd->flags & DETECT_CONTENT_FAST_PATTERN || + cd->flags & DETECT_CONTENT_RELATIVE_NEXT || + cd->flags & DETECT_CONTENT_NEGATED ) { + printf("one failed\n"); + result = 0; + goto end; + } + + sm = sm->next; + if (sm->type != DETECT_BYTE_EXTRACT) { + result = 0; + goto end; + } + bed1 = (DetectByteExtractData *)sm->ctx; + if (bed1->nbytes != 4 || + bed1->offset != 0 || + strcmp(bed1->name, "two") != 0 || + bed1->flags != DETECT_BYTE_EXTRACT_FLAG_STRING || + bed1->endian != DETECT_BYTE_EXTRACT_ENDIAN_NONE || + bed1->base != DETECT_BYTE_EXTRACT_BASE_HEX || + bed1->align_value != 0 || + bed1->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { + goto end; + } + if (bed1->local_id != 0) { + result = 0; + goto end; + } + + sm = sm->next; + if (sm->type != DETECT_BYTE_EXTRACT) { + result = 0; + goto end; + } + bed2 = (DetectByteExtractData *)sm->ctx; + + sm = sm->next; + if (sm->type != DETECT_BYTEJUMP) { + result = 0; + goto end; + } + bjd = (DetectBytejumpData *)sm->ctx; + if (bjd->flags != DETECT_BYTEJUMP_OFFSET_BE || + bjd->offset != 0) { + printf("three failed\n"); + result = 0; + goto end; + } + + sm = sm->next; + if (sm->type != DETECT_BYTEJUMP) { + result = 0; + goto end; + } + bjd = (DetectBytejumpData *)sm->ctx; + if (bjd->flags != DETECT_BYTEJUMP_OFFSET_BE || + bjd->offset != 1) { + printf("four failed\n"); + result = 0; + goto end; + } + + sm = sm->next; + if (sm->type != DETECT_ISDATAAT) { + result = 0; + goto end; + } + isdd = (DetectIsdataatData *)sm->ctx; + if (isdd->flags != ISDATAAT_OFFSET_BE || + isdd->dataat != 1) { + printf("isdataat failed\n"); + result = 0; + goto end; + } + + if (sm->next != NULL) + goto end; + + result = 1; + + end: + SigGroupCleanup(de_ctx); + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + + return result; +} + +int DetectByteExtractTest59(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + Signature *s = NULL; + SigMatch *sm = NULL; + DetectContentData *cd = NULL; + DetectByteExtractData *bed1 = NULL; + DetectByteExtractData *bed2 = NULL; + DetectBytejumpData *bjd = NULL; + DetectIsdataatData *isdd = NULL; + + de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " + "(msg:\"Testing bytejump_body\"; " + "content:one; " + "byte_extract:4,0,two,string,hex; " + "byte_extract:4,0,three,string,hex; " + "byte_jump: 2,two; " + "byte_jump: 3,three; " + "isdataat: three,relative; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) { + result = 0; + goto end; + } + + if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { + result = 0; + goto end; + } + + sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; + if (sm->type != DETECT_CONTENT) { + result = 0; + goto end; + } + cd = (DetectContentData *)sm->ctx; + if (cd->flags & DETECT_CONTENT_RAWBYTES || + strncmp((char *)cd->content, "one", cd->content_len) != 0 || + cd->flags & DETECT_CONTENT_NOCASE || + cd->flags & DETECT_CONTENT_WITHIN || + cd->flags & DETECT_CONTENT_DISTANCE || + cd->flags & DETECT_CONTENT_FAST_PATTERN || + cd->flags & DETECT_CONTENT_RELATIVE_NEXT || + cd->flags & DETECT_CONTENT_NEGATED ) { + printf("one failed\n"); + result = 0; + goto end; + } + + sm = sm->next; + if (sm->type != DETECT_BYTE_EXTRACT) { + result = 0; + goto end; + } + bed1 = (DetectByteExtractData *)sm->ctx; + if (bed1->nbytes != 4 || + bed1->offset != 0 || + strcmp(bed1->name, "two") != 0 || + bed1->flags != DETECT_BYTE_EXTRACT_FLAG_STRING || + bed1->endian != DETECT_BYTE_EXTRACT_ENDIAN_NONE || + bed1->base != DETECT_BYTE_EXTRACT_BASE_HEX || + bed1->align_value != 0 || + bed1->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { + goto end; + } + if (bed1->local_id != 0) { + result = 0; + goto end; + } + + sm = sm->next; + if (sm->type != DETECT_BYTE_EXTRACT) { + result = 0; + goto end; + } + bed2 = (DetectByteExtractData *)sm->ctx; + + sm = sm->next; + if (sm->type != DETECT_BYTEJUMP) { + result = 0; + goto end; + } + bjd = (DetectBytejumpData *)sm->ctx; + if (bjd->flags != DETECT_BYTEJUMP_OFFSET_BE || + bjd->offset != 0) { + printf("three failed\n"); + result = 0; + goto end; + } + + sm = sm->next; + if (sm->type != DETECT_BYTEJUMP) { + result = 0; + goto end; + } + bjd = (DetectBytejumpData *)sm->ctx; + if (bjd->flags != DETECT_BYTEJUMP_OFFSET_BE || + bjd->offset != 1) { + printf("four failed\n"); + result = 0; + goto end; + } + + sm = sm->next; + if (sm->type != DETECT_ISDATAAT) { + result = 0; + goto end; + } + isdd = (DetectIsdataatData *)sm->ctx; + if (isdd->flags != (ISDATAAT_OFFSET_BE | + ISDATAAT_RELATIVE) || + isdd->dataat != 1) { + printf("isdataat failed\n"); + result = 0; + goto end; + } + + if (sm->next != NULL) + goto end; + + result = 1; + + end: + SigGroupCleanup(de_ctx); + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + + return result; +} + +int DetectByteExtractTest60(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + Signature *s = NULL; + SigMatch *sm = NULL; + DetectContentData *cd = NULL; + DetectByteExtractData *bed1 = NULL; + DetectIsdataatData *isdd = NULL; + + de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " + "(msg:\"Testing bytejump_body\"; " + "content:one; " + "byte_extract:4,0,two,string,hex,relative; " + "uricontent: three; " + "byte_extract:4,0,four,string,hex,relative; " + "isdataat: two; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) { + result = 0; + goto end; + } + + if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { + result = 0; + goto end; + } + + sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; + if (sm->type != DETECT_CONTENT) { + result = 0; + goto end; + } + cd = (DetectContentData *)sm->ctx; + if (cd->flags & DETECT_CONTENT_RAWBYTES || + strncmp((char *)cd->content, "one", cd->content_len) != 0 || + cd->flags & DETECT_CONTENT_NOCASE || + cd->flags & DETECT_CONTENT_WITHIN || + cd->flags & DETECT_CONTENT_DISTANCE || + cd->flags & DETECT_CONTENT_FAST_PATTERN || + !(cd->flags & DETECT_CONTENT_RELATIVE_NEXT) || + cd->flags & DETECT_CONTENT_NEGATED ) { + printf("one failed\n"); + result = 0; + goto end; + } + + sm = sm->next; + if (sm->type != DETECT_BYTE_EXTRACT) { + result = 0; + goto end; + } + bed1 = (DetectByteExtractData *)sm->ctx; + if (bed1->nbytes != 4 || + bed1->offset != 0 || + strcmp(bed1->name, "two") != 0 || + bed1->flags != (DETECT_BYTE_EXTRACT_FLAG_STRING | + DETECT_BYTE_EXTRACT_FLAG_RELATIVE) || + bed1->endian != DETECT_BYTE_EXTRACT_ENDIAN_NONE || + bed1->base != DETECT_BYTE_EXTRACT_BASE_HEX || + bed1->align_value != 0 || + bed1->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { + goto end; + } + if (bed1->local_id != 0) { + result = 0; + goto end; + } + + sm = sm->next; + if (sm->type != DETECT_ISDATAAT) { + result = 0; + goto end; + } + isdd = (DetectIsdataatData *)sm->ctx; + if (isdd->flags != (ISDATAAT_OFFSET_BE) || + isdd->dataat != bed1->local_id) { + printf("isdataat failed\n"); + result = 0; + goto end; + } + + if (sm->next != NULL) + goto end; + + if (s->sm_lists_tail[DETECT_SM_LIST_UMATCH] == NULL) { + result = 0; + goto end; + } + + sm = s->sm_lists[DETECT_SM_LIST_UMATCH]; + if (sm->type != DETECT_URICONTENT) { + result = 0; + goto end; + } + cd = (DetectContentData *)sm->ctx; + if (cd->flags != DETECT_CONTENT_RELATIVE_NEXT || + strncmp((char *)cd->content, "three", cd->content_len) != 0) { + printf("one failed\n"); + result = 0; + goto end; + } + + sm = sm->next; + if (sm->type != DETECT_BYTE_EXTRACT) { + result = 0; + goto end; + } + bed1 = (DetectByteExtractData *)sm->ctx; + if (bed1->nbytes != 4 || + bed1->offset != 0 || + strcmp(bed1->name, "four") != 0 || + bed1->flags != (DETECT_BYTE_EXTRACT_FLAG_STRING | + DETECT_BYTE_EXTRACT_FLAG_RELATIVE) || + bed1->endian != DETECT_BYTE_EXTRACT_ENDIAN_NONE || + bed1->base != DETECT_BYTE_EXTRACT_BASE_HEX || + bed1->align_value != 0 || + bed1->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { + goto end; + } + if (bed1->local_id != 1) { + result = 0; + goto end; + } + + if (sm->next != NULL) + goto end; + + result = 1; + + end: + SigGroupCleanup(de_ctx); + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + + return result; +} + +int DetectByteExtractTest61(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + Signature *s = NULL; + SigMatch *sm = NULL; + DetectContentData *cd = NULL; + DetectByteExtractData *bed1 = NULL; + DetectIsdataatData *isdd = NULL; + + de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " + "(msg:\"Testing bytejump_body\"; " + "content:one; " + "byte_extract:4,0,two,string,hex,relative; " + "uricontent: three; " + "byte_extract:4,0,four,string,hex,relative; " + "isdataat: four, relative; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) { + result = 0; + goto end; + } + + if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { + result = 0; + goto end; + } + + sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; + if (sm->type != DETECT_CONTENT) { + result = 0; + goto end; + } + cd = (DetectContentData *)sm->ctx; + if (cd->flags & DETECT_CONTENT_RAWBYTES || + strncmp((char *)cd->content, "one", cd->content_len) != 0 || + cd->flags & DETECT_CONTENT_NOCASE || + cd->flags & DETECT_CONTENT_WITHIN || + cd->flags & DETECT_CONTENT_DISTANCE || + cd->flags & DETECT_CONTENT_FAST_PATTERN || + !(cd->flags & DETECT_CONTENT_RELATIVE_NEXT) || + cd->flags & DETECT_CONTENT_NEGATED ) { + printf("one failed\n"); + result = 0; + goto end; + } + + sm = sm->next; + if (sm->type != DETECT_BYTE_EXTRACT) { + result = 0; + goto end; + } + bed1 = (DetectByteExtractData *)sm->ctx; + if (bed1->nbytes != 4 || + bed1->offset != 0 || + strcmp(bed1->name, "two") != 0 || + bed1->flags != (DETECT_BYTE_EXTRACT_FLAG_STRING | + DETECT_BYTE_EXTRACT_FLAG_RELATIVE) || + bed1->endian != DETECT_BYTE_EXTRACT_ENDIAN_NONE || + bed1->base != DETECT_BYTE_EXTRACT_BASE_HEX || + bed1->align_value != 0 || + bed1->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { + goto end; + } + if (bed1->local_id != 0) { + result = 0; + goto end; + } + + if (sm->next != NULL) + goto end; + + if (s->sm_lists_tail[DETECT_SM_LIST_UMATCH] == NULL) { + result = 0; + goto end; + } + + sm = s->sm_lists[DETECT_SM_LIST_UMATCH]; + if (sm->type != DETECT_URICONTENT) { + result = 0; + goto end; + } + cd = (DetectContentData *)sm->ctx; + if (cd->flags != DETECT_CONTENT_RELATIVE_NEXT || + strncmp((char *)cd->content, "three", cd->content_len) != 0) { + printf("one failed\n"); + result = 0; + goto end; + } + + sm = sm->next; + if (sm->type != DETECT_BYTE_EXTRACT) { + result = 0; + goto end; + } + bed1 = (DetectByteExtractData *)sm->ctx; + if (bed1->nbytes != 4 || + bed1->offset != 0 || + strcmp(bed1->name, "four") != 0 || + bed1->flags != (DETECT_BYTE_EXTRACT_FLAG_STRING | + DETECT_BYTE_EXTRACT_FLAG_RELATIVE) || + bed1->endian != DETECT_BYTE_EXTRACT_ENDIAN_NONE || + bed1->base != DETECT_BYTE_EXTRACT_BASE_HEX || + bed1->align_value != 0 || + bed1->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { + goto end; + } + if (bed1->local_id != 1) { + result = 0; + goto end; + } + + sm = sm->next; + if (sm->type != DETECT_ISDATAAT) { + result = 0; + goto end; + } + isdd = (DetectIsdataatData *)sm->ctx; + if (isdd->flags != (ISDATAAT_OFFSET_BE | + ISDATAAT_RELATIVE) || + isdd->dataat != bed1->local_id) { + printf("isdataat failed\n"); + result = 0; + goto end; + } + + if (sm->next != NULL) + goto end; + + result = 1; + + end: + SigGroupCleanup(de_ctx); + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + + return result; +} + void DetectByteExtractRegisterTests(void) { #ifdef UNITTESTS @@ -4397,6 +4965,11 @@ void DetectByteExtractRegisterTests(void) UtRegisterTest("DetectByteExtractTest55", DetectByteExtractTest55, 1); UtRegisterTest("DetectByteExtractTest56", DetectByteExtractTest56, 1); UtRegisterTest("DetectByteExtractTest57", DetectByteExtractTest57, 1); + + UtRegisterTest("DetectByteExtractTest58", DetectByteExtractTest58, 1); + UtRegisterTest("DetectByteExtractTest59", DetectByteExtractTest59, 1); + UtRegisterTest("DetectByteExtractTest60", DetectByteExtractTest60, 1); + UtRegisterTest("DetectByteExtractTest61", DetectByteExtractTest61, 1); #endif /* UNITTESTS */ return; diff --git a/src/detect-isdataat.c b/src/detect-isdataat.c index 39a1dd66e1..74c1152a65 100644 --- a/src/detect-isdataat.c +++ b/src/detect-isdataat.c @@ -45,11 +45,12 @@ #include "util-byte.h" #include "detect-pcre.h" #include "detect-bytejump.h" +#include "detect-byte-extract.h" /** * \brief Regex for parsing our isdataat options */ -#define PARSE_REGEX "^\\s*!?([0-9]{1,5})\\s*(,\\s*relative)?\\s*(,\\s*rawbytes\\s*)?\\s*$" +#define PARSE_REGEX "^\\s*!?([^\\s,]+)\\s*(,\\s*relative)?\\s*(,\\s*rawbytes\\s*)?\\s*$" static pcre *parse_regex; static pcre_extra *parse_regex_study; @@ -132,7 +133,7 @@ int DetectIsdataatMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet * * \retval idad pointer to DetectIsdataatData on success * \retval NULL on failure */ -DetectIsdataatData *DetectIsdataatParse (char *isdataatstr) +DetectIsdataatData *DetectIsdataatParse (char *isdataatstr, char **offset) { DetectIsdataatData *idad = NULL; char *args[3] = {NULL,NULL,NULL}; @@ -181,16 +182,24 @@ DetectIsdataatData *DetectIsdataatParse (char *isdataatstr) idad->flags = 0; idad->dataat = 0; - if (args[0] != NULL) { + if (args[0][0] != '-' && isalpha(args[0][0])) { + if (offset == NULL) { + SCLogError(SC_ERR_INVALID_ARGUMENT, "isdataat supplied with " + "var name for offset. \"offset\" argument supplied to " + "this function has to be non-NULL"); + goto error; + } + *offset = SCStrdup(args[0]); + if (*offset == NULL) + goto error; + } else { if (ByteExtractStringUint16(&idad->dataat, 10, - strlen(args[0]), args[0]) < 0 ) { + strlen(args[0]), args[0]) < 0 ) { SCLogError(SC_ERR_INVALID_VALUE, "isdataat out of range"); SCFree(idad); idad = NULL; goto error; } - } else { - goto error; } if (args[1] !=NULL) { @@ -242,8 +251,9 @@ int DetectIsdataatSetup (DetectEngineCtx *de_ctx, Signature *s, char *isdataatst SigMatch *dm = NULL; SigMatch *pm = NULL; SigMatch *prev_pm = NULL; + char *offset = NULL; - idad = DetectIsdataatParse(isdataatstr); + idad = DetectIsdataatParse(isdataatstr, &offset); if (idad == NULL) goto error; @@ -279,8 +289,36 @@ int DetectIsdataatSetup (DetectEngineCtx *de_ctx, Signature *s, char *isdataatst DETECT_CONTENT, sm->prev, DETECT_BYTEJUMP, sm->prev, DETECT_PCRE, sm->prev); + if (prev_pm == NULL) { + SCLogDebug("No preceding content or pcre keyword. Possible " + "since this is a dce alproto sig."); + if (offset != NULL) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var " + "seen in isdataat - %s\n", offset); + goto error; + } + return 0; + } } else { - pm = SigMatchGetLastSMFromLists(s, 34, + if (!(idad->flags & ISDATAAT_RELATIVE)) { + SigMatchAppendPayload(s, sm); + if (offset != NULL) { + SigMatch *bed_sm = + DetectByteExtractRetrieveSMVar(offset, s, + SigMatchListSMBelongsTo(s, sm)); + if (bed_sm == NULL) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var " + "seen in isdataat - %s\n", offset); + goto error; + } + DetectIsdataatData *isdd = sm->ctx; + isdd->dataat = ((DetectByteExtractData *)bed_sm->ctx)->local_id; + isdd->flags |= ISDATAAT_OFFSET_BE; + SCFree(offset); + } + return 0; + } + pm = SigMatchGetLastSMFromLists(s, 40, DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], /* 1 */ DETECT_URICONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], DETECT_AL_HTTP_CLIENT_BODY, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], @@ -297,50 +335,54 @@ int DetectIsdataatSetup (DetectEngineCtx *de_ctx, Signature *s, char *isdataatst DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], /* 15 */ DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_PMATCH]); + DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], + DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], + DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_DMATCH], + DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], + DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], + DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_DMATCH], + DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_UMATCH]); if (pm == NULL) { - if (idad->flags & ISDATAAT_RELATIVE) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "isdataat relative seen " - "without a previous content uricontent, " - "http_client_body, http_header, http_raw_header, " - "http_method, http_cookie or http_raw_uri keyword"); - goto error; - } else { - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_PMATCH); - } + SCLogError(SC_ERR_INVALID_SIGNATURE, "isdataat relative seen " + "without a previous content uricontent, " + "http_client_body, http_header, http_raw_header, " + "http_method, http_cookie, http_raw_uri, " + "byte_test, byte_extract, byte_jump keyword"); + goto error; } else { int list_type = -1; - if (pm->type == DETECT_PCRE || pm->type == DETECT_BYTEJUMP) { + if (pm->type == DETECT_PCRE || pm->type == DETECT_BYTEJUMP || + pm->type == DETECT_BYTE_EXTRACT || pm->type == DETECT_BYTETEST) { list_type = SigMatchListSMBelongsTo(s, pm); } else { switch (pm->type) { - case DETECT_CONTENT: - list_type = DETECT_SM_LIST_PMATCH; - break; - case DETECT_URICONTENT: - list_type = DETECT_SM_LIST_UMATCH; - break; - case DETECT_AL_HTTP_CLIENT_BODY: - list_type = DETECT_SM_LIST_HCBDMATCH; - break; - case DETECT_AL_HTTP_RAW_HEADER: - list_type = DETECT_SM_LIST_HRHDMATCH; - break; - case DETECT_AL_HTTP_HEADER: - list_type = DETECT_SM_LIST_HHDMATCH; - break; - case DETECT_AL_HTTP_METHOD: - list_type = DETECT_SM_LIST_HMDMATCH; - break; - case DETECT_AL_HTTP_COOKIE: - list_type = DETECT_SM_LIST_HCDMATCH; - break; - case DETECT_AL_HTTP_RAW_URI: - list_type = DETECT_SM_LIST_HRUDMATCH; - break; - default: - /* would never happen */ - break; + case DETECT_CONTENT: + list_type = DETECT_SM_LIST_PMATCH; + break; + case DETECT_URICONTENT: + list_type = DETECT_SM_LIST_UMATCH; + break; + case DETECT_AL_HTTP_CLIENT_BODY: + list_type = DETECT_SM_LIST_HCBDMATCH; + break; + case DETECT_AL_HTTP_RAW_HEADER: + list_type = DETECT_SM_LIST_HRHDMATCH; + break; + case DETECT_AL_HTTP_HEADER: + list_type = DETECT_SM_LIST_HHDMATCH; + break; + case DETECT_AL_HTTP_METHOD: + list_type = DETECT_SM_LIST_HMDMATCH; + break; + case DETECT_AL_HTTP_COOKIE: + list_type = DETECT_SM_LIST_HCDMATCH; + break; + case DETECT_AL_HTTP_RAW_URI: + list_type = DETECT_SM_LIST_HRUDMATCH; + break; + default: + /* would never happen */ + break; } /* switch */ } /* else */ if (list_type == -1) { @@ -353,22 +395,19 @@ int DetectIsdataatSetup (DetectEngineCtx *de_ctx, Signature *s, char *isdataatst prev_pm = pm; } - if (!(idad->flags & ISDATAAT_RELATIVE)) { - return 0; - } - - if (prev_pm == NULL) { - if (s->alproto == ALPROTO_DCERPC) { - SCLogDebug("No preceding content or pcre keyword. Possible " - "since this is a dce alproto sig."); - return 0; - } else { - SCLogError(SC_ERR_INVALID_SIGNATURE, "No preceding content, pcre, " - "uricontent, http_client_body, http_header, " - "http_raw_header, http_method, http_cookie or " - "http_raw_uri keyword"); + if (offset != NULL) { + SigMatch *bed_sm = + DetectByteExtractRetrieveSMVar(offset, s, + SigMatchListSMBelongsTo(s, sm)); + if (bed_sm == NULL) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var " + "seen in isdataat - %s\n", offset); goto error; } + DetectIsdataatData *isdd = sm->ctx; + isdd->dataat = ((DetectByteExtractData *)bed_sm->ctx)->local_id; + isdd->flags |= ISDATAAT_OFFSET_BE; + SCFree(offset); } DetectContentData *cd = NULL; @@ -406,7 +445,9 @@ int DetectIsdataatSetup (DetectEngineCtx *de_ctx, Signature *s, char *isdataatst break; case DETECT_BYTEJUMP: - SCLogDebug("Do nothing for bytejump"); + case DETECT_BYTETEST: + case DETECT_BYTE_EXTRACT: + SCLogDebug("Do nothing for byte_jump, byte_test, byte_extract"); break; default: @@ -446,7 +487,7 @@ void DetectIsdataatFree(void *ptr) { int DetectIsdataatTestParse01 (void) { int result = 0; DetectIsdataatData *idad = NULL; - idad = DetectIsdataatParse("30 "); + idad = DetectIsdataatParse("30 ", NULL); if (idad != NULL) { DetectIsdataatFree(idad); result = 1; @@ -462,7 +503,7 @@ int DetectIsdataatTestParse01 (void) { int DetectIsdataatTestParse02 (void) { int result = 0; DetectIsdataatData *idad = NULL; - idad = DetectIsdataatParse("30 , relative"); + idad = DetectIsdataatParse("30 , relative", NULL); if (idad != NULL && idad->flags & ISDATAAT_RELATIVE && !(idad->flags & ISDATAAT_RAWBYTES)) { DetectIsdataatFree(idad); result = 1; @@ -478,7 +519,7 @@ int DetectIsdataatTestParse02 (void) { int DetectIsdataatTestParse03 (void) { int result = 0; DetectIsdataatData *idad = NULL; - idad = DetectIsdataatParse("30,relative, rawbytes "); + idad = DetectIsdataatParse("30,relative, rawbytes ", NULL); if (idad != NULL && idad->flags & ISDATAAT_RELATIVE && idad->flags & ISDATAAT_RAWBYTES) { DetectIsdataatFree(idad); result = 1; diff --git a/src/detect-isdataat.h b/src/detect-isdataat.h index daaa8ebc4e..f264f36d9e 100644 --- a/src/detect-isdataat.h +++ b/src/detect-isdataat.h @@ -27,6 +27,7 @@ #define ISDATAAT_RELATIVE 0x01 #define ISDATAAT_RAWBYTES 0x02 #define ISDATAAT_NEGATED 0x04 +#define ISDATAAT_OFFSET_BE 0x08 #define ISDATAAT_MIN 0 #define ISDATAAT_MAX 65535