Skip to content

Instantly share code, notes, and snippets.

@grigorescu
Created September 14, 2017 18:43
Show Gist options
  • Save grigorescu/eee2024c88d6c6cc6e29702d247d8166 to your computer and use it in GitHub Desktop.
Save grigorescu/eee2024c88d6c6cc6e29702d247d8166 to your computer and use it in GitHub Desktop.
@load base/frameworks/sumstats
@load base/protocols/smtp
module SMTP;
export {
redef enum Notice::Type += {
## Generated if a user is sending mail to too many recipients
ExcessiveRecipients
};
const excessive_limit = 100.0 &redef;
const excessive_interval = 120min &redef;
global excessive_whitelist: set[string] = {
} &redef &synchronized;
}
function format_crl_samples(samples: vector of SumStats::Observation): string
{
local ret = "SMTP Message samples\n---------------------";
for ( i in samples )
ret += "\n" + samples[i]$str;
return ret;
}
event bro_init() &priority=3
{
local r1 = SumStats::Reducer(
$stream="recipients",
$apply=set(SumStats::UNIQUE, SumStats::SAMPLE),
$num_samples=5,
$unique_max=double_to_count(excessive_limit+2)
);
SumStats::create([$name = "counting recipients",
$epoch = excessive_interval,
$threshold = excessive_limit,
$reducers = set(r1),
$threshold_val(key: SumStats::Key, result: SumStats::Result) = {
return result["recipients"]$unique + 0.0;
},
$threshold_crossed(key: SumStats::Key, result: SumStats::Result) = {
local r = result["recipients"];
NOTICE([
$note=ExcessiveRecipients,
$msg=fmt("%s has sent mail to more than %d recipients in %s", key$str, r$unique, excessive_interval),
$sub=key$str,
$email_body_sections=vector(format_crl_samples(r$samples)),
$identifier=cat(key$str)
]);
}
]);
}
event SMTP::log_smtp(rec: SMTP::Info)
{
#skip this if it is not an outbound email
#or if it is going to a neighbor site
if(!Site::is_local_addr(rec$id$orig_h))
return;
if(Site::is_neighbor_addr(rec$id$resp_h))
return;
if(!rec?$mailfrom || rec$mailfrom in excessive_whitelist)
return;
if(!rec?$rcptto)
return;
for(recp in rec$rcptto) {
SumStats::observe("recipients", SumStats::Key($str=rec$mailfrom), SumStats::Observation($str=recp));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment