OSSIM Management Server

Server daemon (ossim-server)

ossim-server is a daemon which executes further processing tasks in OSSIM. It usually runs in the background and connects with the database to retrieve and enter data from agents as well as from frameworkd. It is also currently connected with the web php, but this will change to only accept connections from frameworkd. By default, ossim-server listens on port 40001.

Its main purpose is to:

  • Collect all the data from Agents or other servers.
  • Prioritize the events received
  • Correlate events arising from different sources
  • Carry out the Risk assessment by generating alarms.
  • Store events data in the database
  • Forward events or alarms to other servers

From this point, we'll not differentiate between an Agent and a Sensor, although you must bear in mind that a sensor is able to maintain multiple agents within it.

NOTE: Although none of the tasks described herein require root privileges, the easiest way to ensure that this daemon works correctly is to launch it as root.

Connections

The connections that are directed to a server may come from different sources. If any field of the received data is wrong and cannot be parsed, the received message is discarded, and the connection is closed by the server. Incorrect parsing must not occur, as this could be an attack.

A server may receive:

  • Information events: From agents. The server receives the state of the plugins connected to each agent (“Started”, “Stopped”, “Unknown”). This state is used when the framework requests this information from the server, for example in Monitor→Sensors
  • Data collecting events: From Agents or from lower situated servers in the architecture. These events can be redirected to upper servers.
  • Queries requesting data: Usually from the framework or other upper servers.
  • Orders: can only be issued from frameworkd or a master server. A lower situated server is unable to give orders to upper servers.

A server also may send data to other places, like:

  • SQL Database: All the data events are stored here, as well as certain information, like alarms, number of events per Sensor or different server roles.
  • Another server: A server can send data to another server. For example, we have this kind of architecture: web→frameworkd→ServerA→ServerB→agent. So the possibilities are:
    • An upper server in the architecture: this happens for example when frameworkd makes a request to serverA regarding plugins connected to server B. When the answer from server B arrives, server A forwards data to frameworkd
    • A lower server: The same case as above, server A needs to send a message to serverB. So when server B has finished its work, it sends the data to server A.
    • Server in the same level: A server can send data to another server just to store alarms or events in it. It's not mandatory for a server to have someone to report things.
  • Frameworkd: The Server sends all the alarms to frameworkd to let the user configure and use the Action/Responses.

Communications protocol (just for developers)

All connections made to the server must be identified by their OSSIM name, as well as the kind of remote machine. There are 3 types of possible connection sources:

  • Agent:
  • Child Servers:
  • Frameworkd

Collection

Collection is one of the first things required. Data collection is firstly done as a result of the Agents installed in Sensors. Each server can receive data from different sources, but data collection is only possible from:

  1. Agents: These are the main sources for incoming events. Events that come from an agent don't need to have “reliability” or “priority” fields (although they're accepted and rejected for historical reasons). The reason for this is that OSSIM stands for a centralized way of managing things. We can't let every Sensor decide its own data.
  2. Other Server: This is only possible in multi-level architecture. One server lower in the architecture can send data to another server that is higher in the architecture (a master server). The data forwarded may be events or alarms. In both cases, the event is treated like every other event which arrives at the server with this being correlated and processed as normal (see multi-level architecture for more details).

The data will be treated in a different way, depending on the kind of data received. The different kinds of events that the ossim-server accepts are the following:

  • “Normal” Events: these events are the ones that come from all the plugins installed across the network. This may include for example Cisco, Firewall-1, Windows, antivirus, and dozens of others. It is perfectly possible (and desirable) to enter data from different IDS's, like Snort, ISS, Nortel, etc. The only requirement is that all the possible message types must be categorized. All of these events can be correlated in this way:
    • “If from ANY ip, the Cisco router has seen a connection to 192.168.1.10 ip for a duration of 20 seconds, and we see an attack to the 192.168.1.20 IP from the Snort IDS with the same src ip after that, a risk 8 alarm will be generated”
  • OS Events: These events usually come from p0f (Passive Operative system Fingerprinting) detector. In fact the p0f detector just stores data in a file, and the agent is able to read the data as a result of the P0f plugin. Then, the Agent sends the normalized event to the Server, and it stores the information in ossim.host_os. This information can be useful for carrying out an inventory check, generating new directives, or cross correlation.
  • MAC Events: These events usually come from arpwatch or pads detectors. Just like the P0f detector, the Agent reads data and sends it to the server. The MAC change events are very useful to detect ARP poisoning and other layer 2 attacks. The server stores information in the ossim.host_mac table.
  • Service Events: These events keep the database updated with the open ports in the deployment network machines. This makes it possible to carry out cross correlation and store an inventory of all the machines in the net.

To keep all events normalized, OSSIM defines two important values for each one:

  1. Plugin ID: This is the identifier of the plugin that generated the event
  2. Plugin SID: This is a specific event type, inside the plugin type.

At this moment, all the events in OSSIM must have a plugin id and a plugin sid.

Take a look at Plugins to view more information about this.

Implementation Details

Each Agent opens a new thread in the Server when they connect to it. You must be aware of this if you are building a (really) big environment with thousands of Agents, as you may need to increase the number of the system’s maximum threads. In fact we suggest that if this is the case, you should divide the Server in different Servers with each one at a different level.

