]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
Introduce a separate inspection engine for app events.
authorAnoop Saldanha <anoopsaldanha@gmail.com>
Sun, 18 Aug 2013 14:06:55 +0000 (19:36 +0530)
committerAnoop Saldanha <anoopsaldanha@gmail.com>
Sun, 29 Sep 2013 17:43:10 +0000 (23:13 +0530)
src/Makefile.am
src/app-layer-dns-common.c
src/detect-app-layer-event.c
src/detect-dns-query.c
src/detect-engine-apt-event.c [new file with mode: 0644]
src/detect-engine-apt-event.h [new file with mode: 0644]
src/detect-engine-state.h
src/detect-engine.c
src/detect-parse.c
src/detect.h

index 4de0c4157124287fd73fc52a425794ac87c2f1f4..47af7d5479802587e2a77e1dc1b38b3e44a397cf 100644 (file)
@@ -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 \
index b69618392b23b17a8a60445b3fb52b6e1a0391e6..5902d663d7b2bf545467da140962050b2b5b7f78 100644 (file)
@@ -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;
 }
index 449e7540b5b6f0c414637d2368f48cccacde2d3c..c469f8a7f7229f6d80677673ebdc67c3f3fc7058 100644 (file)
@@ -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;
index 398fa159e306b8fce0dccf6f7b6d374398429a47..4a1af274c52ac41869e3b70fac8e462676bf18c0 100644 (file)
@@ -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 (file)
index 0000000..c7f664d
--- /dev/null
@@ -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 <anoopsaldanha@gmail.com>
+ */
+
+#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 (file)
index 0000000..c264efe
--- /dev/null
@@ -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 <anoopsaldanha@gmail.com>
+ */
+
+#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__ */
index 06fd568b4ecbfcc0a7a4d90199d5dc777915a447..72d934317a226acbf3eb5b969a6e2666092fffe7 100644 (file)
@@ -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
index 313e0dbe91b6b39b25971f5e00f178723150b10e..22827ce531c12a6636a9bc97bf100c10b7df1eb1 100644 (file)
@@ -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);
index 269ece987eb2e9616ec936fc5c32f4c8dfaa9573..f1dd264ae01857beb6377fc3441e89fced3163f4 100644 (file)
@@ -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;
index 169d6752d9643100bcf45d963c2f901eef941809..f7bae80d18ac0a0df57f0949ede6bf4c903c8fa2 100644 (file)
@@ -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,