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;
{
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;
{
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;
{
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;
{
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)
* 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 */
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;
}
/* 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;
}
{
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;
}
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;
}
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;
}
/* 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;
}
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;
}
/* 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;
}
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;
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;
}
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;
}
{
/* 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;
/* 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;
}
/* 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;
}
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;
}
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);
}
}
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;
}
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") )
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");
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;
};
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++;
}
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;
}
}
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);
}
}
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;
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;
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);
}
* 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);
}
/********************************************************************
* 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)
// 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;
}
{
// 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
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;
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;
}
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
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;
}
}
// 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
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;
}
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;
}
}
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;
}
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
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;
}
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;
}
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;
}
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);
}
{
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))
{
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
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;
// 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;
}
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;
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,
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;
}
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;
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" },
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;
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))
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;
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:
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;
// 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
// 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;
}
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:
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;
}
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;
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;
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);
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);
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;
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);
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;
* 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
*
********************************************************************/
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)
{
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;
}
{
// 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;
}
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;
}
{
// 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;
}
* 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
* 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;
}
* 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
*
********************************************************************/
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
* 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
*
********************************************************************/
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;
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,
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)
{
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
{
// 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;
}
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;
}
}
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)
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" },
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" },
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;
}
// 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;
}
* 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
* 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;
}
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
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;
}
// 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;
}
// 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;
}
// 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;
}
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;
}
{
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;
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;
// 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;
}
// !!!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))
{
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;
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
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;
}
{
// 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)
|| (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;
}
{
// 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))
{
// 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
// 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));
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;
{
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
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;
}
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;
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;
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;
}