From: Russ Combs (rucombs) Date: Tue, 20 Dec 2016 22:35:25 +0000 (-0500) Subject: Merge pull request #755 in SNORT/snort3 from smb_active_response to master X-Git-Tag: 3.0.0-233~130 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2a94cf6e241db992a98b0bb45cfa39fabd8bfea9;p=thirdparty%2Fsnort3.git Merge pull request #755 in SNORT/snort3 from smb_active_response to master Squashed commit of the following: commit 1382167838c9b098ce5ff7a65560f599b741b579 Author: Bhagya Tholpady Date: Mon Dec 19 04:18:15 2016 -0500 smb active response updates --- diff --git a/src/file_api/file_lib.cc b/src/file_api/file_lib.cc index d5efcb936..bdc22b07b 100644 --- a/src/file_api/file_lib.cc +++ b/src/file_api/file_lib.cc @@ -246,6 +246,17 @@ void FileContext::log_file_event(Flow* flow) } } +FileVerdict FileContext::file_signature_lookup(Flow* flow) +{ + if (get_file_sig_sha256() && is_file_signature_enabled()) + { + FilePolicy& inspect = FileService::get_inspect(); + return inspect.signature_lookup(flow, this); + } + else + return FILE_VERDICT_UNKNOWN; +} + void FileContext::finish_signature_lookup(Flow* flow) { if (get_file_sig_sha256()) diff --git a/src/file_api/file_lib.h b/src/file_api/file_lib.h index 5ebac327c..34d4648a9 100644 --- a/src/file_api/file_lib.h +++ b/src/file_api/file_lib.h @@ -96,6 +96,7 @@ public: FileCaptureState process_file_capture(const uint8_t* file_data, int data_size, FilePosition pos); void log_file_event(Flow*); + FileVerdict file_signature_lookup(Flow*); // Preserve the file in memory until it is released // The file reserved will be returned and it will be detached from file context/session diff --git a/src/main/snort.cc b/src/main/snort.cc index d7a081090..a57ddfb04 100644 --- a/src/main/snort.cc +++ b/src/main/snort.cc @@ -459,6 +459,9 @@ bool Snort::has_dropped_privileges() void Snort::set_main_hook(MainHook_f f) { main_hook = f; } +Packet* Snort::get_packet() +{ return s_packet; } + void Snort::setup(int argc, char* argv[]) { set_main_thread(); @@ -866,4 +869,3 @@ DAQ_Verdict Snort::packet_callback( return verdict; } - diff --git a/src/main/snort.h b/src/main/snort.h index 2b0613e41..d3ce2658c 100644 --- a/src/main/snort.h +++ b/src/main/snort.h @@ -26,6 +26,7 @@ #include #include #include +#include "main/snort_types.h" extern "C" { #include @@ -66,6 +67,8 @@ public: static void set_main_hook(MainHook_f); + SO_PUBLIC static Packet* get_packet(); + private: static void init(int, char**); static void term(); diff --git a/src/service_inspectors/dce_rpc/dce_smb.cc b/src/service_inspectors/dce_rpc/dce_smb.cc index f6c3732ac..43ad89b6e 100644 --- a/src/service_inspectors/dce_rpc/dce_smb.cc +++ b/src/service_inspectors/dce_rpc/dce_smb.cc @@ -24,6 +24,7 @@ #include "file_api/file_service.h" #include "protocols/packet.h" #include "utils/util.h" +#include "packet_io/active.h" #include "dce_smb_module.h" #include "dce_smb_utils.h" @@ -354,6 +355,11 @@ private: Dce2Smb::Dce2Smb(dce2SmbProtoConf& pc) { config = pc; + if ((config.smb_file_inspection == DCE2_SMB_FILE_INSPECTION_ONLY) + || (config.smb_file_inspection == DCE2_SMB_FILE_INSPECTION_ON)) + { + Active::set_enabled(); + } } Dce2Smb::~Dce2Smb() @@ -429,6 +435,7 @@ static void dce2_smb_init() { Dce2SmbFlowData::init(); DCE2_SmbInitGlobals(); + DCE2_SmbInitDeletePdu(); } static Inspector* dce2_smb_ctor(Module* m) diff --git a/src/service_inspectors/dce_rpc/dce_smb.h b/src/service_inspectors/dce_rpc/dce_smb.h index 1b21890f3..53719584e 100644 --- a/src/service_inspectors/dce_rpc/dce_smb.h +++ b/src/service_inspectors/dce_rpc/dce_smb.h @@ -447,10 +447,8 @@ struct DCE2_SmbSsnData Smb2Request* smb2_requests; -#ifdef ACTIVE_RESPONSE DCE2_SmbFileTracker* fb_ftracker; bool block_pdus; -#endif // Maximum file depth as returned from file API int64_t max_file_depth; diff --git a/src/service_inspectors/dce_rpc/dce_smb_commands.cc b/src/service_inspectors/dce_rpc/dce_smb_commands.cc index b76167b80..526929dd3 100644 --- a/src/service_inspectors/dce_rpc/dce_smb_commands.cc +++ b/src/service_inspectors/dce_rpc/dce_smb_commands.cc @@ -643,20 +643,13 @@ DCE2_Ret DCE2_SmbClose(DCE2_SmbSsnData* ssd, const SmbNtHdr*, // Set this for response ssd->cur_rtracker->ftracker = DCE2_SmbGetFileTracker(ssd, fid); - //FIXIT-M port active response related code -/* -#ifdef ACTIVE_RESPONSE if ((ssd->fb_ftracker != NULL) && (ssd->fb_ftracker == ssd->cur_rtracker->ftracker)) { - void *ssnptr = ssd->sd.wire_pkt->stream_session; - void *p = (void *)ssd->sd.wire_pkt; - File_Verdict verdict = DCE2_SmbGetFileVerdict(p, ssnptr); + FileVerdict verdict = DCE2_get_file_verdict(ssd); if ((verdict == FILE_VERDICT_BLOCK) || (verdict == FILE_VERDICT_REJECT)) ssd->block_pdus = true; } -#endif -*/ } else { diff --git a/src/service_inspectors/dce_rpc/dce_smb_utils.cc b/src/service_inspectors/dce_rpc/dce_smb_utils.cc index ed62c3949..02d0ef24c 100644 --- a/src/service_inspectors/dce_rpc/dce_smb_utils.cc +++ b/src/service_inspectors/dce_rpc/dce_smb_utils.cc @@ -22,36 +22,30 @@ #include "dce_smb_utils.h" #include "detection/detection_util.h" -#include "file_api/file_flows.h" #include "utils/util.h" +#include "packet_io/active.h" +#include "main/snort.h" #include "dce_smb_module.h" +static uint8_t dce2_smb_delete_pdu[65535]; + /******************************************************************** * Private function prototypes ********************************************************************/ static void DCE2_SmbSetNewFileAPIFileTracker(DCE2_SmbSsnData* ssd); static void DCE2_SmbResetFileChunks(DCE2_SmbFileTracker* ssd); static void DCE2_SmbFinishFileAPI(DCE2_SmbSsnData* ssd); +static void DCE2_SmbFinishFileBlockVerdict(DCE2_SmbSsnData* ssd); /******************************************************************** * Inline functions ********************************************************************/ static inline bool DCE2_SmbIsVerdictSuspend(bool upload, FilePosition position) { - // FIXIT-M port active response related code -/* -#ifdef ACTIVE_RESPONSE if (upload && ((position == SNORT_FILE_FULL) || (position == SNORT_FILE_END))) return true; -#else -*/ - UNUSED(upload); - UNUSED(position); -/* -#endif -*/ return false; } @@ -254,13 +248,10 @@ void DCE2_SmbRemoveUid(DCE2_SmbSsnData* ssd, const uint16_t uid) { if (ssd->fapi_ftracker == ftracker) DCE2_SmbFinishFileAPI(ssd); - // FIXIT-M port active response related code -/* -#ifdef ACTIVE_RESPONSE - if (ssd->fb_ftracker == ftracker) - DCE2_SmbFinishFileBlockVerdict(ssd); -#endif -*/ + + if (ssd->fb_ftracker == ftracker) + DCE2_SmbFinishFileBlockVerdict(ssd); + DCE2_ListRemoveCurrent(ssd->ftrackers); DCE2_SmbRemoveFileTrackerFromRequestTrackers(ssd, ftracker); } @@ -609,13 +600,9 @@ void DCE2_SmbRemoveFileTracker(DCE2_SmbSsnData* ssd, DCE2_SmbFileTracker* ftrack if (ssd->fapi_ftracker == ftracker) DCE2_SmbFinishFileAPI(ssd); - // FIXIT-M port active response related code -/* -#ifdef ACTIVE_RESPONSE if (ssd->fb_ftracker == ftracker) DCE2_SmbFinishFileBlockVerdict(ssd); -#endif -*/ + if (ftracker == &ssd->ftracker) DCE2_SmbCleanFileTracker(&ssd->ftracker); else if (ssd->ftrackers != nullptr) @@ -926,13 +913,10 @@ void DCE2_SmbRemoveTid(DCE2_SmbSsnData* ssd, const uint16_t tid) { if (ssd->fapi_ftracker == ftracker) DCE2_SmbFinishFileAPI(ssd); - // FIXIT-M port active response related code -/* -#ifdef ACTIVE_RESPONSE + if (ssd->fb_ftracker == ftracker) DCE2_SmbFinishFileBlockVerdict(ssd); -#endif -*/ + DCE2_ListRemoveCurrent(ssd->ftrackers); DCE2_SmbRemoveFileTrackerFromRequestTrackers(ssd, ftracker); } @@ -1494,6 +1478,106 @@ void DCE2_SmbAbortFileAPI(DCE2_SmbSsnData* ssd) ssd->fapi_ftracker = nullptr; } +FileContext* DCE2_get_main_file_context(DCE2_SmbSsnData* ssd) +{ + assert(ssd->sd.wire_pkt); + FileFlows* file_flows = FileFlows::get_file_flows((ssd->sd.wire_pkt)->flow); + assert(file_flows); + return file_flows->get_current_file_context(); +} + +FileVerdict DCE2_get_file_verdict(DCE2_SmbSsnData* ssd) +{ + FileContext* file = DCE2_get_main_file_context(ssd); + if ( !file ) + return FILE_VERDICT_UNKNOWN; + return file->verdict; +} + +void DCE2_SmbInitDeletePdu(void) +{ + NbssHdr *nb_hdr = (NbssHdr *)dce2_smb_delete_pdu; + SmbNtHdr *smb_hdr = (SmbNtHdr *)((uint8_t *)nb_hdr + sizeof(*nb_hdr)); + SmbDeleteReq *del_req = (SmbDeleteReq *)((uint8_t *)smb_hdr + sizeof(*smb_hdr)); + uint8_t *del_req_fmt = (uint8_t *)del_req + sizeof(*del_req); + uint16_t smb_flg2 = 0x4001; + uint16_t search_attrs = 0x0006; + + memset(dce2_smb_delete_pdu, 0, sizeof(dce2_smb_delete_pdu)); + + nb_hdr->type = 0; + nb_hdr->flags = 0; + + memcpy((void *)smb_hdr->smb_idf, (void *)"\xffSMB", sizeof(smb_hdr->smb_idf)); + smb_hdr->smb_com = SMB_COM_DELETE; + smb_hdr->smb_status.nt_status = 0; + //smb_hdr->smb_flg = 0x18; + smb_hdr->smb_flg = 0; + smb_hdr->smb_flg2 = SmbHtons(&smb_flg2); + smb_hdr->smb_tid = 0; // needs to be set before injected + smb_hdr->smb_pid = 777; + smb_hdr->smb_uid = 0; // needs to be set before injected + smb_hdr->smb_mid = 777; + + del_req->smb_wct = 1; + del_req->smb_search_attrs = SmbHtons(&search_attrs); + *del_req_fmt = SMB_FMT__ASCII; +} + +static void DCE2_SmbInjectDeletePdu(DCE2_SmbSsnData *ssd, DCE2_SmbFileTracker *ftracker) +{ + Packet* inject_pkt = Snort::get_packet(); + if( inject_pkt->flow != ssd->sd.wire_pkt->flow ) + return; + + NbssHdr *nb_hdr = (NbssHdr *)dce2_smb_delete_pdu; + SmbNtHdr *smb_hdr = (SmbNtHdr *)((uint8_t *)nb_hdr + sizeof(*nb_hdr)); + SmbDeleteReq *del_req = (SmbDeleteReq *)((uint8_t *)smb_hdr + sizeof(*smb_hdr)); + char *del_filename = (char *)((uint8_t *)del_req + sizeof(*del_req) + 1); + uint16_t file_name_len = strlen(ftracker->file_name) + 1; + + nb_hdr->length = htons(sizeof(*smb_hdr) + sizeof(*del_req) + 1 + file_name_len); + uint32_t len = ntohs(nb_hdr->length) + sizeof(*nb_hdr); + smb_hdr->smb_tid = SmbHtons(&ftracker->tid_v1); + smb_hdr->smb_uid = SmbHtons(&ftracker->uid_v1); + del_req->smb_bcc = 1 + file_name_len; + memcpy(del_filename, ftracker->file_name, file_name_len); + + Active::inject_data(inject_pkt, 0, (uint8_t *)nb_hdr, len); +} + +static FileVerdict DCE2_SmbLookupFileVerdict(DCE2_SmbSsnData* ssd) +{ + Profile profile(dce2_smb_pstat_smb_file_api); + + FileContext* file = DCE2_get_main_file_context(ssd); + + if ( !file ) + return FILE_VERDICT_UNKNOWN; + + FileVerdict verdict = file->verdict; + + if (verdict == FILE_VERDICT_PENDING) + verdict = file->file_signature_lookup(ssd->sd.wire_pkt->flow); + + return verdict; +} + +static void DCE2_SmbFinishFileBlockVerdict(DCE2_SmbSsnData* ssd) +{ + Profile profile(dce2_smb_pstat_smb_file); + + FileVerdict verdict = DCE2_SmbLookupFileVerdict(ssd); + if ((verdict == FILE_VERDICT_BLOCK) || (verdict == FILE_VERDICT_REJECT)) + { + DCE2_SmbInjectDeletePdu(ssd, ssd->fb_ftracker); + } + + ssd->fb_ftracker = nullptr; + ssd->block_pdus = false; + +} + static void DCE2_SmbFinishFileAPI(DCE2_SmbSsnData* ssd) { Packet* p = ssd->sd.wire_pkt; @@ -1514,26 +1598,16 @@ static void DCE2_SmbFinishFileAPI(DCE2_SmbSsnData* ssd) && (ftracker->ff_bytes_processed != 0)) { Profile profile(dce2_smb_pstat_smb_file_api); - // FIXIT-M port active response related code -/* -#ifdef ACTIVE_RESPONSE - if (_dpd.fileAPI->file_process(p, nullptr, 0, SNORT_FILE_END, upload, upload)) + if (file_flows->file_process(nullptr, 0, SNORT_FILE_END, upload)) { if (upload) { - File_Verdict verdict = - _dpd.fileAPI->get_file_verdict(ssd->sd.wire_pkt->stream_session); + FileVerdict verdict = DCE2_get_file_verdict(ssd); if ((verdict == FILE_VERDICT_BLOCK) || (verdict == FILE_VERDICT_REJECT)) ssd->fb_ftracker = ftracker; } } -#else -*/ - file_flows->file_process(nullptr, 0, SNORT_FILE_END, upload); -/* -#endif -*/ dce2_smb_stats.smb_files_processed++; } } @@ -1546,13 +1620,10 @@ static DCE2_Ret DCE2_SmbFileAPIProcess(DCE2_SmbSsnData* ssd, uint32_t data_len, bool upload) { FilePosition position; - // FIXIT-M port active response related code -/* -#ifdef ACTIVE_RESPONSE + if (ssd->fb_ftracker && (ssd->fb_ftracker != ftracker)) return DCE2_RET__SUCCESS; -#endif -*/ + // Trim data length if it exceeds the maximum file depth if ((ssd->max_file_depth != 0) && (ftracker->ff_bytes_processed + data_len) > (uint64_t)ssd->max_file_depth) @@ -1616,12 +1687,9 @@ static DCE2_Ret DCE2_SmbFileAPIProcess(DCE2_SmbSsnData* ssd, if ((position == SNORT_FILE_FULL) || (position == SNORT_FILE_END)) { - // FIXIT-M port active response related code -/*#ifdef - ACTIVE_RESPONSE if (upload) { - File_Verdict verdict = _dpd.fileAPI->get_file_verdict(ssd->sd.wire_pkt->stream_session); + FileVerdict verdict = DCE2_get_file_verdict(ssd); if ((verdict == FILE_VERDICT_BLOCK) || (verdict == FILE_VERDICT_REJECT) || (verdict == FILE_VERDICT_PENDING)) @@ -1629,8 +1697,6 @@ static DCE2_Ret DCE2_SmbFileAPIProcess(DCE2_SmbSsnData* ssd, ssd->fb_ftracker = ftracker; } } -#endif -*/ ftracker->ff_sequential_only = false; dce2_smb_stats.smb_files_processed++; diff --git a/src/service_inspectors/dce_rpc/dce_smb_utils.h b/src/service_inspectors/dce_rpc/dce_smb_utils.h index 63986acf7..a2b31b1e6 100644 --- a/src/service_inspectors/dce_rpc/dce_smb_utils.h +++ b/src/service_inspectors/dce_rpc/dce_smb_utils.h @@ -23,6 +23,7 @@ #define DCE_SMB_UTILS_H #include "dce_smb.h" +#include "file_api/file_flows.h" /******************************************************************** * Enums @@ -176,6 +177,8 @@ void DCE2_SmbProcessFileData(DCE2_SmbSsnData* ssd, DCE2_SmbFileTracker* ftracker, const uint8_t* data_ptr, uint32_t data_len, bool upload); void DCE2_FileDetect(); +FileVerdict DCE2_get_file_verdict(DCE2_SmbSsnData* ); +void DCE2_SmbInitDeletePdu(void); /******************************************************************** * Inline functions diff --git a/src/service_inspectors/dce_rpc/smb_message.cc b/src/service_inspectors/dce_rpc/smb_message.cc index 9e2fcac68..ae27b4482 100644 --- a/src/service_inspectors/dce_rpc/smb_message.cc +++ b/src/service_inspectors/dce_rpc/smb_message.cc @@ -24,6 +24,7 @@ #include "file_api/file_service.h" #include "protocols/packet.h" #include "utils/util.h" +#include "packet_io/active.h" #include "dce_smb_module.h" #include "dce_smb_utils.h" @@ -769,6 +770,12 @@ static void DCE2_SmbProcessCommand(DCE2_SmbSsnData* ssd, const SmbNtHdr* smb_hdr while (nb_len > 0) { + if (ssd->block_pdus && (DCE2_SmbType(ssd) == SMB_TYPE__REQUEST)) + { + Active::drop_packet(ssd->sd.wire_pkt); + status = DCE2_RET__IGNORE; + break; + } // Break out if command not supported if (smb_com_funcs[smb_com] == nullptr) break; diff --git a/src/service_inspectors/dce_rpc/smb_message.h b/src/service_inspectors/dce_rpc/smb_message.h index f2728276b..3b11d40b4 100644 --- a/src/service_inspectors/dce_rpc/smb_message.h +++ b/src/service_inspectors/dce_rpc/smb_message.h @@ -142,6 +142,16 @@ inline uint16_t SmbCloseReqFid(const SmbCloseReq* req) return alignedNtohs(&req->smb_fid); } +/******************************************************************** + * SMB_COM_DELETE + ********************************************************************/ +struct SmbDeleteReq /* smb_wct = 1 */ +{ + uint8_t smb_wct; + uint16_t smb_search_attrs; + uint16_t smb_bcc; +}; + /******************************************************************** * SMB_COM_READ ********************************************************************/