byte extract added to the engine. Detection support added for packet payload, uri and dce detection engines

remotes/origin/master-1.1.x
Anoop Saldanha 15 years ago committed by Victor Julien
parent 64b069369e
commit 35f3eafa5e

@ -147,6 +147,7 @@ detect-asn1.c detect-asn1.h \
detect-http-stat-code.c detect-http-stat-code.h \
detect-ssl-version.c detect-ssl-version.h \
detect-ssl-state.c detect-ssl-state.h \
detect-byte-extract.c detect-byte-extract.h \
util-atomic.h \
util-print.c util-print.h \
util-fmemopen.c util-fmemopen.h \

File diff suppressed because it is too large Load Diff

@ -0,0 +1,74 @@
/* 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 Anoop Saldanha <poonaatsoc@gmail.com>
*/
#ifndef __DETECT_BYTEEXTRACT_H__
#define __DETECT_BYTEEXTRACT_H__
/* flags */
#define DETECT_BYTE_EXTRACT_FLAG_RELATIVE 0x01
#define DETECT_BYTE_EXTRACT_FLAG_MULTIPLIER 0x02
#define DETECT_BYTE_EXTRACT_FLAG_STRING 0x04
#define DETECT_BYTE_EXTRACT_FLAG_ALIGN 0x08
#define DETECT_BYTE_EXTRACT_FLAG_ENDIAN 0x10
/* endian value to be used. Would be stored in DetectByteParseData->endian */
#define DETECT_BYTE_EXTRACT_ENDIAN_NONE 0
#define DETECT_BYTE_EXTRACT_ENDIAN_BIG 1
#define DETECT_BYTE_EXTRACT_ENDIAN_LITTLE 2
#define DETECT_BYTE_EXTRACT_ENDIAN_DCE 3
/**
* \brief Holds data related to byte_extract keyword.
*/
typedef struct DetectByteExtractData_ {
/* local id used by other keywords in the sig to reference this */
uint8_t local_id;
uint8_t nbytes;
int16_t pad;
int32_t offset;
const char *name;
uint8_t flags;
uint8_t endian;
uint8_t base;
uint8_t align_value;
uint16_t multiplier_value;
/* unique id used to reference this byte_extract keyword */
uint16_t id;
} DetectByteExtractData;
/* the max local id used amongst all sigs */
extern int byte_extract_max_local_id;
void DetectByteExtractRegister(void);
int DetectByteExtractSetup(DetectEngineCtx *, Signature *, char *);
void DetectByteExtractFree(void *);
int DetectByteExtractMatch(ThreadVars *, DetectEngineThreadCtx *,
Packet *, Signature *, SigMatch *);
SigMatch *DetectByteExtractRetrieveSMVar(const char *, Signature *, int);
int DetectByteExtractDoMatch(DetectEngineThreadCtx *, SigMatch *, Signature *,
uint8_t *, uint16_t, uint64_t *, uint8_t);
#endif /* __DETECT_BYTEEXTRACT_H__ */

