Building an SEC Ruleset for Attack
Correlations
All of the SEC files on
pkirack3 are all in /usr/share/prelude/sec and its subdirectories.
The ruleset files are in
/usr/share/prelude/sec/rules and have a .sec extension.
sec.pl should normally be started
as a daemon as a Prelude agent…
But for testing purposes
start it from a terminal using the following:
./sec.pl -conf=rules/*.sec
--module=Prelude["--server-addr 141.142.234.4"]
This will run SEC with
whatever rulesets are in .../sec/rules specifying that the input
Is from Prelude (IDMEF
format) and the prelude-manager is on pkirack3 (141.142.234.4).
Prelude-manager will route
all of alert messages that it gets from its sensors to SEC.
Basic IDMEF pattern matching:
The ‘pattern’ is a series of
regex expressions that represent values from the ‘alert’ namespace’
(see the Mithril internal
document ‘alert’ namespace for IDMEF pattern matching in SEC’)
The
order of the lines is unimportant. The entire ‘pattern’ stream is matched
line-by-line.
If
a line matches, the appropriate parameter(s) is/are assigned to $1, $2, $3…
If
all the lines match… the rule is successful and the ‘action’ is performed.
The
following is a very simple example which catches and matches all alerts.
type=Single
ptype=IDMEF
pattern=classification.text:
(.*);
desc=The classification text
is $1
action=write – %s
Typically however… the
‘classification.text:’ parameter would be specified to match an alert.
The ‘action’ sends the value for
‘desc’ to standard output (indicated by ‘-‘).
The following is an example
which detects a portscan followed by an SSH login attempt.
The relationship between the
two rules is that they occur within the same hour.
For
testing I have been running the following from pkirack2 to generate a number of
alerts on pkirack3…
nmap
-n -vvv -sS -T Insane -p 1-65535 pkirack3.ncsa.uiuc.edu
ssh
someuser@pkirack3
# ncsa-portscan_ssh.sec
# this ruleset detects a
portscan followed by an SSH login
# attempt from the same
sourceIP address within the same hour
# upon detection of portscan
create the appropriate context
# this case will be a
portscan followed by a invalid user attempt
type=Single
ptype=IDMEF
pattern=classification.text:
[(]portscan[)] TCP Portscan; \
messageid: (\d+); \
source(0).node.address(0).address: (.*); \
target(0).node.address(0).address: (.*); \
analyzer(-1).analyzerid: (.*); \
analyzer(-2).analyzerid: (.*); \
source(0).user.user_id(0).name: (.*);
continue=TakeNext
desc=TCP Portscan messageID: $2 sourceIP: $3 targetIP: $4
analyzerID1: $5 analyzerID2: $6
action=add PORTSCAN_SSH_$3
%s; \
set PORTSCAN_SSH_$3 3600
# upon detection of an SSH
login attempt
# check if the context exists
# if it exists... create the
correlation
type=Single
ptype=IDMEF
pattern=classification.text:
[Ll]ogin|[Aa]uthentication; \
messageid: (.+); \
assessment.impact.completion: (.+); \
source(0).node.address(0).address: (.*); \
target(0).node.address(0).address: (.*); \
analyzer(-1).analyzerid: (.*); \
analyzer(-2).analyzerid: (.*);
continue=DontCont
context=PORTSCAN_SSH_$3
desc=correlation_alert.name=Portscan_SSH_invalid;
\
correlation_alert.alertident(>>).alertident=$1;
\
correlation_alert.alertident(-1).analyzerid=$6;
action=add PORTSCAN_SSH_$3
%s; \
copy PORTSCAN_SSH_$3 %CONTENT; \
prelude %CONTENT; \
delete PORTSCAN_SSH_$3