After the event arrives, it is parsed and sanitized, and if it's a Collection event, it will be pushed into a queue for it to be treated later. As the events are pushed into a queue, there is almost no decrease in the read performance; as soon as a new event arrives, it is read and removed from the read queue, allowing other events to arrive and be read.

Role assignment

What's the “Role”? Role specifies the behavior of a specific event, in a specific server. You can define two possible roles:

  1. Server Role: This role is a general role for the server. Every event that arrives at the server will do all the things specified in that role (explained below). Each server can perform a different role, and it's possible for this to be edited in Policy→Servers. If you only have one server (not a multiserver architecture), you don't need to specify the server's role; by default, all the fields are set to YES
  1. Policy Role. Although we said that the Server role is used for all the events in a Server, what happens if we want a special behavior in a special kind of event? Well, we have a Policy role for that. A Policy role supersedes the Server role, because it's more specific to a particular case. You can modify it at Policy→Policy.

So, if you want to give general behavior, modify the Server role. If you want specific event role (fine tuning), modify Policy role.

The event’s behavior varies accordingly to its role definition. If a variable inside role is set to YES, the event will do that kind of processing. If it isn’t, however, then it won’t.

OSSIM has the following role types:

RoleDescriptionLimitations
Correlate Must the event be Correlated?Always FALSE if the server doesn’t have a DB
Cross Correlate Must the event be cross correlated?Always FALSE if the server doesn’t have a DB
Store The event will be stored (or not) in snort DB.
Qualify Reprioritize & modify reliability? If the event has been reprioritized in another server, this doesn't matters as it won't be modified
Forward EventsForward events to an upper server, or to another on the same level
Forward AlarmsForward alarms to an upper server

Obviously there are some things that you can't do. If you didn't setup a DB in a Server, you need to configure the Server with Store set to false. You shouldn’t configure a Policy to store data in this case either.

Normalization

Priority

Priority is defined as: How important the attack is if it is successful. The Priority value analyzes how much harm a successful attack could cause.

When an event arrives at a server, once entered into the processing queue, a number of important steps are taken. In fact, the Normalization priority is not the first thing carried out, it's Cross Correlation, but this will be explained later for clarity. Normalization will only occur if the Server role of the Policy role says that this can be executed.

Normalization Priority is important so all events have normalized values in order that the Risk assessment is more accurate, and equal in all cases. We can't let every individual event enter its own priority and reliability.

If the events have been prioritized before (e.g. in a child server situated lower in the architecture in multilevel designs), the priority remains untouched.

There are two possible cases here:

  1. The event belongs to a Policy: In this case, we will use the priority specified in the Policy. Of course, it is possible that although the event matches a Policy, you have the “Do not Change” priority flag on it, so priority is left untouched in this case.
  2. The event doesn't match any policy: The Priority is taken from the plugin_sid table in the ossim DB.

<note important> If the event has been prioritized in a child server situated lower in the architecture, it won't be prioritized again. </note>

We can then see that Policy is a perfect place to easily tune the Risk Assessment. If you want an event to be easily converted into an alarm, you just need to increase priority value.

Priority has a maximum value of 5 which means maximum priority, and a minimum of 0, which means that the event has no interest to us and will not generate an Alarm.

Priority can also be changed in some events if they fit into Cross Correlation or into Inventory Correlation.

Reliability

Reliability relates to how reliable it is that the attack will be successful. For example, the Priority of an atomic bomb falling on our offices could be 5 (really dangerous!) but the Reliability of this is around 0 (possibly 8 or 9 if you live in a country with lots of petroleum).

You can change the Reliability of all the events issued by every Agent. Please bear in mind that when you change a Reliability, you're changing the Reliability of all the events coming from any sensor.

Reliability has a maximum value of 10, which means maximum Reliability, and a minimum of 0, which means that the event has almost no chance of being successful.

Priorization Policy

As stated before, a central place to control the priority of every event that arrives at the OSSIM server is needed. This place is the Policy. The Policy can do more things, but we will concentrate on priority issues.

Priority values range from 0 to 5. We recommend following this table to assign priority values to specific events

ValueMeaning
0 Event has no importance. This event will never generate an alarm because the Risk value will always be 0 (you just need to remember how the Risk assessment is carried out)
1 Event is unimportant, but it's not ruled out
2 This is the default Priority value. Unless you want to do something special with events, or just tune OSSIM, this is the right value.
3 - 4 You can play with these values to get easily Alarms.
5 Maximum priority can be set when you want to be almost certain that this will generate an Alarm. Of course this will depend on machine Assets and Reliability, but it's the easiest way to increase this; if you leave the default values in Asset (2) and reliability (1), you'll get an alarm.

In fact, internally, you can assign a ”-1” value, which means “Don't touch the priority value of this Policy”, as you may want to control other things. This value is specified as “Do not change” in OSSIM interface (Policy→policy).

In prioritization you can also reprioritize an Alarm generated by OSSIM. You may want to reduce the Risk generated in alarms with a specific source IP and with a specific destination (for example, a printer),

