new upstream release (3.3.0); modify package compatibility for Stretch
[ossec-hids.git] / src / analysisd / eventinfo.c
1 /* Copyright (C) 2009 Trend Micro Inc.
2  * All rights reserved.
3  *
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
7  * Foundation.
8  */
9
10 #include "config.h"
11 #include "analysisd.h"
12 #include "eventinfo.h"
13 #include "os_regex/os_regex.h"
14
15 /* Global definitions */
16 #ifdef TESTRULE
17 int full_output;
18 int alert_only;
19 #endif
20
21
22 /* Search last times a signature fired
23  * Will look for only that specific signature.
24  */
25 Eventinfo *Search_LastSids(Eventinfo *my_lf, RuleInfo *rule)
26 {
27     Eventinfo *lf;
28     Eventinfo *first_lf;
29     OSListNode *lf_node;
30
31     /* Set frequency to 0 */
32     rule->__frequency = 0;
33
34     /* Checking if sid search is valid */
35     if (!rule->sid_search) {
36         merror("%s: ERROR: No sid search.", ARGV0);
37         return (NULL);
38     }
39
40     /* Get last node */
41     lf_node = OSList_GetLastNode(rule->sid_search);
42     if (!lf_node) {
43         return (NULL);
44     }
45     first_lf = (Eventinfo *)lf_node->data;
46
47     do {
48         lf = (Eventinfo *)lf_node->data;
49
50         /* If time is outside the timeframe, return */
51         if ((c_time - lf->time) > rule->timeframe) {
52             return (NULL);
53         }
54
55         /* We avoid multiple triggers for the same rule
56          * or rules with a lower level.
57          */
58         else if (lf->matched >= rule->level) {
59             return (NULL);
60         }
61
62         /* Check for same ID */
63         if (rule->context_opts & SAME_ID) {
64             if ((!lf->id) || (!my_lf->id)) {
65                 continue;
66             }
67
68             if (strcmp(lf->id, my_lf->id) != 0) {
69                 continue;
70             }
71         }
72
73         /* Check for repetitions from same src_ip */
74         if (rule->context_opts & SAME_SRCIP) {
75             if ((!lf->srcip) || (!my_lf->srcip)) {
76                 continue;
77             }
78
79             if (strcmp(lf->srcip, my_lf->srcip) != 0) {
80                 continue;
81             }
82         }
83
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)) {
89                     continue;
90                 }
91
92                 if (strcmp(lf->srcport, my_lf->srcport) != 0) {
93                     continue;
94                 }
95             }
96
97             /* Check for same dst port */
98             if (rule->context_opts & SAME_DSTPORT) {
99                 if ((!lf->dstport) || (!my_lf->dstport)) {
100                     continue;
101                 }
102
103                 if (strcmp(lf->dstport, my_lf->dstport) != 0) {
104                     continue;
105                 }
106             }
107
108             /* Check for repetitions on user error */
109             if (rule->context_opts & SAME_USER) {
110                 if ((!lf->dstuser) || (!my_lf->dstuser)) {
111                     continue;
112                 }
113
114                 if (strcmp(lf->dstuser, my_lf->dstuser) != 0) {
115                     continue;
116                 }
117             }
118
119             /* Check for same location */
120             if (rule->context_opts & SAME_LOCATION) {
121                 if (strcmp(lf->hostname, my_lf->hostname) != 0) {
122                     continue;
123                 }
124             }
125
126             /* Check for different URLs */
127             if (rule->context_opts & DIFFERENT_URL) {
128                 if ((!lf->url) || (!my_lf->url)) {
129                     continue;
130                 }
131
132                 if (strcmp(lf->url, my_lf->url) == 0) {
133                     continue;
134                 }
135             }
136
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)) {
140                     continue;
141                 }
142
143                 if (strcmp(lf->srcgeoip, my_lf->srcgeoip) == 0) {
144                     continue;
145                 }
146             }
147
148
149         }
150
151         /* We avoid multiple triggers for the same rule
152          * or rules with a lower level.
153          */
154         else if (lf->matched >= rule->level) {
155             return (NULL);
156         }
157
158
159
160         /* Check if the number of matches worked */
161         if (rule->__frequency <= 10) {
162             rule->last_events[rule->__frequency]
163                 = lf->full_log;
164             rule->last_events[rule->__frequency + 1]
165                 = NULL;
166         }
167
168         if (rule->__frequency < rule->frequency) {
169             rule->__frequency++;
170             continue;
171         }
172         rule->__frequency++;
173
174
175         /* If reached here, we matched */
176         my_lf->matched = rule->level;
177         lf->matched = rule->level;
178         first_lf->matched = rule->level;
179
180         return (lf);
181
182     } while ((lf_node = lf_node->prev) != NULL);
183
184     return (NULL);
185 }
186
187 /* Search last times a group fired
188  * Will look for only that specific group on that rule.
189  */
190 Eventinfo *Search_LastGroups(Eventinfo *my_lf, RuleInfo *rule)
191 {
192     Eventinfo *lf;
193     Eventinfo *first_lf;
194     OSListNode *lf_node;
195
196     /* Set frequency to 0 */
197     rule->__frequency = 0;
198
199     /* Check if sid search is valid */
200     if (!rule->group_search) {
201         merror("%s: No group search!", ARGV0);
202         return (NULL);
203     }
204
205     /* Get last node */
206     lf_node = OSList_GetLastNode(rule->group_search);
207     if (!lf_node) {
208         return (NULL);
209     }
210     first_lf = (Eventinfo *)lf_node->data;
211
212     do {
213         lf = (Eventinfo *)lf_node->data;
214
215         /* If time is outside the timeframe, return */
216         if ((c_time - lf->time) > rule->timeframe) {
217             return (NULL);
218         }
219
220         /* We avoid multiple triggers for the same rule
221          * or rules with a lower level.
222          */
223         else if (lf->matched >= rule->level) {
224             return (NULL);
225         }
226
227         /* Check for same ID */
228         if (rule->context_opts & SAME_ID) {
229             if ((!lf->id) || (!my_lf->id)) {
230                 continue;
231             }
232
233             if (strcmp(lf->id, my_lf->id) != 0) {
234                 continue;
235             }
236         }
237
238         /* Check for repetitions from same src_ip */
239         if (rule->context_opts & SAME_SRCIP) {
240             if ((!lf->srcip) || (!my_lf->srcip)) {
241                 continue;
242             }
243
244             if (strcmp(lf->srcip, my_lf->srcip) != 0) {
245                 continue;
246             }
247         }
248
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)) {
254                     continue;
255                 }
256
257                 if (strcmp(lf->srcport, my_lf->srcport) != 0) {
258                     continue;
259                 }
260             }
261
262             /* Check for same dst port */
263             if (rule->context_opts & SAME_DSTPORT) {
264                 if ((!lf->dstport) || (!my_lf->dstport)) {
265                     continue;
266                 }
267
268                 if (strcmp(lf->dstport, my_lf->dstport) != 0) {
269                     continue;
270                 }
271             }
272
273             /* Check for repetitions on user error */
274             if (rule->context_opts & SAME_USER) {
275                 if ((!lf->dstuser) || (!my_lf->dstuser)) {
276                     continue;
277                 }
278
279                 if (strcmp(lf->dstuser, my_lf->dstuser) != 0) {
280                     continue;
281                 }
282             }
283
284             /* Check for same location */
285             if (rule->context_opts & SAME_LOCATION) {
286                 if (strcmp(lf->hostname, my_lf->hostname) != 0) {
287                     continue;
288                 }
289             }
290
291
292             /* Check for different URLs */
293             if (rule->context_opts & DIFFERENT_URL) {
294                 if ((!lf->url) || (!my_lf->url)) {
295                     continue;
296                 }
297
298                 if (strcmp(lf->url, my_lf->url) == 0) {
299                     continue;
300                 }
301             }
302
303
304             /* Check for different from same srcgeoip */
305             if (rule->context_opts & DIFFERENT_SRCGEOIP) {
306
307                 if ((!lf->srcgeoip) || (!my_lf->srcgeoip)) {
308                     continue;
309                 }
310
311                 if (strcmp(lf->srcgeoip, my_lf->srcgeoip) == 0) {
312                     continue;
313                 }
314             }
315
316
317         }
318         /* We avoid multiple triggers for the same rule
319          * or rules with a lower level.
320          */
321         else if (lf->matched >= rule->level) {
322             return (NULL);
323         }
324
325
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]
330                     = lf->full_log;
331                 rule->last_events[rule->__frequency + 1]
332                     = NULL;
333             }
334
335             rule->__frequency++;
336             continue;
337         }
338
339
340         /* If reached here, we matched */
341         my_lf->matched = rule->level;
342         lf->matched = rule->level;
343         first_lf->matched = rule->level;
344
345         return (lf);
346
347
348     } while ((lf_node = lf_node->prev) != NULL);
349
350     return (NULL);
351 }
352
353
354 /* Look if any of the last events (inside the timeframe)
355  * match the specified rule
356  */
357 Eventinfo *Search_LastEvents(Eventinfo *my_lf, RuleInfo *rule)
358 {
359     EventNode *eventnode_pt;
360     Eventinfo *lf;
361     Eventinfo *first_lf;
362
363
364     /* Last events */
365     eventnode_pt = OS_GetLastEvent();
366     if (!eventnode_pt) {
367         /* Nothing found */
368         return (NULL);
369     }
370
371     /* Set frequency to 0 */
372     rule->__frequency = 0;
373     first_lf = (Eventinfo *)eventnode_pt->event;
374
375     /* Search all previous events */
376     do {
377         lf = eventnode_pt->event;
378
379         /* If time is outside the timeframe, return */
380         if ((c_time - lf->time) > rule->timeframe) {
381             return (NULL);
382         }
383
384         /* We avoid multiple triggers for the same rule
385          * or rules with a lower level.
386          */
387         else if (lf->matched >= rule->level) {
388             return (NULL);
389         }
390
391         /* The category must be the same */
392         else if (lf->decoder_info->type != my_lf->decoder_info->type) {
393             continue;
394         }
395
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)) {
399                 /* Didn't match */
400                 continue;
401             }
402         }
403
404         /* Check for repetitions on user error */
405         if (rule->context_opts & SAME_USER) {
406             if ((!lf->dstuser) || (!my_lf->dstuser)) {
407                 continue;
408             }
409
410             if (strcmp(lf->dstuser, my_lf->dstuser) != 0) {
411                 continue;
412             }
413         }
414
415         /* Check for same ID */
416         if (rule->context_opts & SAME_ID) {
417             if ((!lf->id) || (!my_lf->id)) {
418                 continue;
419             }
420
421             if (strcmp(lf->id, my_lf->id) != 0) {
422                 continue;
423             }
424         }
425
426         /* Check for repetitions from same src_ip */
427         if (rule->context_opts & SAME_SRCIP) {
428             if ((!lf->srcip) || (!my_lf->srcip)) {
429                 continue;
430             }
431
432             if (strcmp(lf->srcip, my_lf->srcip) != 0) {
433                 continue;
434             }
435         }
436
437         /* Check for different urls */
438         if (rule->context_opts & DIFFERENT_URL) {
439             if ((!lf->url) || (!my_lf->url)) {
440                 continue;
441             }
442
443             if (strcmp(lf->url, my_lf->url) == 0) {
444                 continue;
445             }
446         }
447
448         /* Check for different from same srcgeoip */
449         if (rule->context_opts & DIFFERENT_SRCGEOIP) {
450
451             if ((!lf->srcgeoip) || (!my_lf->srcgeoip)) {
452                 continue;
453             }
454
455             if (strcmp(lf->srcgeoip, my_lf->srcgeoip) == 0) {
456                 continue;
457             }
458         }
459
460         /* We avoid multiple triggers for the same rule
461          * or rules with a lower level.
462          */
463         else if (lf->matched >= rule->level) {
464             return (NULL);
465         }
466
467
468
469
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]
474                     = lf->full_log;
475                 rule->last_events[rule->__frequency + 1]
476                     = NULL;
477             }
478
479             rule->__frequency++;
480             continue;
481         }
482
483         /* If reached here, we matched */
484         my_lf->matched = rule->level;
485         lf->matched = rule->level;
486         first_lf->matched = rule->level;
487
488         return (lf);
489
490     } while ((eventnode_pt = eventnode_pt->next) != NULL);
491
492     return (NULL);
493 }
494
495 /* Zero the loginfo structure */
496 void Zero_Eventinfo(Eventinfo *lf)
497 {
498     lf->log = NULL;
499     lf->full_log = NULL;
500     lf->hostname = NULL;
501     lf->program_name = NULL;
502     lf->location = NULL;
503
504     lf->srcip = NULL;
505     lf->srcgeoip = NULL;
506     lf->dstip = NULL;
507     lf->dstgeoip = NULL;
508     lf->srcport = NULL;
509     lf->dstport = NULL;
510     lf->protocol = NULL;
511     lf->action = NULL;
512     lf->srcuser = NULL;
513     lf->dstuser = NULL;
514     lf->id = NULL;
515     lf->status = NULL;
516     lf->command = NULL;
517     lf->url = NULL;
518     lf->data = NULL;
519     lf->systemname = NULL;
520
521     lf->time = 0;
522     lf->matched = 0;
523
524     lf->year = 0;
525     lf->mon[3] = '\0';
526     lf->hour[9] = '\0';
527     lf->day = 0;
528
529     lf->generated_rule = NULL;
530     lf->sid_node_to_delete = NULL;
531     lf->decoder_info = NULL_Decoder;
532
533     lf->filename = NULL;
534     lf->perm_before = 0;
535     lf->perm_after = 0;
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;
546
547     return;
548 }
549
550 /* Free the loginfo structure */
551 void Free_Eventinfo(Eventinfo *lf)
552 {
553     if (!lf) {
554         merror("%s: Trying to free NULL event. Inconsistent..", ARGV0);
555         return;
556     }
557
558     if (lf->full_log) {
559         free(lf->full_log);
560     }
561     if (lf->location) {
562         free(lf->location);
563     }
564
565     if (lf->srcip) {
566         free(lf->srcip);
567     }
568
569     if(lf->srcgeoip) {
570         free(lf->srcgeoip);
571         lf->srcgeoip = NULL;
572     }
573
574     if (lf->dstip) {
575         free(lf->dstip);
576     }
577
578     if(lf->dstgeoip) {
579         free(lf->dstgeoip);
580         lf->dstgeoip = NULL;
581     }
582
583     if (lf->srcport) {
584         free(lf->srcport);
585     }
586     if (lf->dstport) {
587         free(lf->dstport);
588     }
589     if (lf->protocol) {
590         free(lf->protocol);
591     }
592     if (lf->action) {
593         free(lf->action);
594     }
595     if (lf->status) {
596         free(lf->status);
597     }
598     if (lf->srcuser) {
599         free(lf->srcuser);
600     }
601     if (lf->dstuser) {
602         free(lf->dstuser);
603     }
604     if (lf->id) {
605         free(lf->id);
606     }
607     if (lf->command) {
608         free(lf->command);
609     }
610     if (lf->url) {
611         free(lf->url);
612     }
613
614     if (lf->data) {
615         free(lf->data);
616     }
617     if (lf->systemname) {
618         free(lf->systemname);
619     }
620
621     if (lf->filename) {
622         free(lf->filename);
623     }
624     if (lf->md5_before) {
625         free(lf->md5_before);
626     }
627     if (lf->md5_after) {
628         free(lf->md5_after);
629     }
630     if (lf->sha1_before) {
631         free(lf->sha1_before);
632     }
633     if (lf->sha1_after) {
634         free(lf->sha1_after);
635     }
636     if (lf->size_before) {
637         free(lf->size_before);
638     }
639     if (lf->size_after) {
640         free(lf->size_after);
641     }
642     if (lf->owner_before) {
643         free(lf->owner_before);
644     }
645     if (lf->owner_after) {
646         free(lf->owner_after);
647     }
648     if (lf->gowner_before) {
649         free(lf->gowner_before);
650     }
651     if (lf->gowner_after) {
652         free(lf->gowner_after);
653     }
654
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) {
660         unsigned int i = 0;
661
662         while (i < lf->generated_rule->group_prev_matched_sz) {
663             OSList_DeleteOldestNode(lf->generated_rule->group_prev_matched[i]);
664             i++;
665         }
666     }
667
668     /* We dont need to free:
669      * fts
670      * comment
671      */
672     free(lf);
673     lf = NULL;
674
675     return;
676 }
677