diff --git a/monkey/infection_monkey/config.py b/monkey/infection_monkey/config.py index 40a715e62..0d44cb973 100644 --- a/monkey/infection_monkey/config.py +++ b/monkey/infection_monkey/config.py @@ -271,10 +271,10 @@ class Configuration(object): extract_azure_creds = True post_breach_actions = [] - custom_pba_linux_cmd = "" - custom_pba_windows_cmd = "" - custom_pba_linux_file_info = None - custom_pba_windows_file_info = None + custom_PBA_linux_cmd = "" + custom_PBA_windows_cmd = "" + PBA_linux_filename = None + PBA_windows_filename = None WormConfiguration = Configuration() diff --git a/monkey/infection_monkey/example.conf b/monkey/infection_monkey/example.conf index 760ed1139..ca8041382 100644 --- a/monkey/infection_monkey/example.conf +++ b/monkey/infection_monkey/example.conf @@ -97,12 +97,5 @@ "use_file_logging": true, "victims_max_exploit": 7, "victims_max_find": 30, - "post_breach_actions" : [], - "custom_post_breach" : { "linux": "", - "windows": "", - "linux_file": None, - "windows_file": None, - "windows_file_info": None, - "linux_file_info": None - } + "post_breach_actions" : [] } diff --git a/monkey/infection_monkey/post_breach/file_execution.py b/monkey/infection_monkey/post_breach/file_execution.py index f76748141..025e1252a 100644 --- a/monkey/infection_monkey/post_breach/file_execution.py +++ b/monkey/infection_monkey/post_breach/file_execution.py @@ -24,15 +24,15 @@ class FileExecution(PBA): self.windows_filename = WormConfiguration.PBA_windows_filename super(FileExecution, self).__init__("File execution", linux_command, windows_command) - def execute_linux(self): + def _execute_linux(self): FileExecution.download_PBA_file(FileExecution.get_dest_dir(WormConfiguration, True), self.linux_filename) - return super(FileExecution, self).execute_linux() + return super(FileExecution, self)._execute_linux() - def execute_win(self): + def _execute_win(self): FileExecution.download_PBA_file(FileExecution.get_dest_dir(WormConfiguration, True), self.windows_filename) - return super(FileExecution, self).execute_win() + return super(FileExecution, self)._execute_win() def add_default_command(self, is_linux): """ diff --git a/monkey/infection_monkey/post_breach/pba.py b/monkey/infection_monkey/post_breach/pba.py index 3482c96e8..09fe613b3 100644 --- a/monkey/infection_monkey/post_breach/pba.py +++ b/monkey/infection_monkey/post_breach/pba.py @@ -36,7 +36,7 @@ class PBA(object): if command: hostname = socket.gethostname() ControlClient.send_telemetry('post_breach', {'command': command, - 'output': exec_funct(), + 'result': exec_funct(), 'name': self.name, 'hostname': hostname, 'ip': socket.gethostbyname(hostname) @@ -46,18 +46,23 @@ class PBA(object): """ Default linux PBA execution function. Override it if additional functionality is needed """ - self._execute_default(self.linux_command) + return self._execute_default(self.linux_command) def _execute_win(self): """ Default linux PBA execution function. Override it if additional functionality is needed """ - self._execute_default(self.windows_command) + return self._execute_default(self.windows_command) @staticmethod def _execute_default(command): + """ + Default post breach command execution routine + :param command: What command to execute + :return: Tuple of command's output string and boolean, indicating if it succeeded + """ try: - return subprocess.check_output(command, stderr=subprocess.STDOUT, shell=True) + return subprocess.check_output(command, stderr=subprocess.STDOUT, shell=True), True except subprocess.CalledProcessError as e: # Return error output of the command - return e.output + return e.output, False diff --git a/monkey/infection_monkey/post_breach/post_breach_handler.py b/monkey/infection_monkey/post_breach/post_breach_handler.py index e0f7135b1..4e9f269ac 100644 --- a/monkey/infection_monkey/post_breach/post_breach_handler.py +++ b/monkey/infection_monkey/post_breach/post_breach_handler.py @@ -51,22 +51,22 @@ class PostBreach(object): command_pba = PBA(name="Custom") # Add linux commands to PBA's - if config['PBA_linux_filename']: - if config['custom_PBA_linux_cmd']: - file_pba.linux_command = config['custom_PBA_linux_cmd'] + if config.PBA_linux_filename: + if config.custom_PBA_linux_cmd: + file_pba.linux_command = config.custom_PBA_linux_cmd else: file_pba.add_default_command(is_linux=True) - elif config['custom_PBA_linux_cmd']: - command_pba.linux_command = config['custom_PBA_linux_cmd'] + elif config.custom_PBA_linux_cmd: + command_pba.linux_command = config.custom_PBA_linux_cmd # Add windows commands to PBA's - if config['PBA_windows_filename']: - if config['custom_PBA_windows_cmd']: - file_pba.windows_command = config['custom_PBA_windows_cmd'] + if config.PBA_windows_filename: + if config.custom_PBA_windows_cmd: + file_pba.windows_command = config.custom_PBA_windows_cmd else: file_pba.add_default_command(is_linux=False) - elif config['custom_PBA_windows_cmd']: - command_pba.windows_command = config['custom_PBA_windows_cmd'] + elif config.custom_PBA_windows_cmd: + command_pba.windows_command = config.custom_PBA_windows_cmd # Add PBA's to list if file_pba.linux_command or file_pba.windows_command: diff --git a/monkey/monkey_island/cc/resources/pba_file_upload.py b/monkey/monkey_island/cc/resources/pba_file_upload.py index 3b0a85b52..08e4f752d 100644 --- a/monkey/monkey_island/cc/resources/pba_file_upload.py +++ b/monkey/monkey_island/cc/resources/pba_file_upload.py @@ -55,13 +55,13 @@ class FileUpload(flask_restful.Resource): :param file_type: Type indicates which file was deleted, linux of windows :return: Empty response """ - file_conf_path = PBA_LINUX_FILENAME_PATH if file_type == 'PBAlinux' else PBA_WINDOWS_FILENAME_PATH - filename = ConfigService.get_config_value(file_conf_path) + filename_path = PBA_LINUX_FILENAME_PATH if file_type == 'PBAlinux' else PBA_WINDOWS_FILENAME_PATH + filename = ConfigService.get_config_value(filename_path) file_path = os.path.join(UPLOADS_DIR, filename) try: if os.path.exists(file_path): os.remove(file_path) - ConfigService.set_config_value(file_conf_path, {'size': '0', 'name': ''}) + ConfigService.set_config_value(filename_path, '') except OSError as e: LOG.error("Can't remove previously uploaded post breach files: %s" % e) diff --git a/monkey/monkey_island/cc/services/config.py b/monkey/monkey_island/cc/services/config.py index 17bed6782..6e0eb66a6 100644 --- a/monkey/monkey_island/cc/services/config.py +++ b/monkey/monkey_island/cc/services/config.py @@ -4,9 +4,7 @@ import functools import logging from jsonschema import Draft4Validator, validators from six import string_types -from werkzeug.utils import secure_filename import os -import base64 from cc.database import mongo from cc.encryptor import encryptor @@ -36,7 +34,7 @@ ENCRYPTED_CONFIG_STRINGS = \ ['cnc', 'aws_config', 'aws_secret_access_key'] ] -UPLOADS_DIR = '/cc/userUploads' +UPLOADS_DIR = 'monkey_island/cc/userUploads' # Where to find file names in config PBA_WINDOWS_FILENAME_PATH = ['monkey', 'behaviour', 'PBA_windows_filename'] @@ -315,14 +313,12 @@ class ConfigService: @staticmethod def remove_PBA_files(): if ConfigService.get_config(): - linux_file_name = ConfigService.get_config_value( - ['monkey', 'behaviour', 'custom_post_breach', 'linux_file_info', 'name']) - windows_file_name = ConfigService.get_config_value( - ['monkey', 'behaviour', 'custom_post_breach', 'windows_file_info', 'name']) - if linux_file_name: - ConfigService.remove_file(linux_file_name) - if windows_file_name: - ConfigService.remove_file(windows_file_name) + linux_filename = ConfigService.get_config_value(PBA_WINDOWS_FILENAME_PATH) + windows_filename = ConfigService.get_config_value(PBA_LINUX_FILENAME_PATH) + if linux_filename: + ConfigService.remove_file(linux_filename) + if windows_filename: + ConfigService.remove_file(windows_filename) @staticmethod def remove_file(file_name): diff --git a/monkey/monkey_island/cc/services/config_schema.py b/monkey/monkey_island/cc/services/config_schema.py index d800afe9c..382b591db 100644 --- a/monkey/monkey_island/cc/services/config_schema.py +++ b/monkey/monkey_island/cc/services/config_schema.py @@ -329,13 +329,13 @@ SCHEMA = { "Reference your file by filename." }, "custom_PBA_windows_cmd": { - "title": "Windows command", + "title": "Windows post breach command", "type": "string", "default": "", "description": "Windows command to be executed after breaching." }, "PBA_windows_file": { - "title": "Windows file", + "title": "Windows post breach file", "type": "string", "format": "data-url", "description": "File to be executed after breaching. " diff --git a/monkey/monkey_island/cc/ui/src/components/AuthComponent.js b/monkey/monkey_island/cc/ui/src/components/AuthComponent.js index 428c3272a..9eb02a397 100644 --- a/monkey/monkey_island/cc/ui/src/components/AuthComponent.js +++ b/monkey/monkey_island/cc/ui/src/components/AuthComponent.js @@ -6,6 +6,7 @@ class AuthComponent extends React.Component { super(props); this.auth = new AuthService(); this.authFetch = this.auth.authFetch; + this.jwtHeader = this.auth.jwtHeader(); } } diff --git a/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js b/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js index d6b1a2156..bb369fa73 100644 --- a/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js +++ b/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js @@ -198,7 +198,13 @@ class ConfigurePageComponent extends AuthComponent { PBAwindows = () => { return ( { this.setState({ @@ -211,7 +217,13 @@ class ConfigurePageComponent extends AuthComponent { PBAlinux = () => { return ( { this.setState({ diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/PostBreach.js b/monkey/monkey_island/cc/ui/src/components/report-components/PostBreach.js index 5790e26e5..7fac2a167 100644 --- a/monkey/monkey_island/cc/ui/src/components/report-components/PostBreach.js +++ b/monkey/monkey_island/cc/ui/src/components/report-components/PostBreach.js @@ -13,9 +13,19 @@ let renderMachine = function (data) { return
{data.label} ( {renderIpAddresses(data)} )
}; +let renderPbaResults = function (results) { + let pbaClass = ""; + if (results[1]){ + pbaClass="pba-success" + } else { + pbaClass="pba-danger" + } + return
{results[0]}
+}; + const subColumns = [ {id: 'pba_name', Header: "Name", accessor: x => x.name, style: { 'white-space': 'unset' }}, - {id: 'pba_output', Header: "Output", accessor: x => x.output, style: { 'white-space': 'unset' }} + {id: 'pba_output', Header: "Output", accessor: x => renderPbaResults(x.result), style: { 'white-space': 'unset' }} ]; let renderDetails = function (data) { diff --git a/monkey/monkey_island/cc/ui/src/index.js b/monkey/monkey_island/cc/ui/src/index.js index 3a701b52e..329e94dfe 100644 --- a/monkey/monkey_island/cc/ui/src/index.js +++ b/monkey/monkey_island/cc/ui/src/index.js @@ -4,8 +4,6 @@ import ReactDOM from 'react-dom'; import 'babel-polyfill'; import App from './components/Main'; import Bootstrap from 'bootstrap/dist/css/bootstrap.css'; // eslint-disable-line no-unused-vars -import { FilePond, registerPlugin } from 'react-filepond'; -import 'filepond/dist/filepond.min.css'; // Render the main component into the dom ReactDOM.render(, document.getElementById('app')); diff --git a/monkey/monkey_island/cc/ui/src/services/AuthService.js b/monkey/monkey_island/cc/ui/src/services/AuthService.js index 547b14272..9c62bde63 100644 --- a/monkey/monkey_island/cc/ui/src/services/AuthService.js +++ b/monkey/monkey_island/cc/ui/src/services/AuthService.js @@ -15,6 +15,12 @@ export default class AuthService { return this._authFetch(url, options); }; + jwtHeader = () => { + if (this._loggedIn()) { + return 'JWT ' + this._getToken(); + } + }; + hashSha3(text) { let hash = new SHA3(512); hash.update(text); diff --git a/monkey/monkey_island/cc/ui/src/styles/App.css b/monkey/monkey_island/cc/ui/src/styles/App.css index 926052d7a..6155a4dcc 100644 --- a/monkey/monkey_island/cc/ui/src/styles/App.css +++ b/monkey/monkey_island/cc/ui/src/styles/App.css @@ -424,6 +424,14 @@ body { top: 30%; } +.pba-danger { + background-color: #ffc7af; +} + +.pba-success { + background-color: #afd2a2; +} + /* Print report styling */ @media print {