For a while, it looks that “Fraud detection” is a hot-topic for many SIEM vendors (“Security Information and Event Management“). Recent presentations or webcasts I attended had always some time dedicated to “fraud”! The vendors can’t be blamed to find new opportunities to sell their products. Today they are solutions which work quite well at detecting common security incidents. Wikipedia defines a fraud as “an intentional deception made for personal gain or to damage another individual;“. Detecting fraudulent activities is difficult due to their nature: they are based on simple actions and they are hidden in the huge flow of events generated daily by your devices and applications.
If you read my blog, you probably noticed that OSSEC became a recurrent topic for a few weeks. Like I said above, I’m involved in SIEM projects based on commercial products and I find the availableÂ tools fascinating to extract the real value from events! Users activity generates events which are already collected by OSSEC. So why not try to detect fraud with a free solution? They’re many types of frauds (banking, telecommunications, Internet, etc) but I’ll base my example on user accounts fraud.
The scenario: An organization maintains a portal, based on Apache, delivering business information related to the Belgium market. All users receivedÂ personal credentials. The goal is to detect fraudulent login usage. If one of those conditions is met, OSSEC will generate an alert:
- If a login is used from a country outside Belgium
- If a login is used from multiple countries within a small period of time (< time to travel)
- If a login is used from multiple subnets within a small period of time
The implementation of a fraud detection mechanism starts with a white page and some brainstorming: How to translate a fraudulent behavior into rules and triggers? In the examples given above, let’s focus on the second one: detecting a login used across multiple countries during a small period of time. The user’s IP address will be converted to a country name (via geo-localization). And a delta of time will be computed between each access on the website for a same login (We will assume that one day may occur between accesses from two different countries). At OSSEC level, those operations will be performed by an active-response script. The following figure will give you an overview of the solution:
- Apache logs (webaccess) is collected by OSSEC and events created.
- If the event matches our criteria, we will trigger an active-response script to detect of the event looks like fraudulent (without logging or alerting on the original event).
- If yes, we create a new type of event (“fraud”).
- The fraud events are parsed and processed by OSSEC.
- Alerts will be generated.
How to implement this? I’ll assume that your OSSEC server is already configured and processing Apache logs. For details about the installation or deployment of OSSEC, have a look at the documentation.
Apache Parser Update
We need to track users authenticated by the Apache server. To achieve this, we need to change the “web-accesslog” decoder to fill the variable “user” with the right value. Backup your decoder.xml and change the existing decoder like this:
<decoder name="web-accesslog"> <type>web-log</type> <prematch>^\d+.\d+.\d+.\d+ </prematch> <regex>^(\d+.\d+.\d+.\d+) \S+ (\S+) [\S+ \S\d+] </regex> <regex>"\w+ (\S+) HTTP\S+ (\d+) </regex> <order>srcip, user, url, id</order> </decoder>
Local Rule Creation
A new “accesslog” rule will be created in the “local_rules.xml” configuration file:
<!-- Put your suspicious users here --> <var name="WEB_USERS">^mary$|^john$|^sam$</var> <group name="web,accesslog,"> <rule id="50000" level="5"> <if_sid>31100</if_sid> <regex>\d+.\d+.\d+.\d+ - \w+</regex> <user>$WEB_USERS</user> <description>Authenticated web access</description> </rule> </group> <!-- WEB,ACCESSLOG -->
To reduce the server load, I’m using a variable “WEB_USERS” with all the suspicious logins. Only events matching one of those users will be processed. If you want to reduce even more the matches (and the server load), you can restrict to some URL only. The newly created rule will never generate an alert nor a log entry. To achieve this, set the right rule level (here “5”) or use the option “no_email_alert, no_log”.
An active-response configuration must be added into the main OSSEC configuration file:
<command> <name>web-locate</name> <executable>web-locate.sh</executable> <expect>srcip,user</expect> </command> <active-response> <!-- Perform GeoIP localisation for any authenticated web user --> <command>web-locate</command> <location>server</location> <rules_id>50000</rules_id> </active-response>
This configuration defines a new script (“web-locate.sh“) will be triggered by any event matching the rule ID 50000.
Basically, the script “web-locate.sh” does the following:
- It reads the current login information (timestamp, IP address, country) from the filesystem
- It performs the geolocalization of the current IP address (using geoiplookup)
- If the countries differ, it substracts the new and old time:
- If less than 1 day occurred, an alert is generated.
- A line is written in a new logfile (/var/log/fraud.log)
- New data are saved on the filesystem
Here is an example of event generated by the script:
[31-03-2010 21:33:18] Suspicious activity detected for user johndoe \ via IP x.x.x.x in DE, Germany
The script is available here (provided “as is”). Feel free to re-use it.
The last step is to generate a new alert type from OSSEC. To achieve this, the main configuration will be modified to take care of the new log (using the type “syslog” – one event per line):
<localfile> <location>/var/log/fraud.log</location> <log_format>syslog</log_format> </localfile>
And define the new alert via new rule in local_rules.xml:
<group name="local,syslog,"> <rule id="50001" level="10"> <match>Suspicious activity</match> <description>Fraud Detection</description> </rule> </group> <!-- SYSLOG,LOCAL -->
Finally, restart your OSSEC. If one of your monitored logins will be used from different countries in less than 24 hours, alerts like the following example will be generated:
** Alert 1270065106.2956457: mailÂ - local,syslog, 2010 Mar 31 21:51:46 satanas->/var/log/fraud.log Rule: 50001 (level 10) -> 'Fraud Detection' Src IP: (none) User: (none) [31-03-2010 21:51:45] Suspicious activity detected for user johndoe \ via IP x.x.x.x in DE, Germany
Nice isn’t it? The example presented here is quite simple. The ‘active-response’ feature of OSSECÂ is great and can trigger powerful scripts which can perform deeper checks to detect suspicious activities on your network! Of course, keep in mind that forking a script per event could increase the CPU usage on your server (directly related to the EPS level of your infrastructure).
Thanks for your comments. First, the goal of my examples is to show how to improve the security by implementing controls. Of course, an IP address cannot 100% authenticate the physical person behind it.
Regarding the distance, it could be interesting indeed. Unfortunately, the free GeoIP database has limited information. The paying one could help by giving more precise details.
Great principal, but what if the bad guys use a proxy in the same country? Obviously, Belgium is very small, but the US can have thousands of miles between IP addresses. Could one modify the web-locate.sh script to flag significant geographic distances between login IP addresses?
I stumbled upon this looking for active-response examples – bookmarked!
Thanks! Feel free to report your own findings!
I was JUST thinking about how to do geoloc stuff for the SSHD OSSEC log parser – and this solution would perfectly fit for that.