/* @(#) $Id: eventinfo.c,v 1.38 2007/07/20 00:19:24 dcid Exp $ */ /* Copyright (C) 2003-2007 Daniel B. Cid * All rights reserved. * * This program is a free software; you can redistribute it * and/or modify it under the terms of the GNU General Public * License (version 3) as published by the FSF - Free Software * Foundation. * * License details at the LICENSE file included with OSSEC or * online at: http://www.ossec.net/en/licensing.html */ /* Part of the OSSEC. * Available at http://www.ossec.net */ #include "config.h" #include "analysisd.h" #include "eventinfo.h" #include "os_regex/os_regex.h" /* Search last times a signature fired * Will look for only that specific signature. */ Eventinfo *Search_LastSids(Eventinfo *my_lf, RuleInfo *currently_rule) { Eventinfo *lf; Eventinfo *first_lf; OSListNode *lf_node; /* Setting frequency to 0 */ currently_rule->__frequency = 0; /* checking sid search is valid */ if(!currently_rule->sid_search) { merror("%s: No sid search!! XXX", ARGV0); } /* Getting last node */ lf_node = OSList_GetLastNode(currently_rule->sid_search); if(!lf_node) { return(NULL); } first_lf = (Eventinfo *)lf_node->data; do { lf = (Eventinfo *)lf_node->data; /* If time is outside the timeframe, return */ if((c_time - lf->time) > currently_rule->timeframe) { return(NULL); } /* We avoid multiple triggers for the same rule * or rules with a lower level. */ else if(lf->matched >= currently_rule->level) { return(NULL); } /* Checking for same id */ if(currently_rule->context_opts & SAME_ID) { if((!lf->id) || (!my_lf->id)) continue; if(strcmp(lf->id,my_lf->id) != 0) continue; } /* Checking for repetitions from same src_ip */ if(currently_rule->context_opts & SAME_SRCIP) { if((!lf->srcip)||(!my_lf->srcip)) continue; if(strcmp(lf->srcip,my_lf->srcip) != 0) continue; } /* Grouping of additional data */ if(currently_rule->alert_opts & SAME_EXTRAINFO) { /* Checking for same source port */ if(currently_rule->context_opts & SAME_SRCPORT) { if((!lf->srcport)||(!my_lf->srcport)) continue; if(strcmp(lf->srcport, my_lf->srcport) != 0) continue; } /* Checking for same dst port */ if(currently_rule->context_opts & SAME_DSTPORT) { if((!lf->dstport)||(!my_lf->dstport)) continue; if(strcmp(lf->dstport, my_lf->dstport) != 0) continue; } /* Checking for repetitions on user error */ if(currently_rule->context_opts & SAME_USER) { if((!lf->user)||(!my_lf->user)) continue; if(strcmp(lf->user,my_lf->user) != 0) continue; } /* Checking for same location */ if(currently_rule->context_opts & SAME_LOCATION) { if(strcmp(lf->hostname, my_lf->hostname) != 0) continue; } /* Checking for different urls */ if(currently_rule->context_opts & DIFFERENT_URL) { if((!lf->url)||(!my_lf->url)) { continue; } if(strcmp(lf->url, my_lf->url) == 0) { continue; } } } /* Checking if the number of matches worked */ if(currently_rule->__frequency < currently_rule->frequency) { if(currently_rule->__frequency <= 10) { currently_rule->last_events[currently_rule->__frequency] = lf->full_log; currently_rule->last_events[currently_rule->__frequency+1] = NULL; } currently_rule->__frequency++; continue; } /* If reached here, we matched */ my_lf->matched = currently_rule->level; lf->matched = currently_rule->level; first_lf->matched = currently_rule->level; return(lf); }while((lf_node = lf_node->prev) != NULL); return(NULL); } /* Search last times a group fired * Will look for only that specific group on that rule. */ Eventinfo *Search_LastGroups(Eventinfo *my_lf, RuleInfo *currently_rule) { Eventinfo *lf; Eventinfo *first_lf; OSListNode *lf_node; /* Setting frequency to 0 */ currently_rule->__frequency = 0; /* checking sid search is valid */ if(!currently_rule->group_search) { merror("%s: No group search!! XXX", ARGV0); } /* Getting last node */ lf_node = OSList_GetLastNode(currently_rule->group_search); if(!lf_node) { return(NULL); } first_lf = (Eventinfo *)lf_node->data; do { lf = (Eventinfo *)lf_node->data; /* If time is outside the timeframe, return */ if((c_time - lf->time) > currently_rule->timeframe) { return(NULL); } /* We avoid multiple triggers for the same rule * or rules with a lower level. */ else if(lf->matched >= currently_rule->level) { return(NULL); } /* Checking for same id */ if(currently_rule->context_opts & SAME_ID) { if((!lf->id) || (!my_lf->id)) continue; if(strcmp(lf->id,my_lf->id) != 0) continue; } /* Checking for repetitions from same src_ip */ if(currently_rule->context_opts & SAME_SRCIP) { if((!lf->srcip)||(!my_lf->srcip)) continue; if(strcmp(lf->srcip,my_lf->srcip) != 0) continue; } /* Grouping of additional data */ if(currently_rule->alert_opts & SAME_EXTRAINFO) { /* Checking for same source port */ if(currently_rule->context_opts & SAME_SRCPORT) { if((!lf->srcport)||(!my_lf->srcport)) continue; if(strcmp(lf->srcport, my_lf->srcport) != 0) continue; } /* Checking for same dst port */ if(currently_rule->context_opts & SAME_DSTPORT) { if((!lf->dstport)||(!my_lf->dstport)) continue; if(strcmp(lf->dstport, my_lf->dstport) != 0) continue; } /* Checking for repetitions on user error */ if(currently_rule->context_opts & SAME_USER) { if((!lf->user)||(!my_lf->user)) continue; if(strcmp(lf->user,my_lf->user) != 0) continue; } /* Checking for same location */ if(currently_rule->context_opts & SAME_LOCATION) { if(strcmp(lf->hostname, my_lf->hostname) != 0) continue; } /* Checking for different urls */ if(currently_rule->context_opts & DIFFERENT_URL) { if((!lf->url)||(!my_lf->url)) { continue; } if(strcmp(lf->url, my_lf->url) == 0) { continue; } } } /* Checking if the number of matches worked */ if(currently_rule->__frequency < currently_rule->frequency) { if(currently_rule->__frequency <= 10) { currently_rule->last_events[currently_rule->__frequency] = lf->full_log; currently_rule->last_events[currently_rule->__frequency+1] = NULL; } currently_rule->__frequency++; continue; } /* If reached here, we matched */ my_lf->matched = currently_rule->level; lf->matched = currently_rule->level; first_lf->matched = currently_rule->level; return(lf); }while((lf_node = lf_node->prev) != NULL); return(NULL); } /* Search LastEvents. * Will look if any of the last events (inside the timeframe) * match the specified rule. */ Eventinfo *Search_LastEvents(Eventinfo *my_lf, RuleInfo *currently_rule) { EventNode *eventnode_pt; Eventinfo *lf; Eventinfo *first_lf; merror("XXXX : remove me!"); /* Last events */ eventnode_pt = OS_GetLastEvent(); if(!eventnode_pt) { /* Nothing found */ return(NULL); } /* Setting frequency to 0 */ currently_rule->__frequency = 0; first_lf = (Eventinfo *)eventnode_pt->event; /* Searching all previous events */ do { lf = eventnode_pt->event; /* If time is outside the timeframe, return */ if((c_time - lf->time) > currently_rule->timeframe) { return(NULL); } /* We avoid multiple triggers for the same rule * or rules with a lower level. */ else if(lf->matched >= currently_rule->level) { return(NULL); } /* The category must be the same */ else if(lf->decoder_info->type != my_lf->decoder_info->type) { continue; } /* If regex does not match, go to next */ if(currently_rule->if_matched_regex) { if(!OSRegex_Execute(lf->log, currently_rule->if_matched_regex)) { /* Didn't match */ continue; } } /* Checking for repetitions on user error */ if(currently_rule->context_opts & SAME_USER) { if((!lf->user)||(!my_lf->user)) continue; if(strcmp(lf->user,my_lf->user) != 0) continue; } /* Checking for same id */ if(currently_rule->context_opts & SAME_ID) { if((!lf->id) || (!my_lf->id)) continue; if(strcmp(lf->id,my_lf->id) != 0) continue; } /* Checking for repetitions from same src_ip */ if(currently_rule->context_opts & SAME_SRCIP) { if((!lf->srcip)||(!my_lf->srcip)) continue; if(strcmp(lf->srcip,my_lf->srcip) != 0) continue; } /* Checking for different urls */ if(currently_rule->context_opts & DIFFERENT_URL) { if((!lf->url)||(!my_lf->url)) { continue; } if(strcmp(lf->url, my_lf->url) == 0) { continue; } } /* Checking if the number of matches worked */ if(currently_rule->__frequency < currently_rule->frequency) { if(currently_rule->__frequency <= 10) { currently_rule->last_events[currently_rule->__frequency] = lf->full_log; currently_rule->last_events[currently_rule->__frequency+1] = NULL; } currently_rule->__frequency++; continue; } /* If reached here, we matched */ my_lf->matched = currently_rule->level; lf->matched = currently_rule->level; first_lf->matched = currently_rule->level; return(lf); }while((eventnode_pt = eventnode_pt->next) != NULL); return(NULL); } /* Zero the loginfo structure */ void Zero_Eventinfo(Eventinfo *lf) { lf->log = NULL; lf->full_log = NULL; lf->hostname = NULL; lf->program_name = NULL; lf->location = NULL; lf->srcip = NULL; lf->dstip = NULL; lf->srcport = NULL; lf->dstport = NULL; lf->protocol = NULL; lf->action = NULL; lf->user = NULL; lf->dstuser = NULL; lf->id = NULL; lf->status = NULL; lf->command = NULL; lf->url = NULL; lf->data = NULL; lf->systemname = NULL; lf->time = 0; lf->matched = 0; lf->year = 0; lf->mon[3] = '\0'; lf->hour[9] = '\0'; lf->day = 0; lf->generated_rule = NULL; lf->sid_node_to_delete = NULL; lf->decoder_info = NULL_Decoder; return; } /* Free the loginfo structure */ void Free_Eventinfo(Eventinfo *lf) { if(!lf) { merror("%s: Trying to free NULL event. Inconsistent..",ARGV0); return; } if(lf->full_log) free(lf->full_log); if(lf->location) free(lf->location); if(lf->srcip) free(lf->srcip); if(lf->dstip) free(lf->dstip); if(lf->srcport) free(lf->srcport); if(lf->dstport) free(lf->dstport); if(lf->protocol) free(lf->protocol); if(lf->action) free(lf->action); if(lf->user) free(lf->user); if(lf->status) free(lf->status); if(lf->dstuser) free(lf->dstuser); if(lf->id) free(lf->id); if(lf->command) free(lf->command); if(lf->url) free(lf->url); if(lf->data) free(lf->data); if(lf->systemname) free(lf->systemname); /* Freeing node to delete */ if(lf->sid_node_to_delete) { OSList_DeleteThisNode(lf->generated_rule->sid_prev_matched, lf->sid_node_to_delete); } else if(lf->generated_rule && lf->generated_rule->group_prev_matched) { int i = 0; while(i < lf->generated_rule->group_prev_matched_sz) { OSList_DeleteOldestNode(lf->generated_rule->group_prev_matched[i]); i++; } } /* We dont need to free: * fts * comment */ free(lf); lf = NULL; return; } /* EOF */