if (neg_resp_hdr->capabilities & SMB2_GLOBAL_CAP_MULTI_CHANNEL)
{
Packet* p = DetectionEngine::get_current_packet();
- Dce2SmbFlowData* fd =
- create_expected_smb_flow_data(p, (dce2SmbProtoConf *)sd.config);
+ Dce2SmbFlowData* fd = create_expected_smb_flow_data(p);
if (fd)
{
int result = Stream::set_snort_protocol_id_expected(p, PktType::TCP,
const uint8_t* data_ptr = p->data;
uint16_t data_len = p->dsize;
- // Check header length
- if (data_len < sizeof(NbssHdr) + SMB2_HEADER_LENGTH)
- {
- SMB_DEBUG(dce_smb_trace, DEFAULT_TRACE_OPTION_ID, TRACE_CRITICAL_LEVEL,
- p, "Header error with data length %d\n",data_len);
- dce2_smb_stats.v2_hdr_err++;
- return;
- }
-
// Process the header
if (p->is_pdu_start())
{
+ // Check header length
+ if (data_len < sizeof(NbssHdr) + SMB2_HEADER_LENGTH)
+ {
+ SMB_DEBUG(dce_smb_trace, DEFAULT_TRACE_OPTION_ID, TRACE_CRITICAL_LEVEL,
+ p, "Header error with data length %d\n",data_len);
+ dce2_smb_stats.v2_hdr_err++;
+ return;
+ }
const Smb2Hdr* smb_hdr = (const Smb2Hdr*)(data_ptr + sizeof(NbssHdr));
uint32_t next_command_offset;
uint8_t compound_request_index = 0;
ssd = ssd_v;
}
-void Dce2SmbFlowData::handle_expected(Packet* p)
-{
- //we have a fd, but ssd not set, set it here in this flow
- if (ssd)
- delete ssd;
- ssd = new Dce2Smb2SessionData(p, config);
-}
-
Dce2SmbSessionData* Dce2SmbFlowData::upgrade(const Packet* p)
{
dce2SmbProtoConf* config =
return DCE2_SMB_VERSION_NULL;
}
-Dce2SmbFlowData* create_expected_smb_flow_data(const Packet* p, dce2SmbProtoConf* config)
+Dce2SmbFlowData* create_expected_smb_flow_data(const Packet* p)
{
DCE2_SmbVersion smb_version = get_smb_version(p);
if (DCE2_SMB_VERSION_2 == smb_version)
{
- return new Dce2SmbFlowData(config);
+ return new Dce2SmbFlowData();
}
return nullptr;
}
+Dce2SmbSessionData* create_smb_session_data(Dce2SmbFlowData* flow_data, const Packet* p,
+ dce2SmbProtoConf* config)
+{
+ DCE2_SmbVersion smb_version = get_smb_version(p);
+ if (DCE2_SMB_VERSION_2 != smb_version)
+ return nullptr;
+ Dce2SmbSessionData* ssd = (Dce2SmbSessionData*)new Dce2Smb2SessionData(p, config);
+ flow_data->update_smb_session_data(ssd);
+ return ssd;
+}
+
Dce2SmbSessionData* create_new_smb_session(const Packet* p,
dce2SmbProtoConf* config)
{
DCE2_SsnData* get_dce2_session_data(snort::Flow* flow)
{
Dce2SmbFlowData* fd = (Dce2SmbFlowData*)flow->get_flow_data(Dce2SmbFlowData::inspector_id);
- return fd ? fd->get_smb_session_data()->get_dce2_session_data() : nullptr;
+ return fd ? fd->get_smb_session_data() ? fd->get_smb_session_data()->get_dce2_session_data() :
+ nullptr : nullptr;
}
inline FileContext* get_smb_file_context(const Packet* p)
{
public:
Dce2SmbFlowData(Dce2SmbSessionData*);
- Dce2SmbFlowData(dce2SmbProtoConf* cfg) : snort::FlowData(inspector_id)
+ Dce2SmbFlowData() : snort::FlowData(inspector_id)
{
dce2_smb_stats.concurrent_sessions++;
if (dce2_smb_stats.max_concurrent_sessions < dce2_smb_stats.concurrent_sessions)
dce2_smb_stats.max_concurrent_sessions = dce2_smb_stats.concurrent_sessions;
- config = cfg;
ssd = nullptr;
}
{ return ssd; }
Dce2SmbSessionData* upgrade(const snort::Packet*);
+ void update_smb_session_data(Dce2SmbSessionData* ssd_v)
+ {
+ if (ssd) delete ssd;
+ ssd = ssd_v;
+ }
void handle_retransmit(snort::Packet*) override;
- void handle_expected(snort::Packet*) override;
public:
static unsigned inspector_id;
private:
Dce2SmbSessionData* ssd;
- dce2SmbProtoConf* config;
};
-Dce2SmbFlowData* create_expected_smb_flow_data(const snort::Packet*, dce2SmbProtoConf*);
+Dce2SmbFlowData* create_expected_smb_flow_data(const snort::Packet*);
Dce2SmbSessionData* create_new_smb_session(const snort::Packet*, dce2SmbProtoConf*);
+Dce2SmbSessionData* create_smb_session_data(Dce2SmbFlowData*, const snort::Packet*,
+ dce2SmbProtoConf*);
DCE2_SsnData* get_dce2_session_data(snort::Flow*);
snort::FileContext* get_smb_file_context(const snort::Packet*);
snort::FileContext* get_smb_file_context(snort::Flow*, uint64_t, uint64_t, bool);
Dce2SmbSessionData* smb_session_data;
if (smb_flowdata)
+ {
smb_session_data = smb_flowdata->get_smb_session_data();
+ // if flow data present but session data is not, it is an expected session
+ // try to update the session data, will only do for SMBv2. Ideally it should
+ // be done in handle_expected, but we dont have access to the config there.
+ if (!smb_session_data)
+ smb_session_data = create_smb_session_data(smb_flowdata, p, &config);
+ }
else
smb_session_data = create_new_smb_session(p, &config);