def get_config(self): # allow to raise debug level of expressions module explicitly. Beware: # This affects not just individual objects but the whole module which # is why we do it by poking the logger and not via a setter method. log_level = self.get_config_value('log_level', logging.WARNING, option_type=self.config.LOG_LEVEL) expression_logger = logging.getLogger('peekaboo.ruleset.expressions') expression_logger.setLevel(log_level) raw_expressions = self.get_config_value('expression', []) if not raw_expressions: raise PeekabooRulesetConfigError( "List of expressions empty, check %s rule config." % self.rule_name) self.expressions = [] parser = ExpressionParser() # context of dummy objects to test expressions against context = { 'variables': { 'sample': Sample("dummy"), 'cuckooreport': CuckooReport(), 'olereport': OletoolsReport(), 'filereport': FiletoolsReport(), 'knownreport': KnowntoolsReport(), } } for raw_expression in raw_expressions: try: parsed_expression = parser.parse(raw_expression) logger.debug("Expression from config file: %s", raw_expression) logger.debug("Expression parsed: %s", parsed_expression) except SyntaxError as error: raise PeekabooRulesetConfigError(error) if not parsed_expression.is_implication(): raise PeekabooRulesetConfigError( "Malformed expression, missing implication: %s" % raw_expression) # run expression against dummy objects to find out if it's # attempting anything illegal try: parsed_expression.eval(context=context) except IdentifierMissingException as missing: # our dummy context provides everything we would provide at # runtime as well, so any missing identifier is an error at # this point identifier = missing.name raise PeekabooRulesetConfigError( "Invalid expression, unknown identifier %s: %s" % (identifier, raw_expression)) except AttributeError as missing: raise PeekabooRulesetConfigError("Invalid expression, %s: %s" % (missing, raw_expression)) self.expressions.append(parsed_expression)
def __init__(self, config, db_con): """ Initialise the engine, validate its and the individual rules' configuration. @param config: ruleset configuration parser @param db_con: database connection handed to rules (not used by engine itself) @raises PeekabooRulesetConfigError: if configuration errors are found """ # create a lookup table from rule name to class rule_classes = {} for known_rule in self.known_rules: rule_classes[known_rule.rule_name] = known_rule try: enabled_rules = config.getlist('rules', 'rule') except PeekabooConfigException as error: raise PeekabooRulesetConfigError( 'Ruleset configuration error: %s' % error) if not enabled_rules: raise PeekabooRulesetConfigError( 'No enabled rules found, check ruleset config.') # check if unknown rules are enabled known_rule_names = rule_classes.keys() unknown_rules = set(enabled_rules) - set(known_rule_names) if unknown_rules: raise PeekabooRulesetConfigError( 'Unknown rule(s) enabled: %s' % ', '.join(unknown_rules)) # check for unknown config sections by using rule names as rules' # config section names. Allow all known rules not only the enabled ones # because some might be temporarily disabled but should be allowed to # retain their configuration. Use += extension of list to avoid # 'TypeError: can only concatenate list (not "dict_keys") to list' with # python3. known_sections = ['rules'] known_sections += known_rule_names config.check_sections(known_sections) # instantiate enabled rules and have them check their configuration, # user-defined rule order is preserved in enabled_rules and through # ordered append() in self.rules self.rules = [] for rule in enabled_rules: rule = rule_classes[rule](config, db_con) self.rules.append(rule)
def get_config(self): greylist = self.get_config_value('greylist', []) if not greylist: raise PeekabooRulesetConfigError( "Empty greylist, check %s rule config." % self.rule_name) self.greylist = set(greylist)
def get_config(self): whitelist = self.get_config_value('whitelist', []) if not whitelist: raise PeekabooRulesetConfigError( "Empty whitelist, check %s rule config." % self.rule_name) self.whitelist = set(whitelist)
def get_config(self): self.expressions = self.get_config_value('expression', []) if not self.expressions: raise PeekabooRulesetConfigError( "List of expressions empty, check %s rule config." % self.rule_name) self.rules = [] parser = ExpressionParser() for expr in self.expressions: try: rule = parser.parse(expr) logger.debug("EXPR: %s", expr) logger.debug("RULE: %s", rule) self.rules.append(rule) except SyntaxError as error: raise PeekabooRulesetConfigError(error)
def get_config(self): # get list of keywords from config file self.suspicious_keyword_list = self.get_config_value( 'keyword', [], option_type=self.config.IRELIST) if not self.suspicious_keyword_list: raise PeekabooRulesetConfigError( "Empty suspicious keyword list, check %s rule config." % self.rule_name)
def get_config(self): # list all installed signatures # grep -o "description.*" -R . ~/cuckoo2.0/modules/signatures/ self.bad_sigs = self.get_config_value('signature', [], option_type=self.config.RELIST) if not self.bad_sigs: raise PeekabooRulesetConfigError( "Empty bad signature list, check %s rule config." % self.rule_name)
def validate_rule_config(self): """ Validate the rule configuration in various ways. @returns: None @raises PeekabooRulesetConfigError: if configuration errors are found @raises KeyError, ValueError, PeekabooConfigException: by failed config object accesses """ if not self.enabled_rules: raise PeekabooRulesetConfigError( 'No enabled rules found, check ruleset config.') # check if unknown rules are enabled known_rule_names = self.rule_classes.keys() unknown_rules = set(self.enabled_rules) - set(known_rule_names) if unknown_rules: raise PeekabooRulesetConfigError('Unknown rule(s) enabled: %s' % ', '.join(unknown_rules)) # check for unknown config sections by using rule names as rules' # config section names. Allow all known rules not only the enabled ones # because some might be temporarily disabled but should be allowed to # retain their configuration. Use += extension of list to avoid # 'TypeError: can only concatenate list (not "dict_keys") to list' with # python3. known_sections = ['rules'] known_sections += known_rule_names self.config.check_sections(known_sections) # have enabled rules check their configuration for rule in self.enabled_rules: # not passing database connection. Needs revisiting if a rule # ever wants to retrieve configuration from the database. For # now at least rule constructor and get_config() need to be # able to cope without it. rule = self.rule_classes[rule](self.config)
def __init__(self, ruleset_config, db_con): """ Initialise the engine, validate its and the individual rules' configuration. @raises PeekabooRulesetConfigError: if configuration errors are found """ self.config = ruleset_config self.db_con = db_con # create a lookup table from rule name to class self.rule_classes = {} for known_rule in self.known_rules: self.rule_classes[known_rule.rule_name] = known_rule try: self.enabled_rules = self.config.getlist('rules', 'rule') except PeekabooConfigException as error: raise PeekabooRulesetConfigError( 'Ruleset configuration error: %s' % error) self.validate_rule_config()
def start(self): """ Initialise the engine, validate its and the individual rules' configuration. @raises PeekabooRulesetConfigError: if configuration errors are found """ # create a lookup table from rule name to class rule_classes = {} for known_rule in self.known_rules: rule_classes[known_rule.rule_name] = known_rule try: enabled_rules = self.config.getlist('rules', 'rule') except PeekabooConfigException as error: raise PeekabooRulesetConfigError( 'Ruleset configuration error: %s' % error) if not enabled_rules: raise PeekabooRulesetConfigError( 'No enabled rules found, check ruleset config.') # check if unknown rules are enabled known_rule_names = rule_classes.keys() unknown_rules = set(enabled_rules) - set(known_rule_names) if unknown_rules: raise PeekabooRulesetConfigError( 'Unknown rule(s) enabled: %s' % ', '.join(unknown_rules)) # check for unknown config sections by using rule names as rules' # config section names. Allow all known rules not only the enabled ones # because some might be temporarily disabled but should be allowed to # retain their configuration. Use += extension of list to avoid # 'TypeError: can only concatenate list (not "dict_keys") to list' with # python3. known_sections = ['rules'] known_sections += known_rule_names self.config.check_sections(known_sections) # instantiate enabled rules and have them check their configuration, # user-defined rule order is preserved in enabled_rules and through # ordered append() in self.rules for rule_name in enabled_rules: rule = rule_classes[rule_name](self.config, self.db_con) # check if the rule requires any common, long lived logic and # instantiate now if rule.uses_cuckoo: if self.cuckoo is None: logger.debug( "Rule %s uses Cuckoo. Starting job tracker.", rule_name) self.cuckoo = Cuckoo( self.job_queue, self.analyzer_config.cuckoo_url, self.analyzer_config.cuckoo_api_token, self.analyzer_config.cuckoo_poll_interval, self.analyzer_config.cuckoo_submit_original_filename, self.analyzer_config.cuckoo_maximum_job_age) if not self.cuckoo.start_tracker(): raise PeekabooRulesetConfigError( "Failure to initialize Cuckoo job tracker") rule.set_cuckoo_job_tracker(self.cuckoo) if rule.uses_cortex: if self.cortex is None: logger.debug( "Rule %s uses Cortex. Starting job tracker.", rule_name) self.cortex = Cortex( self.job_queue, self.analyzer_config.cortex_url, self.analyzer_config.cortex_tlp, self.analyzer_config.cortex_api_token, self.analyzer_config.cortex_poll_interval, self.analyzer_config.cortex_submit_original_filename, self.analyzer_config.cortex_maximum_job_age) if not self.cortex.start_tracker(): raise PeekabooRulesetConfigError( "Failure to initialize Cortex job tracker") rule.set_cortex_job_tracker(self.cortex) self.rules.append(rule) # abort startup if we've been asked to shut down meanwhile if self.shutdown_requested: break # shut down what we've initialised if our startup was racing a shutdown # request because these resources may not have been allocated yet when # the shutdown request arrived. if self.shutdown_requested: self.shut_down_resources()
def get_config(self): self.evil_domains = self.get_config_value('domain', []) if not self.evil_domains: raise PeekabooRulesetConfigError( "Empty evil domain list, check %s rule config." % self.rule_name)