Implementing rules for generating IDMEF alerts using Prelude-LML

 

Inside prelude-lml.conf the ruleset plugin is specified as…

ruleset=/etc/prelude-lml/ruleset/pcre.rules

 

pcre.rules further breaks down alerts to more specific rulesets

It does so by parsing the logfle line to determine which ruleset

Should be used for a specific alert… for example

 

For this line from auth.log

Aug 14 12:20:01 pkirack3 CRON[11412]: (pam_unix) session opened for user smmsp

 

regex=[Pp][Aa][Mm]_; is successful , which further points to include = pam.rules;

 

Where pam.rules contains a more specific rule for the actual alert.

regex=session opened for user (\S+) by (\S*)\(uid=(\d*)\); \

 

All regex expressions that are not caught by such a specific rule type

Fall out and should be inserted into simple.rules

 

Here is pcre.rules for further details…

 

# pcre.rules

# Rule format :

#

# For more information about the fields described above and their meaning,

# please have a look to the IDMEF Draft located at :

#

# http://www.ietf.org/internet-drafts/draft-ietf-idwg-idmef-xml-14.txt

#

# If one of the IDMEF field you wish to add information too isn't covered in

# the rule language, please take the 5 minutes needed to implement a simple

# parsing function to the simple.c plugin distributed with Prelude LML.

#

# CREATING AND CONTRIBUTING RULES:

# Rulesets that you contribute to the Prelude-LML maintainer should follow

# these guidelines:

# - Avoid using .+ or .* in regex entries unless actually neccessary.  Doing so

#   will make your rule CPU-costly to implement.

# - Avoid capturing variables which you don't use.  This causes unneccessary

#   memory consumption.

# - At a minimum, include regex, classification().text,

#   assessment.impact.severity, assessment.impact.type,

#   assessment.impact.description.

# - If it's correct for this application, include last.

# - Put only a single field on each line of your rules.

# - Include a sample log entry with each rule.

# - Gather as many pieces of data, and fill as many IDMEF fields as possible

#   from the log entry.

# - If a similar rule exists in another ruleset (same function, different

#   software), use the classification().text from the other rule.

# - Use only the actual log message, none of the syslog headers (this generally

#   includes timestamp, originating node, originating process, and pid).

# - Submit new rulesets to the prelude-devel mailing list for consideration.

#

#

# Below you will find a listing of most of the IDMEF fields Prelude-LML

# accepts.  Where you see an item listed with (), it means that item is

# indexed.  Indexing starts at 0, so, for example, an event with multiple

# targets would have the first target listed as target(0), followed by whatever

# IDMEF fields you use.  See the existing rulesets for examples.

#

# - regex:

#   A PCRE regex that should be matched to trigger the alert.

#

# - classification.text:

#   The name of the alert, from one of the origins listed below.

#

# - classification.url:

#   A URL at which the manager (or the human

#   operator of the manager) can find additional information about the

#   alert.  The document pointed to by the URL may include an in-depth

#   description of the attack, appropriate countermeasures, or other

#   information deemed relevant by the vendor.

#

# - assessment.impact.severity:

#   An estimate of the relative severity of the event.

#   Possible values are: low, medium, high.

#

# - assessment.impact.completion:

#   An indication of whether the analyzer believes the attempt that

#   the event describes was successful or not.

#   The permitted values are: failed, succeeded.

#

# - assessment.impact.type:

#   The type of attempt represented by this event, in relatively broad

#   categories.

#   The permitted values are: admin, dos, file, recon, user, other.

#

# - assessment.impact.description:

#   May contain a textual description of the impact, if the analyzer

#   is able to provide additional details.

#

# - source().node.address().address,

#   target().node.address().address:

#   Address that has been attacked/Address that issued the attack.

#   There can be more than one.

#

# - source().node.address().category

#   target().node.address().category

#   The type of address provided.

#   Possible values: unknown, atm, e-mail, lotus-notes, mac, sna, vm,

#   ipv4-addr, ipv4-addr-hex, ipv6-addr, ipv6-addr-hex, ipv6-net, ipv6-net-mask

#

# - source().node.name,

#   target().node.name:

#   The name of the equipment. This information MUST be provided if no Address

#   information is given.

#

# - source().node.category,

#   target().node.category:

#   The domain from which the name information was obtained.

#   Possible values are: unknown, ads, afs, coda, dfs, dns, hosts, kerberos,

#   nds, nis, nisplus, nt, wfw

#

# - source().node.location,

#   target().node.location:

#   The location of the equipment.

#

# - source().spoofed,

#   target().decoy:

