]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #643 in SNORT/snort3 from dce_udp_autodetect to master
authorMichael Altizer (mialtize) <mialtize@cisco.com>
Thu, 29 Sep 2016 18:31:53 +0000 (14:31 -0400)
committerMichael Altizer (mialtize) <mialtize@cisco.com>
Thu, 29 Sep 2016 18:31:53 +0000 (14:31 -0400)
Squashed commit of the following:

commit 75280120e229d16a4137908587d900b34ff14c15
Author: mdagon <mdagon@cisco.com>
Date:   Thu Sep 29 13:17:45 2016 -0400

    Code review

commit 378da827dc3aa45f2367b47b61fd9f176370d260
Author: mdagon <mdagon@cisco.com>
Date:   Tue Sep 27 15:25:47 2016 -0400

    dce_udp autodetect and session creation

src/main/snort_debug.h
src/service_inspectors/dce_rpc/dce_udp.cc
src/service_inspectors/dce_rpc/dce_udp.h
src/service_inspectors/dce_rpc/dce_utils.h

index 540add35ad9aedbda985fd8d700341c6c5fa6192..4f9ebf288efd6ebcc3db01afaa8fbed84487bb5c 100644 (file)
@@ -94,6 +94,7 @@
 #define DEBUG_PIGLET          0x0800000000000000LL
 #endif
 
+#define DEBUG_DCE_UDP         0x1000000000000000LL
 
 #ifdef DEBUG_MSGS
 
@@ -102,7 +103,8 @@ class SO_PUBLIC Debug
 public:
     static bool enabled(uint64_t flag);
 
-    static void print(const char* file, int line, uint64_t dbg, const char* fmt, ...) __attribute__((format (printf, 4, 5)));
+    static void print(const char* file, int line, uint64_t dbg, const char* fmt,
+        ...) __attribute__((format (printf, 4, 5)));
 
 private:
     static bool init;
@@ -127,3 +129,4 @@ private:
 #endif
 
 #endif
+
index 4e499716deeec020e7d71be7730d0b706e7ecff3..984561e04f1587dabec4b1710b3538425f78573a 100644 (file)
@@ -40,6 +40,40 @@ THREAD_LOCAL ProfileStats dce2_udp_pstat_cl_acts;
 THREAD_LOCAL ProfileStats dce2_udp_pstat_cl_frag;
 THREAD_LOCAL ProfileStats dce2_udp_pstat_cl_reass;
 
+void DCE2_ClCleanTracker(DCE2_ClTracker* clt)
+{
+    if (clt == nullptr)
+        return;
+
+    /* Destroy activity trackers list - this will have the
+     * effect of freeing everything inside of it */
+    DCE2_ListDestroy(clt->act_trackers);
+    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
 //-------------------------------------------------------------------------
@@ -49,11 +83,91 @@ Dce2UdpFlowData::Dce2UdpFlowData() : FlowData(flow_id)
 
 Dce2UdpFlowData::~Dce2UdpFlowData()
 {
-    // FIXIT-M add cl_tracker cleanup
+    DCE2_ClCleanTracker(&dce2_udp_session.cl_tracker);
 }
 
 unsigned Dce2UdpFlowData::flow_id = 0;
 
+DCE2_UdpSsnData* get_dce2_udp_session_data(Flow* flow)
+{
+    Dce2UdpFlowData* fd = (Dce2UdpFlowData*)flow->get_flow_data(Dce2UdpFlowData::flow_id);
+    return fd ? &fd->dce2_udp_session : nullptr;
+}
+
+static DCE2_UdpSsnData* set_new_dce2_udp_session(Packet* p)
+{
+    Dce2UdpFlowData* fd = new Dce2UdpFlowData;
+
+    memset(&fd->dce2_udp_session,0,sizeof(DCE2_UdpSsnData));
+    p->flow->set_flow_data(fd);
+    return(&fd->dce2_udp_session);
+}
+
+static DCE2_UdpSsnData* dce2_create_new_udp_session(Packet* p, dce2UdpProtoConf* config)
+{
+    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");
+
+        dce2_udp_sess = set_new_dce2_udp_session(p);
+
+        DCE2_ResetRopts(&dce2_udp_sess->sd.ropts);
+
+        dce2_udp_stats.udp_sessions++;
+        DebugFormat(DEBUG_DCE_UDP,"Created (%p)\n", (void*)dce2_udp_sess);
+
+        dce2_udp_sess->sd.trans = DCE2_TRANS_TYPE__UDP;
+        dce2_udp_sess->sd.wire_pkt = p;
+        dce2_udp_sess->sd.config = (void*)config;
+
+        DCE2_SsnSetAutodetected(&dce2_udp_sess->sd, p);
+    }
+
+    return dce2_udp_sess;
+}
+
+static DCE2_UdpSsnData* dce2_handle_udp_session(Packet* p, dce2UdpProtoConf* config)
+{
+    Profile profile(dce2_udp_pstat_session);
+
+    DCE2_UdpSsnData* dce2_udp_sess =  get_dce2_udp_session_data(p->flow);
+
+    if (dce2_udp_sess == nullptr)
+    {
+        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);
+
+    return dce2_udp_sess;
+}
+
 class Dce2Udp : public Inspector
 {
 public:
@@ -75,8 +189,30 @@ void Dce2Udp::show(SnortConfig*)
     print_dce2_udp_conf(config);
 }
 
