]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #240 in SNORT/snort3 from dcerpc to master
authorRuss Combs (rucombs) <rucombs@cisco.com>
Tue, 9 Feb 2016 04:22:21 +0000 (23:22 -0500)
committerRuss Combs (rucombs) <rucombs@cisco.com>
Tue, 9 Feb 2016 04:22:21 +0000 (23:22 -0500)
Squashed commit of the following:

commit 4f51d158cf3c8f7c2b430476c43ea446bae82c3d
Author: rrp <rrp@cisco.com>
Date:   Mon Feb 8 16:21:35 2016 -0500

    Changes from more CR comments

commit e3bf17154e79721bfc54a1b6a0e7782eb196ad7b
Author: rrp <rrp@cisco.com>
Date:   Mon Feb 8 09:34:27 2016 -0500

    Changes based on CR feedback

commit 0fa0a226f2bf45e9a006dbbbfcffd40da3cd1460
Author: rrp <rrp@cisco.com>
Date:   Fri Jan 29 15:02:26 2016 -0500

    DCE2 PAF and autodetect for TCP and SMB.
    Testing done with basic non-fragmented TCP and SMB traffic and verified with
    debugs that PAF and the preprocessor autodetect the packet correctly and that
    PAF determines the flush point correctly. Coverage between 85 and 90 %.

26 files changed:
src/main/snort_debug.h
src/service_inspectors/dce_rpc/CMakeLists.txt
src/service_inspectors/dce_rpc/Makefile.am
src/service_inspectors/dce_rpc/dce2_common.h [deleted file]
src/service_inspectors/dce_rpc/dce_co.h [moved from src/service_inspectors/dce_rpc/dce2_co.h with 77% similarity]
src/service_inspectors/dce_rpc/dce_common.cc [moved from src/service_inspectors/dce_rpc/dce2_common.cc with 84% similarity]
src/service_inspectors/dce_rpc/dce_common.h [new file with mode: 0644]
src/service_inspectors/dce_rpc/dce_list.cc [moved from src/service_inspectors/dce_rpc/dce2_list.cc with 99% similarity]
src/service_inspectors/dce_rpc/dce_list.h [moved from src/service_inspectors/dce_rpc/dce2_list.h with 98% similarity]
src/service_inspectors/dce_rpc/dce_smb.cc [moved from src/service_inspectors/dce_rpc/dce2_smb.cc with 83% similarity]
src/service_inspectors/dce_rpc/dce_smb.h [moved from src/service_inspectors/dce_rpc/dce2_smb.h with 72% similarity]
src/service_inspectors/dce_rpc/dce_smb_module.cc [moved from src/service_inspectors/dce_rpc/dce2_smb_module.cc with 99% similarity]
src/service_inspectors/dce_rpc/dce_smb_module.h [moved from src/service_inspectors/dce_rpc/dce2_smb_module.h with 94% similarity]
src/service_inspectors/dce_rpc/dce_smb_paf.cc [new file with mode: 0644]
src/service_inspectors/dce_rpc/dce_smb_paf.h [new file with mode: 0644]
src/service_inspectors/dce_rpc/dce_tcp.cc [moved from src/service_inspectors/dce_rpc/dce2_tcp.cc with 79% similarity]
src/service_inspectors/dce_rpc/dce_tcp.h [moved from src/service_inspectors/dce_rpc/dce2_tcp.h with 69% similarity]
src/service_inspectors/dce_rpc/dce_tcp_module.cc [moved from src/service_inspectors/dce_rpc/dce2_tcp_module.cc with 98% similarity]
src/service_inspectors/dce_rpc/dce_tcp_module.h [moved from src/service_inspectors/dce_rpc/dce2_tcp_module.h with 95% similarity]
src/service_inspectors/dce_rpc/dce_tcp_paf.cc [new file with mode: 0644]
src/service_inspectors/dce_rpc/dce_tcp_paf.h [new file with mode: 0644]
src/service_inspectors/dce_rpc/dce_utils.cc [moved from src/service_inspectors/dce_rpc/dce2_utils.cc with 99% similarity]
src/service_inspectors/dce_rpc/dce_utils.h [moved from src/service_inspectors/dce_rpc/dce2_utils.h with 99% similarity]
src/service_inspectors/dce_rpc/ips_dce_iface.cc [moved from src/service_inspectors/dce_rpc/ips_dce2_iface.cc with 99% similarity]
src/service_inspectors/dce_rpc/ips_dce_opnum.cc [moved from src/service_inspectors/dce_rpc/ips_dce2_opnum.cc with 99% similarity]
src/service_inspectors/dce_rpc/ips_dce_stub_data.cc [moved from src/service_inspectors/dce_rpc/ips_dce2_stub_data.cc with 98% similarity]

index 7682d6b9676116bf0bfcfdb72e7369816de4b4b9..4365c7df228748cfdb2f123a5a0dbb72ef82757d 100644 (file)
 #define DEBUG_MPSE            0x0010000000000000LL
 #define DEBUG_SO_RULE         0x0020000000000000LL
 #define DEBUG_LOGGER          0x0040000000000000LL
+#define DEBUG_DCE_TCP         0x0080000000000000LL
+#define DEBUG_DCE_SMB         0x0100000000000000LL
 
 #ifdef PIGLET
-#define DEBUG_PIGLET          0x0080000000000000LL
+#define DEBUG_PIGLET          0x0200000000000000LL
 #endif
 
+
 #ifdef DEBUG_MSGS
 
 class SO_PUBLIC Debug
index 144a9142d9d8f4baa71b23910d1f09e0cfa18d84..d64aad13812438eeab828a806019403ee87cbc8c 100644 (file)
@@ -1,23 +1,27 @@
 
 set( FILE_LIST
-   dce2_co.h 
-   dce2_common.cc 
-   dce2_common.h 
-   dce2_list.h
-   dce2_list.cc
-   dce2_smb.cc 
-   dce2_smb.h 
-   dce2_smb_module.cc 
-   dce2_smb_module.h 
-   dce2_tcp.cc
-   dce2_tcp.h 
-   dce2_tcp_module.cc 
-   dce2_tcp_module.h 
-   dce2_utils.cc
-   dce2_utils.h
-   ips_dce2_iface.cc
-   ips_dce2_opnum.cc
-   ips_dce2_stub_data.cc
+   dce_co.h 
+   dce_common.cc 
+   dce_common.h 
+   dce_list.h
+   dce_list.cc
+   dce_smb.cc 
+   dce_smb.h 
+   dce_smb_module.cc 
+   dce_smb_module.h 
+   dce_smb_paf.cc 
+   dce_smb_paf.h 
+   dce_tcp.cc
+   dce_tcp.h 
+   dce_tcp_module.cc 
+   dce_tcp_module.h 
+   dce_tcp_paf.cc 
+   dce_tcp_paf.h 
+   dce_utils.cc
+   dce_utils.h
+   ips_dce_iface.cc
+   ips_dce_opnum.cc
+   ips_dce_stub_data.cc
 
 )
 
index f4e149883d827dbda7cb67cd1a2bf63ffa767290..7db794e998cd17baab48b62f5f94958f040bad67 100644 (file)
@@ -1,22 +1,26 @@
 file_list = \
