detect/dce: fix false positives in detection

If a signature didn't explicitly specified 'dcerpc' or 'smb' as the
app proto, false positives on other traffic could happen. This was
caused by the sig not having a app_proto set. This isn't set as the
rule is supposed to match against either ALPROTO_DCERPC or ALPROTO_SMB.

To avoid adding runtime costs for checking for both protocols, this
patch adds a new flag for DCERPC in the 'mask' logic. The flag is set
on the sig if dce_* keywords are present and set on the packet if the
flow's app proto is either ALPROTO_DCERPC or ALPROTO_SMB.

Bug #2559

Reported-by: Jason Taylor
pull/3440/head
Victor Julien 7 years ago
parent 8547d113bf
commit a2b8ea57fc

@ -427,12 +427,49 @@ PacketCreateMask(Packet *p, SignatureMask *mask, AppProto alproto,
SCLogDebug("packet has flow");
(*mask) |= SIG_MASK_REQUIRE_FLOW;
}
if (alproto == ALPROTO_SMB || alproto == ALPROTO_DCERPC) {
SCLogDebug("packet will be inspected for DCERPC");
(*mask) |= SIG_MASK_REQUIRE_DCERPC;
}
}
static int g_dce_generic_list_id = -1;
static int g_dce_stub_data_buffer_id = -1;
static bool SignatureNeedsDCERPCMask(const Signature *s)
{
if (g_dce_generic_list_id == -1) {
g_dce_generic_list_id = DetectBufferTypeGetByName("dce_generic");
SCLogDebug("g_dce_generic_list_id %d", g_dce_generic_list_id);
}
if (g_dce_stub_data_buffer_id == -1) {
g_dce_stub_data_buffer_id = DetectBufferTypeGetByName("dce_stub_data");
SCLogDebug("g_dce_stub_data_buffer_id %d", g_dce_stub_data_buffer_id);
}
if (g_dce_generic_list_id >= 0 &&
s->init_data->smlists[g_dce_generic_list_id] != NULL)
{
return true;
}
if (g_dce_stub_data_buffer_id >= 0 &&
s->init_data->smlists[g_dce_stub_data_buffer_id] != NULL)
{
return true;
}
return false;
}
static int SignatureCreateMask(Signature *s)
{
SCEnter();
if (SignatureNeedsDCERPCMask(s)) {
s->mask |= SIG_MASK_REQUIRE_DCERPC;
SCLogDebug("sig requires DCERPC");
}
if (s->init_data->smlists[DETECT_SM_LIST_PMATCH] != NULL) {
s->mask |= SIG_MASK_REQUIRE_PAYLOAD;
SCLogDebug("sig requires payload");

@ -371,7 +371,7 @@ DetectPrefilterBuildNonPrefilterList(DetectEngineThreadCtx *det_ctx, SignatureMa
* so build the non_mpm array only for match candidates */
const SignatureMask rule_mask = det_ctx->non_pf_store_ptr[x].mask;
const uint8_t rule_alproto = det_ctx->non_pf_store_ptr[x].alproto;
if ((rule_mask & mask) == rule_mask && (rule_alproto == 0 || rule_alproto == alproto)) { // TODO dce?
if ((rule_mask & mask) == rule_mask && (rule_alproto == 0 || rule_alproto == alproto)) {
det_ctx->non_pf_id_array[det_ctx->non_pf_id_cnt++] = det_ctx->non_pf_store_ptr[x].id;
}
}

@ -266,7 +266,7 @@ typedef struct DetectPort_ {
#define SIG_MASK_REQUIRE_FLAGS_INITDEINIT (1<<2) /* SYN, FIN, RST */
#define SIG_MASK_REQUIRE_FLAGS_UNUSUAL (1<<3) /* URG, ECN, CWR */
#define SIG_MASK_REQUIRE_NO_PAYLOAD (1<<4)
//
#define SIG_MASK_REQUIRE_DCERPC (1<<5) /* require either SMB+DCE or raw DCE */
#define SIG_MASK_REQUIRE_ENGINE_EVENT (1<<7)
/* for now a uint8_t is enough */

Loading…
Cancel
Save