On 02/29/2012 01:49 AM, [email protected] wrote:
> I want to setup an alert based on too many of one type of log showing up
> compared to another type of log during a window
>
> Ideally, with the appropriate log messages being in a report
>
> For example, I want to look at the number of successful and failed logins,
> and alert if the number of failed logins is>5 and>5% of the successful
> logins within a 20 minute window
>
> So far, the best I've been able to come up with is to use snippets of perl
> code to set variables and then have another rule after them that does the
> comparison.
>
> However, the one thing that I am getting stuck on is how to expire old
> matches after 20 minutes.
>
> I guess I can setup a pair of singlewiththreashold rules with super high
> thresholds to detect the events and then look at the SEC internal
> variables for this to alert on them, but this seems like a fragile way to
> go about this.
>
> any better ideas?
I would use Perl code fragments myself, since this task involves some
arithmetics which can't be done with static thresholds alone.
You are right that for tackling this task, event occurrence times have
to be memorized, and with SingleWithThreshold rules it is indeed hard to
expire old events.
Fortunately, the 2.6 version of SEC has the EventGroup rule which has
the means for handling this problem. First of all, EventGroup allows for
counting more than one event type inside one window, which is one of the
requirements of the task.
Secondly, EventGroup has 'slide', 'count', 'end' and other fields, which
allow for invoking code snippets when
1) individual events arrive,
2) counting window slides forward,
3) the counting operation ends,
etc.
In order to tackle this task, I am using two Perl lists @slogin and
@flogin which contain timestamps of login successes and failures for the
last 20 minutes. The following EventGroup rule maintains these lists,
removing data for old events when event correlation windows moves:
type=EventGroup2
init=lcall %o -> ( sub { @slogin = (); @flogin = (); } )
end= lcall %o -> ( sub { @slogin = (); @flogin = (); } )
ptype=RegExp
pattern=sshd\[\d+\]: Accepted .+ for \S+ from [\d.]+ port \d+ ssh2
count=lcall %o %u -> ( sub { push @slogin, $_[0]; } )
ptype2=RegExp
pattern2=sshd\[\d+\]: Failed .+ for \S+ from [\d.]+ port \d+ ssh2
continue2=TakeNext
count2=lcall %o %u -> ( sub { push @flogin, $_[0]; } )
slide=getwpos %p 0; lcall %o %p -> ( sub { \
while (scalar(@slogin) && $slogin[0] < $_[0]) { shift @slogin; } \
while (scalar(@flogin) && $flogin[0] < $_[0]) { shift @flogin; } \
} )
desc=Track successful and failed logins
multact=yes
action=none
window=1200
Note that we are using default thresholds here (which are set to 1),
since this rule does not do any counting, but maintains the lists only.
For the same reason, the 'action' field is set to 'none'.
However, the 'multact' field has to be set to 'yes', since we want to
continue the counting after default thresholds (1) are hit.
(Note that if 'multact' is left to default value 'no', the same effect
can be achieved by setting 'thresh' and 'thresh2' to very high values
which can never be reached.)
The most complex part of this rule is the 'slide' field -- after the
event correlation window has moved forward, we save the new position of
the window to %p variable with the 'getwpos %p 0'. After that, we are
submitting the value of %p to a subroutine which discards all timestamps
older than %p from both @slogin and @flogin lists.
New timestamps for login successes are added to @slogin in the 'count'
field, while login failures get added to @flogin in the 'count2' field.
Now we have a rule which ensures that @slogin contain N timestamps where
N is the number of successful logins within the last 20 minutes, and
@flogin contains M timestamps where M is the number of failed logins
within the last 20 minutes.
In order to verify if the alarming criteria are true, we need another
rule. In this rule, we are simply checking the condition
scalar(@flogin) >= 5 && scalar(@flogin) >= scalar(@slogin)/20
which verifies if we have at least 5 login failures AND the number of
login failures is at least 5% of the number of login successes:
type=Single
ptype=RegExp
pattern=sshd\[\d+\]: Failed .+ for \S+ from [\d.]+ port \d+ ssh2
context= -> ( sub { return (scalar(@flogin) >= 5 \
&& scalar(@flogin) >= scalar(@slogin)/20); } )
desc=login failures - at least 5 AND at least 5% of successful logins
action=lcall %o -> ( sub { print scalar(@slogin), " ", scalar(@flogin),
"\n"; } )
Note that in principle matching failed login events is not enough, since
if the window of the first rule gets moved and login success events get
discarded, the second alarming criterion could become fullfilled (the
number of failures must be at least 5% of login successes). If you would
also like to handle this case, a synthetic event should be generated
from the 'slide' field of the first rule, and this event should be
matched by another rule.
hope this helps,
risto
>
> ------------------------------------------------------------------------------
> Keep Your Developer Skills Current with LearnDevNow!
> The most comprehensive online learning library for Microsoft developers
> is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3,
> Metro Style Apps, more. Free future releases when you subscribe now!
> http://p.sf.net/sfu/learndevnow-d2d
> _______________________________________________
> Simple-evcorr-users mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/simple-evcorr-users
>
------------------------------------------------------------------------------
Try before you buy = See our experts in action!
The most comprehensive online learning library for Microsoft developers
is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3,
Metro Style Apps, more. Free future releases when you subscribe now!
http://p.sf.net/sfu/learndevnow-dev2
_______________________________________________
Simple-evcorr-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/simple-evcorr-users