-dce2_co.h \
-dce2_common.cc \
-dce2_common.h \
-dce2_list.cc \
-dce2_list.h \
-dce2_smb.cc \
-dce2_smb.h \
-dce2_smb_module.cc \
-dce2_smb_module.h \
-dce2_tcp.cc\
-dce2_tcp.h \
-dce2_tcp_module.cc \
-dce2_tcp_module.h \
-dce2_utils.cc \
-dce2_utils.h \
-ips_dce2_iface.cc \
-ips_dce2_opnum.cc \
-ips_dce2_stub_data.cc
+dce_co.h \
+dce_common.cc \
+dce_common.h \
+dce_list.cc \
+dce_list.h \
+dce_smb.cc \
+dce_smb.h \
+dce_smb_module.cc \
+dce_smb_module.h \
+dce_smb_paf.cc \
+dce_smb_paf.h \
+dce_tcp.cc\
+dce_tcp.h \
+dce_tcp_module.cc \
+dce_tcp_module.h \
+dce_tcp_paf.cc \
+dce_tcp_paf.h \
+dce_utils.cc \
+dce_utils.h \
+ips_dce_iface.cc \
+ips_dce_opnum.cc \
+ips_dce_stub_data.cc
 
 
 if STATIC_INSPECTORS
diff --git a/src/service_inspectors/dce_rpc/dce2_common.h b/src/service_inspectors/dce_rpc/dce2_common.h
deleted file mode 100644 (file)
index 552b955..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-//--------------------------------------------------------------------------
-// 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.
-//-------------------------------------------------------------------------
-
-//dce2_common.h author Rashmi Pitre <rrp@cisco.com>
-
-#ifndef DCE2_COMMON_H
-#define DCE2_COMMON_H
-
-#include "main/snort_types.h"
-#include "framework/module.h"
-#include "framework/inspector.h"
-
-extern const InspectApi dce2_smb_api;
-extern const InspectApi dce2_tcp_api;
-
-#define GID_DCE2 145
-
-enum DCE2_POLICY
-{
-    DCE2_POLICY__WIN2000 = 0,
-    DCE2_POLICY__WINXP,
-    DCE2_POLICY__WINVISTA,
-    DCE2_POLICY__WIN2003,
-    DCE2_POLICY__WIN2008,
-    DCE2_POLICY__WIN7,
-    DCE2_POLICY__SAMBA,
-    DCE2_POLICY__SAMBA_3_0_37,
-    DCE2_POLICY__SAMBA_3_0_22,
-    DCE2_POLICY__SAMBA_3_0_20,
-};
-
-#define DCE2_SARG__POLICY_WIN2000       "Win2000"
-#define DCE2_SARG__POLICY_WINXP         "WinXP"
-#define DCE2_SARG__POLICY_WINVISTA      "WinVista"
-#define DCE2_SARG__POLICY_WIN2003       "Win2003"
-#define DCE2_SARG__POLICY_WIN2008       "Win2008"
-#define DCE2_SARG__POLICY_WIN7          "Win7"
-#define DCE2_SARG__POLICY_SAMBA         "Samba"
-#define DCE2_SARG__POLICY_SAMBA_3_0_37  "Samba-3.0.37"  /* Samba version 3.0.37 and previous */
-#define DCE2_SARG__POLICY_SAMBA_3_0_22  "Samba-3.0.22"  /* Samba version 3.0.22 and previous */
-#define DCE2_SARG__POLICY_SAMBA_3_0_20  "Samba-3.0.20"  /* Samba version 3.0.20 and previous */
-
-struct dce2CommonProtoConf
-{
-    bool disable_defrag;
-    uint16_t max_frag_len;
-    DCE2_POLICY policy;
-};
-
-bool dce2_set_common_config(Value&, dce2CommonProtoConf&);
-void print_dce2_common_config(dce2CommonProtoConf&);
-
-#endif
-
similarity index 77%
rename from src/service_inspectors/dce_rpc/dce2_co.h
rename to src/service_inspectors/dce_rpc/dce_co.h
index c46152e3a7ef17dd2c1fa9f459ced62437bec8af..3bcab948953d79ce42af173d085d8ddcbbbede9e 100644 (file)
 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 //--------------------------------------------------------------------------
 
-// dce2_co.h author Rashmi Pitre <rrp@cisco.com>
+// dce_co.h author Rashmi Pitre <rrp@cisco.com>
 // based on work by Todd Wease
 
-#ifndef DCE2_CO_H
-#define DCE2_CO_H
+#ifndef DCE_CO_H
+#define DCE_CO_H
+
+#include "dce_common.h"
 
 #define DCE2_CO_BAD_MAJOR_VERSION           27
 #define DCE2_CO_BAD_MINOR_VERSION           28
@@ -65,5 +67,52 @@ from opnum established for fragmented request."
     "Connection-oriented DCE/RPC - Context id of non first/last fragment different \
 from context id established for fragmented request."
 
+#pragma pack(1)
+
+struct DceRpcCoVersion
+{
+    uint8_t major;
+    uint8_t minor;
+};
+
+/* Connection oriented common header */
+struct DceRpcCoHdr
+{
+    DceRpcCoVersion pversion;
+    uint8_t ptype;
+    uint8_t pfc_flags;
+    uint8_t packed_drep[4];
+    uint16_t frag_length;
+    uint16_t auth_length;
+    uint32_t call_id;
+};
+
+#pragma pack()
+
+static inline uint8_t DceRpcCoVersMaj(const DceRpcCoHdr* co)
+{
+    return co->pversion.major;
+}
+
+static inline uint8_t DceRpcCoVersMin(const DceRpcCoHdr* co)
+{
+    return co->pversion.minor;
+}
+
+static inline DceRpcPduType DceRpcCoPduType(const DceRpcCoHdr* co)
+{
+    return (DceRpcPduType)co->ptype;
+}
+
+static inline DceRpcBoFlag DceRpcCoByteOrder(const DceRpcCoHdr* co)
+{
+    return DceRpcByteOrder(co->packed_drep[0]);
+}
+
+static inline uint16_t DceRpcCoFragLen(const DceRpcCoHdr* co)
+{
+    return DceRpcNtohs(&co->frag_length, DceRpcCoByteOrder(co));
+}
+
 #endif
 
similarity index 84%
rename from src/service_inspectors/dce_rpc/dce2_common.cc
rename to src/service_inspectors/dce_rpc/dce_common.cc
index 76781354d47c01cfece2494d9a9a61ad4a12233c..09d237336f520c4439c93b8dc7e0566a75de19e6 100644 (file)
 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 //--------------------------------------------------------------------------
 
-// dce2_common.cc author Rashmi Pitre <rrp@cisco.com>
+// dce_common.cc author Rashmi Pitre <rrp@cisco.com>
 
-#include "dce2_common.h"
-#include "framework/module.h"
+#include "dce_common.h"
 #include "framework/base_api.h"
+#include "framework/module.h"
+#include "flow/flow.h"
 #include "log/messages.h"
+#include "main/snort_debug.h"
 
 const char* dce2_get_policy_name(DCE2_POLICY policy)
 {
@@ -90,6 +92,25 @@ void print_dce2_common_config(dce2CommonProtoConf& common)
         dce2_get_policy_name(common.policy));
 }
 
+bool dce2_paf_abort(Flow* flow)
+{
+    if (flow->get_session_flags() & SSNFLAG_MIDSTREAM)
+    {
+        DebugMessage(DEBUG_DCE_TCP,
+            "Aborting PAF because of midstream pickup.\n");
+        return true;
+    }
+    else if (!(flow->get_session_flags() & SSNFLAG_ESTABLISHED))
+    {
+        DebugMessage(DEBUG_DCE_TCP,
+            "Aborting PAF because of unestablished session.\n");
+        return true;
+    }
+    // FIXIT-M add the remaining checks
+
+    return false;
+}
+
 #ifdef BUILDING_SO
 
 extern const BaseApi* ips_dce_iface;