Correlation

Correlation is one of the most important things in OSSIM, as it's what greatly reduces false positives and alerts. The number of events is reduced to just some Alarms in the Correlation, which are much easier to analyze.

Correlation is carried out in different ways, depending on the kind of event that OSSIM receives. It also depends on the type of information that OSSIM has stored about the attack destination.

At first glance, we can divide correlation into the following types:

Type of Correlation Where it is doneOther info needed apart from event data
Cross CorrelationBetween events and destination vulnerabilitiesYes
Inventory CorrelationBetween events and destination characteristicsYes
Logical CorrelationBetween events from different sourcesNo

Correlation can be executed in a specific OSSIM server only if it has a local database installed. As you know, OSSIM servers can be installed without any configured database, and taking its data from a master OSSIM server configured in a multi-level architecture. Of course, this master OSSIM server (or the upper one) must have a database installed in order to be able to correlate things. There is a very simple reason for this: In all correlation types, you'll need to access the database to store certain things or to check certain data that is updated continuously and can't only be taken once when the server starts, for example:

Type of CorrelationData accessed or stored in DB
Cross CorrelationAccess to vulnerabilities discovered
Inventory CorrelationAccess to inventory
Logical CorrelationStored data from each event into backlog

Cross Correlation

Cross correlation is carried out with events that have a defined IP destination address. The reason is that in this kind of correlation, we're going to check if the event destination has some vulnerability defined in the database. That's why OS events, or MAC events for example, can't be cross-correlated, although they can be useful for a cross-correlation of other events. OS events and MAC events do not have a destination, as they refer to a specific host.

Cross Correlation is used to modify the reliability of an event. Modifying this value will have an effect on the Risk, and by extension, the alarm generation.

When an event arrives at the OSSIM server, the correlation engine looks for the IP destination address. This IP destination address may have some associated characteristics. At this moment the different types are:

  • Vulnerabilities (Nessus)
  • OS
  • Open ports

Each one of these types is filled due to the information arriving at the server, and due to the Nessus integration. These characteristics are defined inside the table host_plugin_sid, where the IP with a specific vulnerability, OS, or open port are stored, described thanks to a plugin ID and a plugin SID.

So, we have three basic types, each one working in a similar way by entering data into host_plugin_sid table:

  1. When Nessus discovers a vulnerability in a specific host, the entry is entered with the Nessus ID (field plugin_id, value 3001), the vulnerability discovered (plugin_sid), and the host IP with that problem.
  2. When a new OS event arrives (usually as a result of a P0f detection), the OS identification is inserted into plugin_sid field, the type of detection (OS detection) is inserted into plugin_id with the value 5001, and of course the host IP with that OS.
  3. When a new Service event arrives (usually as a result of pads), the type of detection (5002) is entered into plugin_id, and the discovered port is entered into plugin_sid, as well as the destination host IP.

The values inside host_plugin_sid are updated continuously due to the detectors, so we are able to know if a specific IP destination has some interesting data to correlate at any time.

This means that an event destination IP address may have, for example, a vulnerability and an open port. So we will see something like this in the table host_plugin_sid:

mysql> select * from host_plugin_sid;
+------------+-----------+------------+
| host_ip    | plugin_id | plugin_sid |
+------------+-----------+------------+
| 3232235853 |      3001 |      11041 |
| 3232235853 |      5002 |         80 |
+------------+-----------+------------+

As we can see, the 11041 is the identifier of “nessus: Apache Tomcat /servlet Cross Site Scripting”. So we now know that it has that vulnerability type.

Now, if an event occurs stating that the destination IP address has specific snort vulnerability, we can check if this vulnerability matches with the ones we know the IP has.

So, the basic rule for Cross Correlation is: if snort has discovered an attack to an IP, and we know that IP has that vulnerability, the reliability will change to 10.

The relationships between nessus ID's and snort vulnerabilities are stored in the table plugin_reference. If you want to do some kind of personalization, you have to insert data in this table. Check Personalize Cross Correlation. When a personalized Cross Correlation matches, the event adds the reliability of the new plugin to the old one.

In that table you'll find not just the snort↔nessus relationships, you'll also find the used relationships between snort events and OS or the relationships with ports.

To be clearer, these are the relations between both tables:

ossim.host_plugin_sid.plugin_id == ossim.plugin_reference.reference_id
ossim.host_plugin_sid.plugin_sid == ossim.plugin_reference.reference_sid
ossim.plugin_sid.plugin_id == ossim.plugin_reference.plugin_id
ossim.plugin_sid.sid == ossim.plugin_reference.plugin_sid

If the reliability of the event once the cross correlation is done is >=1, then an alarm is generated

Personalize Cross Correlation

For example, you may want to correlate between an event and a surveillance camera. You'll need to generate two new plugins with a specific plugin_id and some plugin sid(s). Take a look to see how to create a new plugin.

First, you'll need to make the relationships between both plugins. These relationships are stored inside plugin_reference table.

