1 /* Copyright (C) 2009 Trend Micro Inc.
4 * This program is a free software; you can redistribute it
5 * and/or modify it under the terms of the GNU General Public
6 * License (version 2) as published by the FSF - Free Software
11 #include "analysisd.h"
12 #include "eventinfo.h"
13 #include "os_regex/os_regex.h"
15 /* Global definitions */
22 /* Search last times a signature fired
23 * Will look for only that specific signature.
25 Eventinfo *Search_LastSids(Eventinfo *my_lf, RuleInfo *rule)
31 /* Set frequency to 0 */
32 rule->__frequency = 0;
34 /* Checking if sid search is valid */
35 if (!rule->sid_search) {
36 merror("%s: ERROR: No sid search.", ARGV0);
41 lf_node = OSList_GetLastNode(rule->sid_search);
45 first_lf = (Eventinfo *)lf_node->data;
48 lf = (Eventinfo *)lf_node->data;
50 /* If time is outside the timeframe, return */
51 if ((c_time - lf->time) > rule->timeframe) {
55 /* We avoid multiple triggers for the same rule
56 * or rules with a lower level.
58 else if (lf->matched >= rule->level) {
62 /* Check for same ID */
63 if (rule->context_opts & SAME_ID) {
64 if ((!lf->id) || (!my_lf->id)) {
68 if (strcmp(lf->id, my_lf->id) != 0) {
73 /* Check for repetitions from same src_ip */
74 if (rule->context_opts & SAME_SRCIP) {
75 if ((!lf->srcip) || (!my_lf->srcip)) {
79 if (strcmp(lf->srcip, my_lf->srcip) != 0) {
84 /* Grouping of additional data */
85 if (rule->alert_opts & SAME_EXTRAINFO) {
86 /* Check for same source port */
87 if (rule->context_opts & SAME_SRCPORT) {
88 if ((!lf->srcport) || (!my_lf->srcport)) {
92 if (strcmp(lf->srcport, my_lf->srcport) != 0) {
97 /* Check for same dst port */
98 if (rule->context_opts & SAME_DSTPORT) {
99 if ((!lf->dstport) || (!my_lf->dstport)) {
103 if (strcmp(lf->dstport, my_lf->dstport) != 0) {
108 /* Check for repetitions on user error */
109 if (rule->context_opts & SAME_USER) {
110 if ((!lf->dstuser) || (!my_lf->dstuser)) {
114 if (strcmp(lf->dstuser, my_lf->dstuser) != 0) {
119 /* Check for same location */
120 if (rule->context_opts & SAME_LOCATION) {
121 if (strcmp(lf->hostname, my_lf->hostname) != 0) {
126 /* Check for different URLs */
127 if (rule->context_opts & DIFFERENT_URL) {
128 if ((!lf->url) || (!my_lf->url)) {
132 if (strcmp(lf->url, my_lf->url) == 0) {
137 /* GEOIP version of check for repetitions from same src_ip */
138 if (rule->context_opts & DIFFERENT_SRCGEOIP) {
139 if ((!lf->srcgeoip) || (!my_lf->srcgeoip)) {
143 if (strcmp(lf->srcgeoip, my_lf->srcgeoip) == 0) {
151 /* We avoid multiple triggers for the same rule
152 * or rules with a lower level.
154 else if (lf->matched >= rule->level) {
160 /* Check if the number of matches worked */
161 if (rule->__frequency <= 10) {
162 rule->last_events[rule->__frequency]
164 rule->last_events[rule->__frequency + 1]
168 if (rule->__frequency < rule->frequency) {
175 /* If reached here, we matched */
176 my_lf->matched = rule->level;
177 lf->matched = rule->level;
178 first_lf->matched = rule->level;
182 } while ((lf_node = lf_node->prev) != NULL);
187 /* Search last times a group fired
188 * Will look for only that specific group on that rule.
190 Eventinfo *Search_LastGroups(Eventinfo *my_lf, RuleInfo *rule)
196 /* Set frequency to 0 */
197 rule->__frequency = 0;
199 /* Check if sid search is valid */
200 if (!rule->group_search) {
201 merror("%s: No group search!", ARGV0);
206 lf_node = OSList_GetLastNode(rule->group_search);
210 first_lf = (Eventinfo *)lf_node->data;
213 lf = (Eventinfo *)lf_node->data;
215 /* If time is outside the timeframe, return */
216 if ((c_time - lf->time) > rule->timeframe) {
220 /* We avoid multiple triggers for the same rule
221 * or rules with a lower level.
223 else if (lf->matched >= rule->level) {
227 /* Check for same ID */
228 if (rule->context_opts & SAME_ID) {
229 if ((!lf->id) || (!my_lf->id)) {
233 if (strcmp(lf->id, my_lf->id) != 0) {
238 /* Check for repetitions from same src_ip */
239 if (rule->context_opts & SAME_SRCIP) {
240 if ((!lf->srcip) || (!my_lf->srcip)) {
244 if (strcmp(lf->srcip, my_lf->srcip) != 0) {
249 /* Grouping of additional data */
250 if (rule->alert_opts & SAME_EXTRAINFO) {
251 /* Check for same source port */
252 if (rule->context_opts & SAME_SRCPORT) {
253 if ((!lf->srcport) || (!my_lf->srcport)) {
257 if (strcmp(lf->srcport, my_lf->srcport) != 0) {
262 /* Check for same dst port */
263 if (rule->context_opts & SAME_DSTPORT) {
264 if ((!lf->dstport) || (!my_lf->dstport)) {
268 if (strcmp(lf->dstport, my_lf->dstport) != 0) {
273 /* Check for repetitions on user error */
274 if (rule->context_opts & SAME_USER) {
275 if ((!lf->dstuser) || (!my_lf->dstuser)) {
279 if (strcmp(lf->dstuser, my_lf->dstuser) != 0) {
284 /* Check for same location */
285 if (rule->context_opts & SAME_LOCATION) {
286 if (strcmp(lf->hostname, my_lf->hostname) != 0) {
292 /* Check for different URLs */
293 if (rule->context_opts & DIFFERENT_URL) {
294 if ((!lf->url) || (!my_lf->url)) {
298 if (strcmp(lf->url, my_lf->url) == 0) {
304 /* Check for different from same srcgeoip */
305 if (rule->context_opts & DIFFERENT_SRCGEOIP) {
307 if ((!lf->srcgeoip) || (!my_lf->srcgeoip)) {
311 if (strcmp(lf->srcgeoip, my_lf->srcgeoip) == 0) {
318 /* We avoid multiple triggers for the same rule
319 * or rules with a lower level.
321 else if (lf->matched >= rule->level) {
326 /* Check if the number of matches worked */
327 if (rule->__frequency < rule->frequency) {
328 if (rule->__frequency <= 10) {
329 rule->last_events[rule->__frequency]
331 rule->last_events[rule->__frequency + 1]
340 /* If reached here, we matched */
341 my_lf->matched = rule->level;
342 lf->matched = rule->level;
343 first_lf->matched = rule->level;
348 } while ((lf_node = lf_node->prev) != NULL);
354 /* Look if any of the last events (inside the timeframe)
355 * match the specified rule
357 Eventinfo *Search_LastEvents(Eventinfo *my_lf, RuleInfo *rule)
359 EventNode *eventnode_pt;
365 eventnode_pt = OS_GetLastEvent();
371 /* Set frequency to 0 */
372 rule->__frequency = 0;
373 first_lf = (Eventinfo *)eventnode_pt->event;
375 /* Search all previous events */
377 lf = eventnode_pt->event;
379 /* If time is outside the timeframe, return */
380 if ((c_time - lf->time) > rule->timeframe) {
384 /* We avoid multiple triggers for the same rule
385 * or rules with a lower level.
387 else if (lf->matched >= rule->level) {
391 /* The category must be the same */
392 else if (lf->decoder_info->type != my_lf->decoder_info->type) {
396 /* If regex does not match, go to next */
397 if (rule->if_matched_regex) {
398 if (!OSRegex_Execute(lf->log, rule->if_matched_regex)) {
404 /* Check for repetitions on user error */
405 if (rule->context_opts & SAME_USER) {
406 if ((!lf->dstuser) || (!my_lf->dstuser)) {
410 if (strcmp(lf->dstuser, my_lf->dstuser) != 0) {
415 /* Check for same ID */
416 if (rule->context_opts & SAME_ID) {
417 if ((!lf->id) || (!my_lf->id)) {
421 if (strcmp(lf->id, my_lf->id) != 0) {
426 /* Check for repetitions from same src_ip */
427 if (rule->context_opts & SAME_SRCIP) {
428 if ((!lf->srcip) || (!my_lf->srcip)) {
432 if (strcmp(lf->srcip, my_lf->srcip) != 0) {
437 /* Check for different urls */
438 if (rule->context_opts & DIFFERENT_URL) {
439 if ((!lf->url) || (!my_lf->url)) {
443 if (strcmp(lf->url, my_lf->url) == 0) {
448 /* Check for different from same srcgeoip */
449 if (rule->context_opts & DIFFERENT_SRCGEOIP) {
451 if ((!lf->srcgeoip) || (!my_lf->srcgeoip)) {
455 if (strcmp(lf->srcgeoip, my_lf->srcgeoip) == 0) {
460 /* We avoid multiple triggers for the same rule
461 * or rules with a lower level.
463 else if (lf->matched >= rule->level) {
470 /* Check if the number of matches worked */
471 if (rule->__frequency < rule->frequency) {
472 if (rule->__frequency <= 10) {
473 rule->last_events[rule->__frequency]
475 rule->last_events[rule->__frequency + 1]
483 /* If reached here, we matched */
484 my_lf->matched = rule->level;
485 lf->matched = rule->level;
486 first_lf->matched = rule->level;
490 } while ((eventnode_pt = eventnode_pt->next) != NULL);
495 /* Zero the loginfo structure */
496 void Zero_Eventinfo(Eventinfo *lf)
501 lf->program_name = NULL;
519 lf->systemname = NULL;
529 lf->generated_rule = NULL;
530 lf->sid_node_to_delete = NULL;
531 lf->decoder_info = NULL_Decoder;
536 lf->md5_before = NULL;
537 lf->md5_after = NULL;
538 lf->sha1_before = NULL;
539 lf->sha1_after = NULL;
540 lf->size_before = NULL;
541 lf->size_after = NULL;
542 lf->owner_before = NULL;
543 lf->owner_after = NULL;
544 lf->gowner_before = NULL;
545 lf->gowner_after = NULL;
550 /* Free the loginfo structure */
551 void Free_Eventinfo(Eventinfo *lf)
554 merror("%s: Trying to free NULL event. Inconsistent..", ARGV0);
617 if (lf->systemname) {
618 free(lf->systemname);
624 if (lf->md5_before) {
625 free(lf->md5_before);
630 if (lf->sha1_before) {
631 free(lf->sha1_before);
633 if (lf->sha1_after) {
634 free(lf->sha1_after);
636 if (lf->size_before) {
637 free(lf->size_before);
639 if (lf->size_after) {
640 free(lf->size_after);
642 if (lf->owner_before) {
643 free(lf->owner_before);
645 if (lf->owner_after) {
646 free(lf->owner_after);
648 if (lf->gowner_before) {
649 free(lf->gowner_before);
651 if (lf->gowner_after) {
652 free(lf->gowner_after);
655 /* Free node to delete */
656 if (lf->sid_node_to_delete) {
657 OSList_DeleteThisNode(lf->generated_rule->sid_prev_matched,
658 lf->sid_node_to_delete);
659 } else if (lf->generated_rule && lf->generated_rule->group_prev_matched) {
662 while (i < lf->generated_rule->group_prev_matched_sz) {
663 OSList_DeleteOldestNode(lf->generated_rule->group_prev_matched[i]);
668 /* We dont need to free: