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 1ab524e64..57b44f5ed 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 @@ -1,8 +1,13 @@ +import subprocess + from common.data.post_breach_consts import \ POST_BREACH_SHELL_STARTUP_FILE_MODIFICATION from infection_monkey.post_breach.pba import PBA from infection_monkey.post_breach.shell_startup_files.shell_startup_files_modification import \ get_commands_to_modify_shell_startup_files +from infection_monkey.telemetry.post_breach_telem import PostBreachTelem + +EXECUTION_WITHOUT_OUTPUT = "(PBA execution produced no output)" class ModifyShellStartupFiles(PBA): @@ -12,8 +17,12 @@ class ModifyShellStartupFiles(PBA): and profile.ps1 in windows. """ + def __init__(self): + super(ModifyShellStartupFiles, self).__init__(name=POST_BREACH_SHELL_STARTUP_FILE_MODIFICATION) + def run(self): - [pba.run() for pba in self.modify_shell_startup_PBA_list()] + 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() @@ -43,3 +52,14 @@ class ModifyShellStartupFile(PBA): 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 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 4c8f0d11f..b1ef19251 100644 --- a/monkey/monkey_island/cc/services/attack/technique_reports/T1156.py +++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1156.py @@ -14,8 +14,7 @@ class T1156(AttackTechnique): used_msg = "Monkey modified bash startup files on the system." query = [{'$match': {'telem_category': 'post_breach', - 'data.name': POST_BREACH_SHELL_STARTUP_FILE_MODIFICATION, - 'data.command': {'$regex': 'bash'}}}, + 'data.name': POST_BREACH_SHELL_STARTUP_FILE_MODIFICATION}}, {'$project': {'_id': 0, 'machine': {'hostname': '$data.hostname', 'ips': ['$data.ip']}, @@ -25,14 +24,23 @@ class T1156(AttackTechnique): def get_report_data(): data = {'title': T1156.technique_title(), 'info': []} - bash_modification_info = list(mongo.db.telemetry.aggregate(T1156.query)) + 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 + }) status = [] - for pba_node in bash_modification_info: - status.append(pba_node['result'][1]) + 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 data.update(T1156.get_base_data_by_status(status)) - data.update({'info': bash_modification_info}) + data.update({'info': bash_startup_modification_info}) return data 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 a9aeb38b7..57f2bf21f 100644 --- a/monkey/monkey_island/cc/services/attack/technique_reports/T1504.py +++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1504.py @@ -14,8 +14,7 @@ class T1504(AttackTechnique): used_msg = "Monkey modified powershell startup files on the system." query = [{'$match': {'telem_category': 'post_breach', - 'data.name': POST_BREACH_SHELL_STARTUP_FILE_MODIFICATION, - 'data.command': {'$regex': 'powershell'}}}, + 'data.name': POST_BREACH_SHELL_STARTUP_FILE_MODIFICATION}}, {'$project': {'_id': 0, 'machine': {'hostname': '$data.hostname', 'ips': ['$data.ip']}, @@ -25,14 +24,23 @@ class T1504(AttackTechnique): def get_report_data(): data = {'title': T1504.technique_title(), 'info': []} - powershell_profile_modification_info = list(mongo.db.telemetry.aggregate(T1504.query)) + 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 + }) status = [] - for pba_node in powershell_profile_modification_info: - status.append(pba_node['result'][1]) + 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 data.update(T1504.get_base_data_by_status(status)) - data.update({'info': powershell_profile_modification_info}) + data.update({'info': powershell_startup_modification_info}) return data