You'll see 4 columns. The first two columns (plugin_id & plugin_sid) are the identifiers of the event that arrives at the correlation engine. Obviously all the plugin_id and plugin_sid entries in this table must also be in the plugin_sid table, just like any other plugin. The last two columns (reference_id & reference_sid) are in fact the plugin_id and plugin_sid of the other plugin, but now they're entered here to check the relation with the new arriving events.

While the OSSIM server is running, you'll need to insert the data to be compared into host_plugin_sid table. You can choose the data entry method. You can use a script, a specific program, or any other method.

Then, when the new event arrives, correlation engine will first take a look at the host_plugin_sid table, if destination matches something, it will search into plugin_reference table the plugin_id and plugin_sid regarding the reference_id. If it matches, the reliability of the ossim.plugin_reference.reference_sid will be added to the ossim.plugin_reference.plugin_sid reliability, making it easier to generate alarms.

For example, a user may want to cross-correlate between 2 new plugins, say 25000 and 25001. He needs to insert plugin_id 25001 and plugin_sid 1 (i.e.) into host_plugin_sid. After that he needs to fill the plugin_reference table with data like (25000, 1, 25001, 22), so plugin sid 1 from plugin id 2500 has a relationship with plugin_sid 22 from plugin id 25001.

Inventory Correlation

The aim of Inventory Correlation is mainly to reduce the number of false positives. This is done modifying the Reliability of all the events that matches in the inventory correlation.

Inventory Correlation just defines different types of correlation:

  1. OS correlation
  2. Port correlation
  3. Protocol correlation
  4. Service name correlation
  5. Service version correlation.

Reliability will be modified in one way or another with each of these types. For a quick guide, take a look at this table:

Inventory Correlation typeMatchDoesn't matchNot enough data to decideExample
OS+10Remains Untouched“OpenBSD”
PortRemains Untouched0Remains Untouched “80”
ProtocolRemains Untouched0Remains Untouched“TCP”
Service+2Remains UntouchedRemains Untouched“Apache”
Version9Remains UntouchedRemains Untouched“1.3.33”

As can be seen each type of Inventory Correlation has its own values. Inventory Correlation also stores the data needed inside host_plugin_sid and plugin_reference tables, just like in Cross Correlation.

  1. OS Correlation: Here we will check the destination Operating System and will try to decide if the incoming attack event works against that OS. The event itself doesn't have an OS, so we have to firstly check if there is a relationship in the database between the event and a specific OS. To have an easier way of doing the match, OSSIM compares the following OS at this time, without versions or specific service packs:
    • Windows
    • Linux
    • Cisco
    • BSD
    • FreeBSD
    • NetBSD
    • OpenBSD
    • HP-UX
    • Solaris
    • Macos
    • Plan9
    • SCO
    • AIX
    • UNIX
  2. Port Correlation: This is another check to reduce reliability of the event. When an attack event arrives at the correlation engine, it must be checked if the port and protocol matches. Obviously, you can't generate a TCP event without completing a full three-way handshake. This means that you can't attack any application until you get connected. You could attack the network stack in the machine, but not the application itself. So, if you have completed the 3-way handshake, the destination port must be opened and the event port must match the stored opened port, so we leave the reliability untouched.
  3. Protocol Correlation: There is, of course, one special case: UDP. If the event issued is an UDP attack, the attack can be produced with just one packet, without a handshake. So if the destination IP address only has a TCP port open, but the attack is an UDP, we reduce the reliability to 0, as it’s almost impossible to do anything there (just network stack attacks not application attacks). And if the destination IP address only has an UDP port open, and we try to connect to TCP in some way, the connection won't be a success in any case and no event will be generated.
  4. Service: To be able to correlate the service, the port/protocol pre-requisite must firstly be passed. If it doesn't match, the service cannot be checked. In order to get the relationship between event and the service used, it must be checked against the OSVDB database. As you can see, the attack event arriving from the OSSIM server didn't store any information relating to the service name (“Apache”, for example), and we need to know what application is attacking the intruder to increase or reduce reliability. We can obtain that information thanks to OSVDB, and the relationship table ossim.plugin_reference.
    • Internally, it is first checked whether the attack event generated has anything to do with a OSVDB entry in the database. At this time, we have relationships between snort, CVE, Bugtraq, and OSVDB entries in ossim.plugin_reference table.
    • The OSVDB service name (called object_base.base_name inside OSVDB tables) is checked against the service name stored in the ossim.host_service table. If it matches, as we can't say that it's a very dangerous thing, we add 2 to the event reliability. This is done because attacks can be generated automatically, or manually. As we can suppose that the attack is done manually, if we know that the method used will match with the application installed in the destination, the reliability increases slightly.
    • If the host doesn't match, this doesn't mean anything. It is possible that the host changed the “banner” or something similar. So we leave the reliability untouched in this case.
  5. Version: This is one of the most accurate tests in Inventory Correlation. Version is the specific application version installed in the destination, for example “1.3.33” in the case of Apache server, or “2.0”, “3.0”, “3.1”, or “4.0” in the case of Coldfusion. In order to correlate the Version, firstly the Service has to be correlated. This is an important point, because if the Service doesn't match, it makes no sense to try to match only a number, which may fit into multiple applications. If the version matches, now we know that this is an attack that is planned and specially crafted for the destination host, so we increase the event's reliability to 9.

