]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
Store TX id with alerts
authorVictor Julien <victor@inliniac.net>
Wed, 18 Sep 2013 08:18:09 +0000 (10:18 +0200)
committerVictor Julien <victor@inliniac.net>
Tue, 8 Oct 2013 14:40:43 +0000 (16:40 +0200)
When generating an alert and storing it in the packet, store the tx_id
as well. This way the output modules can log the tx_id and access the
proper tx for logging.

Issue #904.

src/decode.h
src/detect-engine-alert.c
src/detect-engine-alert.h
src/detect-engine-iponly.c
src/detect-engine-state.c
src/detect-engine-state.h
src/detect.c

index ab8c782a88e9d0bfdffc2d2f1d418d3ec6922a76..bfd22e979c72a4b31539e0d12cb7caaf2b1f820e 100644 (file)
@@ -248,6 +248,7 @@ typedef struct PacketAlert_ {
     uint8_t action; /* Internal num, used for sorting */
     uint8_t flags;
     struct Signature_ *s;
+    uint64_t tx_id;
 } PacketAlert;
 
 /** After processing an alert by the thresholding module, if at
@@ -258,6 +259,8 @@ typedef struct PacketAlert_ {
 #define PACKET_ALERT_FLAG_STATE_MATCH   0x02
 /** alert was generated based on stream */
 #define PACKET_ALERT_FLAG_STREAM_MATCH  0x04
+/** alert is in a tx, tx_id set */
+#define PACKET_ALERT_FLAG_TX            0x08
 
 #define PACKET_ALERT_MAX 15
 
index e22bb2d29245d428232530eee7bc48473f9beb1b..3d111fd7db4f7cd1e1e96f0b3ef680e5dbb5d15b 100644 (file)
@@ -175,7 +175,7 @@ int PacketAlertRemove(Packet *p, uint16_t pos)
  *  \param flags alert flags
  *  \param alert_msg ptr to StreamMsg object that the signature matched on
  */