#   An indication of wheter the source/target is a decoy.

#   The permitted values are: unknown, yes, no.

#

# - source().interface,

#   target().interface:

#   May be used by a network-based analyzer with multiple interfaces to

#   indicate which interfaces this source/target was seen on.

#

# - source().service.name,

#   target().service.name:

#   The name of the service. Whenever possible, the name from the IANA list

#   of well-known ports SHOULD be used.

#

# - source().service.port,

#   target().service.port:

#   The port number being used.

#

# - source().service.iana_protocol_name,

#   target().service.iana_protocol_name:

#   The IANA protocol being used (tcp/udp/icmp/etc)

#

# - source().service.portlist,

#   target().service.portlist:

#   A list of port numbers beeing used.

#

# - source().user.category,

#   target().user.category:

#   The type of user represented (unknown, application, os-device).

#

# - source().user.userid().

#   target().user.userid().

#   Create a new UserId inside an User object (that may contain several UserId).

#

# - source().user.userid().type,

#   target().user.userid().type:

#   The type of user information represented (current-user, original-user,

#   target-user, user-privs, current-group, group-privs, other-privs).

#

# - source().user.userid().name,

#   target().user.userid().name:

#   A user or group name.

#

# - source().user.userid().number,

#   target().user.userid().number:

#   A user or group number.

#

# - source().process.name,

#   target().process.name:

#   A process name

#

# - source().process.pid,

#   target().process.pid:

#   A process number

#

# - id:

#   The rule ID associated with this rule.

#

# - revision:

#   The current revision number of this rule.

#

# - last:

#   Indicates to LML that if this rule is triggered, stop checking for further

#   regex matches.

 

regex=EMU;                                    include = apc-emu.rules;

regex=(anomaly|since|firstSeen);       include = arbor.rules;

regex=arpwatch;                              include = arpwatch.rules;

regex=(bigconf|kernel);                     include = f5-bigip.rules;

regex=%PIX;                                   include = cisco-pix.rules;

regex=%[A-Z]+-\d+-[A-Z];              include = cisco-router.rules;

regex=SEV=;                                   include = cisco-vpn.rules;

 

# Using this regex rather than simpler clamd to handle events from clamav

# logging format

 

regex=(FOUND|virus);                     include = clamav.rules;

regex=server administrator;               include = dell-om.rules

regex=(kernel|grsec);                        include = grsecurity.rules;

regex=kernel;                                   include = netfilter.rules; \

                                                       include = ipchains.rules;

regex=honeyd;                                 include = honeyd.rules;

 

# Using this somewhat complex regex instead of the simpler httpd due to the

# fact that we might be directly monitoring httpd logs instead of httpd syslog

# entries (in which case we won't have the process name to match against)

 

regex=(\[error\]|Pass|httpd);              include = httpd.rules; \

                                                       include = modsecurity.rules;

regex=ipfw;                                      include = ipfw.rules;

regex=[Ww]ireless;                          include = linksys-wap11.rules;

regex=mssql;                                    include = ms-sql.rules;

regex=nagios;                                   include = nagios.rules;

regex=norton;                                   include = navce.rules;

regex=\[[^:]*:[^\]]*\]:;                        include = netapp-ontap.rules;

regex=system-(emergency|alert)-;      include = netscreen.rules;

regex=security\[;                              include = ntsyslog.rules;

 

# This next regex isn't specific enough for my liking, but there doesn't seem

# to be a better solution based on the log samples

 

regex=[a-z0-9]+:;                             include = openhostapd.rules;

regex=[Pp][Aa][Mm]_;                    include = pam.rules;

regex=pcanywhere;                          include = pcanywhere.rules;

regex=portsentry;                             include = portsentry.rules;

regex=postfix/;                                 include = postfix.rules;

regex=proftpd;                                 include = proftpd.rules;

regex=popper;                                  include = qpopper.rules;

regex=avc:;                                      include = selinux.rules;

regex=sendmail;                               include = sendmail.rules;

regex=(user|group)(mod|add);           include = shadow-utils.rules;

 

# More complex regex to handle data coming directly from Squid log files

 

regex=(Acceptin|Squid|Disabled|DENIED); include = squid.rules;

regex=sshd;                                     include = ssh.rules;

regex=sudo;                                     include = sudo.rules;

regex=tripwire;                                include = tripwire.rules;

regex=[wl]an @Group:;                    include = vigor.rules;

regex=vpopmail;                              include = vpopmail.rules;

regex=webmin;                                include = webmin.rules;

regex=ftpd;                                      include = wu-ftp.rules;

 

include = single.rules;