diff --git a/src/service_inspectors/dce_rpc/dce_common.h b/src/service_inspectors/dce_rpc/dce_common.h
new file mode 100644 (file)
index 0000000..637162c
--- /dev/null
@@ -0,0 +1,194 @@
+//--------------------------------------------------------------------------
+// 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.
+//-------------------------------------------------------------------------
+
+//dce_common.h author Rashmi Pitre <rrp@cisco.com>
+
+#ifndef DCE_COMMON_H
+#define DCE_COMMON_H
+
+#include "dce_utils.h"
+#include "main/snort_types.h"
+#include "framework/module.h"
+#include "framework/inspector.h"
+
+extern const InspectApi dce2_smb_api;
+extern const InspectApi dce2_tcp_api;
+
+#define GID_DCE2 145
+
+enum DCE2_POLICY
+{
+    DCE2_POLICY__WIN2000 = 0,
+    DCE2_POLICY__WINXP,
+    DCE2_POLICY__WINVISTA,
+    DCE2_POLICY__WIN2003,
+    DCE2_POLICY__WIN2008,
+    DCE2_POLICY__WIN7,
+    DCE2_POLICY__SAMBA,
+    DCE2_POLICY__SAMBA_3_0_37,
+    DCE2_POLICY__SAMBA_3_0_22,
+    DCE2_POLICY__SAMBA_3_0_20,
+};
+
+#define DCE2_SARG__POLICY_WIN2000       "Win2000"
+#define DCE2_SARG__POLICY_WINXP         "WinXP"
+#define DCE2_SARG__POLICY_WINVISTA      "WinVista"
+#define DCE2_SARG__POLICY_WIN2003       "Win2003"
+#define DCE2_SARG__POLICY_WIN2008       "Win2008"
+#define DCE2_SARG__POLICY_WIN7          "Win7"
+#define DCE2_SARG__POLICY_SAMBA         "Samba"
+#define DCE2_SARG__POLICY_SAMBA_3_0_37  "Samba-3.0.37"  /* Samba version 3.0.37 and previous */
+#define DCE2_SARG__POLICY_SAMBA_3_0_22  "Samba-3.0.22"  /* Samba version 3.0.22 and previous */
+#define DCE2_SARG__POLICY_SAMBA_3_0_20  "Samba-3.0.20"  /* Samba version 3.0.20 and previous */
+
+struct dce2CommonProtoConf
+{
+    bool disable_defrag;
+    uint16_t max_frag_len;
+    DCE2_POLICY policy;
+};
+
+#define DCE2_DEBUG__PAF_END_MSG    "=========================================================="
+
+/* DCE/RPC byte order flag */
+enum DceRpcBoFlag
+{
+    DCERPC_BO_FLAG__NONE,
+    DCERPC_BO_FLAG__BIG_ENDIAN,
+    DCERPC_BO_FLAG__LITTLE_ENDIAN
+};
+
+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
+};
+
+struct DCE2_Roptions
+{
+    /* dce_iface */
+    int first_frag;    /* Set to sentinel if not applicable */
+    Uuid iface;
+    /* For connectionless */
+    uint32_t iface_vers;        /* For connectionless */
+
+    /* For connection-oriented */
+    uint16_t iface_vers_maj;
+    uint16_t iface_vers_min;
+
+    /* dce_opnum */
+    int opnum;    /* Set to sentinel if not applicable */
+
+    /* dce_byte_test */
+    int hdr_byte_order;   /* Set to sentinel if not applicable */
+    int data_byte_order;  /* Set to sentinel if not applicable */
+
+    /* dce_stub_data */
+    const uint8_t* stub_data;  /* Set to NULL if not applicable */
+};
+
+struct DCE2_SsnData
+{
+    DCE2_POLICY server_policy;
+    DCE2_POLICY client_policy;
+    int flags;
+    const Packet* wire_pkt;
+    uint64_t alert_mask;
+    DCE2_Roptions ropts;
+    int autodetect_dir;
+
+    uint32_t cli_seq;
+    uint32_t cli_nseq;
+    uint32_t srv_seq;
+    uint32_t srv_nseq;
+};
+
+inline DceRpcBoFlag DceRpcByteOrder(const uint8_t value)
+{
+    if ((value & 0x10) >> 4)
+        return DCERPC_BO_FLAG__LITTLE_ENDIAN;
+
+    return DCERPC_BO_FLAG__BIG_ENDIAN;
+}
+
+inline uint16_t DceRpcNtohs(const uint16_t* ptr, const DceRpcBoFlag bo_flag)
+{
+    uint16_t value;
+
+    if (ptr == NULL)
+        return 0;
+
+#ifdef WORDS_MUSTALIGN
+    value = *((uint8_t*)ptr) << 8 | *((uint8_t*)ptr + 1);
+#else
+    value = *ptr;
+#endif  /* WORDS_MUSTALIGN */
+
+    if (bo_flag == DCERPC_BO_FLAG__NONE)
+        return value;
+
+#ifdef WORDS_BIGENDIAN
+    if (bo_flag == DCERPC_BO_FLAG__BIG_ENDIAN)
+#else
+    if (bo_flag == DCERPC_BO_FLAG__LITTLE_ENDIAN)
+#endif  /* WORDS_BIGENDIAN */
+        return value;
+
+    return ((value & 0xff00) >> 8) | ((value & 0x00ff) << 8);
+}
+
+bool dce2_set_common_config(Value&, dce2CommonProtoConf&);
+void print_dce2_common_config(dce2CommonProtoConf&);
+bool dce2_paf_abort(Flow*);
+
+#endif
+
similarity index 99%
rename from src/service_inspectors/dce_rpc/dce2_list.cc
rename to src/service_inspectors/dce_rpc/dce_list.cc
index b8114d499cd998ee4455d95c753c0f6a53d80661..bc484f331fc5964e23786729c7ab0468dffdc3a2 100644 (file)
@@ -25,8 +25,8 @@
  *
  ****************************************************************************/
 
-#include "dce2_list.h"
-#include "dce2_utils.h"
+#include "dce_list.h"
+#include "dce_utils.h"
 
 #include "log/messages.h"
 #include "utils/util.h"
similarity index 98%
rename from src/service_inspectors/dce_rpc/dce2_list.h
rename to src/service_inspectors/dce_rpc/dce_list.h
index cd55b35a5e66ca319a33ab9c2c76488ba6725fc8..e0be02d3081ccbbea6bba9d41b4c87dd28f8d5b5 100644 (file)
 *
 ****************************************************************************/
 
-#ifndef _DCE2_LIST_H_
-#define _DCE2_LIST_H_
+#ifndef _DCE_LIST_H_
+#define _DCE_LIST_H_
 
-#include "dce2_utils.h"
+#include "dce_utils.h"
 
 #include "main/snort_types.h"
 
similarity index 83%
rename from src/service_inspectors/dce_rpc/dce2_smb.cc
rename to src/service_inspectors/dce_rpc/dce_smb.cc
index 0bd9fc1760c81275a53efd1a71ba95e8880d9a8a..90fe7f53136c5e4c862c9fbc7bf90c89551ddc86 100644 (file)
 
 // dce_smb.cc author Rashmi Pitre <rrp@cisco.com>
 
-#include "dce2_smb.h"
-#include "dce2_smb_module.h"
-#include "dce2_list.h"
+#include "dce_smb.h"
+#include "dce_smb_paf.h"
+#include "dce_smb_module.h"
+#include "dce_list.h"
+#include "main/snort_debug.h"
 
 THREAD_LOCAL dce2SmbStats dce2_smb_stats;
 
@@ -45,6 +47,16 @@ THREAD_LOCAL ProfileStats dce2_smb_pstat_smb_file_api;
 THREAD_LOCAL ProfileStats dce2_smb_pstat_smb_fingerprint;
 THREAD_LOCAL ProfileStats dce2_smb_pstat_smb_negotiate;
 
+unsigned Dce2SmbFlowData::flow_id = 0;
+
+DCE2_SmbSsnData* get_dce2_smb_session_data(Flow* flow)
+{
+    Dce2SmbFlowData* fd = (Dce2SmbFlowData*)flow->get_application_data(
+        Dce2SmbFlowData::flow_id);
+
+    return fd ? &fd->dce2_smb_session : nullptr;
+}
+
 //-------------------------------------------------------------------------
 // class stuff
 //-------------------------------------------------------------------------
