diff --git a/src/detect-bytejump.c b/src/detect-bytejump.c index 8a8b5e4b7d..65979a569e 100644 --- a/src/detect-bytejump.c +++ b/src/detect-bytejump.c @@ -168,8 +168,10 @@ int DetectBytejumpDoMatch(DetectEngineThreadCtx *det_ctx, const Signature *s, if (flags & DETECT_BYTEJUMP_BEGIN) { jumpptr = payload + val; //printf("NEWVAL: payload %p + %ld = %p\n", p->payload, val, jumpptr); - } - else { + } else if (flags & DETECT_BYTEJUMP_END) { + jumpptr = payload + payload_len + val; + //printf("NEWVAL: payload %p + %ld = %p\n", p->payload, val, jumpptr); + } else { val += extbytes; jumpptr = ptr + val; //printf("NEWVAL: ptr %p + %ld = %p\n", ptr, val, jumpptr); @@ -435,6 +437,8 @@ static DetectBytejumpData *DetectBytejumpParse(DetectEngineCtx *de_ctx, const ch data->flags |= DETECT_BYTEJUMP_LITTLE; } else if (strcasecmp("from_beginning", args[i]) == 0) { data->flags |= DETECT_BYTEJUMP_BEGIN; + } else if (strcasecmp("from_end", args[i]) == 0) { + data->flags |= DETECT_BYTEJUMP_END; } else if (strcasecmp("align", args[i]) == 0) { data->flags |= DETECT_BYTEJUMP_ALIGN; } else if (strncasecmp("multiplier ", args[i], 11) == 0) { @@ -461,6 +465,12 @@ static DetectBytejumpData *DetectBytejumpParse(DetectEngineCtx *de_ctx, const ch } } + if ((data->flags & DETECT_BYTEJUMP_END) && (data->flags & DETECT_BYTEJUMP_BEGIN)) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "'from_end' and 'from_beginning' " + "cannot be used in the same byte_jump statement"); + goto error; + } + if (data->flags & DETECT_BYTEJUMP_STRING) { /* 23 - This is the largest string (octal, with a zero prefix) that * will not overflow uint64_t. The only way this length @@ -566,6 +576,7 @@ static int DetectBytejumpSetup(DetectEngineCtx *de_ctx, Signature *s, const char (data->flags & DETECT_BYTEJUMP_LITTLE) || (data->flags & DETECT_BYTEJUMP_BIG) || (data->flags & DETECT_BYTEJUMP_BEGIN) || + (data->flags & DETECT_BYTEJUMP_END) || (data->base == DETECT_BYTEJUMP_BASE_DEC) || (data->base == DETECT_BYTEJUMP_BASE_HEX) || (data->base == DETECT_BYTEJUMP_BASE_OCT) ) { @@ -579,7 +590,7 @@ static int DetectBytejumpSetup(DetectEngineCtx *de_ctx, Signature *s, const char SigMatch *bed_sm = DetectByteExtractRetrieveSMVar(offset, s); if (bed_sm == NULL) { SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var " - "seen in byte_jump - %s\n", offset); + "seen in byte_jump - %s", offset); goto error; } data->offset = ((DetectByteExtractData *)bed_sm->ctx)->local_id; @@ -1094,6 +1105,29 @@ static int DetectBytejumpTestParse12(void) return result; } +static int DetectBytejumpTestParse13(void) +{ + DetectBytejumpData *data = DetectBytejumpParse(NULL, + " 4,0 , relative , little, string, dec, " "align, from_end", NULL); + FAIL_IF_NULL(data); + FAIL_IF_NOT(data->flags & DETECT_BYTEJUMP_END); + + DetectBytejumpFree(NULL, data); + + PASS; +} + +static int DetectBytejumpTestParse14(void) +{ + DetectBytejumpData *data = DetectBytejumpParse(NULL, + " 4,0 , relative , little, string, dec, " + "align, from_beginning, from_end", NULL); + + FAIL_IF_NOT_NULL(data); + + PASS; +} + /** * \test DetectByteJumpTestPacket01 is a test to check matches of * byte_jump and byte_jump relative works if the previous keyword is pcre @@ -1283,6 +1317,27 @@ end: return result; } +/** + * \test check matches of with from_end + */ +static int DetectByteJumpTestPacket08 (void) +{ + uint8_t *buf = (uint8_t *)"XX04abcdABCD"; + uint16_t buflen = strlen((char *)buf); + Packet *p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); + + FAIL_IF_NULL(p); + + char sig[] = "alert tcp any any -> any any (content:\"XX\"; byte_jump:2,0," + "relative,string,dec,from_end, post_offset -8; content:\"ABCD\"; sid:1; rev:1;)"; + + FAIL_IF_NOT(UTHPacketMatchSig(p, sig)); + + UTHFreePacket(p); + + PASS; +} + #endif /* UNITTESTS */ @@ -1307,6 +1362,8 @@ static void DetectBytejumpRegisterTests(void) UtRegisterTest("DetectBytejumpTestParse10", DetectBytejumpTestParse10); UtRegisterTest("DetectBytejumpTestParse11", DetectBytejumpTestParse11); UtRegisterTest("DetectBytejumpTestParse12", DetectBytejumpTestParse12); + UtRegisterTest("DetectBytejumpTestParse13", DetectBytejumpTestParse13); + UtRegisterTest("DetectBytejumpTestParse14", DetectBytejumpTestParse14); UtRegisterTest("DetectByteJumpTestPacket01", DetectByteJumpTestPacket01); UtRegisterTest("DetectByteJumpTestPacket02", DetectByteJumpTestPacket02); @@ -1315,6 +1372,7 @@ static void DetectBytejumpRegisterTests(void) UtRegisterTest("DetectByteJumpTestPacket05", DetectByteJumpTestPacket05); UtRegisterTest("DetectByteJumpTestPacket06", DetectByteJumpTestPacket06); UtRegisterTest("DetectByteJumpTestPacket07", DetectByteJumpTestPacket07); + UtRegisterTest("DetectByteJumpTestPacket08", DetectByteJumpTestPacket08); #endif /* UNITTESTS */ } diff --git a/src/detect-bytejump.h b/src/detect-bytejump.h index 08455b9553..eccd2f6af1 100644 --- a/src/detect-bytejump.h +++ b/src/detect-bytejump.h @@ -39,11 +39,12 @@ #define DETECT_BYTEJUMP_ALIGN 0x20 /**< "align" offset */ #define DETECT_BYTEJUMP_DCE 0x40 /**< "dce" enabled */ #define DETECT_BYTEJUMP_OFFSET_BE 0x80 /**< "byte extract" enabled */ +#define DETECT_BYTEJUMP_END 0x100 /**< "from_end" jump */ typedef struct DetectBytejumpData_ { uint8_t nbytes; /**< Number of bytes to compare */ uint8_t base; /**< String value base (oct|dec|hex) */ - uint8_t flags; /**< Flags (big|little|relative|string) */ + uint16_t flags; /**< Flags (big|little|relative|string) */ uint32_t multiplier; /**< Multiplier for nbytes (multiplier n)*/ int32_t offset; /**< Offset in payload to extract value */ int32_t post_offset; /**< Offset to adjust post-jump */