]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #703 in SNORT/snort3 from autodetect to master
authorMichael Altizer (mialtize) <mialtize@cisco.com>
Wed, 16 Nov 2016 16:48:51 +0000 (11:48 -0500)
committerMichael Altizer (mialtize) <mialtize@cisco.com>
Wed, 16 Nov 2016 16:48:51 +0000 (11:48 -0500)
Squashed commit of the following:

commit 2c97fdb0fe074450a90770565c9441cb6dd84623
Author: mdagon <mdagon@cisco.com>
Date:   Wed Nov 2 08:04:19 2016 -0400

    dce wizard

25 files changed:
lua/snort_defaults.lua
src/service_inspectors/dce_rpc/dce_co.cc
src/service_inspectors/dce_rpc/dce_common.h
src/service_inspectors/dce_rpc/dce_smb.cc
src/service_inspectors/dce_rpc/dce_smb.h
src/service_inspectors/dce_rpc/dce_smb_module.cc
src/service_inspectors/dce_rpc/dce_tcp.cc
src/service_inspectors/dce_rpc/dce_tcp.h
src/service_inspectors/dce_rpc/dce_tcp_module.cc
src/service_inspectors/dce_rpc/dce_udp.cc
src/service_inspectors/dce_rpc/dce_udp.h
src/service_inspectors/dce_rpc/dce_udp_module.cc
src/service_inspectors/dce_rpc/dce_udp_processing.cc
src/service_inspectors/dce_rpc/dev_notes.txt
src/service_inspectors/wizard/CMakeLists.txt
src/service_inspectors/wizard/Makefile.am
src/service_inspectors/wizard/curses.cc [new file with mode: 0644]
src/service_inspectors/wizard/curses.h [new file with mode: 0644]
src/service_inspectors/wizard/dev_notes.txt
src/service_inspectors/wizard/wiz_module.cc
src/service_inspectors/wizard/wiz_module.h
src/service_inspectors/wizard/wizard.cc
tools/snort2lua/preprocessor_states/pps_dcerpc.cc
tools/snort2lua/preprocessor_states/pps_dcerpc_server.cc
tools/snort2lua/preprocessor_states/pps_dcerpc_server.h

index bc98c0fd6682d83bed1ca521bfe78d7272ea2508..8b04587053d87d9d7412ae2651e8d1f1e4c6f298 100644 (file)
@@ -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'}
 }
 
 ---------------------------------------------------------------------------
index 1fd323f8217369f277d6f2fb1b2c73773a9b81d9..45ed502e0dc430d1ebdfd6634ae01d5743742c8b 100644 (file)
@@ -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);
         }
index 047ed5ff90b8d4d0bc8a959283ea84ac8d1e6df2..f868a3d98951105d05c080cff77953ebaca85c68 100644 (file)
@@ -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;
index 4d2522c46d7af81415e0f6f39f8af5154accb8bf..24690c7a1a252ee1f1349c05a96bb2ec8867f40b 100644 (file)
@@ -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;
     }
index 20b24429c4b4a887ade13f692a9771f1927704e7..beaca6bf1041b09762b8e8cb5840991c1510b7bc 100644 (file)
 
 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;
index e15d41f4b8ba7546097370cac35acdba4faa4e5d..1ee6b3ec1403b6e5597bf88571f442e3b66e7fbd 100644 (file)
@@ -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" },
index 1e54c2fb9678fbd58c21a54c03e25352cae7a233..428d9f9b30070f92257aec1bcf77efffafe6fe9d 100644 (file)
@@ -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;
     }
index 036ac7c38ca1fff81db6ea6f790def18a0e4ee79..7766b5a08027a63a244a8fd2d38efae16e25b824 100644 (file)
 
 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;
index 7a1d2050ab07cc9d271a58e38c7aab52466a8527..22789ee3da863b2b32ae82cca552340b660b62ee 100644 (file)
@@ -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" },
index 2032832d6a3ae42f919594e72f9f362b9212624b..234e2c827cad4fecf6fb03c13e01892492e294c5 100644 (file)
@@ -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;
     }