@@ -57,6 +69,10 @@ public:
 
     void show(SnortConfig*) override;
     void eval(Packet*) override;
+    StreamSplitter* get_splitter(bool c2s) override
+    {
+        return new Dce2SmbSplitter(c2s);
+    }
 
 private:
     dce2SmbProtoConf config;
@@ -82,7 +98,17 @@ void Dce2Smb::show(SnortConfig*)
 
 void Dce2Smb::eval(Packet* p)
 {
-    UNUSED(p);
+    DCE2_SmbSsnData* dce2_sess = get_dce2_smb_session_data(p->flow);
+
+    if (dce2_sess == nullptr)
+    {
+        /*Check if it is a DCE2 over SMB packet*/
+
+        if (DCE2_SmbAutodetect(p))
+        {
+            DebugMessage(DEBUG_DCE_SMB, "DCE over SMB packet detected\n");
+        }
+    }
 }
 
 //-------------------------------------------------------------------------
similarity index 72%
rename from src/service_inspectors/dce_rpc/dce2_smb.h
rename to src/service_inspectors/dce_rpc/dce_smb.h
index f162ce68f3853159eaf6b949d4bac1fe90acc207..1e42653f903a810ba60486f3d4e781ef604320f8 100644 (file)
 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 //--------------------------------------------------------------------------
 
-//dce2_smb.h author Rashmi Pitre <rrp@cisco.com>
+//dce_smb.h author Rashmi Pitre <rrp@cisco.com>
 // based on work by Todd Wease
 
-#ifndef DCE2_SMB_H
-#define DCE2_SMB_H
+#ifndef DCE_SMB_H
+#define DCE_SMB_H
 
+#include "dce_common.h"
 #include "protocols/packet.h"
 #include "profiler/profiler.h"
 #include "framework/counts.h"
@@ -199,5 +200,128 @@ extern THREAD_LOCAL ProfileStats dce2_smb_pstat_smb_file_detect;
 extern THREAD_LOCAL ProfileStats dce2_smb_pstat_smb_file_api;
 extern THREAD_LOCAL ProfileStats dce2_smb_pstat_smb_fingerprint;
 extern THREAD_LOCAL ProfileStats dce2_smb_pstat_smb_negotiate;
+
+#define NBSS_SESSION_TYPE__MESSAGE            0x00
+#define NBSS_SESSION_TYPE__REQUEST            0x81
+#define NBSS_SESSION_TYPE__POS_RESPONSE       0x82
+#define NBSS_SESSION_TYPE__NEG_RESPONSE       0x83
+#define NBSS_SESSION_TYPE__RETARGET_RESPONSE  0x84
+#define NBSS_SESSION_TYPE__KEEP_ALIVE         0x85
+
+#define DCE2_SMB_ID   0xff534d42  /* \xffSMB */
+#define DCE2_SMB2_ID  0xfe534d42  /* \xfeSMB */
+
+#pragma pack(1)
+
+/********************************************************************
+ * NetBIOS Session Service header
+ ********************************************************************/
+struct NbssHdr
+{
+    uint8_t type;
+    uint8_t flags;   /* Treat flags as the upper byte to length */
+    uint16_t length;
+} ;
+
+struct SmbNtHdr
+{
+    uint8_t smb_idf[4];             /* contains 0xFF, 'SMB' */
+    uint8_t smb_com;                /* command code */
+    union
+    {
+        struct
+        {
+            uint8_t smb_class;      /* dos error class */
+            uint8_t smb_res;        /* reserved for future */
+            uint16_t smb_code;      /* dos error code */
+        } smb_status;
+        uint32_t nt_status;         /* nt status */
+    } smb_status;
+    uint8_t smb_flg;                /* flags */
+    uint16_t smb_flg2;              /* flags */
+    uint16_t smb_pid_high;
+    uint64_t smb_signature;
+    uint16_t smb_res;               /* reserved for future */
+    uint16_t smb_tid;               /* tree id */
+    uint16_t smb_pid;               /* caller's process id */
+    uint16_t smb_uid;               /* authenticated user id */
+    uint16_t smb_mid;               /* multiplex id */
+};
+
+#pragma pack()
+
+struct DCE2_SmbSsnData
+{
+    DCE2_SsnData sd;  // This member must be first
+    // FIXIT-M add all the remaining fields
+};
+
+static inline uint32_t NbssLen(const NbssHdr* nb)
+{
+    /* Treat first bit of flags as the upper byte to length */
+    return ((nb->flags & 0x01) << 16) | ntohs(nb->length);
+}
+
+static inline uint8_t NbssType(const NbssHdr* nb)
+{
+    return nb->type;
+}
+
+static inline uint32_t SmbId(const SmbNtHdr* hdr)
+{
+#ifdef WORDS_MUSTALIGN
+    uint8_t* idf = (uint8_t*)hdr->smb_idf;
+    return *idf << 24 | *(idf + 1) << 16 | *(idf + 2) << 8 | *(idf + 3);
+#else
+    return ntohl(*((uint32_t*)hdr->smb_idf));
+#endif  /* WORDS_MUSTALIGN */
+}
+
+static inline bool DCE2_SmbAutodetect(Packet* p)
+{
+    if (p->dsize > (sizeof(NbssHdr) + sizeof(SmbNtHdr)))
+    {
+        NbssHdr* nb_hdr = (NbssHdr*)p->data;
+
+        switch (NbssType(nb_hdr))
+        {
+        case NBSS_SESSION_TYPE__MESSAGE:
+        {
+            SmbNtHdr* smb_hdr = (SmbNtHdr*)(p->data + sizeof(NbssHdr));
+
+            if ((SmbId(smb_hdr) == DCE2_SMB_ID)
+                || (SmbId(smb_hdr) == DCE2_SMB2_ID))
+            {
+                return true;
+            }
+        }
+
+        break;
+
+        default:
+            break;
+        }
+    }
+
+    return false;
+}
+
+class Dce2SmbFlowData : public FlowData
+{
+public:
+    Dce2SmbFlowData();
+
+    static void init()
+    {
+        flow_id = FlowData::get_flow_id();
+    }
+
+public:
+    static unsigned flow_id;
+    DCE2_SmbSsnData dce2_smb_session;
+};
+
+DCE2_SmbSsnData* get_dce2_smb_session_data(Flow*);
+
 #endif
 
similarity index 99%
rename from src/service_inspectors/dce_rpc/dce2_smb_module.cc
rename to src/service_inspectors/dce_rpc/dce_smb_module.cc
index c293cf06f214d904a2e1796c573fea1c92016ac6..15034100e103ff1e7839fe3ef52c4b475abe5161 100644 (file)
 
 // dce_smb_module.cc author Rashmi Pitre <rrp@cisco.com>
 
-#include "dce2_smb_module.h"
-#include "dce2_smb.h"
-#include "dce2_common.h"
-#include "dce2_co.h"
+#include "dce_smb_module.h"
+#include "dce_smb.h"
+#include "dce_common.h"
+#include "dce_co.h"
 
 #include "main/snort_config.h"
 
similarity index 94%
rename from src/service_inspectors/dce_rpc/dce2_smb_module.h
rename to src/service_inspectors/dce_rpc/dce_smb_module.h
index eb90284978a7aab071e186900a48f07e7bbe9df5..327ddc47ab1e771d36136a12f6e398c73b9326fc 100644 (file)
 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 //--------------------------------------------------------------------------
 //
-// dce2_smb_module.h author Rashmi Pitre <rrp@cisco.com>
+// dce_smb_module.h author Rashmi Pitre <rrp@cisco.com>
 
-#ifndef DCE2_SMB_MODULE_H
-#define DCE2_SMB_MODULE_H
+#ifndef DCE_SMB_MODULE_H
+#define DCE_SMB_MODULE_H
 
