From b0c4dcdfedeeaba5b4b4e7e8522ff5058e3d5c25 Mon Sep 17 00:00:00 2001 From: Bernhard Amann Date: Wed, 15 May 2013 01:09:52 -0700 Subject: [PATCH] make last plugin nicer and samplify sqli detector --- .../base/frameworks/sumstats/plugins/last.bro | 45 ++++++++++--------- scripts/policy/protocols/http/detect-sqli.bro | 8 ++-- 2 files changed, 29 insertions(+), 24 deletions(-) diff --git a/scripts/base/frameworks/sumstats/plugins/last.bro b/scripts/base/frameworks/sumstats/plugins/last.bro index d0587bde08..58baa85b98 100644 --- a/scripts/base/frameworks/sumstats/plugins/last.bro +++ b/scripts/base/frameworks/sumstats/plugins/last.bro @@ -4,46 +4,51 @@ module SumStats; export { + redef enum Calculation += { + ## Keep last X observations in Queue + LAST + }; + redef record Reducer += { - ## A number of sample Observations to collect. - samples: count &default=0; + ## number of elements to keep. + num_last_elements: count &default=0; }; redef record ResultVal += { - ## This is the queue where samples are maintained. Use the - ## :bro:see:`SumStats::get_samples` function to get a vector of the samples. - samples: Queue::Queue &optional; + ## This is the queue where elements are maintained. Use the + ## :bro:see:`SumStats::get_elements` function to get a vector of the samples. + last_elements: Queue::Queue &optional; }; - ## Get a vector of sample Observation values from a ResultVal. - global get_samples: function(rv: ResultVal): vector of Observation; + ## Get a vector of element values from a ResultVal. + global get_elements: function(rv: ResultVal): vector of Observation; } -function get_samples(rv: ResultVal): vector of Observation +function get_elements(rv: ResultVal): vector of Observation { local s: vector of Observation = vector(); - if ( rv?$samples ) - Queue::get_vector(rv$samples, s); + if ( rv?$last_elements ) + Queue::get_vector(rv$last_elements, s); return s; } hook observe_hook(r: Reducer, val: double, obs: Observation, rv: ResultVal) { - if ( r$samples > 0 ) + if ( LAST in r$apply && r$num_last_elements > 0 ) { - if ( ! rv?$samples ) - rv$samples = Queue::init([$max_len=r$samples]); - Queue::put(rv$samples, obs); + if ( ! rv?$last_elements ) + rv$last_elements = Queue::init([$max_len=r$num_last_elements]); + Queue::put(rv$last_elements, obs); } } hook compose_resultvals_hook(result: ResultVal, rv1: ResultVal, rv2: ResultVal) { # Merge $samples - if ( rv1?$samples && rv2?$samples ) - result$samples = Queue::merge(rv1$samples, rv2$samples); - else if ( rv1?$samples ) - result$samples = rv1$samples; - else if ( rv2?$samples ) - result$samples = rv2$samples; + if ( rv1?$last_elements && rv2?$last_elements ) + result$last_elements = Queue::merge(rv1$last_elements, rv2$last_elements); + else if ( rv1?$last_elements ) + result$last_elements = rv1$last_elements; + else if ( rv2?$last_elements ) + result$last_elements = rv2$last_elements; } diff --git a/scripts/policy/protocols/http/detect-sqli.bro b/scripts/policy/protocols/http/detect-sqli.bro index 11dba0dc46..40d3805b92 100644 --- a/scripts/policy/protocols/http/detect-sqli.bro +++ b/scripts/policy/protocols/http/detect-sqli.bro @@ -63,7 +63,7 @@ event bro_init() &priority=3 # Add filters to the metrics so that the metrics framework knows how to # determine when it looks like an actual attack and how to respond when # thresholds are crossed. - local r1: SumStats::Reducer = [$stream="http.sqli.attacker", $apply=set(SumStats::SUM), $samples=collect_SQLi_samples]; + local r1: SumStats::Reducer = [$stream="http.sqli.attacker", $apply=set(SumStats::SUM, SumStats::SAMPLE), $num_samples=collect_SQLi_samples]; SumStats::create([$epoch=sqli_requests_interval, $reducers=set(r1), $threshold_val(key: SumStats::Key, result: SumStats::Result) = @@ -76,12 +76,12 @@ event bro_init() &priority=3 local r = result["http.sqli.attacker"]; NOTICE([$note=SQL_Injection_Attacker, $msg="An SQL injection attacker was discovered!", - $email_body_sections=vector(format_sqli_samples(SumStats::get_samples(r))), + $email_body_sections=vector(format_sqli_samples(r$sample_vector)), $src=key$host, $identifier=cat(key$host)]); }]); - local r2: SumStats::Reducer = [$stream="http.sqli.victim", $apply=set(SumStats::SUM), $samples=collect_SQLi_samples]; + local r2: SumStats::Reducer = [$stream="http.sqli.victim", $apply=set(SumStats::SUM, SumStats::SAMPLE), $num_samples=collect_SQLi_samples]; SumStats::create([$epoch=sqli_requests_interval, $reducers=set(r2), $threshold_val(key: SumStats::Key, result: SumStats::Result) = @@ -94,7 +94,7 @@ event bro_init() &priority=3 local r = result["http.sqli.victim"]; NOTICE([$note=SQL_Injection_Victim, $msg="An SQL injection victim was discovered!", - $email_body_sections=vector(format_sqli_samples(SumStats::get_samples(r))), + $email_body_sections=vector(format_sqli_samples(r$sample_vector)), $src=key$host, $identifier=cat(key$host)]); }]);