index 13f2011742bc01720962752d6013cd63937e58e4..d11a039bb0382562633e32aef34a9877954ee43a 100644 (file)
@@ -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;
index 7e56fe4e1703560c0b983819a926721573abefc4..14057b2a8fee0b08f349747ec669e984ee921432 100644 (file)
@@ -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" },
index e7a4fbd5bbbd38fecbf9369315d750451ba53398..87acb142035433077d67a0bb073a795ac3a2fcb3 100644 (file)
@@ -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,
index 115c98c1a8e36813bea30c273227486747cde493..2b4bd9302fedfb77ebbcef35c2f93ad1350f6f16 100644 (file)
@@ -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.
index 689525e306b7fe4c69295bb62b6d652cf8042da9..ed29ff99a9848ceeed8567aca4e5cd4b7df5ff1f 100644 (file)
@@ -1,5 +1,7 @@
 
 set(FILE_LIST
+    curses.cc
+    curses.h
     magic.cc
     magic.h
     hexes.cc
index 673dcccc0f949f042e15fd26331666683e9f7d32..b8c7b33e55530b875bab53625b3c22f09d278818 100644 (file)
@@ -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 (file)
index 0000000..853c1cc
--- /dev/null
@@ -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 <mdagon@cisco.com>
+
+#include "curses.h"
+
+#include <ctype.h>
+#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<string, CurseDetails> 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 (file)
index 0000000..cbfe726
--- /dev/null
@@ -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 <mdagon@cisco.com>
+
+#ifndef CURSES_H
+#define CURSES_H
+
+#include <ctype.h>
+#include <map>
+#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<std::string, CurseDetails > curse_map;
+
+#endif
+
index 7caf74daf3b7f1d9d3145d41e39f779bb329dabf..a87cdfc0d867e1fbceae4270bbd8f2cdd16c1089 100644 (file)
@@ -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.
index 413df4a633e09b071e6a91550cd67c3997a4525c..1cde6e921f853e3b74cf689ad37a27fe789b0090 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <string>
 
+#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();
 
index d4edff0d8a3db2bb4bb40356eeb9eded8d80dcd9..8af4a7761fec65594bab72fe466a758cee951e21 100644 (file)
@@ -53,6 +53,10 @@ public:
     ProfileStats* get_profile() const override;
 
     MagicBook* get_book(bool c2s, bool hex);
+    std::vector<std::string> get_curse_book()
+    {
+        return curses;
+    }
 
 private:
     void add_spells(MagicBook*, std::string&);
@@ -63,6 +67,7 @@ private:
 
     std::string service;
     std::vector<std::string> spells;
+    std::vector<std::string> curses;
 
     MagicBook* c2s_hexes;
     MagicBook* s2c_hexes;
index 43b972db591cd5ea431f7a2fdd5e7129461e56b7..5b641997911a6f4f183ec5d70d9b5202bf27900a 100644 (file)
@@ -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<CurseServiceTracker> 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<CurseServiceTracker>&,Flow*, const uint8_t*, unsigned);
 
 public:
     MagicBook* c2s_hexes;
@@ -110,6 +119,7 @@ public:
 
     MagicBook* c2s_spells;
     MagicBook* s2c_spells;
+    vector<string> curse_book;
 };
 
 //-------------------------------------------------------------------------
@@ -129,6 +139,10 @@ MagicSplitter::MagicSplitter(bool c2s, class Wizard* w) :
 MagicSplitter::~MagicSplitter()
 {
     wizard->rem_ref();
+
+    // release trackers
+    for (unsigned i=0; i<wand.curse_tracker.size(); i++)
+        delete wand.curse_tracker[i].tracker;
 }
 
 // FIXIT-M stop search on hit and failure (no possible match)
@@ -155,6 +169,7 @@ Wizard::Wizard(WizardModule* m)
 
     c2s_spells = m->get_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<CurseServiceTracker>& 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
 //-------------------------------------------------------------------------
index 700087999d5801095267fcc1743a83fff163fd98..69496cc7ac52a0664400d1e39b25df15a4370ec5 100644 (file)
@@ -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;
 }
index e2c95a3d0c35507e86545bf6f99134ff7e26a071..73e88e67b78288dfe61faa0f45dfc213ba2445b4 100644 (file)
@@ -56,17 +56,6 @@ std::map <std::string, std::vector<uint16_t> > default_ports
     }
 };
 
-// FIXIT-M change to full range - 1025:
-std::map <std::string, std::vector<uint16_t> > 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<std::string,Bin
     }
 }
 
-// FIXIT-M for now add autodetect ports to binder just like regular detect port.
-// Change autodetect ports to full range once they are supported
-void DcerpcServer::add_default_autodetect_ports(std::string type,  std::map<std::string,
-    Binder*> 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<std::string,
-    Binder*> 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;
index 661e533df64a7ff58c3f300e69656d6fca348e94..cfb2c9275e4a277dc2a0c1722be1e49d836dc538 100644 (file)
@@ -48,9 +48,8 @@ private:
     bool parse_detect(std::istringstream& data_stream, std::map<std::string, Binder*> bind, bool
         is_detect);
     void add_default_ports(std::string type, std::map<std::string, Binder*> bind);
-    void add_default_autodetect_ports(std::string type, std::map<std::string, Binder*> bind);
     bool parse_and_add_ports(std::string ports, std::string type,  std::map<std::string,
-        Binder*> 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<std::string,
@@ -70,6 +69,9 @@ bool add_option_to_table(
 
 bool add_option_to_table(
     TableApi&, std::string table_name, std::string option, const bool val);
+
+bool add_deleted_comment_to_table(
+    TableApi&, std::string table_name, std::string option);
 } // namespace dce
 } // namespace preprocessors