From: Bhargava Jandhyala (bjandhya) Date: Mon, 18 Apr 2022 06:26:33 +0000 (+0000) Subject: Pull request #3365: dce_rpc: Handling only named ioctls for smb X-Git-Tag: 3.1.28.0~12 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9666542bb73b3f44358ac87d6b6d8df0547e54e2;p=thirdparty%2Fsnort3.git Pull request #3365: dce_rpc: Handling only named ioctls for smb Merge in SNORT/snort3 from ~BSACHDEV/snort3:dce_ss_crash_2 to master Squashed commit of the following: commit 1d77d1119629f9cd241577206b5bb64328b548fd Author: bsachdev Date: Sun Mar 20 23:51:38 2022 -0400 dce_rpc: Handling only named ioctls for smb Signed-off-by: bsachdev --- diff --git a/src/service_inspectors/dce_rpc/dce_smb2.h b/src/service_inspectors/dce_rpc/dce_smb2.h index beaf91ceb..b1580de17 100644 --- a/src/service_inspectors/dce_rpc/dce_smb2.h +++ b/src/service_inspectors/dce_rpc/dce_smb2.h @@ -69,6 +69,10 @@ extern const char* smb2_command_string[SMB2_COM_MAX]; #define SMB2_CMD_TYPE_RESPONSE 2 #define SMB2_CMD_TYPE_INVALID 3 +#define FSCTL_PIPE_WAIT 0x00110018 +#define FSCTL_PIPE_TRANSCEIVE 0x0011C017 +#define FSCTL_PIPE_PEEK 0x0011400C + struct Smb2Hdr { uint8_t smb_idf[4]; /* contains 0xFE,’SMB’ */ @@ -251,6 +255,38 @@ struct Smb2TreeConnectResponseHdr uint32_t maximal_access; /* maximal access for the user */ }; +struct Smb2IoctlRequestHdr +{ + uint16_t structure_size; /* This MUST be set to 57 */ + uint16_t reserved; + uint32_t ctl_code; + uint64_t fileId_persistent; /* fileId that is persistent */ + uint64_t fileId_volatile; + uint32_t input_offset; + uint32_t input_count; + uint32_t max_input_response; + uint32_t output_offset; + uint32_t output_count; + uint32_t max_output_response; + uint32_t flags; + uint32_t reserved2; +}; + +struct Smb2IoctlResponseHdr +{ + uint16_t structure_size; /* This MUST be set to 49 */ + uint16_t reserved; + uint32_t ctl_code; + uint64_t fileId_persistent; /* fileId that is persistent */ + uint64_t fileId_volatile; + uint32_t input_offset; + uint32_t input_count; + uint32_t output_offset; + uint32_t output_count; + uint32_t flags; + uint32_t reserved2; +}; + #define SMB2_HEADER_LENGTH 64 #define SMB2_ERROR_RESPONSE_STRUC_SIZE 9 diff --git a/src/service_inspectors/dce_rpc/dce_smb2_file.cc b/src/service_inspectors/dce_rpc/dce_smb2_file.cc index b994613ed..1ab85f677 100644 --- a/src/service_inspectors/dce_rpc/dce_smb2_file.cc +++ b/src/service_inspectors/dce_rpc/dce_smb2_file.cc @@ -109,18 +109,22 @@ void Dce2Smb2FileTracker::set_info(char* file_name_v, uint16_t name_len_v, uint6 file_size = size_v; auto updated_flow = update_processing_flow(); Flow* flow = updated_flow.second->get_tcp_flow(); - FileContext* file = get_smb_file_context(flow, file_name_hash, file_id, true); - SMB_DEBUG(dce_smb_trace, DEFAULT_TRACE_OPTION_ID, TRACE_INFO_LEVEL, GET_CURRENT_PACKET, "set file info: file size %" - PRIu64 " fid %" PRIu64 " file_name_hash %" PRIu64 " file context " - "%sfound\n", size_v, file_id, file_name_hash, (file ? "" : "not ")); - if (file) { - ignore = false; - if (file->verdict == FILE_VERDICT_UNKNOWN) + std::lock_guard guard(process_file_mutex); + FileContext* file = get_smb_file_context(flow, file_name_hash, file_id, true); + SMB_DEBUG(dce_smb_trace, DEFAULT_TRACE_OPTION_ID, TRACE_INFO_LEVEL, GET_CURRENT_PACKET, + "set file info: file size %" + PRIu64 " fid %" PRIu64 " file_name_hash %" PRIu64 " file context " + "%sfound\n", size_v, file_id, file_name_hash, (file ? "" : "not ")); + if (file) { - if ((file_name_v and name_len_v) or updated_flow.first) - file->set_file_name(file_name, file_name_len); - file->set_file_size(size_v ? size_v : UNKNOWN_FILE_SIZE); + ignore = false; + if (file->verdict == FILE_VERDICT_UNKNOWN) + { + if ((file_name_v and name_len_v) or updated_flow.first) + file->set_file_name(file_name, file_name_len); + file->set_file_size(size_v ? size_v : UNKNOWN_FILE_SIZE); + } } } } @@ -135,10 +139,12 @@ bool Dce2Smb2FileTracker::close(const uint32_t current_flow_key) file_size = file_offset; Dce2Smb2SessionData* processing_flow = update_processing_flow().second; Flow* flow = processing_flow->get_tcp_flow(); - FileContext* file = get_smb_file_context(flow, file_name_hash, file_id, false); - if (file) - file->set_file_size(file_size); - + { + std::lock_guard guard(process_file_mutex); + FileContext* file = get_smb_file_context(flow, file_name_hash, file_id, false); + if (file) + file->set_file_size(file_size); + } Dce2Smb2SessionTrackerPtr ses_ptr = processing_flow->find_session(session_id); return (!process_data(current_flow_key, nullptr, 0,ses_ptr)); } @@ -153,25 +159,25 @@ bool Dce2Smb2FileTracker::process_data(const uint32_t current_flow_key, const ui current_flow_state.file_offset = offset; current_flow_state.max_offset = offset + max_offset; flow_state_mutex.unlock(); - Dce2Smb2SessionTracker *sess = parent_tree->get_parent(); + Dce2Smb2SessionTracker* sess = parent_tree->get_parent(); if (parent_tree->get_share_type() != SMB2_SHARE_TYPE_DISK) { - Dce2Smb2SessionData *current_flow = nullptr; - if (sess) - { - parent_tree->get_parent()->set_do_not_delete(true); - current_flow = parent_tree->get_parent()->get_flow(current_flow_key); - if (!current_flow) - { - parent_tree->get_parent()->set_do_not_delete(false); - return false; - } - } - else - { + Dce2Smb2SessionData* current_flow = nullptr; + if (sess) + { + parent_tree->get_parent()->set_do_not_delete(true); + current_flow = parent_tree->get_parent()->get_flow(current_flow_key); + if (!current_flow) + { + parent_tree->get_parent()->set_do_not_delete(false); return false; - } - + } + } + else + { + return false; + } + if (data_size > UINT16_MAX) { data_size = UINT16_MAX; @@ -253,33 +259,34 @@ bool Dce2Smb2FileTracker::process_data(const uint32_t current_flow_key, const ui SMB_DEBUG(dce_smb_trace, DEFAULT_TRACE_OPTION_ID, TRACE_INFO_LEVEL, p,"file_process fid %" PRIu64 " data_size %" PRIu32 " offset %" PRIu64 "\n", file_id, data_size, file_offset); - - FileFlows* file_flows = FileFlows::get_file_flows(processing_flow->get_tcp_flow()); - - if (!file_flows) { - SMB_DEBUG(dce_smb_trace, DEFAULT_TRACE_OPTION_ID, TRACE_CRITICAL_LEVEL, p, "file_flows not found\n"); - session_tracker->set_do_not_delete(false); - return true; - } + std::lock_guard guard(process_file_mutex); + FileFlows* file_flows = FileFlows::get_file_flows(processing_flow->get_tcp_flow()); - if (updated_flow.first) - { - // update the new file context in case of flow switch - FileContext* file = file_flows->get_file_context(file_name_hash, true, file_id); - file->set_file_name(file_name, file_name_len); - file->set_file_size(file_size.load() ? file_size.load() : UNKNOWN_FILE_SIZE); - } + if (!file_flows) + { + SMB_DEBUG(dce_smb_trace, DEFAULT_TRACE_OPTION_ID, TRACE_CRITICAL_LEVEL, p, "file_flows not found\n"); + session_tracker->set_do_not_delete(false); + return true; + } - process_file_mutex.lock(); - bool continue_processing = file_flows->file_process(p, file_name_hash, file_data, data_size, - file_offset, direction, file_id); - process_file_mutex.unlock(); - if (!continue_processing) - { - SMB_DEBUG(dce_smb_trace, DEFAULT_TRACE_OPTION_ID, TRACE_INFO_LEVEL, p, "file_process completed\n"); - session_tracker->set_do_not_delete(false); - return false; + if (updated_flow.first) + { + // update the new file context in case of flow switch + FileContext* file = file_flows->get_file_context(file_name_hash, true, file_id); + file->set_file_name(file_name, file_name_len); + file->set_file_size(file_size.load() ? file_size.load() : UNKNOWN_FILE_SIZE); + } + + bool continue_processing = file_flows->file_process(p, file_name_hash, file_data, data_size, + file_offset, direction, file_id); + + if (!continue_processing) + { + SMB_DEBUG(dce_smb_trace, DEFAULT_TRACE_OPTION_ID, TRACE_INFO_LEVEL, p, "file_process completed\n"); + session_tracker->set_do_not_delete(false); + return false; + } } file_offset += data_size; diff --git a/src/service_inspectors/dce_rpc/dce_smb2_tree.cc b/src/service_inspectors/dce_rpc/dce_smb2_tree.cc index 154ad4813..2a7bb73e4 100644 --- a/src/service_inspectors/dce_rpc/dce_smb2_tree.cc +++ b/src/service_inspectors/dce_rpc/dce_smb2_tree.cc @@ -157,12 +157,7 @@ void Dce2Smb2TreeTracker::process_close_request(const Smb2Hdr* smb_header, if (share_type != SMB2_SHARE_TYPE_DISK) { - if (co_tracker != nullptr) - { - DCE2_CoCleanTracker(co_tracker); - snort_free((void*)co_tracker); - co_tracker = nullptr; - } + DCE2_CoCleanTracker(co_tracker); } } @@ -453,7 +448,25 @@ void Dce2Smb2TreeTracker::process_ioctl_command(const uint8_t command_type, const uint8_t* smb_data = (const uint8_t*)smb_header + SMB2_HEADER_LENGTH; const uint8_t structure_size = (command_type == SMB2_CMD_TYPE_REQUEST) ? SMB2_IOCTL_REQUEST_STRUC_SIZE : SMB2_IOCTL_RESPONSE_STRUC_SIZE; + if (SMB2_CMD_TYPE_REQUEST == command_type) + { + const Smb2IoctlRequestHdr* ioctl_req = (const Smb2IoctlRequestHdr*)smb_data; + if ((ioctl_req->ctl_code != FSCTL_PIPE_PEEK) and (ioctl_req->ctl_code != + FSCTL_PIPE_WAIT) and (ioctl_req->ctl_code != FSCTL_PIPE_TRANSCEIVE)) + { + return; + } + } + if (SMB2_CMD_TYPE_RESPONSE == command_type) + { + const Smb2IoctlResponseHdr* ioctl_response = (const Smb2IoctlResponseHdr*)smb_data; + if ((ioctl_response->ctl_code != FSCTL_PIPE_PEEK) and (ioctl_response->ctl_code != + FSCTL_PIPE_WAIT) and (ioctl_response->ctl_code != FSCTL_PIPE_TRANSCEIVE)) + { + return; + } + } const uint8_t* file_data = (const uint8_t*)smb_data + structure_size - 1; int data_size = end - file_data; Dce2Smb2SessionData* current_flow = parent_session->get_flow(current_flow_key);