forked from p15670423/monkey
Configuration "reset to defaults" added
This commit is contained in:
parent
f5da1bf3b6
commit
cce76f37df
|
@ -29,7 +29,7 @@ from cc.resources.telemetry import Telemetry
|
||||||
from cc.resources.telemetry_feed import TelemetryFeed
|
from cc.resources.telemetry_feed import TelemetryFeed
|
||||||
from cc.resources.pba_file_download import PBAFileDownload
|
from cc.resources.pba_file_download import PBAFileDownload
|
||||||
from cc.resources.pba_file_upload import FileUpload
|
from cc.resources.pba_file_upload import FileUpload
|
||||||
from cc.resources.attack import AttckConfiguration
|
from cc.resources.attack import AttackConfiguration
|
||||||
from cc.services.config import ConfigService
|
from cc.services.config import ConfigService
|
||||||
|
|
||||||
__author__ = 'Barak'
|
__author__ = 'Barak'
|
||||||
|
@ -124,6 +124,6 @@ def init_app(mongo_url):
|
||||||
'/api/fileUpload/<string:file_type>?load=<string:filename>',
|
'/api/fileUpload/<string:file_type>?load=<string:filename>',
|
||||||
'/api/fileUpload/<string:file_type>?restore=<string:filename>')
|
'/api/fileUpload/<string:file_type>?restore=<string:filename>')
|
||||||
api.add_resource(RemoteRun, '/api/remote-monkey', '/api/remote-monkey/')
|
api.add_resource(RemoteRun, '/api/remote-monkey', '/api/remote-monkey/')
|
||||||
api.add_resource(AttckConfiguration, '/api/attack')
|
api.add_resource(AttackConfiguration, '/api/attack')
|
||||||
|
|
||||||
return app
|
return app
|
||||||
|
|
|
@ -6,13 +6,18 @@ from cc.auth import jwt_required
|
||||||
from cc.services.attack.attack import AttackService
|
from cc.services.attack.attack import AttackService
|
||||||
|
|
||||||
|
|
||||||
class AttckConfiguration(flask_restful.Resource):
|
class AttackConfiguration(flask_restful.Resource):
|
||||||
@jwt_required()
|
@jwt_required()
|
||||||
def get(self):
|
def get(self):
|
||||||
return jsonify(configuration=AttackService.get_config()['properties'])
|
return jsonify(configuration=AttackService.get_config()['properties'])
|
||||||
|
|
||||||
@jwt_required()
|
@jwt_required()
|
||||||
def post(self):
|
def post(self):
|
||||||
|
config_json = json.loads(request.data)
|
||||||
|
if 'reset_attack_matrix' in config_json:
|
||||||
|
AttackService.reset_config()
|
||||||
|
return jsonify(configuration=AttackService.get_config()['properties'])
|
||||||
|
else:
|
||||||
AttackService.update_config({'properties': json.loads(request.data)})
|
AttackService.update_config({'properties': json.loads(request.data)})
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
|
|
@ -162,7 +162,7 @@ class AppComponent extends AuthComponent {
|
||||||
|
|
||||||
<hr/>
|
<hr/>
|
||||||
<ul>
|
<ul>
|
||||||
<li><NavLink to="/attck">ATT&CK Configuration</NavLink></li>
|
<li><NavLink to="/attack">ATT&CK Configuration</NavLink></li>
|
||||||
<li><NavLink to="/configure">Configuration</NavLink></li>
|
<li><NavLink to="/configure">Configuration</NavLink></li>
|
||||||
<li><NavLink to="/infection/telemetry">Log</NavLink></li>
|
<li><NavLink to="/infection/telemetry">Log</NavLink></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -188,7 +188,7 @@ class AppComponent extends AuthComponent {
|
||||||
{this.renderRoute('/start-over', <StartOverPage onStatusChange={this.updateStatus}/>)}
|
{this.renderRoute('/start-over', <StartOverPage onStatusChange={this.updateStatus}/>)}
|
||||||
{this.renderRoute('/report', <ReportPage onStatusChange={this.updateStatus}/>)}
|
{this.renderRoute('/report', <ReportPage onStatusChange={this.updateStatus}/>)}
|
||||||
{this.renderRoute('/license', <LicensePage onStatusChange={this.updateStatus}/>)}
|
{this.renderRoute('/license', <LicensePage onStatusChange={this.updateStatus}/>)}
|
||||||
{this.renderRoute('/attck', <AttckPage onStatusChange={this.updateStatus}/>)}
|
{this.renderRoute('/attack', <AttckPage onStatusChange={this.updateStatus}/>)}
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
|
@ -46,15 +46,18 @@ let parseTechniques = function (data, maxLen) {
|
||||||
class MatrixComponent extends AuthComponent {
|
class MatrixComponent extends AuthComponent {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {lastAction: 'none', matrixData: this.props.configuration};
|
|
||||||
// Copy configuration and parse it for ATT&CK matrix table
|
// Copy configuration and parse it for ATT&CK matrix table
|
||||||
let configCopy = JSON.parse(JSON.stringify(this.props.configuration));
|
let configCopy = JSON.parse(JSON.stringify(this.props.configuration));
|
||||||
this.maxTechniques = findMaxTechniques(Object.values(configCopy));
|
this.state = {lastAction: 'none',
|
||||||
this.data = parseTechniques(Object.values(configCopy), this.maxTechniques);
|
configData: this.props.configuration,
|
||||||
}
|
maxTechniques: findMaxTechniques(Object.values(configCopy))};
|
||||||
|
this.state.matrixTableData = parseTechniques(Object.values(configCopy), this.state.maxTechniques);
|
||||||
|
this.state.columns = this.getColumns(this.state.matrixTableData)
|
||||||
|
};
|
||||||
|
|
||||||
getColumns() {
|
|
||||||
return Object.keys(this.data[0]).map((key)=>{
|
getColumns(matrixData) {
|
||||||
|
return Object.keys(matrixData[0]).map((key)=>{
|
||||||
return {
|
return {
|
||||||
Header: key,
|
Header: key,
|
||||||
id: key,
|
id: key,
|
||||||
|
@ -84,7 +87,7 @@ class MatrixComponent extends AuthComponent {
|
||||||
{
|
{
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {'Content-Type': 'application/json'},
|
headers: {'Content-Type': 'application/json'},
|
||||||
body: JSON.stringify(this.state.matrixData)
|
body: JSON.stringify(this.state.configData)
|
||||||
})
|
})
|
||||||
.then(res => {
|
.then(res => {
|
||||||
if (!res.ok)
|
if (!res.ok)
|
||||||
|
@ -102,26 +105,54 @@ class MatrixComponent extends AuthComponent {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
handleTechniqueChange = (technique, value) => {
|
resetConfig = () => {
|
||||||
Object.entries(this.state.matrixData).forEach(techType => {
|
this.authFetch('/api/attack',
|
||||||
if(techType[1].properties.hasOwnProperty(technique)){
|
{
|
||||||
let tempMatrix = this.state.matrixData;
|
method: 'POST',
|
||||||
tempMatrix[techType[0]].properties[technique].value = value;
|
headers: {'Content-Type': 'application/json'},
|
||||||
this.setState({matrixData: tempMatrix});
|
body: JSON.stringify('reset_attack_matrix')
|
||||||
}
|
})
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(res => {
|
||||||
|
this.updateStateFromConfig(res.configuration, 'reset')
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
updateStateFromConfig = (config, lastAction = '') => {
|
||||||
|
let configCopy = JSON.parse(JSON.stringify(config));
|
||||||
|
let maxTechniques = findMaxTechniques(Object.values(configCopy));
|
||||||
|
let matrixTableData = parseTechniques(Object.values(configCopy), maxTechniques);
|
||||||
|
let columns = this.getColumns(matrixTableData);
|
||||||
|
this.setState({
|
||||||
|
lastAction: lastAction,
|
||||||
|
configData: config,
|
||||||
|
maxTechniques: maxTechniques,
|
||||||
|
matrixTableData: matrixTableData,
|
||||||
|
columns: columns
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
handleTechniqueChange = (technique, value) => {
|
||||||
|
// Change value on configuration
|
||||||
|
Object.entries(this.state.configData).forEach(techType => {
|
||||||
|
if(techType[1].properties.hasOwnProperty(technique)){
|
||||||
|
let tempMatrix = this.state.configData;
|
||||||
|
tempMatrix[techType[0]].properties[technique].value = value;
|
||||||
|
this.updateStateFromConfig(tempMatrix);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let columns = this.getColumns();
|
|
||||||
return (
|
return (
|
||||||
<div className={"attack-matrix"}>
|
<div className={"attack-matrix"}>
|
||||||
<form onSubmit={this.onSubmit}>
|
<form onSubmit={this.onSubmit}>
|
||||||
<ReactTable
|
<ReactTable
|
||||||
columns={columns}
|
columns={this.state.columns}
|
||||||
data={this.data}
|
data={this.state.matrixTableData}
|
||||||
showPagination={false}
|
showPagination={false}
|
||||||
defaultPageSize={this.maxTechniques} />
|
defaultPageSize={this.state.maxTechniques} />
|
||||||
<div className={"messages"}>
|
<div className={"messages"}>
|
||||||
{ this.state.lastAction === 'reset' ?
|
{ this.state.lastAction === 'reset' ?
|
||||||
<div className="alert alert-success">
|
<div className="alert alert-success">
|
||||||
|
@ -146,6 +177,9 @@ class MatrixComponent extends AuthComponent {
|
||||||
<button type="button" onClick={this.onSubmit} className="btn btn-success btn-lg" style={{margin: '5px'}}>
|
<button type="button" onClick={this.onSubmit} className="btn btn-success btn-lg" style={{margin: '5px'}}>
|
||||||
Apply to configuration
|
Apply to configuration
|
||||||
</button>
|
</button>
|
||||||
|
<button type="button" onClick={this.resetConfig} className="btn btn-danger btn-lg" style={{margin: '5px'}}>
|
||||||
|
Reset to default matrix
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>);
|
</div>);
|
||||||
|
|
Loading…
Reference in New Issue