Ejemplo n.º 1
0
    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)
Ejemplo n.º 2
0
    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)
Ejemplo n.º 3
0
    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)
Ejemplo n.º 4
0
    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)
Ejemplo n.º 5
0
    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)
Ejemplo n.º 6
0
 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)
Ejemplo n.º 7
0
 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)
Ejemplo n.º 8
0
    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)
Ejemplo n.º 9
0
    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()
Ejemplo n.º 10
0
    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()
Ejemplo n.º 11
0
 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)