Implementing Active Lists in OSSEC

Crime WatchThe second OSSEC week just ended. Here is a reflection about a feature that does not exist (yet?) in OSSEC. The goal of a SIEM (“Security Incidents and Events Management“) is to collect logs from multiple non-heterogeneous sources and process them to add some extra value to the events. To achieve this, powerful correlation engines can be used to create rules to match different types of events  coming from different sources and to create a unique security incident:

  if (condition1 && condition2 && condition3)
  {
    created_security_alert();
  }

Once created, The security incident must be processed. The basic action is to notify the right people with messages displayed on a console, new events, emails, etc. But, depending on their criticality, not all security incidents must result in messages. Some correlation rules results may just create new information which will be re-used later.

An interesting feature in some commercial SIEM implementations is the ability to create “active lists.” Such lists are like database tables where information can be stored temporary.  As a result of a correlation rule, a new item can be inserted in a temporary table. Basically they can contain any relevant information about the security of an information system: IP addresses, user names, domain names, autonomous systems. Just use your imagination!

Why use active lists? They can be implemented to keep a list of suspicious items to be re-used by other rules to increase their efficiency. Basically, two operations can be performed:

  • Store an item in the list
  • Query the list for one or more items

Queries can be performed by the same correlation engine or re-used by third party applications like seen on the schema below:

Active List Principle
Click to enlarge

Imagine a scenario with a SIEM environment collecting events generated by an IDS. In a common attack scenario, an attacker will first perform the network reconnaissance. One of the actions will be to start a port scanning against the target. This is a classic alert reported by any IDS. Instead of generating an alert, the SIEM can use an active list to store the IP addresses performing the port scanning for a specific amount of time (like a few hours). More rules can also populate the active list and the system will always have a list of suspicious IP addresses available. Other rules can be defined to query the same table and generate alerts with a higher priority based on events containing one of the IP addresses stored in the active list:

  if (condition1 &&
      condition2 &&
      source_ip in active_list)
  {
    create_security_alert();
  }

Example: A denied SSH connection attempt issued from a suspicious IP address will have an higher priority then the same event issued from an “unknown” address. The benefit of active lists are more reliable security incidents.

How to implement this in OSSEC? The active-response feature is our best friend! The principle will be to create an active-response script which will be triggered by a set of rules considered as dangerous like:

  • Rule 5712 – SSHD brute force trying to get access to the system.
  • Rule 20151 – Multiple IDS events from same source ip.
  • Rule 40601 – Network scan from same source ip.

My active-response script stores the suspicious information into a MySQL database. Later, the same DB will be used to query some IP addresses. I choose MySQL to store the information to make them available to third party tools.

The database schema is quite simple in this case:

  create database `ossec_active_lists`;
  create table `ip_addresses` (
    `ip`            varchar(15) not null,
    `timestamp`     datetime NOT NULL default '0000-00-00 00:00:00',
    `alertid`       int(6),
    `ruleid`        int(6),
    `comment`       varchar(256),
    unique key (`ip`)
  );

Copy the active-response script in your active-response/bin/ directory and apply the following changes in your ossec.conf:

  <command>
    <name>active-list</name>
    <executable>active-list.pl</executable>
    <expect>srcip</expect>
    <timeout_allowed>yes</timeout_allowed>
  </command>

  <active-response>
    <!-- This response is going to execute the active-list
      -- command for every event that fires a rule with
      -- the specific rule ID's
      -- The IP is going to be logged for  1 day.
      -->
    <command>active-list</command>
    <location>local</location>
    <timeout>86400</timeout>
    <rules_id>5712, 20151, 40601</rules_id>
  </active-response>

How to re-use the active list in other rules to increase the efficiency? (this is a proof-of-concept)

  1. Create a new active-response script which will query the datbase (key = IP address)
  2. Assign the active-response script to the alert you’d like to add the active list check
  3. If the IP address is present in the active list, create a new syslog message
  4. Create a new rule which will be triggered by the new syslog message (with a higher level)

This is only a proof of concept. From my point of view, the execution of several active-response scripts will be a major bottleneck and decrease the OSSEC server performance. Why not implementing active-lists directly in the core server code? What do you think?

3 comments

  1. Very interesting idea. I’m not sure how easy this would be to implement inside of analysisd, but some similar ideas have been floating around for a bit.

    For longer lived data (fairly static list of suspect IP addresses for example) you can use the cdb list functions. Unfortunately cdb is optimized for writing, and modifying the data in a timely fashion is difficult.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.