-void Dce2Udp::eval(Packet*)
+void Dce2Udp::eval(Packet* p)
 {
+    DCE2_UdpSsnData* dce2_udp_sess;
+    Profile profile(dce2_udp_pstat_main);
+    if (DCE2_SsnFromServer(p))
+    {
+        DebugMessage(DEBUG_DCE_UDP, "Packet from Server.\n");
+    }
+    else
+    {
+        DebugMessage(DEBUG_DCE_UDP, "Packet from Client.\n");
+    }
+
+    assert(p->flow);
+
+    dce2_udp_sess = dce2_handle_udp_session(p, &config);
+
+    if (dce2_udp_sess)
+    {
+        dce2_udp_stats.udp_pkts++;
+
+        if (!DCE2_SsnAutodetected(&dce2_udp_sess->sd))
+            DisableInspection();
+    }
 }
 
 //-------------------------------------------------------------------------
index ccf38cdc258e7e212ab1b6c8c84efd0ebeb2616f..c084c16dd5b84b149893fa075e61950386211c2b 100644 (file)
@@ -75,6 +75,50 @@ extern THREAD_LOCAL ProfileStats dce2_udp_pstat_cl_acts;
 extern THREAD_LOCAL ProfileStats dce2_udp_pstat_cl_frag;
 extern THREAD_LOCAL ProfileStats dce2_udp_pstat_cl_reass;
 
+struct DceRpcClHdr   /* Connectionless header */
+{
+    uint8_t rpc_vers;
+    uint8_t ptype;
+    uint8_t flags1;
+    uint8_t flags2;
+    uint8_t drep[3];
+    uint8_t serial_hi;
+    Uuid object;
+    Uuid if_id;
+    Uuid act_id;
+    uint32_t server_boot;
+    uint32_t if_vers;
+    uint32_t seqnum;
+    uint16_t opnum;
+    uint16_t ihint;
+    uint16_t ahint;
+    uint16_t len;
+    uint16_t fragnum;
+    uint8_t auth_proto;
+    uint8_t serial_lo;
+
+};
+
+inline uint8_t DceRpcClRpcVers(const DceRpcClHdr *cl)
+{
+    return cl->rpc_vers;
+}
+
+inline uint8_t DceRpcClPduType(const DceRpcClHdr *cl)
+{
+    return cl->ptype;
+}
+
+inline DceRpcBoFlag DceRpcClByteOrder(const DceRpcClHdr *cl)
+{
+    return DceRpcByteOrder(cl->drep[0]);
+}
+
+inline uint16_t DceRpcClLen(const DceRpcClHdr *cl)
+{
+    return DceRpcNtohs(&cl->len, DceRpcClByteOrder(cl));
+}
+
 struct DCE2_ClTracker
 {
     DCE2_List* act_trackers;  /* List of activity trackers */
@@ -102,5 +146,7 @@ public:
     DCE2_UdpSsnData dce2_udp_session;
 };
 
+DCE2_UdpSsnData* get_dce2_udp_session_data(Flow*);
+
 #endif
 
index e821c23f58803485833dc9c44293fe3076563335..92d0bc374daea1fc4df914df4bea7703275c0ce4 100644 (file)
@@ -54,6 +54,7 @@ enum DCE2_TransType
     DCE2_TRANS_TYPE__NONE = 0,
     DCE2_TRANS_TYPE__SMB,
     DCE2_TRANS_TYPE__TCP,
+    DCE2_TRANS_TYPE__UDP,
     DCE2_TRANS_TYPE__MAX
 };