@ -32,6 +32,7 @@
#include "app-layer.h"
#include "detect-bytejump.h"
#include "detect-byte-extract.h"
#include "detect-content.h"
#include "detect-uricontent.h"
@ -105,7 +106,8 @@ error:
* \retval 0 no match
*/
int DetectBytejumpDoMatch(DetectEngineThreadCtx *det_ctx, Signature *s,
SigMatch *m, uint8_t *payload, uint32_t payload_len)
SigMatch *m, uint8_t *payload, uint32_t payload_len,
uint8_t flags, int32_t offset)
{
SCEnter();
@ -123,7 +125,7 @@ int DetectBytejumpDoMatch(DetectEngineThreadCtx *det_ctx, Signature *s,
/* Calculate the ptr value for the bytejump and length remaining in
* the packet from that point.
*/
if (data->flags & DETECT_BYTEJUMP_RELATIVE) {
if (flags & DETECT_BYTEJUMP_RELATIVE) {
ptr = payload + det_ctx->payload_offset;
len = payload_len - det_ctx->payload_offset;
@ -132,12 +134,12 @@ int DetectBytejumpDoMatch(DetectEngineThreadCtx *det_ctx, Signature *s,
SCReturnInt(0);
}
ptr += data->offset;
len -= data->offset;
ptr += offset;
len -= offset;
}
else {
ptr = payload + data->offset;
len = payload_len - data->offset;
ptr = payload + offset;
len = payload_len - offset;
}
/* Verify the to-be-extracted data is within the packet */
@ -149,7 +151,7 @@ int DetectBytejumpDoMatch(DetectEngineThreadCtx *det_ctx, Signature *s,
}
/* Extract the byte data */
if (data->flags & DETECT_BYTEJUMP_STRING) {
if (flags & DETECT_BYTEJUMP_STRING) {
extbytes = ByteExtractStringUint64(&val, data->base,
data->nbytes, (const char *)ptr);
if(extbytes <= 0) {
@ -159,7 +161,7 @@ int DetectBytejumpDoMatch(DetectEngineThreadCtx *det_ctx, Signature *s,
}
}
else {
int endianness = (data->flags & DETECT_BYTEJUMP_LITTLE) ? BYTE_LITTLE_ENDIAN : BYTE_BIG_ENDIAN;
int endianness = (flags & DETECT_BYTEJUMP_LITTLE) ? BYTE_LITTLE_ENDIAN : BYTE_BIG_ENDIAN;
extbytes = ByteExtractUint64(&val, endianness, data->nbytes, ptr);
if (extbytes != data->nbytes) {
SCLogError(SC_ERR_BYTE_EXTRACT_FAILED,"Error extracting %d bytes "
@ -172,7 +174,7 @@ int DetectBytejumpDoMatch(DetectEngineThreadCtx *det_ctx, Signature *s,
/* Adjust the jump value based on flags */
val *= data->multiplier;
if (data->flags & DETECT_BYTEJUMP_ALIGN) {
if (flags & DETECT_BYTEJUMP_ALIGN) {
if ((val % 4) != 0) {
val += 4 - (val % 4);
}
@ -180,7 +182,7 @@ int DetectBytejumpDoMatch(DetectEngineThreadCtx *det_ctx, Signature *s,
val += extbytes + data->post_offset;
/* Calculate the jump location */
if (data->flags & DETECT_BYTEJUMP_BEGIN) {
if (flags & DETECT_BYTEJUMP_BEGIN) {
jumpptr = payload + val;
//printf("NEWVAL: payload %p + %ld = %p\n", p->payload, val, jumpptr);
}
@ -201,7 +203,7 @@ int DetectBytejumpDoMatch(DetectEngineThreadCtx *det_ctx, Signature *s,
#ifdef DEBUG
if (SCLogDebugEnabled()) {
uint8_t *sptr = (data->flags & DETECT_BYTEJUMP_BEGIN) ? payload : ptr;
uint8_t *sptr = (flags & DETECT_BYTEJUMP_BEGIN) ? payload : ptr;
SCLogDebug("jumping %" PRId64 " bytes from %p (%08x) to %p (%08x)",
val, sptr, (int)(sptr - payload),
jumpptr, (int)(jumpptr - payload));
@ -323,7 +325,7 @@ int DetectBytejumpMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
return 1;
}
DetectBytejumpData *DetectBytejumpParse(char *optstr)
DetectBytejumpData *DetectBytejumpParse(char *optstr, char **offset)
{
DetectBytejumpData *data = NULL;
char *args[10] = {
@ -412,12 +414,23 @@ DetectBytejumpData *DetectBytejumpParse(char *optstr)
}
/* Offset */
if (ByteExtractStringInt32(&data->offset, 0, strlen(args[1]), args[1]) <= 0) {
SCLogError(SC_ERR_INVALID_VALUE, "Malformed offset: %s", optstr);
goto error;
if (args[1][0] != '-' && isalpha(args[1][0])) {
if (offset == NULL) {
SCLogError(SC_ERR_INVALID_ARGUMENT, "byte_jump supplied with "
"var name for offset. \"value\" argument supplied to "
"this function has to be non-NULL");
goto error;
}
*offset = SCStrdup(args[1]);
if (*offset == NULL)
goto error;
} else {
if (ByteExtractStringInt32(&data->offset, 0, strlen(args[1]), args[1]) <= 0) {
SCLogError(SC_ERR_INVALID_VALUE, "Malformed offset: %s", optstr);
goto error;
}
}
/* The remaining options are flags. */
/** \todo Error on dups? */
for (i = 2; i < numargs; i++) {
@ -514,8 +527,9 @@ int DetectBytejumpSetup(DetectEngineCtx *de_ctx, Signature *s, char *optstr)
{
DetectBytejumpData *data = NULL;
SigMatch *sm = NULL;
char *offset = NULL;
data = DetectBytejumpParse(optstr);
data = DetectBytejumpParse(optstr, &offset);
if (data == NULL)
goto error;
@ -574,6 +588,21 @@ int DetectBytejumpSetup(DetectEngineCtx *de_ctx, Signature *s, char *optstr)
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 byte_jump - %s\n", offset);
goto error;
}
DetectBytejumpData *bjd = sm->ctx;
bjd->offset = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
bjd->flags |= DETECT_BYTEJUMP_OFFSET_BE;
SCFree(offset);
}
if ( !(data->flags & DETECT_BYTEJUMP_RELATIVE)) {
return(0);
}
@ -681,7 +710,7 @@ void DetectBytejumpFree(void *ptr)
int DetectBytejumpTestParse01(void) {
int result = 0;
DetectBytejumpData *data = NULL;
data = DetectBytejumpParse("4,0");
data = DetectBytejumpParse("4,0", NULL);
if (data != NULL) {
DetectBytejumpFree(data);
result = 1;
@ -696,7 +725,7 @@ int DetectBytejumpTestParse01(void) {
int DetectBytejumpTestParse02(void) {
int result = 0;
DetectBytejumpData *data = NULL;
data = DetectBytejumpParse("4, 0");
data = DetectBytejumpParse("4, 0", NULL);
if (data != NULL) {
if ( (data->nbytes == 4)
&& (data->offset == 0)
@ -720,7 +749,7 @@ int DetectBytejumpTestParse03(void) {
int result = 0;
DetectBytejumpData *data = NULL;
data = DetectBytejumpParse(" 4,0 , relative , little, string, "
"dec, align, from_beginning");
"dec, align, from_beginning", NULL);
if (data != NULL) {
if ( (data->nbytes == 4)
&& (data->offset == 0)
@ -752,7 +781,7 @@ int DetectBytejumpTestParse04(void) {
DetectBytejumpData *data = NULL;
data = DetectBytejumpParse(" 4,0 , relative , little, string, "
"dec, align, from_beginning , "
"multiplier 2 , post_offset -16 ");
"multiplier 2 , post_offset -16 ", NULL);
if (data != NULL) {
if ( (data->nbytes == 4)
&& (data->offset == 0)
@ -780,7 +809,7 @@ int DetectBytejumpTestParse05(void) {
int result = 0;
DetectBytejumpData *data = NULL;
data = DetectBytejumpParse(" 4,0 , relative , little, dec, "
"align, from_beginning");
"align, from_beginning", NULL);
if (data == NULL) {
result = 1;
}
@ -794,7 +823,7 @@ int DetectBytejumpTestParse05(void) {
int DetectBytejumpTestParse06(void) {
int result = 0;
DetectBytejumpData *data = NULL;
data = DetectBytejumpParse("9, 0");
data = DetectBytejumpParse("9, 0", NULL);
if (data == NULL) {
result = 1;
}
@ -808,7 +837,7 @@ int DetectBytejumpTestParse06(void) {
int DetectBytejumpTestParse07(void) {
int result = 0;
DetectBytejumpData *data = NULL;
data = DetectBytejumpParse("24, 0, string, dec");
data = DetectBytejumpParse("24, 0, string, dec", NULL);
if (data == NULL) {
result = 1;
}
@ -822,7 +851,7 @@ int DetectBytejumpTestParse07(void) {
int DetectBytejumpTestParse08(void) {
int result = 0;
DetectBytejumpData *data = NULL;
data = DetectBytejumpParse("4, 0xffffffffffffffff");
data = DetectBytejumpParse("4, 0xffffffffffffffff", NULL);
if (data == NULL) {
result = 1;
}

@ -38,6 +38,7 @@
#define DETECT_BYTEJUMP_RELATIVE 0x10 /**< "relative" offset */
#define DETECT_BYTEJUMP_ALIGN 0x20 /**< "align" offset */
#define DETECT_BYTEJUMP_DCE 0x40 /**< "dce" enabled */
#define DETECT_BYTEJUMP_OFFSET_BE 0x80 /**< "byte extract" enabled */
typedef struct DetectBytejumpData_ {
uint8_t nbytes; /**< Number of bytes to compare */
@ -86,11 +87,13 @@ void DetectBytejumpFree(void *ptr);
* "align", "from beginning", "multiplier N", "post_offset N"
*
* \param optstr Pointer to the user provided byte_jump options
* \param offset Used to pass the offset back, if byte_jump uses a byte_extract
* var.
*
* \retval data pointer to DetectBytejumpData on success
* \retval NULL on failure
*/
DetectBytejumpData *DetectBytejumpParse(char *optstr);
DetectBytejumpData *DetectBytejumpParse(char *optstr, char **offset);
/**
* This function is used to match byte_jump
@ -111,7 +114,8 @@ DetectBytejumpData *DetectBytejumpParse(char *optstr);
*/
int DetectBytejumpMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
Packet *p, Signature *s, SigMatch *m);
int DetectBytejumpDoMatch(DetectEngineThreadCtx *, Signature *, SigMatch *, uint8_t *, uint32_t);
int DetectBytejumpDoMatch(DetectEngineThreadCtx *, Signature *, SigMatch *,
uint8_t *, uint32_t, uint8_t, int32_t);
#endif /* __DETECT_BYTEJUMP_H__ */

@ -34,6 +34,7 @@
#include "detect-uricontent.h"
#include "detect-bytetest.h"
#include "detect-bytejump.h"
#include "detect-byte-extract.h"
#include "app-layer.h"
#include "util-byte.h"
@ -109,7 +110,8 @@ error:
* \retval 1 match
* \retval 0 no match
*/
int DetectBytetestDoMatch(DetectEngineThreadCtx *det_ctx, Signature *s, SigMatch *m, uint8_t *payload, uint32_t payload_len) {
int DetectBytetestDoMatch(DetectEngineThreadCtx *det_ctx, Signature *s, SigMatch *m, uint8_t *payload, uint32_t payload_len,
uint8_t flags, int32_t offset, uint64_t value) {
SCEnter();
DetectBytetestData *data = (DetectBytetestData *)m->ctx;
@ -127,7 +129,7 @@ int DetectBytetestDoMatch(DetectEngineThreadCtx *det_ctx, Signature *s, SigMatch
/* Calculate the ptr value for the bytetest and length remaining in
* the packet from that point.
*/
if (data->flags & DETECT_BYTETEST_RELATIVE) {
if (flags & DETECT_BYTETEST_RELATIVE) {
SCLogDebug("relative, working with det_ctx->payload_offset %"PRIu32", "
"data->offset %"PRIu32"", det_ctx->payload_offset, data->offset);
@ -139,16 +141,16 @@ int DetectBytetestDoMatch(DetectEngineThreadCtx *det_ctx, Signature *s, SigMatch
SCReturnInt(0);
}
ptr += data->offset;
len -= data->offset;
ptr += offset;
len -= offset;
//PrintRawDataFp(stdout,ptr,len);
}
else {
SCLogDebug("absolute, data->offset %"PRIu32"", data->offset);
ptr = payload + data->offset;
len = payload_len - data->offset;
ptr = payload + offset;
len = payload_len - offset;
}
/* Validate that the to-be-extracted is within the packet
@ -160,10 +162,10 @@ int DetectBytetestDoMatch(DetectEngineThreadCtx *det_ctx, Signature *s, SigMatch
SCReturnInt(0);
}
neg = data->flags & DETECT_BYTETEST_NEGOP;
neg = flags & DETECT_BYTETEST_NEGOP;
/* Extract the byte data */
if (data->flags & DETECT_BYTETEST_STRING) {
if (flags & DETECT_BYTETEST_STRING) {
extbytes = ByteExtractStringUint64(&val, data->base,
data->nbytes, (const char *)ptr);
if (extbytes <= 0) {
@ -182,7 +184,7 @@ int DetectBytetestDoMatch(DetectEngineThreadCtx *det_ctx, Signature *s, SigMatch
data->base, val, (neg ? "!" : ""), data->op, data->value);
}
else {
int endianness = (data->flags & DETECT_BYTETEST_LITTLE) ?
int endianness = (flags & DETECT_BYTETEST_LITTLE) ?
BYTE_LITTLE_ENDIAN : BYTE_BIG_ENDIAN;
extbytes = ByteExtractUint64(&val, endianness, data->nbytes, ptr);
if (extbytes != data->nbytes) {
@ -195,42 +197,41 @@ int DetectBytetestDoMatch(DetectEngineThreadCtx *det_ctx, Signature *s, SigMatch
val, (neg ? "!" : ""), data->op, data->value);
}
/* Compare using the configured operator */
match = 0;
switch (data->op) {
case DETECT_BYTETEST_OP_EQ:
if (val == data->value) {
if (val == value) {
match = 1;
}
break;
case DETECT_BYTETEST_OP_LT:
if (val < data->value) {
if (val < value) {
match = 1;
}
break;
case DETECT_BYTETEST_OP_GT:
if (val > data->value) {
if (val > value) {
match = 1;
}
break;
case DETECT_BYTETEST_OP_AND:
if (val & data->value) {
if (val & value) {
match = 1;
}
break;
case DETECT_BYTETEST_OP_OR:
if (val ^ data->value) {
if (val ^ value) {
match = 1;
}
break;
case DETECT_BYTETEST_OP_GE:
if (val >= data->value) {
if (val >= value) {
match = 1;
}
break;
case DETECT_BYTETEST_OP_LE:
if (val <= data->value) {
if (val <= value) {
match = 1;
}
break;
@ -253,7 +254,8 @@ int DetectBytetestDoMatch(DetectEngineThreadCtx *det_ctx, Signature *s, SigMatch
int DetectBytetestMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
Packet *p, Signature *s, SigMatch *m)
{
return DetectBytetestDoMatch(det_ctx, s, m, p->payload, p->payload_len);
return DetectBytetestDoMatch(det_ctx, s, m, p->payload, p->payload_len,
((DetectBytetestData *)m->ctx)->flags, 0, 0);
#if 0
DetectBytetestData *data = (DetectBytetestData *)m->ctx;
uint8_t *ptr = NULL;
@ -376,7 +378,7 @@ int DetectBytetestMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
#endif
}
DetectBytetestData *DetectBytetestParse(char *optstr)
DetectBytetestData *DetectBytetestParse(char *optstr, char **value, char **offset)
{
DetectBytetestData *data = NULL;
char *args[9] = {
@ -457,18 +459,41 @@ DetectBytetestData *DetectBytetestParse(char *optstr)
}
/* Value */
if (ByteExtractStringUint64(&data->value, 0, 0, args[3]) <= 0) {
SCLogError(SC_ERR_INVALID_VALUE, "Malformed value: %s", str_ptr);
goto error;
if (args[3][0] != '-' && isalpha(args[3][0])) {
if (value == NULL) {
SCLogError(SC_ERR_INVALID_ARGUMENT, "byte_test supplied with "
"var name for value. \"value\" argument supplied to "
"this function has to be non-NULL");
goto error;
}
*value = SCStrdup(args[3]);
if (*value == NULL)
goto error;
} else {
if (ByteExtractStringUint64(&data->value, 0, 0, args[3]) <= 0) {
SCLogError(SC_ERR_INVALID_VALUE, "Malformed value: %s", str_ptr);
goto error;
}
}
/* Offset */
if (ByteExtractStringInt32(&data->offset, 0, 0, args[4]) <= 0) {
SCLogError(SC_ERR_INVALID_VALUE, " Malformed offset: %s", str_ptr);
goto error;
if (args[4][0] != '-' && isalpha(args[4][0])) {
if (offset == NULL) {
SCLogError(SC_ERR_INVALID_ARGUMENT, "byte_test supplied with "
"var name for offset. \"offset\" argument supplied to "
"this function has to be non-NULL");
goto error;
}
*offset = SCStrdup(args[4]);
if (*offset == NULL)
goto error;
} else {
if (ByteExtractStringInt32(&data->offset, 0, 0, args[4]) <= 0) {
SCLogError(SC_ERR_INVALID_VALUE, " Malformed offset: %s", str_ptr);
goto error;
}
}
/* The remaining options are flags. */
/** \todo Error on dups? */
for (i = 5; i < (ret - 1); i++) {
@ -545,8 +570,10 @@ int DetectBytetestSetup(DetectEngineCtx *de_ctx, Signature *s, char *optstr)
{
DetectBytetestData *data = NULL;
SigMatch *sm = NULL;
char *value = NULL;
char *offset = NULL;
data = DetectBytetestParse(optstr);
data = DetectBytetestParse(optstr, &value, &offset);
if (data == NULL)
goto error;
@ -604,6 +631,36 @@ int DetectBytetestSetup(DetectEngineCtx *de_ctx, Signature *s, char *optstr)
SigMatchAppendPayload(s, sm);
}
if (value != NULL) {
SigMatch *bed_sm =
DetectByteExtractRetrieveSMVar(value, s,
SigMatchListSMBelongsTo(s, sm));
if (bed_sm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
"seen in byte_test - %s\n", value);
goto error;
}
DetectBytetestData *btd = sm->ctx;
btd->value = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
btd->flags |= DETECT_BYTETEST_VALUE_BE;
SCFree(value);
}
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 byte_test - %s\n", offset);
goto error;
}
DetectBytetestData *btd = sm->ctx;
btd->offset = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
btd->flags |= DETECT_BYTETEST_OFFSET_BE;
SCFree(offset);
}
if ( !(data->flags & DETECT_BYTETEST_RELATIVE)) {
return 0;
}
@ -682,10 +739,10 @@ int DetectBytetestSetup(DetectEngineCtx *de_ctx, Signature *s, char *optstr)
return 0;
error:
if (data != NULL)
DetectBytetestFree(data);
if (sm != NULL)
SCFree(sm);
//if (data != NULL)
// DetectBytetestFree(data);
//if (sm != NULL)
// SCFree(sm);
return -1;
}
@ -711,7 +768,7 @@ void DetectBytetestFree(void *ptr)
int DetectBytetestTestParse01(void) {
int result = 0;
DetectBytetestData *data = NULL;
data = DetectBytetestParse("4, =, 1 , 0");
data = DetectBytetestParse("4, =, 1 , 0", NULL, NULL);
if (data != NULL) {
DetectBytetestFree(data);
result = 1;
@ -726,7 +783,7 @@ int DetectBytetestTestParse01(void) {
int DetectBytetestTestParse02(void) {
int result = 0;
DetectBytetestData *data = NULL;
data = DetectBytetestParse("4, !=, 1, 0");
data = DetectBytetestParse("4, !=, 1, 0", NULL, NULL);
if (data != NULL) {
if ( (data->op == DETECT_BYTETEST_OP_EQ)
&& (data->nbytes == 4)
@ -749,7 +806,7 @@ int DetectBytetestTestParse02(void) {
int DetectBytetestTestParse03(void) {
int result = 0;
DetectBytetestData *data = NULL;
data = DetectBytetestParse("4, !=, 1, 0, relative");
data = DetectBytetestParse("4, !=, 1, 0, relative", NULL, NULL);
if (data != NULL) {
if ( (data->op == DETECT_BYTETEST_OP_EQ)
&& (data->nbytes == 4)
@ -773,7 +830,7 @@ int DetectBytetestTestParse03(void) {
int DetectBytetestTestParse04(void) {
int result = 0;
DetectBytetestData *data = NULL;
data = DetectBytetestParse("4, !=, 1, 0, string, oct");
data = DetectBytetestParse("4, !=, 1, 0, string, oct", NULL, NULL);
if (data != NULL) {
if ( (data->op == DETECT_BYTETEST_OP_EQ)
&& (data->nbytes == 4)
@ -797,7 +854,7 @@ int DetectBytetestTestParse04(void) {
int DetectBytetestTestParse05(void) {
int result = 0;
DetectBytetestData *data = NULL;
data = DetectBytetestParse("4, =, 1, 0, string, dec");
data = DetectBytetestParse("4, =, 1, 0, string, dec", NULL, NULL);
if (data != NULL) {
if ( (data->op == DETECT_BYTETEST_OP_EQ)
&& (data->nbytes == 4)
@ -820,7 +877,7 @@ int DetectBytetestTestParse05(void) {
int DetectBytetestTestParse06(void) {
int result = 0;
DetectBytetestData *data = NULL;
data = DetectBytetestParse("4, >, 1, 0, string, hex");
data = DetectBytetestParse("4, >, 1, 0, string, hex", NULL, NULL);
if (data != NULL) {
if ( (data->op == DETECT_BYTETEST_OP_GT)
&& (data->nbytes == 4)
@ -843,7 +900,7 @@ int DetectBytetestTestParse06(void) {
int DetectBytetestTestParse07(void) {
int result = 0;
DetectBytetestData *data = NULL;
data = DetectBytetestParse("4, <, 5, 0, big");
data = DetectBytetestParse("4, <, 5, 0, big", NULL, NULL);
if (data != NULL) {
if ( (data->op == DETECT_BYTETEST_OP_LT)
&& (data->nbytes == 4)
@ -866,7 +923,7 @@ int DetectBytetestTestParse07(void) {
int DetectBytetestTestParse08(void) {
int result = 0;
DetectBytetestData *data = NULL;
data = DetectBytetestParse("4, <, 5, 0, little");
data = DetectBytetestParse("4, <, 5, 0, little", NULL, NULL);
if (data != NULL) {
if ( (data->op == DETECT_BYTETEST_OP_LT)
&& (data->nbytes == 4)
@ -889,7 +946,7 @@ int DetectBytetestTestParse08(void) {
int DetectBytetestTestParse09(void) {
int result = 0;
DetectBytetestData *data = NULL;
data = DetectBytetestParse("4, !, 5, 0");
data = DetectBytetestParse("4, !, 5, 0", NULL, NULL);
if (data != NULL) {
if ( (data->op == DETECT_BYTETEST_OP_EQ)
&& (data->nbytes == 4)
@ -912,7 +969,7 @@ int DetectBytetestTestParse09(void) {
int DetectBytetestTestParse10(void) {
int result = 0;
DetectBytetestData *data = NULL;
data = DetectBytetestParse(" 4 , ! &, 5 , 0 , little ");
data = DetectBytetestParse(" 4 , ! &, 5 , 0 , little ", NULL, NULL);
if (data != NULL) {
if ( (data->op == DETECT_BYTETEST_OP_AND)
&& (data->nbytes == 4)
@ -935,7 +992,7 @@ int DetectBytetestTestParse10(void) {
int DetectBytetestTestParse11(void) {
int result = 0;
DetectBytetestData *data = NULL;
data = DetectBytetestParse("4,!^,5,0,little,string,relative,hex");
data = DetectBytetestParse("4,!^,5,0,little,string,relative,hex", NULL, NULL);
if (data != NULL) {
if ( (data->op == DETECT_BYTETEST_OP_OR)
&& (data->nbytes == 4)
@ -961,7 +1018,7 @@ int DetectBytetestTestParse11(void) {
int DetectBytetestTestParse12(void) {
int result = 0;
DetectBytetestData *data = NULL;
data = DetectBytetestParse("4, =, 1, 0, hex");
data = DetectBytetestParse("4, =, 1, 0, hex", NULL, NULL);
if (data == NULL) {
result = 1;
}
@ -975,7 +1032,7 @@ int DetectBytetestTestParse12(void) {
int DetectBytetestTestParse13(void) {
int result = 0;
DetectBytetestData *data = NULL;
data = DetectBytetestParse("9, =, 1, 0");
data = DetectBytetestParse("9, =, 1, 0", NULL, NULL);
if (data == NULL) {
result = 1;
}
@ -989,7 +1046,7 @@ int DetectBytetestTestParse13(void) {
int DetectBytetestTestParse14(void) {
int result = 0;
DetectBytetestData *data = NULL;
data = DetectBytetestParse("23,=,0xffffffffffffffffULL,0,string,oct");
data = DetectBytetestParse("23,=,0xffffffffffffffffULL,0,string,oct", NULL, NULL);
if (data != NULL) {
if ( (data->op == DETECT_BYTETEST_OP_EQ)
&& (data->nbytes == 23)
@ -1012,7 +1069,7 @@ int DetectBytetestTestParse14(void) {
int DetectBytetestTestParse15(void) {
int result = 0;
DetectBytetestData *data = NULL;
data = DetectBytetestParse("24, =, 0xffffffffffffffffULL, 0, string");
data = DetectBytetestParse("24, =, 0xffffffffffffffffULL, 0, string", NULL, NULL);
if (data == NULL) {
result = 1;
}
@ -1026,7 +1083,7 @@ int DetectBytetestTestParse15(void) {
int DetectBytetestTestParse16(void) {
int result = 0;
DetectBytetestData *data = NULL;
data = DetectBytetestParse("4,=,0,0xffffffffffffffffULL");
data = DetectBytetestParse("4,=,0,0xffffffffffffffffULL", NULL, NULL);
if (data == NULL) {
result = 1;
}
@ -1040,7 +1097,7 @@ int DetectBytetestTestParse16(void) {
int DetectBytetestTestParse17(void) {
int result = 0;
DetectBytetestData *data = NULL;
data = DetectBytetestParse("4, <, 5, 0, dce");
data = DetectBytetestParse("4, <, 5, 0, dce", NULL, NULL);
if (data != NULL) {
if ( (data->op == DETECT_BYTETEST_OP_LT) &&
(data->nbytes == 4) &&
@ -1061,7 +1118,7 @@ int DetectBytetestTestParse17(void) {
int DetectBytetestTestParse18(void) {
int result = 0;
DetectBytetestData *data = NULL;
data = DetectBytetestParse("4, <, 5, 0");
data = DetectBytetestParse("4, <, 5, 0", NULL, NULL);
if (data != NULL) {
if ( (data->op == DETECT_BYTETEST_OP_LT) &&
(data->nbytes == 4) &&

@ -46,6 +46,8 @@
#define DETECT_BYTETEST_STRING 0x08 /**< "string" value */
#define DETECT_BYTETEST_RELATIVE 0x10 /**< "relative" offset */
#define DETECT_BYTETEST_DCE 0x20 /**< dce enabled */
#define DETECT_BYTETEST_VALUE_BE 0x40 /**< byte extract value enabled */
#define DETECT_BYTETEST_OFFSET_BE 0x80 /**< byte extract value enabled */
typedef struct DetectBytetestData_ {
uint8_t nbytes; /**< Number of bytes to compare */
@ -93,11 +95,16 @@ void DetectBytetestFree(void *ptr);
* flags: "big", "little", "relative", "string", "oct", "dec", "hex"
*
* \param optstr Pointer to the user provided byte_test options
* \param value Used to pass the value back, if byte_test uses a byte_extract
* var.
* \param offset Used to pass the offset back, if byte_test uses a byte_extract
* var.
*
* \retval data pointer to DetectBytetestData on success
* \retval NULL on failure
*/
DetectBytetestData *DetectBytetestParse(char *optstr);
DetectBytetestData *DetectBytetestParse(char *optstr, char **value,
char **offset);
/**
* This function is used to match byte_test
@ -115,7 +122,7 @@ DetectBytetestData *DetectBytetestParse(char *optstr);
*/
int DetectBytetestMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
Packet *p, Signature *s, SigMatch *m);
int DetectBytetestDoMatch(DetectEngineThreadCtx *, Signature *, SigMatch *, uint8_t *, uint32_t);
int DetectBytetestDoMatch(DetectEngineThreadCtx *, Signature *, SigMatch *, uint8_t *, uint32_t,
uint8_t, int32_t, uint64_t);
#endif /* __DETECT_BYTETEST_H__ */

@ -52,6 +52,12 @@
#define DETECT_CONTENT_HCD_MPM 0x00040000
#define DETECT_CONTENT_HRUD_MPM 0x00080000
/* BE - byte extract */
#define DETECT_CONTENT_OFFSET_BE 0x00100000
#define DETECT_CONTENT_DEPTH_BE 0x00200000
#define DETECT_CONTENT_DISTANCE_BE 0x00400000
#define DETECT_CONTENT_WITHIN_BE 0x00800000
#define DETECT_CONTENT_IS_SINGLE(c) (!((c)->flags & DETECT_CONTENT_DISTANCE || \
(c)->flags & DETECT_CONTENT_WITHIN || \
(c)->flags & DETECT_CONTENT_RELATIVE_NEXT || \

@ -32,6 +32,7 @@
#include "detect-parse.h"
#include "detect-content.h"
#include "detect-uricontent.h"
#include "detect-byte-extract.h"
#include "detect-parse.h"
#include "flow-var.h"
@ -134,14 +135,28 @@ static int DetectDepthSetup (DetectEngineCtx *de_ctx, Signature *s, char *depths
}
}
ud->depth = (uint32_t)atoi(str);
if (ud->depth < ud->content_len) {
ud->depth = ud->content_len;
SCLogDebug("depth increased to %"PRIu32" to match pattern len ",
ud->depth);
if (str[0] != '-' && isalpha(str[0])) {
SigMatch *bed_sm =
DetectByteExtractRetrieveSMVar(str, s,
SigMatchListSMBelongsTo(s, pm));
if (bed_sm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
"seen in depth - %s\n", str);
goto error;
}
ud->depth = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
ud->flags |= DETECT_CONTENT_DEPTH_BE;
} else {
ud->depth = (uint32_t)atoi(str);
if (ud->depth < ud->content_len) {
ud->depth = ud->content_len;
SCLogDebug("depth increased to %"PRIu32" to match pattern len ",
ud->depth);
}
/* Now update the real limit, as depth is relative to the offset */
ud->depth += ud->offset;
}
/* Now update the real limit, as depth is relative to the offset */
ud->depth += ud->offset;
ud->flags |= DETECT_CONTENT_DEPTH;
break;
@ -168,14 +183,28 @@ static int DetectDepthSetup (DetectEngineCtx *de_ctx, Signature *s, char *depths
}
}
cd->depth = (uint32_t)atoi(str);
if (cd->depth < cd->content_len) {
cd->depth = cd->content_len;
SCLogDebug("depth increased to %"PRIu32" to match pattern len ",
cd->depth);
if (str[0] != '-' && isalpha(str[0])) {
SigMatch *bed_sm =
DetectByteExtractRetrieveSMVar(str, s,
SigMatchListSMBelongsTo(s, pm));
if (bed_sm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
"seen in depth - %s\n", str);
goto error;
}
cd->depth = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
cd->flags |= DETECT_CONTENT_DEPTH_BE;
} else {
cd->depth = (uint32_t)atoi(str);
if (cd->depth < cd->content_len) {
cd->depth = cd->content_len;
SCLogDebug("depth increased to %"PRIu32" to match pattern len ",
cd->depth);
}
/* Now update the real limit, as depth is relative to the offset */
cd->depth += cd->offset;
}
/* Now update the real limit, as depth is relative to the offset */
cd->depth += cd->offset;
cd->flags |= DETECT_CONTENT_DEPTH;
break;
@ -196,14 +225,28 @@ static int DetectDepthSetup (DetectEngineCtx *de_ctx, Signature *s, char *depths
}
}
cd->depth = (uint32_t)atoi(str);
if (cd->depth < cd->content_len) {
cd->depth = cd->content_len;
SCLogDebug("depth increased to %"PRIu32" to match pattern len ",
cd->depth);
if (str[0] != '-' && isalpha(str[0])) {
SigMatch *bed_sm =
DetectByteExtractRetrieveSMVar(str, s,
SigMatchListSMBelongsTo(s, pm));
if (bed_sm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
"seen in depth - %s\n", str);
goto error;
}
cd->depth = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
cd->flags |= DETECT_CONTENT_DEPTH_BE;
} else {
cd->depth = (uint32_t)atoi(str);
if (cd->depth < cd->content_len) {
cd->depth = cd->content_len;
SCLogDebug("depth increased to %"PRIu32" to match pattern len ",
cd->depth);
}
/* Now update the real limit, as depth is relative to the offset */
cd->depth += cd->offset;
}
/* Now update the real limit, as depth is relative to the offset */
cd->depth += cd->offset;
cd->flags |= DETECT_CONTENT_DEPTH;
break;
@ -224,14 +267,28 @@ static int DetectDepthSetup (DetectEngineCtx *de_ctx, Signature *s, char *depths
}
}
cd->depth = (uint32_t)atoi(str);
if (cd->depth < cd->content_len) {
cd->depth = cd->content_len;
SCLogDebug("depth increased to %"PRIu32" to match pattern len ",
cd->depth);
if (str[0] != '-' && isalpha(str[0])) {
SigMatch *bed_sm =
DetectByteExtractRetrieveSMVar(str, s,
SigMatchListSMBelongsTo(s, pm));
if (bed_sm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
"seen in depth - %s\n", str);
goto error;
}
cd->depth = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
cd->flags |= DETECT_CONTENT_DEPTH_BE;
} else {
cd->depth = (uint32_t)atoi(str);
if (cd->depth < cd->content_len) {
cd->depth = cd->content_len;
SCLogDebug("depth increased to %"PRIu32" to match pattern len ",
cd->depth);
}
/* Now update the real limit, as depth is relative to the offset */
cd->depth += cd->offset;
}
/* Now update the real limit, as depth is relative to the offset */
cd->depth += cd->offset;
cd->flags |= DETECT_CONTENT_DEPTH;
break;
@ -252,14 +309,28 @@ static int DetectDepthSetup (DetectEngineCtx *de_ctx, Signature *s, char *depths
}
}
cd->depth = (uint32_t)atoi(str);
if (cd->depth < cd->content_len) {
cd->depth = cd->content_len;
SCLogDebug("depth increased to %"PRIu32" to match pattern len ",
cd->depth);
if (str[0] != '-' && isalpha(str[0])) {
SigMatch *bed_sm =
DetectByteExtractRetrieveSMVar(str, s,
SigMatchListSMBelongsTo(s, pm));
if (bed_sm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
"seen in depth - %s\n", str);
goto error;
}
cd->depth = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
cd->flags |= DETECT_CONTENT_DEPTH_BE;
} else {
cd->depth = (uint32_t)atoi(str);
if (cd->depth < cd->content_len) {
cd->depth = cd->content_len;
SCLogDebug("depth increased to %"PRIu32" to match pattern len ",
cd->depth);
}
/* Now update the real limit, as depth is relative to the offset */
cd->depth += cd->offset;
}
/* Now update the real limit, as depth is relative to the offset */
cd->depth += cd->offset;
cd->flags |= DETECT_CONTENT_DEPTH;
break;
@ -280,14 +351,28 @@ static int DetectDepthSetup (DetectEngineCtx *de_ctx, Signature *s, char *depths
}
}
cd->depth = (uint32_t)atoi(str);
if (cd->depth < cd->content_len) {
cd->depth = cd->content_len;
SCLogDebug("depth increased to %"PRIu32" to match pattern len ",
cd->depth);
if (str[0] != '-' && isalpha(str[0])) {
SigMatch *bed_sm =
DetectByteExtractRetrieveSMVar(str, s,
SigMatchListSMBelongsTo(s, pm));
if (bed_sm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
"seen in depth - %s\n", str);
goto error;
}
cd->depth = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
cd->flags |= DETECT_CONTENT_DEPTH_BE;
} else {
cd->depth = (uint32_t)atoi(str);
if (cd->depth < cd->content_len) {
cd->depth = cd->content_len;
SCLogDebug("depth increased to %"PRIu32" to match pattern len ",
cd->depth);
}
/* Now update the real limit, as depth is relative to the offset */
cd->depth += cd->offset;
}
/* Now update the real limit, as depth is relative to the offset */
cd->depth += cd->offset;
cd->flags |= DETECT_CONTENT_DEPTH;
break;
@ -308,14 +393,28 @@ static int DetectDepthSetup (DetectEngineCtx *de_ctx, Signature *s, char *depths
}
}
cd->depth = (uint32_t)atoi(str);
if (cd->depth < cd->content_len) {
cd->depth = cd->content_len;
SCLogDebug("depth increased to %"PRIu32" to match pattern len ",
cd->depth);
if (str[0] != '-' && isalpha(str[0])) {
SigMatch *bed_sm =
DetectByteExtractRetrieveSMVar(str, s,
SigMatchListSMBelongsTo(s, pm));
if (bed_sm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
"seen in depth - %s\n", str);
goto error;
}
cd->depth = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
cd->flags |= DETECT_CONTENT_DEPTH_BE;
} else {
cd->depth = (uint32_t)atoi(str);
if (cd->depth < cd->content_len) {
cd->depth = cd->content_len;
SCLogDebug("depth increased to %"PRIu32" to match pattern len ",
cd->depth);
}
/* Now update the real limit, as depth is relative to the offset */
cd->depth += cd->offset;
}
/* Now update the real limit, as depth is relative to the offset */
cd->depth += cd->offset;
cd->flags |= DETECT_CONTENT_DEPTH;
break;
@ -336,15 +435,28 @@ static int DetectDepthSetup (DetectEngineCtx *de_ctx, Signature *s, char *depths
}
}
cd->depth = (uint32_t)atoi(str);
if (cd->depth < cd->content_len) {
cd->depth = cd->content_len;
SCLogDebug("depth increased to %"PRIu32" to match pattern len ",
cd->depth);
if (str[0] != '-' && isalpha(str[0])) {
SigMatch *bed_sm =
DetectByteExtractRetrieveSMVar(str, s,
SigMatchListSMBelongsTo(s, pm));
if (bed_sm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
"seen in depth - %s\n", str);
goto error;
}
cd->depth = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
cd->flags |= DETECT_CONTENT_DEPTH_BE;
} else {
cd->depth = (uint32_t)atoi(str);
if (cd->depth < cd->content_len) {
cd->depth = cd->content_len;
SCLogDebug("depth increased to %"PRIu32" to match pattern len ",
cd->depth);
}
/* Now update the real limit, as depth is relative to the offset */
cd->depth += cd->offset;
cd->flags |= DETECT_CONTENT_DEPTH;
}
/* Now update the real limit, as depth is relative to the offset */
cd->depth += cd->offset;
cd->flags |= DETECT_CONTENT_DEPTH;
break;

@ -37,6 +37,7 @@
#include "detect-content.h"
#include "detect-uricontent.h"
#include "detect-pcre.h"
#include "detect-byte-extract.h"
#include "flow-var.h"
@ -215,10 +216,23 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s,
}
}
ud->distance = strtol(str, NULL, 10);
if (ud->flags & DETECT_CONTENT_WITHIN) {
if ((ud->distance + ud->content_len) > ud->within) {
ud->within = ud->distance + ud->content_len;
if (str[0] != '-' && isalpha(str[0])) {
SigMatch *bed_sm =
DetectByteExtractRetrieveSMVar(str, s,
SigMatchListSMBelongsTo(s, pm));
if (bed_sm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
"seen in distance - %s\n", str);
goto error;
}
ud->distance = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
ud->flags |= DETECT_CONTENT_DISTANCE_BE;
} else {
ud->distance = strtol(str, NULL, 10);
if (ud->flags & DETECT_CONTENT_WITHIN) {
if ((ud->distance + ud->content_len) > ud->within) {
ud->within = ud->distance + ud->content_len;
}
}
}
@ -303,14 +317,28 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s,
}
}
cd->distance = strtol(str, NULL, 10);
cd->flags |= DETECT_CONTENT_DISTANCE;
if (cd->flags & DETECT_CONTENT_WITHIN) {
if ((cd->distance + cd->content_len) > cd->within) {
cd->within = cd->distance + cd->content_len;
if (str[0] != '-' && isalpha(str[0])) {
SigMatch *bed_sm =
DetectByteExtractRetrieveSMVar(str, s,
SigMatchListSMBelongsTo(s, pm));
if (bed_sm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
"seen in distance - %s\n", str);
goto error;
}
cd->distance = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
cd->flags |= DETECT_CONTENT_DISTANCE_BE;
} else {
cd->distance = strtol(str, NULL, 10);
if (cd->flags & DETECT_CONTENT_WITHIN) {
if ((cd->distance + cd->content_len) > cd->within) {
cd->within = cd->distance + cd->content_len;
}
}
}
cd->flags |= DETECT_CONTENT_DISTANCE;
pm = SigMatchGetLastSMFromLists(s, 6,
DETECT_CONTENT, pm->prev,
DETECT_PCRE, pm->prev,
@ -377,10 +405,24 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s,
case DETECT_AL_HTTP_CLIENT_BODY:
cd = (DetectContentData *)pm->ctx;
cd->distance = strtol(str, NULL, 10);
if (cd->flags & DETECT_CONTENT_WITHIN) {
if ((cd->distance + cd->content_len) > cd->within) {
cd->within = cd->distance + cd->content_len;
if (str[0] != '-' && isalpha(str[0])) {
SigMatch *bed_sm =
DetectByteExtractRetrieveSMVar(str, s,
SigMatchListSMBelongsTo(s, pm));
if (bed_sm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
"seen in distance - %s\n", str);
goto error;
}
cd->distance = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
cd->flags |= DETECT_CONTENT_DISTANCE_BE;
} else {
cd->distance = strtol(str, NULL, 10);
if (cd->flags & DETECT_CONTENT_WITHIN) {
if ((cd->distance + cd->content_len) > cd->within) {
cd->within = cd->distance + cd->content_len;
}
}
}
@ -444,12 +486,26 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s,
}
}
cd->distance = strtol(str, NULL, 10);
if (cd->flags & DETECT_CONTENT_WITHIN) {
if ((cd->distance + cd->content_len) > cd->within) {
cd->within = cd->distance + cd->content_len;
if (str[0] != '-' && isalpha(str[0])) {
SigMatch *bed_sm =
DetectByteExtractRetrieveSMVar(str, s,
SigMatchListSMBelongsTo(s, pm));
if (bed_sm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
"seen in distance - %s\n", str);
goto error;
}
cd->distance = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
cd->flags |= DETECT_CONTENT_DISTANCE_BE;
} else {
cd->distance = strtol(str, NULL, 10);
if (cd->flags & DETECT_CONTENT_WITHIN) {
if ((cd->distance + cd->content_len) > cd->within) {
cd->within = cd->distance + cd->content_len;
}
}
}
cd->flags |= DETECT_CONTENT_DISTANCE;
/* reassigning pm */
@ -496,12 +552,26 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s,
}
}
cd->distance = strtol(str, NULL, 10);
if (cd->flags & DETECT_CONTENT_WITHIN) {
if ((cd->distance + cd->content_len) > cd->within) {
cd->within = cd->distance + cd->content_len;
if (str[0] != '-' && isalpha(str[0])) {
SigMatch *bed_sm =
DetectByteExtractRetrieveSMVar(str, s,
SigMatchListSMBelongsTo(s, pm));
if (bed_sm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
"seen in distance - %s\n", str);
goto error;
}
cd->distance = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
cd->flags |= DETECT_CONTENT_DISTANCE_BE;
} else {
cd->distance = strtol(str, NULL, 10);
if (cd->flags & DETECT_CONTENT_WITHIN) {
if ((cd->distance + cd->content_len) > cd->within) {
cd->within = cd->distance + cd->content_len;
}
}
}
cd->flags |= DETECT_CONTENT_DISTANCE;
/* reassigning pm */
@ -549,12 +619,26 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s,
}
}
cd->distance = strtol(str, NULL, 10);
if (cd->flags & DETECT_CONTENT_WITHIN) {
if ((cd->distance + cd->content_len) > cd->within) {
cd->within = cd->distance + cd->content_len;
if (str[0] != '-' && isalpha(str[0])) {
SigMatch *bed_sm =
DetectByteExtractRetrieveSMVar(str, s,
SigMatchListSMBelongsTo(s, pm));
if (bed_sm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
"seen in distance - %s\n", str);
goto error;
}
cd->distance = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
cd->flags |= DETECT_CONTENT_DISTANCE_BE;
} else {
cd->distance = strtol(str, NULL, 10);
if (cd->flags & DETECT_CONTENT_WITHIN) {
if ((cd->distance + cd->content_len) > cd->within) {
cd->within = cd->distance + cd->content_len;
}
}
}
cd->flags |= DETECT_CONTENT_DISTANCE;
/* reassigning pm */
@ -602,12 +686,26 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s,
}
}
cd->distance = strtol(str, NULL, 10);
if (cd->flags & DETECT_CONTENT_WITHIN) {
if ((cd->distance + cd->content_len) > cd->within) {
cd->within = cd->distance + cd->content_len;
if (str[0] != '-' && isalpha(str[0])) {
SigMatch *bed_sm =
DetectByteExtractRetrieveSMVar(str, s,
SigMatchListSMBelongsTo(s, pm));
if (bed_sm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
"seen in distance - %s\n", str);
goto error;
}
cd->distance = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
cd->flags |= DETECT_CONTENT_DISTANCE_BE;
} else {
cd->distance = strtol(str, NULL, 10);
if (cd->flags & DETECT_CONTENT_WITHIN) {
if ((cd->distance + cd->content_len) > cd->within) {
cd->within = cd->distance + cd->content_len;
}
}
}
cd->flags |= DETECT_CONTENT_DISTANCE;
/* reassigning pm */
@ -655,12 +753,26 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s,
}
}
cd->distance = strtol(str, NULL, 10);
if (cd->flags & DETECT_CONTENT_WITHIN) {
if ((cd->distance + cd->content_len) > cd->within) {
cd->within = cd->distance + cd->content_len;
if (str[0] != '-' && isalpha(str[0])) {
SigMatch *bed_sm =
DetectByteExtractRetrieveSMVar(str, s,
SigMatchListSMBelongsTo(s, pm));
if (bed_sm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
"seen in distance - %s\n", str);
goto error;
}
cd->distance = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
cd->flags |= DETECT_CONTENT_DISTANCE_BE;
} else {
cd->distance = strtol(str, NULL, 10);
if (cd->flags & DETECT_CONTENT_WITHIN) {
if ((cd->distance + cd->content_len) > cd->within) {
cd->within = cd->distance + cd->content_len;
}
}
}
cd->flags |= DETECT_CONTENT_DISTANCE;
/* reassigning pm */

@ -34,6 +34,7 @@
#include "detect-isdataat.h"
#include "detect-bytetest.h"
#include "detect-bytejump.h"
#include "detect-byte-extract.h"
#include "util-spm.h"
#include "util-spm-bm.h"
@ -124,50 +125,77 @@ static int DoInspectDcePayload(DetectEngineCtx *de_ctx,
offset = prev_payload_offset;
depth = stub_len;
int distance = cd->distance;
if (cd->flags & DETECT_CONTENT_DISTANCE) {
if (cd->distance < 0 && (uint32_t)(abs(cd->distance)) > offset) {
offset = 0;
} else {
offset += cd->distance;
if (cd->flags & DETECT_CONTENT_DISTANCE_BE) {
distance = det_ctx->bj_values[cd->distance];
}
if (distance < 0 && (uint32_t)(abs(distance)) > offset)
offset = 0;
else
offset += distance;
SCLogDebug("cd->distance %"PRIi32", offset %"PRIu32", depth %"PRIu32,
cd->distance, offset, depth);
}
if (cd->flags & DETECT_CONTENT_WITHIN) {
if ((int32_t)depth > (int32_t)(prev_payload_offset + cd->within + cd->distance)) {
depth = prev_payload_offset + cd->within + cd->distance;
}
if (cd->flags & DETECT_CONTENT_WITHIN_BE) {
if ((int32_t)depth > (int32_t)(prev_payload_offset + det_ctx->bj_values[cd->within] + distance)) {
depth = prev_payload_offset + det_ctx->bj_values[cd->within] + distance;
}
} else {
if ((int32_t)depth > (int32_t)(prev_payload_offset + cd->within + distance)) {
depth = prev_payload_offset + cd->within + distance;
}
SCLogDebug("cd->within %"PRIi32", prev_payload_offset "
"%"PRIu32", depth %"PRIu32, cd->within,
prev_payload_offset, depth);
SCLogDebug("cd->within %"PRIi32", prev_payload_offset "
"%"PRIu32", depth %"PRIu32, cd->within,
prev_payload_offset, depth);
}
}
if (cd->depth != 0) {
if ((cd->depth + prev_payload_offset) < depth) {
depth = prev_payload_offset + cd->depth;
}
if (cd->flags & DETECT_CONTENT_DEPTH_BE) {
if ((det_ctx->bj_values[cd->depth] + prev_payload_offset) < depth) {
depth = prev_payload_offset + det_ctx->bj_values[cd->depth];
}
} else {
if (cd->depth != 0) {
if ((cd->depth + prev_payload_offset) < depth) {
depth = prev_payload_offset + cd->depth;
}
SCLogDebug("cd->depth %"PRIu32", depth %"PRIu32,
cd->depth, depth);
SCLogDebug("cd->depth %"PRIu32", depth %"PRIu32,
cd->depth, depth);
}
}
if (cd->offset > offset) {
offset = cd->offset;
SCLogDebug("setting offset %"PRIu32, offset);
if (cd->flags & DETECT_CONTENT_OFFSET_BE) {
if (det_ctx->bj_values[cd->offset] > offset)
offset = det_ctx->bj_values[cd->offset];
} else {
if (cd->offset > offset) {
offset = cd->offset;
SCLogDebug("setting offset %"PRIu32, offset);
}
}
/* implied no relative matches */
} else {
/* set depth */
if (cd->depth != 0) {
depth = cd->depth;
if (cd->flags & DETECT_CONTENT_DEPTH_BE) {
depth = det_ctx->bj_values[cd->depth];
} else {
if (cd->depth != 0) {
depth = cd->depth;
}
}
/* set offset */
offset = cd->offset;
if (cd->flags & DETECT_CONTENT_OFFSET_BE)
offset = det_ctx->bj_values[cd->offset];
else
offset = cd->offset;
prev_payload_offset = 0;
}
@ -340,47 +368,76 @@ static int DoInspectDcePayload(DetectEngineCtx *de_ctx,
case DETECT_BYTETEST:
{
DetectBytetestData *data = (DetectBytetestData *)sm->ctx;
uint32_t temp_flags = data->flags;
uint8_t flags = data->flags;
int32_t offset = data->offset;;
uint64_t value = data->value;
if (flags & DETECT_BYTETEST_OFFSET_BE) {
offset = det_ctx->bj_values[offset];
}
if (flags & DETECT_BYTETEST_VALUE_BE) {
value = det_ctx->bj_values[value];
}
/* if we have dce enabled we will have to use the endianness
* specified by the dce header */
if (data->flags & DETECT_BYTETEST_DCE) {
if (flags & DETECT_BYTETEST_DCE) {
/* enable the endianness flag temporarily. once we are done
* processing we reset the flags to the original value*/
data->flags |= ((dcerpc_state->dcerpc.dcerpchdr.packed_drep[0] == 0x10) ?
DETECT_BYTETEST_LITTLE: 0);
flags |= ((dcerpc_state->dcerpc.dcerpchdr.packed_drep[0] == 0x10) ?
DETECT_BYTETEST_LITTLE: 0);
}
if (DetectBytetestDoMatch(det_ctx, s, sm, stub, stub_len) != 1) {
if (DetectBytetestDoMatch(det_ctx, s, sm, stub, stub_len, flags, offset, value) != 1) {
SCReturnInt(0);
}
/* reset the flags */
data->flags = temp_flags;
goto match;
}
case DETECT_BYTEJUMP:
{
DetectBytejumpData *data = (DetectBytejumpData *)sm->ctx;
uint32_t temp_flags = data->flags;
uint8_t flags = data->flags;
int32_t offset = data->offset;;
if (flags & DETECT_BYTEJUMP_OFFSET_BE) {
offset = det_ctx->bj_values[offset];
}
/* if we have dce enabled we will have to use the endianness
* specified by the dce header */
if (data->flags & DETECT_BYTEJUMP_DCE) {
if (flags & DETECT_BYTEJUMP_DCE) {
/* enable the endianness flag temporarily. once we are done
* processing we reset the flags to the original value*/
data->flags |= ((dcerpc_state->dcerpc.dcerpchdr.packed_drep[0] == 0x10) ?
DETECT_BYTEJUMP_LITTLE : 0);
flags |= ((dcerpc_state->dcerpc.dcerpchdr.packed_drep[0] == 0x10) ?
DETECT_BYTEJUMP_LITTLE : 0);
}
if (DetectBytejumpDoMatch(det_ctx, s, sm, stub, stub_len) != 1) {
if (DetectBytejumpDoMatch(det_ctx, s, sm, stub, stub_len, flags, offset) != 1) {
SCReturnInt(0);
}
/* reset the flags */
data->flags = temp_flags;
goto match;
}
case DETECT_BYTE_EXTRACT:
{
DetectByteExtractData *bed = (DetectByteExtractData *)sm->ctx;
uint8_t endian = bed->endian;
/* if we have dce enabled we will have to use the endianness
* specified by the dce header */
if (bed->flags & DETECT_BYTE_EXTRACT_FLAG_ENDIAN &&
endian == DETECT_BYTE_EXTRACT_ENDIAN_DCE) {
/* enable the endianness flag temporarily. once we are done
* processing we reset the flags to the original value*/
endian |= ((dcerpc_state->dcerpc.dcerpchdr.packed_drep[0] == 0x10) ?
DETECT_BYTE_EXTRACT_ENDIAN_LITTLE : DETECT_BYTE_EXTRACT_ENDIAN_BIG);
}
if (DetectByteExtractDoMatch(det_ctx, sm, s, stub, stub_len,
&det_ctx->bj_values[bed->local_id], endian) != 1) {
SCReturnInt(0);
}
goto match;
}

@ -36,6 +36,7 @@
#include "detect-isdataat.h"
#include "detect-bytetest.h"
#include "detect-bytejump.h"
#include "detect-byte-extract.h"
#include "util-spm.h"
#include "util-spm-bm.h"
@ -131,45 +132,73 @@ static int DoInspectPacketPayload(DetectEngineCtx *de_ctx,
offset = prev_payload_offset;
depth = payload_len;
int distance = cd->distance;
if (cd->flags & DETECT_CONTENT_DISTANCE) {
if (cd->distance < 0 && (uint32_t)(abs(cd->distance)) > offset)
if (cd->flags & DETECT_CONTENT_DISTANCE_BE) {
distance = det_ctx->bj_values[cd->distance];
}
if (distance < 0 && (uint32_t)(abs(distance)) > offset)
offset = 0;
else
offset += cd->distance;
offset += distance;
SCLogDebug("cd->distance %"PRIi32", offset %"PRIu32", depth %"PRIu32,
cd->distance, offset, depth);
distance, offset, depth);
}
if (cd->flags & DETECT_CONTENT_WITHIN) {
if ((int32_t)depth > (int32_t)(prev_payload_offset + cd->within + cd->distance)) {
depth = prev_payload_offset + cd->within + cd->distance;
if (cd->flags & DETECT_CONTENT_WITHIN_BE) {
if ((int32_t)depth > (int32_t)(prev_payload_offset + det_ctx->bj_values[cd->within] + distance)) {
depth = prev_payload_offset + det_ctx->bj_values[cd->within] + distance;
}
} else {
if ((int32_t)depth > (int32_t)(prev_payload_offset + cd->within + distance)) {
depth = prev_payload_offset + cd->within + distance;
}
SCLogDebug("cd->within %"PRIi32", det_ctx->payload_offset %"PRIu32", depth %"PRIu32,
cd->within, prev_payload_offset, depth);
}
SCLogDebug("cd->within %"PRIi32", det_ctx->payload_offset %"PRIu32", depth %"PRIu32,
cd->within, prev_payload_offset, depth);
}
if (cd->depth != 0) {
if ((cd->depth + prev_payload_offset) < depth) {
depth = prev_payload_offset + cd->depth;
if (cd->flags & DETECT_CONTENT_DEPTH_BE) {
if ((det_ctx->bj_values[cd->depth] + prev_payload_offset) < depth) {
depth = prev_payload_offset + det_ctx->bj_values[cd->depth];
}
} else {
if (cd->depth != 0) {
if ((cd->depth + prev_payload_offset) < depth) {
depth = prev_payload_offset + cd->depth;
}
SCLogDebug("cd->depth %"PRIu32", depth %"PRIu32, cd->depth, depth);
SCLogDebug("cd->depth %"PRIu32", depth %"PRIu32, cd->depth, depth);
}
}
if (cd->offset > offset) {
offset = cd->offset;
SCLogDebug("setting offset %"PRIu32, offset);
if (cd->flags & DETECT_CONTENT_OFFSET_BE) {
if (det_ctx->bj_values[cd->offset] > offset)
offset = det_ctx->bj_values[cd->offset];
} else {
if (cd->offset > offset) {
offset = cd->offset;
SCLogDebug("setting offset %"PRIu32, offset);
}
}
} else { /* implied no relative matches */
/* set depth */
if (cd->depth != 0) {
depth = cd->depth;
if (cd->flags & DETECT_CONTENT_DEPTH_BE) {
depth = det_ctx->bj_values[cd->depth];
} else {
if (cd->depth != 0) {
depth = cd->depth;
}
}
/* set offset */
offset = cd->offset;
if (cd->flags & DETECT_CONTENT_OFFSET_BE)
offset = det_ctx->bj_values[cd->offset];
else
offset = cd->offset;
prev_payload_offset = 0;
}
@ -339,7 +368,18 @@ static int DoInspectPacketPayload(DetectEngineCtx *de_ctx,
}
case DETECT_BYTETEST:
{
if (DetectBytetestDoMatch(det_ctx,s,sm,payload,payload_len) != 1) {
DetectBytetestData *btd = (DetectBytetestData *)sm->ctx;
int32_t offset = btd->offset;
uint64_t value = btd->value;
if (btd->flags & DETECT_BYTETEST_OFFSET_BE) {
offset = det_ctx->bj_values[offset];
}
if (btd->flags & DETECT_BYTETEST_VALUE_BE) {
value = det_ctx->bj_values[value];
}
if (DetectBytetestDoMatch(det_ctx,s,sm,payload,payload_len, btd->flags,
offset, value) != 1) {
SCReturnInt(0);
}
@ -347,7 +387,28 @@ static int DoInspectPacketPayload(DetectEngineCtx *de_ctx,
}
case DETECT_BYTEJUMP:
{
if (DetectBytejumpDoMatch(det_ctx,s,sm,payload,payload_len) != 1) {
DetectBytejumpData *bjd = (DetectBytejumpData *)sm->ctx;
int32_t offset = bjd->offset;
if (bjd->flags & DETECT_BYTEJUMP_OFFSET_BE) {
offset = det_ctx->bj_values[offset];
}
if (DetectBytejumpDoMatch(det_ctx,s,sm,payload,payload_len,
bjd->flags, offset) != 1) {
SCReturnInt(0);
}
goto match;
}
case DETECT_BYTE_EXTRACT:
{
DetectByteExtractData *bed = (DetectByteExtractData *)sm->ctx;
if (DetectByteExtractDoMatch(det_ctx, sm, s, payload,
payload_len,
&det_ctx->bj_values[bed->local_id],
bed->endian) != 1) {
SCReturnInt(0);
}
@ -940,6 +1001,211 @@ end:
return result;
}
static int PayloadTestSig18(void)
{
uint8_t buf[] = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x35, /* the last byte is 2 */
0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
0x0E, 0x0F,
};
uint16_t buflen = sizeof(buf);
Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP);
int result = 0;
char sig[] = "alert tcp any any -> any any (msg:\"dummy\"; "
"content:|01 02 03 04|; "
"byte_extract:1,2,one,string,dec,relative; "
"content:|0C 0D 0E 0F|; distance:one; sid:1;)";
if (UTHPacketMatchSigMpm(p, sig, MPM_AC) == 0) {
result = 0;
goto end;
}
result = 1;
end:
if (p != NULL)
UTHFreePacket(p);
return result;
}
static int PayloadTestSig19(void)
{
uint8_t buf[] = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x35, /* the last byte is 2 */
0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
0x0E, 0x0F,
};
uint16_t buflen = sizeof(buf);
Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP);
int result = 0;
char sig[] = "alert tcp any any -> any any (msg:\"dummy\"; "
"content:|01 02 03 04|; "
"byte_extract:1,2,one,string,hex,relative; "
"content:|0C 0D 0E 0F|; distance:one; sid:1;)";
if (UTHPacketMatchSigMpm(p, sig, MPM_AC) == 0) {
result = 0;
goto end;
}
result = 1;
end:
if (p != NULL)
UTHFreePacket(p);
return result;
}
static int PayloadTestSig20(void)
{
uint8_t buf[] = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x35, /* the last byte is 2 */
0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
0x0E, 0x0F,
};
uint16_t buflen = sizeof(buf);
Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP);
int result = 0;
char sig[] = "alert tcp any any -> any any (msg:\"dummy\"; "
"content:|01 02 03 04|; "
"byte_extract:1,2,one,string,dec,relative; "
"content:|06 35 07 08|; offset:one; sid:1;)";
if (UTHPacketMatchSigMpm(p, sig, MPM_AC) == 0) {
result = 0;
goto end;
}
result = 1;
end:
if (p != NULL)
UTHFreePacket(p);
return result;
}
static int PayloadTestSig21(void)
{
uint8_t buf[] = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x36, /* the last byte is 2 */
0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
0x0E, 0x0F,
};
uint16_t buflen = sizeof(buf);
Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP);
int result = 0;
char sig[] = "alert tcp any any -> any any (msg:\"dummy\"; "
"content:|01 02 03 04|; "
"byte_extract:1,2,one,string,dec,relative; "
"content:|03 04 05 06|; depth:one; sid:1;)";
if (UTHPacketMatchSigMpm(p, sig, MPM_AC) == 0) {
result = 0;
goto end;
}
result = 1;
end:
if (p != NULL)
UTHFreePacket(p);
return result;
}
static int PayloadTestSig22(void)
{
uint8_t buf[] = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x36, /* the last byte is 2 */
0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
0x0E, 0x0F,
};
uint16_t buflen = sizeof(buf);
Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP);
int result = 0;
char sig[] = "alert tcp any any -> any any (msg:\"dummy\"; "
"content:|01 02 03 04|; "
"byte_extract:1,2,one,string,dec,relative; "
"content:|09 0A 0B 0C|; within:one; sid:1;)";
if (UTHPacketMatchSigMpm(p, sig, MPM_AC) == 0) {
result = 0;
goto end;
}
result = 1;
end:
if (p != NULL)
UTHFreePacket(p);
return result;
}
static int PayloadTestSig23(void)
{
uint8_t buf[] = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x32, /* the last byte is 2 */
0x07, 0x08, 0x09, 0x33, 0x0B, 0x0C, 0x0D,
0x32, 0x0F,
};
uint16_t buflen = sizeof(buf);
Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP);
int result = 0;
char sig[] = "alert tcp any any -> any any (msg:\"dummy\"; "
"content:|01 02 03 04|; "
"byte_extract:1,2,one,string,dec,relative; "
"byte_extract:1,3,two,string,dec,relative; "
"byte_test:1,=,one,two,string,dec,relative; sid:1;)";
if (UTHPacketMatchSigMpm(p, sig, MPM_AC) == 0) {
result = 0;
goto end;
}
result = 1;
end:
if (p != NULL)
UTHFreePacket(p);
return result;
}
static int PayloadTestSig24(void)
{
uint8_t buf[] = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x32, /* the last byte is 2 */
0x07, 0x08, 0x33, 0x0A, 0x0B, 0x0C, 0x0D,
0x0E, 0x0F,
};
uint16_t buflen = sizeof(buf);
Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP);
int result = 0;
char sig[] = "alert tcp any any -> any any (msg:\"dummy\"; "
"content:|01 02 03 04|; "
"byte_extract:1,2,one,string,dec,relative; "
"byte_jump:1,one,string,dec,relative; "
"content:|0D 0E 0F|; distance:0; sid:1;)";
if (UTHPacketMatchSigMpm(p, sig, MPM_AC) == 0) {
result = 0;
goto end;
}
result = 1;
end:
if (p != NULL)
UTHFreePacket(p);
return result;
}
#endif /* UNITTESTS */
void PayloadRegisterTests(void) {
@ -961,6 +1227,14 @@ void PayloadRegisterTests(void) {
UtRegisterTest("PayloadTestSig15", PayloadTestSig15, 1);
UtRegisterTest("PayloadTestSig16", PayloadTestSig16, 1);
UtRegisterTest("PayloadTestSig17", PayloadTestSig17, 1);
UtRegisterTest("PayloadTestSig18", PayloadTestSig18, 1);
UtRegisterTest("PayloadTestSig19", PayloadTestSig19, 1);
UtRegisterTest("PayloadTestSig20", PayloadTestSig20, 1);
UtRegisterTest("PayloadTestSig21", PayloadTestSig21, 1);
UtRegisterTest("PayloadTestSig22", PayloadTestSig22, 1);
UtRegisterTest("PayloadTestSig23", PayloadTestSig23, 1);
UtRegisterTest("PayloadTestSig24", PayloadTestSig24, 1);
#endif /* UNITTESTS */
return;

@ -37,6 +37,7 @@
#include "detect-isdataat.h"
#include "detect-bytetest.h"
#include "detect-bytejump.h"
#include "detect-byte-extract.h"
#include "flow-util.h"
#include "util-spm.h"
@ -125,45 +126,73 @@ static int DoInspectPacketUri(DetectEngineCtx *de_ctx,
offset = prev_payload_offset;
depth = payload_len;
int distance = ud->distance;
if (ud->flags & DETECT_CONTENT_DISTANCE) {
if (ud->distance < 0 && (uint32_t)(abs(ud->distance)) > offset)
if (ud->flags & DETECT_CONTENT_DISTANCE_BE) {
distance = det_ctx->bj_values[ud->distance];
}
if (distance < 0 && (uint32_t)(abs(distance)) > offset)
offset = 0;
else
offset += ud->distance;
offset += distance;
SCLogDebug("ud->distance %"PRIi32", offset %"PRIu32", depth %"PRIu32,
ud->distance, offset, depth);
distance, offset, depth);
}
if (ud->flags & DETECT_CONTENT_WITHIN) {
if ((int32_t)depth > (int32_t)(prev_payload_offset + ud->within + ud->distance)) {
depth = prev_payload_offset + ud->within + ud->distance;
if (ud->flags & DETECT_CONTENT_WITHIN_BE) {
if ((int32_t)depth > (int32_t)(prev_payload_offset + det_ctx->bj_values[ud->within] + distance)) {
depth = prev_payload_offset + det_ctx->bj_values[ud->within] + distance;
}
} else {
if ((int32_t)depth > (int32_t)(prev_payload_offset + ud->within + distance)) {
depth = prev_payload_offset + ud->within + distance;
}
SCLogDebug("ud->within %"PRIi32", prev_payload_offset %"PRIu32", depth %"PRIu32,
ud->within, prev_payload_offset, depth);
}
SCLogDebug("ud->within %"PRIi32", prev_payload_offset %"PRIu32", depth %"PRIu32,
ud->within, prev_payload_offset, depth);
}
if (ud->depth != 0) {
if ((ud->depth + prev_payload_offset) < depth) {
depth = prev_payload_offset + ud->depth;
if (ud->flags & DETECT_CONTENT_DEPTH_BE) {
if ((det_ctx->bj_values[ud->depth] + prev_payload_offset) < depth) {
depth = prev_payload_offset + det_ctx->bj_values[ud->depth];
}
} else {
if (ud->depth != 0) {
if ((ud->depth + prev_payload_offset) < depth) {
depth = prev_payload_offset + ud->depth;
}
SCLogDebug("ud->depth %"PRIu32", depth %"PRIu32, ud->depth, depth);
SCLogDebug("ud->depth %"PRIu32", depth %"PRIu32, ud->depth, depth);
}
}
if (ud->offset > offset) {
offset = ud->offset;
SCLogDebug("setting offset %"PRIu32, offset);
if (ud->flags & DETECT_CONTENT_OFFSET_BE) {
if (det_ctx->bj_values[ud->offset] > offset)
offset = det_ctx->bj_values[ud->offset];
} else {
if (ud->offset > offset) {
offset = ud->offset;
SCLogDebug("setting offset %"PRIu32, offset);
}
}
} else { /* implied no relative matches */
/* set depth */
if (ud->depth != 0) {
depth = ud->depth;
if (ud->flags & DETECT_CONTENT_DEPTH_BE) {
depth = det_ctx->bj_values[ud->depth];
} else {
if (ud->depth != 0) {
depth = ud->depth;
}
}
/* set offset */
offset = ud->offset;
if (ud->flags & DETECT_CONTENT_OFFSET_BE)
offset = det_ctx->bj_values[ud->offset];
else
offset = ud->offset;
prev_payload_offset = 0;
}
@ -356,6 +385,16 @@ static int DoInspectPacketUri(DetectEngineCtx *de_ctx,
}
SCReturnInt(0);
} else if (sm->type == DETECT_BYTE_EXTRACT) {
DetectByteExtractData *bed = (DetectByteExtractData *)sm->ctx;
if (DetectByteExtractDoMatch(det_ctx, sm, s, payload,
payload_len,
&det_ctx->bj_values[bed->local_id],
bed->endian) != 1) {
SCReturnInt(0);
}
goto match;
} else {
/* we should never get here, but bail out just in case */
SCLogDebug("sm->type %u", sm->type);
@ -3294,6 +3333,481 @@ end:
return result;
}
static int UriTestSig28(void)
{
int result = 0;
uint8_t *http_buf = (uint8_t *)"POST /this_b5ig_string_now_in_http HTTP/1.0\r\n"
"User-Agent: Mozilla/1.0\r\n";
uint32_t http_buf_len = strlen((char *)http_buf);
Flow f;
TcpSession ssn;
HtpState *http_state = NULL;
Packet *p = NULL;
ThreadVars tv;
DetectEngineThreadCtx *det_ctx = NULL;
memset(&tv, 0, sizeof(ThreadVars));
memset(&f, 0, sizeof(Flow));
memset(&ssn, 0, sizeof(TcpSession));
p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.src.family = AF_INET;
f.dst.family = AF_INET;
p->flow = &f;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_ESTABLISHED;
f.alproto = ALPROTO_HTTP;
StreamTcpInitConfig(TRUE);
FlowL7DataPtrInit(&f);
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL) {
goto end;
}
de_ctx->mpm_matcher = MPM_B2G;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx,
"alert tcp any any -> any any (msg:\"dummy\"; "
"uricontent:this; "
"byte_extract:1,2,one,string,dec,relative; "
"uricontent:ring; distance:one; sid:1;)");
if (de_ctx->sig_list == NULL) {
goto end;
}
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
goto end;
}
http_state = f.aldata[AlpGetStateIdx(ALPROTO_HTTP)];
if (http_state == NULL) {
printf("no http state: ");
goto end;
}
/* do detect */
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
if (!PacketAlertCheck(p, 1)) {
printf("sig 1 didn't alert, but should have: ");
goto end;
}
result = 1;
end:
if (det_ctx != NULL)
DetectEngineThreadCtxDeinit(&tv, det_ctx);
if (de_ctx != NULL)
SigGroupCleanup(de_ctx);
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
StreamTcpFreeConfig(TRUE);
FLOW_DESTROY(&f);
UTHFreePacket(p);
return result;
}
static int UriTestSig29(void)
{
int result = 0;
uint8_t *http_buf = (uint8_t *)"POST /this_b5ig_string_now_in_http HTTP/1.0\r\n"
"User-Agent: Mozilla/1.0\r\n";
uint32_t http_buf_len = strlen((char *)http_buf);
Flow f;
TcpSession ssn;
HtpState *http_state = NULL;
Packet *p = NULL;
ThreadVars tv;
DetectEngineThreadCtx *det_ctx = NULL;
memset(&tv, 0, sizeof(ThreadVars));
memset(&f, 0, sizeof(Flow));
memset(&ssn, 0, sizeof(TcpSession));
p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.src.family = AF_INET;
f.dst.family = AF_INET;
p->flow = &f;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_ESTABLISHED;
f.alproto = ALPROTO_HTTP;
StreamTcpInitConfig(TRUE);
FlowL7DataPtrInit(&f);
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL) {
goto end;
}
de_ctx->mpm_matcher = MPM_B2G;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx,
"alert tcp any any -> any any (msg:\"dummy\"; "
"uricontent:this; "
"byte_extract:1,2,one,string,dec,relative; "
"uricontent:ring; distance:one; sid:1;)");
if (de_ctx->sig_list == NULL) {
goto end;
}
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
goto end;
}
http_state = f.aldata[AlpGetStateIdx(ALPROTO_HTTP)];
if (http_state == NULL) {
printf("no http state: ");
goto end;
}
/* do detect */
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
if (!PacketAlertCheck(p, 1)) {
printf("sig 1 didn't alert, but should have: ");
goto end;
}
result = 1;
end:
if (det_ctx != NULL)
DetectEngineThreadCtxDeinit(&tv, det_ctx);
if (de_ctx != NULL)
SigGroupCleanup(de_ctx);
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
StreamTcpFreeConfig(TRUE);
FLOW_DESTROY(&f);
UTHFreePacket(p);
return result;
}
static int UriTestSig30(void)
{
int result = 0;
uint8_t *http_buf = (uint8_t *)"POST /this_b5ig_string_now_in_http HTTP/1.0\r\n"
"User-Agent: Mozilla/1.0\r\n";
uint32_t http_buf_len = strlen((char *)http_buf);
Flow f;
TcpSession ssn;
HtpState *http_state = NULL;
Packet *p = NULL;
ThreadVars tv;
DetectEngineThreadCtx *det_ctx = NULL;
memset(&tv, 0, sizeof(ThreadVars));
memset(&f, 0, sizeof(Flow));
memset(&ssn, 0, sizeof(TcpSession));
p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.src.family = AF_INET;
f.dst.family = AF_INET;
p->flow = &f;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_ESTABLISHED;
f.alproto = ALPROTO_HTTP;
StreamTcpInitConfig(TRUE);
FlowL7DataPtrInit(&f);
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL) {
goto end;
}
de_ctx->mpm_matcher = MPM_B2G;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx,
"alert tcp any any -> any any (msg:\"dummy\"; "
"uricontent:this; "
"byte_extract:1,2,one,string,dec,relative; "
"uricontent:_b5ig; offset:one; sid:1;)");
if (de_ctx->sig_list == NULL) {
goto end;
}
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
goto end;
}
http_state = f.aldata[AlpGetStateIdx(ALPROTO_HTTP)];
if (http_state == NULL) {
printf("no http state: ");
goto end;
}
/* do detect */
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
if (!PacketAlertCheck(p, 1)) {
printf("sig 1 didn't alert, but should have: ");
goto end;
}
result = 1;
end:
if (det_ctx != NULL)
DetectEngineThreadCtxDeinit(&tv, det_ctx);
if (de_ctx != NULL)
SigGroupCleanup(de_ctx);
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
StreamTcpFreeConfig(TRUE);
FLOW_DESTROY(&f);
UTHFreePacket(p);
return result;
}
static int UriTestSig31(void)
{
int result = 0;
uint8_t *http_buf = (uint8_t *)"POST /this_b5ig_string_now_in_http HTTP/1.0\r\n"
"User-Agent: Mozilla/1.0\r\n";
uint32_t http_buf_len = strlen((char *)http_buf);
Flow f;
TcpSession ssn;
HtpState *http_state = NULL;
Packet *p = NULL;
ThreadVars tv;
DetectEngineThreadCtx *det_ctx = NULL;
memset(&tv, 0, sizeof(ThreadVars));
memset(&f, 0, sizeof(Flow));
memset(&ssn, 0, sizeof(TcpSession));
p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.src.family = AF_INET;
f.dst.family = AF_INET;
p->flow = &f;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_ESTABLISHED;
f.alproto = ALPROTO_HTTP;
StreamTcpInitConfig(TRUE);
FlowL7DataPtrInit(&f);
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL) {
goto end;
}
de_ctx->mpm_matcher = MPM_B2G;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx,
"alert tcp any any -> any any (msg:\"dummy\"; "
"uricontent:this; "
"byte_extract:1,2,one,string,dec,relative; "
"uricontent:his; depth:one; sid:1;)");
if (de_ctx->sig_list == NULL) {
goto end;
}
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
goto end;
}
http_state = f.aldata[AlpGetStateIdx(ALPROTO_HTTP)];
if (http_state == NULL) {
printf("no http state: ");
goto end;
}
/* do detect */
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
if (!PacketAlertCheck(p, 1)) {
printf("sig 1 didn't alert, but should have: ");
goto end;
}
result = 1;
end:
if (det_ctx != NULL)
DetectEngineThreadCtxDeinit(&tv, det_ctx);
if (de_ctx != NULL)
SigGroupCleanup(de_ctx);
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
StreamTcpFreeConfig(TRUE);
FLOW_DESTROY(&f);
UTHFreePacket(p);
return result;
}
static int UriTestSig32(void)
{
int result = 0;
uint8_t *http_buf = (uint8_t *)"POST /this_b5ig_string_now_in_http HTTP/1.0\r\n"
"User-Agent: Mozilla/1.0\r\n";
uint32_t http_buf_len = strlen((char *)http_buf);
Flow f;
TcpSession ssn;
HtpState *http_state = NULL;
Packet *p = NULL;
ThreadVars tv;
DetectEngineThreadCtx *det_ctx = NULL;
memset(&tv, 0, sizeof(ThreadVars));
memset(&f, 0, sizeof(Flow));
memset(&ssn, 0, sizeof(TcpSession));
p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.src.family = AF_INET;
f.dst.family = AF_INET;
p->flow = &f;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_ESTABLISHED;
f.alproto = ALPROTO_HTTP;
StreamTcpInitConfig(TRUE);
FlowL7DataPtrInit(&f);
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL) {
goto end;
}
de_ctx->mpm_matcher = MPM_B2G;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx,
"alert tcp any any -> any any (msg:\"dummy\"; "
"uricontent:this; "
"byte_extract:1,2,one,string,dec,relative; "
"uricontent:g_st; within:one; sid:1;)");
if (de_ctx->sig_list == NULL) {
goto end;
}
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
int r = AppLayerParse(&f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
goto end;
}
http_state = f.aldata[AlpGetStateIdx(ALPROTO_HTTP)];
if (http_state == NULL) {
printf("no http state: ");
goto end;
}
/* do detect */
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
if (!PacketAlertCheck(p, 1)) {
printf("sig 1 didn't alert, but should have: ");
goto end;
}
result = 1;
end:
if (det_ctx != NULL)
DetectEngineThreadCtxDeinit(&tv, det_ctx);
if (de_ctx != NULL)
SigGroupCleanup(de_ctx);
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
StreamTcpFreeConfig(TRUE);
FLOW_DESTROY(&f);
UTHFreePacket(p);
return result;
}
#endif /* UNITTESTS */
void UriRegisterTests(void)
@ -3327,6 +3841,12 @@ void UriRegisterTests(void)
UtRegisterTest("UriTestSig25", UriTestSig25, 1);
UtRegisterTest("UriTestSig26", UriTestSig26, 1);
UtRegisterTest("UriTestSig27", UriTestSig27, 1);
UtRegisterTest("UriTestSig28", UriTestSig28, 1);
UtRegisterTest("UriTestSig29", UriTestSig29, 1);
UtRegisterTest("UriTestSig30", UriTestSig30, 1);
UtRegisterTest("UriTestSig31", UriTestSig31, 1);
UtRegisterTest("UriTestSig32", UriTestSig32, 1);
#endif /* UNITTESTS */
return;

@ -41,6 +41,7 @@
#include "detect-engine.h"
#include "detect-byte-extract.h"
#include "detect-content.h"
#include "detect-uricontent.h"
#include "detect-engine-threshold.h"
@ -441,6 +442,11 @@ TmEcode DetectEngineThreadCtxInit(ThreadVars *tv, void *initdata, void **data) {
/* this detection engine context belongs to this thread instance */
det_ctx->tv = tv;
det_ctx->bj_values = SCMalloc(sizeof(*det_ctx->bj_values) * byte_extract_max_local_id);
if (det_ctx->bj_values == NULL) {
return TM_ECODE_FAILED;
}
*data = (void *)det_ctx;
return TM_ECODE_OK;
@ -469,6 +475,9 @@ TmEcode DetectEngineThreadCtxDeinit(ThreadVars *tv, void *data) {
if (det_ctx->de_state_sig_array != NULL)
SCFree(det_ctx->de_state_sig_array);
if (det_ctx->bj_values != NULL)
SCFree(det_ctx->bj_values);
SCFree(det_ctx);
return TM_ECODE_OK;

@ -32,6 +32,7 @@
#include "detect-parse.h"
#include "detect-content.h"
#include "detect-uricontent.h"
#include "detect-byte-extract.h"
#include "app-layer.h"
#include "flow-var.h"
@ -131,15 +132,28 @@ int DetectOffsetSetup (DetectEngineCtx *de_ctx, Signature *s, char *offsetstr)
}
}
ud->offset = (uint32_t)atoi(str);
if (ud->depth != 0) {
if (ud->depth < ud->content_len) {
SCLogDebug("depth increased to %"PRIu32" to match pattern len",
ud->content_len);
ud->depth = ud->content_len;
if (str[0] != '-' && isalpha(str[0])) {
SigMatch *bed_sm =
DetectByteExtractRetrieveSMVar(str, s,
SigMatchListSMBelongsTo(s, pm));
if (bed_sm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
"seen in offset - %s\n", str);
goto error;
}
ud->offset = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
ud->flags |= DETECT_CONTENT_OFFSET_BE;
} else {
ud->offset = (uint32_t)atoi(str);
if (ud->depth != 0) {
if (ud->depth < ud->content_len) {
SCLogDebug("depth increased to %"PRIu32" to match pattern len",
ud->content_len);
ud->depth = ud->content_len;
}
/* Updating the depth as is relative to the offset */
ud->depth += ud->offset;
}
/* Updating the depth as is relative to the offset */
ud->depth += ud->offset;
}
ud->flags |= DETECT_CONTENT_OFFSET;
@ -169,15 +183,28 @@ int DetectOffsetSetup (DetectEngineCtx *de_ctx, Signature *s, char *offsetstr)
}
}
cd->offset = (uint32_t)atoi(str);
if (cd->depth != 0) {
if (cd->depth < cd->content_len) {
SCLogDebug("depth increased to %"PRIu32" to match pattern len",
cd->content_len);
cd->depth = cd->content_len;
if (str[0] != '-' && isalpha(str[0])) {
SigMatch *bed_sm =
DetectByteExtractRetrieveSMVar(str, s,
SigMatchListSMBelongsTo(s, pm));
if (bed_sm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
"seen in offset - %s\n", str);
goto error;
}
cd->offset = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
cd->flags |= DETECT_CONTENT_OFFSET_BE;
} else {
cd->offset = (uint32_t)atoi(str);
if (cd->depth != 0) {
if (cd->depth < cd->content_len) {
SCLogDebug("depth increased to %"PRIu32" to match pattern len",
cd->content_len);
cd->depth = cd->content_len;
}
/* Updating the depth as is relative to the offset */
cd->depth += cd->offset;
}
/* Updating the depth as is relative to the offset */
cd->depth += cd->offset;
}
cd->flags |= DETECT_CONTENT_OFFSET;
@ -200,15 +227,28 @@ int DetectOffsetSetup (DetectEngineCtx *de_ctx, Signature *s, char *offsetstr)
}
}
cd->offset = (uint32_t)atoi(str);
if (cd->depth != 0) {
if (cd->depth < cd->content_len) {
SCLogDebug("depth increased to %"PRIu32" to match pattern len",
cd->content_len);
cd->depth = cd->content_len;
if (str[0] != '-' && isalpha(str[0])) {
SigMatch *bed_sm =
DetectByteExtractRetrieveSMVar(str, s,
SigMatchListSMBelongsTo(s, pm));
if (bed_sm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
"seen in offset - %s\n", str);
goto error;
}
cd->offset = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
cd->flags |= DETECT_CONTENT_OFFSET_BE;
} else {
cd->offset = (uint32_t)atoi(str);
if (cd->depth != 0) {
if (cd->depth < cd->content_len) {
SCLogDebug("depth increased to %"PRIu32" to match pattern len",
cd->content_len);
cd->depth = cd->content_len;
}
/* Updating the depth as is relative to the offset */
cd->depth += cd->offset;
}
/* Updating the depth as is relative to the offset */
cd->depth += cd->offset;
}
cd->flags |= DETECT_CONTENT_OFFSET;
@ -231,15 +271,28 @@ int DetectOffsetSetup (DetectEngineCtx *de_ctx, Signature *s, char *offsetstr)
}
}
cd->offset = (uint32_t)atoi(str);
if (cd->depth != 0) {
if (cd->depth < cd->content_len) {
SCLogDebug("depth increased to %"PRIu32" to match pattern len",
cd->content_len);
cd->depth = cd->content_len;
if (str[0] != '-' && isalpha(str[0])) {
SigMatch *bed_sm =
DetectByteExtractRetrieveSMVar(str, s,
SigMatchListSMBelongsTo(s, pm));
if (bed_sm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
"seen in offset - %s\n", str);
goto error;
}
cd->offset = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
cd->flags |= DETECT_CONTENT_OFFSET_BE;
} else {
cd->offset = (uint32_t)atoi(str);
if (cd->depth != 0) {
if (cd->depth < cd->content_len) {
SCLogDebug("depth increased to %"PRIu32" to match pattern len",
cd->content_len);
cd->depth = cd->content_len;
}
/* Updating the depth as is relative to the offset */
cd->depth += cd->offset;
}
/* Updating the depth as is relative to the offset */
cd->depth += cd->offset;
}
cd->flags |= DETECT_CONTENT_OFFSET;
@ -262,15 +315,28 @@ int DetectOffsetSetup (DetectEngineCtx *de_ctx, Signature *s, char *offsetstr)
}
}
cd->offset = (uint32_t)atoi(str);
if (cd->depth != 0) {
if (cd->depth < cd->content_len) {
SCLogDebug("depth increased to %"PRIu32" to match pattern len",
cd->content_len);
cd->depth = cd->content_len;
if (str[0] != '-' && isalpha(str[0])) {
SigMatch *bed_sm =
DetectByteExtractRetrieveSMVar(str, s,
SigMatchListSMBelongsTo(s, pm));
if (bed_sm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
"seen in offset - %s\n", str);
goto error;
}
cd->offset = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
cd->flags |= DETECT_CONTENT_OFFSET_BE;
} else {
cd->offset = (uint32_t)atoi(str);
if (cd->depth != 0) {
if (cd->depth < cd->content_len) {
SCLogDebug("depth increased to %"PRIu32" to match pattern len",
cd->content_len);
cd->depth = cd->content_len;
}
/* Updating the depth as is relative to the offset */
cd->depth += cd->offset;
}
/* Updating the depth as is relative to the offset */
cd->depth += cd->offset;
}
cd->flags |= DETECT_CONTENT_OFFSET;
@ -293,15 +359,28 @@ int DetectOffsetSetup (DetectEngineCtx *de_ctx, Signature *s, char *offsetstr)
}
}
cd->offset = (uint32_t)atoi(str);
if (cd->depth != 0) {
if (cd->depth < cd->content_len) {
SCLogDebug("depth increased to %"PRIu32" to match pattern len",
cd->content_len);
cd->depth = cd->content_len;
if (str[0] != '-' && isalpha(str[0])) {
SigMatch *bed_sm =
DetectByteExtractRetrieveSMVar(str, s,
SigMatchListSMBelongsTo(s, pm));
if (bed_sm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
"seen in offset - %s\n", str);
goto error;
}
cd->offset = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
cd->flags |= DETECT_CONTENT_OFFSET_BE;
} else {
cd->offset = (uint32_t)atoi(str);
if (cd->depth != 0) {
if (cd->depth < cd->content_len) {
SCLogDebug("depth increased to %"PRIu32" to match pattern len",
cd->content_len);
cd->depth = cd->content_len;
}
/* Updating the depth as is relative to the offset */
cd->depth += cd->offset;
}
/* Updating the depth as is relative to the offset */
cd->depth += cd->offset;
}
cd->flags |= DETECT_CONTENT_OFFSET;
@ -324,15 +403,28 @@ int DetectOffsetSetup (DetectEngineCtx *de_ctx, Signature *s, char *offsetstr)
}
}
cd->offset = (uint32_t)atoi(str);
if (cd->depth != 0) {
if (cd->depth < cd->content_len) {
SCLogDebug("depth increased to %"PRIu32" to match pattern len",
cd->content_len);
cd->depth = cd->content_len;
if (str[0] != '-' && isalpha(str[0])) {
SigMatch *bed_sm =
DetectByteExtractRetrieveSMVar(str, s,
SigMatchListSMBelongsTo(s, pm));
if (bed_sm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
"seen in offset - %s\n", str);
goto error;
}
cd->offset = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
cd->flags |= DETECT_CONTENT_OFFSET_BE;
} else {
cd->offset = (uint32_t)atoi(str);
if (cd->depth != 0) {
if (cd->depth < cd->content_len) {
SCLogDebug("depth increased to %"PRIu32" to match pattern len",
cd->content_len);
cd->depth = cd->content_len;
}
/* Updating the depth as is relative to the offset */
cd->depth += cd->offset;
}
/* Updating the depth as is relative to the offset */
cd->depth += cd->offset;
}
cd->flags |= DETECT_CONTENT_OFFSET;
@ -355,15 +447,28 @@ int DetectOffsetSetup (DetectEngineCtx *de_ctx, Signature *s, char *offsetstr)
}
}
cd->offset = (uint32_t)atoi(str);
if (cd->depth != 0) {
if (cd->depth < cd->content_len) {
SCLogDebug("depth increased to %"PRIu32" to match pattern len",
cd->content_len);
cd->depth = cd->content_len;
if (str[0] != '-' && isalpha(str[0])) {
SigMatch *bed_sm =
DetectByteExtractRetrieveSMVar(str, s,
SigMatchListSMBelongsTo(s, pm));
if (bed_sm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
"seen in offset - %s\n", str);
goto error;
}
cd->offset = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
cd->flags |= DETECT_CONTENT_OFFSET_BE;
} else {
cd->offset = (uint32_t)atoi(str);
if (cd->depth != 0) {
if (cd->depth < cd->content_len) {
SCLogDebug("depth increased to %"PRIu32" to match pattern len",
cd->content_len);
cd->depth = cd->content_len;
}
/* Updating the depth as is relative to the offset */
cd->depth += cd->offset;
}
/* Updating the depth as is relative to the offset */
cd->depth += cd->offset;
}
cd->flags |= DETECT_CONTENT_OFFSET;

@ -33,6 +33,7 @@
#include "detect-content.h"
#include "detect-uricontent.h"
#include "detect-bytejump.h"
#include "detect-byte-extract.h"
#include "app-layer.h"
#include "detect-parse.h"
@ -217,13 +218,26 @@ static int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, char *withi
}
}
ud->within = strtol(str, NULL, 10);
if (ud->within < (int32_t)ud->content_len) {
SCLogError(SC_ERR_WITHIN_INVALID, "within argument \"%"PRIi32"\" is "
"less than the content length \"%"PRIu32"\" which is invalid, since "
"this will never match. Invalidating signature", ud->within,
ud->content_len);
goto error;
if (str[0] != '-' && isalpha(str[0])) {
SigMatch *bed_sm =
DetectByteExtractRetrieveSMVar(str, s,
SigMatchListSMBelongsTo(s, pm));
if (bed_sm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
"seen in within - %s\n", str);
goto error;
}
ud->within = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
ud->flags |= DETECT_CONTENT_WITHIN_BE;
} else {
ud->within = strtol(str, NULL, 10);
if (ud->within < (int32_t)ud->content_len) {
SCLogError(SC_ERR_WITHIN_INVALID, "within argument \"%"PRIi32"\" is "
"less than the content length \"%"PRIu32"\" which is invalid, since "
"this will never match. Invalidating signature", ud->within,
ud->content_len);
goto error;
}
}
ud->flags |= DETECT_CONTENT_WITHIN;
@ -314,13 +328,26 @@ static int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, char *withi
}
}
cd->within = strtol(str, NULL, 10);
if (cd->within < (int32_t)cd->content_len) {
SCLogError(SC_ERR_WITHIN_INVALID, "within argument \"%"PRIi32"\" is "
"less than the content length \"%"PRIu32"\" which is invalid, since "
"this will never match. Invalidating signature", cd->within,
cd->content_len);
goto error;
if (str[0] != '-' && isalpha(str[0])) {
SigMatch *bed_sm =
DetectByteExtractRetrieveSMVar(str, s,
SigMatchListSMBelongsTo(s, pm));
if (bed_sm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
"seen in within - %s\n", str);
goto error;
}
cd->within = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
cd->flags |= DETECT_CONTENT_WITHIN_BE;
} else {
cd->within = strtol(str, NULL, 10);
if (cd->within < (int32_t)cd->content_len) {
SCLogError(SC_ERR_WITHIN_INVALID, "within argument \"%"PRIi32"\" is "
"less than the content length \"%"PRIu32"\" which is invalid, since "
"this will never match. Invalidating signature", cd->within,
cd->content_len);
goto error;
}
}
cd->flags |= DETECT_CONTENT_WITHIN;
@ -397,13 +424,27 @@ static int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, char *withi
case DETECT_AL_HTTP_CLIENT_BODY:
cd = (DetectContentData *)pm->ctx;
cd->within = strtol(str, NULL, 10);
if (cd->within < (int32_t)cd->content_len) {
SCLogError(SC_ERR_WITHIN_INVALID, "within argument \"%"PRIi32"\" is "
"less than the content length \"%"PRIu32"\" which is invalid, since "
"this will never match. Invalidating signature", cd->within,
cd->content_len);
goto error;
if (str[0] != '-' && isalpha(str[0])) {
SigMatch *bed_sm =
DetectByteExtractRetrieveSMVar(str, s,
SigMatchListSMBelongsTo(s, pm));
if (bed_sm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
"seen in within - %s\n", str);
goto error;
}
cd->within = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
cd->flags |= DETECT_CONTENT_WITHIN_BE;
} else {
cd->within = strtol(str, NULL, 10);
if (cd->within < (int32_t)cd->content_len) {
SCLogError(SC_ERR_WITHIN_INVALID, "within argument \"%"PRIi32"\" is "
"less than the content length \"%"PRIu32"\" which is invalid, since "
"this will never match. Invalidating signature", cd->within,
cd->content_len);
goto error;
}
}
if (cd->flags & DETECT_CONTENT_NEGATED) {
@ -466,14 +507,28 @@ static int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, char *withi
}
}
cd->within = strtol(str, NULL, 10);
if (cd->within < (int32_t)cd->content_len) {
SCLogError(SC_ERR_WITHIN_INVALID, "within argument \"%"PRIi32"\" is "
"less than the content length \"%"PRIu32"\" which is invalid, since "
"this will never match. Invalidating signature", cd->within,
cd->content_len);
goto error;
if (str[0] != '-' && isalpha(str[0])) {
SigMatch *bed_sm =
DetectByteExtractRetrieveSMVar(str, s,
SigMatchListSMBelongsTo(s, pm));
if (bed_sm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
"seen in within - %s\n", str);
goto error;
}
cd->within = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
cd->flags |= DETECT_CONTENT_WITHIN_BE;
} else {
cd->within = strtol(str, NULL, 10);
if (cd->within < (int32_t)cd->content_len) {
SCLogError(SC_ERR_WITHIN_INVALID, "within argument \"%"PRIi32"\" is "
"less than the content length \"%"PRIu32"\" which is invalid, since "
"this will never match. Invalidating signature", cd->within,
cd->content_len);
goto error;
}
}
cd->flags |= DETECT_CONTENT_WITHIN;
/* reassigning pm */
@ -520,14 +575,28 @@ static int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, char *withi
}
}
cd->within = strtol(str, NULL, 10);
if (cd->within < (int32_t)cd->content_len) {
SCLogError(SC_ERR_WITHIN_INVALID, "within argument \"%"PRIi32"\" is "
"less than the content length \"%"PRIu32"\" which is invalid, since "
"this will never match. Invalidating signature", cd->within,
cd->content_len);
goto error;
if (str[0] != '-' && isalpha(str[0])) {
SigMatch *bed_sm =
DetectByteExtractRetrieveSMVar(str, s,
SigMatchListSMBelongsTo(s, pm));
if (bed_sm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
"seen in within - %s\n", str);
goto error;
}
cd->within = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
cd->flags |= DETECT_CONTENT_WITHIN_BE;
} else {
cd->within = strtol(str, NULL, 10);
if (cd->within < (int32_t)cd->content_len) {
SCLogError(SC_ERR_WITHIN_INVALID, "within argument \"%"PRIi32"\" is "
"less than the content length \"%"PRIu32"\" which is invalid, since "
"this will never match. Invalidating signature", cd->within,
cd->content_len);
goto error;
}
}
cd->flags |= DETECT_CONTENT_WITHIN;
/* reassigning pm */
@ -574,14 +643,28 @@ static int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, char *withi
}
}
cd->within = strtol(str, NULL, 10);
if (cd->within < (int32_t)cd->content_len) {
SCLogError(SC_ERR_WITHIN_INVALID, "within argument \"%"PRIi32"\" is "
"less than the content length \"%"PRIu32"\" which is invalid, since "
"this will never match. Invalidating signature", cd->within,
cd->content_len);
goto error;
if (str[0] != '-' && isalpha(str[0])) {
SigMatch *bed_sm =
DetectByteExtractRetrieveSMVar(str, s,
SigMatchListSMBelongsTo(s, pm));
if (bed_sm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
"seen in within - %s\n", str);
goto error;
}
cd->within = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
cd->flags |= DETECT_CONTENT_WITHIN_BE;
} else {
cd->within = strtol(str, NULL, 10);
if (cd->within < (int32_t)cd->content_len) {
SCLogError(SC_ERR_WITHIN_INVALID, "within argument \"%"PRIi32"\" is "
"less than the content length \"%"PRIu32"\" which is invalid, since "
"this will never match. Invalidating signature", cd->within,
cd->content_len);
goto error;
}
}
cd->flags |= DETECT_CONTENT_WITHIN;
/* reassigning pm */
@ -628,14 +711,28 @@ static int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, char *withi
}
}
cd->within = strtol(str, NULL, 10);
if (cd->within < (int32_t)cd->content_len) {
SCLogError(SC_ERR_WITHIN_INVALID, "within argument \"%"PRIi32"\" is "
"less than the content length \"%"PRIu32"\" which is invalid, since "
"this will never match. Invalidating signature", cd->within,
cd->content_len);
goto error;
if (str[0] != '-' && isalpha(str[0])) {
SigMatch *bed_sm =
DetectByteExtractRetrieveSMVar(str, s,
SigMatchListSMBelongsTo(s, pm));
if (bed_sm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
"seen in within - %s\n", str);
goto error;
}
cd->within = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
cd->flags |= DETECT_CONTENT_WITHIN_BE;
} else {
cd->within = strtol(str, NULL, 10);
if (cd->within < (int32_t)cd->content_len) {
SCLogError(SC_ERR_WITHIN_INVALID, "within argument \"%"PRIi32"\" is "
"less than the content length \"%"PRIu32"\" which is invalid, since "
"this will never match. Invalidating signature", cd->within,
cd->content_len);
goto error;
}
}
cd->flags |= DETECT_CONTENT_WITHIN;
/* reassigning pm */
@ -682,14 +779,28 @@ static int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, char *withi
}
}
cd->within = strtol(str, NULL, 10);
if (cd->within < (int32_t)cd->content_len) {
SCLogError(SC_ERR_WITHIN_INVALID, "within argument \"%"PRIi32"\" is "
"less than the content length \"%"PRIu32"\" which is invalid, since "
"this will never match. Invalidating signature", cd->within,
cd->content_len);
goto error;
if (str[0] != '-' && isalpha(str[0])) {
SigMatch *bed_sm =
DetectByteExtractRetrieveSMVar(str, s,
SigMatchListSMBelongsTo(s, pm));
if (bed_sm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
"seen in within - %s\n", str);
goto error;
}
cd->within = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
cd->flags |= DETECT_CONTENT_WITHIN_BE;
} else {
cd->within = strtol(str, NULL, 10);
if (cd->within < (int32_t)cd->content_len) {
SCLogError(SC_ERR_WITHIN_INVALID, "within argument \"%"PRIi32"\" is "
"less than the content length \"%"PRIu32"\" which is invalid, since "
"this will never match. Invalidating signature", cd->within,
cd->content_len);
goto error;
}
}
cd->flags |= DETECT_CONTENT_WITHIN;
/* reassigning pm */

@ -122,6 +122,7 @@
#include "detect-engine-hmd.h"
#include "detect-engine-hcd.h"
#include "detect-engine-hrud.h"
#include "detect-byte-extract.h"
#include "util-rule-vars.h"
@ -4256,6 +4257,7 @@ void SigTableSetup(void) {
DetectSshSoftwareVersionRegister();
DetectHttpStatCodeRegister();
DetectSslVersionRegister();
DetectByteExtractRegister();
uint8_t i = 0;
for (i = 0; i < DETECT_TBLSIZE; i++) {

@ -787,6 +787,9 @@ typedef struct DetectionEngineThreadCtx_ {
/** ip only rules ctx */
DetectEngineIPOnlyThreadCtx io_ctx;
/* byte jump values */
uint64_t *bj_values;
DetectEngineCtx *de_ctx;
#ifdef __SC_CUDA_SUPPORT__
/* each detection thread would have it's own queue where the cuda dispatcher
@ -999,6 +1002,7 @@ enum {
DETECT_AL_SSH_SOFTWAREVERSION,
DETECT_AL_SSL_VERSION,
DETECT_AL_SSL_STATE,
DETECT_BYTE_EXTRACT,
DETECT_DCE_IFACE,
DETECT_DCE_OPNUM,

Loading…
Cancel
Save