From: Michael Altizer Date: Fri, 5 Jun 2020 17:39:32 +0000 (-0400) Subject: Revert "Merge pull request #2243 in SNORT/snort3 from ~CYLEONAR/snort3:master to... X-Git-Tag: 3.0.1-5~23 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9255327b23cdb122319f26079411defc6f598133;p=thirdparty%2Fsnort3.git Revert "Merge pull request #2243 in SNORT/snort3 from ~CYLEONAR/snort3:master to master" This reverts commit 59cfcb6ac6564174bdb9673a3f32e65607fcebc3. --- diff --git a/src/actions/actions.cc b/src/actions/actions.cc index 357890890..2f28c9aea 100644 --- a/src/actions/actions.cc +++ b/src/actions/actions.cc @@ -121,12 +121,14 @@ void Actions::execute(Actions::Type action, Packet* p, const OptTreeNode* otn, case Actions::DROP: p->active->drop_packet(p); + p->active->set_drop_reason("ips"); alert(p, otn); SetTags(p, otn, event_id); break; case Actions::BLOCK: p->active->block_session(p); + p->active->set_drop_reason("ips"); alert(p, otn); SetTags(p, otn, event_id); break; diff --git a/src/file_api/file_cache.cc b/src/file_api/file_cache.cc index 675472761..a64397b75 100644 --- a/src/file_api/file_cache.cc +++ b/src/file_api/file_cache.cc @@ -274,11 +274,13 @@ bool FileCache::apply_verdict(Packet* p, FileContext* file_ctx, FileVerdict verd case FILE_VERDICT_BLOCK: // can't block session inside a session act->set_delayed_action(Active::ACT_BLOCK, true); + act->set_drop_reason("file"); break; case FILE_VERDICT_REJECT: // can't reset session inside a session act->set_delayed_action(Active::ACT_RESET, true); + act->set_drop_reason("file"); break; case FILE_VERDICT_STOP_CAPTURE: file_ctx->stop_file_capture(); diff --git a/src/file_api/file_lib.cc b/src/file_api/file_lib.cc index 4b8514427..54ddaefd9 100644 --- a/src/file_api/file_lib.cc +++ b/src/file_api/file_lib.cc @@ -349,6 +349,13 @@ void FileContext::finish_signature_lookup(Packet* p, bool final_lookup, FilePoli FileCache* file_cache = FileService::get_file_cache(); if (file_cache) file_cache->apply_verdict(p, this, verdict, false, policy); + + if ( PacketTracer::is_active() and ( verdict == FILE_VERDICT_BLOCK + or verdict == FILE_VERDICT_REJECT )) + { + PacketTracer::log("File: signature lookup verdict %s\n", + verdict == FILE_VERDICT_BLOCK ? "block" : "reject"); + } log_file_event(flow, policy); config_file_signature(false); file_stats->signatures_processed[get_file_type()][get_file_direction()]++; @@ -450,6 +457,13 @@ bool FileContext::process(Packet* p, const uint8_t* file_data, int data_size, FileCache* file_cache = FileService::get_file_cache(); if (file_cache) file_cache->apply_verdict(p, this, v, false, policy); + + if ( PacketTracer::is_active() and ( v == FILE_VERDICT_BLOCK + or v == FILE_VERDICT_REJECT )) + { + PacketTracer::log("File: file type verdict %s\n", + v == FILE_VERDICT_BLOCK ? "block" : "reject"); + } } log_file_event(flow, policy); diff --git a/src/flow/flow_control.cc b/src/flow/flow_control.cc index 3735a7519..31bddb9e8 100644 --- a/src/flow/flow_control.cc +++ b/src/flow/flow_control.cc @@ -470,7 +470,10 @@ unsigned FlowControl::process(Flow* flow, Packet* p) else p->active->block_again(); + p->active->set_drop_reason("session"); DetectionEngine::disable_all(p); + if ( PacketTracer::is_active() ) + PacketTracer::log("Session: session has been blocked, drop\n"); break; case Flow::FlowState::RESET: @@ -480,7 +483,10 @@ unsigned FlowControl::process(Flow* flow, Packet* p) p->active->reset_again(); Stream::blocked_flow(p); + p->active->set_drop_reason("session"); DetectionEngine::disable_all(p); + if ( PacketTracer::is_active() ) + PacketTracer::log("Session: session has been reset\n"); break; } diff --git a/src/flow/test/flow_cache_test.cc b/src/flow/test/flow_cache_test.cc index db8f0a1d2..7b1005c62 100644 --- a/src/flow/test/flow_cache_test.cc +++ b/src/flow/test/flow_cache_test.cc @@ -54,12 +54,12 @@ THREAD_LOCAL bool Active::s_suspend = false; THREAD_LOCAL PacketTracer* snort::s_pkt_trace = nullptr; void Active::drop_packet(snort::Packet const*, bool) { } -PacketTracer::PacketTracer() { } PacketTracer::~PacketTracer() { } void PacketTracer::log(const char*, ...) { } void PacketTracer::open_file() { } void PacketTracer::dump_to_daq(Packet*) { } void PacketTracer::reset() { } +void Active::set_drop_reason(char const*) { } Packet::Packet(bool) { } Packet::~Packet() { } Flow::Flow() { memset(this, 0, sizeof(*this)); } diff --git a/src/flow/test/flow_control_test.cc b/src/flow/test/flow_control_test.cc index da1fc84bb..5cc2d97f2 100644 --- a/src/flow/test/flow_control_test.cc +++ b/src/flow/test/flow_control_test.cc @@ -54,12 +54,12 @@ THREAD_LOCAL bool Active::s_suspend = false; THREAD_LOCAL PacketTracer* snort::s_pkt_trace = nullptr; void Active::drop_packet(snort::Packet const*, bool) { } -PacketTracer::PacketTracer() = default; PacketTracer::~PacketTracer() = default; void PacketTracer::log(const char*, ...) { } void PacketTracer::open_file() { } void PacketTracer::dump_to_daq(Packet*) { } void PacketTracer::reset() { } +void Active::set_drop_reason(char const*) { } Packet::Packet(bool) { } Packet::~Packet() = default; FlowCache::FlowCache(const FlowCacheConfig& cfg) : config(cfg) { } diff --git a/src/main/CMakeLists.txt b/src/main/CMakeLists.txt index d1d61cd96..c5eaed25e 100644 --- a/src/main/CMakeLists.txt +++ b/src/main/CMakeLists.txt @@ -2,6 +2,7 @@ set (INCLUDES analyzer_command.h policy.h + snort.h snort_config.h snort_debug.h snort_types.h diff --git a/src/main/analyzer.cc b/src/main/analyzer.cc index 37105a1ec..dcc89bf67 100644 --- a/src/main/analyzer.cc +++ b/src/main/analyzer.cc @@ -392,6 +392,9 @@ void Analyzer::post_process_daq_pkt_msg(Packet* p) DataBus::publish(FINALIZE_PACKET_EVENT, event); } + if (verdict == DAQ_VERDICT_BLOCK or verdict == DAQ_VERDICT_BLACKLIST) + p->active->send_reason_to_daq(*p); + p->pkth = nullptr; // No longer avail after finalize_message. { diff --git a/src/main/test/distill_verdict_test.cc b/src/main/test/distill_verdict_test.cc index 3e16dad49..f4d106df2 100644 --- a/src/main/test/distill_verdict_test.cc +++ b/src/main/test/distill_verdict_test.cc @@ -26,6 +26,7 @@ #include "stubs.h" #include "main/analyzer.h" +#include "packet_io/sfdaq_instance.h" #include #include diff --git a/src/main/test/stubs.h b/src/main/test/stubs.h index 75f564d42..7c3581a76 100644 --- a/src/main/test/stubs.h +++ b/src/main/test/stubs.h @@ -152,6 +152,7 @@ bool SFDAQ::forwarding_packet(const DAQ_PktHdr_t*) { return false; } int SFDAQ::inject(DAQ_Msg_h, int, const uint8_t*, uint32_t) { return -1; } bool SFDAQ::can_inject() { return false; } bool SFDAQ::can_inject_raw() { return false; } +int SFDAQInstance::set_packet_verdict_reason(DAQ_Msg_h, uint8_t) { return 0; } DetectionEngine::DetectionEngine() { } DetectionEngine::~DetectionEngine() { } void DetectionEngine::onload() { } diff --git a/src/network_inspectors/packet_tracer/packet_tracer.cc b/src/network_inspectors/packet_tracer/packet_tracer.cc index a027f90bb..59e51dc97 100644 --- a/src/network_inspectors/packet_tracer/packet_tracer.cc +++ b/src/network_inspectors/packet_tracer/packet_tracer.cc @@ -31,6 +31,7 @@ #include "detection/ips_context.h" #include "log/log.h" #include "log/messages.h" +#include "packet_io/active.h" #include "packet_io/sfdaq_instance.h" #include "protocols/eth.h" #include "protocols/icmp4.h" @@ -49,11 +50,6 @@ using namespace snort; // static variables // ----------------------------------------------------------------------------- -static const uint8_t VERDICT_REASON_NO_BLOCK = 2; /* Not blocking packet; all enum defined after this indicates blocking */ - -// FIXIT-M currently non-thread-safe accesses being done in packet threads against this -static std::unordered_map reasons = { {VERDICT_REASON_NO_BLOCK, PacketTracer::PRIORITY_UNSET} }; - // FIXIT-M refactor the way this is used so all methods are members called against this pointer THREAD_LOCAL PacketTracer* snort::s_pkt_trace = nullptr; @@ -67,12 +63,6 @@ static bool config_status = false; // static functions // ----------------------------------------------------------------------------- -void PacketTracer::register_verdict_reason(uint8_t reason_code, uint8_t priority) -{ - assert(reasons.find(reason_code) == reasons.end()); - reasons[reason_code] = priority; -} - void PacketTracer::set_log_file(const std::string& file) { log_file = file; } @@ -120,18 +110,18 @@ void PacketTracer::dump(Packet* p) if (s_pkt_trace->daq_activated) s_pkt_trace->dump_to_daq(p); - if (s_pkt_trace->user_enabled or s_pkt_trace->shell_enabled) + if ((s_pkt_trace->buff_len > 0) + and (s_pkt_trace->user_enabled or s_pkt_trace->shell_enabled)) + { + const char* drop_reason = p->active->get_drop_reason(); + if (drop_reason) + PacketTracer::log("Verdict Reason: %s\n", drop_reason); LogMessage(s_pkt_trace->log_fh, "%s\n", s_pkt_trace->buffer); + } s_pkt_trace->reset(); } -void PacketTracer::set_reason(uint8_t reason) -{ - if ( reasons[reason] > reasons[s_pkt_trace->reason] ) - s_pkt_trace->reason = reason; -} - void PacketTracer::log(const char* format, ...) { if (is_paused()) @@ -240,10 +230,6 @@ void PacketTracer::activate(const Packet& p) // non-static functions // ----------------------------------------------------------------------------- -// constructor -PacketTracer::PacketTracer() -{ reason = VERDICT_REASON_NO_BLOCK; } - // destructor PacketTracer::~PacketTracer() { @@ -405,7 +391,7 @@ void PacketTracer::open_file() void PacketTracer::dump_to_daq(Packet* p) { assert(p); - p->daq_instance->modify_flow_pkt_trace(p->daq_msg, reason, + p->daq_instance->set_packet_trace_data(p->daq_msg, (uint8_t *)buffer, buff_len + 1); } @@ -413,12 +399,10 @@ void PacketTracer::reset() { buff_len = 0; buffer[0] = '\0'; - reason = VERDICT_REASON_NO_BLOCK; for ( unsigned i = 0; i < mutes.size(); i++ ) mutes[i] = false; } - // -------------------------------------------------------------------------- // unit tests // -------------------------------------------------------------------------- @@ -430,8 +414,6 @@ void PacketTracer::reset() class TestPacketTracer : public PacketTracer { public: - uint8_t dump_reason = VERDICT_REASON_NO_BLOCK; - static void thread_init() { PacketTracer::_thread_init(); } @@ -456,14 +438,8 @@ public: static bool is_paused() { return ((TestPacketTracer*)s_pkt_trace)->pause_count; } - static uint8_t get_reason() - { return ((TestPacketTracer*)s_pkt_trace)->reason; } - - static uint8_t get_dump_reason() - { return ((TestPacketTracer*)s_pkt_trace)->dump_reason; } - void dump_to_daq(Packet*) override - { dump_reason = reason; } + { } static std::vector get_mutes() { return ((TestPacketTracer*)s_pkt_trace)->mutes; } @@ -595,42 +571,6 @@ TEST_CASE("pause", "[PacketTracer]") TestPacketTracer::thread_term(); } -TEST_CASE("reasons", "[PacketTracer]") -{ - TestPacketTracer::thread_init(); - TestPacketTracer::set_daq_enable(true); - uint8_t low1 = 100, low2 = 101, high = 102; - TestPacketTracer::register_verdict_reason(low1, PacketTracer::PRIORITY_LOW); - TestPacketTracer::register_verdict_reason(low2, PacketTracer::PRIORITY_LOW); - TestPacketTracer::register_verdict_reason(high, PacketTracer::PRIORITY_HIGH); - - // Init - CHECK((TestPacketTracer::get_reason() == VERDICT_REASON_NO_BLOCK)); - - // Update - TestPacketTracer::set_reason(low1); - CHECK((TestPacketTracer::get_reason() == low1)); - - // Don't update if already set - TestPacketTracer::set_reason(VERDICT_REASON_NO_BLOCK); - CHECK((TestPacketTracer::get_reason() == low1)); - TestPacketTracer::set_reason(low2); - CHECK((TestPacketTracer::get_reason() == low1)); - - // Always update for high priority - TestPacketTracer::set_reason(high); - CHECK((TestPacketTracer::get_reason() == high)); - - // Dump resets reason - TestPacketTracer::dump(nullptr); - CHECK((TestPacketTracer::get_reason() == VERDICT_REASON_NO_BLOCK)); - - // Dump delivers reason to daq - CHECK((TestPacketTracer::get_dump_reason() == high)); - - TestPacketTracer::thread_term(); -} - TEST_CASE("verbosity", "[PacketTracer]") { TestPacketTracer::thread_init(); diff --git a/src/network_inspectors/packet_tracer/packet_tracer.h b/src/network_inspectors/packet_tracer/packet_tracer.h index 16fef4ff4..413cb3514 100644 --- a/src/network_inspectors/packet_tracer/packet_tracer.h +++ b/src/network_inspectors/packet_tracer/packet_tracer.h @@ -44,14 +44,7 @@ struct Packet; class PacketTracer { public: - enum VerdictPriority : uint8_t - { - PRIORITY_UNSET = 0, - PRIORITY_LOW = 1, - PRIORITY_HIGH = 2 - }; - - PacketTracer(); + PacketTracer() = default; virtual ~PacketTracer(); typedef uint8_t TracerMute; @@ -76,8 +69,6 @@ public: static SO_PUBLIC TracerMute get_mute(); - static SO_PUBLIC void register_verdict_reason(uint8_t reason_code, uint8_t priority); - static SO_PUBLIC void set_reason(uint8_t); static SO_PUBLIC void log(const char* format, ...) __attribute__((format (printf, 1, 2))); static SO_PUBLIC void log(TracerMute, const char* format, ...) __attribute__((format (printf, 2, 3))); @@ -89,7 +80,6 @@ protected: std::vector mutes; char buffer[max_buff_size]; unsigned buff_len = 0; - uint8_t reason; unsigned pause_count = 0; bool user_enabled = false; diff --git a/src/network_inspectors/reputation/reputation_inspect.cc b/src/network_inspectors/reputation/reputation_inspect.cc index d8f9e31c5..3fe290b12 100644 --- a/src/network_inspectors/reputation/reputation_inspect.cc +++ b/src/network_inspectors/reputation/reputation_inspect.cc @@ -37,8 +37,6 @@ #include "reputation_parse.h" -#define VERDICT_REASON_REPUTATION 19 - using namespace snort; THREAD_LOCAL ProfileStats reputation_perf_stats; @@ -277,12 +275,10 @@ static void snort_reputation(ReputationConfig* config, Packet* p) // disable all preproc analysis and detection for this packet DetectionEngine::disable_all(p); act->block_session(p, true); + act->set_drop_reason("reputation"); reputationstats.blacklisted++; if (PacketTracer::is_active()) - { - PacketTracer::set_reason(VERDICT_REASON_REPUTATION); PacketTracer::log("Reputation: packet blacklisted, drop\n"); - } } else if (MONITORED_SRC == decision or MONITORED_DST == decision) @@ -453,10 +449,6 @@ static Module* mod_ctor() static void mod_dtor(Module* m) { delete m; } -static void reputation_init() -{ - PacketTracer::register_verdict_reason(VERDICT_REASON_REPUTATION, PacketTracer::PRIORITY_LOW); -} static Inspector* reputation_ctor(Module* m) { @@ -488,7 +480,7 @@ const InspectApi reputation_api = PROTO_BIT__ANY_IP, nullptr, // buffers nullptr, // service - reputation_init, // pinit + nullptr, // pinit nullptr, // pterm nullptr, // tinit nullptr, // tterm diff --git a/src/packet_io/active.cc b/src/packet_io/active.cc index 2b7cfa257..a98f6d751 100644 --- a/src/packet_io/active.cc +++ b/src/packet_io/active.cc @@ -79,6 +79,9 @@ static THREAD_LOCAL ip_t* s_ipnet = nullptr; static THREAD_LOCAL send_t s_send = SFDAQ::inject; static ResetAction default_reset; +static int default_drop_reason_id = -1; + +static std::unordered_map drop_reason_id_map; //-------------------------------------------------------------------- // helpers @@ -775,6 +778,7 @@ void Active::reset() active_action = ACT_ALLOW; delayed_active_action = ACT_ALLOW; delayed_reject = nullptr; + drop_reason = nullptr; } void Active::clear_queue(Packet* p) @@ -792,3 +796,37 @@ void Active::execute(Packet* p) } } +void Active::set_default_drop_reason(uint8_t reason_id) +{ + default_drop_reason_id = reason_id; +} + +void Active::map_drop_reason_id(const char* verdict_reason, uint8_t id) +{ + drop_reason_id_map[verdict_reason] = id; +} + +void Active::set_drop_reason(const char* reason) +{ + if ( drop_reason == nullptr ) + drop_reason = reason; +} + +int Active::get_drop_reason_id() +{ + const auto iter = drop_reason_id_map.find(drop_reason); + if ( iter != drop_reason_id_map.end() ) + return iter->second; + + return default_drop_reason_id; +} + +void Active::send_reason_to_daq(Packet& p) +{ + if ( drop_reason == nullptr ) + return; + + int reason = get_drop_reason_id(); + if ( reason != -1 ) + p.daq_instance->set_packet_verdict_reason(p.daq_msg, reason); +} diff --git a/src/packet_io/active.h b/src/packet_io/active.h index cc8e97e40..5c9ccc7fa 100644 --- a/src/packet_io/active.h +++ b/src/packet_io/active.h @@ -156,6 +156,14 @@ public: void reset(); + static void set_default_drop_reason(uint8_t reason_id); + static void map_drop_reason_id(const char* verdict_reason, uint8_t id); + void set_drop_reason(const char*); + void send_reason_to_daq(Packet&); + + const char* get_drop_reason() + { return drop_reason; } + private: static bool open(const char*); static void close(); @@ -169,6 +177,8 @@ private: void cant_drop(); + int get_drop_reason_id(); + private: static const char* act_str[ACT_MAX][AST_MAX]; static bool enabled; @@ -176,6 +186,7 @@ private: static THREAD_LOCAL bool s_suspend; int active_tunnel_bypass; + const char* drop_reason; bool prevent_trust_action; diff --git a/src/packet_io/sfdaq_instance.cc b/src/packet_io/sfdaq_instance.cc index 561dbaac3..38735fc12 100644 --- a/src/packet_io/sfdaq_instance.cc +++ b/src/packet_io/sfdaq_instance.cc @@ -317,12 +317,21 @@ int SFDAQInstance::modify_flow_opaque(DAQ_Msg_h msg, uint32_t opaque) return daq_instance_ioctl(instance, DIOCTL_SET_FLOW_OPAQUE, &d_sfo, sizeof(d_sfo)); } -int SFDAQInstance::modify_flow_pkt_trace(DAQ_Msg_h msg, uint8_t verdict_reason, uint8_t* buff, uint32_t buff_len) +int SFDAQInstance::set_packet_verdict_reason(DAQ_Msg_h msg, uint8_t verdict_reason) +{ + DIOCTL_SetPacketVerdictReason d_spvr; + + d_spvr.msg = msg; + d_spvr.verdict_reason = verdict_reason; + + return daq_instance_ioctl(instance, DIOCTL_SET_PACKET_VERDICT_REASON, &d_spvr, sizeof(d_spvr)); +} + +int SFDAQInstance::set_packet_trace_data(DAQ_Msg_h msg, uint8_t* buff, uint32_t buff_len) { DIOCTL_SetPacketTraceData d_sptd; d_sptd.msg = msg; - d_sptd.verdict_reason = verdict_reason; d_sptd.trace_data_len = buff_len; d_sptd.trace_data = buff; diff --git a/src/packet_io/sfdaq_instance.h b/src/packet_io/sfdaq_instance.h index 19027cbbe..d8b2249fa 100644 --- a/src/packet_io/sfdaq_instance.h +++ b/src/packet_io/sfdaq_instance.h @@ -76,8 +76,8 @@ public: SO_PUBLIC int ioctl(DAQ_IoctlCmd cmd, void *arg, size_t arglen); SO_PUBLIC int modify_flow_opaque(DAQ_Msg_h, uint32_t opaque); - int modify_flow_pkt_trace(DAQ_Msg_h, uint8_t verdict_reason, - uint8_t* buff, uint32_t buff_len); + int set_packet_verdict_reason(DAQ_Msg_h msg, uint8_t verdict_reason); + int set_packet_trace_data(DAQ_Msg_h, uint8_t* buff, uint32_t buff_len); int add_expected(const Packet* ctrlPkt, const SfIp* cliIP, uint16_t cliPort, const SfIp* srvIP, uint16_t srvPort, IpProtocol, unsigned timeout_ms, unsigned /* flags */); diff --git a/src/service_inspectors/dce_rpc/dce_smb_utils.cc b/src/service_inspectors/dce_rpc/dce_smb_utils.cc index bcaf0bd5a..7586b650f 100644 --- a/src/service_inspectors/dce_rpc/dce_smb_utils.cc +++ b/src/service_inspectors/dce_rpc/dce_smb_utils.cc @@ -30,6 +30,7 @@ #include "file_api/file_api.h" #include "main/snort.h" #include "main/snort_debug.h" +#include "network_inspectors/packet_tracer/packet_tracer.h" #include "packet_io/active.h" #include "utils/util.h" @@ -1444,6 +1445,7 @@ static void DCE2_SmbFinishFileBlockVerdict(DCE2_SmbSsnData* ssd) if ((verdict == FILE_VERDICT_BLOCK) || (verdict == FILE_VERDICT_REJECT)) { DCE2_SmbInjectDeletePdu(ssd->fb_ftracker); + DetectionEngine::get_current_packet()->active->set_drop_reason("smb"); } ssd->fb_ftracker = nullptr; @@ -1475,7 +1477,12 @@ static void DCE2_SmbFinishFileAPI(DCE2_SmbSsnData* ssd) FileVerdict verdict = DCE2_get_file_verdict(); if ((verdict == FILE_VERDICT_BLOCK) || (verdict == FILE_VERDICT_REJECT)) + { ssd->fb_ftracker = ftracker; + if (PacketTracer::is_active()) + PacketTracer::log("Dce2_smb: smb file verdict %s\n", + verdict == FILE_VERDICT_BLOCK ? "block" : "reject"); + } } } dce2_smb_stats.smb_files_processed++; @@ -1558,6 +1565,11 @@ static DCE2_Ret DCE2_SmbFileAPIProcess(DCE2_SmbSsnData* ssd, || (verdict == FILE_VERDICT_PENDING)) { ssd->fb_ftracker = ftracker; + if (verdict != FILE_VERDICT_PENDING and PacketTracer::is_active()) + { + PacketTracer::log("Dce2_smb: smb file verdict %s\n", + verdict == FILE_VERDICT_BLOCK ? "block" : "reject"); + } } } ftracker->ff_sequential_only = false; diff --git a/src/service_inspectors/ftp_telnet/ftp_data.cc b/src/service_inspectors/ftp_telnet/ftp_data.cc index 45388297a..a70fa93f1 100644 --- a/src/service_inspectors/ftp_telnet/ftp_data.cc +++ b/src/service_inspectors/ftp_telnet/ftp_data.cc @@ -62,6 +62,9 @@ static void FTPDataProcess( if (data_ssn->packet_flags & FTPDATA_FLG_REST) { p->active->block_again(); + p->active->set_drop_reason("ftp"); + if (PacketTracer::is_active()) + PacketTracer::log("FTP: session reset, drop\n"); return; } diff --git a/src/stream/stream.cc b/src/stream/stream.cc index 430fd3100..f9e2284de 100644 --- a/src/stream/stream.cc +++ b/src/stream/stream.cc @@ -33,6 +33,7 @@ #include "main/snort.h" #include "main/snort_config.h" #include "main/snort_debug.h" +#include "network_inspectors/packet_tracer/packet_tracer.h" #include "packet_io/active.h" #include "protocols/vlan.h" #include "stream/base/stream_module.h" @@ -180,7 +181,12 @@ void Stream::check_flow_closed(Packet* p) flow->set_state(Flow::FlowState::BLOCK); if ( !(p->packet_flags & PKT_STATELESS) ) + { drop_traffic(p, SSN_DIR_BOTH); + p->active->set_drop_reason("stream"); + if (PacketTracer::is_active()) + PacketTracer::log("Stream: pending block, drop\n"); + } flow->session_state &= ~STREAM_STATE_BLOCK_PENDING; } } @@ -319,6 +325,10 @@ void Stream::drop_flow(const Packet* p) if ( !(p->packet_flags & PKT_STATELESS) ) drop_traffic(p, SSN_DIR_BOTH); + + p->active->set_drop_reason("stream"); + if (PacketTracer::is_active()) + PacketTracer::log("Stream: session has been dropped\n"); } //------------------------------------------------------------------------- @@ -600,6 +610,9 @@ bool Stream::blocked_flow(Packet* p) DetectionEngine::disable_content(p); p->active->drop_packet(p); active_response(p, flow); + p->active->set_drop_reason("stream"); + if (PacketTracer::is_active()) + PacketTracer::log("Stream: session was already blocked\n"); return true; } return false; diff --git a/src/stream/tcp/tcp_event_logger.cc b/src/stream/tcp/tcp_event_logger.cc index bbbab52cc..fdeb83d7b 100644 --- a/src/stream/tcp/tcp_event_logger.cc +++ b/src/stream/tcp/tcp_event_logger.cc @@ -29,6 +29,7 @@ #include "detection/rules.h" #include "filters/sfrf.h" #include "main/snort_config.h" +#include "packet_tracer/packet_tracer.h" #include "tcp_module.h" @@ -38,35 +39,37 @@ struct tcp_event_sid { uint32_t event_id; uint32_t sid; + const char* event_description; }; // ffs returns 1 as bit position of lsb so event id array // has dummy entry for index 0 struct tcp_event_sid tcp_event_sids[] = { - { 0, 0 }, - { EVENT_SYN_ON_EST, STREAM_TCP_SYN_ON_EST }, - { EVENT_DATA_ON_SYN, STREAM_TCP_DATA_ON_SYN }, - { EVENT_DATA_ON_CLOSED, STREAM_TCP_DATA_ON_CLOSED }, - { EVENT_BAD_TIMESTAMP, STREAM_TCP_BAD_TIMESTAMP }, - { EVENT_WINDOW_TOO_LARGE, STREAM_TCP_WINDOW_TOO_LARGE }, - { EVENT_DATA_AFTER_RESET, STREAM_TCP_DATA_AFTER_RESET }, - { EVENT_SESSION_HIJACK_CLIENT, STREAM_TCP_SESSION_HIJACKED_CLIENT }, - { EVENT_SESSION_HIJACK_SERVER, STREAM_TCP_SESSION_HIJACKED_SERVER }, - { EVENT_DATA_WITHOUT_FLAGS, STREAM_TCP_DATA_WITHOUT_FLAGS }, - { EVENT_4WHS, STREAM_TCP_4WAY_HANDSHAKE }, - { EVENT_NO_TIMESTAMP, STREAM_TCP_NO_TIMESTAMP }, - { EVENT_BAD_RST, STREAM_TCP_BAD_RST }, - { EVENT_BAD_FIN, STREAM_TCP_BAD_FIN }, - { EVENT_BAD_ACK, STREAM_TCP_BAD_ACK }, - { EVENT_DATA_AFTER_RST_RCVD, STREAM_TCP_DATA_AFTER_RST_RCVD }, - { EVENT_WINDOW_SLAM, STREAM_TCP_WINDOW_SLAM }, - { EVENT_NO_3WHS, STREAM_TCP_NO_3WHS }, - { EVENT_BAD_SEGMENT, STREAM_TCP_BAD_SEGMENT }, - { EVENT_EXCESSIVE_OVERLAP, STREAM_TCP_EXCESSIVE_TCP_OVERLAPS }, - { EVENT_MAX_SMALL_SEGS_EXCEEDED, STREAM_TCP_SMALL_SEGMENT }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } + { 0, 0, nullptr }, + { EVENT_SYN_ON_EST, STREAM_TCP_SYN_ON_EST, "SYN_ON_EST" }, + { EVENT_DATA_ON_SYN, STREAM_TCP_DATA_ON_SYN, "DATA_ON_SYN" }, + { EVENT_DATA_ON_CLOSED, STREAM_TCP_DATA_ON_CLOSED, "DATA_ON_CLOSED" }, + { EVENT_BAD_TIMESTAMP, STREAM_TCP_BAD_TIMESTAMP, "BAD_TIMESTAMP" }, + { EVENT_WINDOW_TOO_LARGE, STREAM_TCP_WINDOW_TOO_LARGE, "WINDOW_TOO_LARGE" }, + { EVENT_DATA_AFTER_RESET, STREAM_TCP_DATA_AFTER_RESET, "DATA_AFTER_RESET" }, + { EVENT_SESSION_HIJACK_CLIENT, STREAM_TCP_SESSION_HIJACKED_CLIENT, "SESSION_HIJACK_CLIENT" }, + { EVENT_SESSION_HIJACK_SERVER, STREAM_TCP_SESSION_HIJACKED_SERVER, "SESSION_HIJACK_SERVER" }, + { EVENT_DATA_WITHOUT_FLAGS, STREAM_TCP_DATA_WITHOUT_FLAGS, "DATA_WITHOUT_FLAGS" }, + { EVENT_4WHS, STREAM_TCP_4WAY_HANDSHAKE, "4WHS" }, + { EVENT_NO_TIMESTAMP, STREAM_TCP_NO_TIMESTAMP, "NO_TIMESTAMP" }, + { EVENT_BAD_RST, STREAM_TCP_BAD_RST, "BAD_RST" }, + { EVENT_BAD_FIN, STREAM_TCP_BAD_FIN, "BAD_FIN" }, + { EVENT_BAD_ACK, STREAM_TCP_BAD_ACK, "BAD_ACK" }, + { EVENT_DATA_AFTER_RST_RCVD, STREAM_TCP_DATA_AFTER_RST_RCVD, "DATA_AFTER_RST_RCVD" }, + { EVENT_WINDOW_SLAM, STREAM_TCP_WINDOW_SLAM, "WINDOW_SLAM" }, + { EVENT_NO_3WHS, STREAM_TCP_NO_3WHS, "NO_3WHS" }, + { EVENT_BAD_SEGMENT, STREAM_TCP_BAD_SEGMENT, "BAD_SEGMENT" }, + { EVENT_EXCESSIVE_OVERLAP, STREAM_TCP_EXCESSIVE_TCP_OVERLAPS, "EXCESSIVE_OVERLAP" }, + { EVENT_MAX_SMALL_SEGS_EXCEEDED, STREAM_TCP_SMALL_SEGMENT, "MAX_SMALL_SEGS_EXCEEDED" }, + { 0, 0, nullptr }, { 0, 0, nullptr }, { 0, 0, nullptr }, { 0, 0, nullptr }, + { 0, 0, nullptr }, { 0, 0, nullptr }, { 0, 0, nullptr }, { 0, 0, nullptr }, + { 0, 0, nullptr }, { 0, 0, nullptr }, { 0, 0, nullptr }, { 0, 0, nullptr } }; void TcpEventLogger::log_internal_event(uint32_t eventSid) @@ -85,8 +88,11 @@ void TcpEventLogger::log_tcp_events() uint32_t idx = ffs(tcp_events); if ( idx ) { - DetectionEngine::queue_event(GID_STREAM_TCP, tcp_event_sids[ idx ].sid); - tcp_events ^= tcp_event_sids[ idx ].event_id; + DetectionEngine::queue_event(GID_STREAM_TCP, tcp_event_sids[idx].sid); + if ( PacketTracer::is_active() ) + PacketTracer::log("Stream: TCP normalization error in %s\n", + tcp_event_sids[idx].event_description); + tcp_events ^= tcp_event_sids[idx].event_id; tcpStats.events++; } } diff --git a/src/stream/tcp/tcp_normalizer.cc b/src/stream/tcp/tcp_normalizer.cc index 3c59f8531..961981091 100644 --- a/src/stream/tcp/tcp_normalizer.cc +++ b/src/stream/tcp/tcp_normalizer.cc @@ -30,7 +30,6 @@ #include "tcp_stream_session.h" #include "tcp_stream_tracker.h" - using namespace snort; THREAD_LOCAL PegCount tcp_norm_stats[PC_TCP_MAX][NORM_MODE_MAX]; @@ -102,6 +101,7 @@ bool TcpNormalizer::packet_dropper( { Packet* p = tsd.get_pkt(); p->active->drop_packet(p); + p->active->set_drop_reason("stream"); return true; } diff --git a/src/stream/tcp/tcp_state_fin_wait2.cc b/src/stream/tcp/tcp_state_fin_wait2.cc index 3e1f42aee..ce70698b4 100644 --- a/src/stream/tcp/tcp_state_fin_wait2.cc +++ b/src/stream/tcp/tcp_state_fin_wait2.cc @@ -66,8 +66,8 @@ bool TcpStateFinWait2::ack_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk { if ( SEQ_GT(tsd.get_seg_ack(), trk.get_snd_nxt() ) ) { - trk.normalizer.packet_dropper(tsd, NORM_TCP_BLOCK); trk.session->tel.set_tcp_event(EVENT_BAD_ACK); + trk.normalizer.packet_dropper(tsd, NORM_TCP_BLOCK); trk.session->set_pkt_action_flag(ACTION_BAD_PKT); } else @@ -88,8 +88,8 @@ bool TcpStateFinWait2::data_seg_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker { if ( SEQ_GT(tsd.get_seg_ack(), trk.get_snd_nxt() ) ) { - trk.normalizer.packet_dropper(tsd, NORM_TCP_BLOCK); trk.session->tel.set_tcp_event(EVENT_BAD_ACK); + trk.normalizer.packet_dropper(tsd, NORM_TCP_BLOCK); trk.session->set_pkt_action_flag(ACTION_BAD_PKT); } else diff --git a/src/stream/tcp/tcp_state_syn_recv.cc b/src/stream/tcp/tcp_state_syn_recv.cc index 0f1806e1c..72356671b 100644 --- a/src/stream/tcp/tcp_state_syn_recv.cc +++ b/src/stream/tcp/tcp_state_syn_recv.cc @@ -180,8 +180,8 @@ bool TcpStateSynRecv::rst_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) else { inc_tcp_discards(); - trk.normalizer.packet_dropper(tsd, NORM_TCP_BLOCK); trk.session->tel.set_tcp_event(EVENT_BAD_RST); + trk.normalizer.packet_dropper(tsd, NORM_TCP_BLOCK); } // FIXIT-L might be good to create alert specific to RST with data