Configuration "reset to defaults" added

This commit is contained in:
VakarisZ 2019-03-25 21:37:55 +02:00
parent f5da1bf3b6
commit cce76f37df
4 changed files with 64 additions and 25 deletions

View File

@ -29,7 +29,7 @@ from cc.resources.telemetry import Telemetry
from cc.resources.telemetry_feed import TelemetryFeed
from cc.resources.pba_file_download import PBAFileDownload
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
__author__ = 'Barak'
@ -124,6 +124,6 @@ def init_app(mongo_url):
'/api/fileUpload/<string:file_type>?load=<string:filename>',
'/api/fileUpload/<string:file_type>?restore=<string:filename>')
api.add_resource(RemoteRun, '/api/remote-monkey', '/api/remote-monkey/')
api.add_resource(AttckConfiguration, '/api/attack')
api.add_resource(AttackConfiguration, '/api/attack')
return app

View File

@ -6,13 +6,18 @@ from cc.auth import jwt_required
from cc.services.attack.attack import AttackService
class AttckConfiguration(flask_restful.Resource):
class AttackConfiguration(flask_restful.Resource):
@jwt_required()
def get(self):
return jsonify(configuration=AttackService.get_config()['properties'])
@jwt_required()
def post(self):
AttackService.update_config({'properties': json.loads(request.data)})
return {}
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)})
return {}

View File

@ -162,7 +162,7 @@ class AppComponent extends AuthComponent {
<hr/>
<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="/infection/telemetry">Log</NavLink></li>
</ul>
@ -188,7 +188,7 @@ class AppComponent extends AuthComponent {
{this.renderRoute('/start-over', <StartOverPage onStatusChange={this.updateStatus}/>)}
{this.renderRoute('/report', <ReportPage 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>
</Row>
</Grid>

View File

@ -46,15 +46,18 @@ let parseTechniques = function (data, maxLen) {
class MatrixComponent extends AuthComponent {
constructor(props) {
super(props);
this.state = {lastAction: 'none', matrixData: this.props.configuration};
// Copy configuration and parse it for ATT&CK matrix table
let configCopy = JSON.parse(JSON.stringify(this.props.configuration));
this.maxTechniques = findMaxTechniques(Object.values(configCopy));
this.data = parseTechniques(Object.values(configCopy), this.maxTechniques);
}
this.state = {lastAction: 'none',
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 {
Header: key,
id: key,
@ -84,7 +87,7 @@ class MatrixComponent extends AuthComponent {
{
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(this.state.matrixData)
body: JSON.stringify(this.state.configData)
})
.then(res => {
if (!res.ok)
@ -102,26 +105,54 @@ class MatrixComponent extends AuthComponent {
});
};
handleTechniqueChange = (technique, value) => {
Object.entries(this.state.matrixData).forEach(techType => {
if(techType[1].properties.hasOwnProperty(technique)){
let tempMatrix = this.state.matrixData;
tempMatrix[techType[0]].properties[technique].value = value;
this.setState({matrixData: tempMatrix});
}
resetConfig = () => {
this.authFetch('/api/attack',
{
method: 'POST',
headers: {'Content-Type': 'application/json'},
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() {
let columns = this.getColumns();
return (
<div className={"attack-matrix"}>
<form onSubmit={this.onSubmit}>
<ReactTable
columns={columns}
data={this.data}
columns={this.state.columns}
data={this.state.matrixTableData}
showPagination={false}
defaultPageSize={this.maxTechniques} />
defaultPageSize={this.state.maxTechniques} />
<div className={"messages"}>
{ this.state.lastAction === 'reset' ?
<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'}}>
Apply to configuration
</button>
<button type="button" onClick={this.resetConfig} className="btn btn-danger btn-lg" style={{margin: '5px'}}>
Reset to default matrix
</button>
</div>
</form>
</div>);