• No results found

CORRELATION 4.1 Introduction

4.7 Alert aggregation

A common problem among alert correlation systems is the huge amount of atomic alerts generated by an IDS and possibly by several IDSs. An IDS may trigger a large quantity of the same alerts at close time intervals that are related to the same security violation. Alert aggregation is proposed to remove duplicated alerts, e.g. the same alerts corresponding to the same signature description or attack class. A pre-defined window is used to determine whether two alerts are close enough to be aggregated into a single alert. In addition, our aggregation approach is based on graph reduction techniques that remove duplication in vertex set and migrating connecting edges to the nominated node.

126

The resulting graph will only contain alerts that are in fact representing different security events.

Definition 4.5: Given a cyclic directed graph G(V,E) where V is the vertex set and E is

the edges set, the in-degree of a vertex is the number of edges entering it. A vertex with zero in-degree values indicates a vertex with no edges entering it (e.g. root nodes).

In the attack graph, the node’s in-degree is the number of how many times the alert appears in caused alert group. The aggregation algorithm begins with defining the in- degree value of each node which is not aggregated in the graph. A list of zero in-degree values are identified to represent the first layer of the graph nodes; in other words, the alerts that are not caused by others. The zero in-degree list will contain groups of similar alerts occur at different times. Each group is treated as follows:

1- Nominate a master alert, which is the first alert in the temporally sorted list. 2- The aggregation process for the other alerts in the same group is based on:

- Similarity of signature IDs; this can be generalized to consider attack classes for a coarse granularity.

- Equality of source and destination IP addresses of the parties involved. - The time difference between the detection of the two alerts does not exceed a

defined value, e.g. 1 second.

3- If the above conditions are satisfied, the processed alert is added to the aggregated alerts corresponding to its master alert.

4- Change all the relationships between the aggregated alert and other alerts in the whole graph by replacing it with its master alert. Hence, the master alert will represent the aggregated alerts without losing the causal connections in the primary correlated collection.

127

5- Since all aggregated alerts are represented by a single alert, the corresponding time should cover the actual detection time for any further correlation. Thus, the start time of the master alert is the earliest time among the aggregated start times, and the end time is the latest one.

6- Remove the aggregated alert from the graph; however, the original information is not ignored as the graph can be disaggregated when required. Each master alert has its own counter of related aggregated alerts and graph layer.

After aggregating each group, the first graph layer, zero in-degree of all aggregated groups, is decremented by 1 to obtain the next layer. This is an opposite method to creating zero in-degree values. The second level will also have zero in-degree nodes and the same procedure is executed in an iterated fashion until all the graph nodes are treated. The algorithms shown in Figures 4.14-4.17 are describing the complete steps of the aggregation process.

128

Algorithm: AggregationAnalyzer Input: Temporary Correlated Alerts Output: Aggregated alerts collection

Declaration: Graph : NameValueCollection, Indegree: hashtable, aggregatedAlertList:ArrayList , allRawAlerts: Hashtable Methods:

Create a queue aggregatedZeroIndegreeAlertsCollection Get zeroIndegreeAlertsList

Layer← 1 // the first level in the graph , initial alerts not caused by other alerts aggregateZeroIndegreeAlertsId(zeroIndegreeAlertsList,

aggregatedZeroIndegreeAlertsCollection, Layer) if length [aggregatedZeroIndegreeAlertsCollection]>0

then

zeroIndegreeAlertsList←null

Count← length [aggregatedZeroIndegreeAlertsCollection]

for i←1 to Count

do // count denote how many groups have been aggregated

sameAlertType← DEQUEUE aggregatedZeroIndegreeAlertsCollection n←0 while AlertId=sameAlertType[n] do if NOT (Graph[AlertId].values=null) get Graph[AlertId].values for m←1 to length[Graph.values] do Indegree(values.AlertId) ← Indegree(values.AlertId)-1 if Indegree(values.AlertId)=0 then

