]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #1491 in SNORT/snort3 from ~MASHASAN/snort3:dce_alert_once to...
authorMike Stepanek (mstepane) <mstepane@cisco.com>
Mon, 28 Jan 2019 15:32:54 +0000 (10:32 -0500)
committerMike Stepanek (mstepane) <mstepane@cisco.com>
Mon, 28 Jan 2019 15:32:54 +0000 (10:32 -0500)
Squashed commit of the following:

commit a8c8665b06181ab0dad9979787d2455d2e1b1731
Author: Masud Hasan <mashasan@cisco.com>
Date:   Thu Jan 17 15:31:35 2019 -0500

    dce_rpc: Limiting each signature alert to once per session using 'limit_alerts' config

15 files changed:
src/service_inspectors/dce_rpc/dce_co.cc
src/service_inspectors/dce_rpc/dce_common.cc
src/service_inspectors/dce_rpc/dce_common.h
src/service_inspectors/dce_rpc/dce_smb2.cc
src/service_inspectors/dce_rpc/dce_smb_commands.cc
src/service_inspectors/dce_rpc/dce_smb_module.cc
src/service_inspectors/dce_rpc/dce_smb_module.h
src/service_inspectors/dce_rpc/dce_smb_transaction.cc
src/service_inspectors/dce_rpc/dce_smb_transaction_utils.cc
src/service_inspectors/dce_rpc/dce_smb_transaction_utils.h
src/service_inspectors/dce_rpc/dce_smb_utils.cc
src/service_inspectors/dce_rpc/dce_tcp_module.cc
src/service_inspectors/dce_rpc/dce_udp_module.cc
src/service_inspectors/dce_rpc/dce_udp_processing.cc
src/service_inspectors/dce_rpc/smb_message.cc

