From a39a0c2ce6b49a392df4da89c89a0f5ddc5f424e Mon Sep 17 00:00:00 2001 From: Shreya Date: Tue, 21 Jul 2020 22:54:48 +0530 Subject: [PATCH] CR changes - Added nested classes - Extracted repetitive code --- .../actions/modify_shell_startup_files.py | 63 +++++++++---------- .../attack/technique_reports/T1156.py | 19 ++---- .../attack/technique_reports/T1504.py | 19 ++---- .../technique_report_tools.py | 21 +++++++ 4 files changed, 62 insertions(+), 60 deletions(-) diff --git a/monkey/infection_monkey/post_breach/actions/modify_shell_startup_files.py b/monkey/infection_monkey/post_breach/actions/modify_shell_startup_files.py index 57b44f5ed..3973724e0 100644 --- a/monkey/infection_monkey/post_breach/actions/modify_shell_startup_files.py +++ b/monkey/infection_monkey/post_breach/actions/modify_shell_startup_files.py @@ -18,48 +18,47 @@ class ModifyShellStartupFiles(PBA): """ def __init__(self): - super(ModifyShellStartupFiles, self).__init__(name=POST_BREACH_SHELL_STARTUP_FILE_MODIFICATION) + super().__init__(name=POST_BREACH_SHELL_STARTUP_FILE_MODIFICATION) def run(self): results = [pba.run() for pba in self.modify_shell_startup_PBA_list()] PostBreachTelem(self, results).send() def modify_shell_startup_PBA_list(self): - return ShellStartupPBAGenerator.get_modify_shell_startup_pbas() + return self.ShellStartupPBAGenerator().get_modify_shell_startup_pbas() + class ShellStartupPBAGenerator(): + def get_modify_shell_startup_pbas(self): + (cmds_for_linux, shell_startup_files_for_linux, usernames_for_linux),\ + (cmds_for_windows, shell_startup_files_per_user_for_windows) =\ + get_commands_to_modify_shell_startup_files() -class ShellStartupPBAGenerator(): - def get_modify_shell_startup_pbas(): - (cmds_for_linux, shell_startup_files_for_linux, usernames_for_linux),\ - (cmds_for_windows, shell_startup_files_per_user_for_windows) = get_commands_to_modify_shell_startup_files() + pbas = [] - pbas = [] + for startup_file_per_user in shell_startup_files_per_user_for_windows: + windows_cmds = ' '.join(cmds_for_windows).format(startup_file_per_user) + pbas.append(self.ModifyShellStartupFile(linux_cmds='', windows_cmds=['powershell.exe', windows_cmds])) - for startup_file_per_user in shell_startup_files_per_user_for_windows: - windows_cmds = ' '.join(cmds_for_windows).format(startup_file_per_user) - pbas.append(ModifyShellStartupFile(linux_cmds='', windows_cmds=['powershell.exe', windows_cmds])) + for username in usernames_for_linux: + for shell_startup_file in shell_startup_files_for_linux: + linux_cmds = ' '.join(cmds_for_linux).format(shell_startup_file).format(username) + pbas.append(self.ModifyShellStartupFile(linux_cmds=linux_cmds, windows_cmds='')) - for username in usernames_for_linux: - for shell_startup_file in shell_startup_files_for_linux: - linux_cmds = ' '.join(cmds_for_linux).format(shell_startup_file).format(username) - pbas.append(ModifyShellStartupFile(linux_cmds=linux_cmds, windows_cmds='')) + return pbas - return pbas + class ModifyShellStartupFile(PBA): + def __init__(self, linux_cmds, windows_cmds): + super().__init__(name=POST_BREACH_SHELL_STARTUP_FILE_MODIFICATION, + linux_cmd=linux_cmds, + windows_cmd=windows_cmds) - -class ModifyShellStartupFile(PBA): - def __init__(self, linux_cmds, windows_cmds): - super(ModifyShellStartupFile, self).__init__(name=POST_BREACH_SHELL_STARTUP_FILE_MODIFICATION, - linux_cmd=linux_cmds, - windows_cmd=windows_cmds) - - def run(self): - if self.command: - try: - output = subprocess.check_output(self.command, stderr=subprocess.STDOUT, shell=True).decode() - if not output: - output = EXECUTION_WITHOUT_OUTPUT - return output, True - except subprocess.CalledProcessError as e: - # Return error output of the command - return e.output.decode(), False + def run(self): + if self.command: + try: + output = subprocess.check_output(self.command, stderr=subprocess.STDOUT, shell=True).decode() + if not output: + output = EXECUTION_WITHOUT_OUTPUT + return output, True + except subprocess.CalledProcessError as e: + # Return error output of the command + return e.output.decode(), False diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1156.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1156.py index b1ef19251..c6ddcba93 100644 --- a/monkey/monkey_island/cc/services/attack/technique_reports/T1156.py +++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1156.py @@ -1,8 +1,9 @@ from common.data.post_breach_consts import \ POST_BREACH_SHELL_STARTUP_FILE_MODIFICATION -from common.utils.attack_utils import ScanStatus from monkey_island.cc.database import mongo from monkey_island.cc.services.attack.technique_reports import AttackTechnique +from monkey_island.cc.services.attack.technique_reports.technique_report_tools import \ + extract_shell_startup_files_modification_info, get_shell_startup_files_modification_status __author__ = "shreyamalviya" @@ -26,20 +27,10 @@ class T1156(AttackTechnique): shell_startup_files_modification_info = list(mongo.db.telemetry.aggregate(T1156.query)) - bash_startup_modification_info = [] - for shell_startup_file_result in shell_startup_files_modification_info[0]['result']: - # only want bash startup files - if any(file_name in shell_startup_file_result[0] for file_name in [".bash", ".profile"]): - bash_startup_modification_info.append({ - 'machine': shell_startup_files_modification_info[0]['machine'], - 'result': shell_startup_file_result - }) + bash_startup_modification_info =\ + extract_shell_startup_files_modification_info(shell_startup_files_modification_info, [".bash", ".profile"]) - status = [] - for bash_startup_file in bash_startup_modification_info: - status.append(bash_startup_file['result'][1]) - status = (ScanStatus.USED.value if any(status) else ScanStatus.SCANNED.value)\ - if status else ScanStatus.UNSCANNED.value + status = get_shell_startup_files_modification_status(bash_startup_modification_info) data.update(T1156.get_base_data_by_status(status)) data.update({'info': bash_startup_modification_info}) diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1504.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1504.py index 57f2bf21f..4fd0a475a 100644 --- a/monkey/monkey_island/cc/services/attack/technique_reports/T1504.py +++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1504.py @@ -1,8 +1,9 @@ from common.data.post_breach_consts import \ POST_BREACH_SHELL_STARTUP_FILE_MODIFICATION -from common.utils.attack_utils import ScanStatus from monkey_island.cc.database import mongo from monkey_island.cc.services.attack.technique_reports import AttackTechnique +from monkey_island.cc.services.attack.technique_reports.technique_report_tools import \ + extract_shell_startup_files_modification_info, get_shell_startup_files_modification_status __author__ = "shreyamalviya" @@ -26,20 +27,10 @@ class T1504(AttackTechnique): shell_startup_files_modification_info = list(mongo.db.telemetry.aggregate(T1504.query)) - powershell_startup_modification_info = [] - for shell_startup_file_result in shell_startup_files_modification_info[0]['result']: - # only want powershell startup files - if "profile.ps1" in shell_startup_file_result[0]: - powershell_startup_modification_info.append({ - 'machine': shell_startup_files_modification_info[0]['machine'], - 'result': shell_startup_file_result - }) + powershell_startup_modification_info =\ + extract_shell_startup_files_modification_info(shell_startup_files_modification_info, ["profile.ps1"]) - status = [] - for powershell_startup_file in powershell_startup_modification_info: - status.append(powershell_startup_file['result'][1]) - status = (ScanStatus.USED.value if any(status) else ScanStatus.SCANNED.value)\ - if status else ScanStatus.UNSCANNED.value + status = get_shell_startup_files_modification_status(powershell_startup_modification_info) data.update(T1504.get_base_data_by_status(status)) data.update({'info': powershell_startup_modification_info}) diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/technique_report_tools.py b/monkey/monkey_island/cc/services/attack/technique_reports/technique_report_tools.py index 80bfb952d..e7e2eb8e0 100644 --- a/monkey/monkey_island/cc/services/attack/technique_reports/technique_report_tools.py +++ b/monkey/monkey_island/cc/services/attack/technique_reports/technique_report_tools.py @@ -1,4 +1,5 @@ from monkey_island.cc.encryptor import encryptor +from common.utils.attack_utils import ScanStatus def parse_creds(attempt): @@ -44,3 +45,23 @@ def censor_hash(hash_, plain_chars=5): return "" hash_ = encryptor.dec(hash_) return hash_[0: plain_chars] + ' ...' + + +def extract_shell_startup_files_modification_info(shell_startup_files_modification_info, required_file_names): + required_shell_startup_files_modification_info = [] + for shell_startup_file_result in shell_startup_files_modification_info[0]['result']: + if any(file_name in shell_startup_file_result[0] for file_name in required_file_names): + shell_startup_files_modification_info.append({ + 'machine': shell_startup_files_modification_info[0]['machine'], + 'result': shell_startup_file_result + }) + return required_shell_startup_files_modification_info + + +def get_shell_startup_files_modification_status(shell_startup_files_modification_info): + status = [] + for startup_file in shell_startup_files_modification_info: + status.append(startup_file['result'][1]) + status = (ScanStatus.USED.value if any(status) else ScanStatus.SCANNED.value)\ + if status else ScanStatus.UNSCANNED.value + return status