David Waugh

Sample ESA Rule to Detect New User Agents in an environment

Discussion created by David Waugh Employee on Jan 13, 2016
Latest reply on Jan 14, 2016 by David Waugh

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.



@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




Meta Generated from Alert:


sessionid    =    1157482825
time    =    2016-01-13T14:22:18.0
size    =    2112
lc.cid    =   

forward.ip    =
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    =