From: Michael Altizer (mialtize) Date: Wed, 16 Nov 2016 16:48:51 +0000 (-0500) Subject: Merge pull request #703 in SNORT/snort3 from autodetect to master X-Git-Tag: 3.0.0-233~191 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a5c585520c1180c0d9b938a4ee7f72a5e105bfc5;p=thirdparty%2Fsnort3.git Merge pull request #703 in SNORT/snort3 from autodetect to master Squashed commit of the following: commit 2c97fdb0fe074450a90770565c9441cb6dd84623 Author: mdagon Date: Wed Nov 2 08:04:19 2016 -0400 dce wizard --- diff --git a/lua/snort_defaults.lua b/lua/snort_defaults.lua index bc98c0fd6..8b0458705 100644 --- a/lua/snort_defaults.lua +++ b/lua/snort_defaults.lua @@ -445,9 +445,6 @@ default_wizard = }, hexes = { - { service = 'dcerpc', proto = 'tcp', client_first = true, - to_server = { '|05 00|' }, to_client = { '|05 00|' } }, - { service = 'dnp3', proto = 'tcp', client_first = true, to_server = { '|05 64|' }, to_client = { '|05 64|' } }, @@ -461,18 +458,15 @@ default_wizard = to_server = { '????|0 0 0 0 0 0 0 1|' }, to_client = { '????|0 0 0 0 0 0 0 1|' } }, --]] - { service = 'smb', proto = 'tcp', client_first = true, - to_server = { '|FF|SMB' }, to_client = { '|FF|SMB' } }, - - { service = 'smb', proto = 'udp', client_first = true, - to_server = { '|FF|SMB' }, to_client = { '|FF|SMB' } }, { service = 'ssl', proto = 'tcp', client_first = true, to_server = { '|16 03|' }, to_client = { '|16 03|' } }, { service = 'telnet', proto = 'tcp', client_first = true, to_server = telnet_commands, to_client = telnet_commands }, - } + }, + + curses = {'dce_udp', 'dce_tcp', 'dce_smb'} } --------------------------------------------------------------------------- diff --git a/src/service_inspectors/dce_rpc/dce_co.cc b/src/service_inspectors/dce_rpc/dce_co.cc index 1fd323f82..45ed502e0 100644 --- a/src/service_inspectors/dce_rpc/dce_co.cc +++ b/src/service_inspectors/dce_rpc/dce_co.cc @@ -359,9 +359,9 @@ static DCE2_Ret DCE2_CoHdrChecks(DCE2_SsnData* sd, DCE2_CoTracker* cot, const Dc if (frag_len < sizeof(DceRpcCoHdr)) { - /* Assume we autodetected incorrectly or that DCE/RPC is not running + /* Assume that DCE/RPC is not running * over the SMB named pipe */ - if (!DCE2_SsnAutodetected(sd) && (sd->trans != DCE2_TRANS_TYPE__SMB)) + 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); @@ -372,7 +372,7 @@ static DCE2_Ret DCE2_CoHdrChecks(DCE2_SsnData* sd, DCE2_CoTracker* cot, const Dc if (DceRpcCoVersMaj(co_hdr) != DCERPC_PROTO_MAJOR_VERS__5) { - if (!DCE2_SsnAutodetected(sd) && (sd->trans != DCE2_TRANS_TYPE__SMB)) + if (sd->trans != DCE2_TRANS_TYPE__SMB) { dce_alert(GID_DCE2, DCE2_CO_BAD_MAJOR_VERSION,dce_common_stats); } @@ -382,7 +382,7 @@ static DCE2_Ret DCE2_CoHdrChecks(DCE2_SsnData* sd, DCE2_CoTracker* cot, const Dc if (DceRpcCoVersMin(co_hdr) != DCERPC_PROTO_MINOR_VERS__0) { - if (!DCE2_SsnAutodetected(sd) && (sd->trans != DCE2_TRANS_TYPE__SMB)) + if (sd->trans != DCE2_TRANS_TYPE__SMB) { dce_alert(GID_DCE2, DCE2_CO_BAD_MINOR_VERSION,dce_common_stats); } @@ -391,7 +391,7 @@ static DCE2_Ret DCE2_CoHdrChecks(DCE2_SsnData* sd, DCE2_CoTracker* cot, const Dc } if (pdu_type >= DCERPC_PDU_TYPE__MAX) { - if (!DCE2_SsnAutodetected(sd) && (sd->trans != DCE2_TRANS_TYPE__SMB)) + if (sd->trans != DCE2_TRANS_TYPE__SMB) { dce_alert(GID_DCE2, DCE2_CO_BAD_PDU_TYPE,dce_common_stats); } diff --git a/src/service_inspectors/dce_rpc/dce_common.h b/src/service_inspectors/dce_rpc/dce_common.h index 047ed5ff9..f868a3d98 100644 --- a/src/service_inspectors/dce_rpc/dce_common.h +++ b/src/service_inspectors/dce_rpc/dce_common.h @@ -58,9 +58,6 @@ enum DCE2_Policy struct dce2CommonStats { PegCount events; - PegCount sessions_aborted; - PegCount bad_autodetects; - PegCount co_pdus; PegCount co_bind; PegCount co_bind_ack; @@ -190,9 +187,8 @@ struct DCE2_Roptions enum DCE2_SsnFlag { DCE2_SSN_FLAG__NONE = 0x0000, - DCE2_SSN_FLAG__AUTODETECTED = 0x0001, - DCE2_SSN_FLAG__NO_INSPECT = 0x0002, - DCE2_SSN_FLAG__SMB2 = 0x0004, + DCE2_SSN_FLAG__NO_INSPECT = 0x0001, + DCE2_SSN_FLAG__SMB2 = 0x0002, DCE2_SSN_FLAG__ALL = 0xffff }; @@ -205,7 +201,6 @@ struct DCE2_SsnData Packet* wire_pkt; uint64_t alert_mask; DCE2_Roptions ropts; - int autodetect_dir; void* config; uint32_t cli_seq; @@ -234,28 +229,6 @@ inline void DCE2_ResetRopts(DCE2_Roptions* ropts) ropts->stub_data = nullptr; } -inline void DCE2_SsnSetAutodetected(DCE2_SsnData* sd, Packet* p) -{ - sd->flags |= DCE2_SSN_FLAG__AUTODETECTED; - sd->autodetect_dir = p->packet_flags & (PKT_FROM_CLIENT | PKT_FROM_SERVER); -} - -inline int DCE2_SsnAutodetectDir(DCE2_SsnData* sd) -{ - return sd->autodetect_dir; -} - -inline int DCE2_SsnAutodetected(DCE2_SsnData* sd) -{ - return sd->flags & DCE2_SSN_FLAG__AUTODETECTED; -} - -inline void DCE2_SsnClearAutodetected(DCE2_SsnData* sd) -{ - sd->flags &= ~DCE2_SSN_FLAG__AUTODETECTED; - sd->autodetect_dir = 0; -} - inline void DCE2_SsnSetNoInspect(DCE2_SsnData* sd) { sd->flags |= DCE2_SSN_FLAG__NO_INSPECT; diff --git a/src/service_inspectors/dce_rpc/dce_smb.cc b/src/service_inspectors/dce_rpc/dce_smb.cc index 4d2522c46..24690c7a1 100644 --- a/src/service_inspectors/dce_rpc/dce_smb.cc +++ b/src/service_inspectors/dce_rpc/dce_smb.cc @@ -348,7 +348,6 @@ static void DCE2_SmbCheckCommand(DCE2_SmbSsnData*, const SmbNtHdr*, const uint8_t, const uint8_t*, uint32_t, DCE2_SmbComInfo&); static void DCE2_SmbProcessCommand(DCE2_SmbSsnData*, const SmbNtHdr*, const uint8_t*, uint32_t); static DCE2_SmbRequestTracker* DCE2_SmbInspect(DCE2_SmbSsnData*, const SmbNtHdr*); -static bool DCE2_SmbAutodetect(Packet* p); static DCE2_SmbRequestTracker* DCE2_SmbFindRequestTracker(DCE2_SmbSsnData*, const SmbNtHdr*); static inline DCE2_Ret DCE2_SmbCheckAndXOffset(const uint8_t*, @@ -1550,48 +1549,6 @@ static void DCE2_SmbProcessRawData(DCE2_SmbSsnData* ssd, const uint8_t* nb_ptr, } } -static bool DCE2_SmbAutodetect(Packet* p) -{ - if (p->dsize > (sizeof(NbssHdr) + sizeof(SmbNtHdr))) - { - NbssHdr* nb_hdr = (NbssHdr*)p->data; - SmbNtHdr* smb_hdr = (SmbNtHdr*)(p->data + sizeof(NbssHdr)); - - if ((SmbId(smb_hdr) != DCE2_SMB_ID) - && (SmbId(smb_hdr) != DCE2_SMB2_ID)) - { - return false; - } - - switch (NbssType(nb_hdr)) - { - // FIXIT-L currently all ports are treated as autodetect. - // On port 139, there is always an initial Session Request / Session Positive/Negative - // response. - // These message types were added , to make sure port 139 is treated as smb. - // Remove once detect/autodetect supported. - case NBSS_SESSION_TYPE__REQUEST: - if (DCE2_SsnFromClient(p)) - return true; - break; - - case NBSS_SESSION_TYPE__POS_RESPONSE: - case NBSS_SESSION_TYPE__NEG_RESPONSE: - if (DCE2_SsnFromServer(p)) - return true; - break; - - case NBSS_SESSION_TYPE__MESSAGE: - return true; - break; - default: - break; - } - } - - return false; -} - static void DCE2_SmbDataFree(DCE2_SmbSsnData* ssd) { if (ssd == nullptr) @@ -1678,43 +1635,35 @@ static DCE2_SmbSsnData* dce2_create_new_smb_session(Packet* p, dce2SmbProtoConf* DCE2_SmbSsnData* dce2_smb_sess = nullptr; Profile profile(dce2_smb_pstat_new_session); - //FIXIT-M Re-evaluate after infrastructure/binder support if autodetect here - //is necessary - - if (DCE2_SmbAutodetect(p)) - { - DebugMessage(DEBUG_DCE_SMB, "DCE over SMB packet detected\n"); - DebugMessage(DEBUG_DCE_SMB, "Creating new session\n"); - - dce2_smb_sess = set_new_dce2_smb_session(p); - if ( dce2_smb_sess ) - { - dce2_smb_sess->dialect_index = DCE2_SENTINEL; - dce2_smb_sess->max_outstanding_requests = 10; // Until Negotiate/SessionSetupAndX - dce2_smb_sess->cli_data_state = DCE2_SMB_DATA_STATE__NETBIOS_HEADER; - dce2_smb_sess->srv_data_state = DCE2_SMB_DATA_STATE__NETBIOS_HEADER; - dce2_smb_sess->pdu_state = DCE2_SMB_PDU_STATE__COMMAND; - dce2_smb_sess->uid = DCE2_SENTINEL; - dce2_smb_sess->tid = DCE2_SENTINEL; - dce2_smb_sess->ftracker.fid_v1 = DCE2_SENTINEL; - dce2_smb_sess->rtracker.mid = DCE2_SENTINEL; - dce2_smb_sess->max_file_depth = FileService::get_max_file_depth(); - - DCE2_ResetRopts(&dce2_smb_sess->sd.ropts); - - dce2_smb_stats.smb_sessions++; - DebugFormat(DEBUG_DCE_SMB,"Created (%p)\n", (void*)dce2_smb_sess); - - dce2_smb_sess->sd.trans = DCE2_TRANS_TYPE__SMB; - dce2_smb_sess->sd.server_policy = config->common.policy; - dce2_smb_sess->sd.client_policy = DCE2_POLICY__WINXP; - dce2_smb_sess->sd.wire_pkt = p; - dce2_smb_sess->sd.config = (void*)config; - - DCE2_SsnSetAutodetected(&dce2_smb_sess->sd, p); - } - } - + DebugMessage(DEBUG_DCE_SMB, "DCE over SMB packet detected\n"); + DebugMessage(DEBUG_DCE_SMB, "Creating new session\n"); + + dce2_smb_sess = set_new_dce2_smb_session(p); + if ( dce2_smb_sess ) + { + dce2_smb_sess->dialect_index = DCE2_SENTINEL; + dce2_smb_sess->max_outstanding_requests = 10; // Until Negotiate/SessionSetupAndX + dce2_smb_sess->cli_data_state = DCE2_SMB_DATA_STATE__NETBIOS_HEADER; + dce2_smb_sess->srv_data_state = DCE2_SMB_DATA_STATE__NETBIOS_HEADER; + dce2_smb_sess->pdu_state = DCE2_SMB_PDU_STATE__COMMAND; + dce2_smb_sess->uid = DCE2_SENTINEL; + dce2_smb_sess->tid = DCE2_SENTINEL; + dce2_smb_sess->ftracker.fid_v1 = DCE2_SENTINEL; + dce2_smb_sess->rtracker.mid = DCE2_SENTINEL; + dce2_smb_sess->max_file_depth = FileService::get_max_file_depth(); + + DCE2_ResetRopts(&dce2_smb_sess->sd.ropts); + + dce2_smb_stats.smb_sessions++; + DebugFormat(DEBUG_DCE_SMB,"Created (%p)\n", (void*)dce2_smb_sess); + + dce2_smb_sess->sd.trans = DCE2_TRANS_TYPE__SMB; + dce2_smb_sess->sd.server_policy = config->common.policy; + dce2_smb_sess->sd.client_policy = DCE2_POLICY__WINXP; + dce2_smb_sess->sd.wire_pkt = p; + dce2_smb_sess->sd.config = (void*)config; + } + return dce2_smb_sess; } @@ -1728,29 +1677,9 @@ static DCE2_SmbSsnData* dce2_handle_smb_session(Packet* p, dce2SmbProtoConf* con { dce2_smb_sess = dce2_create_new_smb_session(p, config); } - else - { - DCE2_SsnData* sd = (DCE2_SsnData*)dce2_smb_sess; - sd->wire_pkt = p; - - if (DCE2_SsnAutodetected(sd) && !(p->packet_flags & sd->autodetect_dir)) - { - /* Try to autodetect in opposite direction */ - if (!DCE2_SmbAutodetect(p)) - { - DebugMessage(DEBUG_DCE_SMB, "Bad autodetect.\n"); - DCE2_SsnNoInspect(sd); - dce2_smb_stats.sessions_aborted++; - dce2_smb_stats.bad_autodetects++; - return nullptr; - } - DCE2_SsnClearAutodetected(sd); - } - } + DebugFormat(DEBUG_DCE_SMB, "Session pointer: %p\n", (void*)dce2_smb_sess); - // FIXIT-M add remaining session handling logic - return dce2_smb_sess; } @@ -3095,9 +3024,6 @@ void Dce2Smb::eval(Packet* p) DCE2_ResetRopts(&dce2_smb_sess->sd.ropts); DCE2_PopPkt(&dce2_smb_sess->sd); - if (!DCE2_SsnAutodetected(&dce2_smb_sess->sd)) - DisableInspection(); - delete p->endianness; p->endianness = nullptr; } diff --git a/src/service_inspectors/dce_rpc/dce_smb.h b/src/service_inspectors/dce_rpc/dce_smb.h index 20b24429c..beaca6bf1 100644 --- a/src/service_inspectors/dce_rpc/dce_smb.h +++ b/src/service_inspectors/dce_rpc/dce_smb.h @@ -169,15 +169,7 @@ struct dce2SmbStats { -/* FIXIT-M add array based peg counts - PegCount sessions_autodetected; -#ifdef DEBUG - PegCount autoports[65535][DCE2_TRANS_TYPE__MAX]; -#endif -*/ PegCount events; - PegCount sessions_aborted; - PegCount bad_autodetects; PegCount co_pdus; PegCount co_bind; diff --git a/src/service_inspectors/dce_rpc/dce_smb_module.cc b/src/service_inspectors/dce_rpc/dce_smb_module.cc index e15d41f4b..1ee6b3ec1 100644 --- a/src/service_inspectors/dce_rpc/dce_smb_module.cc +++ b/src/service_inspectors/dce_rpc/dce_smb_module.cc @@ -30,8 +30,6 @@ using namespace std; static const PegInfo dce2_smb_pegs[] = { { "events", "total events" }, - { "aborted sessions", "total aborted sessions" }, - { "bad autodetects", "total bad autodetects" }, { "PDUs", "total connection-oriented PDUs" }, { "Binds", "total connection-oriented binds" }, { "Bind acks", "total connection-oriented binds acks" }, diff --git a/src/service_inspectors/dce_rpc/dce_tcp.cc b/src/service_inspectors/dce_rpc/dce_tcp.cc index 1e54c2fb9..428d9f9b3 100644 --- a/src/service_inspectors/dce_rpc/dce_tcp.cc +++ b/src/service_inspectors/dce_rpc/dce_tcp.cc @@ -77,31 +77,24 @@ static DCE2_TcpSsnData* dce2_create_new_tcp_session(Packet* p, dce2TcpProtoConf* DCE2_TcpSsnData* dce2_tcp_sess = nullptr; Profile profile(dce2_tcp_pstat_new_session); - // FIXIT-M re-evaluate after infrastructure/binder support if autodetect here - // is necessary - if (DCE2_TcpAutodetect(p)) - { - DebugMessage(DEBUG_DCE_TCP, "DCE over TCP packet detected\n"); - DebugMessage(DEBUG_DCE_TCP, "Creating new session\n"); - - dce2_tcp_sess = set_new_dce2_tcp_session(p); + DebugMessage(DEBUG_DCE_TCP, "DCE over TCP packet detected\n"); + DebugMessage(DEBUG_DCE_TCP, "Creating new session\n"); - if ( dce2_tcp_sess ) - { - DCE2_CoInitTracker(&dce2_tcp_sess->co_tracker); - DCE2_ResetRopts(&dce2_tcp_sess->sd.ropts); + dce2_tcp_sess = set_new_dce2_tcp_session(p); - dce2_tcp_stats.tcp_sessions++; - DebugFormat(DEBUG_DCE_TCP,"Created (%p)\n", (void*)dce2_tcp_sess); + if ( dce2_tcp_sess ) + { + DCE2_CoInitTracker(&dce2_tcp_sess->co_tracker); + DCE2_ResetRopts(&dce2_tcp_sess->sd.ropts); - dce2_tcp_sess->sd.trans = DCE2_TRANS_TYPE__TCP; - dce2_tcp_sess->sd.server_policy = config->common.policy; - dce2_tcp_sess->sd.client_policy = DCE2_POLICY__WINXP; - dce2_tcp_sess->sd.wire_pkt = p; - dce2_tcp_sess->sd.config = (void*)config; + dce2_tcp_stats.tcp_sessions++; + DebugFormat(DEBUG_DCE_TCP,"Created (%p)\n", (void*)dce2_tcp_sess); - DCE2_SsnSetAutodetected(&dce2_tcp_sess->sd, p); - } + dce2_tcp_sess->sd.trans = DCE2_TRANS_TYPE__TCP; + dce2_tcp_sess->sd.server_policy = config->common.policy; + dce2_tcp_sess->sd.client_policy = DCE2_POLICY__WINXP; + dce2_tcp_sess->sd.wire_pkt = p; + dce2_tcp_sess->sd.config = (void*)config; } return dce2_tcp_sess; @@ -117,26 +110,6 @@ static DCE2_TcpSsnData* dce2_handle_tcp_session(Packet* p, dce2TcpProtoConf* con { dce2_tcp_sess = dce2_create_new_tcp_session(p, config); } - else - { - DCE2_SsnData* sd = (DCE2_SsnData*)dce2_tcp_sess; - sd->wire_pkt = p; - - if (DCE2_SsnAutodetected(sd) && !(p->packet_flags & sd->autodetect_dir)) - { - /* Try to autodetect in opposite direction */ - if (!DCE2_TcpAutodetect(p)) - { - DebugMessage(DEBUG_DCE_TCP, "Bad autodetect.\n"); - DCE2_SsnNoInspect(sd); - dce2_tcp_stats.sessions_aborted++; - dce2_tcp_stats.bad_autodetects++; - return nullptr; - } - - DCE2_SsnClearAutodetected(sd); - } - } DebugFormat(DEBUG_DCE_TCP, "Session pointer: %p\n", (void*)dce2_tcp_sess); @@ -219,9 +192,6 @@ void Dce2Tcp::eval(Packet* p) DCE2_ResetRopts(&dce2_tcp_sess->sd.ropts); DCE2_PopPkt(&dce2_tcp_sess->sd); - if (!DCE2_SsnAutodetected(&dce2_tcp_sess->sd)) - DisableInspection(); - delete p->endianness; p->endianness = nullptr; } diff --git a/src/service_inspectors/dce_rpc/dce_tcp.h b/src/service_inspectors/dce_rpc/dce_tcp.h index 036ac7c38..7766b5a08 100644 --- a/src/service_inspectors/dce_rpc/dce_tcp.h +++ b/src/service_inspectors/dce_rpc/dce_tcp.h @@ -33,19 +33,8 @@ struct dce2TcpStats { -/* FIXIT-M add array based peg counts - PegCount sessions_autodetected; -#ifdef DEBUG - PegCount autoports[65535][DCE2_TRANS_TYPE__MAX]; -#endif -*/ - /* The common stats block has to be at the beginning followed - by the protocol specific stats */ - - /*common stats -defined in common.h*/ + /* common stats - defined in dce_common.h*/ PegCount events; - PegCount sessions_aborted; - PegCount bad_autodetects; PegCount co_pdus; PegCount co_bind; diff --git a/src/service_inspectors/dce_rpc/dce_tcp_module.cc b/src/service_inspectors/dce_rpc/dce_tcp_module.cc index 7a1d2050a..22789ee3d 100644 --- a/src/service_inspectors/dce_rpc/dce_tcp_module.cc +++ b/src/service_inspectors/dce_rpc/dce_tcp_module.cc @@ -61,8 +61,6 @@ static const RuleMap dce2_tcp_rules[] = static const PegInfo dce2_tcp_pegs[] = { { "events", "total events" }, - { "aborted sessions", "total aborted sessions" }, - { "bad autodetects", "total bad autodetects" }, { "PDUs", "total connection-oriented PDUs" }, { "Binds", "total connection-oriented binds" }, { "Bind acks", "total connection-oriented binds acks" }, diff --git a/src/service_inspectors/dce_rpc/dce_udp.cc b/src/service_inspectors/dce_rpc/dce_udp.cc index 2032832d6..234e2c827 100644 --- a/src/service_inspectors/dce_rpc/dce_udp.cc +++ b/src/service_inspectors/dce_rpc/dce_udp.cc @@ -52,29 +52,6 @@ static void DCE2_ClCleanTracker(DCE2_ClTracker* clt) clt->act_trackers = nullptr; } -// Tries to determine if a packet is likely to be DCE/RPC over UDP -static DCE2_TransType DCE2_UdpAutodetect(const Packet* p) -{ - if (p->dsize >= sizeof(DceRpcClHdr)) - { - const DceRpcClHdr* cl_hdr = (DceRpcClHdr*)p->data; - - if ((DceRpcClRpcVers(cl_hdr) == DCERPC_PROTO_MAJOR_VERS__4) && - ((DceRpcClPduType(cl_hdr) == DCERPC_PDU_TYPE__REQUEST) || - (DceRpcClPduType(cl_hdr) == DCERPC_PDU_TYPE__RESPONSE) || - (DceRpcClPduType(cl_hdr) == DCERPC_PDU_TYPE__FAULT) || - (DceRpcClPduType(cl_hdr) == DCERPC_PDU_TYPE__REJECT) || - (DceRpcClPduType(cl_hdr) == DCERPC_PDU_TYPE__FACK)) && - ((DceRpcClLen(cl_hdr) != 0) && - (DceRpcClLen(cl_hdr) + sizeof(DceRpcClHdr)) <= p->dsize)) - { - return DCE2_TRANS_TYPE__UDP; - } - } - - return DCE2_TRANS_TYPE__NONE; -} - //------------------------------------------------------------------------- // class stuff //------------------------------------------------------------------------- @@ -109,26 +86,19 @@ static DCE2_UdpSsnData* dce2_create_new_udp_session(Packet* p, dce2UdpProtoConf* DCE2_UdpSsnData* dce2_udp_sess = nullptr; Profile profile(dce2_udp_pstat_new_session); - // FIXIT-M re-evaluate after infrastructure/binder support if autodetect here - // is necessary - if (DCE2_UdpAutodetect(p)) - { - DebugMessage(DEBUG_DCE_UDP, "DCE over UDP packet detected\n"); - DebugMessage(DEBUG_DCE_UDP, "Creating new session\n"); + DebugMessage(DEBUG_DCE_UDP, "DCE over UDP packet detected\n"); + DebugMessage(DEBUG_DCE_UDP, "Creating new session\n"); - dce2_udp_sess = set_new_dce2_udp_session(p); - - DCE2_ResetRopts(&dce2_udp_sess->sd.ropts); + dce2_udp_sess = set_new_dce2_udp_session(p); - dce2_udp_stats.udp_sessions++; - DebugFormat(DEBUG_DCE_UDP,"Created (%p)\n", (void*)dce2_udp_sess); + DCE2_ResetRopts(&dce2_udp_sess->sd.ropts); - dce2_udp_sess->sd.trans = DCE2_TRANS_TYPE__UDP; - dce2_udp_sess->sd.wire_pkt = p; - dce2_udp_sess->sd.config = (void*)config; + dce2_udp_stats.udp_sessions++; + DebugFormat(DEBUG_DCE_UDP,"Created (%p)\n", (void*)dce2_udp_sess); - DCE2_SsnSetAutodetected(&dce2_udp_sess->sd, p); - } + dce2_udp_sess->sd.trans = DCE2_TRANS_TYPE__UDP; + dce2_udp_sess->sd.wire_pkt = p; + dce2_udp_sess->sd.config = (void*)config; return dce2_udp_sess; } @@ -143,26 +113,6 @@ static DCE2_UdpSsnData* dce2_handle_udp_session(Packet* p, dce2UdpProtoConf* con { dce2_udp_sess = dce2_create_new_udp_session(p, config); } - else - { - DCE2_SsnData* sd = (DCE2_SsnData*)dce2_udp_sess; - sd->wire_pkt = p; - - if (DCE2_SsnAutodetected(sd) && !(p->packet_flags & sd->autodetect_dir)) - { - /* Try to autodetect in opposite direction */ - if (!DCE2_UdpAutodetect(p)) - { - DebugMessage(DEBUG_DCE_UDP, "Bad autodetect.\n"); - DCE2_SsnNoInspect(sd); - dce2_udp_stats.sessions_aborted++; - dce2_udp_stats.bad_autodetects++; - return nullptr; - } - - DCE2_SsnClearAutodetected(sd); - } - } DebugFormat(DEBUG_DCE_UDP, "Session pointer: %p\n", (void*)dce2_udp_sess); @@ -228,9 +178,6 @@ void Dce2Udp::eval(Packet* p) DCE2_ResetRopts(&dce2_udp_sess->sd.ropts); DCE2_PopPkt(&dce2_udp_sess->sd); - if (!DCE2_SsnAutodetected(&dce2_udp_sess->sd)) - DisableInspection(); - delete p->endianness; p->endianness = nullptr; } diff --git a/src/service_inspectors/dce_rpc/dce_udp.h b/src/service_inspectors/dce_rpc/dce_udp.h index 13f201174..d11a039bb 100644 --- a/src/service_inspectors/dce_rpc/dce_udp.h +++ b/src/service_inspectors/dce_rpc/dce_udp.h @@ -38,8 +38,6 @@ struct dce2UdpStats /*common stats -defined in common.h*/ PegCount events; - PegCount sessions_aborted; - PegCount bad_autodetects; /*DCE UDP specific*/ PegCount udp_sessions; diff --git a/src/service_inspectors/dce_rpc/dce_udp_module.cc b/src/service_inspectors/dce_rpc/dce_udp_module.cc index 7e56fe4e1..14057b2a8 100644 --- a/src/service_inspectors/dce_rpc/dce_udp_module.cc +++ b/src/service_inspectors/dce_rpc/dce_udp_module.cc @@ -47,8 +47,6 @@ static const RuleMap dce2_udp_rules[] = static const PegInfo dce2_udp_pegs[] = { { "events", "total events" }, - { "aborted sessions", "total aborted sessions" }, - { "bad autodetects", "total bad autodetects" }, { "udp sessions", "total udp sessions" }, { "udp packets", "total udp packets" }, { "Requests", "total connection-less requests" }, diff --git a/src/service_inspectors/dce_rpc/dce_udp_processing.cc b/src/service_inspectors/dce_rpc/dce_udp_processing.cc index e7a4fbd5b..87acb1420 100644 --- a/src/service_inspectors/dce_rpc/dce_udp_processing.cc +++ b/src/service_inspectors/dce_rpc/dce_udp_processing.cc @@ -107,12 +107,7 @@ void DCE2_ClProcess(DCE2_SsnData* sd, DCE2_ClTracker* clt) if (data_len < sizeof(DceRpcClHdr)) { - // FIXIT-M currently we always do autodetect. Uncomment once - // detect/autodetect is supported. -/* - if (!DCE2_SsnAutodetected(sd)) - 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); return; } @@ -238,23 +233,13 @@ static DCE2_Ret DCE2_ClHdrChecks(DCE2_SsnData*, const DceRpcClHdr* cl_hdr) { if (DceRpcClRpcVers(cl_hdr) != DCERPC_PROTO_MAJOR_VERS__4) { - // FIXIT-M currently we always do autodetect. Uncomment once - // detect/autodetect is supported. - /* If we autodetected the session, we probably guessed wrong */ - /* if (!DCE2_SsnAutodetected(sd)) - 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); return DCE2_RET__ERROR; } if (DceRpcClPduType(cl_hdr) >= DCERPC_PDU_TYPE__MAX) { - // FIXIT-M currently we always do autodetect. Uncomment once - // detect/autodetect is supported. -/* - if (!DCE2_SsnAutodetected(sd)) - 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); return DCE2_RET__ERROR; } @@ -568,12 +553,12 @@ static int DCE2_ClFragCompare(const void* a, const void* b) static void DCE2_ClFragReassemble(DCE2_SsnData* sd, DCE2_ClActTracker* at, const DceRpcClHdr* cl_hdr) { - uint8_t dce2_cl_rbuf[IP_MAXPACKET]; - DCE2_ClFragTracker* ft = &at->frag_tracker; - uint8_t* rdata = dce2_cl_rbuf; + uint8_t dce2_cl_rbuf[IP_MAXPACKET]; + DCE2_ClFragTracker* ft = &at->frag_tracker; + uint8_t* rdata = dce2_cl_rbuf; uint16_t rlen = sizeof(dce2_cl_rbuf); - DCE2_ClFragNode* fnode; - uint32_t stub_len = 0; + DCE2_ClFragNode* fnode; + uint32_t stub_len = 0; Profile profile(dce2_udp_pstat_cl_reass); @@ -594,7 +579,7 @@ static void DCE2_ClFragReassemble(DCE2_SsnData* sd, DCE2_ClActTracker* at, const stub_len += fnode->frag_len; } - Packet* rpkt = DCE2_GetRpkt(sd->wire_pkt, DCE2_RPKT_TYPE__UDP_CL_FRAG, dce2_cl_rbuf, stub_len); + Packet* rpkt = DCE2_GetRpkt(sd->wire_pkt, DCE2_RPKT_TYPE__UDP_CL_FRAG, dce2_cl_rbuf, stub_len); if (rpkt == nullptr) { DebugFormat(DEBUG_DCE_UDP, diff --git a/src/service_inspectors/dce_rpc/dev_notes.txt b/src/service_inspectors/dce_rpc/dev_notes.txt index 115c98c1a..2b4bd9302 100644 --- a/src/service_inspectors/dce_rpc/dev_notes.txt +++ b/src/service_inspectors/dce_rpc/dev_notes.txt @@ -14,16 +14,8 @@ The Snort 2x server configuration is now split between the inspectors. Options that are meaningful to all inspectors, such as policy, are copied into each inspector configuration. -The address/port mapping is handled by the binder. Since the -infrastructure has no support for "autodetect" all ports are treated -the same currently and autodetection performed. Default autodetect -ranges were temporarly replaced by a single port default. +The address/port mapping is handled by the binder. Autodetect +functionality is replaced by wizard curses. The Snort 2x global configuration is now rolled into server configuration. - -Note: Some logic related to DCE segmentation and packet stack seems -unnecessary. It is assumed that the only case for which segmentation -logic will come into play is if the fragment size is > MAX_PAF_MAX -resulting in a partial fragment being delivered to the inspector. All -other logic has been removed with comment #PORT_IF_NEEDED. diff --git a/src/service_inspectors/wizard/CMakeLists.txt b/src/service_inspectors/wizard/CMakeLists.txt index 689525e30..ed29ff99a 100644 --- a/src/service_inspectors/wizard/CMakeLists.txt +++ b/src/service_inspectors/wizard/CMakeLists.txt @@ -1,5 +1,7 @@ set(FILE_LIST + curses.cc + curses.h magic.cc magic.h hexes.cc diff --git a/src/service_inspectors/wizard/Makefile.am b/src/service_inspectors/wizard/Makefile.am index 673dcccc0..b8c7b33e5 100644 --- a/src/service_inspectors/wizard/Makefile.am +++ b/src/service_inspectors/wizard/Makefile.am @@ -1,5 +1,7 @@ file_list = \ +curses.cc \ +curses.h \ magic.cc magic.h \ hexes.cc \ spells.cc \ diff --git a/src/service_inspectors/wizard/curses.cc b/src/service_inspectors/wizard/curses.cc new file mode 100644 index 000000000..853c1cc71 --- /dev/null +++ b/src/service_inspectors/wizard/curses.cc @@ -0,0 +1,261 @@ +//-------------------------------------------------------------------------- +// Copyright (C) 2016-2016 Cisco and/or its affiliates. All rights reserved. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License Version 2 as published +// by the Free Software Foundation. You may not use, modify or distribute +// this program under any other version of the GNU General Public License. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +//-------------------------------------------------------------------------- +// curses.cc author Maya Dagon + +#include "curses.h" + +#include +#include "flow/flow.h" +#include "protocols/packet.h" + +using namespace std; + +enum DceRpcPduType +{ + DCERPC_PDU_TYPE__REQUEST = 0, + DCERPC_PDU_TYPE__PING, + DCERPC_PDU_TYPE__RESPONSE, + DCERPC_PDU_TYPE__FAULT, + DCERPC_PDU_TYPE__WORKING, + DCERPC_PDU_TYPE__NOCALL, + DCERPC_PDU_TYPE__REJECT, + DCERPC_PDU_TYPE__ACK, + DCERPC_PDU_TYPE__CL_CANCEL, + DCERPC_PDU_TYPE__FACK, + DCERPC_PDU_TYPE__CANCEL_ACK, + DCERPC_PDU_TYPE__BIND, + DCERPC_PDU_TYPE__BIND_ACK, + DCERPC_PDU_TYPE__BIND_NACK, + DCERPC_PDU_TYPE__ALTER_CONTEXT, + DCERPC_PDU_TYPE__ALTER_CONTEXT_RESP, + DCERPC_PDU_TYPE__AUTH3, + DCERPC_PDU_TYPE__SHUTDOWN, + DCERPC_PDU_TYPE__CO_CANCEL, + DCERPC_PDU_TYPE__ORPHANED, + DCERPC_PDU_TYPE__MICROSOFT_PROPRIETARY_OUTLOOK2003_RPC_OVER_HTTP, + DCERPC_PDU_TYPE__MAX +}; + +/* Version 4 is for Connectionless + * Version 5 is for Connection oriented */ +enum DceRpcProtoMajorVers +{ + DCERPC_PROTO_MAJOR_VERS__4 = 4, + DCERPC_PROTO_MAJOR_VERS__5 = 5 +}; + +enum DceRpcProtoMinorVers +{ + DCERPC_PROTO_MINOR_VERS__0 = 0, + DCERPC_PROTO_MINOR_VERS__1 = 1 +}; + +bool dce_udp_curse(const uint8_t* data, unsigned len, CurseTracker*) +{ + const uint8_t dcerpc_cl_hdr_len = 80; + const uint8_t cl_len_offset = 74; + + if (len >= dcerpc_cl_hdr_len) + { + uint8_t version = data[0]; + uint8_t pdu_type = data[1]; + bool little_endian = ((data[4] & 0x10) >> 4) ? true : false; + uint16_t cl_len; + +#ifdef WORDS_BIGENDIAN + if (!little_endian) +#else + if (little_endian) +#endif /* WORDS_BIGENDIAN */ + cl_len = (data[cl_len_offset+1] << 8) | data[cl_len_offset]; + else + cl_len = (data[cl_len_offset] << 8) | data[cl_len_offset+1]; + + if ((version == DCERPC_PROTO_MAJOR_VERS__4) && + ((pdu_type == DCERPC_PDU_TYPE__REQUEST) || + (pdu_type == DCERPC_PDU_TYPE__RESPONSE) || + (pdu_type == DCERPC_PDU_TYPE__FAULT) || + (pdu_type == DCERPC_PDU_TYPE__REJECT) || + (pdu_type == DCERPC_PDU_TYPE__FACK)) && + ((cl_len != 0) && + (cl_len + (unsigned)dcerpc_cl_hdr_len) <= len)) + return true; + } + + return false; +} + +bool dce_tcp_curse(const uint8_t* data, unsigned len, CurseTracker* tracker) +{ + const uint8_t dce_rpc_co_hdr_len = 16; + + uint32_t n = 0; + while (n < len) + { + switch (tracker->state) + { + case STATE_0: // check major version + { + if (data[n] != DCERPC_PROTO_MAJOR_VERS__5) + { + // go to bad state + tracker->state = STATE_10; + return false; + } + tracker->state = (DCE_States)((int)tracker->state + 1); + break; + } + + case STATE_1: // check minor version + { + if (data[n] != DCERPC_PROTO_MINOR_VERS__0) + { + // go to bad state + tracker->state = STATE_10; + return false; + } + tracker->state = (DCE_States)((int)tracker->state + 1); + break; + } + + case STATE_2: // pdu_type + { + uint8_t pdu_type = data[n]; + if ((pdu_type != DCERPC_PDU_TYPE__BIND) && + (pdu_type != DCERPC_PDU_TYPE__BIND_ACK)) + { + // go to bad state + tracker->state = STATE_10; + return false; + } + tracker->state = (DCE_States)((int)tracker->state + 1); + break; + } + + case STATE_4: //little endian + tracker->helper = (data[n] & 0x10) << 20; + tracker->state = (DCE_States)((int)tracker->state + 1); + break; + case STATE_8: + tracker->helper |= data[n]; + tracker->state = (DCE_States)((int)tracker->state + 1); + break; + case STATE_9: + { +#ifdef WORDS_BIGENDIAN + if (!(tracker->helper >> 24)) +#else + if (tracker->helper >> 24) +#endif /* WORDS_BIGENDIAN */ + tracker->helper = (data[n] << 8) | (tracker->helper & 0XFF); + else + { + tracker->helper <<=8; + tracker->helper |= data[n]; + } + + if (tracker->helper >= dce_rpc_co_hdr_len) + return true; + + tracker->state = STATE_10; + break; + } + + case STATE_10: + // no match + return false; + default: + tracker->state = (DCE_States)((int)tracker->state + 1); + break; + } + n++; + } + + return false; +} + +bool dce_smb_curse(const uint8_t* data, unsigned len, CurseTracker* tracker) +{ + const uint32_t dce_smb_id = 0xff534d42; /* \xffSMB */ + const uint32_t dce_smb2_id = 0xfe534d42; /* \xfeSMB */ + const uint8_t nbss_type_message = 0; + + uint32_t n = 0; + while (n < len) + { + switch (tracker->state) + { + case STATE_0: + { + if (data[n] != nbss_type_message) + { + tracker->state = STATE_8; + return false; + } + tracker->state = (DCE_States)((int)tracker->state + 1); + break; + } + case STATE_4: + { + tracker->helper = data[n]; + tracker->state = (DCE_States)((int)tracker->state + 1); + break; + } + case STATE_5: + case STATE_6: + { + tracker->helper <<= 8; + tracker->helper |= data[n]; + tracker->state = (DCE_States)((int)tracker->state + 1); + break; + } + + case STATE_7: + { + tracker->helper <<= 8; + tracker->helper |= data[n]; + if ((tracker->helper == dce_smb_id) || (tracker->helper == dce_smb2_id)) + return true; + + tracker->state = (DCE_States)((int)tracker->state + 1); + break; + } + + case STATE_8: + // no match + return false; + + default: + tracker->state = (DCE_States)((int)tracker->state + 1); + break; + } + n++; + } + + return false; +} + +// map between service and curse details +map curse_map +{ + // service_name alg is_tcp + { "dce_udp", { dce_udp_curse, false }}, + { "dce_tcp", { dce_tcp_curse, true }}, + { "dce_smb", { dce_smb_curse, true }}, +}; + diff --git a/src/service_inspectors/wizard/curses.h b/src/service_inspectors/wizard/curses.h new file mode 100644 index 000000000..cbfe7264e --- /dev/null +++ b/src/service_inspectors/wizard/curses.h @@ -0,0 +1,64 @@ +//-------------------------------------------------------------------------- +// Copyright (C) 2016-2016 Cisco and/or its affiliates. All rights reserved. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License Version 2 as published +// by the Free Software Foundation. You may not use, modify or distribute +// this program under any other version of the GNU General Public License. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +//-------------------------------------------------------------------------- +// curses.h author Maya Dagon + +#ifndef CURSES_H +#define CURSES_H + +#include +#include +#include "flow/flow.h" +#include "protocols/packet.h" + +enum DCE_States +{ + STATE_0 = 0, + STATE_1, + STATE_2, + STATE_3, + STATE_4, + STATE_5, + STATE_6, + STATE_7, + STATE_8, + STATE_9, + STATE_10 +}; + +class CurseTracker +{ +public: + DCE_States state; + uint32_t helper; + + CurseTracker() { state = STATE_0; } +}; + +typedef bool (* curse_alg)(const uint8_t* data, unsigned len, CurseTracker*); + +struct CurseDetails +{ + curse_alg alg; + bool is_tcp; +}; + +// map between service and curse details +extern std::map curse_map; + +#endif + diff --git a/src/service_inspectors/wizard/dev_notes.txt b/src/service_inspectors/wizard/dev_notes.txt index 7caf74daf..a87cdfc0d 100644 --- a/src/service_inspectors/wizard/dev_notes.txt +++ b/src/service_inspectors/wizard/dev_notes.txt @@ -1,5 +1,5 @@ -The wizard uses hexes and spells to determine the most likely service on a -flow. It does not determine the service with certainty; that is the job of +The wizard uses hexes, spells and curses to determine the most likely service +on a flow. It does not determine the service with certainty; that is the job of the service inspector or appId. The goal is to get the most likely service inspector engaged as quickly as possible. @@ -37,3 +37,6 @@ The current implementation of the magic is very straightforward. Due to the limited number of patterns, space is not a concern and each state has 256 byte array of pointers to the next. +Curses are presently used for binary protocols that require more than pattern +matching. They use internal algorithms to identify services, +implemented with custom FSMs. diff --git a/src/service_inspectors/wizard/wiz_module.cc b/src/service_inspectors/wizard/wiz_module.cc index 413df4a63..1cde6e921 100644 --- a/src/service_inspectors/wizard/wiz_module.cc +++ b/src/service_inspectors/wizard/wiz_module.cc @@ -25,6 +25,7 @@ #include +#include "curses.h" #include "magic.h" using namespace std; @@ -97,6 +98,9 @@ static const Parameter s_params[] = { "spells", Parameter::PT_LIST, wizard_spells_params, nullptr, "criteria for text service identification" }, + { "curses", Parameter::PT_MULTI, "dce_smb | dce_udp | dce_tcp", nullptr, + "enable service identification based on internal algorithm" }, + { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr } }; @@ -138,6 +142,9 @@ bool WizardModule::set(const char*, Value& v, SnortConfig*) else if ( v.is("spell") ) spells.push_back(v.get_string()); + else if ( v.is("curses") ) + curses.push_back(v.get_string()); + else return false; @@ -153,6 +160,7 @@ bool WizardModule::begin(const char* fqn, int, SnortConfig*) c2s_spells = new SpellBook; s2c_spells = new SpellBook; + curses.clear(); } else if ( !strcmp(fqn, "wizard.hexes") ) hex = true; @@ -200,6 +208,7 @@ bool WizardModule::end(const char*, int idx, SnortConfig*) else add_spells(s2c_spells, service); } + spells.clear(); service.clear(); diff --git a/src/service_inspectors/wizard/wiz_module.h b/src/service_inspectors/wizard/wiz_module.h index d4edff0d8..8af4a7761 100644 --- a/src/service_inspectors/wizard/wiz_module.h +++ b/src/service_inspectors/wizard/wiz_module.h @@ -53,6 +53,10 @@ public: ProfileStats* get_profile() const override; MagicBook* get_book(bool c2s, bool hex); + std::vector get_curse_book() + { + return curses; + } private: void add_spells(MagicBook*, std::string&); @@ -63,6 +67,7 @@ private: std::string service; std::vector spells; + std::vector curses; MagicBook* c2s_hexes; MagicBook* s2c_hexes; diff --git a/src/service_inspectors/wizard/wizard.cc b/src/service_inspectors/wizard/wizard.cc index 43b972db5..5b6419979 100644 --- a/src/service_inspectors/wizard/wizard.cc +++ b/src/service_inspectors/wizard/wizard.cc @@ -29,6 +29,7 @@ #include "log/messages.h" #include "host_tracker/host_cache.h" +#include "curses.h" #include "magic.h" #include "wiz_module.h" @@ -63,10 +64,17 @@ THREAD_LOCAL WizStats tstats; // configuration //------------------------------------------------------------------------- +struct CurseServiceTracker +{ + string service; + CurseTracker* tracker; +}; + struct Wand { const MagicPage* hex; const MagicPage* spell; + vector curse_tracker; }; class Wizard; @@ -103,6 +111,7 @@ public: void reset(Wand&, bool tcp, bool c2s); bool cast_spell(Wand&, Flow*, const uint8_t*, unsigned); bool spellbind(const MagicPage*&, Flow*, const uint8_t*, unsigned); + bool cursebind(vector&,Flow*, const uint8_t*, unsigned); public: MagicBook* c2s_hexes; @@ -110,6 +119,7 @@ public: MagicBook* c2s_spells; MagicBook* s2c_spells; + vector curse_book; }; //------------------------------------------------------------------------- @@ -129,6 +139,10 @@ MagicSplitter::MagicSplitter(bool c2s, class Wizard* w) : MagicSplitter::~MagicSplitter() { wizard->rem_ref(); + + // release trackers + for (unsigned i=0; iget_book(true, false); s2c_spells = m->get_book(false, false); + curse_book = m->get_curse_book(); } Wizard::~Wizard() @@ -166,7 +181,7 @@ Wizard::~Wizard() delete s2c_spells; } -void Wizard::reset(Wand& w, bool /*tcp*/, bool c2s) +void Wizard::reset(Wand& w, bool tcp, bool c2s) { if ( c2s ) { @@ -178,6 +193,20 @@ void Wizard::reset(Wand& w, bool /*tcp*/, bool c2s) w.hex = s2c_hexes->page1(); w.spell = s2c_spells->page1(); } + + if (w.curse_tracker.empty()) + { + for ( auto service:curse_book ) + { + if (tcp == curse_map[service].is_tcp) + { + if (tcp) + w.curse_tracker.push_back({ service, new CurseTracker }); + else + w.curse_tracker.push_back({ service, nullptr }); + } + } + } } void Wizard::eval(Packet* p) @@ -227,9 +256,37 @@ bool Wizard::cast_spell( if ( w.spell && spellbind(w.spell, f, data, len) ) return true; + if (cursebind(w.curse_tracker, f, data, len)) + return true; + return false; } +bool Wizard::cursebind( + vector& curse_tracker, Flow* f, const uint8_t* data, unsigned len) +{ + bool match = false; + + for (auto const& p : curse_tracker) + { + if (curse_map[p.service].alg(data,len, p.tracker)) + { + match = true; + f->service = p.service.c_str(); + break; + } + } + + if (match) + { + // FIXIT-H need to make sure Flow's ipproto and service + // correspond to HostApplicationEntry's ipproto and service + host_cache_add_service(f->server_ip, f->ip_proto, f->server_port, f->service); + } + + return match; +} + //------------------------------------------------------------------------- // api stuff //------------------------------------------------------------------------- diff --git a/tools/snort2lua/preprocessor_states/pps_dcerpc.cc b/tools/snort2lua/preprocessor_states/pps_dcerpc.cc index 700087999..69496cc7a 100644 --- a/tools/snort2lua/preprocessor_states/pps_dcerpc.cc +++ b/tools/snort2lua/preprocessor_states/pps_dcerpc.cc @@ -31,7 +31,6 @@ public: virtual bool convert(std::istringstream& data); private: - bool add_deleted_comment_to_table(std::string table_name, std::string option); bool add_deleted_comment_to_defaults(std::string option); bool add_option_to_all(std::string option, const bool val, bool co_only); bool add_option_to_all(std::string option, const int val, bool co_only); @@ -42,14 +41,6 @@ private: std::istringstream& stream); }; -bool Dcerpc::add_deleted_comment_to_table(std::string table_name, std::string option) -{ - table_api.open_table(table_name); - bool tmpval = table_api.add_deleted_comment(option); - table_api.close_table(); - - return tmpval; -} bool Dcerpc::add_option_to_all(std::string option, const bool val, bool co_only) { @@ -119,7 +110,7 @@ bool Dcerpc::add_deleted_comment_to_defaults(std::string option) for (auto type : transport) { - tmpval = add_deleted_comment_to_table("dce_" + type, option) && tmpval; + tmpval = add_deleted_comment_to_table(table_api,"dce_" + type, option) && tmpval; } return tmpval; } diff --git a/tools/snort2lua/preprocessor_states/pps_dcerpc_server.cc b/tools/snort2lua/preprocessor_states/pps_dcerpc_server.cc index e2c95a3d0..73e88e67b 100644 --- a/tools/snort2lua/preprocessor_states/pps_dcerpc_server.cc +++ b/tools/snort2lua/preprocessor_states/pps_dcerpc_server.cc @@ -56,17 +56,6 @@ std::map > default_ports } }; -// FIXIT-M change to full range - 1025: -std::map > autodetect_default_ports -{ - { "smb", { 1025 } - }, - { "tcp", { 1026 } - }, - { "udp", { 1027 } - } -}; - ///////////////////////// // Utility functions //////////////////////// @@ -101,6 +90,15 @@ bool add_option_to_table(TableApi& table_api,std::string table_name, std::string return tmpval; } +bool add_deleted_comment_to_table(TableApi& table_api, std::string table_name, std::string option) +{ + table_api.open_table(table_name); + bool tmpval = table_api.add_deleted_comment(option); + table_api.close_table(); + + return tmpval; +} + ///////////////////////////// ///// DcerpcServer ///////////////////////////// @@ -111,7 +109,6 @@ DcerpcServer::DcerpcServer(Converter& c) : ConversionState(c) { for (auto type: transport) { - autodetect_ports_set[type] = false; detect_ports_set[type] = false; } } @@ -230,20 +227,9 @@ void DcerpcServer::add_default_ports(std::string type, std::map bind) -{ - for (auto port : autodetect_default_ports[type]) - { - bind[type]->add_when_port(std::to_string(port)); - } -} - // add single port / range bool DcerpcServer::parse_and_add_ports(std::string ports, std::string type, std::map bind, bool is_detect) + Binder*> bind) { if (ports.empty()) { @@ -287,14 +273,7 @@ bool DcerpcServer::parse_and_add_ports(std::string ports, std::string type, std: } } - if (is_detect) - { - detect_ports_set[type] = true; - } - else - { - autodetect_ports_set[type] = true; - } + detect_ports_set[type] = true; return true; } @@ -357,9 +336,10 @@ bool DcerpcServer::parse_detect(std::istringstream& data_stream, for (auto transport_type: transport) { if (is_detect) + { detect_ports_set[transport_type] = true; - else - autodetect_ports_set[transport_type] = true; + bind[transport_type]->print_binding(false); + } } } @@ -437,6 +417,12 @@ bool DcerpcServer::parse_detect(std::istringstream& data_stream, { continue; } + // if this is autodetect- stop here + if (!is_detect) + { + add_deleted_comment_to_table(table_api, table_name[type], "autodetect"); + continue; + } // remove '[',']' ports.erase(std::remove(ports.begin(), ports.end(), '['), ports.end()); @@ -444,7 +430,7 @@ bool DcerpcServer::parse_detect(std::istringstream& data_stream, // remove extra spaces ports.erase(remove_if(ports.begin(), ports.end(), isspace), ports.end()); - if (!parse_and_add_ports(ports, type, bind, is_detect)) + if (!parse_and_add_ports(ports, type, bind)) { return false; } @@ -765,10 +751,6 @@ bool DcerpcServer::convert(std::istringstream& data_stream) { add_default_ports(type, bind); } - if (!autodetect_ports_set[type]) - { - add_default_autodetect_ports(type, bind); - } } return retval; diff --git a/tools/snort2lua/preprocessor_states/pps_dcerpc_server.h b/tools/snort2lua/preprocessor_states/pps_dcerpc_server.h index 661e533df..cfb2c9275 100644 --- a/tools/snort2lua/preprocessor_states/pps_dcerpc_server.h +++ b/tools/snort2lua/preprocessor_states/pps_dcerpc_server.h @@ -48,9 +48,8 @@ private: bool parse_detect(std::istringstream& data_stream, std::map bind, bool is_detect); void add_default_ports(std::string type, std::map bind); - void add_default_autodetect_ports(std::string type, std::map bind); bool parse_and_add_ports(std::string ports, std::string type, std::map bind, bool is_detect); + Binder*> bind); bool init_net_created_table(); bool init_new_tables(bool is_default); bool parse_nets(std::istringstream& data_stream, std::map