If the reliability of the event once the cross correlation is done is >=1, an alarm is generated.

Logical Correlation

Logical Correlation is part of the OSSIM's heart. You'll be able to generate alarms without knowing the specific type of attack. False positives will also be reduced because it's only possible to show relevant things once the events have been treated and qualified.

As a result of this, you'll be able to generate alarms in this way:

  1. “If the external Cisco router generates a trap like 'Deny IP due to Land Attack', and we then see traffic in the DMZ with the originating IP, and then we see some kind of connection from that IP to a database, an alarm with a specific Risk is generated”
  2. “John Doe is accessing the company's database from his account across the wireless network. He didn't, however, enter the building, as we have not received any information from the physical access control system. So someone is very probably hijacking John's account, and an alarm with a high Risk is generated”
  3. And more general things: “if A and B, but not C, and A stays connected to D, an Alarm is generated”

The Logical Correlation engine works thanks to the rules specified in an XML file. Usually, this file is in

/etc/ossim/server/directives.xml 

As this is an XML file, you can make multiple sub-files to separate and organize them into something better. In the default OSSIM installation, at this moment you'll also find some files, like:

/etc/ossim/server/generic.xml  --> As its name says, they're generic rules for generic attacks
/etc/ossim/server/trojans.xml  --> they're specific rules for multiple trojans

You can add more rules just by editing the file by hand. We're working on a web-based rules editor so stay tuned for that.

Directives are a special type of “plugin”. When a directive generates an Alarm what it does is create a special type of event. Just like any other event, it must be generated by some plugin. This plugin, as any other plugin, must own a plugin ID (1505, the identifier for directives) and one or multiple plugin sids. The plugin sids are the directives identifier, and they're loaded into the memory when the OSSIM server starts, and entered into ossim.plugin_sid table. That's needed to be able to modify a directive’s reliability as a result of Policy for example, as with any other plugin.

Contrary to how we normally think, alarms aren't created when the events are correlated. Instead, a Directive Event is generated, and thanks to its reliability and priority, it will later be transformed into an alarm.

How it works

Each of the rules mentioned before, are a piece inside a Directive. Directives are the real heart of Correlation. They can have multiple levels. Each level has its own keyword and specifications. It is also possible to group Directives for clarity.

Another important element of Directives is the backlog. Backlog is the memory struct where the directives that have matched in some level are loaded. Each of the Directive’s memory structs (each node) is called a “Level”. This directive for example has two levels:

<directive id="8" name="Strange global behaviour" priority="3">
    <rule type="detector" name="Active host sender / known hosts anomaly" reliability="2"
    occurrence="1" from="ANY" to="ANY" port_from="ANY" port_to="ANY"
    plugin_id="1508" plugin_sid="ANY">
        <rules>
            <rule type="detector" name="Too many active host sender / known
            hosts anomaly" reliability="5" time_out="300" occurrence="49"
            from="1:SRC_IP" to="ANY" port_from="ANY" port_to="ANY"
            plugin_id="1508" plugin_sid="ANY"/>
        </rules>
    </rule>
</directive>

To understand the meaning of each field, and to be able to generate your own Directives, please take a look at How to Create a Directive. To get the up-to-date syntax, please go to Correlation->Directives inside the OSSIM web interface.

In fact, Backlog is a directive with some other additional information.

To go through the complete process, we're going to suppose that the server has started right now, and this is the first event arriving at it.

  • When an event arrives to Correlation engine, all of its variables (src, dst, port, plugin_id, and so on) are checked against the first backlog entry. As this is the first event, there are no data inside Backlog, so we know that this event still didn't matched with nothing, and jumps to the next step.
    • It's time to check this against the first rule of the first Directive. As stated before, all the event fields will be compared with the data in the first Directive's rule, the first level. If the event matches with the rule a new Backlog entry is created. This Backlog is a Directive with the information of the event associated to its first rule. The keywords that accept data from other Directive levels are the following:
      • from
      • to
      • port_from
      • port_to
      • protocol
      • plugin_sid
      • sensor
      • filename
      • username
      • password
      • userdata1 - userdata9

NOTE: It is necessary to store this information because the sub-levels (other rules) of the Directive may need to access a specific keyword. For example, if there is an element in the directive with a src_ip = “ANY”, we need to know what src_ip has matched with the “ANY” keyword to get the rules with 1:SRC_IP knowing the value. See How to Create a Directive) for more information about this point.

  • Once the event has been stored into the first backlog's rule, it's inserted into ossim.event table to reference it later if needed. This may happen in the Framework; if this event is part of an alarm, the event's ID must be known so it can be referenced.