-#include "dce2_common.h"
+#include "dce_common.h"
 #include "framework/module.h"
-#include "dce2_list.h"
+#include "dce_list.h"
 
 struct SnortConfig;
 
diff --git a/src/service_inspectors/dce_rpc/dce_smb_paf.cc b/src/service_inspectors/dce_rpc/dce_smb_paf.cc
new file mode 100644 (file)
index 0000000..2159aed
--- /dev/null
@@ -0,0 +1,184 @@
+//--------------------------------------------------------------------------
+// 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.
+//--------------------------------------------------------------------------
+
+// dce_smb_paf.cc author Rashmi Pitre <rrp@cisco.com>
+// based on work by Todd Wease
+
+#include "dce_smb_paf.h"
+#include "dce_smb.h"
+#include "dce_common.h"
+#include "main/snort_debug.h"
+#include "protocols/packet.h"
+
+/*********************************************************************
+ * Function: DCE2_PafSmbIsValidNetbiosHdr()
+ *
+ * Purpose: Validates that the NetBIOS header is valid.  If in
+ *          junk states, header type must be Session Message.
+ *
+ *********************************************************************/
+static inline bool DCE2_PafSmbIsValidNetbiosHdr(uint32_t nb_hdr, bool junk)
+{
+    uint8_t type = (uint8_t)(nb_hdr >> 24);
+    uint8_t bit = (uint8_t)((nb_hdr & 0x00ff0000) >> 16);
+
+    if (junk)
+    {
+        if (type != NBSS_SESSION_TYPE__MESSAGE)
+            return false;
+    }
+    else
+    {
+        switch (type)
+        {
+        case NBSS_SESSION_TYPE__MESSAGE:
+        case NBSS_SESSION_TYPE__REQUEST:
+        case NBSS_SESSION_TYPE__POS_RESPONSE:
+        case NBSS_SESSION_TYPE__NEG_RESPONSE:
+        case NBSS_SESSION_TYPE__RETARGET_RESPONSE:
+        case NBSS_SESSION_TYPE__KEEP_ALIVE:
+            break;
+        default:
+            return false;
+        }
+    }
+
+    if ((bit != 0x00) && (bit != 0x01))
+        return false;
+
+    return true;
+}
+
+/*********************************************************************
+ * Function: DCE2_SmbPaf()
+ *
+ * Purpose: The DCE/RPC over SMB PAF callback.
+ *          Inspects a byte at a time changing state and shifting
+ *          bytes onto the 64bit nb_hdr member.  At state 3
+ *          determines if NetBIOS header is valid and if so sets
+ *          flush point.  If not valid goes to states 4-7 where
+ *          there is the possibility that junk data was inserted
+ *          before request/response.  Needs to validate SMB ID at
+ *          this point.  At state 7 determines if NetBIOS header
+ *          is valid and that the SMB ID is present.  Stays in
+ *          state 7 until this is the case.
+ *
+ *********************************************************************/
+StreamSplitter::Status dce2_smb_paf(DCE2_PafSmbData* ss, Flow* flow, const uint8_t* data,
+    uint32_t len, uint32_t flags, uint32_t* fp)
+{
+    uint32_t n = 0;
+    StreamSplitter::Status ps = StreamSplitter::SEARCH;
+    uint32_t nb_hdr;
+    uint32_t nb_len;
+
+    DebugFormat(DEBUG_DCE_SMB, "%s\n", DCE2_DEBUG__PAF_START_MSG_SMB);
+    DebugFormat(DEBUG_DCE_SMB, "SMB: %u bytes of data\n", len);
+
+    if (flags & PKT_FROM_CLIENT)
+        DebugMessage(DEBUG_DCE_SMB, "Packet from Client\n");
+    else
+        DebugMessage(DEBUG_DCE_SMB, "Packet from Server\n");
+
+    if (dce2_paf_abort(flow))
+    {
+        DebugFormat(DEBUG_DCE_SMB, "%s\n", DCE2_DEBUG__PAF_END_MSG);
+        return StreamSplitter::ABORT;
+    }
+
+    DebugFormat(DEBUG_DCE_SMB, "Start state: %u\n", ss->paf_state);
+
+    while (n < len)
+    {
+        DebugFormat(DEBUG_DCE_SMB, " State %d : 0x%02x", ss->paf_state, data[n]);
+
+        switch (ss->paf_state)
+        {
+        case DCE2_PAF_SMB_STATES__0:
+            ss->nb_hdr = (uint64_t)data[n];
+            ss->paf_state = (DCE2_PafSmbStates)(((int)ss->paf_state) + 1);
+            break;
+        case DCE2_PAF_SMB_STATES__3:
+            DCE2_SMB_PAF_SHIFT(ss->nb_hdr, data[n]);
+            if (DCE2_PafSmbIsValidNetbiosHdr((uint32_t)ss->nb_hdr, false))
+            {
+                nb_hdr = htonl((uint32_t)ss->nb_hdr);
+                nb_len = NbssLen((const NbssHdr*)&nb_hdr);
+                *fp = (nb_len + sizeof(NbssHdr) + n) - ss->paf_state;
+                ss->paf_state = DCE2_PAF_SMB_STATES__0;
+                DebugFormat(DEBUG_DCE_SMB,
+                    "Setting flush point: %u\n", *fp);
+                DebugFormat(DEBUG_DCE_SMB, "%s\n", DCE2_DEBUG__PAF_END_MSG);
+                return StreamSplitter::FLUSH;
+            }
+            DebugMessage(DEBUG_DCE_SMB, "Invalid NetBIOS header - "
+                "entering junk data states.\n");
+            ss->paf_state = (DCE2_PafSmbStates)(((int)ss->paf_state) + 1);
+            break;
+        case DCE2_PAF_SMB_STATES__7:
+            DCE2_SMB_PAF_SHIFT(ss->nb_hdr, data[n]);
+
+            if (!DCE2_PafSmbIsValidNetbiosHdr((uint32_t)(ss->nb_hdr >> 32), true))
+            {
+                DebugMessage(DEBUG_DCE_SMB, "Invalid NetBIOS header - "
+                    "staying in State 7.\n");
+                break;
+            }
+            if (((uint32_t)ss->nb_hdr != DCE2_SMB_ID)
+                && ((uint32_t)ss->nb_hdr != DCE2_SMB2_ID))
+            {
+                DebugMessage(DEBUG_DCE_SMB, "Invalid SMB ID - "
+                    "staying in State 7.\n");
+                break;
+            }
+
+            nb_hdr = htonl((uint32_t)(ss->nb_hdr >> 32));
+            nb_len = NbssLen((const NbssHdr*)&nb_hdr);
+            *fp = (nb_len + sizeof(NbssHdr) + n) - ss->paf_state;
+            DebugFormat(DEBUG_DCE_SMB,
+                "Setting flush point: %u\n", *fp);
+            ss->paf_state = DCE2_PAF_SMB_STATES__0;
+            DebugFormat(DEBUG_DCE_SMB, "%s\n", DCE2_DEBUG__PAF_END_MSG);
+            return StreamSplitter::FLUSH;
+        default:
+            DCE2_SMB_PAF_SHIFT(ss->nb_hdr, data[n]);
+            ss->paf_state = (DCE2_PafSmbStates)(((int)ss->paf_state) + 1);
+            break;
+        }
+
+        n++;
+    }
+
+    DebugFormat(DEBUG_DCE_SMB, "%s\n", DCE2_DEBUG__PAF_END_MSG);
+    return ps;
+}
+
+Dce2SmbSplitter::Dce2SmbSplitter(bool c2s) : StreamSplitter(c2s)
+{
+    state.paf_state = DCE2_PAF_SMB_STATES__0;
+    state.nb_hdr = 0;
+}
+
+StreamSplitter::Status Dce2SmbSplitter::scan(
+    Flow* flow, const uint8_t* data, uint32_t len,
+    uint32_t flags, uint32_t* fp)
+{
+    DCE2_PafSmbData* pfdata = &state;
+    return dce2_smb_paf(pfdata, flow, data, len, flags, fp);
+}
+
diff --git a/src/service_inspectors/dce_rpc/dce_smb_paf.h b/src/service_inspectors/dce_rpc/dce_smb_paf.h
new file mode 100644 (file)
index 0000000..0f783ad
--- /dev/null
@@ -0,0 +1,71 @@
+//--------------------------------------------------------------------------
+// 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.
+//--------------------------------------------------------------------------
+
+// dce_smb_paf.h author Rashmi Pitre <rrp@cisco.com>
+// based on work by Todd Wease
+
+#ifndef DCE_SMB_PAF_H
+#define DCE_SMB_PAF_H
+
+#include "main/snort_types.h"
+#include "stream/stream_api.h"
+#include "stream/stream_splitter.h"
+
+#define DCE2_SMB_PAF_SHIFT(x64, x8) { x64 <<= 8; x64 |= (uint64_t)x8; }
+#define DCE2_DEBUG__PAF_START_MSG_SMB  "DCE/RPC over SMB PAF ====================================="
+
+// Enumerations for PAF states
+enum DCE2_PafSmbStates
+{
+    DCE2_PAF_SMB_STATES__0 = 0,  // NetBIOS type
+    DCE2_PAF_SMB_STATES__1,      // Added bit of NetBIOS length
+    DCE2_PAF_SMB_STATES__2,      // First byte of NetBIOS length
+    DCE2_PAF_SMB_STATES__3,      // Second byte of NetBIOS length
+    // Junk states
+    DCE2_PAF_SMB_STATES__4,      // 0xff
+    DCE2_PAF_SMB_STATES__5,      // 'S'
+    DCE2_PAF_SMB_STATES__6,      // 'M'
+    DCE2_PAF_SMB_STATES__7       // 'B'
+};
+
+// State tracker for DCE/RPC over SMB PAF
+struct DCE2_PafSmbData
+{
+    DCE2_PafSmbStates paf_state;
+    uint64_t nb_hdr;   // Enough for NetBIOS header and 4 bytes SMB header
+};
+
+class Dce2SmbSplitter : public StreamSplitter
+{
+public:
+    Dce2SmbSplitter(bool c2s);
+
+    Status scan(Flow*, const uint8_t* data, uint32_t len,
+        uint32_t flags, uint32_t* fp) override;
+
+    bool is_paf() override
+    {
+        return true;
+    }
+
+public:
+    DCE2_PafSmbData state;
+};
+
+#endif
+
similarity index 79%
rename from src/service_inspectors/dce_rpc/dce2_tcp.cc
rename to src/service_inspectors/dce_rpc/dce_tcp.cc
index 45c0035333b7a72e5c385493bbc2481c395cb312..77e6fe8302e5e5dd51bdfe7289df2fac7c4e1273 100644 (file)
 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 //--------------------------------------------------------------------------
 
