X-Git-Url: http://ftp.carnet.hr/carnet-debian/scm?p=ossec-hids.git;a=blobdiff_plain;f=src%2Fanalysisd%2Frules.c;fp=src%2Fanalysisd%2Frules.c;h=8ce5f8ddb15d90c298de6ef431b9f8bd9406e7c8;hp=8c97197cdfc419ba216493b7b8968a15ed899f4f;hb=301048b51990573e58a30dc4a5bb4ec285cad554;hpb=914feba5d54f979cd5d7e69c349c3d01f630042a diff --git a/src/analysisd/rules.c b/src/analysisd/rules.c index 8c97197..8ce5f8d 100755 --- a/src/analysisd/rules.c +++ b/src/analysisd/rules.c @@ -1,11 +1,11 @@ -/* @(#) $Id: rules.c,v 1.79 2009/11/04 18:45:37 dcid Exp $ */ +/* @(#) $Id$ */ /* Copyright (C) 2009 Trend Micro Inc. * 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 + * License (version 2) as published by the FSF - Free Software * Foundation. * * License details at the LICENSE file included with OSSEC or @@ -57,8 +57,6 @@ void Rules_OP_CreateRules() return; } - - /* Rules_OP_ReadRules, v0.3, 2005/03/21 * Read the log rules. * v0.3: Fixed many memory problems. @@ -99,7 +97,18 @@ int Rules_OP_ReadRules(char * rulefile) char *xml_status = "status"; char *xml_action = "action"; char *xml_compiled = "compiled_rule"; - + + char *xml_list = "list"; + char *xml_list_lookup = "lookup"; + char *xml_list_field = "field"; + char *xml_list_cvalue = "check_value"; + char *xml_match_key = "match_key"; + char *xml_not_match_key = "not_match_key"; + char *xml_match_key_value = "match_key_value"; + char *xml_address_key = "address_match_key"; + char *xml_not_address_key = "not_address_match_key"; + char *xml_address_key_value = "address_match_key_value"; + char *xml_if_sid = "if_sid"; char *xml_if_group = "if_group"; char *xml_if_level = "if_level"; @@ -115,6 +124,7 @@ int Rules_OP_ReadRules(char * rulefile) char *xml_same_user = "same_user"; char *xml_same_location = "same_location"; char *xml_same_id = "same_id"; + char *xml_dodiff = "check_diff"; char *xml_different_url = "different_url"; @@ -131,15 +141,25 @@ int Rules_OP_ReadRules(char * rulefile) int default_timeframe = 360; - /* Building the rule file name + path */ - i = strlen(RULEPATH) + strlen(rulefile) + 2; - rulepath = (char *)calloc(i,sizeof(char)); - if(!rulepath) + /* If no directory in the rulefile add the default */ + if((strchr(rulefile, '/')) == NULL) { - ErrorExit(MEM_ERROR,ARGV0); + /* Building the rule file name + path */ + i = strlen(RULEPATH) + strlen(rulefile) + 2; + rulepath = (char *)calloc(i,sizeof(char)); + if(!rulepath) + { + ErrorExit(MEM_ERROR,ARGV0); + } + snprintf(rulepath,i,"%s/%s",RULEPATH,rulefile); + } + else + { + os_strdup(rulefile, rulepath); + debug1("%s is the rulefile", rulefile); + debug1("Not modifing the rule path"); } - snprintf(rulepath,i,"%s/%s",RULEPATH,rulefile); i = 0; @@ -338,6 +358,9 @@ int Rules_OP_ReadRules(char * rulefile) /* Rule elements block */ { int k = 0; + int info_type = 0; + int count_info_detail = 0; + RuleInfoDetail *last_info_detail = NULL; char *regex = NULL; char *match = NULL; char *url = NULL; @@ -393,8 +416,61 @@ int Rules_OP_ReadRules(char * rulefile) return(-1); } } + else if(strcasecmp(rule_opt[k]->element,xml_cve)==0) + { + if(config_ruleinfo->info_details == NULL) + { + config_ruleinfo->info_details = zeroinfodetails(RULEINFODETAIL_CVE, + rule_opt[k]->content); + } + else + { + for (last_info_detail = config_ruleinfo->info_details; + last_info_detail->next != NULL; + last_info_detail = last_info_detail->next) + { + count_info_detail++; + } + /* Silently Drop info messages if their are more then MAX_RULEINFODETAIL */ + if (count_info_detail <= MAX_RULEINFODETAIL) + { + last_info_detail->next = zeroinfodetails(RULEINFODETAIL_CVE, + rule_opt[k]->content); + } + } + + /* keep old methods for now */ + config_ruleinfo->cve= + loadmemory(config_ruleinfo->cve, + rule_opt[k]->content); + } else if(strcasecmp(rule_opt[k]->element,xml_info)==0) { + + info_type = get_info_attributes(rule_opt[k]->attributes, + rule_opt[k]->values); + debug1("info_type = %d", info_type); + + if(config_ruleinfo->info_details == NULL) + { + config_ruleinfo->info_details = zeroinfodetails(info_type, + rule_opt[k]->content); + } + else + { + for (last_info_detail = config_ruleinfo->info_details; + last_info_detail->next != NULL; + last_info_detail = last_info_detail->next) { + count_info_detail++; + } + /* Silently Drop info messages if their are more then MAX_RULEINFODETAIL */ + if (count_info_detail <= MAX_RULEINFODETAIL) { + last_info_detail->next = zeroinfodetails(info_type, rule_opt[k]->content); + } + } + + + /* keep old methods for now */ config_ruleinfo->info= loadmemory(config_ruleinfo->info, rule_opt[k]->content); @@ -435,12 +511,6 @@ int Rules_OP_ReadRules(char * rulefile) loadmemory(config_ruleinfo->group, rule_opt[k]->content); } - else if(strcasecmp(rule_opt[k]->element,xml_cve)==0) - { - config_ruleinfo->cve= - loadmemory(config_ruleinfo->cve, - rule_opt[k]->content); - } else if(strcasecmp(rule_opt[k]->element,xml_comment)==0) { char *newline; @@ -593,6 +663,132 @@ int Rules_OP_ReadRules(char * rulefile) loadmemory(config_ruleinfo->action, rule_opt[k]->content); } + else if(strcasecmp(rule_opt[k]->element,xml_list)==0) + { + debug1("-> %s == %s",rule_opt[k]->element, xml_list); + if (rule_opt[k]->attributes && rule_opt[k]->values && rule_opt[k]->content) + { + int list_att_num=0; + int rule_type=0; + OSMatch *matcher=NULL; + int lookup_type = LR_STRING_MATCH; + while(rule_opt[k]->attributes[list_att_num]) + { + if(strcasecmp(rule_opt[k]->attributes[list_att_num], xml_list_lookup) == 0) + { + if(strcasecmp(rule_opt[k]->values[list_att_num],xml_match_key) == 0) + lookup_type = LR_STRING_MATCH; + else if(strcasecmp(rule_opt[k]->values[list_att_num],xml_not_match_key)==0) + lookup_type = LR_STRING_NOT_MATCH; + else if(strcasecmp(rule_opt[k]->values[list_att_num],xml_match_key_value)==0) + lookup_type = LR_STRING_MATCH_VALUE; + else if(strcasecmp(rule_opt[k]->values[list_att_num],xml_address_key)==0) + lookup_type = LR_ADDRESS_MATCH; + else if(strcasecmp(rule_opt[k]->values[list_att_num],xml_not_address_key)==0) + lookup_type = LR_ADDRESS_NOT_MATCH; + else if(strcasecmp(rule_opt[k]->values[list_att_num],xml_address_key_value)==0) + lookup_type = LR_ADDRESS_MATCH_VALUE; + else + { + merror(INVALID_CONFIG, ARGV0, + rule_opt[k]->element, + rule_opt[k]->content); + merror("%s: List match lookup=\"%s\" is not valid.", + ARGV0,rule_opt[k]->values[list_att_num]); + return(-1); + } + } + else if(strcasecmp(rule_opt[k]->attributes[list_att_num], xml_list_field)==0) + { + if(strcasecmp(rule_opt[k]->values[list_att_num],xml_srcip)==0) + rule_type = RULE_SRCIP; + else if (strcasecmp(rule_opt[k]->values[list_att_num],xml_srcport)==0) + rule_type = RULE_SRCPORT; + else if (strcasecmp(rule_opt[k]->values[list_att_num],xml_dstip)==0) + rule_type = RULE_DSTIP; + else if (strcasecmp(rule_opt[k]->values[list_att_num],xml_dstport)==0) + rule_type = RULE_DSTPORT; + else if (strcasecmp(rule_opt[k]->values[list_att_num],xml_user)==0) + rule_type = RULE_USER; + else if (strcasecmp(rule_opt[k]->values[list_att_num],xml_url)==0) + rule_type = RULE_URL; + else if (strcasecmp(rule_opt[k]->values[list_att_num],xml_id)==0) + rule_type = RULE_ID; + else if (strcasecmp(rule_opt[k]->values[list_att_num],xml_hostname)==0) + rule_type = RULE_HOSTNAME; + else if (strcasecmp(rule_opt[k]->values[list_att_num],xml_program_name)==0) + rule_type = RULE_PROGRAM_NAME; + else if (strcasecmp(rule_opt[k]->values[list_att_num],xml_status)==0) + rule_type = RULE_STATUS; + else if (strcasecmp(rule_opt[k]->values[list_att_num],xml_action)==0) + rule_type = RULE_ACTION; + else + { + merror(INVALID_CONFIG, ARGV0, + rule_opt[k]->element, + rule_opt[k]->content); + merror("%s: List match field=\"%s\" is not valid.", + ARGV0,rule_opt[k]->values[list_att_num]); + return(-1); + } + } + else if(strcasecmp(rule_opt[k]->attributes[list_att_num], xml_list_cvalue)==0) + { + os_calloc(1, sizeof(OSMatch), matcher); + if(!OSMatch_Compile(rule_opt[k]->values[list_att_num], matcher, 0)) + { + merror(INVALID_CONFIG, ARGV0, + rule_opt[k]->element, + rule_opt[k]->content); + merror(REGEX_COMPILE, + ARGV0, + rule_opt[k]->values[list_att_num], + matcher->error); + return(-1); + } + } + else + { + merror("%s:List feild=\"%s\" is not valid",ARGV0, + rule_opt[k]->values[list_att_num]); + merror(INVALID_CONFIG, ARGV0, + rule_opt[k]->element, rule_opt[k]->content); + return(-1); + } + list_att_num++; + } + if(rule_type == 0) + { + merror("%s:List requires the field=\"\" Attrubute",ARGV0); + merror(INVALID_CONFIG, ARGV0, + rule_opt[k]->element, rule_opt[k]->content); + return(-1); + } + + /* Wow it's all ready - this seams too complex to get to this point */ + config_ruleinfo->lists = OS_AddListRule(config_ruleinfo->lists, + lookup_type, + rule_type, + rule_opt[k]->content, + matcher); + if (config_ruleinfo->lists == NULL) + { + merror("%s: List error: Could not load %s", ARGV0, rule_opt[k]->content); + return(-1); + } + } + else + { + merror("%s:List must have a correctly formatted feild attribute", + ARGV0); + merror(INVALID_CONFIG, + ARGV0, + rule_opt[k]->element, + rule_opt[k]->content); + return(-1); + } + /* xml_list eval is done */ + } else if(strcasecmp(rule_opt[k]->element,xml_url)==0) { url= @@ -735,6 +931,14 @@ int Rules_OP_ReadRules(char * rulefile) config_ruleinfo->alert_opts |= SAME_EXTRAINFO; } else if(strcasecmp(rule_opt[k]->element, + xml_dodiff)==0) + { + config_ruleinfo->context++; + config_ruleinfo->context_opts|= SAME_DODIFF; + if(!(config_ruleinfo->alert_opts & DO_EXTRAINFO)) + config_ruleinfo->alert_opts |= DO_EXTRAINFO; + } + else if(strcasecmp(rule_opt[k]->element, xml_same_dst_port) == 0) { config_ruleinfo->context_opts|= SAME_DSTPORT; @@ -827,6 +1031,13 @@ int Rules_OP_ReadRules(char * rulefile) config_ruleinfo->alert_opts &=0xfff-DO_LOGALERT; } } + else if(strcmp("no_ar", rule_opt[k]->content) == 0) + { + if(!(config_ruleinfo->alert_opts & NO_AR)) + { + config_ruleinfo->alert_opts|= NO_AR; + } + } else { merror(XML_VALUEERR, ARGV0, xml_options, @@ -1238,8 +1449,16 @@ int Rules_OP_ReadRules(char * rulefile) } else if(config_ruleinfo->context) { - config_ruleinfo->event_search = + if((config_ruleinfo->context == 1) && + (config_ruleinfo->context_opts & SAME_DODIFF)) + { + config_ruleinfo->context = 0; + } + else + { + config_ruleinfo->event_search = (void *)Search_LastEvents; + } } } /* while(rule[j]) */ @@ -1335,6 +1554,29 @@ char *loadmemory(char *at, char *str) } +RuleInfoDetail *zeroinfodetails(int type, char *data) +{ + RuleInfoDetail *info_details_pt = NULL; + + info_details_pt = (RuleInfoDetail *)calloc(1,sizeof(RuleInfoDetail)); + + if (info_details_pt == NULL) + { + ErrorExit(MEM_ERROR,ARGV0); + } + /* type */ + info_details_pt->type = type; + + /* data */ + os_strdup(data, info_details_pt->data); + + info_details_pt->next = NULL; + + + return(info_details_pt); +} + + RuleInfo *zerorulemember(int id, int level, int maxsize, int frequency, int timeframe, int noalert, @@ -1403,6 +1645,7 @@ RuleInfo *zerorulemember(int id, int level, ruleinfo_pt->comment = NULL; ruleinfo_pt->info = NULL; ruleinfo_pt->cve = NULL; + ruleinfo_pt->info_details = NULL; ruleinfo_pt->if_sid = NULL; ruleinfo_pt->if_group = NULL; @@ -1437,10 +1680,48 @@ RuleInfo *zerorulemember(int id, int level, ruleinfo_pt->event_search = NULL; ruleinfo_pt->compiled_rule = NULL; + ruleinfo_pt->lists = NULL; return(ruleinfo_pt); } +int get_info_attributes(char **attributes, char **values) +{ + char *xml_type = "type"; + int k=0; + if(!attributes) + return(RULEINFODETAIL_TEXT); + + while(attributes[k]) + { + if (!values[k]) + { + merror("rules_op: Entry info type \"%s\" does not have a value", + attributes[k]); + return (-1); + } + else if(strcasecmp(attributes[k],xml_type) == 0) + { + if(strcmp(values[k], "text") == 0) + { + return(RULEINFODETAIL_TEXT); + } + else if(strcmp(values[k], "link") == 0) + { + return(RULEINFODETAIL_LINK); + } + else if(strcmp(values[k], "cve") == 0) + { + return(RULEINFODETAIL_CVE); + } + else if(strcmp(values[k], "osvdb") == 0) + { + return(RULEINFODETAIL_OSVDB); + } + } + } + return(RULEINFODETAIL_TEXT); +} /* Get the attributes */ int getattributes(char **attributes, char **values, @@ -1641,6 +1922,12 @@ void Rule_AddAR(RuleInfo *rule_config) return; } + /* No AR when options no_ar is set */ + if(rule_config->alert_opts & NO_AR) + { + return; + } + if(!active_responses) { return;