-int PacketAlertAppend(DetectEngineThreadCtx *det_ctx, Signature *s, Packet *p, uint8_t flags)
+int PacketAlertAppend(DetectEngineThreadCtx *det_ctx, Signature *s, Packet *p, uint64_t tx_id, uint8_t flags)
 {
     int i = 0;
 
@@ -192,6 +192,7 @@ int PacketAlertAppend(DetectEngineThreadCtx *det_ctx, Signature *s, Packet *p, u
         p->alerts.alerts[p->alerts.cnt].action = s->action;
         p->alerts.alerts[p->alerts.cnt].flags = flags;
         p->alerts.alerts[p->alerts.cnt].s = s;
+        p->alerts.alerts[p->alerts.cnt].tx_id = tx_id;
     } else {
         /* We need to make room for this s->num
          (a bit ugly with memcpy but we are planning changes here)*/
@@ -205,6 +206,7 @@ int PacketAlertAppend(DetectEngineThreadCtx *det_ctx, Signature *s, Packet *p, u
         p->alerts.alerts[i].action = s->action;
         p->alerts.alerts[i].flags = flags;
         p->alerts.alerts[i].s = s;
+        p->alerts.alerts[i].tx_id = tx_id;
     }
 
     /* Update the count */
index 8bff764dd4a4b2943968537365b1904998d74021..6f200b268d4e82e7f1f783b4ef163d485e73896f 100644 (file)
@@ -29,7 +29,7 @@
 #include "detect.h"
 
 void PacketAlertFinalize(DetectEngineCtx *, DetectEngineThreadCtx *, Packet *);
-int PacketAlertAppend(DetectEngineThreadCtx *, Signature *, Packet *, uint8_t);
+int PacketAlertAppend(DetectEngineThreadCtx *, Signature *, Packet *, uint64_t tx_id, uint8_t);
 int PacketAlertCheck(Packet *, uint32_t);
 int PacketAlertRemove(Packet *, uint16_t);
 void PacketAlertTagInit(void);
index d22d339f37978d658e5c2b9d0d0704dfa13831ea..0dc648d8c4fee2a76b0c5af3ad873c64f88c8059 100644 (file)
@@ -1084,9 +1084,9 @@ void IPOnlyMatchPacket(ThreadVars *tv,
                     }
                     if (!(s->flags & SIG_FLAG_NOALERT)) {
                         if (s->action & ACTION_DROP)
-                            PacketAlertAppend(det_ctx, s, p, PACKET_ALERT_FLAG_DROP_FLOW);
+                            PacketAlertAppend(det_ctx, s, p, 0, PACKET_ALERT_FLAG_DROP_FLOW);
                         else
-                            PacketAlertAppend(det_ctx, s, p, 0);
+                            PacketAlertAppend(det_ctx, s, p, 0, 0);
                     } else {
                         /* apply actions for noalert/rule suppressed as well */
                         PACKET_UPDATE_ACTION(p, s->action);
index b10af8049d93f64b8911ac87537c7c9da2975471..90ce81e5d34ef45aec4d699a76e20632942a6704 100644 (file)
@@ -236,7 +236,7 @@ int DeStateFlowHasInspectableState(Flow *f, uint16_t alproto, uint16_t alversion
 
 int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
                                 DetectEngineThreadCtx *det_ctx,
-                                Signature *s, Flow *f, uint8_t flags,
+                                Signature *s, Packet *p, Flow *f, uint8_t flags,
                                 void *alstate, uint16_t alproto, uint16_t alversion)
 {
     DetectEngineAppInspectionEngine *engine = NULL;
@@ -310,8 +310,17 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
             /* all the engines seem to be exhausted at this point.  If we
              * didn't have a match in one of the engines we would have
              * broken off and engine wouldn't be NULL.  Hence the alert. */
-            if (engine == NULL && total_matches > 0)
-                alert_cnt++;
+            if (engine == NULL && total_matches > 0) {
+
+                if (!(s->flags & SIG_FLAG_NOALERT)) {
+                    PacketAlertAppend(det_ctx, s, p, tx_id,
+                            PACKET_ALERT_FLAG_STATE_MATCH|PACKET_ALERT_FLAG_TX);
+                } else {
+                    PACKET_UPDATE_ACTION(p, s->action);
+                }
+
+                alert_cnt = 1;
+            }
 
             if (tx_id == (total_txs - 1)) {
                 void *tx = AppLayerGetTx(alproto, alstate, tx_id);
@@ -337,12 +346,27 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
             if (smb_state->dcerpc_present &&
                 DetectEngineInspectDcePayload(de_ctx, det_ctx, s, f,
                                               flags, &smb_state->dcerpc) == 1) {
-                alert_cnt++;
+                if (!(s->flags & SIG_FLAG_NOALERT)) {
+                    PacketAlertAppend(det_ctx, s, p, 0,
+                            PACKET_ALERT_FLAG_STATE_MATCH);
+                } else {
+                    PACKET_UPDATE_ACTION(p, s->action);
+                }
+
+                alert_cnt = 1;
             }
         } else {
             if (DetectEngineInspectDcePayload(de_ctx, det_ctx, s, f,
                                               flags, alstate) == 1) {
-                alert_cnt++;
+                alert_cnt = 1;
+
+                if (!(s->flags & SIG_FLAG_NOALERT)) {
+                    PacketAlertAppend(det_ctx, s, p, 0,
+                            PACKET_ALERT_FLAG_STATE_MATCH);
+                } else {
+                    PACKET_UPDATE_ACTION(p, s->action);
+                }
+
             }
         }
     }
@@ -373,8 +397,15 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
     if (s->sm_lists[DETECT_SM_LIST_AMATCH] != NULL) {
         store_de_state = 1;
         if (sm == NULL || inspect_flags & DE_STATE_FLAG_SIG_CANT_MATCH) {
-            if (match == 1)
+            if (match == 1) {
+                if (!(s->flags & SIG_FLAG_NOALERT)) {
+                    PacketAlertAppend(det_ctx, s, p, 0,
+                            PACKET_ALERT_FLAG_STATE_MATCH);
+                } else {
+                    PACKET_UPDATE_ACTION(p, s->action);
+                }
                 alert_cnt = 1;
+            }
             inspect_flags |= DE_STATE_FLAG_FULL_INSPECT;
         }
     }
@@ -405,7 +436,7 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
     SCMutexUnlock(&f->de_state_m);
 
  end:
-    return alert_cnt;
+    return alert_cnt ? 1:0;
 }
 
 void DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
@@ -621,7 +652,12 @@ void DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
                 SigMatchSignaturesRunPostMatch(tv, de_ctx, det_ctx, p, s);
 
                 if (!(s->flags & SIG_FLAG_NOALERT)) {
-                    PacketAlertAppend(det_ctx, s, p, 0);
+                    if (alproto_supports_txs)
+                        PacketAlertAppend(det_ctx, s, p, inspect_tx_id,
+                                PACKET_ALERT_FLAG_STATE_MATCH|PACKET_ALERT_FLAG_TX);
+                    else
+                        PacketAlertAppend(det_ctx, s, p, 0,
+                                PACKET_ALERT_FLAG_STATE_MATCH);
                 } else {
                     PACKET_UPDATE_ACTION(p, s->action);
                 }
index 72d934317a226acbf3eb5b969a6e2666092fffe7..7606278f9d1f1d818dffaa1c58c6c529aa3da61e 100644 (file)
@@ -170,7 +170,7 @@ int DeStateFlowHasInspectableState(Flow *f, uint16_t alproto, uint16_t alversion
  */
 int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
                                 DetectEngineThreadCtx *det_ctx,
-                                Signature *s, Flow *f, uint8_t flags,
+                                Signature *s, Packet *p, Flow *f, uint8_t flags,
                                 void *alstate, uint16_t alproto,
                                 uint16_t alversion);
 
index d84d485676025361dd149a192083dca7b719b4fd..79b60365e3cc6130bb3f278fbe950e726edafceb 100644 (file)
@@ -1103,8 +1103,8 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
     SigMatch *sm = NULL;
     uint16_t alversion = 0;
     int reset_de_state = 0;
+    int state_alert = 0;
     int alerts = 0;
-    int i;
     int app_decoder_events = 0;
 
     SCEnter();
@@ -1305,7 +1305,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
     /* inspect the sigs against the packet */
     for (idx = 0; idx < det_ctx->match_array_cnt; idx++) {
         RULE_PROFILING_START;
-        alerts = 0;
+        state_alert = 0;
 #ifdef PROFILING
         smatch = 0;
 #endif
@@ -1492,11 +1492,16 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
             }
 
             SCLogDebug("stateful app layer match inspection starting");
+
+            /* if DeStateDetectStartDetection matches, it's a full
+             * signature match. It will then call PacketAlertAppend
+             * itself, so we can skip it below. This is done so it
+             * can store the tx_id with the alert */
             PACKET_PROFILING_DETECT_START(p, PROF_DETECT_STATEFUL);
-            alerts = DeStateDetectStartDetection(th_v, de_ctx, det_ctx, s,
-                                                 p->flow, flags, alstate, alproto, alversion);
+            state_alert = DeStateDetectStartDetection(th_v, de_ctx, det_ctx, s,
+                                                 p, p->flow, flags, alstate, alproto, alversion);
             PACKET_PROFILING_DETECT_END(p, PROF_DETECT_STATEFUL);
-            if (alerts == 0)
+            if (state_alert == 0)
                 goto next;
 
             /* match */
@@ -1506,11 +1511,6 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
             alert_flags |= PACKET_ALERT_FLAG_STATE_MATCH;
         }
 
-        /* If we have reached this stage and we don't have any alerts, it
-         * indicates that we didn't have a stateful sig, hence we set alerts
-         * to 1.  But if we have an alert set, then the sig is definitely a
-         * stateful sig and we need to retain the no of alerts */
-        alerts = (alerts == 0) ? 1 : alerts;
 #ifdef PROFILING
         smatch = 1;
 #endif
@@ -1518,12 +1518,14 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
         SigMatchSignaturesRunPostMatch(th_v, de_ctx, det_ctx, p, s);
 
         if (!(s->flags & SIG_FLAG_NOALERT)) {
-            for (i = 0; i < alerts; i++)
-                PacketAlertAppend(det_ctx, s, p, alert_flags);
+            /* stateful sigs call PacketAlertAppend from DeStateDetectStartDetection */
+            if (!state_alert)
+                PacketAlertAppend(det_ctx, s, p, 0, alert_flags);
         } else {
             /* apply actions even if not alerting */
             PACKET_UPDATE_ACTION(p, s->action);
         }
+        alerts++;
 next:
         DetectFlowvarProcessList(det_ctx, p->flow);
         DetectReplaceFree(det_ctx->replist);