2016-01-13 09:28 AM
I had a customer who wanted to track new User Agents in their environment, so I wrote an ESA Rule to track this.
The rule will fire if the user agent has not been seen in the preceding 60 minutes. This value can be changed but be aware, that the longer the time period, the greater the window size.
On my small test system, this rule used 55 MB of memory and peaked at just short of 200MB.
The ESA Rule is as follows:
(Paste the following into the Query Box for an Advanced Rule)
module UserAgent_Alert;
@Hint('reclaim_group_aged=60 minutes,reclaim_group_freq=1')
// The stage setters - the output of these statements is for Esper to retain (internally)
CREATE WINDOW UserAgentWatchList.win:time(60 minutes) (client string);
INSERT INTO UserAgentWatchList SELECT client from Event(client IS NOT NULL AND alert_id IS NOT "Client Ignore");
// The real “alerter”. The annotation, identifies it as the one that ESA needs to watch for.
@RSAAlert
@RSAPersist
@Name('UserAgent Watchlist')
@Description('This alert will trigger on new User Agents but only 1 alert per individual IP address.')
SELECT * FROM Event(client is NOT NULL AND alert_id IS NOT "Client Ignore" ) WHERE client NOT in (SELECT client FROM UserAgentWatchList) ;
In order to exclude Clients that I was not interested in I created an App rule that put the text Client Ignore in the alert.id meta field.
I got also changed my ESA Syslog Notification template as follows, so that the alert included as much information as possible.
The body of the template was
<#include "macros.ftl"/>
CEF:0|RSA|Security Analytics ESA|10.4|${statement}|${moduleName}|${severity}|rt=${time?datetime} id=${id} source=${eventSourceId} <#list events as metadata><#list metadata?keys?sort as key> ${key}=<@value_of metadata[key]/></#list></#list>
In the ESA any key names that contained a dot are replaced with an underscore. As a result the alerts contained for example ip_dst rather than ip.dst
In order that these were parsed correctly, I updated the CEF parser on my log decoders as follows:
The CEF parser is stored under /etc/netwitness/ng/envision/etc/devices/cef/cef.xml
I added in the lines:
<ExtensionKey cefName="ip_dst" metaName="daddr"/>
<ExtensionKey cefName="ip_src" metaName="saddr"/>
To the part of the parser that contained similar entries.
Here is an example of the alert and the meta generated
Alert:
Meta Generated from Alert:
sessionid | = | 1157482825 |
time | = | 2016-01-13T14:22:18.0 |
size | = | 2112 |
lc.cid | = | |
forward.ip | = | 127.0.0.1 |
device.ip | = | |
medium | = | 32 |
device.type | = | |
event.time.str | = | |
alias.host | = | |
product | = | |
version | = | |
event.type | = | |
event.desc | = | |
severity | = | |
param_event_time | = | "2016-01-13T14:21Z" |
client | = | |
cn_log_did | = | "rsadecoder" |
ip.dst | = | |
custnet.src | = | |
custsite.src | = | |
ip.src | = | |
ipsrc.bin | = | |
ad.username.src | = | |
ad.computer.src | = | |
ad.domain.src | = | |
custnet.src | = | |
custsite.src | = | |
alias.host | = | |
Local.ip | = | |
Gateway.ip | = | |
ecat.macaddress | = | |
ecat.OS | = | |
ecat.AgentID | = | |
ecat.stime | = | |
domain.src | = | |
ecat.ctime | = | |
ecat.score | = | |
cs_lifetime | = | "58" |
cs_log_medium | = | "1" |
packets | = | 264 |
cs_payload | = | "15773" |
cn_log_rid | = | "324832440" |
cn_rpackets | = | "6" |
cs_rpayload | = | "572" |
server | = | |
service.name | = | |
log.session.id | = | "318333239" |
bytes | = | |
cs_streams | = | "2" |
custnet.dst | = | |
alert | = | |
alert | = | |
alert | = | |
alert | = |
2016-01-14 12:21 PM
I noticed that the packet parsers were putting the user agent string in the client metakey, whereas the log parsers were putting it in the user.agent metakey.
I edited by table-map-custom.xml file so that the log parsers also put the information into the client meta key as this was easier than changing the packet parsers.