From b4fdb13e8ab9b8bba1de86d7f73de3e56c64de8d Mon Sep 17 00:00:00 2001 From: phantinuss <79651203+phantinuss@users.noreply.github.com> Date: Tue, 10 May 2022 11:07:40 +0200 Subject: [PATCH] chore: test rules: check for unused selections --- .../proc_creation_lnx_webshell_detection.yml | 10 +++--- ...oc_creation_win_reg_defender_tampering.yml | 3 +- .../proc_creation_win_reg_lsass_ppl.yml | 3 +- tests/test_rules.py | 32 +++++++++++++++++++ 4 files changed, 41 insertions(+), 7 deletions(-) diff --git a/rules/linux/process_creation/proc_creation_lnx_webshell_detection.yml b/rules/linux/process_creation/proc_creation_lnx_webshell_detection.yml index 6a8b600a2..4816e3fe1 100644 --- a/rules/linux/process_creation/proc_creation_lnx_webshell_detection.yml +++ b/rules/linux/process_creation/proc_creation_lnx_webshell_detection.yml @@ -5,7 +5,7 @@ description: Detects suspicious sub processes of web server processes references: - https://www.acunetix.com/blog/articles/web-shells-101-using-php-introduction-web-shells-part-2/ date: 2021/10/15 -modified: 2022/03/14 +modified: 2022/05/09 author: Florian Roth tags: - attack.persistence @@ -26,18 +26,18 @@ detection: ParentCommandLine|contains|all: - '/bin/java' - 'tomcat' - selection_websphere: # ? just guessing + selection_websphere: # ? just guessing ParentCommandLine|contains|all: - '/bin/java' - 'websphere' selection_sub_processes: - Image|endswith: + Image|endswith: - '/whoami' - '/ifconfig' - '/usr/bin/ip' - '/bin/uname' - condition: selection_sub_processes and ( selection_general or selection_tomcat ) + condition: selection_sub_processes and ( selection_general or selection_tomcat or selection_websphere) falsepositives: - - Web applications that invoke Linux command line tools + - Web applications that invoke Linux command line tools level: critical diff --git a/rules/windows/process_creation/proc_creation_win_reg_defender_tampering.yml b/rules/windows/process_creation/proc_creation_win_reg_defender_tampering.yml index 5a5d32ced..88b58785a 100644 --- a/rules/windows/process_creation/proc_creation_win_reg_defender_tampering.yml +++ b/rules/windows/process_creation/proc_creation_win_reg_defender_tampering.yml @@ -6,6 +6,7 @@ references: - https://thedfirreport.com/2022/03/21/apt35-automates-initial-access-using-proxyshell/ author: Florian Roth date: 2022/03/22 +modified: 2022/05/09 logsource: category: process_creation product: windows @@ -22,7 +23,7 @@ detection: CommandLine|contains: - 'Real-Time Protection' - 'TamperProtection' - condition: selection + condition: selection and selection_target falsepositives: - Legitimate use level: high diff --git a/rules/windows/process_creation/proc_creation_win_reg_lsass_ppl.yml b/rules/windows/process_creation/proc_creation_win_reg_lsass_ppl.yml index b84fc5db8..5a2eaee7f 100644 --- a/rules/windows/process_creation/proc_creation_win_reg_lsass_ppl.yml +++ b/rules/windows/process_creation/proc_creation_win_reg_lsass_ppl.yml @@ -6,6 +6,7 @@ references: - https://thedfirreport.com/2022/03/21/apt35-automates-initial-access-using-proxyshell/ author: Florian Roth date: 2022/03/22 +modified: 2022/05/09 logsource: category: process_creation product: windows @@ -21,7 +22,7 @@ detection: CommandLine|contains: - 'Real-Time Protection' - 'TamperProtection' - condition: selection + condition: selection and selection_target falsepositives: - Unlikely level: high diff --git a/tests/test_rules.py b/tests/test_rules.py index bc444666c..c3d3af0c6 100755 --- a/tests/test_rules.py +++ b/tests/test_rules.py @@ -749,6 +749,38 @@ class TestRules(unittest.TestCase): self.assertEqual(faulty_rules, [], Fore.RED + "There are rules using list with only 1 element") + def test_unused_selection(self): + faulty_rules = [] + for file in self.yield_next_rule_file_path(self.path_to_rules): + detection = self.get_rule_part(file_path=file, part_name="detection") + condition = detection["condition"] + wildcard_selections = re.compile(r"\sof\s([\w\*]+)(?:$|\s|\))") + + # skip rules containing aggregations + if type(condition) == list: + continue + + for selection in detection: + if selection == "condition": + continue + if selection == "timeframe": + continue + if selection in condition: + continue + # find all wildcards in condition + found = False + for wildcard_selection in wildcard_selections.findall(condition): + # wildcard matches selection + if re.search(wildcard_selection.replace(r"*", r".*"), selection) is not None: + found = True + break + # selection was not found in condition + if not found: + print(Fore.RED + "Rule {} has an unused selection '{}'".format(file, selection)) + faulty_rules.append(file) + + self.assertEqual(faulty_rules, [], Fore.RED + "There are rules with unused selections") + def test_condition_operator_casesensitive(self): faulty_rules = [] for file in self.yield_next_rule_file_path(self.path_to_rules):