public void Enqueue(SecurityEvent securityEvent) { FireQueueItem item = new FireQueueItem(securityEvent.time, securityEvent.srcIP, securityEvent.srcPort, securityEvent.destIP, securityEvent.destPort); // Remove first item if queue is full if (Queue.Count == maxSize) { logger.Trace("{0} Dequeue item (>maxSize): {1}", Assistant.GetPadding(), Queue.First().ToString()); Queue.Dequeue(); } Queue.Enqueue(item); logger.Trace("{0} Enqueue item: {1}", Assistant.GetPadding(), item.ToString()); // Remove first items if the time difference between the first and last item > timeFrame while (true) { if ((item.time - Queue.First().time).TotalSeconds > timeFrame) { logger.Trace("{0} Dequeue item (>timeFrame): {1}", Assistant.GetPadding(), Queue.First().ToString()); Queue.Dequeue(); } else { break; } } ShowQueueBrief(); }
public void MatchRule(SecurityEvent securityEvent, Rule rule) { // Raise an event onAlertReceived(securityEvent, rule); // If rule is queue tracked, increase a counter if (fireDictionary.ContainsKey(rule.ID)) { logger.Trace(Assistant.GetPadding() + " Matched rule is queue tracked"); fireDictionary[rule.ID].Enqueue(securityEvent); } // Save statistics if (matchList.ContainsKey(rule.ID)) { matchList[rule.ID]++; if (matchList[rule.ID] > maxCount) { matchList[rule.ID] = maxCount; } } else { matchList.Add(rule.ID, 1); } }
public void ApplyRule(SecurityEvent securityEvent, Rule rule) { string padding = Assistant.GetPadding(); logger.Trace("{0}Check rule {1} - {2}", padding, rule.ID, rule.description); if (CheckIfMatched(ref securityEvent, ref rule) == true) { // Perform actions when the rule is triggered MatchRule(securityEvent, rule); // Process rules recursively if (rule.HasChidren()) { logger.Trace(padding + " Check the child rules"); foreach (int item in rule.children) { ApplyRule(securityEvent, ruleList[item]); } logger.Trace(padding + " Check the child rules: OK"); } } else { logger.Trace("{0}Rule {1} not matched", padding, rule.ID); } logger.Trace("{0}Check rule {1}: OK", padding, rule.ID); }
public void ProcessMessage(SecurityEvent securityEvent) { // First step of recursion // Apply only rules "without parents" foreach (KeyValuePair <int, Rule> ruleKVP in ruleList) { Rule rule = ruleKVP.Value; if (!rule.HasParent()) { ApplyRule(securityEvent, rule); } } }
public bool CheckIfMatched(SecurityEvent securityEvent, Rule rule) { // Scan from the end of the queue // Increase the counter while the event is within a timeframe // If the counter has reached rule.frequency, return true logger.Trace(Assistant.GetPadding() + "QueueDictionary.CheckIfMatched start"); int counter = 0; int counterSameSourceIP = 0; for (int i = Queue.Count - 1; i >= 0; i--) { // Check whether an event is within a timeframe if ((securityEvent.time - Queue.ElementAt(i).time).TotalSeconds > rule.timeFrame) { break; } counter++; logger.Trace("{0} counter++ => counter=[{1}]", Assistant.GetPadding(), counter); // Check if the IP addresses are the same if (rule.sameSourceIP) { if (securityEvent.srcIP.Equals(Queue.ElementAt(i).srcIP)) { counterSameSourceIP++; logger.Trace("{0} counterSameSourceIP++ => counterSameSourceIP=[{1}]", Assistant.GetPadding(), counterSameSourceIP); } if (counterSameSourceIP >= rule.frequency) { return(true); } } // Check the frequency if (!rule.sameSourceIP) { if (counter >= rule.frequency) { return(true); } } } return(false); }
// Callback for message receive public static void handleMessage(byte[] utfMessage) { try { var message = Encoding.UTF8.GetString(utfMessage); if (message.Contains("ApacheConnector:")) { SecurityEvent securityEvent = new SecurityEvent(message, LogMessageType.ApacheLog); logger.Trace(securityEvent.ToString()); // Process received message engine.ProcessMessage(securityEvent); } } catch (Exception ex) { logger.Warn("HandleMessage exception: " + ex.ToString()); } }
// Callback for alert receive public static void handleAlert(SecurityEvent securityEvent, Rule rule) { logger.Trace("{0} Rule {1} matched", Assistant.GetPadding(), rule.ID); logger.Trace("{0} ALERT: LEVEL {1} - {2}", Assistant.GetPadding(), rule.level, rule.description); Console.WriteLine("ALERT: LEVEL {1} - {2}", Assistant.GetPadding(), rule.level, rule.description); try { if (translateAlertsToDB) { DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); long timeStamp = (long)(DateTime.UtcNow - UnixEpoch).TotalSeconds; // http://mongodb.github.io/mongo-csharp-driver/2.2/getting_started/quick_tour/ var client = new MongoClient(MongoDBConnectionString); var dataBase = client.GetDatabase("AirSIEM"); var collection = dataBase.GetCollection <BsonDocument>("alerts"); var alert = new BsonDocument { { "matching_rule_SID", rule.ID }, { "message", rule.description }, { "src_IP", securityEvent.srcIP }, { "src_port", securityEvent.srcPort }, { "dest_IP", securityEvent.destIP }, { "dest_port", securityEvent.destPort }, { "log_string", securityEvent.logString }, { "level", rule.level }, { "timestamp", DateTime.Now.ToString("HH:mm:ss") }, { "rule_chain", new BsonArray(new[] { 12345, 1234, 123 }) } }; collection.InsertOne(alert); } } catch (Exception ex) { logger.Warn("HandleAlert exception: " + ex.ToString()); } }
public bool CheckIfMatched(ref SecurityEvent securityEvent, ref Rule rule) { string padding = Assistant.GetPadding(); // Check <if_sid> element => scan dependencies and matchList if (rule.ifSID != 0) { logger.Trace("{0}Check <if_sid>{1}</if_sid>", padding, rule.ifSID); if (!matchList.ContainsKey(rule.ifSID)) { return(false); } if (matchList[rule.ifSID] == 0) { return(false); } } // Check <same_source_ip> element if (!rule.sourceIP.Equals("")) { logger.Trace(padding + " Check <same_source_ip/>"); if (!securityEvent.srcIP.Equals(rule.sourceIP)) { return(false); } } // Check <match> element if (!rule.match.Equals("")) { logger.Trace("{0}Check <match>{1}</match>", padding, rule.match); // Process logical OR bool check = false; string[] parts = rule.match.Split(new Char[] { '|' }, StringSplitOptions.RemoveEmptyEntries); foreach (string part in parts) { if (securityEvent.message.IndexOf(part, StringComparison.OrdinalIgnoreCase) >= 0) { check = true; break; } } if (!check) { return(false); } } // Check <if_matched_sid> element if (rule.ifMatchedSID != 0) { logger.Trace("{0}Check <if_matched_sid>{1}</if_matched_sid>", padding, rule.ifMatchedSID); if (matchList.ContainsKey(rule.ifMatchedSID)) { if (matchList[rule.ifMatchedSID] == 0) { return(false); } // Scan FireQueue if (!fireDictionary.ContainsKey(rule.ifMatchedSID)) { return(false); } if (fireDictionary[rule.ifMatchedSID].CheckIfMatched(securityEvent, rule)) { logger.Trace("{0} Rule {1} QueueDictionary.CheckIfMatched == TRUE", padding, rule.ifMatchedSID); } else { logger.Trace("{0} Rule {1} QueueDictionary.CheckIfMatched == FALSE", padding, rule.ifMatchedSID); return(false); } } } // Rule matched return(true); }