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
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,
#
# - 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;