]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #755 in SNORT/snort3 from smb_active_response to master
authorRuss Combs (rucombs) <rucombs@cisco.com>
Tue, 20 Dec 2016 22:35:25 +0000 (17:35 -0500)
committerRuss Combs (rucombs) <rucombs@cisco.com>
Tue, 20 Dec 2016 22:35:25 +0000 (17:35 -0500)
Squashed commit of the following:

commit 1382167838c9b098ce5ff7a65560f599b741b579
Author: Bhagya Tholpady <bbantwal@cisco.com>
Date:   Mon Dec 19 04:18:15 2016 -0500

    smb active response updates

src/file_api/file_lib.cc
src/file_api/file_lib.h
src/main/snort.cc
src/main/snort.h
src/service_inspectors/dce_rpc/dce_smb.cc
src/service_inspectors/dce_rpc/dce_smb.h
src/service_inspectors/dce_rpc/dce_smb_commands.cc
src/service_inspectors/dce_rpc/dce_smb_utils.cc
src/service_inspectors/dce_rpc/dce_smb_utils.h
src/service_inspectors/dce_rpc/smb_message.cc
src/service_inspectors/dce_rpc/smb_message.h

index d5efcb93638ff9853eaf7e217f869b67650a92b5..bdc22b07b150168a9b8889f46f321db2afd7835a 100644 (file)
@@ -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())
index 5ebac327c1791a6ca1a494891b5479fe099b1ec0..34d4648a9445fe7c9117b1890b9f04bb860780c8 100644 (file)
@@ -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
index d7a081090d1c2ea2aa489e6f53d02c2dc9c5fb87..a57ddfb04e529d3def7a525a73210e4732e32cd3 100644 (file)
@@ -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;
 }
-
index 2b0613e419aa11416252e7890143d3e7478154d5..d3ce2658c59303d84ece9043a3708567fd2a7c61 100644 (file)
@@ -26,6 +26,7 @@
 #include <assert.h>
 #include <sys/types.h>
 #include <stdio.h>
+#include "main/snort_types.h"
 
 extern "C" {
 #include <daq_common.h>
@@ -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();
index f6c3732ac02e3fc6ea92266418b2fa96ab1e413d..43ad89b6e4255ffd30e3a638aabf1985c8bffc2b 100644 (file)
@@ -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)
index 1b21890f35023971c934c774f45c897c259a8a45..53719584e1df4b5dcfc42037faeb21b44c1ace23 100644 (file)
@@ -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;
index b76167b805b9904f637e9bc0f355f6b79572784c..526929dd35d2c038741672ef84055bb7f40d21a2 100644 (file)
@@ -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
     {
index ed62c3949cbe1cba18c3fd7e77970b0c6edb52c4..02d0ef24cba5fb8fb22307305f3bb98345f6c314 100644 (file)
 #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++;
index 63986acf7d83ec5b65e5e07f868c1fd35d3299e6..a2b31b1e6cf3d51f3cd067de3ab6a3dd3902b9fa 100644 (file)
@@ -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
index 9e2fcac68520fe06cc19c0b74c66c6976c78aa71..ae27b4482d097be155d2328b6d218a42e9915512 100644 (file)
@@ -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;
index f2728276b5a6621a3114ba07ae75e355a5b914d0..3b11d40b4bc1b492ae59ca91088c116f6c630fb7 100644 (file)
@@ -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
  ********************************************************************/