-// dce2_tcp.cc author Rashmi Pitre <rrp@cisco.com>
+// dce_tcp.cc author Rashmi Pitre <rrp@cisco.com>
 // based on work by Todd Wease
 
-#include "dce2_tcp.h"
-#include "dce2_tcp_module.h"
+#include "dce_tcp.h"
+#include "dce_tcp_paf.h"
+#include "dce_tcp_module.h"
+#include "main/snort_debug.h"
 
 THREAD_LOCAL dce2TcpStats dce2_tcp_stats;
 
@@ -35,6 +37,16 @@ THREAD_LOCAL ProfileStats dce2_tcp_pstat_co_frag;
 THREAD_LOCAL ProfileStats dce2_tcp_pstat_co_reass;
 THREAD_LOCAL ProfileStats dce2_tcp_pstat_co_ctx;
 
+unsigned Dce2TcpFlowData::flow_id = 0;
+
+DCE2_TcpSsnData* get_dce2_tcp_session_data(Flow* flow)
+{
+    Dce2TcpFlowData* fd = (Dce2TcpFlowData*)flow->get_application_data(
+        Dce2TcpFlowData::flow_id);
+
+    return fd ? &fd->dce2_tcp_session : nullptr;
+}
+
 //-------------------------------------------------------------------------
 // class stuff
 //-------------------------------------------------------------------------
@@ -46,6 +58,10 @@ public:
 
     void show(SnortConfig*) override;
     void eval(Packet*) override;
+    StreamSplitter* get_splitter(bool c2s) override
+    {
+        return new Dce2TcpSplitter(c2s);
+    }
 
 private:
     dce2TcpProtoConf config;
@@ -63,7 +79,18 @@ void Dce2Tcp::show(SnortConfig*)
 
 void Dce2Tcp::eval(Packet* p)
 {
-    UNUSED(p);
+    DCE2_TcpSsnData* dce2_sess = get_dce2_tcp_session_data(p->flow);
+
+    if (dce2_sess == nullptr)
+    {
+        /*Check if it is a DCE2 over TCP packet*/
+       
+        if (DCE2_TcpAutodetect(p))
+        {
+            DebugMessage(DEBUG_DCE_TCP, "DCE over TCP packet detected\n");
+        }
+        
+    }
 }
 
 //-------------------------------------------------------------------------
similarity index 69%
rename from src/service_inspectors/dce_rpc/dce2_tcp.h
rename to src/service_inspectors/dce_rpc/dce_tcp.h
index 699cc385ea2558a75a3a0e6f140bebfff85f9e3b..a24d13aee232556e3e80281c397282c7383bb232 100644 (file)
 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 //--------------------------------------------------------------------------
 
-//dce2_tcp.h author Rashmi Pitre <rrp@cisco.com>
+//dce_tcp.h author Rashmi Pitre <rrp@cisco.com>
 // based on work by Todd Wease
 
-#ifndef DCE2_TCP_H
-#define DCE2_TCP_H
+#ifndef DCE_TCP_H
+#define DCE_TCP_H
 
+#include "dce_co.h"
 #include "protocols/packet.h"
 #include "profiler/profiler.h"
 #include "framework/counts.h"
@@ -85,5 +86,53 @@ extern THREAD_LOCAL ProfileStats dce2_tcp_pstat_co_frag;
 extern THREAD_LOCAL ProfileStats dce2_tcp_pstat_co_reass;
 extern THREAD_LOCAL ProfileStats dce2_tcp_pstat_co_ctx;
 
+static inline bool DCE2_TcpAutodetect(Packet* p)
+{
+    if (p->dsize >= sizeof(DceRpcCoHdr))
+    {
+        DceRpcCoHdr* co_hdr = (DceRpcCoHdr*)p->data;
+
+        if ((DceRpcCoVersMaj(co_hdr) == DCERPC_PROTO_MAJOR_VERS__5)
+            && (DceRpcCoVersMin(co_hdr) == DCERPC_PROTO_MINOR_VERS__0)
+            && ((p->from_client()
+            && DceRpcCoPduType(co_hdr) == DCERPC_PDU_TYPE__BIND)
+            || (p->from_server()
+            && DceRpcCoPduType(co_hdr) == DCERPC_PDU_TYPE__BIND_ACK))
+            && (DceRpcCoFragLen(co_hdr) >= sizeof(DceRpcCoHdr)))
+        {
+            return true;
+        }
+    }
+    else if ((*p->data == DCERPC_PROTO_MAJOR_VERS__5) && p->from_client())
+    {
+        return true;
+    }
+
+    return false;
+}
+
+struct DCE2_TcpSsnData
+{
+    DCE2_SsnData sd;  // This member must be first
+    // FIXIT-M add all the remaining fields
+};
+
+class Dce2TcpFlowData : public FlowData
+{
+public:
+    Dce2TcpFlowData();
+
+    static void init()
+    {
+        flow_id = FlowData::get_flow_id();
+    }
+
+public:
+    static unsigned flow_id;
+    DCE2_TcpSsnData dce2_tcp_session;
+};
+
+DCE2_TcpSsnData* get_dce2_tcp_session_data(Flow*);
+
 #endif
 
