2016-02-29 09:33 AM
ESA engine is based on ESPER library, which is actually so powerful that I propose to read Solution patterns to understand espers capabilities http://www.espertech.com/esper/solution_patterns.php
In this article I show you how to create custom based functions to extend ESA capabilities. We create two functions to count lower and upper letters in string, next we will use them to detect abnormal host names in our network (actually you can use regex but this is just for example).
1) Create simple java class EsperUtils with two public static methods: countUpper and countLower
package NKlendar;
public class EsperUtils {
public static int countUpper(String input){
int count = 0;
try{
for(int i=0; i< input.length();i++){
if (Character.isUpperCase(input.charAt(i)))
count++;
}
}catch (Exception e){}
return count;
}
public static int countLower(String input){
int count = 0;
try{
for(int i=0; i< input.length();i++){
if (Character.isLowerCase(input.charAt(i)))
count++;
}
}catch (Exception e){}
return count;
}
}
2) Generate jar and call it myUtils.jar and copy it somewhere on esa server, in my case to /opt/uib/lib/myUtils.jar
3) Edit /opt/rsa/esa/conf/wrapper.conf and add wrapper.java.classpath parameter pointing to our jar file (do not forget to change numeric part):
wrapper.java.classpath.167=/opt/uib/lib/myUtils.jar
3) Edit /opt/rsa/esa/conf/esper-config.xml and add new function description (before <engine-settings> section😞
<plugin-singlerow-function name="countUpper" function-class="NKlendar.EsperUtils" function-method="countUpper" />
<plugin-singlerow-function name="countLower" function-class="NKlendar.EsperUtils" function-method="countLower" />
3) restart ESA:
service rsa-esa restart
4) use new function to detect anomaly host names in advanced ESA rules (we analyze count of upper and lower cases letters in source hostname which are in windows login events).
@Name('Win-AnomalyHostname')
@RSAAlert
Select window(*) from Event(
device_type='winevent_nic'
AND alias_host[0] IS NOT NULL
AND event_cat_name like '%Login%'
AND (alias_host[0]).length()>=14
AND countLower(alias_host[0])>=3
AND countUpper(alias_host[0])>=3
).win:time(1 min)
GROUP BY ip_src
output first every 30 min;
6) monitor mem and cpu usage changes!
5) Extend this idea to detect abnormal dns host names and count entropy of letters
Are you continue to use such ugly regexes to filter private IP:
ip_src REGEXP '(10\.[0-9]{1,3}|172\.(3[01]|2[0-9]|1[6-9])|192\.168)\.[0-9]{1,3}\.[0-9]{1,3}'
AND
ip_dst REGEXP '(10\.[0-9]{1,3}|172\.(3[01]|2[0-9]|1[6-9])|192\.168)\.[0-9]{1,3}\.[0-9]{1,3}'
in my rules I use following approach:
isPrivateIP(ip_src)
AND
isPrivateIP(ip_dst)
So I created NetUtils class with simple functions and registered it in esper engine:
<plugin-singlerow-function name="isPrivateIP" function-class="NKlendar.NetUtils" function-method="isPrivateIP" />
<plugin-singlerow-function name="isPublicIP" function-class="NKlendar.NetUtils" function-method="isPublicIP" />
<plugin-singlerow-function name="isIPInCIDR" function-class="NKlendar.NetUtils" function-method="isIPInCIDR" />
and registered jar in wrapper.conf
wrapper.java.classpath.167=/opt/uib/lib/NKlendar_utils.jar
If you like this article or have question or interesting ideas for custom functions please post it.
2016-03-01 03:56 AM
A really great example of expanding ESA functionality. Thank you for sharing.
Another approach would be to write a LUA function to do this. App Rules can also be used to tag Public and Private IP Address ranges. This would just reduce the processing load on the ESA.
2016-03-01 04:31 AM
Yep, it was just an example)
Another interesting thing is custom virtual data window. The idea is to create command based enrichment source. If I have an network scanning alert I want to nmap source host or try to get process list on the host and include this collected info to alert. Have a draft version but have no time to test