diff --git a/src/Makefile.am b/src/Makefile.am index 4de0c41571..47af7d5479 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -83,6 +83,7 @@ detect-engine-address-ipv4.c detect-engine-address-ipv4.h \ detect-engine-address-ipv6.c detect-engine-address-ipv6.h \ detect-engine-alert.c detect-engine-alert.h \ detect-engine-analyzer.c detect-engine-analyzer.h \ +detect-engine-apt-event.c detect-engine-apt-event.h \ detect-engine.c detect-engine.h \ detect-engine-content-inspection.c detect-engine-content-inspection.h \ detect-engine-dcepayload.c detect-engine-dcepayload.h \ diff --git a/src/app-layer-dns-common.c b/src/app-layer-dns-common.c index b69618392b..5902d663d7 100644 --- a/src/app-layer-dns-common.c +++ b/src/app-layer-dns-common.c @@ -49,7 +49,7 @@ int DNSStateGetEventInfo(const char *event_name, return -1; } - *event_type = APP_LAYER_EVENT_TYPE_GENERAL; + *event_type = APP_LAYER_EVENT_TYPE_TRANSACTION; return 0; } diff --git a/src/detect-app-layer-event.c b/src/detect-app-layer-event.c index 449e7540b5..c469f8a7f7 100644 --- a/src/detect-app-layer-event.c +++ b/src/detect-app-layer-event.c @@ -88,28 +88,10 @@ int DetectAppLayerEventAppMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, SCEnter(); AppLayerDecoderEvents *decoder_events = NULL; int r = 0; - uint64_t tx_id = 0, max_id; DetectAppLayerEventData *aled = (DetectAppLayerEventData *)m->ctx; FLOWLOCK_RDLOCK(f); - /* inspect TX events first if we need to */ - if (AppLayerProtoIsTxEventAware(f->alproto)) { - SCLogDebug("proto is AppLayerProtoIsTxEventAware true"); - - tx_id = AppLayerTransactionGetInspectId(f, flags); - max_id = AppLayerGetTxCnt(f->alproto, f->alstate); - - for (; tx_id < max_id; tx_id++) { - decoder_events = AppLayerGetEventsFromFlowByTx(f, tx_id); - if (decoder_events != NULL && - AppLayerDecoderEventsIsEventSet(decoder_events, aled->event_id)) { - r = 1; - break; - } - } - } - if (r == 0) { decoder_events = AppLayerGetDecoderEventsForFlow(f); if (decoder_events != NULL && @@ -244,9 +226,13 @@ int DetectAppLayerEventSetup(DetectEngineCtx *de_ctx, Signature *s, char *arg) if (event_type == APP_LAYER_EVENT_TYPE_PACKET) { SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); - } else { + } else if (event_type == APP_LAYER_EVENT_TYPE_GENERAL) { SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH); s->flags |= SIG_FLAG_APPLAYER; + } else { + /* implied APP_LAYER_EVENT_TYPE_TRANSACTION */ + SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_APP_EVENT); + s->flags |= SIG_FLAG_APPLAYER; } return 0; diff --git a/src/detect-dns-query.c b/src/detect-dns-query.c index 398fa159e3..4a1af274c5 100644 --- a/src/detect-dns-query.c +++ b/src/detect-dns-query.c @@ -168,7 +168,7 @@ static int DetectDnsQueryTest01(void) { de_ctx->mpm_matcher = DEFAULT_MPM; de_ctx->flags |= DE_QUIET; - s = DetectEngineAppendSig(de_ctx, "alert dnsudp any any -> any any " + s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any " "(msg:\"Test dns_query option\"; " "dns_query; content:\"google\"; nocase; sid:1;)"); if (s == NULL) { @@ -295,13 +295,13 @@ static int DetectDnsQueryTest02(void) { de_ctx->mpm_matcher = DEFAULT_MPM; de_ctx->flags |= DE_QUIET; - s = DetectEngineAppendSig(de_ctx, "alert dnsudp any any -> any any " + s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any " "(msg:\"Test dns_query option\"; " "dns_query; content:\"google.com\"; nocase; sid:1;)"); if (s == NULL) { goto end; } - s = DetectEngineAppendSig(de_ctx, "alert dnsudp any any -> any any " + s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any " "(msg:\"Test dns_query option\"; " "dns_query; content:\"google.net\"; nocase; sid:2;)"); if (s == NULL) { @@ -866,14 +866,14 @@ static int DetectDnsQueryTest06(void) { de_ctx->mpm_matcher = DEFAULT_MPM; de_ctx->flags |= DE_QUIET; - s = DetectEngineAppendSig(de_ctx, "alert dnsudp any any -> any any " + s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any " "(msg:\"Test dns_query option\"; " "dns_query; content:\"google\"; nocase; " "pcre:\"/google\\.com$/i\"; sid:1;)"); if (s == NULL) { goto end; } - s = DetectEngineAppendSig(de_ctx, "alert dnsudp any any -> any any " + s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any " "(msg:\"Test dns_query option\"; " "dns_query; content:\"google\"; nocase; " "pcre:\"/^\\.[a-z]{2,3}$/iR\"; sid:2;)"); @@ -1007,19 +1007,19 @@ static int DetectDnsQueryTest07(void) { de_ctx->mpm_matcher = DEFAULT_MPM; de_ctx->flags |= DE_QUIET; - s = DetectEngineAppendSig(de_ctx, "alert dnsudp any any -> any any " + s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any " "(msg:\"Test dns_query option\"; " "dns_query; content:\"google.com\"; nocase; sid:1;)"); if (s == NULL) { goto end; } - s = DetectEngineAppendSig(de_ctx, "alert dnsudp any any -> any any " + s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any " "(msg:\"Test dns_query option\"; " "dns_query; content:\"google.net\"; nocase; sid:2;)"); if (s == NULL) { goto end; } - s = DetectEngineAppendSig(de_ctx, "alert dnsudp any any -> any any " + s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any " "(msg:\"Test Z flag event\"; " "app-layer-event:dns.z_flag_set; sid:3;)"); if (s == NULL) { diff --git a/src/detect-engine-apt-event.c b/src/detect-engine-apt-event.c new file mode 100644 index 0000000000..c7f664d39a --- /dev/null +++ b/src/detect-engine-apt-event.c @@ -0,0 +1,75 @@ +/* Copyright (C) 2007-2013 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 + */ + +#include "suricata-common.h" +#include "suricata.h" + +#include "app-layer-parser.h" +#include "detect-app-layer-event.h" +#include "detect-engine-state.h" +#include "stream.h" +#include "detect-engine-apt-event.h" + +#include "util-unittest.h" + +int DetectEngineAptEventInspect(ThreadVars *tv, + DetectEngineCtx *de_ctx, + DetectEngineThreadCtx *det_ctx, + Signature *s, Flow *f, uint8_t flags, + void *alstate, + void *tx, uint64_t tx_id) +{ + AppLayerDecoderEvents *decoder_events = NULL; + int r = 0; + int direction = 0; + uint16_t alproto; + SigMatch *sm; + DetectAppLayerEventData *aled = NULL; + + alproto = f->alproto; + decoder_events = AppLayerGetEventsFromFlowByTx(f, tx_id); + if (decoder_events == NULL) + goto end; + + for (sm = s->sm_lists[DETECT_SM_LIST_APP_EVENT]; sm != NULL; sm = sm->next) { + aled = (DetectAppLayerEventData *)sm->ctx; + if (AppLayerDecoderEventsIsEventSet(decoder_events, aled->event_id)) + continue; + goto end; + } + + r = 1; + + end: + if (r == 1) { + return DETECT_ENGINE_INSPECT_SIG_MATCH; + } else { + direction = (flags & STREAM_TOSERVER) ? 0 : 1; + if (AppLayerGetAlstateProgress(alproto, tx, direction) == + AppLayerGetAlstateProgressCompletionStatus(alproto, direction)) + { + return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; + } else { + return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; + } + } +} diff --git a/src/detect-engine-apt-event.h b/src/detect-engine-apt-event.h new file mode 100644 index 0000000000..c264efe945 --- /dev/null +++ b/src/detect-engine-apt-event.h @@ -0,0 +1,34 @@ +/* Copyright (C) 2007-2013 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 + */ + +#ifndef __DETECT_ENGINE_APT_EVENT__H__ +#define __DETECT_ENGINE_APT_EVENT__H__ + +int DetectEngineAptEventInspect(ThreadVars *tv, + DetectEngineCtx *de_ctx, + DetectEngineThreadCtx *det_ctx, + Signature *s, Flow *f, uint8_t flags, + void *alstate, + void *tx, uint64_t tx_id); +void DetectEngineAptEventRegisterTests(void); + +#endif /* __DETECT_ENGINE_APT_EVENT__H__ */ diff --git a/src/detect-engine-state.h b/src/detect-engine-state.h index 06fd568b4e..72d934317a 100644 --- a/src/detect-engine-state.h +++ b/src/detect-engine-state.h @@ -75,6 +75,7 @@ #define DE_STATE_FLAG_FULL_INSPECT (1 << 15) #define DE_STATE_FLAG_SIG_CANT_MATCH (1 << 16) #define DE_STATE_FLAG_DNSQUERY_INSPECT (1 << 17) +#define DE_STATE_FLAG_APP_EVENT_INSPECT (1 << 18) /* state flags */ #define DETECT_ENGINE_STATE_FLAG_FILE_STORE_DISABLED 0x0001 diff --git a/src/detect-engine.c b/src/detect-engine.c index 313e0dbe91..22827ce531 100644 --- a/src/detect-engine.c +++ b/src/detect-engine.c @@ -365,6 +365,14 @@ void DetectEngineRegisterAppInspectionEngine(uint16_t alproto, exit(EXIT_FAILURE); } + DetectEngineAppInspectionEngine *tmp = list[alproto][dir]; + while (tmp != NULL) { + if (tmp->sm_list == sm_list && tmp->Callback == Callback) { + return; + } + tmp = tmp->next; + } + DetectEngineAppInspectionEngine *new_engine = SCMalloc(sizeof(DetectEngineAppInspectionEngine)); if (unlikely(new_engine == NULL)) { exit(EXIT_FAILURE); diff --git a/src/detect-parse.c b/src/detect-parse.c index 269ece987e..f1dd264ae0 100644 --- a/src/detect-parse.c +++ b/src/detect-parse.c @@ -31,6 +31,7 @@ #include "detect-engine-address.h" #include "detect-engine-port.h" #include "detect-engine-mpm.h" +#include "detect-engine-state.h" #include "detect-content.h" #include "detect-pcre.h" @@ -39,6 +40,7 @@ #include "detect-ipproto.h" #include "detect-flow.h" #include "detect-app-layer-protocol.h" +#include "detect-engine-apt-event.h" #include "pkt-var.h" #include "host.h" @@ -1472,6 +1474,8 @@ static Signature *SigInitHelper(DetectEngineCtx *de_ctx, char *sigstr, sig->flags |= SIG_FLAG_STATE_MATCH; if (sig->sm_lists[DETECT_SM_LIST_DNSQUERY_MATCH]) sig->flags |= SIG_FLAG_STATE_MATCH; + if (sig->sm_lists[DETECT_SM_LIST_APP_EVENT]) + sig->flags |= SIG_FLAG_STATE_MATCH; if (!(sig->init_flags & SIG_FLAG_INIT_FLOW)) { sig->flags |= SIG_FLAG_TOSERVER; @@ -1484,6 +1488,48 @@ static Signature *SigInitHelper(DetectEngineCtx *de_ctx, char *sigstr, SigBuildAddressMatchArray(sig); + if (sig->sm_lists[DETECT_SM_LIST_APP_EVENT] != NULL && + (AppLayerProtoIsTxEventAware(sig->alproto) || sig->alproto == ALPROTO_DNS)) { + if (sig->alproto == ALPROTO_DNS) { + DetectEngineRegisterAppInspectionEngine(ALPROTO_DNS_TCP, + 0, + DETECT_SM_LIST_APP_EVENT, + DE_STATE_FLAG_APP_EVENT_INSPECT, + DE_STATE_FLAG_APP_EVENT_INSPECT, + DetectEngineAptEventInspect, + app_inspection_engine); + DetectEngineRegisterAppInspectionEngine(ALPROTO_DNS_UDP, + 0, + DETECT_SM_LIST_APP_EVENT, + DE_STATE_FLAG_APP_EVENT_INSPECT, + DE_STATE_FLAG_APP_EVENT_INSPECT, + DetectEngineAptEventInspect, + app_inspection_engine); + DetectEngineRegisterAppInspectionEngine(ALPROTO_DNS_TCP, + 1, + DETECT_SM_LIST_APP_EVENT, + DE_STATE_FLAG_APP_EVENT_INSPECT, + DE_STATE_FLAG_APP_EVENT_INSPECT, + DetectEngineAptEventInspect, + app_inspection_engine); + DetectEngineRegisterAppInspectionEngine(ALPROTO_DNS_UDP, + 1, + DETECT_SM_LIST_APP_EVENT, + DE_STATE_FLAG_APP_EVENT_INSPECT, + DE_STATE_FLAG_APP_EVENT_INSPECT, + DetectEngineAptEventInspect, + app_inspection_engine); + } else { + DetectEngineRegisterAppInspectionEngine(sig->alproto, + (sig->flags & SIG_FLAG_TOSERVER) ? 0 : 1, + DETECT_SM_LIST_APP_EVENT, + DE_STATE_FLAG_APP_EVENT_INSPECT, + DE_STATE_FLAG_APP_EVENT_INSPECT, + DetectEngineAptEventInspect, + app_inspection_engine); + } + } + /* validate signature, SigValidate will report the error reason */ if (SigValidate(de_ctx, sig) == 0) { goto error; diff --git a/src/detect.h b/src/detect.h index 169d6752d9..f7bae80d18 100644 --- a/src/detect.h +++ b/src/detect.h @@ -108,6 +108,8 @@ enum { DETECT_SM_LIST_HCDMATCH, /* list for http_user_agent keyword and the ones relative to it */ DETECT_SM_LIST_HUADMATCH, + /* app event engine sm list */ + DETECT_SM_LIST_APP_EVENT, DETECT_SM_LIST_AMATCH, DETECT_SM_LIST_DMATCH,