FIXME: there is a design fault and there is a point that will be changed. I'll document it better when it gets reprogrammed. Remember: Monitor Rules

  • A Directive Event is generated. As stated before, this directive event will be transformed later in an alarm, as an Alarm is just one event with the alarm flag activated. The alarm will fill its different fields with the following data. We'll show just the most important fields:
    • time: exact time when the alarm was generated
    • backlog_id: Identifier inside the backlog table. As the event (alarm) generated belongs to a Directive, it must know which is the backlog_id of that directive.
    • plugin_id: 1505, the directives plugin identifier
    • plugin_sid: directive identifier, so you know what Directive has been matched.
    • IP and Ports: The Alarm will take the data from the rule that generated it. Here we have an interesting thing, because as you know, some rules may have the “ANY” keyword, and “ANY” is not an IP. Now enter the game, the data stored inside the Directive in an earlier step. Those “ANY” are substituted with the IP from the event that matched the Rule. This is valid for source IP, destination IP address, source port, destination port, and Protocol. There is a special case, the Rules with something like “1:SRC_IP” in the from field (the source IP field). These rules will take the data from the Rule level specified with the number, so in our example we will take the SRC_IP from the first Rule level.
    • Data: The directive is written inside the “data” field to have more information.
    • Level: The Directive's rule that matched is also stored.
    • Reliability: This can be set to different values depending on the reliability values from the rule, and the absolute tag:
      1. Absolute: If the rule's reliability is absolute, the event's new reliability will be the same as the rule.
      2. relative: In this case, the reliability will be the sum of all the reliabilities from upper levels in the Directive, with a maximum reliability of 10.
    • id: As the event hasn't got an ID, it gets a new one and it’s entered into ossim.event table
  • After the Directive Event has been created, it’s inserted into ossim.backlog and ossim.backlog_event tables.
  • Also, an important thing happens: the directive event is reinjected into the event queue, so we can reprioritize, store, forward, or do anything else that we do with “normal” events.
  • At this moment, the event has matched with the first level in the Directive. Now, when another event arrives to the ossim-server, the backlog queue won't be empty and we'll enter another execution flow.
  • The event is checked against the Directives stored in the Backlog, to see if it matches with that Directive's children. If it matches, time and event data is stored in the Directive memory, the same as what happened with the previous event.
  • If the previous step has been matched, a new Directive event is generated and inserted into the backlog and ossim.event tables, so, again, we can reference it later.
  • The level of the Rule is checked. If it’s the last rule, then the Directive stored in the memory (called Backlog) doesn’t make any sense. If some events that match with a Directive have been received, and they arrive to the inner Rule in the Directive, the Directive's interest is null, so we'll add it to a queue to remove it later.

FIXME: Same as the other one.

<note important>All the events are checked against all the directives. If one event has already matched a directive, it doesn't mean it won't be checked against others. So, an event may generate multiple different alarms. </note>

You may not want one event generating multiple Directive events, and you want to group all Alarms. In this case, the rules definition (take a look at How to Create a Directive) allows you to group multiple Directives so they are visually maintained as only one Alarm.

Logical Correlation mainly uses two variables to generate the Alarm Risk: Reliability and Priority. These two values are taken from the Directive rule, as explained before. When the Directive Event is inserted again in the event queue and enters into the Risk Assessment module, it’s transformed into an Alarm.

Risk Assessment

Risk Assessment is another important tool to reduce false positives. From multiple events we will be able to get an excerpt of the most important, once converted into alarms. In order to decide whether or not to perform an action we evaluate the threat represented by an event in relation to certain assets, bearing in mind the reliability of our data and the probability that the event will occur.

Basically, Risk Assessment is where an event's Priority and C & A levels are changed to generate an Alarm with more or less Risk, so it takes part in the decision of when an Alarm will be issued.

Risk assessment is a step in the risk management process. Risk Assessment measures two quantities of the host and networks assets, the magnitude of the potential loss, and the reliability that the loss will occur. Security in any system should be commensurate with its risks. One of the prime functions of security risk analysis is to put this process onto an objective basis so different approaches can be done depending on the Risk; a concrete and measurable value.

<note warning>The Risk Assessment will be executed only if the Server's Role, or a Policy Role installed in that server allows the event to Qualify.</note>

The importance given to an event depends on these three factors:

  1. The threat represented by the event (Priority)
  2. The value of the assets associated with the event
  3. The probability that the event will occur (Reliability)

So there are three phases in Risk Assessment:

  • Priority changes
  • Update C & A levels
  • Calculate Risk

Those three steps are executed in order, and it works as follows:

Priority changes

Priority is assigned to events depending on their membership to a specific Policy. This has been explained in Priority Normalization

If the event that enters in the Priority Normalization doesn't have information inside the database like plugin_id and plugin_sid, it is rejected. To increase security and keep normalization rules working fine, OSSIM only works with events defined inside DB.

C & A levels

First of all, we have to answer a question: What is the meaning of C & A? The short answer is: Compromise and Attack. But let's go with the large one:

  • “C” or level of compromise, which measures the probability that a machine is compromised. This shows a value about how many events that machine is generating.
  • “A” or level of attack to which a system is subjected that measures the potential risk due to attacks launched. The value shows a relation regarding how many events the machine is generating.

Why separate these two variables for monitoring? Firstly, because they characterize different situations: the level of attack indicates the probability that an attack has been launched, an attack that may or may not be successful; while the level of compromise provides direct evidence that there has been an attack and that it has been successful.

