From: Giuseppe Longo Date: Thu, 13 Jul 2017 22:22:13 +0000 (+0200) Subject: detect: set events in inspection phase X-Git-Tag: suricata-4.1.0-beta1~228 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=822faa08f8ef1365b6f1f9557cd27e93d5996403;p=thirdparty%2Fsuricata.git detect: set events in inspection phase During the inspection phase actually is not possible to catch an error if it occurs. This patch permits to store events in the detection engine such that we can match on events and catch them. --- diff --git a/src/detect-app-layer-event.c b/src/detect-app-layer-event.c index be2bb5aedc..107ee63ab2 100644 --- a/src/detect-app-layer-event.c +++ b/src/detect-app-layer-event.c @@ -194,8 +194,13 @@ static int DetectAppLayerEventParseAppP2(DetectAppLayerEventData *data, return -1; } - r = AppLayerParserGetEventInfo(ipproto, data->alproto, - p_idx + 1, &event_id, event_type); + if (!data->needs_detctx) { + r = AppLayerParserGetEventInfo(ipproto, data->alproto, + p_idx + 1, &event_id, event_type); + } else { + r = DetectEngineGetEventInfo(p_idx + 1, &event_id, event_type); + } + if (r < 0) { SCLogError(SC_ERR_INVALID_SIGNATURE, "app-layer-event keyword's " "protocol \"%s\" doesn't have event \"%s\" registered", @@ -214,6 +219,7 @@ static DetectAppLayerEventData *DetectAppLayerEventParseAppP1(const char *arg) AppProto alproto; const char *p_idx; char alproto_name[MAX_ALPROTO_NAME]; + int needs_detctx = FALSE; p_idx = strchr(arg, '.'); if (strlen(arg) > MAX_ALPROTO_NAME) { @@ -225,10 +231,14 @@ static DetectAppLayerEventData *DetectAppLayerEventParseAppP1(const char *arg) alproto = AppLayerGetProtoByName(alproto_name); if (alproto == ALPROTO_UNKNOWN) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "app-layer-event keyword " - "supplied with unknown protocol \"%s\"", - alproto_name); - return NULL; + if (!strcmp(alproto_name, "file")) { + needs_detctx = TRUE; + } else { + SCLogError(SC_ERR_INVALID_SIGNATURE, "app-layer-event keyword " + "supplied with unknown protocol \"%s\"", + alproto_name); + return NULL; + } } aled = SCMalloc(sizeof(*aled)); @@ -237,6 +247,7 @@ static DetectAppLayerEventData *DetectAppLayerEventParseAppP1(const char *arg) memset(aled, 0x00, sizeof(*aled)); aled->alproto = alproto; aled->arg = SCStrdup(arg); + aled->needs_detctx = needs_detctx; if (aled->arg == NULL) { SCFree(aled); return NULL; @@ -791,6 +802,31 @@ static int DetectAppLayerEventTest05(void) PASS; } +static int DetectAppLayerEventTest06(void) +{ + AppLayerEventType event_type; + uint8_t ipproto_bitarray[256 / 8]; + memset(ipproto_bitarray, 0, sizeof(ipproto_bitarray)); + ipproto_bitarray[IPPROTO_TCP / 8] |= 1 << (IPPROTO_TCP % 8); + + DetectAppLayerEventData *aled = DetectAppLayerEventParse("file.test", + &event_type); + + FAIL_IF_NULL(aled); + + if (DetectAppLayerEventParseAppP2(aled, ipproto_bitarray, &event_type) < 0) + goto error; + + if (aled->alproto != ALPROTO_UNKNOWN || aled->event_id != DET_CTX_EVENT_TEST) + goto error; + + DetectAppLayerEventFree(aled); + PASS; + +error: + DetectAppLayerEventFree(aled); + FAIL; +} #endif /* UNITTESTS */ /** @@ -804,6 +840,7 @@ void DetectAppLayerEventRegisterTests(void) UtRegisterTest("DetectAppLayerEventTest03", DetectAppLayerEventTest03); UtRegisterTest("DetectAppLayerEventTest04", DetectAppLayerEventTest04); UtRegisterTest("DetectAppLayerEventTest05", DetectAppLayerEventTest05); + UtRegisterTest("DetectAppLayerEventTest06", DetectAppLayerEventTest06); #endif /* UNITTESTS */ return; diff --git a/src/detect-app-layer-event.h b/src/detect-app-layer-event.h index a3ed608828..b7d6133dbe 100644 --- a/src/detect-app-layer-event.h +++ b/src/detect-app-layer-event.h @@ -28,6 +28,9 @@ typedef struct DetectAppLayerEventData_ { AppProto alproto; int event_id; + /* it's used to check if there are event set into the detect engine */ + bool needs_detctx; + char *arg; } DetectAppLayerEventData; diff --git a/src/detect-engine.c b/src/detect-engine.c index 91822231a2..41861a8832 100644 --- a/src/detect-engine.c +++ b/src/detect-engine.c @@ -100,6 +100,27 @@ static uint32_t DetectEngineTentantGetIdFromPcap(const void *ctx, const Packet * static DetectEngineAppInspectionEngine *g_app_inspect_engines = NULL; +SCEnumCharMap det_ctx_event_table[ ] = { +#ifdef UNITTESTS + { "TEST", DET_CTX_EVENT_TEST }, +#endif + { "NO_MEMORY", FILE_DECODER_EVENT_NO_MEM }, + { "INVALID_SWF_LENGTH", FILE_DECODER_EVENT_INVALID_SWF_LENGTH }, + { "INVALID_SWF_VERSION", FILE_DECODER_EVENT_INVALID_SWF_VERSION }, + { "Z_DATA_ERROR", FILE_DECODER_EVENT_Z_DATA_ERROR }, + { "Z_STREAM_ERROR", FILE_DECODER_EVENT_Z_STREAM_ERROR }, + { "Z_BUF_ERROR", FILE_DECODER_EVENT_Z_BUF_ERROR }, + { "Z_UNKNOWN_ERROR", FILE_DECODER_EVENT_Z_UNKNOWN_ERROR }, + { "LZMA_DECODER_ERROR", FILE_DECODER_EVENT_LZMA_DECODER_ERROR }, + { "LZMA_MEMLIMIT_ERROR", FILE_DECODER_EVENT_LZMA_MEMLIMIT_ERROR }, + { "LZMA_OPTIONS_ERROR", FILE_DECODER_EVENT_LZMA_OPTIONS_ERROR }, + { "LZMA_FORMAT_ERROR", FILE_DECODER_EVENT_LZMA_FORMAT_ERROR }, + { "LZMA_DATA_ERROR", FILE_DECODER_EVENT_LZMA_DATA_ERROR }, + { "LZMA_BUF_ERROR", FILE_DECODER_EVENT_LZMA_BUF_ERROR }, + { "LZMA_UNKNOWN_ERROR", FILE_DECODER_EVENT_LZMA_UNKNOWN_ERROR }, + { NULL, -1 }, +}; + void DetectAppLayerInspectEngineRegister(const char *name, AppProto alproto, uint32_t dir, int progress, InspectEngineFuncPtr Callback) @@ -3102,6 +3123,32 @@ const char *DetectSigmatchListEnumToString(enum DetectSigmatchListEnum type) return "error"; } +/* events api */ +void DetectEngineSetEvent(DetectEngineThreadCtx *det_ctx, uint8_t e) +{ + AppLayerDecoderEventsSetEventRaw(&det_ctx->decoder_events, e); + det_ctx->events++; +} + +AppLayerDecoderEvents *DetectEngineGetEvents(DetectEngineThreadCtx *det_ctx) +{ + return det_ctx->decoder_events; +} + +int DetectEngineGetEventInfo(const char *event_name, int *event_id, + AppLayerEventType *event_type) +{ + *event_id = SCMapEnumNameToValue(event_name, det_ctx_event_table); + if (*event_id == -1) { + SCLogError(SC_ERR_INVALID_ENUM_MAP, "event \"%s\" not present in " + "det_ctx's enum map table.", event_name); + /* this should be treated as fatal */ + return -1; + } + *event_type = APP_LAYER_EVENT_TYPE_TRANSACTION; + + return 0; +} /*************************************Unittest*********************************/ diff --git a/src/detect.h b/src/detect.h index e5e1f7c268..89a6f0d527 100644 --- a/src/detect.h +++ b/src/detect.h @@ -50,6 +50,8 @@ #include "util-var-name.h" +#include "app-layer-events.h" + #define DETECT_MAX_RULE_SIZE 8192 /* forward declarations for the structures from detect-engine-sigorder.h */ @@ -959,6 +961,9 @@ typedef struct DetectEngineThreadCtx_ { int base64_decoded_len; int base64_decoded_len_max; + AppLayerDecoderEvents *decoder_events; + uint16_t events; + #ifdef DEBUG uint64_t pkt_stream_add_cnt; uint64_t payload_mpm_cnt; @@ -1018,6 +1023,27 @@ typedef struct SigTableElmt_ { } SigTableElmt; +/* event code */ +enum { +#ifdef UNITTESTS + DET_CTX_EVENT_TEST, +#endif + FILE_DECODER_EVENT_NO_MEM, + FILE_DECODER_EVENT_INVALID_SWF_LENGTH, + FILE_DECODER_EVENT_INVALID_SWF_VERSION, + FILE_DECODER_EVENT_Z_DATA_ERROR, + FILE_DECODER_EVENT_Z_STREAM_ERROR, + FILE_DECODER_EVENT_Z_BUF_ERROR, + FILE_DECODER_EVENT_Z_UNKNOWN_ERROR, + FILE_DECODER_EVENT_LZMA_DECODER_ERROR, + FILE_DECODER_EVENT_LZMA_MEMLIMIT_ERROR, + FILE_DECODER_EVENT_LZMA_OPTIONS_ERROR, + FILE_DECODER_EVENT_LZMA_FORMAT_ERROR, + FILE_DECODER_EVENT_LZMA_DATA_ERROR, + FILE_DECODER_EVENT_LZMA_BUF_ERROR, + FILE_DECODER_EVENT_LZMA_UNKNOWN_ERROR, +}; + #define SIG_GROUP_HEAD_HAVERAWSTREAM (1 << 0) #ifdef HAVE_MAGIC #define SIG_GROUP_HEAD_HAVEFILEMAGIC (1 << 20) @@ -1265,6 +1291,12 @@ void DetectFlowbitsAnalyze(DetectEngineCtx *de_ctx); int DetectMetadataHashInit(DetectEngineCtx *de_ctx); void DetectMetadataHashFree(DetectEngineCtx *de_ctx); +/* events */ +void DetectEngineSetEvent(DetectEngineThreadCtx *det_ctx, uint8_t e); +AppLayerDecoderEvents *DetectEngineGetEvents(DetectEngineThreadCtx *det_ctx); +int DetectEngineGetEventInfo(const char *event_name, int *event_id, + AppLayerEventType *event_type); + #include "detect-engine-build.h" #include "detect-engine-register.h"