diff options
author | Michael Weiser <michael.weiser@gmx.de> | 2019-02-22 13:43:52 +0000 |
---|---|---|
committer | Michael Weiser <michael.weiser@gmx.de> | 2019-04-25 12:20:20 +0000 |
commit | e6c44a8ca3c2216904731e4d889e53473691c0dc (patch) | |
tree | e1af84c58c42d41759c6fbc75173003b0765dae3 | |
parent | cb54cc4dda6a43b8b5d6d8ab22518fef27b70c60 (diff) |
Allow rules to run to be configured
Make the list of rules to run a section in the ruleset configuration.
This allows rules to be reordered and (potentially) run more than once
without code changes.
This also obsoletes the enabled setting per rule because they're now
implicitly enabled if they're listed. Commenting out disables a rule.
-rw-r--r-- | peekaboo/config.py | 22 | ||||
-rw-r--r-- | peekaboo/locale/de/LC_MESSAGES/peekaboo.mo | bin | 4286 -> 4219 bytes | |||
-rw-r--r-- | peekaboo/locale/de/LC_MESSAGES/peekaboo.po | 90 | ||||
-rw-r--r-- | peekaboo/locale/peekaboo.pot | 89 | ||||
-rw-r--r-- | peekaboo/ruleset/engine.py | 26 | ||||
-rw-r--r-- | peekaboo/ruleset/rules.py | 2 | ||||
-rw-r--r-- | ruleset.conf.sample | 31 |
7 files changed, 116 insertions, 144 deletions
diff --git a/peekaboo/config.py b/peekaboo/config.py index e1da0c4..9215011 100644 --- a/peekaboo/config.py +++ b/peekaboo/config.py @@ -293,11 +293,7 @@ class PeekabooRulesetConfig(object): # - There are no duplicate settings with ConfigParser. The last # one always wins. - # special keyword enabled is boolean and has the same behaviour - # for all rules - if key.lower() in ['enabled']: - saved_val = config.getboolean(section, setting) - elif is_list: + if is_list: saved_val.append(config.get(section, setting)) else: saved_val = config.get(section, setting) @@ -313,22 +309,6 @@ class PeekabooRulesetConfig(object): configuration is present. """ return self.ruleset_config.get(rule) - def rule_enabled(self, rule): - """ Check if a rule is enabled. Cases are: - - no config section for that rule is present - - enabled keyword is not present in that section or - - the value of the enabled is True (i.e. yes, true, 1 in the file) - - @param rule: Name of the rule to check if enabled or not. - @type rule: string - @return: True or False based on above criteria. - """ - config = self.rule_config(rule) - if config is None: - return True - - return config.get('enabled', True) - def __str__(self): return '<PeekabooRulesetConfiguration(filepath="%s", %s)>' % \ (self.config_file, self.ruleset_config) diff --git a/peekaboo/locale/de/LC_MESSAGES/peekaboo.mo b/peekaboo/locale/de/LC_MESSAGES/peekaboo.mo Binary files differindex dab15b2..6cca488 100644 --- a/peekaboo/locale/de/LC_MESSAGES/peekaboo.mo +++ b/peekaboo/locale/de/LC_MESSAGES/peekaboo.mo diff --git a/peekaboo/locale/de/LC_MESSAGES/peekaboo.po b/peekaboo/locale/de/LC_MESSAGES/peekaboo.po index 86ff0ac..3a2be9f 100644 --- a/peekaboo/locale/de/LC_MESSAGES/peekaboo.po +++ b/peekaboo/locale/de/LC_MESSAGES/peekaboo.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: PeekabooAV 1.6.2\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2019-04-15 15:41+0000\n" +"POT-Creation-Date: 2019-04-17 09:12+0000\n" "PO-Revision-Date: 2019-02-14 22:02+0000\n" "Last-Translator: Michael Weiser <michael.weiser@gmx.de>\n" "Language: de\n" @@ -17,143 +17,138 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.4.0\n" -#: peekaboo/queuing.py:390 +#: peekaboo/queuing.py:382 msgid "Sample initialization failed" msgstr "Initialisierung der zu analysierenden Datei fehlgeschlagen" -#: peekaboo/sample.py:189 +#: peekaboo/sample.py:186 #, python-format msgid "File \"%s\" %s is being analyzed" msgstr "Datei \"%s\" %s wird analysiert" -#: peekaboo/sample.py:242 +#: peekaboo/sample.py:239 #, python-format msgid "File \"%s\" is considered \"%s\"" msgstr "Die Datei \"%s\" wird als \"%s\" betrachtet" -#: peekaboo/sample.py:302 +#: peekaboo/sample.py:299 #, python-format msgid "File \"%s\": %s" msgstr "Datei \"%s\": %s" -#: peekaboo/sample.py:498 +#: peekaboo/sample.py:495 #, python-format msgid "Sample %s successfully submitted to Cuckoo as job %d" msgstr "Erfolgreich an Cuckoo gegeben %s als Job %d" -#: peekaboo/server.py:143 +#: peekaboo/server.py:141 msgid "Hello, this is Peekaboo." msgstr "Hallo das ist Peekaboo" -#: peekaboo/server.py:176 +#: peekaboo/server.py:174 #, fuzzy msgid "Error: Invalid JSON in request." msgstr "FEHLER: Ungültiges JSON." -#: peekaboo/server.py:181 +#: peekaboo/server.py:179 msgid "ERROR: Invalid data structure." msgstr "FEHLER: Ungültiges Datenformat." -#: peekaboo/server.py:188 +#: peekaboo/server.py:186 msgid "ERROR: Incomplete data structure." msgstr "FEHLER: Unvollständige Datenstruktur." -#: peekaboo/server.py:195 +#: peekaboo/server.py:193 msgid "ERROR: Path does not exist or no permission to access it." msgstr "FEHLER: Pfad existiert nicht oder Zugriff verweigert." -#: peekaboo/server.py:202 +#: peekaboo/server.py:200 msgid "ERRROR: Input is not a file" msgstr "FEHLER: Eingabe ist keine Datei" -#: peekaboo/server.py:209 +#: peekaboo/server.py:207 msgid "Error submitting sample to job queue" msgstr "Fehler beim Einstellen in Warteschlange" -#: peekaboo/server.py:241 +#: peekaboo/server.py:239 msgid "Files are being analyzed..." msgstr "Dateien werden analysiert..." -#: peekaboo/server.py:264 +#: peekaboo/server.py:262 msgid "Peekaboo is shutting down." msgstr "Peekaboo wird beendet." -#: peekaboo/server.py:316 +#: peekaboo/server.py:314 #, python-format msgid "The file collection has been categorized \"%s\"" msgstr "Die Datensammlung wurde als \"%s\" eingestuft" -#: peekaboo/ruleset/__init__.py:66 +#: peekaboo/ruleset/__init__.py:64 msgid "Rule without result" msgstr "Regel ohne Ergebnis" -#: peekaboo/ruleset/__init__.py:70 +#: peekaboo/ruleset/__init__.py:68 #, python-format msgid "Result \"%s\" of rule %s - %s, analysis continues: %s." msgstr "Ergebnis \"%s\" der Regel %s - %s, Analyse wird fortgesetzt: %s." -#: peekaboo/ruleset/__init__.py:72 +#: peekaboo/ruleset/__init__.py:70 msgid "Yes" msgstr "Ja" -#: peekaboo/ruleset/__init__.py:72 +#: peekaboo/ruleset/__init__.py:70 msgid "No" msgstr "Nein" -#: peekaboo/ruleset/engine.py:88 -#, python-format -msgid "Rule '%s' is disabled." -msgstr "Regel '%s' ist deaktiviert." - -#: peekaboo/ruleset/engine.py:102 +#: peekaboo/ruleset/engine.py:97 msgid "Rule aborted with error" msgstr "Regel mit Fehler abgebrochen" -#: peekaboo/ruleset/rules.py:84 +#: peekaboo/ruleset/rules.py:86 msgid "File is not yet known to the system" msgstr "Datei ist dem System noch nicht bekannt" -#: peekaboo/ruleset/rules.py:104 +#: peekaboo/ruleset/rules.py:106 #, python-format msgid "Failure to determine sample file size: %s" msgstr "Ermittlung der Dateigröße fehlgeschlagen: %s" -#: peekaboo/ruleset/rules.py:109 +#: peekaboo/ruleset/rules.py:111 #, python-format msgid "File has more than %d bytes" msgstr "Datei hat mehr als %d bytes" -#: peekaboo/ruleset/rules.py:114 +#: peekaboo/ruleset/rules.py:116 #, python-format msgid "File is more than %d bytes long" msgstr "Datei ist nur %d bytes lang" -#: peekaboo/ruleset/rules.py:133 +#: peekaboo/ruleset/rules.py:135 msgid "File type is on whitelist" msgstr "Dateityp ist auf Whitelist" -#: peekaboo/ruleset/rules.py:137 +#: peekaboo/ruleset/rules.py:139 msgid "File type is not on whitelist" msgstr "Dateityp ist nicht auf Whitelist" -#: peekaboo/ruleset/rules.py:156 +#: peekaboo/ruleset/rules.py:158 msgid "File type is on the list of types to analyze" msgstr "Dateityp ist auf der Liste der zu analysiserenden Typen" -#: peekaboo/ruleset/rules.py:161 +#: peekaboo/ruleset/rules.py:163 #, python-format msgid "File type is not on the list of types to analyse (%s)" msgstr "Dateityp ist nicht auf der Liste der zu analysierenden Typen (%s)" -#: peekaboo/ruleset/rules.py:174 +#: peekaboo/ruleset/rules.py:176 msgid "The file contains an Office macro" msgstr "Die Datei beinhaltet ein Office-Makro" -#: peekaboo/ruleset/rules.py:178 +#: peekaboo/ruleset/rules.py:180 msgid "The file does not contain a recognizable Office macro" msgstr "Die Datei beinhaltet kein erkennbares Office-Makro" -#: peekaboo/ruleset/rules.py:205 peekaboo/ruleset/rules.py:327 +#: peekaboo/ruleset/rules.py:210 peekaboo/ruleset/rules.py:332 msgid "" "Behavioral analysis by Cuckoo has produced an error and did not finish " "successfully" @@ -161,49 +156,48 @@ msgstr "" "Die Verhaltensanalyse durch Cuckoo hat einen Fehler produziert und konnte" " nicht erfolgreich abgeschlossen werden" -#: peekaboo/ruleset/rules.py:239 +#: peekaboo/ruleset/rules.py:244 msgid "Empty list of malicious signatures" msgstr "Leere Liste schädlicher Signaturen" -#: peekaboo/ruleset/rules.py:257 +#: peekaboo/ruleset/rules.py:262 msgid "No signature suggesting malware detected" msgstr "Keine Signatur erkannt die auf Schadcode hindeutet" -#: peekaboo/ruleset/rules.py:262 +#: peekaboo/ruleset/rules.py:267 #, python-format msgid "The following signatures have been recognized: %s" msgstr "Folgende Signaturen wurden erkannt: %s" -#: peekaboo/ruleset/rules.py:279 +#: peekaboo/ruleset/rules.py:284 #, python-format msgid "Cuckoo score >= %s: %s" msgstr "" -#: peekaboo/ruleset/rules.py:284 +#: peekaboo/ruleset/rules.py:289 #, python-format msgid "Cuckoo score < %s: %s" msgstr "" -#: peekaboo/ruleset/rules.py:300 +#: peekaboo/ruleset/rules.py:305 msgid "Empty domain list" msgstr "Leere Domainliste" -#: peekaboo/ruleset/rules.py:305 +#: peekaboo/ruleset/rules.py:310 #, python-format msgid "The file attempts to contact at least one domain on the blacklist (%s)" msgstr "" "Die Datei versucht mindestens eine Domain aus der Blacklist zu " "kontaktieren (%s)" -#: peekaboo/ruleset/rules.py:311 +#: peekaboo/ruleset/rules.py:316 msgid "File does not seem to attempt contact with domains on the blacklist" msgstr "Datei scheint keine Domains aus der Blacklist kontaktieren zu wollen" -#: peekaboo/ruleset/rules.py:347 +#: peekaboo/ruleset/rules.py:352 msgid "Behavioral analysis by Cuckoo completed successfully" msgstr "Die Verhaltensanalyse durch Cuckoo wurde erfolgreich abgeschlossen" -#: peekaboo/ruleset/rules.py:364 +#: peekaboo/ruleset/rules.py:369 msgid "File does not seem to exhibit recognizable malicious behaviour" msgstr "Datei scheint keine erkennbaren Schadroutinen zu starten" - diff --git a/peekaboo/locale/peekaboo.pot b/peekaboo/locale/peekaboo.pot index 8551395..d2231b7 100644 --- a/peekaboo/locale/peekaboo.pot +++ b/peekaboo/locale/peekaboo.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2019-04-15 15:41+0000\n" +"POT-Creation-Date: 2019-04-17 09:12+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -17,188 +17,183 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.4.0\n" -#: peekaboo/queuing.py:390 +#: peekaboo/queuing.py:382 msgid "Sample initialization failed" msgstr "" -#: peekaboo/sample.py:189 +#: peekaboo/sample.py:186 #, python-format msgid "File \"%s\" %s is being analyzed" msgstr "" -#: peekaboo/sample.py:242 +#: peekaboo/sample.py:239 #, python-format msgid "File \"%s\" is considered \"%s\"" msgstr "" -#: peekaboo/sample.py:302 +#: peekaboo/sample.py:299 #, python-format msgid "File \"%s\": %s" msgstr "" -#: peekaboo/sample.py:498 +#: peekaboo/sample.py:495 #, python-format msgid "Sample %s successfully submitted to Cuckoo as job %d" msgstr "" -#: peekaboo/server.py:143 +#: peekaboo/server.py:141 msgid "Hello, this is Peekaboo." msgstr "" -#: peekaboo/server.py:176 +#: peekaboo/server.py:174 msgid "Error: Invalid JSON in request." msgstr "" -#: peekaboo/server.py:181 +#: peekaboo/server.py:179 msgid "ERROR: Invalid data structure." msgstr "" -#: peekaboo/server.py:188 +#: peekaboo/server.py:186 msgid "ERROR: Incomplete data structure." msgstr "" -#: peekaboo/server.py:195 +#: peekaboo/server.py:193 msgid "ERROR: Path does not exist or no permission to access it." msgstr "" -#: peekaboo/server.py:202 +#: peekaboo/server.py:200 msgid "ERRROR: Input is not a file" msgstr "" -#: peekaboo/server.py:209 +#: peekaboo/server.py:207 msgid "Error submitting sample to job queue" msgstr "" -#: peekaboo/server.py:241 +#: peekaboo/server.py:239 msgid "Files are being analyzed..." msgstr "" -#: peekaboo/server.py:264 +#: peekaboo/server.py:262 msgid "Peekaboo is shutting down." msgstr "" -#: peekaboo/server.py:316 +#: peekaboo/server.py:314 #, python-format msgid "The file collection has been categorized \"%s\"" msgstr "" -#: peekaboo/ruleset/__init__.py:66 +#: peekaboo/ruleset/__init__.py:64 msgid "Rule without result" msgstr "" -#: peekaboo/ruleset/__init__.py:70 +#: peekaboo/ruleset/__init__.py:68 #, python-format msgid "Result \"%s\" of rule %s - %s, analysis continues: %s." msgstr "" -#: peekaboo/ruleset/__init__.py:72 +#: peekaboo/ruleset/__init__.py:70 msgid "Yes" msgstr "" -#: peekaboo/ruleset/__init__.py:72 +#: peekaboo/ruleset/__init__.py:70 msgid "No" msgstr "" -#: peekaboo/ruleset/engine.py:88 -#, python-format -msgid "Rule '%s' is disabled." -msgstr "" - -#: peekaboo/ruleset/engine.py:102 +#: peekaboo/ruleset/engine.py:97 msgid "Rule aborted with error" msgstr "" -#: peekaboo/ruleset/rules.py:84 +#: peekaboo/ruleset/rules.py:86 msgid "File is not yet known to the system" msgstr "" -#: peekaboo/ruleset/rules.py:104 +#: peekaboo/ruleset/rules.py:106 #, python-format msgid "Failure to determine sample file size: %s" msgstr "" -#: peekaboo/ruleset/rules.py:109 +#: peekaboo/ruleset/rules.py:111 #, python-format msgid "File has more than %d bytes" msgstr "" -#: peekaboo/ruleset/rules.py:114 +#: peekaboo/ruleset/rules.py:116 #, python-format msgid "File is more than %d bytes long" msgstr "" -#: peekaboo/ruleset/rules.py:133 +#: peekaboo/ruleset/rules.py:135 msgid "File type is on whitelist" msgstr "" -#: peekaboo/ruleset/rules.py:137 +#: peekaboo/ruleset/rules.py:139 msgid "File type is not on whitelist" msgstr "" -#: peekaboo/ruleset/rules.py:156 +#: peekaboo/ruleset/rules.py:158 msgid "File type is on the list of types to analyze" msgstr "" -#: peekaboo/ruleset/rules.py:161 +#: peekaboo/ruleset/rules.py:163 #, python-format msgid "File type is not on the list of types to analyse (%s)" msgstr "" -#: peekaboo/ruleset/rules.py:174 +#: peekaboo/ruleset/rules.py:176 msgid "The file contains an Office macro" msgstr "" -#: peekaboo/ruleset/rules.py:178 +#: peekaboo/ruleset/rules.py:180 msgid "The file does not contain a recognizable Office macro" msgstr "" -#: peekaboo/ruleset/rules.py:205 peekaboo/ruleset/rules.py:327 +#: peekaboo/ruleset/rules.py:210 peekaboo/ruleset/rules.py:332 msgid "" "Behavioral analysis by Cuckoo has produced an error and did not finish " "successfully" msgstr "" -#: peekaboo/ruleset/rules.py:239 +#: peekaboo/ruleset/rules.py:244 msgid "Empty list of malicious signatures" msgstr "" -#: peekaboo/ruleset/rules.py:257 +#: peekaboo/ruleset/rules.py:262 msgid "No signature suggesting malware detected" msgstr "" -#: peekaboo/ruleset/rules.py:262 +#: peekaboo/ruleset/rules.py:267 #, python-format msgid "The following signatures have been recognized: %s" msgstr "" -#: peekaboo/ruleset/rules.py:279 +#: peekaboo/ruleset/rules.py:284 #, python-format msgid "Cuckoo score >= %s: %s" msgstr "" -#: peekaboo/ruleset/rules.py:284 +#: peekaboo/ruleset/rules.py:289 #, python-format msgid "Cuckoo score < %s: %s" msgstr "" -#: peekaboo/ruleset/rules.py:300 +#: peekaboo/ruleset/rules.py:305 msgid "Empty domain list" msgstr "" -#: peekaboo/ruleset/rules.py:305 +#: peekaboo/ruleset/rules.py:310 #, python-format msgid "The file attempts to contact at least one domain on the blacklist (%s)" msgstr "" -#: peekaboo/ruleset/rules.py:311 +#: peekaboo/ruleset/rules.py:316 msgid "File does not seem to attempt contact with domains on the blacklist" msgstr "" -#: peekaboo/ruleset/rules.py:347 +#: peekaboo/ruleset/rules.py:352 msgid "Behavioral analysis by Cuckoo completed successfully" msgstr "" -#: peekaboo/ruleset/rules.py:364 +#: peekaboo/ruleset/rules.py:369 msgid "File does not seem to exhibit recognizable malicious behaviour" msgstr "" diff --git a/peekaboo/ruleset/engine.py b/peekaboo/ruleset/engine.py index 8b4287b..86b95e8 100644 --- a/peekaboo/ruleset/engine.py +++ b/peekaboo/ruleset/engine.py @@ -40,7 +40,7 @@ class RulesetEngine(object): @since: 1.6 """ - rules = [ + known_rules = [ KnownRule, FileLargerThanRule, FileTypeOnWhitelistRule, @@ -59,9 +59,14 @@ class RulesetEngine(object): self.config = ruleset_config self.db_con = db_con + # create a lookup table from rule name to class + self.rules = {} + for known_rule in self.known_rules: + self.rules[known_rule.rule_name] = known_rule + def run(self): - for rule in RulesetEngine.rules: - result = self.__exec_rule(self.sample, rule) + for rule in self.config.rule_config('rules').get('rule'): + result = self.__exec_rule(self.sample, self.rules[rule]) if not result.further_analysis: return @@ -75,18 +80,9 @@ class RulesetEngine(object): logger.debug("Processing rule '%s' for %s" % (rule_name, sample)) try: - # skip disabled rules. - if self.config.rule_enabled(rule_name): - rule_config = self.config.rule_config(rule_name) - rule = rule_class(config=rule_config, db_con=self.db_con) - result = rule.evaluate(sample) - else: - logger.debug("Rule '%s' is disabled." % rule_name) - result = RuleResult( - rule_name, result=Result.unchecked, - reason=_("Rule '%s' is disabled.") % rule_name, - further_analysis=True) - + rule_config = self.config.rule_config(rule_name) + rule = rule_class(config=rule_config, db_con=self.db_con) + result = rule.evaluate(sample) sample.add_rule_result(result) except PeekabooAnalysisDeferred: # in case the Sample is requesting the Cuckoo report diff --git a/peekaboo/ruleset/rules.py b/peekaboo/ruleset/rules.py index 120e4f5..a631cc1 100644 --- a/peekaboo/ruleset/rules.py +++ b/peekaboo/ruleset/rules.py @@ -40,6 +40,8 @@ class Rule(object): """ This is the base class for all rules. It provides common infrastructure such as resources that can be used by the rules (configuration, database connection) or helper functions. """ + rule_name = 'unimplemented' + def __init__(self, config=None, db_con=None): """ Initialize common configuration and resources """ self.db_con = db_con diff --git a/ruleset.conf.sample b/ruleset.conf.sample index cde5f5b..c8909a9 100644 --- a/ruleset.conf.sample +++ b/ruleset.conf.sample @@ -2,15 +2,23 @@ # Peekaboo ruleset configuration file # Copyright (C) 2016-2019 science + computing ag # -# rule specific configuration options -# the section name equals the name of the rule -# - -[known] -# if not specified the default is enabled : yes -enabled : yes +# list of rules to run on samples +[rules] +rule.1 : known +rule.2 : file_larger_than +rule.3 : file_type_on_whitelist +rule.4 : file_type_on_greylist +rule.5 : cuckoo_evil_sig +rule.6 : cuckoo_score +rule.7 : office_macro +#rule.8 : requests_evil_domain +rule.9 : cuckoo_analysis_failed +#rule.10 : contains_peekabooyar +rule.11 : final_rule +# rule specific configuration options +# the section name equals the name of the rule #[file_larger_than] # defaults: #bytes : 5 @@ -113,15 +121,10 @@ signature.43 : Wscript.exe initiated network communications indicative of a scri #higher_than : 4.0 [requests_evil_domain] -enabled : no # define a list of bad domains here domain.1 : canarytokens.com -# this rule is for testing only, so it is disabled by default -[contains_peekabooyar] -enabled : no - -[cuckoo_analysis_failed] +#[cuckoo_analysis_failed] # This rule checks whether analysis by Cuckoo failed. If so, it reports a # result of "failed" for this sample and aborts rule processing. In case of # success, result "unknown" is returned (because successful analysis in itself @@ -153,5 +156,7 @@ enabled : no #failure.1: end of analysis reached! # rules without configuration options: +# - known +# - contains_peekabooyar # - office_macro # - final_rule |