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:
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.
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:
A server also may send data to other places, like:
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:
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:
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:
To keep all events normalized, OSSIM defines two important values for each one:
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.
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.
What's the “Role”? Role specifies the behavior of a specific event, in a specific server. You can define two possible roles:
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:
| Role | Description | Limitations |
|---|---|---|
| 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 Events | Forward events to an upper server, or to another on the same level | |
| Forward Alarms | Forward 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.
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:
<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 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.
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
| Value | Meaning |
|---|---|
| 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 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 done | Other info needed apart from event data |
|---|---|---|
| Cross Correlation | Between events and destination vulnerabilities | Yes |
| Inventory Correlation | Between events and destination characteristics | Yes |
| Logical Correlation | Between events from different sources | No |
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 Correlation | Data accessed or stored in DB |
|---|---|
| Cross Correlation | Access to vulnerabilities discovered |
| Inventory Correlation | Access to inventory |
| Logical Correlation | Stored data from each event into backlog |
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:
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:
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
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.
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:
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 type | Match | Doesn't match | Not enough data to decide | Example |
|---|---|---|---|---|
| OS | +1 | 0 | Remains Untouched | “OpenBSD” |
| Port | Remains Untouched | 0 | Remains Untouched | “80” |
| Protocol | Remains Untouched | 0 | Remains Untouched | “TCP” |
| Service | +2 | Remains Untouched | Remains Untouched | “Apache” |
| Version | 9 | Remains Untouched | Remains 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.
If the reliability of the event once the cross correlation is done is >=1, an alarm is generated.
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:
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.
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.
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.
: 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
: 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 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:
So there are three phases in Risk Assessment:
Those three steps are executed in order, and it works as follows:
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.
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:
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:
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.
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:
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:
| Data | Max | Min |
|---|---|---|
| Priority | 5 | 0 |
| Reliability | 10 | 0 |
| Asset | 5 | 0 |
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 is a powerful tool built into OSSIM. We basically have two types of recursion:
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:
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

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.
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.
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.
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:
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