similarity index 98%
rename from src/service_inspectors/dce_rpc/dce2_tcp_module.cc
rename to src/service_inspectors/dce_rpc/dce_tcp_module.cc
index c2d7ea9663f2aba3a47c97f885dc922c3af16e1a..0bb1edc793b2e0eba7196576f73c704b99471047 100644 (file)
 
 // dce_tcp_module.cc author Rashmi Pitre <rrp@cisco.com>
 
-#include "dce2_tcp_module.h"
-#include "dce2_tcp.h"
-#include "dce2_common.h"
+#include "dce_tcp_module.h"
+#include "dce_tcp.h"
+#include "dce_common.h"
 #include "main/snort_config.h"
-#include "dce2_co.h"
+#include "dce_co.h"
 
 using namespace std;
 
similarity index 95%
rename from src/service_inspectors/dce_rpc/dce2_tcp_module.h
rename to src/service_inspectors/dce_rpc/dce_tcp_module.h
index 6205c7ef622e897b9f66d486b850cf4d7c5cd128..c7de6b9affad4941718639424f4d56906a42a9e1 100644 (file)
 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 //--------------------------------------------------------------------------
 //
-// dce2_tcp_module.h author Rashmi Pitre <rrp@cisco.com>
+// dce_tcp_module.h author Rashmi Pitre <rrp@cisco.com>
 
 #ifndef DCE2_TCP_MODULE_H
 #define DCE2_TCP_MODULE_H
 
-#include "dce2_common.h"
+#include "dce_common.h"
 #include "framework/module.h"
 
 struct SnortConfig;
diff --git a/src/service_inspectors/dce_rpc/dce_tcp_paf.cc b/src/service_inspectors/dce_rpc/dce_tcp_paf.cc
new file mode 100644 (file)
index 0000000..6d348d7
--- /dev/null
@@ -0,0 +1,187 @@
+//--------------------------------------------------------------------------
+// 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.
+//--------------------------------------------------------------------------
+
+// dce_tcp_paf.cc author Rashmi Pitre <rrp@cisco.com>
+// based on work by Todd Wease
+
+#include "dce_tcp_paf.h"
+#include "dce_tcp.h"
+#include "dce_common.h"
+#include "main/snort_debug.h"
+
+/*********************************************************************
+ * Function: dce2_tcp_paf()
+ *
+ * Purpose: The DCE/RPC over TCP PAF callback.
+ *          Inspects a byte at a time changing state.  At state 4
+ *          gets byte order of PDU.  At states 8 and 9 gets
+ *          fragment length and sets flush point if no more data.
+ *          Otherwise accumulates flush points because there can
+ *          be multiple PDUs in a single TCP segment (evasion case).
+ *
+ *********************************************************************/
+static StreamSplitter::Status dce2_tcp_paf(DCE2_PafTcpData* ds, Flow* flow, const uint8_t* data,
+    uint32_t len, uint32_t flags, uint32_t* fp)
+{
+    uint32_t n = 0;
+    int start_state;
+    StreamSplitter::Status ps = StreamSplitter::SEARCH;
+    uint32_t tmp_fp = 0;
+    DCE2_TcpSsnData* sd = get_dce2_tcp_session_data(flow);
+
+    int num_requests = 0;
+
+    DebugFormat(DEBUG_DCE_TCP, "%s\n", DCE2_DEBUG__PAF_START_MSG_TCP);
+    DebugFormat(DEBUG_DCE_TCP, "TCP: %u bytes of data\n", len);
+
+    if (flags & PKT_FROM_CLIENT)
+        DebugMessage(DEBUG_DCE_TCP, "Packet from Client\n");
+    else
+        DebugMessage(DEBUG_DCE_TCP, "Packet from Server\n");
+
+    if (dce2_paf_abort(flow))
+    {
+        DebugFormat(DEBUG_DCE_TCP, "%s\n", DCE2_DEBUG__PAF_END_MSG);
+        return StreamSplitter::ABORT;
+    }
+
+    if (sd == NULL)
+    {
+        bool autodetected = false;
+        DebugMessage(DEBUG_DCE_TCP, "No session data - autodetecting\n");
+
+        if (len >= sizeof(DceRpcCoHdr))
+        {
+            DceRpcCoHdr* co_hdr = (DceRpcCoHdr*)data;
+
+            if ((DceRpcCoVersMaj(co_hdr) == DCERPC_PROTO_MAJOR_VERS__5)
+                && (DceRpcCoVersMin(co_hdr) == DCERPC_PROTO_MINOR_VERS__0)
+                && (((flags & PKT_FROM_CLIENT)
+                && DceRpcCoPduType(co_hdr) == DCERPC_PDU_TYPE__BIND)
+                || ((flags & PKT_FROM_SERVER)
+                && DceRpcCoPduType(co_hdr) == DCERPC_PDU_TYPE__BIND_ACK))
+                && (DceRpcCoFragLen(co_hdr) >= sizeof(DceRpcCoHdr)))
+            {
+                autodetected = true;
+                DebugMessage(DEBUG_DCE_TCP, "Autodetected!\n");
+            }
+        }
+        else if ((*data == DCERPC_PROTO_MAJOR_VERS__5) && (flags & PKT_FROM_CLIENT))
+        {
+            autodetected = true;
+            DebugMessage(DEBUG_DCE_TCP, "Autodetected!\n");
+        }
+
+        if (!autodetected)
+        {
+            DebugMessage(DEBUG_DCE_TCP, "Couldn't autodetect - aborting\n");
+            DebugFormat(DEBUG_DCE_TCP, "%s\n", DCE2_DEBUG__PAF_END_MSG);
+            return StreamSplitter::ABORT;
+        }
+    }
+
+    DebugFormat(DEBUG_DCE_TCP, "Start state: %u\n", ds->paf_state);
+    start_state = (uint8_t)ds->paf_state;
+
+    while (n < len)
+    {
+        DebugFormat(DEBUG_DCE_TCP, " State %d : 0x%02x", ds->paf_state, data[n]);
+
+        switch (ds->paf_state)
+        {
+        case DCE2_PAF_TCP_STATES__4:      // Get byte order
+            ds->byte_order = DceRpcByteOrder(data[n]);
+            ds->paf_state = (DCE2_PafTcpStates)(((int)ds->paf_state) + 1);
+            if (ds->byte_order == DCERPC_BO_FLAG__LITTLE_ENDIAN)
+            {
+                DebugMessage(DEBUG_DCE_TCP, "Byte order: Little endian\n");
+            }
+            else
+            {
+                DebugMessage(DEBUG_DCE_TCP, "Byte order: Big endian\n");
+            }
+            break;
+        case DCE2_PAF_TCP_STATES__8:
+            DebugMessage(DEBUG_DCE_TCP, "First byte of fragment length\n");
+            if (ds->byte_order == DCERPC_BO_FLAG__LITTLE_ENDIAN)
+                ds->frag_len = data[n];
+            else
+                ds->frag_len = data[n] << 8;
+            ds->paf_state = (DCE2_PafTcpStates)(((int)ds->paf_state) + 1);
+            break;
+        case DCE2_PAF_TCP_STATES__9:
+            DebugMessage(DEBUG_DCE_TCP, "Second byte of fragment length\n");
+            if (ds->byte_order == DCERPC_BO_FLAG__LITTLE_ENDIAN)
+                ds->frag_len |= data[n] << 8;
+            else
+                ds->frag_len |= data[n];
+
+            /* If we get a bad frag length abort */
+            if (ds->frag_len < sizeof(DceRpcCoHdr))
+            {
+                DebugFormat(DEBUG_DCE_TCP, "%s\n", DCE2_DEBUG__PAF_END_MSG);
+                return StreamSplitter::ABORT;
+            }
+
+            DebugFormat(DEBUG_DCE_TCP, "Fragment length: %u\n", ds->frag_len);
+
+            /* Increment n here so we can continue */
+            n += ds->frag_len - (uint8_t)ds->paf_state;
+            num_requests++;
+            /* Might have multiple PDUs in one segment.  If the last PDU is partial,
+             * flush just before it */
+            if ((num_requests == 1) || (n <= len))
+                tmp_fp += ds->frag_len;
+            DebugFormat(DEBUG_DCE_TCP, "Requests: %u\n", num_requests);
+            ds->paf_state = DCE2_PAF_TCP_STATES__0;
+            continue;      // we incremented n already
+        default:
+            ds->paf_state = (DCE2_PafTcpStates)(((int)ds->paf_state) + 1);
+            break;
+        }
+
+        n++;
+    }
+
+    if (tmp_fp != 0)
+    {
+        *fp = tmp_fp - start_state;
+        DebugFormat(DEBUG_DCE_TCP, "Setting flush point: %u\n", *fp);
+        DebugFormat(DEBUG_DCE_TCP, "%s\n", DCE2_DEBUG__PAF_END_MSG);
+        return StreamSplitter::FLUSH;
+    }
+
+    DebugFormat(DEBUG_DCE_TCP, "%s\n", DCE2_DEBUG__PAF_END_MSG);
+    return ps;
+}
+
+Dce2TcpSplitter::Dce2TcpSplitter(bool c2s) : StreamSplitter(c2s)
+{
+    state.paf_state = DCE2_PAF_TCP_STATES__0;
+    state.byte_order = DCERPC_BO_FLAG__NONE;
+    state.frag_len = 0;
+}
+
+StreamSplitter::Status Dce2TcpSplitter::scan(
+    Flow* flow, const uint8_t* data, uint32_t len,
+    uint32_t flags, uint32_t* fp)
+{
+    DCE2_PafTcpData* pfdata = &state;
+    return dce2_tcp_paf(pfdata, flow, data, len, flags, fp);
+}
+
diff --git a/src/service_inspectors/dce_rpc/dce_tcp_paf.h b/src/service_inspectors/dce_rpc/dce_tcp_paf.h
new file mode 100644 (file)
index 0000000..8a10bfe
--- /dev/null
@@ -0,0 +1,72 @@
+//--------------------------------------------------------------------------
+// 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.
+//--------------------------------------------------------------------------
+
+// dce_tcp_paf.h author Rashmi Pitre <rrp@cisco.com>
+// based on work by Todd Wease
+
+#ifndef DCE_TCP_PAF_H
+#define DCE_TCP_PAF_H
+
+#include "dce_common.h"
+#include "main/snort_types.h"
+#include "stream/stream_api.h"
+#include "stream/stream_splitter.h"
+
+#define DCE2_DEBUG__PAF_START_MSG_TCP  "DCE/RPC over TCP PAF ====================================="
+
+enum DCE2_PafTcpStates
+{
+    DCE2_PAF_TCP_STATES__0 = 0,
+    DCE2_PAF_TCP_STATES__1,
+    DCE2_PAF_TCP_STATES__2,
+    DCE2_PAF_TCP_STATES__3,
+    DCE2_PAF_TCP_STATES__4,   // Byte order
+    DCE2_PAF_TCP_STATES__5,
+    DCE2_PAF_TCP_STATES__6,
+    DCE2_PAF_TCP_STATES__7,
+    DCE2_PAF_TCP_STATES__8,   // First byte of fragment length
+    DCE2_PAF_TCP_STATES__9    // Second byte of fragment length
+};
+
+// State tracker for DCE/RPC over TCP PAF
+struct DCE2_PafTcpData
+{
+    DCE2_PafTcpStates paf_state;
+    DceRpcBoFlag byte_order;
+    uint16_t frag_len;
+};
+
+class Dce2TcpSplitter : public StreamSplitter
+{
+public:
+    Dce2TcpSplitter(bool c2s);
+
+    Status scan(Flow*, const uint8_t* data, uint32_t len,
+        uint32_t flags, uint32_t* fp) override;
+
+    bool is_paf() override
+    {
+        return true;
+    }
+
+public:
+    DCE2_PafTcpData state;
+};
+
+#endif
+
similarity index 99%
rename from src/service_inspectors/dce_rpc/dce2_utils.cc
rename to src/service_inspectors/dce_rpc/dce_utils.cc
index 8428467f1956436fec216135fce4cea0a3004aac..dca58f59e281911ddffbf1d4531c6a903865219b 100644 (file)
@@ -17,7 +17,7 @@
 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 //--------------------------------------------------------------------------
 