Secondly, the importance of both variables depends on the situation of the machine. Mainly due to the exposed state of perimeter networks, which are exposed to an enormous number of attacks, most of them automated, unfortunately a high level-of-attack value is a “normal” situation. However, any sign of compromise or movement that might lead us to think there is an attacker residing in these networks should be immediately pointed out and reviewed.

On the other hand, there are cases in which a machine generates anomalies within the network due to the nature of its function (such as a security scanner, a service with random passive ports, bad-configured DNS servers, and so on) and these will normally have a high C and a low A. We must bear in mind that although a machine may have a very high C value, it doesn't mean that it's always compromised, this machine just needs to be fine tuned.

A value is assigned to the C or A variable for a machine on the network according to three rules:

  1. Any possible attack launched from machine 1 on machine 2 will increase the A (level of attacks experienced) of machine 2 and the C (level of compromise, or suspicious actions normally perpetrated by a hacker) of machine 1.
  2. If the event type doesn’t have a destination because events are internal to that machine (MAC events, OS change events, Host IDs events…) we only update the C level for the originating machine
  3. If the event belongs to a specific network, the C & A of that network is updated in the same way as the event.

The C & A levels are both updated thanks to the Risk levels. This means that each event will update in a different way the C or A host's value. We can see then that C & A increasing levels depends on the event's Risk, and of course we have two different Risks depending on what are we calculating, source C or destination A. This is a direct dependency, because the Risk level will be added to the source host C and/or destination A level, each one with a different value.

As we are interested in assessing recent events, the C & A levels should have short-term memory that places importance on the most recent events and discards the oldest. The current implementation uses a simple variable for recovery over time. The system will periodically lower the C and A levels for each machine by a constant value, defined in Configuration→Main→recovery.

Calculating Risk

Risk is an interesting way to normalize and determine a value which can be used to make decisions about a specific set of attacks performed in a specific timeframe and in a specific order.

OSSIM uses two different Risks values, one for the source and another one for the destination IP address of the event. So every event has two risks.

The risk must be calculated on a source/destination basis. This means that as we have two risks, each one of them will be calculated with the asset of the machine involved in the attack. These are the two rules that we will follow:

  1. If we're calculating Risk C, we will use the source asset
  2. If we're calculating Risk A, we will use the destination asset

So, thanks to this, Risk is also used to modify the C & A values, adding its value to them. If we have calculated Risk C it will modify the source's machine C level. If the calculated value is Risk A, then it will be added to the destination's machine A level.

To normalize the Risk, we use this formula:

Risk = (Priority * Reliability * Asset) / 25

This is a way to normalize the Risk in every possible case. The maximum and minimum values of the internal variables which mold the Risk are as follows:

DataMaxMin
Priority50
Reliability100
Asset50

So, as we can see, if we get the maximum values of each variable, this is the result:

Risk = (5 * 10 * 5) / 25 = 10

And we will get the maximum risk value. If we reduce any of those numbers, the Risk will also be reduced. In this way, we normalize the Risk to get a high visibility of the problem and we will be able to act in some way thanks to it.

When an Alarm is issued, the greater Risk is the one entered into it. So if Risk A is greater than Risk C, then risk A will be chosen. If Risk C is greater, then Risk C will be entered into the database.

Risk is also used to modify the C & A values, adding its value to them.

Of course, OSSIM is able to react to alarms, for example sending mails or executing whatever command you want. You can access Policy→Responses to give it a try.

Recursion

Recursion is a powerful tool built into OSSIM. We basically have two types of recursion:

  • Directive events recursion (in fact, Alarm recursion)
  • Multilevel server recursion (event forwarding and re-insertion server→server)

When a Directive event is issued, it’s re-inserted into the event queue. This will let us work again with that event as though it were a normal event. You have to remember that the Directive event is usually transformed into an alarm after its Priority and Reliability has been checked and the Risk Assessment has been executed . So, Recursion means that you'll be able to do the following with the generated future Alarms:

  • Correlate: Once an Alarm has been generated, you'll be able to generate new Alarms when it arrives again to the correlation engine if you have defined a Directive that matches it. To do that, you'll need to create a Directive with plugin_id 1505 (identifier for Directive events) and the plugin_sid will be the Directive id that generated the first Directive event. With this strategy, you can do lots of things:
    • Generate Alarms which depend on other alarms to increase their risk
    • Generate different Alarms when a host of dangerous events have happened, letting you make multiple executions with each one, which make it easy to manage the escalation strategy for security incidents.
    • Send different Alarms that are separated in time but relate to the same thing to your CTO, so he knows that the security breach is increasing.
  • Reprioritize: it is possible that you don’t want a Directive Event’s Risk to increase to a great extent if it is issued from a specific place, and you don’t want it to convert into an Alarm, although the Directives state otherwise. For example, you may have multiple remote offices with important data. Each office is very important and you want to receive an alarm by text message if they suffer an attack. However one of the offices where you carry out tests is also owned by you and you're pretty sure that your activity will generate an alarm, which is what you don’t want. You can reprioritize the Directive events which come from those offices, lowering the Reliability as a secondary effect, to avoid generating more alarms so you are not bothered by useless text messages.
  • Modify the C & A levels: A Directive event will increase the values of the C & A host and network levels, just like any other event. But has the advantage that you know when it’s done, that it's a real increase in the levels, because you have correlated it before. That's why the Directive events usually have a greater Priority and Reliability than the other events, and that's why they are easily converted into Alarms. As a secondary effect, usually the C & A levels increase more than with a normal event, providing you with a better accuracy in monitoring these variables.
  • Store Directive events in the same DB as normal events. This will let you browse and analyze them in the same way. These are obviously treated in further ways and you'll be able to access them in more places (Control Panel→ Alarms, for example).