INSERT (zeroIndegreeAlertList, values.AlertId) n←n+1 i←i+1 Layer←Layer+1 if length[aggregateZeroIndegreeAlertsId]>0 then aggregateZeroIndegreeAlertsId(zeroIndegreeAlertsList, aggregatedZeroIndegreeAlertsCollection, Layer)

129

Function:AggregateZeroIndegreeAlertsId (zeroIndegreeAlertsList,

aggregatedZeroIndegreeAlertsCollection, Layer)

if length[zeroIndegreeAlertsList]=1

then // in case of a single zero indegree node

aggregatedZeroIndegreeAlerts:Array[] INSERT (aggregatedZeroIndegreeAlerts,zeroIndegreeAlertsList[0]) ENQUEUE (aggregatedZeroIndegreeAlertsCollection, aggregatedZeroIndgreeAlerts) saveAggrAlert(zeroIndegreeAlertsList[0],1,Layer) UpdateRawAlertCollection(zeroIndegreeAlertsList[0], zeroIndegreeAlertsList[0]) else // in case of zero indegree contains more than one element for i←0 to length[zeroIndegreeAlertsList]

do

if zeroIndegreeAlertsList[i]<0 // has been already aggregated

continue

aggregatedZeroIndegreeAlerts:Array[]

INSERT (aggregatedZeroIndegreeAlerts, zeroIndegreeAlertsList[i]) IndexalertId← zeroIndegreeAlertsList[i]

appointedRawAlert: RawAlert // nominated as a master alert allRawAlerts←null

if allRawAlerts contains IndexalertId then

appointedRawAlert=allRawAlert[IndexalertId]

else // create a new one

appointedRawAlert← new RawAlert[IndexalertId] ADD (allRawAlerts, appointedRawAlert)

UpdateRawAlertCollection(appointedRawAlert,

appointedRawAlert)

rawCollectionCount: integer // internal loop

for j←i+1 to length[zeroIndegreeAlertsList] if zeroIndegreeAlertsList[j]<0

continue

130

// new alert in the same aggregated group indexRawAlert:RawAlert

internalAlertId :int

if allRawAlerts contains zeroIndegreeAlertsList[j] then

indexRawAlert←allRawAlerts[internalAlertId] else

indexRawAlert←new RawAlert[zeroIndegreeAlertsList[j]) ADD (allRawAlerts, indexRawAlert)

if appointedRawAlert.sigId =indexRawAlert.sigId AND appointedRawAlert.srcIPAddress=

indexRawAlert.srcIPAddress

AND appointedRawAlert.desIPAddress =

indexRawAlert. desIPAddress AND DIFF (appointedRawAlert.endTime,

indexRawAlert.endTime)≤1

then

INSERT (aggregatedZeroIndegreeAlerts, zeroIndegreeAlertsList[j]) // relationships will be shifted to the new master alert

if NOT(Graph.zeroIndegreeAlertsList[j])=null then

values← get Grpah.zeroIndegreeAlertsList[j] for k←0 to length[values]

do

INSERT (Graph.values, indexAlertId) // remove the aggregated alert from the Grpah

DELETE (Graph.values , zeroIndegreeAlertsList[k]) // add the aggregated alert to the aggregated list

INSERT (aggregatedAlertIdList, zeroIndegreeAlertsList[k]) // make this Id as a negative value in the zero indegree

zeroIndegreeAlertsList[k] ← zeroIndegreeAlertsList[k] × (-1) // increase the alert count for the associated master alert

rawCollectionCount ← rawCollectionCount+1

131

// the aggregated group of alerts takes the start time of the earliest alert // and the end time at the latest end time

if appointedRawAlert.startTime > indexRawAlert.startTime then appointedRawAlert.startTime← indexRawAlert.startTime if appointedRawAlert.endTime < indexRawAlert.endTime then appointedRawAlert.endTime← indexRawAlert.endTime // delete the post conditions of the aggregated alert

DELETE (postConditionTable, indexRawAlert) ENQUEUE (aggregatedZeroIndegreeAlertsCollection,

aggregatedZeroIndgreeAlerts)

Figure.4.17 Aggregation of zero in-degree alerts algorithm (continued).