From: Mike Stepanek (mstepane) Date: Mon, 28 Jan 2019 15:32:54 +0000 (-0500) Subject: Merge pull request #1491 in SNORT/snort3 from ~MASHASAN/snort3:dce_alert_once to... X-Git-Tag: 3.0.0-251~60 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cd42c152e9738e912fc369059c1610ca859654f0;p=thirdparty%2Fsnort3.git Merge pull request #1491 in SNORT/snort3 from ~MASHASAN/snort3:dce_alert_once to master Squashed commit of the following: commit a8c8665b06181ab0dad9979787d2455d2e1b1731 Author: Masud Hasan Date: Thu Jan 17 15:31:35 2019 -0500 dce_rpc: Limiting each signature alert to once per session using 'limit_alerts' config --- diff --git a/src/service_inspectors/dce_rpc/dce_co.cc b/src/service_inspectors/dce_rpc/dce_co.cc index 6494be375..6a1c206c8 100644 --- a/src/service_inspectors/dce_rpc/dce_co.cc +++ b/src/service_inspectors/dce_rpc/dce_co.cc @@ -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; } diff --git a/src/service_inspectors/dce_rpc/dce_common.cc b/src/service_inspectors/dce_rpc/dce_common.cc index bcd873c90..d68405b80 100644 --- a/src/service_inspectors/dce_rpc/dce_common.cc +++ b/src/service_inspectors/dce_rpc/dce_common.cc @@ -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"); diff --git a/src/service_inspectors/dce_rpc/dce_common.h b/src/service_inspectors/dce_rpc/dce_common.h index b43ba2c9b..cc1553a1c 100644 --- a/src/service_inspectors/dce_rpc/dce_common.h +++ b/src/service_inspectors/dce_rpc/dce_common.h @@ -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++; } diff --git a/src/service_inspectors/dce_rpc/dce_smb2.cc b/src/service_inspectors/dce_rpc/dce_smb2.cc index abb1f4fa9..0610b8761 100644 --- a/src/service_inspectors/dce_rpc/dce_smb2.cc +++ b/src/service_inspectors/dce_rpc/dce_smb2.cc @@ -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); } diff --git a/src/service_inspectors/dce_rpc/dce_smb_commands.cc b/src/service_inspectors/dce_rpc/dce_smb_commands.cc index ff36d48e2..b53339759 100644 --- a/src/service_inspectors/dce_rpc/dce_smb_commands.cc +++ b/src/service_inspectors/dce_rpc/dce_smb_commands.cc @@ -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; diff --git a/src/service_inspectors/dce_rpc/dce_smb_module.cc b/src/service_inspectors/dce_rpc/dce_smb_module.cc index b72742930..9ccae1144 100644 --- a/src/service_inspectors/dce_rpc/dce_smb_module.cc +++ b/src/service_inspectors/dce_rpc/dce_smb_module.cc @@ -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" }, diff --git a/src/service_inspectors/dce_rpc/dce_smb_module.h b/src/service_inspectors/dce_rpc/dce_smb_module.h index e83d3d28b..8c5588f9c 100644 --- a/src/service_inspectors/dce_rpc/dce_smb_module.h +++ b/src/service_inspectors/dce_rpc/dce_smb_module.h @@ -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; diff --git a/src/service_inspectors/dce_rpc/dce_smb_transaction.cc b/src/service_inspectors/dce_rpc/dce_smb_transaction.cc index 68f13997d..a2301904c 100644 --- a/src/service_inspectors/dce_rpc/dce_smb_transaction.cc +++ b/src/service_inspectors/dce_rpc/dce_smb_transaction.cc @@ -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; diff --git a/src/service_inspectors/dce_rpc/dce_smb_transaction_utils.cc b/src/service_inspectors/dce_rpc/dce_smb_transaction_utils.cc index 4d3f5d528..3303ee053 100644 --- a/src/service_inspectors/dce_rpc/dce_smb_transaction_utils.cc +++ b/src/service_inspectors/dce_rpc/dce_smb_transaction_utils.cc @@ -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; diff --git a/src/service_inspectors/dce_rpc/dce_smb_transaction_utils.h b/src/service_inspectors/dce_rpc/dce_smb_transaction_utils.h index ba2173a00..b21758dfe 100644 --- a/src/service_inspectors/dce_rpc/dce_smb_transaction_utils.h +++ b/src/service_inspectors/dce_rpc/dce_smb_transaction_utils.h @@ -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) { diff --git a/src/service_inspectors/dce_rpc/dce_smb_utils.cc b/src/service_inspectors/dce_rpc/dce_smb_utils.cc index 7374fc3ad..f44bba82e 100644 --- a/src/service_inspectors/dce_rpc/dce_smb_utils.cc +++ b/src/service_inspectors/dce_rpc/dce_smb_utils.cc @@ -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) diff --git a/src/service_inspectors/dce_rpc/dce_tcp_module.cc b/src/service_inspectors/dce_rpc/dce_tcp_module.cc index 9f226da27..3015ac2a0 100644 --- a/src/service_inspectors/dce_rpc/dce_tcp_module.cc +++ b/src/service_inspectors/dce_rpc/dce_tcp_module.cc @@ -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" }, diff --git a/src/service_inspectors/dce_rpc/dce_udp_module.cc b/src/service_inspectors/dce_rpc/dce_udp_module.cc index d2967bca4..eb0ce79fd 100644 --- a/src/service_inspectors/dce_rpc/dce_udp_module.cc +++ b/src/service_inspectors/dce_rpc/dce_udp_module.cc @@ -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" }, diff --git a/src/service_inspectors/dce_rpc/dce_udp_processing.cc b/src/service_inspectors/dce_rpc/dce_udp_processing.cc index d96496e33..840033fdc 100644 --- a/src/service_inspectors/dce_rpc/dce_udp_processing.cc +++ b/src/service_inspectors/dce_rpc/dce_udp_processing.cc @@ -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; } diff --git a/src/service_inspectors/dce_rpc/smb_message.cc b/src/service_inspectors/dce_rpc/smb_message.cc index 08a28432f..cc11fba40 100644 --- a/src/service_inspectors/dce_rpc/smb_message.cc +++ b/src/service_inspectors/dce_rpc/smb_message.cc @@ -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; }