index 6494be37545c4103a68903da5a298e669d0ca7d4..6a1c206c8e9f8d8e7b8153e75fc1227de85a85aa 100644 (file)
@@ -369,7 +369,7 @@ static DCE2_Ret DCE2_CoHdrChecks(DCE2_SsnData* sd, DCE2_CoTracker* cot, const Dc
         if (sd->trans != DCE2_TRANS_TYPE__SMB)
         {
             // FIXIT-L PORT_IF_NEEDED segment check, same for all cases below
-            dce_alert(GID_DCE2, DCE2_CO_FRAG_LEN_LT_HDR,dce_common_stats);
+            dce_alert(GID_DCE2, DCE2_CO_FRAG_LEN_LT_HDR, dce_common_stats, *sd);
         }
 
         return DCE2_RET__ERROR;
@@ -379,7 +379,7 @@ static DCE2_Ret DCE2_CoHdrChecks(DCE2_SsnData* sd, DCE2_CoTracker* cot, const Dc
     {
         if (sd->trans != DCE2_TRANS_TYPE__SMB)
         {
-            dce_alert(GID_DCE2, DCE2_CO_BAD_MAJOR_VERSION,dce_common_stats);
+            dce_alert(GID_DCE2, DCE2_CO_BAD_MAJOR_VERSION,dce_common_stats, *sd);
         }
 
         return DCE2_RET__ERROR;
@@ -389,7 +389,7 @@ static DCE2_Ret DCE2_CoHdrChecks(DCE2_SsnData* sd, DCE2_CoTracker* cot, const Dc
     {
         if (sd->trans != DCE2_TRANS_TYPE__SMB)
         {
-            dce_alert(GID_DCE2, DCE2_CO_BAD_MINOR_VERSION,dce_common_stats);
+            dce_alert(GID_DCE2, DCE2_CO_BAD_MINOR_VERSION,dce_common_stats, *sd);
         }
 
         return DCE2_RET__ERROR;
@@ -398,7 +398,7 @@ static DCE2_Ret DCE2_CoHdrChecks(DCE2_SsnData* sd, DCE2_CoTracker* cot, const Dc
     {
         if (sd->trans != DCE2_TRANS_TYPE__SMB)
         {
-            dce_alert(GID_DCE2, DCE2_CO_BAD_PDU_TYPE,dce_common_stats);
+            dce_alert(GID_DCE2, DCE2_CO_BAD_PDU_TYPE,dce_common_stats, *sd);
         }
 
         return DCE2_RET__ERROR;
@@ -408,7 +408,7 @@ static DCE2_Ret DCE2_CoHdrChecks(DCE2_SsnData* sd, DCE2_CoTracker* cot, const Dc
     {
         if (frag_len > cot->max_xmit_frag)
         {
-            dce_alert(GID_DCE2, DCE2_CO_FRAG_GT_MAX_XMIT_FRAG,dce_common_stats);
+            dce_alert(GID_DCE2, DCE2_CO_FRAG_GT_MAX_XMIT_FRAG,dce_common_stats, *sd);
         }
         else if (!DceRpcCoLastFrag(co_hdr) && (pdu_type == DCERPC_PDU_TYPE__REQUEST)
             && ((((int)cot->max_xmit_frag - DCE2_MAX_XMIT_SIZE_FUZZ) < 0)
@@ -419,7 +419,7 @@ static DCE2_Ret DCE2_CoHdrChecks(DCE2_SsnData* sd, DCE2_CoTracker* cot, const Dc
              * only if it is considerably less - have seen legitimate fragments that are just
              * slightly less the negotiated fragment size. */
 
-            dce_alert(GID_DCE2, DCE2_CO_FRAG_LT_MAX_XMIT_FRAG,dce_common_stats);
+            dce_alert(GID_DCE2, DCE2_CO_FRAG_LT_MAX_XMIT_FRAG,dce_common_stats, *sd);
         }
 
         /* Continue processing */
@@ -537,7 +537,7 @@ static DCE2_CoCtxIdNode* dce_co_process_ctx_id(DCE2_SsnData* sd,DCE2_CoTracker*
 
     if (frag_len < sizeof(DceRpcCoContElem))
     {
-        dce_alert(GID_DCE2, DCE2_CO_REM_FRAG_LEN_LT_SIZE, dce_common_stats);
+        dce_alert(GID_DCE2, DCE2_CO_REM_FRAG_LEN_LT_SIZE, dce_common_stats, *sd);
         return nullptr;
     }
 
@@ -550,7 +550,7 @@ static DCE2_CoCtxIdNode* dce_co_process_ctx_id(DCE2_SsnData* sd,DCE2_CoTracker*
     /* No transfer syntaxes */
     if (num_tsyns == 0)
     {
-        dce_alert(GID_DCE2, DCE2_CO_NO_TFER_SYNTAX_SPECFD,dce_common_stats);
+        dce_alert(GID_DCE2, DCE2_CO_NO_TFER_SYNTAX_SPECFD, dce_common_stats, *sd);
         return nullptr;
     }
 
@@ -561,7 +561,7 @@ static DCE2_CoCtxIdNode* dce_co_process_ctx_id(DCE2_SsnData* sd,DCE2_CoTracker*
     {
         if (frag_len < sizeof(DceRpcCoSynId))
         {
-            dce_alert(GID_DCE2, DCE2_CO_REM_FRAG_LEN_LT_SIZE, dce_common_stats);
+            dce_alert(GID_DCE2, DCE2_CO_REM_FRAG_LEN_LT_SIZE, dce_common_stats, *sd);
             return nullptr;
         }
 
@@ -627,7 +627,7 @@ static void DCE2_CoCtxReq(DCE2_SsnData* sd, DCE2_CoTracker* cot, const DceRpcCoH
 
     if (num_ctx_items == 0)
     {
-        dce_alert(GID_DCE2, DCE2_CO_NO_CTX_ITEMS_SPECFD, dce_common_stats);
+        dce_alert(GID_DCE2, DCE2_CO_NO_CTX_ITEMS_SPECFD, dce_common_stats, *sd);
         return;
     }
 
@@ -781,7 +781,7 @@ static void DCE2_CoBindAck(DCE2_SsnData* sd, DCE2_CoTracker* cot,
 
     if (frag_len < sizeof(DceRpcCoBindAck))
     {
-        dce_alert(GID_DCE2, DCE2_CO_REM_FRAG_LEN_LT_SIZE,dce_common_stats);
+        dce_alert(GID_DCE2, DCE2_CO_REM_FRAG_LEN_LT_SIZE, dce_common_stats, *sd);
         return;
     }
 
@@ -800,7 +800,7 @@ static void DCE2_CoBindAck(DCE2_SsnData* sd, DCE2_CoTracker* cot,
     /* First move past secondary address */
     if (ctx_len < sec_addr_len)
     {
-        dce_alert(GID_DCE2, DCE2_CO_REM_FRAG_LEN_LT_SIZE,dce_common_stats);
+        dce_alert(GID_DCE2, DCE2_CO_REM_FRAG_LEN_LT_SIZE, dce_common_stats, *sd);
         return;
     }
 
@@ -812,7 +812,7 @@ static void DCE2_CoBindAck(DCE2_SsnData* sd, DCE2_CoTracker* cot,
 
     if (ctx_len < pad)
     {
-        dce_alert(GID_DCE2, DCE2_CO_REM_FRAG_LEN_LT_SIZE,dce_common_stats);
+        dce_alert(GID_DCE2, DCE2_CO_REM_FRAG_LEN_LT_SIZE, dce_common_stats, *sd);
         return;
     }
 
@@ -821,7 +821,7 @@ static void DCE2_CoBindAck(DCE2_SsnData* sd, DCE2_CoTracker* cot,
     /* Now we're at the start of the context item results */
     if (ctx_len < sizeof(DceRpcCoContResultList))
     {
-        dce_alert(GID_DCE2, DCE2_CO_REM_FRAG_LEN_LT_SIZE,dce_common_stats);
+        dce_alert(GID_DCE2, DCE2_CO_REM_FRAG_LEN_LT_SIZE, dce_common_stats, *sd);
         return;
     }
 
@@ -837,7 +837,7 @@ static void DCE2_CoBindAck(DCE2_SsnData* sd, DCE2_CoTracker* cot,
 
         if (ctx_len < sizeof(DceRpcCoContResult))
         {
-            dce_alert(GID_DCE2, DCE2_CO_REM_FRAG_LEN_LT_SIZE,dce_common_stats);
+            dce_alert(GID_DCE2, DCE2_CO_REM_FRAG_LEN_LT_SIZE, dce_common_stats, *sd);
             return;
         }
         ctx_result = (const DceRpcCoContResult*)ctx_data;
@@ -870,7 +870,7 @@ static void DCE2_CoBind(DCE2_SsnData* sd, DCE2_CoTracker* cot,
 
     if (frag_len < sizeof(DceRpcCoBind))
     {
-        dce_alert(GID_DCE2, DCE2_CO_REM_FRAG_LEN_LT_SIZE,dce_common_stats);
+        dce_alert(GID_DCE2, DCE2_CO_REM_FRAG_LEN_LT_SIZE, dce_common_stats, *sd);
         return;
     }
 
@@ -936,7 +936,7 @@ static void DCE2_CoAlterCtx(DCE2_SsnData* sd, DCE2_CoTracker* cot,
 
     if (frag_len < sizeof(DceRpcCoAltCtx))
     {
-        dce_alert(GID_DCE2, DCE2_CO_REM_FRAG_LEN_LT_SIZE,dce_common_stats);
+        dce_alert(GID_DCE2, DCE2_CO_REM_FRAG_LEN_LT_SIZE, dce_common_stats, *sd);
         return;
     }
 
@@ -959,7 +959,8 @@ static void DCE2_CoAlterCtx(DCE2_SsnData* sd, DCE2_CoTracker* cot,
         {
             /* This is anomalous behavior.  Alert, but continue processing */
             if (cot->data_byte_order != DCE2_SENTINEL)
-                dce_alert(GID_DCE2, DCE2_CO_ALTER_CHANGE_BYTE_ORDER,dce_common_stats);
+                dce_alert(GID_DCE2, DCE2_CO_ALTER_CHANGE_BYTE_ORDER, dce_common_stats,
+                    *sd);
         }
 
         break;
@@ -996,7 +997,7 @@ static int DCE2_CoGetAuthLen(DCE2_SsnData* sd, const DceRpcCoHdr* co_hdr,
     /* This means the auth len was bogus */
     if (auth_len > frag_len)
     {
-        dce_alert(GID_DCE2, DCE2_CO_REM_FRAG_LEN_LT_SIZE,dce_common_stats);
+        dce_alert(GID_DCE2, DCE2_CO_REM_FRAG_LEN_LT_SIZE, dce_common_stats, *sd);
         return -1;
     }
 
@@ -1012,7 +1013,7 @@ static int DCE2_CoGetAuthLen(DCE2_SsnData* sd, const DceRpcCoHdr* co_hdr,
     /* This means the auth pad len was bogus */
     if (auth_len > frag_len)
     {
-        dce_alert(GID_DCE2, DCE2_CO_REM_FRAG_LEN_LT_SIZE,dce_common_stats);
+        dce_alert(GID_DCE2, DCE2_CO_REM_FRAG_LEN_LT_SIZE, dce_common_stats, *sd);
         return -1;
     }
 
@@ -1477,7 +1478,7 @@ static void DCE2_CoRequest(DCE2_SsnData* sd, DCE2_CoTracker* cot,
 
     if (frag_len < req_size)
     {
-        dce_alert(GID_DCE2, DCE2_CO_REM_FRAG_LEN_LT_SIZE,dce_common_stats);
+        dce_alert(GID_DCE2, DCE2_CO_REM_FRAG_LEN_LT_SIZE, dce_common_stats, *sd);
         return;
     }
 
@@ -1546,19 +1547,19 @@ static void DCE2_CoRequest(DCE2_SsnData* sd, DCE2_CoTracker* cot,
             if ((ft->expected_opnum != DCE2_SENTINEL) &&
                 (ft->expected_opnum != cot->opnum))
             {
-                dce_alert(GID_DCE2, DCE2_CO_FRAG_DIFF_OPNUM,dce_common_stats);
+                dce_alert(GID_DCE2, DCE2_CO_FRAG_DIFF_OPNUM, dce_common_stats, *sd);
             }
 
             if ((ft->expected_ctx_id != DCE2_SENTINEL) &&
                 (ft->expected_ctx_id != cot->ctx_id))
             {
-                dce_alert(GID_DCE2, DCE2_CO_FRAG_DIFF_CTX_ID,dce_common_stats);
+                dce_alert(GID_DCE2, DCE2_CO_FRAG_DIFF_CTX_ID, dce_common_stats, *sd);
             }
 
             if ((ft->expected_call_id != DCE2_SENTINEL) &&
                 (ft->expected_call_id != cot->call_id))
             {
-                dce_alert(GID_DCE2, DCE2_CO_FRAG_DIFF_CALL_ID,dce_common_stats);
+                dce_alert(GID_DCE2, DCE2_CO_FRAG_DIFF_CALL_ID, dce_common_stats, *sd);
             }
         }
 
@@ -1659,7 +1660,7 @@ static void DCE2_CoResponse(DCE2_SsnData* sd, DCE2_CoTracker* cot,
 
     if (frag_len < sizeof(DceRpcCoResponse))
     {
-        dce_alert(GID_DCE2, DCE2_CO_REM_FRAG_LEN_LT_SIZE,dce_common_stats);
+        dce_alert(GID_DCE2, DCE2_CO_REM_FRAG_LEN_LT_SIZE, dce_common_stats, *sd);
 
         return;
     }
index bcd873c903f2ebf8cbdc30c8e50119eff7492ac8..d68405b804555583cec044c2b3ba2430c69fce1b 100644 (file)
@@ -84,7 +84,10 @@ static const char* dce2_get_policy_name(DCE2_Policy policy)
 
 bool dce2_set_common_config(Value& v, dce2CommonProtoConf& common)
 {
-    if ( v.is("disable_defrag") )
+    if ( v.is("limit_alerts") )
+            common.limit_alerts = v.get_bool();
+
+    else if ( v.is("disable_defrag") )
         common.disable_defrag = v.get_bool();
 
     else if ( v.is("max_frag_len") )
@@ -115,6 +118,9 @@ bool dce2_set_co_config(Value& v, dce2CoProtoConf& co)
 
 void print_dce2_common_config(dce2CommonProtoConf& common)
 {
+    LogMessage("    One alert per flow: %s\n",
+        common.limit_alerts ?
+        "ENABLED" : "DISABLED");
     LogMessage("    Defragmentation: %s\n",
         common.disable_defrag ?
         "DISABLED" : "ENABLED");
index b43ba2c9bfcb37cf9a2d2189ee5eaeaa2959f1e1..cc1553a1c918630fa9fc638e80147427e8a3d114 100644 (file)
@@ -101,13 +101,14 @@ struct dce2CommonStats
 
 struct dce2CommonProtoConf
 {
+    bool limit_alerts;
     bool disable_defrag;
     int max_frag_len;
 };
 
 struct dce2CoProtoConf
 {
-    dce2CommonProtoConf common;
+    dce2CommonProtoConf common; // This member must be first
     DCE2_Policy policy;
     uint16_t co_reassemble_threshold;
 };
@@ -381,8 +382,15 @@ inline bool DCE2_SsnIsServerSambaPolicy(DCE2_SsnData* sd)
     return false;
 }
 
-inline void dce_alert(uint32_t gid, uint32_t sid, dce2CommonStats* stats)
+inline void dce_alert(uint32_t gid, uint32_t sid, dce2CommonStats* stats, DCE2_SsnData& sd)
 {
+    if ( ((dce2CommonProtoConf*)sd.config)->limit_alerts )
+    {
+        // Assuming the maximum sid for dce is less than 64
+        if ( sd.alert_mask & ((uint64_t)1 << sid) )
+            return;
+        sd.alert_mask |= ((uint64_t)1 << sid);
+    }
     snort::DetectionEngine::queue_event(gid,sid);
     stats->events++;
 }
index abb1f4fa9a80ce989a648d167b1298099ff830fe..0610b87610bf8604689576ca524538b97675f57d 100644 (file)
@@ -128,7 +128,8 @@ static inline void DCE2_Smb2StoreRequest(DCE2_SmbSsnData* ssd,
 
     if (ssd->outstanding_requests >= ssd->max_outstanding_requests)
     {
-        dce_alert(GID_DCE2, DCE2_SMB_MAX_REQS_EXCEEDED, (dce2CommonStats*)&dce2_smb_stats);
+        dce_alert(GID_DCE2, DCE2_SMB_MAX_REQS_EXCEEDED, (dce2CommonStats*)&dce2_smb_stats,
+            ssd->sd);
         snort_free((void*)request);
         return;
     }
@@ -491,7 +492,8 @@ static void DCE2_Smb2ReadRequest(DCE2_SmbSsnData* ssd, const Smb2Hdr* smb_hdr,
     }
     if (ssd->ftracker.tracker.file.file_size && (offset > ssd->ftracker.tracker.file.file_size))
     {
-        dce_alert(GID_DCE2, DCE2_SMB_INVALID_FILE_OFFSET, (dce2CommonStats*)&dce2_smb_stats);
+        dce_alert(GID_DCE2, DCE2_SMB_INVALID_FILE_OFFSET, (dce2CommonStats*)&dce2_smb_stats,
+            ssd->sd);
     }
 }
 
@@ -519,7 +521,7 @@ static void DCE2_Smb2ReadResponse(DCE2_SmbSsnData* ssd, const Smb2Hdr* smb_hdr,
     data_offset = alignedNtohs((const uint16_t*)(&(smb_read_hdr->data_offset)));
     if (data_offset + (const uint8_t*)smb_hdr > end)
     {
-        dce_alert(GID_DCE2, DCE2_SMB_BAD_OFF, (dce2CommonStats*)&dce2_smb_stats);
+        dce_alert(GID_DCE2, DCE2_SMB_BAD_OFF, (dce2CommonStats*)&dce2_smb_stats, ssd->sd);
     }
 
     ssd->ftracker.tracker.file.file_offset = request->offset;
@@ -597,13 +599,14 @@ static void DCE2_Smb2WriteRequest(DCE2_SmbSsnData* ssd, const Smb2Hdr* smb_hdr,
     data_offset = alignedNtohs((const uint16_t*)(&(smb_write_hdr->data_offset)));
     if (data_offset + (const uint8_t*)smb_hdr > end)
     {
-        dce_alert(GID_DCE2, DCE2_SMB_BAD_OFF, (dce2CommonStats*)&dce2_smb_stats);
+        dce_alert(GID_DCE2, DCE2_SMB_BAD_OFF, (dce2CommonStats*)&dce2_smb_stats, ssd->sd);
     }
 
     offset = alignedNtohq((const uint64_t*)(&(smb_write_hdr->offset)));
     if (ssd->ftracker.tracker.file.file_size && (offset > ssd->ftracker.tracker.file.file_size))
     {
-        dce_alert(GID_DCE2, DCE2_SMB_INVALID_FILE_OFFSET, (dce2CommonStats*)&dce2_smb_stats);
+        dce_alert(GID_DCE2, DCE2_SMB_INVALID_FILE_OFFSET, (dce2CommonStats*)&dce2_smb_stats,
+            ssd->sd);
     }
     ssd->ftracker.tracker.file.file_direction = DCE2_SMB_FILE_DIRECTION__UPLOAD;
     ssd->ftracker.tracker.file.file_offset = offset;
@@ -723,7 +726,7 @@ void DCE2_Smb2Process(DCE2_SmbSsnData* ssd)
         if (next_command_offset + sizeof(NbssHdr) > p->dsize)
         {
             dce_alert(GID_DCE2, DCE2_SMB_BAD_NEXT_COMMAND_OFFSET,
-                (dce2CommonStats*)&dce2_smb_stats);
+                (dce2CommonStats*)&dce2_smb_stats, ssd->sd);
         }
         DCE2_Smb2Inspect(ssd, smb_hdr, data_ptr +  data_len);
     }
index ff36d48e28dd6657c7f74f4e64b996f3de2a7e4b..b5333975909bfc6ef313f29a9874d9efa31d1ecc 100644 (file)
@@ -195,18 +195,22 @@ static DCE2_Ret DCE2_SmbWriteAndXRawRequest(DCE2_SmbSsnData*, const SmbNtHdr*,
  * Returns: None
  *
  ********************************************************************/
-static inline void DCE2_SmbCheckFmtData(DCE2_SmbSsnData*,
+static inline void DCE2_SmbCheckFmtData(DCE2_SmbSsnData* ssd,
     const uint32_t nb_len, const uint16_t bcc, const uint8_t fmt,
     const uint16_t com_dcnt, const uint16_t fmt_dcnt)
 {
     if (fmt != SMB_FMT__DATA_BLOCK)
-        dce_alert(GID_DCE2, DCE2_SMB_BAD_FORM, (dce2CommonStats*)&dce2_smb_stats);
+        dce_alert(GID_DCE2, DCE2_SMB_BAD_FORM, (dce2CommonStats*)&dce2_smb_stats,
+            ssd->sd);
     if (com_dcnt != fmt_dcnt)
-        dce_alert(GID_DCE2, DCE2_SMB_DCNT_MISMATCH, (dce2CommonStats*)&dce2_smb_stats);
+        dce_alert(GID_DCE2, DCE2_SMB_DCNT_MISMATCH, (dce2CommonStats*)&dce2_smb_stats,
+            ssd->sd);
     if (com_dcnt != (bcc - 3))
-        dce_alert(GID_DCE2, DCE2_SMB_INVALID_DSIZE, (dce2CommonStats*)&dce2_smb_stats);
+        dce_alert(GID_DCE2, DCE2_SMB_INVALID_DSIZE, (dce2CommonStats*)&dce2_smb_stats,
+            ssd->sd);
     if (nb_len < com_dcnt)
-        dce_alert(GID_DCE2, DCE2_SMB_NB_LT_DSIZE, (dce2CommonStats*)&dce2_smb_stats);
+        dce_alert(GID_DCE2, DCE2_SMB_NB_LT_DSIZE, (dce2CommonStats*)&dce2_smb_stats,
+            ssd->sd);
 }
 
 /********************************************************************
@@ -231,7 +235,7 @@ static inline void DCE2_SmbCheckFmtData(DCE2_SmbSsnData*,
  *              DCE2_RET__SUCCESS if data can be processed
  *
  ********************************************************************/
-static DCE2_Ret DCE2_SmbCheckData(DCE2_SmbSsnData*,
+static DCE2_Ret DCE2_SmbCheckData(DCE2_SmbSsnData* ssd,
     const uint8_t* smb_hdr_ptr, const uint8_t* nb_ptr,
     const uint32_t nb_len, const uint16_t bcc,
     const uint32_t dcnt, uint16_t doff)
@@ -244,11 +248,12 @@ static DCE2_Ret DCE2_SmbCheckData(DCE2_SmbSsnData*,
     // byte count can handle.  This can happen if CAP_LARGE_READX or
     // CAP_LARGE_WRITEX were negotiated.
     if ((dcnt <= UINT16_MAX) && (bcc < dcnt))
-        dce_alert(GID_DCE2, DCE2_SMB_BCC_LT_DSIZE, (dce2CommonStats*)&dce2_smb_stats);
+        dce_alert(GID_DCE2, DCE2_SMB_BCC_LT_DSIZE, (dce2CommonStats*)&dce2_smb_stats,
+            ssd->sd);
 
     if (offset > nb_end)
     {
-        dce_alert(GID_DCE2, DCE2_SMB_BAD_OFF, (dce2CommonStats*)&dce2_smb_stats);
+        dce_alert(GID_DCE2, DCE2_SMB_BAD_OFF, (dce2CommonStats*)&dce2_smb_stats, ssd->sd);
         // Error if offset is beyond data left
         return DCE2_RET__ERROR;
     }
@@ -258,7 +263,7 @@ static DCE2_Ret DCE2_SmbCheckData(DCE2_SmbSsnData*,
     {
         // Not necessarily and error if the offset puts the data
         // before or in the command structure.
-        dce_alert(GID_DCE2, DCE2_SMB_BAD_OFF, (dce2CommonStats*)&dce2_smb_stats);
+        dce_alert(GID_DCE2, DCE2_SMB_BAD_OFF, (dce2CommonStats*)&dce2_smb_stats, ssd->sd);
     }
 
     // Not necessarily an error if the addition of the data count goes
@@ -266,7 +271,8 @@ static DCE2_Ret DCE2_SmbCheckData(DCE2_SmbSsnData*,
 
     if (dcnt > (nb_end - offset))           // beyond data left
     {
-        dce_alert(GID_DCE2, DCE2_SMB_NB_LT_DSIZE, (dce2CommonStats*)&dce2_smb_stats);
+        dce_alert(GID_DCE2, DCE2_SMB_NB_LT_DSIZE, (dce2CommonStats*)&dce2_smb_stats,
+            ssd->sd);
     }
 
     return DCE2_RET__SUCCESS;
@@ -553,7 +559,8 @@ DCE2_Ret DCE2_SmbOpen(DCE2_SmbSsnData* ssd, const SmbNtHdr* smb_hdr,
 
         if (!SmbFmtAscii(*nb_ptr))
         {
-            dce_alert(GID_DCE2, DCE2_SMB_BAD_FORM, (dce2CommonStats*)&dce2_smb_stats);
+            dce_alert(GID_DCE2, DCE2_SMB_BAD_FORM, (dce2CommonStats*)&dce2_smb_stats,
+                ssd->sd);
             return DCE2_RET__ERROR;
         }
 
@@ -601,7 +608,7 @@ DCE2_Ret DCE2_SmbCreate(DCE2_SmbSsnData* ssd, const SmbNtHdr* smb_hdr,
 
             if (SmbEvasiveFileAttrs(file_attrs))
                 dce_alert(GID_DCE2, DCE2_SMB_EVASIVE_FILE_ATTRS,
-                    (dce2CommonStats*)&dce2_smb_stats);
+                    (dce2CommonStats*)&dce2_smb_stats, ssd->sd);
         }
 
         // Have at least 2 bytes of data based on byte count check done earlier
@@ -610,7 +617,8 @@ DCE2_Ret DCE2_SmbCreate(DCE2_SmbSsnData* ssd, const SmbNtHdr* smb_hdr,
 
         if (!SmbFmtAscii(*nb_ptr))
         {
-            dce_alert(GID_DCE2, DCE2_SMB_BAD_FORM, (dce2CommonStats*)&dce2_smb_stats);
+            dce_alert(GID_DCE2, DCE2_SMB_BAD_FORM, (dce2CommonStats*)&dce2_smb_stats,
+                ssd->sd);
             return DCE2_RET__ERROR;
         }
 
@@ -655,7 +663,7 @@ DCE2_Ret DCE2_SmbClose(DCE2_SmbSsnData* ssd, const SmbNtHdr*,
 }
 
 // SMB_COM_RENAME
-DCE2_Ret DCE2_SmbRename(DCE2_SmbSsnData*, const SmbNtHdr* smb_hdr,
+DCE2_Ret DCE2_SmbRename(DCE2_SmbSsnData* ssd, const SmbNtHdr* smb_hdr,
     const DCE2_SmbComInfo* com_info, const uint8_t* nb_ptr, uint32_t nb_len)
 {
     // NOTE: This command is only processed for CVE-2006-4696 where the buffer
@@ -674,7 +682,8 @@ DCE2_Ret DCE2_SmbRename(DCE2_SmbSsnData*, const SmbNtHdr* smb_hdr,
 
         if (!SmbFmtAscii(*nb_ptr))
         {
-            dce_alert(GID_DCE2, DCE2_SMB_BAD_FORM, (dce2CommonStats*)&dce2_smb_stats);
+            dce_alert(GID_DCE2, DCE2_SMB_BAD_FORM, (dce2CommonStats*)&dce2_smb_stats,
+                ssd->sd);
             return DCE2_RET__ERROR;
         }
 
@@ -708,7 +717,8 @@ DCE2_Ret DCE2_SmbRename(DCE2_SmbSsnData*, const SmbNtHdr* smb_hdr,
 
         if ((nb_len > 0) && !SmbFmtAscii(*nb_ptr))
         {
-            dce_alert(GID_DCE2, DCE2_SMB_BAD_FORM, (dce2CommonStats*)&dce2_smb_stats);
+            dce_alert(GID_DCE2, DCE2_SMB_BAD_FORM, (dce2CommonStats*)&dce2_smb_stats,
+                ssd->sd);
             return DCE2_RET__ERROR;
         }
     }
@@ -782,7 +792,8 @@ DCE2_Ret DCE2_SmbWrite(DCE2_SmbSsnData* ssd, const SmbNtHdr*,
 
         if (com_dcnt == 0)
         {
-            dce_alert(GID_DCE2, DCE2_SMB_DCNT_ZERO, (dce2CommonStats*)&dce2_smb_stats);
+            dce_alert(GID_DCE2, DCE2_SMB_DCNT_ZERO, (dce2CommonStats*)&dce2_smb_stats,
+                ssd->sd);
             return DCE2_RET__ERROR;
         }
 
@@ -828,7 +839,7 @@ DCE2_Ret DCE2_SmbCreateNew(DCE2_SmbSsnData* ssd, const SmbNtHdr* smb_hdr,
 
             if (SmbEvasiveFileAttrs(file_attrs))
                 dce_alert(GID_DCE2, DCE2_SMB_EVASIVE_FILE_ATTRS,
-                    (dce2CommonStats*)&dce2_smb_stats);
+                    (dce2CommonStats*)&dce2_smb_stats, ssd->sd);
         }
 
         // Have at least 2 bytes of data based on byte count check done earlier
@@ -837,7 +848,8 @@ DCE2_Ret DCE2_SmbCreateNew(DCE2_SmbSsnData* ssd, const SmbNtHdr* smb_hdr,
 
         if (!SmbFmtAscii(*nb_ptr))
         {
-            dce_alert(GID_DCE2, DCE2_SMB_BAD_FORM, (dce2CommonStats*)&dce2_smb_stats);
+            dce_alert(GID_DCE2, DCE2_SMB_BAD_FORM, (dce2CommonStats*)&dce2_smb_stats,
+                ssd->sd);
             return DCE2_RET__ERROR;
         }
 
@@ -889,7 +901,8 @@ DCE2_Ret DCE2_SmbLockAndRead(DCE2_SmbSsnData* ssd, const SmbNtHdr*,
 
         if (com_dcnt == 0)
         {
-            dce_alert(GID_DCE2, DCE2_SMB_DCNT_ZERO, (dce2CommonStats*)&dce2_smb_stats);
+            dce_alert(GID_DCE2, DCE2_SMB_DCNT_ZERO, (dce2CommonStats*)&dce2_smb_stats,
+                ssd->sd);
             return DCE2_RET__ERROR;
         }
 
@@ -945,7 +958,8 @@ DCE2_Ret DCE2_SmbWriteAndUnlock(DCE2_SmbSsnData* ssd, const SmbNtHdr* smb_hdr,
 
         if (com_dcnt == 0)
         {
-            dce_alert(GID_DCE2, DCE2_SMB_DCNT_ZERO, (dce2CommonStats*)&dce2_smb_stats);
+            dce_alert(GID_DCE2, DCE2_SMB_DCNT_ZERO, (dce2CommonStats*)&dce2_smb_stats,
+                ssd->sd);
             return DCE2_RET__ERROR;
         }
 
@@ -1035,7 +1049,7 @@ DCE2_Ret DCE2_SmbOpenAndX(DCE2_SmbSsnData* ssd, const SmbNtHdr* smb_hdr,
 
             if (SmbEvasiveFileAttrs(file_attrs))
                 dce_alert(GID_DCE2, DCE2_SMB_EVASIVE_FILE_ATTRS,
-                    (dce2CommonStats*)&dce2_smb_stats);
+                    (dce2CommonStats*)&dce2_smb_stats, ssd->sd);
             ssd->cur_rtracker->file_size = SmbOpenAndXReqAllocSize((const SmbOpenAndXReq*)nb_ptr);
         }
 
@@ -1564,7 +1578,8 @@ DCE2_Ret DCE2_SmbNegotiate(DCE2_SmbSsnData* ssd, const SmbNtHdr*,
         {
             if (!SmbFmtDialect(*nb_ptr))
             {
-                dce_alert(GID_DCE2, DCE2_SMB_BAD_FORM, (dce2CommonStats*)&dce2_smb_stats);
+                dce_alert(GID_DCE2, DCE2_SMB_BAD_FORM, (dce2CommonStats*)&dce2_smb_stats,
+                    ssd->sd);
 
                 // Windows errors if bad format
                 if (DCE2_SsnIsWindowsPolicy(&ssd->sd))
@@ -1601,7 +1616,7 @@ DCE2_Ret DCE2_SmbNegotiate(DCE2_SmbSsnData* ssd, const SmbNtHdr*,
         {
             ssd->dialect_index = DCE2_SENTINEL;
             dce_alert(GID_DCE2, DCE2_SMB_DEPR_DIALECT_NEGOTIATED,
-                (dce2CommonStats*)&dce2_smb_stats);
+                (dce2CommonStats*)&dce2_smb_stats, ssd->sd);
         }
     }
     else
@@ -1611,7 +1626,7 @@ DCE2_Ret DCE2_SmbNegotiate(DCE2_SmbSsnData* ssd, const SmbNtHdr*,
 
         if ((ssd->dialect_index != DCE2_SENTINEL) && (dialect_index != ssd->dialect_index))
             dce_alert(GID_DCE2, DCE2_SMB_DEPR_DIALECT_NEGOTIATED,
-                (dce2CommonStats*)&dce2_smb_stats);
+                (dce2CommonStats*)&dce2_smb_stats, ssd->sd);
 
         ssd->ssn_state_flags |= DCE2_SMB_SSN_STATE__NEGOTIATED;
 
@@ -1731,7 +1746,8 @@ DCE2_Ret DCE2_SmbTreeConnect(DCE2_SmbSsnData* ssd, const SmbNtHdr* smb_hdr,
         // This byte will realign things.
         if (*nb_ptr != SMB_FMT__ASCII)
         {
-            dce_alert(GID_DCE2, DCE2_SMB_BAD_FORM, (dce2CommonStats*)&dce2_smb_stats);
+            dce_alert(GID_DCE2, DCE2_SMB_BAD_FORM, (dce2CommonStats*)&dce2_smb_stats,
+                ssd->sd);
             return DCE2_RET__ERROR;
         }
 
@@ -1886,7 +1902,7 @@ DCE2_Ret DCE2_SmbNtCreateAndX(DCE2_SmbSsnData* ssd, const SmbNtHdr* smb_hdr,
 
             if (SmbEvasiveFileAttrs(ext_file_attrs))
                 dce_alert(GID_DCE2, DCE2_SMB_EVASIVE_FILE_ATTRS,
-                    (dce2CommonStats*)&dce2_smb_stats);
+                    (dce2CommonStats*)&dce2_smb_stats, ssd->sd);
             // If the file is going to be accessed sequentially, track it.
             if (SmbNtCreateAndXReqSequentialOnly((const SmbNtCreateAndXReq*)nb_ptr))
                 ssd->cur_rtracker->sequential_only = true;
@@ -2035,7 +2051,7 @@ DCE2_Ret DCE2_SmbWriteRaw(DCE2_SmbSsnData* ssd, const SmbNtHdr* smb_hdr,
 
         DCE2_MOVE(nb_ptr, nb_len, com_size);
 
-        if (DCE2_SmbCheckTotalCount(tdcnt, dcnt, 0) != DCE2_RET__SUCCESS)
+        if (DCE2_SmbCheckTotalCount(ssd, tdcnt, dcnt, 0) != DCE2_RET__SUCCESS)
             return DCE2_RET__ERROR;
 
         if (DCE2_SmbCheckData(ssd, (const uint8_t*)smb_hdr, nb_ptr, nb_len,
@@ -2047,7 +2063,8 @@ DCE2_Ret DCE2_SmbWriteRaw(DCE2_SmbSsnData* ssd, const SmbNtHdr* smb_hdr,
 
         if (dcnt > nb_len)
         {
-            dce_alert(GID_DCE2, DCE2_SMB_NB_LT_DSIZE, (dce2CommonStats*)&dce2_smb_stats);
+            dce_alert(GID_DCE2, DCE2_SMB_NB_LT_DSIZE, (dce2CommonStats*)&dce2_smb_stats,
+                ssd->sd);
             return DCE2_RET__ERROR;
         }
 
@@ -2129,13 +2146,15 @@ DCE2_Ret DCE2_SmbWriteAndClose(DCE2_SmbSsnData* ssd, const SmbNtHdr* smb_hdr,
 
         if (dcnt == 0)
         {
-            dce_alert(GID_DCE2, DCE2_SMB_DCNT_ZERO, (dce2CommonStats*)&dce2_smb_stats);
+            dce_alert(GID_DCE2, DCE2_SMB_DCNT_ZERO, (dce2CommonStats*)&dce2_smb_stats,
+                ssd->sd);
             return DCE2_RET__ERROR;
         }
 
         // WriteAndClose has a 1 byte pad after the byte count
         if ((uint32_t)(dcnt + 1) != (uint32_t)byte_count)
-            dce_alert(GID_DCE2, DCE2_SMB_INVALID_DSIZE, (dce2CommonStats*)&dce2_smb_stats);
+            dce_alert(GID_DCE2, DCE2_SMB_INVALID_DSIZE, (dce2CommonStats*)&dce2_smb_stats,
+                ssd->sd);
 
         if (dcnt > nb_len)
             dcnt = (uint16_t)nb_len;
index b727429307f17bd87c484aed1bbc63c1840f643a..9ccae11441df358fc10477a095df72a7bbac3d5c 100644 (file)
@@ -100,6 +100,9 @@ static const char* dce2SmbFingerprintPolicyStrings[] =
 
 static const Parameter s_params[] =
 {
+    { "limit_alerts", Parameter::PT_BOOL, nullptr, "true",
+      "limit DCE alert to at most one per signature per flow" },
+
     { "disable_defrag", Parameter::PT_BOOL, nullptr, "false",
       "disable DCE/RPC defragmentation" },
 
index e83d3d28b6373de0377ad8f2b890ea93cce10dc6..8c5588f9c81ebb742964a40bdb82cbe2559ffeb9 100644 (file)
@@ -55,7 +55,7 @@ struct dce2SmbShare
 
 struct dce2SmbProtoConf
 {
-    dce2CoProtoConf common;
+    dce2CoProtoConf common; // This member must be first
     dce2SmbFingerprintPolicy smb_fingerprint_policy;
     uint8_t smb_max_chain;
     uint8_t smb_max_compound;
index 68f13997d30714757faccaf1e46554509e8a3139..a2301904cde7aa07c90ec7b3cb369e55b4f95c1d 100644 (file)
@@ -261,7 +261,7 @@ static DCE2_Ret DCE2_SmbNtTransactCreateReq(DCE2_SmbSsnData* ssd,
 
         if (SmbEvasiveFileAttrs(ext_file_attrs))
             dce_alert(GID_DCE2, DCE2_SMB_EVASIVE_FILE_ATTRS,
-                (dce2CommonStats*)&dce2_smb_stats);
+                (dce2CommonStats*)&dce2_smb_stats, ssd->sd);
 
         // If the file is going to be accessed sequentially, track it.
         if (SmbNtTransactCreateReqSequentialOnly((const SmbNtTransactCreateReqParams*)param_ptr))
@@ -422,11 +422,11 @@ static DCE2_Ret DCE2_SmbUpdateTransSecondary(DCE2_SmbSsnData* ssd,
 
     DCE2_MOVE(nb_ptr, nb_len, com_size);
 
-    if (DCE2_SmbValidateTransactionFields((const uint8_t*)smb_hdr, nb_ptr, nb_len,
+    if (DCE2_SmbValidateTransactionFields(ssd, (const uint8_t*)smb_hdr, nb_ptr, nb_len,
         byte_count, tdcnt, tpcnt, dcnt, doff, ddisp, pcnt, poff, pdisp) != DCE2_RET__SUCCESS)
         return DCE2_RET__ERROR;
 
-    if (DCE2_SmbValidateTransactionSent(ttracker->dsent, dcnt, ttracker->tdcnt,
+    if (DCE2_SmbValidateTransactionSent(ssd, ttracker->dsent, dcnt, ttracker->tdcnt,
         ttracker->psent, pcnt, ttracker->tpcnt) != DCE2_RET__SUCCESS)
         return DCE2_RET__IGNORE;
 
@@ -534,7 +534,8 @@ static DCE2_Ret DCE2_SmbUpdateTransRequest(DCE2_SmbSsnData* ssd,
             break;
 
         case TRANS_READ_NMPIPE:
-            dce_alert(GID_DCE2, DCE2_SMB_UNUSUAL_COMMAND_USED, (dce2CommonStats*)&dce2_smb_stats);
+            dce_alert(GID_DCE2, DCE2_SMB_UNUSUAL_COMMAND_USED, (dce2CommonStats*)&dce2_smb_stats,
+                ssd->sd);
             break;
 
         case TRANS_SET_NMPIPE_STATE:
@@ -542,7 +543,8 @@ static DCE2_Ret DCE2_SmbUpdateTransRequest(DCE2_SmbSsnData* ssd,
             break;
 
         case TRANS_WRITE_NMPIPE:
-            dce_alert(GID_DCE2, DCE2_SMB_UNUSUAL_COMMAND_USED, (dce2CommonStats*)&dce2_smb_stats);
+            dce_alert(GID_DCE2, DCE2_SMB_UNUSUAL_COMMAND_USED, (dce2CommonStats*)&dce2_smb_stats,
+                ssd->sd);
             data_params = DCE2_SMB_TRANS__DATA;
             break;
 
@@ -554,7 +556,8 @@ static DCE2_Ret DCE2_SmbUpdateTransRequest(DCE2_SmbSsnData* ssd,
 
         // Can at most do a DCE/RPC bind
         case TRANS_CALL_NMPIPE:
-            dce_alert(GID_DCE2, DCE2_SMB_DEPR_COMMAND_USED, (dce2CommonStats*)&dce2_smb_stats);
+            dce_alert(GID_DCE2, DCE2_SMB_DEPR_COMMAND_USED, (dce2CommonStats*)&dce2_smb_stats,
+                ssd->sd);
             // fallthrough
 
         // Aren't looking at these or the three above
@@ -570,7 +573,8 @@ static DCE2_Ret DCE2_SmbUpdateTransRequest(DCE2_SmbSsnData* ssd,
         // Servers return error if incorrect setup count
         if (setup_count != 2)
         {
-            dce_alert(GID_DCE2, DCE2_SMB_INVALID_SETUP_COUNT, (dce2CommonStats*)&dce2_smb_stats);
+            dce_alert(GID_DCE2, DCE2_SMB_INVALID_SETUP_COUNT, (dce2CommonStats*)&dce2_smb_stats,
+                ssd->sd);
             return DCE2_RET__ERROR;
         }
 
@@ -602,7 +606,8 @@ static DCE2_Ret DCE2_SmbUpdateTransRequest(DCE2_SmbSsnData* ssd,
         switch (sub_com)
         {
         case TRANS2_OPEN2:
-            dce_alert(GID_DCE2, DCE2_SMB_UNUSUAL_COMMAND_USED, (dce2CommonStats*)&dce2_smb_stats);
+            dce_alert(GID_DCE2, DCE2_SMB_UNUSUAL_COMMAND_USED, (dce2CommonStats*)&dce2_smb_stats,
+                ssd->sd);
             data_params = DCE2_SMB_TRANS__PARAMS;
             break;
         case TRANS2_QUERY_FILE_INFORMATION:
@@ -632,7 +637,8 @@ static DCE2_Ret DCE2_SmbUpdateTransRequest(DCE2_SmbSsnData* ssd,
 
         if (setup_count != 1)
         {
-            dce_alert(GID_DCE2, DCE2_SMB_INVALID_SETUP_COUNT, (dce2CommonStats*)&dce2_smb_stats);
+            dce_alert(GID_DCE2, DCE2_SMB_INVALID_SETUP_COUNT, (dce2CommonStats*)&dce2_smb_stats,
+                ssd->sd);
             return DCE2_RET__ERROR;
         }
 
@@ -653,11 +659,12 @@ static DCE2_Ret DCE2_SmbUpdateTransRequest(DCE2_SmbSsnData* ssd,
         switch (sub_com)
         {
         case NT_TRANSACT_CREATE:
-            dce_alert(GID_DCE2, DCE2_SMB_UNUSUAL_COMMAND_USED, (dce2CommonStats*)&dce2_smb_stats);
+            dce_alert(GID_DCE2, DCE2_SMB_UNUSUAL_COMMAND_USED, (dce2CommonStats*)&dce2_smb_stats,
+                ssd->sd);
             if (setup_count != 0)
             {
                 dce_alert(GID_DCE2, DCE2_SMB_INVALID_SETUP_COUNT,
-                    (dce2CommonStats*)&dce2_smb_stats);
+                    (dce2CommonStats*)&dce2_smb_stats, ssd->sd);
                 return DCE2_RET__ERROR;
             }
             data_params = DCE2_SMB_TRANS__PARAMS;
@@ -680,7 +687,7 @@ static DCE2_Ret DCE2_SmbUpdateTransRequest(DCE2_SmbSsnData* ssd,
         return DCE2_RET__ERROR;
     }
 
-    if (DCE2_SmbValidateTransactionFields((const uint8_t*)smb_hdr, nb_ptr, nb_len,
+    if (DCE2_SmbValidateTransactionFields(ssd, (const uint8_t*)smb_hdr, nb_ptr, nb_len,
         byte_count, tdcnt, tpcnt, dcnt, doff, 0, pcnt, poff, 0) != DCE2_RET__SUCCESS)
         return DCE2_RET__ERROR;
 
@@ -701,7 +708,8 @@ static DCE2_Ret DCE2_SmbUpdateTransRequest(DCE2_SmbSsnData* ssd,
     if (data_params & DCE2_SMB_TRANS__DATA)
     {
         if (tdcnt == 0)
-            dce_alert(GID_DCE2, DCE2_SMB_DCNT_ZERO, (dce2CommonStats*)&dce2_smb_stats);
+            dce_alert(GID_DCE2, DCE2_SMB_DCNT_ZERO, (dce2CommonStats*)&dce2_smb_stats,
+                ssd->sd);
 
         DCE2_MOVE(nb_ptr, nb_len, ((const uint8_t*)smb_hdr + doff) - nb_ptr);
 
@@ -717,7 +725,8 @@ static DCE2_Ret DCE2_SmbUpdateTransRequest(DCE2_SmbSsnData* ssd,
     if (data_params & DCE2_SMB_TRANS__PARAMS)
     {
         if (tpcnt == 0)
-            dce_alert(GID_DCE2, DCE2_SMB_DCNT_ZERO, (dce2CommonStats*)&dce2_smb_stats);
+            dce_alert(GID_DCE2, DCE2_SMB_DCNT_ZERO, (dce2CommonStats*)&dce2_smb_stats,
+                ssd->sd);
 
         DCE2_MOVE(nb_ptr, nb_len, ((const uint8_t*)smb_hdr + poff) - nb_ptr);
 
@@ -869,12 +878,12 @@ static DCE2_Ret DCE2_SmbUpdateTransResponse(DCE2_SmbSsnData* ssd,
             ttracker->tpcnt = pcnt;
     }
 
-    if (DCE2_SmbValidateTransactionFields((const uint8_t*)smb_hdr, nb_ptr, nb_len,
+    if (DCE2_SmbValidateTransactionFields(ssd, (const uint8_t*)smb_hdr, nb_ptr, nb_len,
         DCE2_ComInfoByteCount(com_info), tdcnt, tpcnt, dcnt, doff, ddisp,
         pcnt, poff, pdisp) != DCE2_RET__SUCCESS)
         return DCE2_RET__ERROR;
 
-    if (DCE2_SmbValidateTransactionSent(ttracker->dsent, dcnt, ttracker->tdcnt,
+    if (DCE2_SmbValidateTransactionSent(ssd, ttracker->dsent, dcnt, ttracker->tdcnt,
         ttracker->psent, pcnt, ttracker->tpcnt) != DCE2_RET__SUCCESS)
         return DCE2_RET__ERROR;
 
@@ -938,7 +947,7 @@ static DCE2_Ret DCE2_SmbTrans2Open2Req(DCE2_SmbSsnData* ssd,
 
         if (SmbEvasiveFileAttrs(file_attrs))
             dce_alert(GID_DCE2, DCE2_SMB_EVASIVE_FILE_ATTRS,
-                (dce2CommonStats*)&dce2_smb_stats);
+                (dce2CommonStats*)&dce2_smb_stats, ssd->sd);
 
         ssd->cur_rtracker->file_size =
             SmbTrans2Open2ReqAllocSize((const SmbTrans2Open2ReqParams*)param_ptr);
@@ -1003,7 +1012,7 @@ static DCE2_Ret DCE2_SmbTrans2SetFileInfoReq(DCE2_SmbSsnData* ssd,
 
         if (SmbEvasiveFileAttrs(ext_file_attrs))
             dce_alert(GID_DCE2, DCE2_SMB_EVASIVE_FILE_ATTRS,
-                (dce2CommonStats*)&dce2_smb_stats);
+                (dce2CommonStats*)&dce2_smb_stats, ssd->sd);
 
         // Don't need to see the response
         return DCE2_RET__IGNORE;
index 4d3f5d528b1d5d4e6082fdf9e63cd940ee6eac2b..3303ee05316c4316102b7c5c65c7d7ebe56bb87b 100644 (file)
@@ -105,6 +105,7 @@ static const DCE2_SmbFsm dce2_samba_pipe_fsm[] =
  *  though it's currently not checked.
  *
  * Arguments:
+ *  DCE2_SmbSsnData * - pointer to SMB flow data
  *  const uint8_t *   - pointer to start of SMB header where offset is
  *                      taken from.
  *  const uint8_t *   - current pointer - should be right after command
@@ -122,7 +123,7 @@ static const DCE2_SmbFsm dce2_samba_pipe_fsm[] =
  *
  ********************************************************************/
 static DCE2_Ret DCE2_SmbCheckTransDataParams(
-    const uint8_t* smb_hdr_ptr, const uint8_t* nb_ptr, const uint32_t nb_len,
+    DCE2_SmbSsnData* ssd, const uint8_t* smb_hdr_ptr, const uint8_t* nb_ptr, const uint32_t nb_len,
     const uint16_t bcc, const uint32_t dcnt, const uint32_t doff,
     const uint32_t pcnt, const uint32_t poff)
 {
@@ -131,13 +132,14 @@ static DCE2_Ret DCE2_SmbCheckTransDataParams(
     const uint8_t* nb_end = nb_ptr + nb_len;
 
     if (bcc < ((uint64_t)dcnt + pcnt))
-        dce_alert(GID_DCE2, DCE2_SMB_BCC_LT_DSIZE, (dce2CommonStats*)&dce2_smb_stats);
+        dce_alert(GID_DCE2, DCE2_SMB_BCC_LT_DSIZE, (dce2CommonStats*)&dce2_smb_stats,
+            ssd->sd);
 
     // Check data offset out of bounds
     if ((doffset > nb_end) || (doffset < smb_hdr_ptr))
     {
         // Beyond data left or wrap
-        dce_alert(GID_DCE2, DCE2_SMB_BAD_OFF, (dce2CommonStats*)&dce2_smb_stats);
+        dce_alert(GID_DCE2, DCE2_SMB_BAD_OFF, (dce2CommonStats*)&dce2_smb_stats, ssd->sd);
         return DCE2_RET__ERROR;
     }
 
@@ -147,12 +149,13 @@ static DCE2_Ret DCE2_SmbCheckTransDataParams(
     {
         // Not necessarily and error if the offset puts the data
         // before or in the command structure.
-        dce_alert(GID_DCE2, DCE2_SMB_BAD_OFF, (dce2CommonStats*)&dce2_smb_stats);
+        dce_alert(GID_DCE2, DCE2_SMB_BAD_OFF, (dce2CommonStats*)&dce2_smb_stats, ssd->sd);
     }
 
     if (dcnt > (nb_end - doffset))            // beyond data left
     {
-        dce_alert(GID_DCE2, DCE2_SMB_NB_LT_DSIZE, (dce2CommonStats*)&dce2_smb_stats);
+        dce_alert(GID_DCE2, DCE2_SMB_NB_LT_DSIZE, (dce2CommonStats*)&dce2_smb_stats,
+            ssd->sd);
         return DCE2_RET__ERROR;
     }
 
@@ -160,7 +163,7 @@ static DCE2_Ret DCE2_SmbCheckTransDataParams(
     if ((poffset > nb_end) || (poffset < smb_hdr_ptr))
     {
         // Beyond data left or wrap
-        dce_alert(GID_DCE2, DCE2_SMB_BAD_OFF, (dce2CommonStats*)&dce2_smb_stats);
+        dce_alert(GID_DCE2, DCE2_SMB_BAD_OFF, (dce2CommonStats*)&dce2_smb_stats, ssd->sd);
         return DCE2_RET__ERROR;
     }
 
@@ -170,12 +173,13 @@ static DCE2_Ret DCE2_SmbCheckTransDataParams(
     {
         // Not necessarily and error if the offset puts the data
         // before or in the command structure.
-        dce_alert(GID_DCE2, DCE2_SMB_BAD_OFF, (dce2CommonStats*)&dce2_smb_stats);
+        dce_alert(GID_DCE2, DCE2_SMB_BAD_OFF, (dce2CommonStats*)&dce2_smb_stats, ssd->sd);
     }
 
     if (pcnt > (nb_end - poffset))            // beyond data left
     {
-        dce_alert(GID_DCE2, DCE2_SMB_NB_LT_DSIZE, (dce2CommonStats*)&dce2_smb_stats);
+        dce_alert(GID_DCE2, DCE2_SMB_NB_LT_DSIZE, (dce2CommonStats*)&dce2_smb_stats,
+            ssd->sd);
         return DCE2_RET__ERROR;
     }
 
@@ -193,6 +197,7 @@ static DCE2_Ret DCE2_SmbCheckTransDataParams(
  *  Transaction and Transaction Secondary commands.
  *
  * Arguments:
+ *  DCE2_SmbSsnData * - pointer to SMB flow data
  *  const uint32_t    - total data count
  *  const uint32_t    - data count/size
  *  const uint32_t    - data displacement
@@ -202,20 +207,22 @@ static DCE2_Ret DCE2_SmbCheckTransDataParams(
  *             DCE2_RET__ERROR if any of the checks fail.
  *
  ********************************************************************/
-DCE2_Ret DCE2_SmbCheckTotalCount(const uint32_t tcnt, const uint32_t cnt, const uint32_t
-    disp)
+DCE2_Ret DCE2_SmbCheckTotalCount(DCE2_SmbSsnData* ssd, const uint32_t tcnt, const uint32_t cnt,
+    const uint32_t disp)
 {
     DCE2_Ret ret = DCE2_RET__SUCCESS;
 
     if (cnt > tcnt)
     {
-        dce_alert(GID_DCE2, DCE2_SMB_TDCNT_LT_DSIZE, (dce2CommonStats*)&dce2_smb_stats);
+        dce_alert(GID_DCE2, DCE2_SMB_TDCNT_LT_DSIZE, (dce2CommonStats*)&dce2_smb_stats,
+            ssd->sd);
         ret = DCE2_RET__ERROR;
     }
 
     if (((uint64_t)disp + cnt) > tcnt)
     {
-        dce_alert(GID_DCE2, DCE2_SMB_DSENT_GT_TDCNT, (dce2CommonStats*)&dce2_smb_stats);
+        dce_alert(GID_DCE2, DCE2_SMB_DSENT_GT_TDCNT, (dce2CommonStats*)&dce2_smb_stats,
+            ssd->sd);
         ret = DCE2_RET__ERROR;
     }
 
@@ -272,6 +279,7 @@ DCE2_Ret DCE2_SmbTransactionGetName(const uint8_t* nb_ptr,
  *  the total count expected.
  *
  * Arguments:
+ *  DCE2_SmbSsnData * - pointer to SMB flow data
  *  const uint32_t    - amount of data sent so far
  *  const uint32_t    - reported total data count
  *  const uint32_t    - reported data count
@@ -285,19 +293,21 @@ DCE2_Ret DCE2_SmbTransactionGetName(const uint8_t* nb_ptr,
  *
  ********************************************************************/
 DCE2_Ret DCE2_SmbValidateTransactionSent(
-    uint32_t dsent, uint32_t dcnt, uint32_t tdcnt,
+    DCE2_SmbSsnData* ssd, uint32_t dsent, uint32_t dcnt, uint32_t tdcnt,
     uint32_t psent, uint32_t pcnt, uint32_t tpcnt)
 {
     if (((dsent + dcnt) > tdcnt) || ((psent + pcnt) > tpcnt))
     {
         if ((dsent + dcnt) > tdcnt)
         {
-            dce_alert(GID_DCE2, DCE2_SMB_DSENT_GT_TDCNT, (dce2CommonStats*)&dce2_smb_stats);
+            dce_alert(GID_DCE2, DCE2_SMB_DSENT_GT_TDCNT, (dce2CommonStats*)&dce2_smb_stats,
+                ssd->sd);
         }
 
         if ((psent + pcnt) > tpcnt)
         {
-            dce_alert(GID_DCE2, DCE2_SMB_DSENT_GT_TDCNT, (dce2CommonStats*)&dce2_smb_stats);
+            dce_alert(GID_DCE2, DCE2_SMB_DSENT_GT_TDCNT, (dce2CommonStats*)&dce2_smb_stats,
+                ssd->sd);
         }
 
         // Samba throws out entire transaction and Windows seems to hang in
@@ -316,6 +326,7 @@ DCE2_Ret DCE2_SmbValidateTransactionSent(
  *  count and total data count and DCE2_SmbCheckTransDataParams()
  *
  * Arguments:
+ *  DCE2_SmbSsnData * - pointer to SMB flow data
  *  const uint8_t *   - pointer to start of SMB header where offset is
  *                      taken from.
  *  const uint8_t *   - current pointer - should be right after command
@@ -337,19 +348,19 @@ DCE2_Ret DCE2_SmbValidateTransactionSent(
  *
  ********************************************************************/
 DCE2_Ret DCE2_SmbValidateTransactionFields(
-    const uint8_t* smb_hdr_ptr,
+    DCE2_SmbSsnData* ssd, const uint8_t* smb_hdr_ptr,
     const uint8_t* nb_ptr, const uint32_t nb_len, const uint16_t bcc,
     const uint32_t tdcnt, const uint32_t tpcnt,
     const uint32_t dcnt, const uint32_t doff, const uint32_t ddisp,
     const uint32_t pcnt, const uint32_t poff, const uint32_t pdisp)
 {
-    if (DCE2_SmbCheckTotalCount(tdcnt, dcnt, ddisp) != DCE2_RET__SUCCESS)
+    if (DCE2_SmbCheckTotalCount(ssd, tdcnt, dcnt, ddisp) != DCE2_RET__SUCCESS)
         return DCE2_RET__ERROR;
 
-    if (DCE2_SmbCheckTotalCount(tpcnt, pcnt, pdisp) != DCE2_RET__SUCCESS)
+    if (DCE2_SmbCheckTotalCount(ssd, tpcnt, pcnt, pdisp) != DCE2_RET__SUCCESS)
         return DCE2_RET__ERROR;
 
-    if (DCE2_SmbCheckTransDataParams(smb_hdr_ptr,
+    if (DCE2_SmbCheckTransDataParams(ssd, smb_hdr_ptr,
         nb_ptr, nb_len, bcc, dcnt, doff, pcnt, poff) != DCE2_RET__SUCCESS)
         return DCE2_RET__ERROR;
 
index ba2173a00e99f4bb0976d3432cdd7cc31156ddb4..b21758dfe815a7f439bda933af95de996732a187 100644 (file)
@@ -28,14 +28,14 @@ DCE2_Ret DCE2_SmbTransactionGetName(const uint8_t* nb_ptr,
     uint32_t nb_len, uint16_t bcc, bool unicode);
 
 DCE2_Ret DCE2_SmbValidateTransactionFields(
-    const uint8_t* smb_hdr_ptr,
+    DCE2_SmbSsnData* ssd, const uint8_t* smb_hdr_ptr,
     const uint8_t* nb_ptr, const uint32_t nb_len, const uint16_t bcc,
     const uint32_t tdcnt, const uint32_t tpcnt,
     const uint32_t dcnt, const uint32_t doff, const uint32_t ddisp,
     const uint32_t pcnt, const uint32_t poff, const uint32_t pdisp);
 
 DCE2_Ret DCE2_SmbValidateTransactionSent(
-    uint32_t dsent, uint32_t dcnt, uint32_t tdcnt,
+    DCE2_SmbSsnData* ssd, uint32_t dsent, uint32_t dcnt, uint32_t tdcnt,
     uint32_t psent, uint32_t pcnt, uint32_t tpcnt);
 
 DCE2_Ret DCE2_SmbBufferTransactionData(DCE2_SmbTransactionTracker* ttracker,
@@ -44,8 +44,8 @@ DCE2_Ret DCE2_SmbBufferTransactionData(DCE2_SmbTransactionTracker* ttracker,
 DCE2_Ret DCE2_SmbBufferTransactionParameters(DCE2_SmbTransactionTracker* ttracker,
     const uint8_t* param_ptr, uint16_t pcnt, uint16_t pdisp);
 
-DCE2_Ret DCE2_SmbCheckTotalCount(const uint32_t tcnt, const uint32_t cnt, const uint32_t
-    disp);
+DCE2_Ret DCE2_SmbCheckTotalCount(DCE2_SmbSsnData* ssd, const uint32_t tcnt, const uint32_t cnt,
+    const uint32_t disp);
 
 inline bool DCE2_SmbFileUpload(DCE2_SmbFileDirection dir)
 {
index 7374fc3ad28a9cf051f65124da2af9de1bd0db97..f44bba82e4baca01b55b40bffe1a4f2fd7f52942 100644 (file)
@@ -270,7 +270,8 @@ DCE2_SmbRequestTracker* DCE2_SmbNewRequestTracker(DCE2_SmbSsnData* ssd,
 
     if (ssd->outstanding_requests >= ssd->max_outstanding_requests)
     {
-        dce_alert(GID_DCE2, DCE2_SMB_MAX_REQS_EXCEEDED, (dce2CommonStats*)&dce2_smb_stats);
+        dce_alert(GID_DCE2, DCE2_SMB_MAX_REQS_EXCEEDED, (dce2CommonStats*)&dce2_smb_stats,
+            ssd->sd);
     }
 
     // Check for outstanding requests with the same MID
@@ -281,7 +282,8 @@ DCE2_SmbRequestTracker* DCE2_SmbNewRequestTracker(DCE2_SmbSsnData* ssd,
         {
             // Have yet to see an MID repeatedly used so shouldn't
             // be any outstanding requests with the same MID.
-            dce_alert(GID_DCE2, DCE2_SMB_REQS_SAME_MID, (dce2CommonStats*)&dce2_smb_stats);
+            dce_alert(GID_DCE2, DCE2_SMB_REQS_SAME_MID, (dce2CommonStats*)&dce2_smb_stats,
+                ssd->sd);
             break;
         }
 
@@ -967,7 +969,8 @@ void DCE2_SmbInvalidShareCheck(DCE2_SmbSsnData* ssd,
         if (i == share_str_len)
         {
             /* Should only match one share since no duplicate shares in list */
-            dce_alert(GID_DCE2, DCE2_SMB_INVALID_SHARE, (dce2CommonStats*)&dce2_smb_stats);
+            dce_alert(GID_DCE2, DCE2_SMB_INVALID_SHARE, (dce2CommonStats*)&dce2_smb_stats,
+                ssd->sd);
             break;
         }
     }
@@ -1362,7 +1365,7 @@ void DCE2_SmbSegAlert(DCE2_SmbSsnData* ssd, uint32_t rule_id)
     if (rpkt == nullptr)
         return;
 
-    dce_alert(GID_DCE2, rule_id, (dce2CommonStats*)&dce2_smb_stats);
+    dce_alert(GID_DCE2, rule_id, (dce2CommonStats*)&dce2_smb_stats, ssd->sd);
 }
 
 static void DCE2_SmbResetFileChunks(DCE2_SmbFileTracker* ftracker)
index 9f226da27dcb8a5f8b8e78edbb75ad49a4adebbf..3015ac2a027538c1d8211d68133173893cad6222 100644 (file)
@@ -33,6 +33,9 @@ using namespace std;
 
 static const Parameter s_params[] =
 {
+    { "limit_alerts", Parameter::PT_BOOL, nullptr, "true",
+      "limit DCE alert to at most one per signature per flow" },
+
     { "disable_defrag", Parameter::PT_BOOL, nullptr, "false",
       "disable DCE/RPC defragmentation" },
 
index d2967bca445881513e230cd1650fbb9529124a44..eb0ce79fd1e9d2602d9077d0dcc9b97c2f81a028 100644 (file)
@@ -35,6 +35,9 @@ Trace TRACE_NAME(dce_udp);
 
 static const Parameter s_params[] =
 {
+    { "limit_alerts", Parameter::PT_BOOL, nullptr, "true",
+      "limit DCE alert to at most one per signature per flow" },
+
     { "disable_defrag", Parameter::PT_BOOL, nullptr, "false",
       "disable DCE/RPC defragmentation" },
 
index d96496e337d46316f1a6e94397181dc3200bc28b..840033fdc834fa1f3fe1ed62c3aa733b3e944e91 100644 (file)
@@ -112,7 +112,7 @@ void DCE2_ClProcess(DCE2_SsnData* sd, DCE2_ClTracker* clt)
 
     if (data_len < sizeof(DceRpcClHdr))
     {
-        dce_alert(GID_DCE2,  DCE2_CL_DATA_LT_HDR, (dce2CommonStats*)&dce2_udp_stats);
+        dce_alert(GID_DCE2,  DCE2_CL_DATA_LT_HDR, (dce2CommonStats*)&dce2_udp_stats, *sd);
         return;
     }
 
@@ -219,17 +219,17 @@ void DCE2_ClProcess(DCE2_SsnData* sd, DCE2_ClTracker* clt)
 // alert on the header anomaly.  If we've autodetected the session,
 // however, don't alert, but set a header anomaly flag, so we can
 // re-autodetect on the next go around.
-static DCE2_Ret DCE2_ClHdrChecks(DCE2_SsnData*, const DceRpcClHdr* cl_hdr)
+static DCE2_Ret DCE2_ClHdrChecks(DCE2_SsnData* sd, const DceRpcClHdr* cl_hdr)
 {
     if (DceRpcClRpcVers(cl_hdr) != DCERPC_PROTO_MAJOR_VERS__4)
     {
-        dce_alert(GID_DCE2, DCE2_CL_BAD_MAJOR_VERSION, (dce2CommonStats*)&dce2_udp_stats);
+        dce_alert(GID_DCE2, DCE2_CL_BAD_MAJOR_VERSION, (dce2CommonStats*)&dce2_udp_stats, *sd);
         return DCE2_RET__ERROR;
     }
 
     if (DceRpcClPduType(cl_hdr) >= DCERPC_PDU_TYPE__MAX)
     {
-        dce_alert(GID_DCE2, DCE2_CL_BAD_PDU_TYPE, (dce2CommonStats*)&dce2_udp_stats);
+        dce_alert(GID_DCE2, DCE2_CL_BAD_PDU_TYPE, (dce2CommonStats*)&dce2_udp_stats, *sd);
         return DCE2_RET__ERROR;
     }
 
index 08a28432f55d9930ee7b0645cbbf92625c6dec39..cc11fba40f1490c2880f2fd2649e9fa1769371a4 100644 (file)
@@ -82,6 +82,7 @@ static inline bool DCE2_SmbIsRawData(DCE2_SmbSsnData* ssd)
  *  data we have to work with.
  *
  * Arguments:
+ *  DCE2_SmbSsnData * - pointer to SMB flow data
  *  uint8_t * - pointer to where the offset would take us.
  *  uint8_t * - pointer to bound offset
  *  uint8_t * - length of data where offset should be within
@@ -91,15 +92,15 @@ static inline bool DCE2_SmbIsRawData(DCE2_SmbSsnData* ssd)
  *  DCE2_RET__ERROR   - Offset is bad.
  *
  ********************************************************************/
-static inline DCE2_Ret DCE2_SmbCheckAndXOffset(const uint8_t* off_ptr, const uint8_t* start_bound,
-    const uint32_t length)
+static inline DCE2_Ret DCE2_SmbCheckAndXOffset(DCE2_SmbSsnData* ssd, const uint8_t* off_ptr,
+    const uint8_t* start_bound, const uint32_t length)
 {
     /* Offset should not point within data we just looked at or be equal to
      * or beyond the length of the NBSS length left */
     if ((off_ptr < start_bound) ||
         (off_ptr > (start_bound + length)))
     {
-        dce_alert(GID_DCE2, DCE2_SMB_BAD_OFF, (dce2CommonStats*)&dce2_smb_stats);
+        dce_alert(GID_DCE2, DCE2_SMB_BAD_OFF, (dce2CommonStats*)&dce2_smb_stats, ssd->sd);
 
         return DCE2_RET__ERROR;
     }
@@ -395,7 +396,8 @@ static DCE2_Ret DCE2_SmbHdrChecks(DCE2_SmbSsnData* ssd, const SmbNtHdr* smb_hdr)
         if (is_seg_buf)
             DCE2_SmbSegAlert(ssd, DCE2_SMB_BAD_TYPE);
         else
-            dce_alert(GID_DCE2, DCE2_SMB_BAD_TYPE, (dce2CommonStats*)&dce2_smb_stats);
+            dce_alert(GID_DCE2, DCE2_SMB_BAD_TYPE, (dce2CommonStats*)&dce2_smb_stats,
+                ssd->sd);
 
         // Continue looking at traffic.  Neither Windows nor Samba seem
         // to care, or even look at this flag
@@ -407,7 +409,8 @@ static DCE2_Ret DCE2_SmbHdrChecks(DCE2_SmbSsnData* ssd, const SmbNtHdr* smb_hdr)
         if (is_seg_buf)
             DCE2_SmbSegAlert(ssd, DCE2_SMB_BAD_ID);
         else
-            dce_alert(GID_DCE2, DCE2_SMB_BAD_ID, (dce2CommonStats*)&dce2_smb_stats);
+            dce_alert(GID_DCE2, DCE2_SMB_BAD_ID, (dce2CommonStats*)&dce2_smb_stats,
+                ssd->sd);
 
         return DCE2_RET__IGNORE;
     }
@@ -593,7 +596,8 @@ static void DCE2_SmbCheckCommand(DCE2_SmbSsnData* ssd,
         // Verify there is enough data to do checks
         if (nb_len < sizeof(SmbEmptyCom))
         {
-            dce_alert(GID_DCE2, DCE2_SMB_NB_LT_COM, (dce2CommonStats*)&dce2_smb_stats);
+            dce_alert(GID_DCE2, DCE2_SMB_NB_LT_COM, (dce2CommonStats*)&dce2_smb_stats,
+                ssd->sd);
             com_info.cmd_error |= DCE2_SMB_COM_ERROR__BAD_LENGTH;
             return;
         }
@@ -627,7 +631,8 @@ static void DCE2_SmbCheckCommand(DCE2_SmbSsnData* ssd,
     // Verify there is enough data to do checks
     if (nb_len < (uint32_t)chk_com_size)
     {
-        dce_alert(GID_DCE2, DCE2_SMB_NB_LT_COM, (dce2CommonStats*)&dce2_smb_stats);
+        dce_alert(GID_DCE2, DCE2_SMB_NB_LT_COM, (dce2CommonStats*)&dce2_smb_stats,
+            ssd->sd);
         com_info.cmd_error |= DCE2_SMB_COM_ERROR__BAD_LENGTH;
         return;
     }
@@ -640,7 +645,7 @@ static void DCE2_SmbCheckCommand(DCE2_SmbSsnData* ssd,
     // won't lie on data correctly and out of bounds data accesses are possible.
     if (!DCE2_SmbIsValidWordCount(smb_com, (uint8_t)com_info.smb_type, com_info.word_count))
     {
-        dce_alert(GID_DCE2, DCE2_SMB_BAD_WCT, (dce2CommonStats*)&dce2_smb_stats);
+        dce_alert(GID_DCE2, DCE2_SMB_BAD_WCT, (dce2CommonStats*)&dce2_smb_stats, ssd->sd);
         com_info.cmd_error |= DCE2_SMB_COM_ERROR__INVALID_WORD_COUNT;
         return;
     }
@@ -650,7 +655,8 @@ static void DCE2_SmbCheckCommand(DCE2_SmbSsnData* ssd,
     com_info.cmd_size = (uint16_t)SMB_COM_SIZE(com_info.word_count);
     if (nb_len < com_info.cmd_size)
     {
-        dce_alert(GID_DCE2, DCE2_SMB_NB_LT_COM, (dce2CommonStats*)&dce2_smb_stats);
+        dce_alert(GID_DCE2, DCE2_SMB_NB_LT_COM, (dce2CommonStats*)&dce2_smb_stats,
+            ssd->sd);
         com_info.cmd_error |= DCE2_SMB_COM_ERROR__BAD_LENGTH;
         return;
     }
@@ -677,7 +683,8 @@ static void DCE2_SmbCheckCommand(DCE2_SmbSsnData* ssd,
         {
             if (smb_bcc != 0)
             {
-                dce_alert(GID_DCE2, DCE2_SMB_BAD_BCC, (dce2CommonStats*)&dce2_smb_stats);
+                dce_alert(GID_DCE2, DCE2_SMB_BAD_BCC, (dce2CommonStats*)&dce2_smb_stats,
+                    ssd->sd);
                 com_info.cmd_error |= DCE2_SMB_COM_ERROR__INVALID_BYTE_COUNT;
             }
             break;
@@ -686,7 +693,8 @@ static void DCE2_SmbCheckCommand(DCE2_SmbSsnData* ssd,
     default:
         if (!DCE2_SmbIsValidByteCount(smb_com, (uint8_t)com_info.smb_type, smb_bcc))
         {
-            dce_alert(GID_DCE2, DCE2_SMB_BAD_BCC, (dce2CommonStats*)&dce2_smb_stats);
+            dce_alert(GID_DCE2, DCE2_SMB_BAD_BCC, (dce2CommonStats*)&dce2_smb_stats,
+                ssd->sd);
             com_info.cmd_error |= DCE2_SMB_COM_ERROR__INVALID_BYTE_COUNT;
         }
         break;
@@ -698,7 +706,8 @@ static void DCE2_SmbCheckCommand(DCE2_SmbSsnData* ssd,
     // Validate that there is enough data to be able to process the command
     if (nb_len < DCE2_SmbGetMinByteCount(smb_com, (uint8_t)com_info.smb_type))
     {
-        dce_alert(GID_DCE2, DCE2_SMB_NB_LT_BCC, (dce2CommonStats*)&dce2_smb_stats);
+        dce_alert(GID_DCE2, DCE2_SMB_NB_LT_BCC, (dce2CommonStats*)&dce2_smb_stats,
+            ssd->sd);
         com_info.cmd_error |= DCE2_SMB_COM_ERROR__BAD_LENGTH;
     }
 
@@ -708,7 +717,8 @@ static void DCE2_SmbCheckCommand(DCE2_SmbSsnData* ssd,
     // !!!WARNING!!! the byte count should probably never be used.
     if (smb_bcc > nb_len)
     {
-        dce_alert(GID_DCE2, DCE2_SMB_NB_LT_BCC, (dce2CommonStats*)&dce2_smb_stats);
+        dce_alert(GID_DCE2, DCE2_SMB_NB_LT_BCC, (dce2CommonStats*)&dce2_smb_stats,
+            ssd->sd);
         // Large byte count doesn't seem to matter for early Samba
         switch (DCE2_SsnGetPolicy(&ssd->sd))
         {
@@ -780,12 +790,14 @@ static void DCE2_SmbProcessCommand(DCE2_SmbSsnData* ssd, const SmbNtHdr* smb_hdr
 
         if (smb_deprecated_coms[smb_com])
         {
-            dce_alert(GID_DCE2, DCE2_SMB_DEPR_COMMAND_USED, (dce2CommonStats*)&dce2_smb_stats);
+            dce_alert(GID_DCE2, DCE2_SMB_DEPR_COMMAND_USED, (dce2CommonStats*)&dce2_smb_stats,
+                ssd->sd);
         }
 
         if (smb_unusual_coms[smb_com])
         {
-            dce_alert(GID_DCE2, DCE2_SMB_UNUSUAL_COMMAND_USED, (dce2CommonStats*)&dce2_smb_stats);
+            dce_alert(GID_DCE2, DCE2_SMB_UNUSUAL_COMMAND_USED, (dce2CommonStats*)&dce2_smb_stats,
+                ssd->sd);
         }
 
         DCE2_SmbComInfo com_info;
@@ -828,7 +840,8 @@ static void DCE2_SmbProcessCommand(DCE2_SmbSsnData* ssd, const SmbNtHdr* smb_hdr
         if (DCE2_ScSmbMaxChain((dce2SmbProtoConf*)ssd->sd.config) &&
             (num_chained >= DCE2_ScSmbMaxChain((dce2SmbProtoConf*)ssd->sd.config)))
         {
-            dce_alert(GID_DCE2, DCE2_SMB_EXCESSIVE_CHAINING, (dce2CommonStats*)&dce2_smb_stats);
+            dce_alert(GID_DCE2, DCE2_SMB_EXCESSIVE_CHAINING, (dce2CommonStats*)&dce2_smb_stats,
+                ssd->sd);
         }
 
         // Multiple SessionSetupAndX, TreeConnectAndX, OpenAndX and NtCreateAndX
@@ -840,7 +853,8 @@ static void DCE2_SmbProcessCommand(DCE2_SmbSsnData* ssd, const SmbNtHdr* smb_hdr
         if ((smb_com2 == SMB_COM_SESSION_SETUP_ANDX) && sess_chain)
         {
             // There is only one place to return a uid.
-            dce_alert(GID_DCE2, DCE2_SMB_MULT_CHAIN_SS, (dce2CommonStats*)&dce2_smb_stats);
+            dce_alert(GID_DCE2, DCE2_SMB_MULT_CHAIN_SS, (dce2CommonStats*)&dce2_smb_stats,
+                ssd->sd);
             // FIXIT-L Should we continue processing?
             break;
         }
@@ -850,7 +864,8 @@ static void DCE2_SmbProcessCommand(DCE2_SmbSsnData* ssd, const SmbNtHdr* smb_hdr
         {
             // This essentially deletes the uid created by the login
             // and doesn't make any sense.
-            dce_alert(GID_DCE2, DCE2_SMB_CHAIN_SS_LOGOFF, (dce2CommonStats*)&dce2_smb_stats);
+            dce_alert(GID_DCE2, DCE2_SMB_CHAIN_SS_LOGOFF, (dce2CommonStats*)&dce2_smb_stats,
+                ssd->sd);
         }
 
         if (smb_com == SMB_COM_TREE_CONNECT_ANDX)
@@ -861,7 +876,8 @@ static void DCE2_SmbProcessCommand(DCE2_SmbSsnData* ssd, const SmbNtHdr* smb_hdr
             || (smb_com2 == SMB_COM_TREE_CONNECT)) && tree_chain)
         {
             // There is only one place to return a tid.
-            dce_alert(GID_DCE2, DCE2_SMB_MULT_CHAIN_TC, (dce2CommonStats*)&dce2_smb_stats);
+            dce_alert(GID_DCE2, DCE2_SMB_MULT_CHAIN_TC, (dce2CommonStats*)&dce2_smb_stats,
+                ssd->sd);
             // FIXIT-L Should we continue processing?
             break;
         }
@@ -871,7 +887,8 @@ static void DCE2_SmbProcessCommand(DCE2_SmbSsnData* ssd, const SmbNtHdr* smb_hdr
         {
             // This essentially deletes the tid created by the tree connect
             // and doesn't make any sense.
-            dce_alert(GID_DCE2, DCE2_SMB_CHAIN_TC_TDIS, (dce2CommonStats*)&dce2_smb_stats);
+            dce_alert(GID_DCE2, DCE2_SMB_CHAIN_TC_TDIS, (dce2CommonStats*)&dce2_smb_stats,
+                ssd->sd);
         }
 
         if ((smb_com == SMB_COM_OPEN_ANDX) || (smb_com == SMB_COM_NT_CREATE_ANDX))
@@ -882,7 +899,8 @@ static void DCE2_SmbProcessCommand(DCE2_SmbSsnData* ssd, const SmbNtHdr* smb_hdr
         {
             // This essentially deletes the fid created by the open command
             // and doesn't make any sense.
-            dce_alert(GID_DCE2, DCE2_SMB_CHAIN_OPEN_CLOSE, (dce2CommonStats*)&dce2_smb_stats);
+            dce_alert(GID_DCE2, DCE2_SMB_CHAIN_OPEN_CLOSE, (dce2CommonStats*)&dce2_smb_stats,
+                ssd->sd);
         }
 
         // Check that policy allows for such chaining
@@ -894,7 +912,7 @@ static void DCE2_SmbProcessCommand(DCE2_SmbSsnData* ssd, const SmbNtHdr* smb_hdr
 
         // FIXIT-L Need to test out of order chaining
         const uint8_t* off2_ptr = (const uint8_t*)smb_hdr + SmbAndXOff2(andx_ptr);
-        if (DCE2_SmbCheckAndXOffset(off2_ptr, nb_ptr, nb_len) != DCE2_RET__SUCCESS)
+        if (DCE2_SmbCheckAndXOffset(ssd, off2_ptr, nb_ptr, nb_len) != DCE2_RET__SUCCESS)
             break;
 
         DCE2_MOVE(nb_ptr, nb_len, (off2_ptr - nb_ptr));
@@ -1036,7 +1054,7 @@ static DCE2_SmbRequestTracker* DCE2_SmbInspect(DCE2_SmbSsnData* ssd, const SmbNt
             if (ssd->ssn_state_flags & DCE2_SMB_SSN_STATE__NEGOTIATED)
             {
                 dce_alert(GID_DCE2, DCE2_SMB_MULTIPLE_NEGOTIATIONS,
-                    (dce2CommonStats*)&dce2_smb_stats);
+                    (dce2CommonStats*)&dce2_smb_stats, ssd->sd);
                 return nullptr;
             }
             break;
@@ -1179,7 +1197,8 @@ static void DCE2_SmbProcessRawData(DCE2_SmbSsnData* ssd, const uint8_t* nb_ptr,
     {
         if (nb_len > ssd->cur_rtracker->writeraw_remaining)
         {
-            dce_alert(GID_DCE2, DCE2_SMB_TDCNT_LT_DSIZE, (dce2CommonStats*)&dce2_smb_stats);
+            dce_alert(GID_DCE2, DCE2_SMB_TDCNT_LT_DSIZE, (dce2CommonStats*)&dce2_smb_stats,
+                ssd->sd);
 
             // If this happens, Windows never responds regardless of
             // WriteThrough flag, so get rid of request tracker
@@ -1390,7 +1409,8 @@ static DCE2_Ret DCE2_NbssHdrChecks(DCE2_SmbSsnData* ssd, const NbssHdr* nb_hdr)
                 if (is_seg_buf)
                     DCE2_SmbSegAlert(ssd, DCE2_SMB_NB_LT_SMBHDR);
                 else
-                    dce_alert(GID_DCE2, DCE2_SMB_NB_LT_SMBHDR, (dce2CommonStats*)&dce2_smb_stats);
+                    dce_alert(GID_DCE2, DCE2_SMB_NB_LT_SMBHDR, (dce2CommonStats*)&dce2_smb_stats,
+                        ssd->sd);
 
                 return DCE2_RET__IGNORE;
             }
@@ -1404,7 +1424,8 @@ static DCE2_Ret DCE2_NbssHdrChecks(DCE2_SmbSsnData* ssd, const NbssHdr* nb_hdr)
             if (is_seg_buf)
                 DCE2_SmbSegAlert(ssd, DCE2_SMB_BAD_NBSS_TYPE);
             else
-                dce_alert(GID_DCE2, DCE2_SMB_BAD_NBSS_TYPE, (dce2CommonStats*)&dce2_smb_stats);
+                dce_alert(GID_DCE2, DCE2_SMB_BAD_NBSS_TYPE, (dce2CommonStats*)&dce2_smb_stats,
+                    ssd->sd);
         }
 
         break;
@@ -1417,7 +1438,8 @@ static DCE2_Ret DCE2_NbssHdrChecks(DCE2_SmbSsnData* ssd, const NbssHdr* nb_hdr)
             if (is_seg_buf)
                 DCE2_SmbSegAlert(ssd, DCE2_SMB_BAD_NBSS_TYPE);
             else
-                dce_alert(GID_DCE2, DCE2_SMB_BAD_NBSS_TYPE, (dce2CommonStats*)&dce2_smb_stats);
+                dce_alert(GID_DCE2, DCE2_SMB_BAD_NBSS_TYPE, (dce2CommonStats*)&dce2_smb_stats,
+                    ssd->sd);
         }
 
         break;
@@ -1429,7 +1451,8 @@ static DCE2_Ret DCE2_NbssHdrChecks(DCE2_SmbSsnData* ssd, const NbssHdr* nb_hdr)
         if (is_seg_buf)
             DCE2_SmbSegAlert(ssd, DCE2_SMB_BAD_NBSS_TYPE);
         else
-            dce_alert(GID_DCE2, DCE2_SMB_BAD_NBSS_TYPE, (dce2CommonStats*)&dce2_smb_stats);
+            dce_alert(GID_DCE2, DCE2_SMB_BAD_NBSS_TYPE, (dce2CommonStats*)&dce2_smb_stats,
+                ssd->sd);
 
         return DCE2_RET__ERROR;
     }