return false;
}
+bool HostTracker::add_smb_fingerprint(uint32_t fpid)
+{
+ lock_guard<mutex> lck(host_tracker_lock);
+ auto result = smb_fpids.emplace(fpid);
+ return result.second;
+}
+
bool HostTracker::set_visibility(bool v)
{
// get_valid_id may use its own lock, so get this outside our lock
str += to_string(fpid) + (--total ? ", " : "");
}
+ total = smb_fpids.size();
+ if ( total )
+ {
+ str += "\nsmb fingerprint: ";
+ for ( const auto& fpid : smb_fpids )
+ str += to_string(fpid) + (--total ? ", " : "");
+ }
+
if ( !netbios_name.empty() )
str += "\nnetbios name: " + netbios_name;
}
bool add_ua_fingerprint(uint32_t fpid, uint32_t fp_type, bool jail_broken,
const char* device_info, uint8_t max_devices);
bool add_udp_fingerprint(uint32_t fpid);
+ bool add_smb_fingerprint(uint32_t fpid);
// This should be updated whenever HostTracker data members are changed
void stringify(std::string& str);
std::vector<HostClient, HostClientAllocator> clients;
std::set<uint32_t, std::less<uint32_t>, HostCacheAllocIp<uint32_t>> tcp_fpids;
std::set<uint32_t, std::less<uint32_t>, HostCacheAllocIp<uint32_t>> udp_fpids;
+ std::set<uint32_t, std::less<uint32_t>, HostCacheAllocIp<uint32_t>> smb_fpids;
std::vector<DeviceFingerprint, HostDeviceFpAllocator> ua_fps;
std::string netbios_name;
#define MAX_SFTP_PACKET_COUNT 55
#define APPID_SESSION_DATA_NONE 0
-#define APPID_SESSION_DATA_SMB_DATA 4
#define APPID_SESSION_DATA_SERVICE_MODSTATE_BIT 0x20000000
#define APPID_SESSION_DATA_CLIENT_MODSTATE_BIT 0x40000000
#define APPID_SESSION_DATA_DETECTOR_MODSTATE_BIT 0x80000000
#include "service_netbios.h"
+#include "detection/detection_engine.h"
#include "protocols/packet.h"
+#include "pub_sub/smb_events.h"
#include "utils/endian.h"
#include "app_info_table.h"
void NbdgmServiceDetector::add_smb_info(AppIdSession& asd, unsigned major, unsigned minor,
uint32_t flags)
{
- FpSMBData* sd;
-
if ( flags & FINGERPRINT_UDP_FLAGS_XENIX )
return;
if ( asd.get_session_flags(APPID_SESSION_HAS_SMB_INFO) )
return;
- sd = (FpSMBData*)snort_calloc(sizeof(FpSMBData));
-
- if ( asd.add_flow_data(sd, APPID_SESSION_DATA_SMB_DATA, (AppIdFreeFCN)AppIdFreeSMBData) )
- {
- AppIdFreeSMBData(sd);
- return;
- }
-
asd.set_session_flags(APPID_SESSION_HAS_SMB_INFO);
- sd->major = major;
- sd->minor = minor;
- sd->flags = flags & FINGERPRINT_UDP_FLAGS_MASK;
-}
-
-void NbdgmServiceDetector::AppIdFreeSMBData(FpSMBData* sd)
-{
- snort_free(sd);
+ Packet* p = DetectionEngine::get_current_packet();
+ FpSMBDataEvent event(p, major, minor, (flags & FINGERPRINT_UDP_FLAGS_MASK));
+ DataBus::publish(FP_SMB_DATA_EVENT, event, p->flow);
}
class AppIdSession;
class ServiceDiscovery;
-struct FpSMBData
-{
- FpSMBData* next;
- unsigned major;
- unsigned minor;
- uint32_t flags;
-};
-
class NbssServiceDetector : public ServiceDetector
{
public:
int validate(AppIdDiscoveryArgs&) override;
- static void AppIdFreeSMBData(FpSMBData*);
-
private:
void add_smb_info(AppIdSession&, unsigned major, unsigned minor, uint32_t flags);
};
include_directories ( appid PRIVATE ${APPID_INCLUDE_DIR} )
add_cpputest( service_rsync_test )
-add_cpputest( service_netbios_test )
StashGenericObject(STASH_GENERIC_OBJECT_APPID) {}
}
-SslPatternMatchers::~SslPatternMatchers() = default;
-SipPatternMatchers::~SipPatternMatchers() = default;
-HttpPatternMatchers::~HttpPatternMatchers() = default;
-DnsPatternMatchers::~DnsPatternMatchers() = default;
+SslPatternMatchers::~SslPatternMatchers() { }
+SipPatternMatchers::~SipPatternMatchers() { }
+HttpPatternMatchers::~HttpPatternMatchers() { }
+DnsPatternMatchers::~DnsPatternMatchers() { }
void ClientDiscovery::initialize(AppIdInspector&) {}
void ClientDiscovery::reload() {}
FpSMBData* smb_data = nullptr;
int, unsigned){}
int AppIdDiscovery::add_service_port(AppIdDetector*, const ServiceDetectorPort&){return 0;}
void ApplicationDescriptor::set_id(const snort::Packet&, AppIdSession&, AppidSessionDirection, AppId, AppidChangeBits&){}
-int AppIdSession::add_flow_data(void* data, unsigned type, AppIdFreeFCN)
-{
- if ( type == APPID_SESSION_DATA_SMB_DATA )
- {
- smb_data = (FpSMBData*)data;
- set_session_flags(APPID_SESSION_HAS_SMB_INFO);
- }
- return 0;
-}
-
+int AppIdSession::add_flow_data(void*, unsigned, AppIdFreeFCN) { return 0; }
int dcerpc_validate(const uint8_t*, int){return 0; }
-AppIdDiscovery::~AppIdDiscovery() = default;
+AppIdDiscovery::~AppIdDiscovery() { }
void show_stats(PegCount*, const PegInfo*, unsigned, const char*) { }
void show_stats(PegCount*, const PegInfo*, const IndexVec&, const char*, FILE*) { }
AppIdConfig config;
set (RNA_INCLUDES
rna_fingerprint.h
+ rna_fingerprint_smb.h
rna_fingerprint_tcp.h
rna_fingerprint_ua.h
rna_fingerprint_udp.h
rna_event_handler.cc
rna_event_handler.h
rna_fingerprint.cc
+ rna_fingerprint_smb.cc
rna_fingerprint_tcp.cc
rna_fingerprint_ua.cc
rna_fingerprint_udp.cc
RnaLogger& logger, const char* username, AppId service, IpProtocol proto, RnaConfig* conf,
bool login_success)
{
- RnaTracker rt;
- if ( p->is_from_server() )
- {
- if ( !filter.is_host_monitored(p, nullptr, nullptr, FlowCheckDirection::DF_SERVER) )
- return;
- rt = get_server_rna_tracker(p, rna_flow);
- }
- else
- {
- if ( !filter.is_host_monitored(p, nullptr, nullptr, FlowCheckDirection::DF_CLIENT) )
- return;
- rt = get_client_rna_tracker(p, rna_flow);
- }
-
+ assert(rna_flow);
+ RnaTracker rt = rna_flow->get_tracker(p, filter);
if ( !rt or !rt->is_visible() )
return;
- rt->update_last_seen();
if ( rt->update_service_user(p->flow->server_port, proto, username,
(uint32_t) packet_time(), conf ? conf->max_host_services : 0, login_success) )
void RnaAppDiscovery::discover_netbios_name(const snort::Packet* p, DiscoveryFilter& filter,
RNAFlow* rna_flow, RnaLogger& logger, const char* nb_name)
{
- RnaTracker rt;
- if ( p->is_from_server() )
- {
- if ( !filter.is_host_monitored(p, nullptr, nullptr, FlowCheckDirection::DF_SERVER) )
- return;
- rt = get_server_rna_tracker(p, rna_flow);
- }
- else
- {
- if ( !filter.is_host_monitored(p, nullptr, nullptr, FlowCheckDirection::DF_CLIENT) )
- return;
- rt = get_client_rna_tracker(p, rna_flow);
- }
-
- if ( !rt or !rt->is_visible() )
+ RnaTracker rt = rna_flow->get_tracker(p, filter);
+ if ( !rt or !rt->is_visible())
return;
- rt->update_last_seen();
if ( rt->set_netbios_name(nb_name) )
{
static void discover_netbios_name(const snort::Packet*, DiscoveryFilter&,
RNAFlow*, RnaLogger&, const char*);
+ static RnaTracker get_server_rna_tracker(const snort::Packet*, RNAFlow*);
+ static RnaTracker get_client_rna_tracker(const snort::Packet*, RNAFlow*);
+
private:
static void update_service_info(const snort::Packet*, DiscoveryFilter&, RNAFlow*, IpProtocol,
uint16_t, const char* vendor, const char* version, RnaLogger&, RnaConfig*, AppId service,
static void analyze_user_agent_fingerprint(const snort::Packet*, DiscoveryFilter&, RNAFlow*,
const char* host, const char* uagent, RnaLogger&, snort::UaFpProcessor&);
- static RnaTracker get_server_rna_tracker(const snort::Packet*, RNAFlow*);
- static RnaTracker get_client_rna_tracker(const snort::Packet*, RNAFlow*);
};
#endif
class TcpFpProcessor;
class UaFpProcessor;
class UdpFpProcessor;
+class SmbFpProcessor;
}
struct RnaModuleConfig
snort::TcpFpProcessor* tcp_processor = nullptr;
snort::UaFpProcessor* ua_processor = nullptr;
snort::UdpFpProcessor* udp_processor = nullptr;
+ snort::SmbFpProcessor* smb_processor = nullptr;
};
// Give default values so that RNA can work even if rna_conf_path is not provided
#include "rna_event_handler.h"
#include "pub_sub/dhcp_events.h"
+#include "pub_sub/smb_events.h"
using namespace snort;
++rna_stats.dhcp_data;
pnd.analyze_dhcp_fingerprint(event);
}
+
+void RnaFpSMBEventHandler::handle(DataEvent& event, Flow*)
+{
+ Profile profile(rna_perf_stats);
+ ++rna_stats.smb;
+ pnd.analyze_smb_fingerprint(event);
+}
RnaPnd& pnd;
};
+class RnaFpSMBEventHandler : public snort::DataHandler
+{
+public:
+ RnaFpSMBEventHandler(RnaPnd& nd) : DataHandler(RNA_NAME), pnd(nd) { }
+ void handle(snort::DataEvent&, snort::Flow*) override;
+private:
+ RnaPnd& pnd;
+};
+
#endif
std::string dhcp55;
std::string dhcp60;
+ int16_t smb_major;
+ int16_t smb_minor;
+ uint32_t smb_flags;
+
void clear()
{
fpid = 0;
device.clear();
dhcp55.clear();
dhcp60.clear();
+ smb_major = 0;
+ smb_minor = 0;
+ smb_flags=0;
}
};
--- /dev/null
+//--------------------------------------------------------------------------
+// Copyright (C) 2021-2021 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.
+//--------------------------------------------------------------------------
+
+// rna_fingerprint_smb.cc author Silviu Minut <sminut@cisco.com>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "rna_fingerprint_smb.h"
+
+#include <sstream>
+
+#ifdef UNIT_TEST
+#include "catch/snort_catch.h"
+#endif
+
+#include "log/messages.h"
+
+using namespace snort;
+using namespace std;
+
+static THREAD_LOCAL SmbFpProcessor* smb_fp_processor = nullptr;
+
+SmbFpProcessor* get_smb_fp_processor()
+{
+ return smb_fp_processor;
+}
+
+void set_smb_fp_processor(SmbFpProcessor* processor)
+{
+ smb_fp_processor = processor;
+}
+
+namespace snort
+{
+
+SmbFingerprint::SmbFingerprint(unsigned maj, unsigned min, uint32_t f)
+ : major(maj), minor(min), flags(f) { }
+
+SmbFingerprint::SmbFingerprint(const RawFingerprint& rfp)
+{
+ fpid = rfp.fpid;
+ fp_type = rfp.fp_type;
+ fpuuid = rfp.fpuuid;
+ ttl = rfp.ttl;
+
+ major = rfp.smb_major;
+ minor = rfp.smb_minor;
+ flags = rfp.smb_flags;
+}
+
+bool SmbFingerprint::operator==(const SmbFingerprint& y) const
+{
+ return ((fpid == y.fpid) &&
+ (fp_type == y.fp_type) &&
+ (fpuuid == y.fpuuid) &&
+ (ttl == y.ttl) &&
+ (major == y.major) &&
+ (minor == y.minor) &&
+ (flags == y.flags) );
+}
+
+bool SmbFpProcessor::push(const SmbFingerprint& sfp)
+{
+ auto result = smb_fps.emplace(sfp);
+ if (!result.second)
+ WarningMessage("SmbFpProcessor: ignoring previously seen fingerprint id: %d\n", sfp.fpid);
+ return result.second;
+}
+
+const SmbFingerprint* SmbFpProcessor::find(const SmbFingerprint& key) const
+{
+ const auto& it = smb_fps.find(key);
+ return it != smb_fps.end() ? &(*it) : nullptr;
+}
+
+}
+
+#ifdef UNIT_TEST
+
+TEST_CASE("get_smb_fp_processor", "[rna_fingerprint_smb]")
+{
+ SmbFpProcessor smb_processor;
+ set_smb_fp_processor(&smb_processor);
+
+ SmbFpProcessor* processor = get_smb_fp_processor();
+ CHECK(processor == &smb_processor);
+
+ unsigned major = 6;
+ unsigned minor = 4;
+ uint32_t flags = 4096;
+ SmbFingerprint fp(major, minor, flags);
+ processor->push(fp);
+
+ // positive test:
+ const SmbFingerprint* fpptr = processor->find({major, minor, flags});
+ CHECK(fpptr != nullptr);
+ CHECK(*fpptr == fp);
+
+ // negative test:
+ fpptr = processor->find({0, 0, 0});
+ CHECK(fpptr == nullptr);
+
+ set_smb_fp_processor(nullptr);
+ CHECK(smb_fp_processor == nullptr);
+}
+
+#endif
--- /dev/null
+//--------------------------------------------------------------------------
+// Copyright (C) 2021-2021 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.
+//--------------------------------------------------------------------------
+
+// rna_fingerprint_smb.h author Silviu Minut <sminut@cisco.com>
+
+#ifndef RNA_FINGERPRINT_SMB_H
+#define RNA_FINGERPRINT_SMB_H
+
+#include <mutex>
+#include <unordered_map>
+#include <vector>
+
+#include "main/snort_types.h"
+#include "protocols/packet.h"
+#include "protocols/tcp.h"
+#include "sfip/sf_ip.h"
+
+#include "rna_fingerprint.h"
+
+class RNAFlow;
+
+namespace snort
+{
+
+class SO_PUBLIC SmbFingerprint : public FpFingerprint
+{
+public:
+
+ SmbFingerprint(unsigned maj = 0, unsigned min = 0, uint32_t f = 0);
+ SmbFingerprint(const RawFingerprint& rfp);
+
+ unsigned major;
+ unsigned minor;
+ uint32_t flags;
+
+ bool operator==(const SmbFingerprint& y) const;
+};
+
+class SO_PUBLIC SmbFpProcessor
+{
+public:
+
+ struct SmbFpHash
+ {
+ size_t operator()(const SmbFingerprint & key) const noexcept
+ {
+ std::hash<decltype(SmbFingerprint::major)> hm;
+ std::hash<decltype(SmbFingerprint::flags)> hf;
+ auto const h = hm(key.major) ^ (hm(key.minor) << 1) ^ (hf(key.flags) << 2);
+ return h;
+ }
+ };
+
+ struct SmbEqTo
+ {
+ bool operator() (const SmbFingerprint& x, const SmbFingerprint& y) const
+ {
+ return x.major == y.major && x.minor == y.minor && x.flags == y.flags;
+ }
+ };
+
+ typedef std::unordered_set<SmbFingerprint, SmbFpHash, SmbEqTo> SmbFpContainer;
+ typedef SmbFpContainer::const_iterator SmbFpIter;
+
+ bool push(const SmbFingerprint&);
+ const SmbFingerprint* find(const SmbFingerprint& ) const;
+
+private:
+
+ SmbFpContainer smb_fps;
+};
+
+}
+
+snort::SmbFpProcessor* get_smb_fp_processor();
+SO_PUBLIC void set_smb_fp_processor(snort::SmbFpProcessor*);
+
+#endif
#include "rna_flow.h"
+#include "helpers/discovery_filter.h"
#include "host_tracker/host_cache.h"
+#include "protocols/packet.h"
+
+#ifdef UNIT_TEST
+#include "catch/snort_catch.h"
+#endif
using namespace snort;
using namespace std;
return loc_ht;
}
+RnaTracker RNAFlow::get_tracker(const Packet* p, DiscoveryFilter& filter)
+{
+ RnaTracker rt;
+ if ( p->is_from_server() && filter.is_host_monitored(p, nullptr, nullptr, FlowCheckDirection::DF_SERVER) )
+ rt = get_server(p->flow->server_ip);
+ else if (p->is_from_client() && filter.is_host_monitored(p, nullptr, nullptr, FlowCheckDirection::DF_CLIENT) )
+ rt = get_client(p->flow->server_ip);
+
+ if ( rt && rt->is_visible() )
+ rt->update_last_seen();
+ return rt;
+}
+
void RNAFlow::set_server(RnaTracker& ht)
{
rna_mutex.lock();
clientht = ht;
rna_mutex.unlock();
}
+
+
+#ifdef UNIT_TEST
+
+TEST_CASE("RNA Flow", "[get_tracker]")
+{
+ timeval curr_time;
+ Packet p;
+ Flow flow;
+ p.flow=&flow;
+
+ DiscoveryFilter filter("");
+ RnaTracker ht(new HostTracker);
+
+ RNAFlow::init();
+ RNAFlow* rna_flow = new RNAFlow();
+ p.flow->set_flow_data(rna_flow);
+
+ RnaTracker rt;
+ uint32_t last_seen;
+
+ // test the server path
+ curr_time.tv_sec = 12345678;
+ packet_time_update(&curr_time);
+ p.packet_flags = PKT_FROM_SERVER;
+ rna_flow->set_server(ht);
+ rt = rna_flow->get_tracker(&p, filter);
+ CHECK(rt == ht);
+ last_seen = ht->get_last_seen();
+ CHECK(last_seen == curr_time.tv_sec);
+
+ // and the client path
+ curr_time.tv_sec = 23456789;
+ packet_time_update(&curr_time);
+ p.packet_flags = PKT_FROM_CLIENT;
+ rna_flow->set_client(ht);
+ rt = rna_flow->get_tracker(&p, filter);
+ CHECK(rt == ht);
+ last_seen = ht->get_last_seen();
+ CHECK(last_seen == curr_time.tv_sec);
+
+ flow.free_flow_data();
+}
+
+#endif
#include "rna_fingerprint_tcp.h"
+namespace snort
+{
+struct Packet;
+}
+
+class DiscoveryFilter;
+
using RnaTracker = std::shared_ptr<snort::HostTracker>;
class RNAFlow : public snort::FlowData
RnaTracker get_server(const snort::SfIp&);
RnaTracker get_client(const snort::SfIp&);
+ RnaTracker get_tracker(const snort::Packet*, DiscoveryFilter&);
void set_server(RnaTracker& ht);
void set_client(RnaTracker& ht);
#include "managers/inspector_manager.h"
#include "protocols/packet.h"
#include "pub_sub/dhcp_events.h"
+#include "pub_sub/smb_events.h"
#include "rna_event_handler.h"
+#include "rna_fingerprint_smb.h"
#include "rna_fingerprint_tcp.h"
#include "rna_fingerprint_ua.h"
#include "rna_fingerprint_udp.h"
delete mod_conf->tcp_processor;
delete mod_conf->ua_processor;
delete mod_conf->udp_processor;
+ delete mod_conf->smb_processor;
delete mod_conf;
}
}
DataBus::subscribe_global( APPID_EVENT_ANY_CHANGE, new RnaAppidEventHandler(*pnd), sc );
DataBus::subscribe_global( DHCP_INFO_EVENT, new RnaDHCPInfoEventHandler(*pnd), sc);
DataBus::subscribe_global( DHCP_DATA_EVENT, new RnaDHCPDataEventHandler(*pnd), sc);
+ DataBus::subscribe_global( FP_SMB_DATA_EVENT, new RnaFpSMBEventHandler(*pnd), sc);
DataBus::subscribe_global( STREAM_ICMP_NEW_FLOW_EVENT, new RnaIcmpNewFlowEventHandler(*pnd), sc );
DataBus::subscribe_global( STREAM_ICMP_BIDIRECTIONAL_EVENT, new RnaIcmpBidirectionalEventHandler(*pnd), sc );
set_tcp_fp_processor(mod_conf->tcp_processor);
set_ua_fp_processor(mod_conf->ua_processor);
set_udp_fp_processor(mod_conf->udp_processor);
+ set_smb_fp_processor(mod_conf->smb_processor);
set_host_cache_mac(host_cache_mac_ptr);
}
#include "utils/util.h"
#include "data_purge_cmd.h"
+#include "rna_fingerprint_smb.h"
#include "rna_fingerprint_tcp.h"
#include "rna_fingerprint_ua.h"
#include "rna_fingerprint_udp.h"
{ "dhcp60", Parameter::PT_STRING, nullptr, nullptr,
"dhcp option 60 values" },
+ { "major", Parameter::PT_INT, "0:max31", nullptr,
+ "smb major version" },
+
+ { "minor", Parameter::PT_INT, "0:max31", nullptr,
+ "smb minor version" },
+
+ { "flags", Parameter::PT_INT, "0:max32", nullptr,
+ "smb flags" },
+
{ nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
};
{ "udp_fingerprints", Parameter::PT_LIST, rna_fp_params, nullptr,
"list of udp fingerprints" },
+ { "smb_fingerprints", Parameter::PT_LIST, rna_fp_params, nullptr,
+ "list of smb fingerprints" },
+
{ nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
};
{ CountType::SUM, "change_host_update", "count number of change host update events" },
{ CountType::SUM, "dhcp_data", "count of DHCP data events received" },
{ CountType::SUM, "dhcp_info", "count of new DHCP lease events received" },
+ { CountType::SUM, "smb", "count of new SMB events received" },
{ CountType::END, nullptr, nullptr},
};
if (!mod_conf->udp_processor)
mod_conf->udp_processor = new UdpFpProcessor;
}
+ else if (!strcmp(fqn, "rna.smb_fingerprints"))
+ {
+ fingerprint.clear();
+ if (!mod_conf->smb_processor)
+ mod_conf->smb_processor = new SmbFpProcessor;
+ }
return true;
}
dump_file = snort_strdup(v.get_string());
}
else if ( fqn and ( strstr(fqn, "rna.tcp_fingerprints") or
- strstr(fqn, "rna.ua_fingerprints") or strstr(fqn, "rna.udp_fingerprints") ) )
+ strstr(fqn, "rna.ua_fingerprints") or strstr(fqn, "rna.udp_fingerprints")
+ or strstr(fqn, "rna.smb_fingerprints") ) )
{
if (v.is("fpid"))
fingerprint.fpid = v.get_uint32();
fingerprint.dhcp55 = v.get_string();
else if (v.is("dhcp60"))
fingerprint.dhcp60 = v.get_string();
+ else if (v.is("major"))
+ fingerprint.smb_major = v.get_int16();
+ else if (v.is("minor"))
+ fingerprint.smb_minor = v.get_int16();
+ else if (v.is("flags"))
+ fingerprint.smb_flags = v.get_uint32();
else
return false;
}
if ( mod_conf->ua_processor )
mod_conf->ua_processor->make_mpse(sc);
+
}
if ( index > 0 and mod_conf->tcp_processor and !strcmp(fqn, "rna.tcp_fingerprints") )
mod_conf->udp_processor->push(fingerprint);
fingerprint.clear();
}
+ else if ( index > 0 and mod_conf->smb_processor and !strcmp(fqn, "rna.smb_fingerprints") )
+ {
+ mod_conf->smb_processor->push(fingerprint);
+ fingerprint.clear();
+ }
return true;
}
{
return !strcmp(fqn, RNA_NAME) or !strcmp(fqn, "rna.tcp_fingerprints") or
!strcmp(fqn, "rna.ua_fingerprints") or !strcmp(fqn, "rna.ua_fingerprints.user_agent") or
- !strcmp(fqn, "rna.udp_fingerprints");
+ !strcmp(fqn, "rna.udp_fingerprints") or !strcmp(fqn, "rna.smb_fingerprints");
}
PegCount change_host_update;
PegCount dhcp_data;
PegCount dhcp_info;
+ PegCount smb;
};
extern THREAD_LOCAL RnaStats rna_stats;
#include "protocols/protocol_ids.h"
#include "rna_app_discovery.h"
+#include "rna_fingerprint_smb.h"
#include "rna_fingerprint_tcp.h"
#include "rna_fingerprint_udp.h"
#include "rna_flow.h"
lease, net_mask, (const struct in6_addr*) router_ip.get_ip6_ptr());
}
+void RnaPnd::analyze_smb_fingerprint(DataEvent& event)
+{
+ const SmbFpProcessor* processor = get_smb_fp_processor();
+ if (!processor)
+ return;
+
+ const Packet* p = event.get_packet();
+ RNAFlow* rna_flow = (RNAFlow*) p->flow->get_flow_data(RNAFlow::inspector_id);
+ if ( !rna_flow )
+ return;
+
+ RnaTracker rt = rna_flow->get_tracker(p, filter);
+ if ( !rt or !rt->is_visible() )
+ return;
+
+ const FpSMBDataEvent& fp_smb_data_event = static_cast<FpSMBDataEvent&>(event);
+ unsigned major = fp_smb_data_event.get_fp_smb_major();
+ unsigned minor = fp_smb_data_event.get_fp_smb_minor();
+ uint32_t flags = fp_smb_data_event.get_fp_smb_flags();
+
+ const SmbFingerprint* fp = processor->find({major, minor, flags});
+
+ if ( fp && rt->add_smb_fingerprint(fp->fpid) )
+ {
+ const auto& src_ip = p->ptrs.ip_api.get_src();
+ const auto& src_ip_ptr = (const struct in6_addr*) src_ip->get_ip6_ptr();
+ const auto& src_mac = layer::get_eth_layer(p)->ether_src;
+
+ logger.log(RNA_EVENT_NEW, NEW_OS, p, &rt, src_ip_ptr, src_mac, fp, packet_time());
+ }
+}
+
inline void RnaPnd::update_vlan(const Packet* p, HostTrackerMac& hm)
{
if ( !(p->proto_bits & PROTO_BIT__VLAN) )
CHECK(is_eligible_packet(&p) == true);
}
}
+
#endif
#include "protocols/vlan.h"
#include "pub_sub/appid_events.h"
#include "pub_sub/dhcp_events.h"
+#include "pub_sub/smb_events.h"
#include "sfip/sf_ip.h"
#include "rna_config.h"
void analyze_flow_udp(const snort::Packet*);
void analyze_dhcp_fingerprint(snort::DataEvent&);
void add_dhcp_info(snort::DataEvent&);
+ void analyze_smb_fingerprint(snort::DataEvent&);
// generate change event for all hosts in the ip cache
void generate_change_host_update();
void UdpFpProcessor::push(RawFingerprint const&) { }
+SmbFingerprint::SmbFingerprint(const RawFingerprint&) { }
+bool SmbFingerprint::operator==(const SmbFingerprint&) const { return true; }
+bool SmbFpProcessor::push(SmbFingerprint const&) { return true; }
+
// inspector
class RnaInspector
{
http_events.h
opportunistic_tls_event.h
sip_events.h
+ smb_events.h
)
add_library( pub_sub OBJECT
--- /dev/null
+//--------------------------------------------------------------------------
+// Copyright (C) 2021-2021 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.
+//--------------------------------------------------------------------------
+// smb_events.h author Sreeja Athirkandathil Narayanan <sathirka@cisco.com>
+
+#ifndef SMB_EVENTS_H
+#define SMB_EVENTS_H
+
+#include "framework/data_bus.h"
+
+#define FP_SMB_DATA_EVENT "fp_smb_data_event"
+
+namespace snort
+{
+
+class FpSMBDataEvent : public snort::DataEvent
+{
+public:
+ FpSMBDataEvent(const snort::Packet* p, unsigned major, unsigned minor,
+ uint32_t flags) : pkt(p), major_version(major), minor_version(minor), flags(flags) { }
+
+ const snort::Packet* get_packet() override
+ { return pkt; }
+
+ unsigned get_fp_smb_major() const
+ { return major_version; }
+
+ unsigned get_fp_smb_minor() const
+ { return minor_version; }
+
+ uint32_t get_fp_smb_flags() const
+ { return flags; }
+
+private:
+ const snort::Packet* pkt;
+ unsigned major_version;
+ unsigned minor_version;
+ uint32_t flags;
+};
+
+}
+
+#endif // SMB_EVENTS_H