forked from p15670423/monkey
Added jwt requirements to PBA endpoints, fixed bugs, added different
display if PBA succeeded than if failed.
This commit is contained in:
parent
92615b848d
commit
be598d0953
|
@ -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()
|
||||
|
|
|
@ -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" : []
|
||||
}
|
||||
|
|
|
@ -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):
|
||||
"""
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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. "
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -198,7 +198,13 @@ class ConfigurePageComponent extends AuthComponent {
|
|||
|
||||
PBAwindows = () => {
|
||||
return (<FilePond
|
||||
server='/api/fileUpload/PBAwindows'
|
||||
server={{ url:'/api/fileUpload/PBAwindows',
|
||||
process: {headers: {'Authorization': this.jwtHeader}},
|
||||
revert: {headers: {'Authorization': this.jwtHeader}},
|
||||
restore: {headers: {'Authorization': this.jwtHeader}},
|
||||
load: {headers: {'Authorization': this.jwtHeader}},
|
||||
fetch: {headers: {'Authorization': this.jwtHeader}}
|
||||
}}
|
||||
files={this.getWinPBAfile()}
|
||||
onupdatefiles={fileItems => {
|
||||
this.setState({
|
||||
|
@ -211,7 +217,13 @@ class ConfigurePageComponent extends AuthComponent {
|
|||
|
||||
PBAlinux = () => {
|
||||
return (<FilePond
|
||||
server='/api/fileUpload/PBAlinux'
|
||||
server={{ url:'/api/fileUpload/PBAlinux',
|
||||
process: {headers: {'Authorization': this.jwtHeader}},
|
||||
revert: {headers: {'Authorization': this.jwtHeader}},
|
||||
restore: {headers: {'Authorization': this.jwtHeader}},
|
||||
load: {headers: {'Authorization': this.jwtHeader}},
|
||||
fetch: {headers: {'Authorization': this.jwtHeader}}
|
||||
}}
|
||||
files={this.getLinuxPBAfile()}
|
||||
onupdatefiles={fileItems => {
|
||||
this.setState({
|
||||
|
|
|
@ -13,9 +13,19 @@ let renderMachine = function (data) {
|
|||
return <div>{data.label} ( {renderIpAddresses(data)} )</div>
|
||||
};
|
||||
|
||||
let renderPbaResults = function (results) {
|
||||
let pbaClass = "";
|
||||
if (results[1]){
|
||||
pbaClass="pba-success"
|
||||
} else {
|
||||
pbaClass="pba-danger"
|
||||
}
|
||||
return <div className={pbaClass}> {results[0]} </div>
|
||||
};
|
||||
|
||||
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) {
|
||||
|
|
|
@ -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(<App />, document.getElementById('app'));
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -424,6 +424,14 @@ body {
|
|||
top: 30%;
|
||||
}
|
||||
|
||||
.pba-danger {
|
||||
background-color: #ffc7af;
|
||||
}
|
||||
|
||||
.pba-success {
|
||||
background-color: #afd2a2;
|
||||
}
|
||||
|
||||
/* Print report styling */
|
||||
|
||||
@media print {
|
||||
|
|
Loading…
Reference in New Issue