diff --git a/monkey/infection_monkey/exploit/__init__.py b/monkey/infection_monkey/exploit/__init__.py index 7353d77bc..84dd81393 100644 --- a/monkey/infection_monkey/exploit/__init__.py +++ b/monkey/infection_monkey/exploit/__init__.py @@ -24,7 +24,8 @@ class HostExploiter(object): 'started': '', 'finished': '', 'vulnerable_urls': [], - 'vulnerable_ports': []} + 'vulnerable_ports': [], + 'executed_cmds': []} self._exploit_attempts = [] self.host = host diff --git a/monkey/infection_monkey/exploit/hadoop.py b/monkey/infection_monkey/exploit/hadoop.py index f02c4f3d3..1e8ac9d8e 100644 --- a/monkey/infection_monkey/exploit/hadoop.py +++ b/monkey/infection_monkey/exploit/hadoop.py @@ -49,6 +49,7 @@ class HadoopExploiter(WebRCE): return False http_thread.join(self.DOWNLOAD_TIMEOUT) http_thread.stop() + self._exploit_info['executed_cmds'].append(command) return True def exploit(self, url, command): diff --git a/monkey/infection_monkey/exploit/mssqlexec.py b/monkey/infection_monkey/exploit/mssqlexec.py index c7d29c8c2..1f21f9ecd 100644 --- a/monkey/infection_monkey/exploit/mssqlexec.py +++ b/monkey/infection_monkey/exploit/mssqlexec.py @@ -76,7 +76,7 @@ class MSSQLExploiter(HostExploiter): commands.extend(monkey_args) MSSQLExploiter.execute_command(cursor, commands) MSSQLExploiter.run_file(cursor, tmp_file_path) - + self._exploit_info['executed_cmds'].append(commands[-1]) return True @staticmethod diff --git a/monkey/infection_monkey/exploit/rdpgrinder.py b/monkey/infection_monkey/exploit/rdpgrinder.py index 8e219b5c8..dcbc01b1d 100644 --- a/monkey/infection_monkey/exploit/rdpgrinder.py +++ b/monkey/infection_monkey/exploit/rdpgrinder.py @@ -343,5 +343,5 @@ class RdpExploiter(HostExploiter): LOG.info("Executed monkey '%s' on remote victim %r", os.path.basename(src_path), self.host) - + self._exploit_info['executed_cmds'].append(command) return True diff --git a/monkey/infection_monkey/exploit/shellshock.py b/monkey/infection_monkey/exploit/shellshock.py index 2f6e3516f..b308c57fe 100644 --- a/monkey/infection_monkey/exploit/shellshock.py +++ b/monkey/infection_monkey/exploit/shellshock.py @@ -144,6 +144,7 @@ class ShellShockExploiter(HostExploiter): if not (self.check_remote_file_exists(url, header, exploit, self._config.monkey_log_path_linux)): LOG.info("Log file does not exist, monkey might not have run") continue + self._exploit_info['executed_cmds'].append(cmdline) return True return False diff --git a/monkey/infection_monkey/exploit/sshexec.py b/monkey/infection_monkey/exploit/sshexec.py index 09982876d..9aafae2a4 100644 --- a/monkey/infection_monkey/exploit/sshexec.py +++ b/monkey/infection_monkey/exploit/sshexec.py @@ -178,6 +178,7 @@ class SSHExploiter(HostExploiter): self._config.dropper_target_path_linux, self.host, cmdline) ssh.close() + self._exploit_info['executed_cmds'].append(cmdline) return True except Exception as exc: diff --git a/monkey/infection_monkey/exploit/vsftpd.py b/monkey/infection_monkey/exploit/vsftpd.py index 3f6a7c304..23a89a96e 100644 --- a/monkey/infection_monkey/exploit/vsftpd.py +++ b/monkey/infection_monkey/exploit/vsftpd.py @@ -138,6 +138,7 @@ class VSFTPDExploiter(HostExploiter): if backdoor_socket.send(run_monkey): LOG.info("Executed monkey '%s' on remote victim %r (cmdline=%r)", self._config.dropper_target_path_linux, self.host, run_monkey) + self._exploit_info['executed_cmds'].append(run_monkey) return True else: return False diff --git a/monkey/infection_monkey/exploit/web_rce.py b/monkey/infection_monkey/exploit/web_rce.py index 2b08575c3..57a4cfa60 100644 --- a/monkey/infection_monkey/exploit/web_rce.py +++ b/monkey/infection_monkey/exploit/web_rce.py @@ -419,6 +419,8 @@ class WebRCE(HostExploiter): LOG.error("Something went wrong when trying to execute remote monkey: %s" % e) return False LOG.info("Execution attempt finished") + + self._exploit_info['executed_cmds'].append(command) return resp def get_monkey_upload_path(self, url_to_monkey): diff --git a/monkey/infection_monkey/exploit/win_ms08_067.py b/monkey/infection_monkey/exploit/win_ms08_067.py index 41b3820d5..72fca6d1d 100644 --- a/monkey/infection_monkey/exploit/win_ms08_067.py +++ b/monkey/infection_monkey/exploit/win_ms08_067.py @@ -92,7 +92,7 @@ class SRVSVC_Exploit(object): def get_telnet_port(self): """get_telnet_port() - + The port on which the Telnet service will listen. """ @@ -100,7 +100,7 @@ class SRVSVC_Exploit(object): def start(self): """start() -> socket - + Exploit the target machine and return a socket connected to it's listening Telnet service. """ @@ -153,6 +153,7 @@ class SRVSVC_Exploit(object): class Ms08_067_Exploiter(HostExploiter): _TARGET_OS_TYPE = ['windows'] + _EXPLOITED_SERVICE = 'Microsoft Server Service' _windows_versions = {'Windows Server 2003 3790 Service Pack 2': WindowsVersion.Windows2003_SP2, 'Windows Server 2003 R2 3790 Service Pack 2': WindowsVersion.Windows2003_SP2} diff --git a/monkey/monkey_island/cc/services/attack/attack_report.py b/monkey/monkey_island/cc/services/attack/attack_report.py index b1079d8c7..4ec62d7a2 100644 --- a/monkey/monkey_island/cc/services/attack/attack_report.py +++ b/monkey/monkey_island/cc/services/attack/attack_report.py @@ -1,5 +1,5 @@ import logging -from monkey_island.cc.services.attack.technique_reports import T1210, T1197, T1110, T1075, T1003 +from monkey_island.cc.services.attack.technique_reports import T1210, T1197, T1110, T1075, T1003, T1059 from monkey_island.cc.services.attack.attack_telem import AttackTelemService from monkey_island.cc.services.attack.attack_config import AttackConfig from monkey_island.cc.database import mongo @@ -13,7 +13,8 @@ TECHNIQUES = {'T1210': T1210.T1210, 'T1197': T1197.T1197, 'T1110': T1110.T1110, 'T1075': T1075.T1075, - 'T1003': T1003.T1003} + 'T1003': T1003.T1003, + 'T1059': T1059.T1059} REPORT_NAME = 'new_report' diff --git a/monkey/monkey_island/cc/services/attack/attack_schema.py b/monkey/monkey_island/cc/services/attack/attack_schema.py index 2a59103ad..a79b57a87 100644 --- a/monkey/monkey_island/cc/services/attack/attack_schema.py +++ b/monkey/monkey_island/cc/services/attack/attack_schema.py @@ -84,5 +84,19 @@ SCHEMA = { } } }, + "execution": { + "title": "Execution", + "type": "object", + "properties": { + "T1059": { + "title": "T1059 Command line interface", + "type": "bool", + "value": True, + "necessary": True, + "description": "Adversaries may use command-line interfaces to interact with systems " + "and execute other software during the course of an operation.", + } + } + }, } } diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1059.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1059.py new file mode 100644 index 000000000..bf29247fd --- /dev/null +++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1059.py @@ -0,0 +1,30 @@ +from monkey_island.cc.services.attack.technique_reports import AttackTechnique +from common.utils.attack_utils import ScanStatus +from monkey_island.cc.database import mongo + +__author__ = "VakarisZ" + + +class T1059(AttackTechnique): + + tech_id = "T1059" + unscanned_msg = "Monkey didn't exploit any machines to run commands at." + scanned_msg = "" + used_msg = "Monkey successfully ran commands on exploited machines in the network." + + query = [{'$match': {'telem_type': 'exploit', + 'data.info.executed_cmds': {'$not': {'$size': 0}}}}, + {'$project': {'_id': 0, + 'machine': '$data.machine', + 'info': '$data.info'}}, + {'$group': {'_id': '$machine', 'data': {'$push': '$$ROOT'}}}] + + @staticmethod + def get_report_data(): + cmd_data = list(mongo.db.telemetry.aggregate(T1059.query)) + data = {'title': T1059.technique_title(T1059.tech_id), 'data': cmd_data} + if cmd_data: + data.update({'message': T1059.used_msg, 'status': ScanStatus.USED.name}) + else: + data.update({'message': T1059.unscanned_msg, 'status': ScanStatus.UNSCANNED.name}) + return data diff --git a/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1059.js b/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1059.js new file mode 100644 index 000000000..1cf93065f --- /dev/null +++ b/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1059.js @@ -0,0 +1,38 @@ +import React from 'react'; +import '../../../styles/Collapse.scss' +import ReactTable from "react-table"; +import { RenderMachine } from "./Helpers" + + +class T1059 extends React.Component { + + constructor(props) { + super(props); + } + + static getHashColumns() { + return ([{ + columns: [ + {Header: 'Machine', id: 'machine', accessor: x => RenderMachine(x.machine), style: { 'whiteSpace': 'unset' }}, + {Header: 'Command', id: 'command', accessor: x => x.attempts[0].hashType, style: { 'whiteSpace': 'unset' }}, + ] + }])}; + + render() { + return ( +