From b4b990cfb56ccb60846f39abe8c9c33a1ebdfb64 Mon Sep 17 00:00:00 2001 From: Seth Hall Date: Thu, 30 Jun 2011 21:26:30 -0400 Subject: [PATCH] Updates to the DPD framework. - Removed the ProtocolViolation notice. I'd like to hear if someone actually used that notice for something. - Folded the dyn-disable functionality into the dpd/base script. - Other small cleanup. --- policy/frameworks/dpd/__load__.bro | 1 - policy/frameworks/dpd/base.bro | 63 +++++++++++++++---- policy/frameworks/dpd/dyn-disable.bro | 42 ------------- .../frameworks/dpd/packet-segment-logging.bro | 4 ++ .../defaults/remove-high-volume-notices.bro | 2 - 5 files changed, 55 insertions(+), 57 deletions(-) delete mode 100644 policy/frameworks/dpd/dyn-disable.bro diff --git a/policy/frameworks/dpd/__load__.bro b/policy/frameworks/dpd/__load__.bro index 6fdb165ffb..b1712cc445 100644 --- a/policy/frameworks/dpd/__load__.bro +++ b/policy/frameworks/dpd/__load__.bro @@ -1,3 +1,2 @@ @load dpd/base -@load dpd/dyn-disable @load dpd/packet-segment-logging \ No newline at end of file diff --git a/policy/frameworks/dpd/base.bro b/policy/frameworks/dpd/base.bro index 6a16b6d1f9..7412ebf75d 100644 --- a/policy/frameworks/dpd/base.bro +++ b/policy/frameworks/dpd/base.bro @@ -1,4 +1,5 @@ -##! Activates port-independent protocol detection. +##! Activates port-independent protocol detection and selectively disables +##! analyzers if protocol violations occur. @load functions @load signatures @@ -6,19 +7,34 @@ module DPD; ## Add the DPD signatures to the signature framework. -redef signature_files += "dpd/dpd.sig"; +redef signature_files += "frameworks/dpd/dpd.sig"; export { redef enum Log::ID += { DPD }; type Info: record { + ## Timestamp for when protocol analysis failed. ts: time &log; + ## Connection unique ID. uid: string &log; + ## Connection ID. id: conn_id &log; + ## Transport protocol for the violation. proto: transport_proto &log; + ## The analyzer that generated the violation. analyzer: string &log; + ## The textual reason for the analysis failure. failure_reason: string &log; + + ## Disabled analyzer IDs. This is only for internal tracking + ## so as to not attempt to disable analyzers multiple times. + # TODO: This is waiting on ticket #460 to remove the '0'. + disabled_aids: set[count] &default=set(0); }; + + ## Ignore violations which go this many bytes into the connection. + ## Set to 0 to never ignore protocol violations. + const ignore_violations_after = 10 * 1024 &redef; } redef record connection += { @@ -29,6 +45,7 @@ event bro_init() { Log::create_stream(DPD, [$columns=Info]); + # Populate the internal DPD analysis variable. for ( a in dpd_config ) { for ( p in dpd_config[a]$ports ) @@ -42,31 +59,53 @@ event bro_init() event protocol_confirmation(c: connection, atype: count, aid: count) &priority=10 { - if ( fmt("-%s",analyzer_name(atype)) in c$service ) - delete c$service[fmt("-%s", analyzer_name(atype))]; + local analyzer = analyzer_name(atype); + + if ( fmt("-%s",analyzer) in c$service ) + delete c$service[fmt("-%s", analyzer)]; - add c$service[analyzer_name(atype)]; + add c$service[analyzer]; } event protocol_violation(c: connection, atype: count, aid: count, - reason: string) &priority=5 + reason: string) &priority=10 { - if ( analyzer_name(atype) in c$service ) - delete c$service[analyzer_name(atype)]; - add c$service[fmt("-%s", analyzer_name(atype))]; + local analyzer = analyzer_name(atype); + # If the service hasn't been confirmed yet, don't generate a log message + # for the protocol violation. + if ( analyzer !in c$service ) + return; + + delete c$service[analyzer]; + add c$service[fmt("-%s", analyzer)]; local info: Info; info$ts=network_time(); info$uid=c$uid; info$id=c$id; info$proto=get_conn_transport_proto(c$id); - info$analyzer=analyzer_name(atype); + info$analyzer=analyzer; info$failure_reason=reason; c$dpd = info; } +event protocol_violation(c: connection, atype: count, aid: count, reason: string) &priority=5 + { + if ( !c?$dpd || aid in c$dpd$disabled_aids ) + return; + + local size = c$orig$size + c$resp$size; + if ( ignore_violations_after > 0 && size > ignore_violations_after ) + return; + + # Disable the analyzer that raised the last core-generated event. + disable_analyzer(c$id, aid); + add c$dpd$disabled_aids[aid]; + } + event protocol_violation(c: connection, atype: count, aid: count, reason: string) &priority=-5 { - Log::write(DPD, c$dpd); - } \ No newline at end of file + if ( c?$dpd ) + Log::write(DPD, c$dpd); + } diff --git a/policy/frameworks/dpd/dyn-disable.bro b/policy/frameworks/dpd/dyn-disable.bro deleted file mode 100644 index d7b34413f6..0000000000 --- a/policy/frameworks/dpd/dyn-disable.bro +++ /dev/null @@ -1,42 +0,0 @@ -##! When this script is loaded, analyzers that raise protocol_violation events -##! are disabled for the affected connection. - -@load dpd/base -@load notice - -module DPD; - -export { - redef enum Notice::Type += { - ProtocolViolation - }; - - redef record DPD::Info += { - ## Disabled analyzer IDs. - # TODO: This is waiting on ticket #460 to remove the '0'. - disabled_aids: set[count] &default=set(0); - }; - - ## Ignore violations which go this many bytes into the connection. - const max_data_volume = 10 * 1024 &redef; -} - - -event protocol_violation(c: connection, atype: count, aid: count, - reason: string) &priority=5 - { - if ( aid in c$dpd$disabled_aids ) - return; - - local size = c$orig$size + c$resp$size; - if ( max_data_volume > 0 && size > max_data_volume ) - return; - - # Disable the analyzer that raised the last core-generated event. - disable_analyzer(c$id, aid); - add c$dpd$disabled_aids[aid]; - - NOTICE([$note=ProtocolViolation, $conn=c, - $msg=fmt("%s disabled due to protocol violation", analyzer_name(atype)), - $sub=reason, $n=atype]); - } diff --git a/policy/frameworks/dpd/packet-segment-logging.bro b/policy/frameworks/dpd/packet-segment-logging.bro index a7c305bf00..cb489d6b24 100644 --- a/policy/frameworks/dpd/packet-segment-logging.bro +++ b/policy/frameworks/dpd/packet-segment-logging.bro @@ -10,6 +10,8 @@ module DPD; export { redef record Info += { + ## A chunk of the payload the most likely resulted in the protocol + ## violation. packet_segment: string &optional &log; }; @@ -21,5 +23,7 @@ export { event protocol_violation(c: connection, atype: count, aid: count, reason: string) &priority=4 { + if ( ! c?$dpd ) return; + c$dpd$packet_segment=fmt("%s", sub_bytes(get_current_packet()$data, 0, packet_segment_size)); } \ No newline at end of file diff --git a/policy/tuning/defaults/remove-high-volume-notices.bro b/policy/tuning/defaults/remove-high-volume-notices.bro index a7093ab106..e5c549b358 100644 --- a/policy/tuning/defaults/remove-high-volume-notices.bro +++ b/policy/tuning/defaults/remove-high-volume-notices.bro @@ -5,7 +5,6 @@ # Load the policy scripts where the notices are defined. @load frameworks/notice/weird -@load dpd # Remove these notices from logging since they can be too noisy. redef Notice::ignored_types += { @@ -13,5 +12,4 @@ redef Notice::ignored_types += { Weird::AckAboveHole, Weird::RetransmissionInconsistency, Weird::WeirdActivity, # Only allow these to go in the weird log. - DPD::ProtocolViolation, }; \ No newline at end of file