-#include "dce2_utils.h"
+#include "dce_utils.h"
 
 
 /********************************************************************
similarity index 99%
rename from src/service_inspectors/dce_rpc/dce2_utils.h
rename to src/service_inspectors/dce_rpc/dce_utils.h
index 862f7e10c5fde514d675315975507a2ebc924f48..deffe804ba7f31503d1177ff617a5482a741c7c8 100644 (file)
@@ -17,8 +17,8 @@
 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 //--------------------------------------------------------------------------
 
-#ifndef _DCE2_UTILS_H_
-#define _DCE2_UTILS_H_
+#ifndef _DCE_UTILS_H_
+#define _DCE_UTILS_H_
 
 #include <string.h>
 #include <ctype.h>
similarity index 99%
rename from src/service_inspectors/dce_rpc/ips_dce2_iface.cc
rename to src/service_inspectors/dce_rpc/ips_dce_iface.cc
index 6d0d005119283c025912df98083c7e5d12a6f11a..e3e68f55cba025644452a8dfe818fba0ed3b13db 100644 (file)
 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 //--------------------------------------------------------------------------
 
-// ips_dce2_iface.cc author Maya Dagon <mdagon@cisco.com>
+// ips_dce_iface.cc author Maya Dagon <mdagon@cisco.com>
 // based on work by Todd Wease
 
-#include "dce2_utils.h"
+#include "dce_utils.h"
 
 #include "framework/ips_option.h"
 #include "framework/module.h"
similarity index 99%
rename from src/service_inspectors/dce_rpc/ips_dce2_opnum.cc
rename to src/service_inspectors/dce_rpc/ips_dce_opnum.cc
index fd809bb12934574e590bd317f85be2e70ef6d34f..8a50740bf709463f9df819ed6710ba58b64a61a5 100644 (file)
 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 //--------------------------------------------------------------------------
 
-// ips_dce2_opnum.cc author Maya Dagon <mdagon@cisco.com>
+// ips_dce_opnum.cc author Maya Dagon <mdagon@cisco.com>
 // based on work by Todd Wease
 
-#include "dce2_utils.h"
+#include "dce_utils.h"
 
 #include "framework/ips_option.h"
 #include "framework/module.h"
similarity index 98%
rename from src/service_inspectors/dce_rpc/ips_dce2_stub_data.cc
rename to src/service_inspectors/dce_rpc/ips_dce_stub_data.cc
index feda11c3e92de7200c6167ee93acc17225b06536..7251102b4adad76531f345dd62420c6c15ce9107 100644 (file)
@@ -16,7 +16,7 @@
 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 //--------------------------------------------------------------------------
 
-// ips_dce2_stub_data.cc author Maya Dagon <mdagon@cisco.com>
+// ips_dce_stub_data.cc author Maya Dagon <mdagon@cisco.com>
 // based on work by Todd Wease
 
 #include "detection/detection_defines.h"