dce_tcp_module.cc
dce_tcp_module.h
dce_tcp_paf.cc
- dce_tcp_paf.h
+ dce_tcp_paf.h
+ dce_udp.cc
+ dce_udp.h
+ dce_udp_module.cc
+ dce_udp_module.h
dce_utils.cc
dce_utils.h
ips_dce_iface.cc
dce_tcp_module.h \
dce_tcp_paf.cc \
dce_tcp_paf.h \
+dce_udp.cc\
+dce_udp.h \
+dce_udp_module.cc \
+dce_udp_module.h \
dce_utils.cc \
dce_utils.h \
ips_dce_iface.cc \
void* config = sd->config;
if (sd->trans == DCE2_TRANS_TYPE__TCP)
{
- if (((dce2TcpProtoConf*)config)->co_reassemble_threshold > 0)
+ if (((dce2TcpProtoConf*)config)->common.co_reassemble_threshold > 0)
return true;
}
else
{
- if (((dce2SmbProtoConf*)config)->co_reassemble_threshold > 0)
+ if (((dce2SmbProtoConf*)config)->common.co_reassemble_threshold > 0)
return true;
}
return false;
{
if (sd->trans == DCE2_TRANS_TYPE__TCP)
{
- return ((dce2TcpProtoConf*)config)->co_reassemble_threshold;
+ return ((dce2TcpProtoConf*)config)->common.co_reassemble_threshold;
}
else
{
- return ((dce2SmbProtoConf*)config)->co_reassemble_threshold;
+ return ((dce2SmbProtoConf*)config)->common.co_reassemble_threshold;
}
}
return UINT16_MAX;
else if ( v.is("max_frag_len") )
common.max_frag_len = v.get_long();
+ else
+ return false;
+ return true;
+}
+bool dce2_set_co_config(Value& v, dce2CoProtoConf& co)
+{
+ if (dce2_set_common_config(v, co.common))
+ return true;
else if ( v.is("policy") )
- common.policy = (DCE2_Policy)v.get_long();
+ co.policy = (DCE2_Policy)v.get_long();
+ else if ( v.is("reassemble_threshold") )
+ co.co_reassemble_threshold = v.get_long();
else
return false;
return true;
"DISABLED" : "ENABLED");
LogMessage(" Max Fragment length: %d\n",
common.max_frag_len);
+}
+
+void print_dce2_co_config(dce2CoProtoConf& co)
+{
+ print_dce2_common_config(co.common);
+
LogMessage(" Policy : %s\n",
- dce2_get_policy_name(common.policy));
+ dce2_get_policy_name(co.policy));
+ LogMessage(" Reassemble Threshold : %d\n",
+ co.co_reassemble_threshold);
}
bool dce2_paf_abort(Flow* flow, DCE2_SsnData* sd)
{
&dce2_tcp_api.base,
&dce2_smb_api.base,
+ &dce2_udp_api.base,
ips_dce_iface,
ips_dce_opnum,
ips_dce_stub_data,
const BaseApi* sin_dce_tcp = &dce2_tcp_api.base;
const BaseApi* sin_dce_smb = &dce2_smb_api.base;
+const BaseApi* sin_dce_udp = &dce2_udp_api.base;
#endif
extern const InspectApi dce2_smb_api;
extern const InspectApi dce2_tcp_api;
+extern const InspectApi dce2_udp_api;
extern THREAD_LOCAL int dce2_detected;
extern THREAD_LOCAL int dce2_inspector_instances;
extern THREAD_LOCAL DCE2_CStack* dce2_pkt_stack;
{
bool disable_defrag;
int max_frag_len;
+};
+
+struct dce2CoProtoConf
+{
+ dce2CommonProtoConf common;
DCE2_Policy policy;
+ uint16_t co_reassemble_threshold;
};
#define DCE2_DEBUG__PAF_END_MSG "=========================================================="
bool dce2_set_common_config(Value&, dce2CommonProtoConf&);
void print_dce2_common_config(dce2CommonProtoConf&);
+bool dce2_set_co_config(Value&, dce2CoProtoConf&);
+void print_dce2_co_config(dce2CoProtoConf&);
bool dce2_paf_abort(Flow*, DCE2_SsnData*);
void DCE2_Detect(DCE2_SsnData*);
Packet* DCE2_GetRpkt(Packet*, DCE2_RpktType,
bool Dce2SmbModule::set(const char*, Value& v, SnortConfig*)
{
- if (dce2_set_common_config(v,config.common))
+ if (dce2_set_co_config(v,config.common))
return true;
- else if ( v.is("reassemble_threshold") )
- config.co_reassemble_threshold = v.get_long();
else if ( v.is("smb_fingerprint_policy") )
config.smb_fingerprint_policy = (dce2SmbFingerprintPolicy)v.get_long();
else if ( v.is("smb_max_chain") )
{
LogMessage("DCE SMB config: \n");
- print_dce2_common_config(config.common);
- LogMessage(" Reassemble Threshold : %d\n",
- config.co_reassemble_threshold);
+ print_dce2_co_config(config.common);
LogMessage(" SMB fingerprint policy : %s\n",
dce2SmbFingerprintPolicyStrings[config.smb_fingerprint_policy]);
struct dce2SmbProtoConf
{
- dce2CommonProtoConf common;
- uint16_t co_reassemble_threshold;
+ dce2CoProtoConf common;
dce2SmbFingerprintPolicy smb_fingerprint_policy;
uint8_t smb_max_chain;
uint8_t smb_max_compound;
bool Dce2TcpModule::set(const char*, Value& v, SnortConfig*)
{
- if (dce2_set_common_config(v,config.common))
+ if (dce2_set_co_config(v,config.common))
return true;
- else if ( v.is("reassemble_threshold") )
- config.co_reassemble_threshold = v.get_long();
- else
- return false;
- return true;
+
+ return false;
}
void Dce2TcpModule::get_data(dce2TcpProtoConf& dce2_tcp_config)
void print_dce2_tcp_conf(dce2TcpProtoConf& config)
{
LogMessage("DCE TCP config: \n");
-
- print_dce2_common_config(config.common);
- LogMessage(" Reassemble Threshold : %d\n",
- config.co_reassemble_threshold);
+ print_dce2_co_config(config.common);
}
struct dce2TcpProtoConf
{
- dce2CommonProtoConf common;
- uint16_t co_reassemble_threshold;
+ dce2CoProtoConf common;
};
class Dce2TcpModule : public Module
--- /dev/null
+//--------------------------------------------------------------------------
+// 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_udp.cc author Maya Dagon <mdagon@cisco.com>
+// based on work by Todd Wease
+
+#include "dce_udp.h"
+#include "dce_udp_module.h"
+#include "main/snort_debug.h"
+#include "detection/detect.h"
+#include "log/messages.h"
+#include "protocols/packet_manager.h"
+#include "utils/util.h"
+
+THREAD_LOCAL int dce2_udp_inspector_instances = 0;
+
+THREAD_LOCAL dce2UdpStats dce2_udp_stats;
+
+THREAD_LOCAL ProfileStats dce2_udp_pstat_main;
+THREAD_LOCAL ProfileStats dce2_udp_pstat_session;
+THREAD_LOCAL ProfileStats dce2_udp_pstat_new_session;
+THREAD_LOCAL ProfileStats dce2_udp_pstat_detect;
+THREAD_LOCAL ProfileStats dce2_udp_pstat_log;
+THREAD_LOCAL ProfileStats dce2_udp_pstat_cl_acts;
+THREAD_LOCAL ProfileStats dce2_udp_pstat_cl_frag;
+THREAD_LOCAL ProfileStats dce2_udp_pstat_cl_reass;
+
+//-------------------------------------------------------------------------
+// class stuff
+//-------------------------------------------------------------------------
+Dce2UdpFlowData::Dce2UdpFlowData() : FlowData(flow_id)
+{
+}
+
+Dce2UdpFlowData::~Dce2UdpFlowData()
+{
+ // FIXIT-M add cl_tracker cleanup
+}
+
+unsigned Dce2UdpFlowData::flow_id = 0;
+
+class Dce2Udp : public Inspector
+{
+public:
+ Dce2Udp(dce2UdpProtoConf&);
+ void show(SnortConfig*) override;
+ void eval(Packet*) override;
+
+private:
+ dce2UdpProtoConf config;
+};
+
+Dce2Udp::Dce2Udp(dce2UdpProtoConf& pc)
+{
+ config = pc;
+}
+
+void Dce2Udp::show(SnortConfig*)
+{
+ print_dce2_udp_conf(config);
+}
+
+void Dce2Udp::eval(Packet*)
+{
+}
+
+//-------------------------------------------------------------------------
+// api stuff
+//-------------------------------------------------------------------------
+
+static Module* mod_ctor()
+{
+ return new Dce2UdpModule;
+}
+
+static void mod_dtor(Module* m)
+{
+ delete m;
+}
+
+static Inspector* dce2_udp_ctor(Module* m)
+{
+ Dce2UdpModule* mod = (Dce2UdpModule*)m;
+ dce2UdpProtoConf config;
+ mod->get_data(config);
+ return new Dce2Udp(config);
+}
+
+static void dce2_udp_dtor(Inspector* p)
+{
+ delete p;
+}
+
+static void dce2_udp_init()
+{
+ Dce2UdpFlowData::init();
+}
+
+static void dce2_udp_thread_init()
+{
+ dce2_udp_inspector_instances++;
+}
+
+static void dce2_udp_thread_term()
+{
+ dce2_udp_inspector_instances--;
+}
+
+const InspectApi dce2_udp_api =
+{
+ {
+ PT_INSPECTOR,
+ sizeof(InspectApi),
+ INSAPI_VERSION,
+ 0,
+ API_RESERVED,
+ API_OPTIONS,
+ DCE2_UDP_NAME,
+ DCE2_UDP_HELP,
+ mod_ctor,
+ mod_dtor
+ },
+ IT_SERVICE,
+ (uint16_t)PktType::UDP,
+ nullptr, // buffers
+ "dce_udp",
+ dce2_udp_init,
+ nullptr, // pterm
+ dce2_udp_thread_init, // tinit
+ dce2_udp_thread_term, // tterm
+ dce2_udp_ctor,
+ dce2_udp_dtor,
+ nullptr, // ssn
+ nullptr // reset
+};
+
--- /dev/null
+//--------------------------------------------------------------------------
+// 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.h author Maya Dagon <mdagon@cisco.com>
+// based on work by Todd Wease
+
+#ifndef DCE_UDP_H
+#define DCE_UDP_H
+
+#include "dce_common.h"
+#include "dce_list.h"
+#include "protocols/packet.h"
+#include "profiler/profiler.h"
+#include "framework/counts.h"
+
+#define DCE2_UDP_NAME "dce_udp"
+#define DCE2_UDP_HELP "dce over udp inspection"
+
+struct dce2UdpStats
+{
+ /* The common stats block has to be at the beginning followed
+ by the protocol specific stats */
+
+ /*common stats -defined in common.h*/
+ PegCount events;
+ PegCount sessions_aborted;
+ PegCount bad_autodetects;
+
+ /*DCE UDP specific*/
+ PegCount udp_sessions;
+ PegCount udp_pkts;
+ PegCount cl_pkts;
+ PegCount cl_request;
+ PegCount cl_ack;
+ PegCount cl_cancel;
+ PegCount cl_cli_fack;
+ PegCount cl_ping;
+ PegCount cl_response;
+ PegCount cl_reject;
+ PegCount cl_cancel_ack;
+ PegCount cl_srv_fack;
+ PegCount cl_fault;
+ PegCount cl_nocall;
+ PegCount cl_working;
+ PegCount cl_other_req;
+ PegCount cl_other_resp;
+ PegCount cl_fragments;
+ PegCount cl_max_frag_size;
+ PegCount cl_frag_reassembled;
+ PegCount cl_max_seqnum;
+};
+
+extern THREAD_LOCAL dce2UdpStats dce2_udp_stats;
+extern THREAD_LOCAL ProfileStats dce2_udp_pstat_main;
+extern THREAD_LOCAL ProfileStats dce2_udp_pstat_session;
+extern THREAD_LOCAL ProfileStats dce2_udp_pstat_new_session;
+extern THREAD_LOCAL ProfileStats dce2_udp_pstat_detect;
+extern THREAD_LOCAL ProfileStats dce2_udp_pstat_log;
+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 DCE2_ClTracker
+{
+ DCE2_List* act_trackers; /* List of activity trackers */
+};
+
+struct DCE2_UdpSsnData
+{
+ DCE2_SsnData sd; // This member must be first
+ DCE2_ClTracker cl_tracker;
+};
+
+class Dce2UdpFlowData : public FlowData
+{
+public:
+ Dce2UdpFlowData();
+ ~Dce2UdpFlowData();
+
+ static void init()
+ {
+ flow_id = FlowData::get_flow_id();
+ }
+
+public:
+ static unsigned flow_id;
+ DCE2_UdpSsnData dce2_udp_session;
+};
+
+#endif
+
--- /dev/null
+//--------------------------------------------------------------------------
+// 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_udp_module.cc author Maya Dagon <mdagon@cisco.com>
+
+#include "dce_udp_module.h"
+#include "dce_udp.h"
+#include "dce_common.h"
+#include "main/snort_config.h"
+
+using namespace std;
+
+static const Parameter s_params[] =
+{
+ { "disable_defrag", Parameter::PT_BOOL, nullptr, "false",
+ " Disable DCE/RPC defragmentation" },
+ { "max_frag_len", Parameter::PT_INT, "1514:65535", "65535",
+ " Maximum fragment size for defragmentation" },
+ { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
+};
+
+static const RuleMap dce2_udp_rules[] =
+{
+ { DCE2_CL_BAD_MAJOR_VERSION, DCE2_CL_BAD_MAJOR_VERSION_STR },
+ { DCE2_CL_BAD_PDU_TYPE, DCE2_CL_BAD_PDU_TYPE_STR },
+ { DCE2_CL_DATA_LT_HDR, DCE2_CL_DATA_LT_HDR_STR },
+ { DCE2_CL_BAD_SEQ_NUM, DCE2_CL_BAD_SEQ_NUM_STR },
+ { 0, nullptr }
+};
+
+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" },
+ { "Acks", "total connection-less acks" },
+ { "Cancels", "total connection-less cancels" },
+ { "Client facks", "total connection-less client facks" },
+ { "Ping", "total connection-less ping" },
+ { "Responses", "total connection-less responses" },
+ { "Rejects", "total connection-less rejects" },
+ { "Cancel acks", "total connection-less cancel acks" },
+ { "Server facks", "total connection-less server facks" },
+ { "Faults", "total connection-less faults" },
+ { "No calls", "total connection-less no calls" },
+ { "Working", "total connection-less working" },
+ { "Other requests", "total connection-less other requests" },
+ { "Other responses", "total connection-less other responses" },
+ { "Fragments", "total connection-less fragments" },
+ { "Max fragment size",
+ "connection-less maximum fragment size" },
+ { "Frags reassembled",
+ "total connection-less fragments reassembled" },
+ { "Max seqnum",
+ "max connection-less seqnum" },
+ { nullptr, nullptr }
+};
+
+Dce2UdpModule::Dce2UdpModule() : Module(DCE2_UDP_NAME, DCE2_UDP_HELP, s_params)
+{
+}
+
+const RuleMap* Dce2UdpModule::get_rules() const
+{
+ return dce2_udp_rules;
+}
+
+const PegInfo* Dce2UdpModule::get_pegs() const
+{
+ return dce2_udp_pegs;
+}
+
+PegCount* Dce2UdpModule::get_counts() const
+{
+ return (PegCount*)&dce2_udp_stats;
+}
+
+ProfileStats* Dce2UdpModule::get_profile(
+ unsigned index, const char*& name, const char*& parent) const
+{
+ switch ( index )
+ {
+ case 0:
+ name = "dce_udp_main";
+ parent = nullptr;
+ return &dce2_udp_pstat_main;
+
+ case 1:
+ name = "dce_udp_session";
+ parent = "dce_udp_main";
+ return &dce2_udp_pstat_session;
+
+ case 2:
+ name = "dce_udp_new_session";
+ parent = "dce_udp_session";
+ return &dce2_udp_pstat_new_session;
+
+ case 3:
+ name = "dce_udp_detect";
+ parent = "dce_udp_main";
+ return &dce2_udp_pstat_detect;
+
+ case 4:
+ name = "dce_udp_log";
+ parent = "dce_udp_main";
+ return &dce2_udp_pstat_log;
+
+ case 5:
+ name = "dce_udp_cl_acts";
+ parent = "dce_udp_main";
+ return &dce2_udp_pstat_cl_acts;
+
+ case 6:
+ name = "dce_udp_cl_frag";
+ parent = "dce_udp_main";
+ return &dce2_udp_pstat_cl_frag;
+
+ case 7:
+ name = "dce_udp_cl_reass";
+ parent = "dce_udp_main";
+ return &dce2_udp_pstat_cl_reass;
+ }
+ return nullptr;
+}
+
+bool Dce2UdpModule::set(const char*, Value& v, SnortConfig*)
+{
+ if (dce2_set_common_config(v,config.common))
+ return true;
+ else
+ return false;
+}
+
+void Dce2UdpModule::get_data(dce2UdpProtoConf& dce2_udp_config)
+{
+ dce2_udp_config = config;
+}
+
+void print_dce2_udp_conf(dce2UdpProtoConf& config)
+{
+ LogMessage("DCE UDP config: \n");
+ print_dce2_common_config(config.common);
+}
+
--- /dev/null
+//--------------------------------------------------------------------------
+// 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_udp_module.h author Maya Dagon <mdagon@cisco.com>
+
+#ifndef DCE2_UDP_MODULE_H
+#define DCE2_UDP_MODULE_H
+
+#include "dce_common.h"
+#include "framework/module.h"
+
+#define DCE2_CL_BAD_MAJOR_VERSION 40
+#define DCE2_CL_BAD_PDU_TYPE 41
+#define DCE2_CL_DATA_LT_HDR 42
+#define DCE2_CL_BAD_SEQ_NUM 43
+
+#define DCE2_CL_BAD_MAJOR_VERSION_STR "Connection-less DCE/RPC - Invalid major version."
+#define DCE2_CL_BAD_PDU_TYPE_STR "Connection-less DCE/RPC - Invalid pdu type."
+#define DCE2_CL_DATA_LT_HDR_STR \
+ "Connection-less DCE/RPC - Data length less than header size."
+#define DCE2_CL_BAD_SEQ_NUM_STR \
+ "Connection-less DCE/RPC - Bad sequence number."
+
+struct SnortConfig;
+
+struct dce2UdpProtoConf
+{
+ dce2CommonProtoConf common;
+};
+
+class Dce2UdpModule : public Module
+{
+public:
+ Dce2UdpModule();
+
+ bool set(const char*, Value&, SnortConfig*) override;
+
+ unsigned get_gid() const override
+ {
+ return GID_DCE2;
+ }
+
+ const RuleMap* get_rules() const override;
+ const PegInfo* get_pegs() const override;
+ PegCount* get_counts() const override;
+ ProfileStats* get_profile(unsigned, const char*&, const char*&) const override;
+ void get_data(dce2UdpProtoConf&);
+
+private:
+ dce2UdpProtoConf config;
+};
+
+void print_dce2_udp_conf(dce2UdpProtoConf& config);
+
+#endif
+
extern const BaseApi* sin_bo;
extern const BaseApi* sin_dce_smb;
extern const BaseApi* sin_dce_tcp;
+extern const BaseApi* sin_dce_udp;
extern const BaseApi* sin_dnp3;
extern const BaseApi* sin_dns;
extern const BaseApi* sin_ftp_client;
sin_bo,
sin_dce_smb,
sin_dce_tcp,
+ sin_dce_udp,
sin_dnp3,
sin_dns,
sin_ftp_client,