Storage

The storage of the data collected by the sensors is carried out once they have been reprioritized. We can insert the data into the database once they have their correct values, not before.

Although all aggregated data are always shown on the viewer and are correlated regardless of their origin, they are stored in different tables and different tasks are carried out according to the origin in question. In spite of this division, the data are all linked for the user and are handled in the same way, except that some of them have additional characteristics which will be useful when using the tool.

OSSIM stores the data that it receives in two different databases, depending on whether it is simply a case of storage or elements obtained as a result of correlation. We can then see that data are stored in databases known as snort and ossim. As a small example, part of what is inserted into each database is shown below

  1. snort: All the events that reach OSSIM are inserted into the snort database for storage and/or subsequent analysis. The use and adaptation of the snort database enables us to process all the events in the same way. All the events from any external device from which data are collected by the agents are thus split up into different parts and each part is inserted into a specific table. Specific OSSIM information, such as priority, reliability, asset values, risk, etc. is stored in the table snort.ossim.event. Any additional event data that the agent decides to send can also be stored in the special table snort.extra_data. We can see that there are also tables relating to ACID (such as snort.acid_event, where cached events are saved for example). However, these will shortly cease to be used and will become obsolete. FIXME
  2. ossim: The events which are still being correlated are inserted into this database, enabling them to be consulted (table ossim.backlog_event), in addition to those which have already been correlated and form part of an alarm (ossim.event), or the alarms themselves (ossim.alarm). The directives are also stored as they coincide with correlated events, enabling both to be linked (ossim.backlog). Events relating to MAC changes (ossim.host_mac), OS changes (ossim.host_os) and discovered services events (ossim.host_services) are also inserted.

The following types of events, as well as appearing on the general viewer with all the other events, can also be seen on the anomaly viewer, which is accessed from the web interface under Control Panel → Anomalies.

  • RRD events: These types of events are generated by ntop and are used as Monitors or Detectors to find modifications in traffic levels, the number of hosts connected or sending data, the number of emails sent over a certain period of time, the number of known hosts, etc. They are stored in the table ossim.rrd_anomalies
  • MAC, OS or service events.

The snort database is used to store events for historical and practical reasons, as OSSIM originally used snort as one of the entries for existing vulnerability events. Now all the events, whether or not they belong to snort, are stored in these tables.

Backup

The amount of data that OSSIM can store depends directly on the memory used in the database. In order to avoid saturation, OSSIM incorporates a tool which automatically saves oldest data onto a file so that the database, even if left unattended, will not increase in size to the point of becoming unmanageable. It is possible for these data to be retrieved at any time and reinserted into the database for analysis using the OSSIM interface.

In general, for medium-sized servers (2.5-3Ghz, 1-2Gb RAM) a database with around 500,000 - 700,000 events is considered acceptable for relative ease of use. You can vastly improve this with a commercial solution from the OSSIM developers.

Forwarding

OSSIM is able to forward data from the correlation servers to other servers and the frameworkd. Whether or not the servers are located on a higher level in the architecture or on the same logical level, the mechanism is applied equally in both cases. The only difference is the way in which the data is processed in the server to which it is forwarded.

With regard to the traffic between servers, there are many reasons why forwarding data from one server to another can be useful:

  • A server located directly in a sensor filters the events forwarded to it by the agent using a policy. The higher-level server is therefore only sent certain relevant events and not the rest, thereby reducing network traffic.
  • A server located on lower levels needs to forward correlated events to a higher-level server so this server only has to receive alarms which have already been generated.
  • We want the data to also be stored in a secondary server whose sole function will be to store events in its database as a backup copy or unchanged data.
  • … etc.

Data are not only forwarded to other servers, but also to the frameworkd. It should be taken into account that it is alarms that are forwarded to the frameworkd, not normal events. When these alarms reach the frameworkd, it checks its own policy; this would be the Policy → Responses tab on the interface.

We might thus, for example, want to integrate the generation of OSSIM events into a proprietary system for event collection located in the network infrastructure. By using this mechanism, we can forward the already correlated alarms by email (using the Actions) directly from the frameworkd .

In a distributed architecture, data forwarding is obviously not only important, but essential.

Date forwarding (in relation to events or alarms) occurs at the end of the whole process for the analysis and study of the event. In order for the data to be forwarded it is necessary for it to be authorised by the roles assigned to this event. Let us remind you that both the server role and the policy role will influence this point (the policy role taking precedence over the server role) and that for the forwarding to work it must be authorised by the role.

Alberto Roman Linacero 2008/01/28 18:49

 
documentation/serverd.txt · Last modified: 2009/11/28 21:59 (external edit)
 
Recent changes RSS feed Creative Commons License Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki