forked from p15670423/monkey
Sketches of config implementation
This commit is contained in:
parent
1c847ccc06
commit
d2670be767
|
@ -28,8 +28,9 @@ from cc.resources.root import Root
|
||||||
from cc.resources.telemetry import Telemetry
|
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.services.config import ConfigService
|
|
||||||
from cc.resources.pba_file_upload import FileUpload
|
from cc.resources.pba_file_upload import FileUpload
|
||||||
|
from cc.resources.attck import AttckConfiguration
|
||||||
|
from cc.services.config import ConfigService
|
||||||
|
|
||||||
__author__ = 'Barak'
|
__author__ = 'Barak'
|
||||||
|
|
||||||
|
@ -123,5 +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/attck')
|
||||||
|
|
||||||
return app
|
return app
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
import flask_restful
|
||||||
|
from flask import jsonify
|
||||||
|
|
||||||
|
from cc.auth import jwt_required
|
||||||
|
from cc.services.attck.attck import AttckService
|
||||||
|
|
||||||
|
|
||||||
|
class AttckConfiguration(flask_restful.Resource):
|
||||||
|
@jwt_required()
|
||||||
|
def get(self):
|
||||||
|
return jsonify(schema=AttckService.get_config_schema(),
|
||||||
|
configuration=AttckService.get_config())
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
__author__ = 'VakarisZ'
|
|
@ -0,0 +1,43 @@
|
||||||
|
import logging
|
||||||
|
from cc.database import mongo
|
||||||
|
from attck_schema import SCHEMA
|
||||||
|
from jsonschema import Draft4Validator, validators
|
||||||
|
|
||||||
|
__author__ = "VakarisZ"
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class AttckService:
|
||||||
|
default_config = None
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_config():
|
||||||
|
config = mongo.db.attck.find_one({'name': 'newconfig'}) or AttckService.get_default_config()
|
||||||
|
return config
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_config_schema():
|
||||||
|
return SCHEMA
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def reset_config():
|
||||||
|
config = AttckService.get_default_config()
|
||||||
|
AttckService.update_config(config)
|
||||||
|
logger.info('Monkey config reset was called')
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def update_config(config_json):
|
||||||
|
mongo.db.attck.update({'name': 'newconfig'}, {"$set": config_json}, upsert=True)
|
||||||
|
logger.info('Attck config was updated')
|
||||||
|
return True
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_default_config():
|
||||||
|
if not AttckService.default_config:
|
||||||
|
AttckService.update_config(SCHEMA)
|
||||||
|
AttckService.default_config = SCHEMA
|
||||||
|
return AttckService.default_config
|
|
@ -0,0 +1,46 @@
|
||||||
|
SCHEMA = {
|
||||||
|
"title": "ATT&CK configuration",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"lateral_movement": {
|
||||||
|
"title": "Lateral movement",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"T1210": {
|
||||||
|
"title": "T1210 Exploitation of Remote services",
|
||||||
|
"type": "bool",
|
||||||
|
"default": True,
|
||||||
|
"description": "Exploitation of a software vulnerability occurs when an adversary "
|
||||||
|
"takes advantage of a programming error in a program, service, or within the "
|
||||||
|
"operating system software or kernel itself to execute adversary-controlled code."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"credential_access": {
|
||||||
|
"title": "Credential access",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"T1110": {
|
||||||
|
"title": "T1110 Brute force",
|
||||||
|
"type": "bool",
|
||||||
|
"default": True,
|
||||||
|
"description": "Adversaries may use brute force techniques to attempt access to accounts "
|
||||||
|
"when passwords are unknown or when password hashes are obtained."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"defence_evasion": {
|
||||||
|
"title": "Defence evasion",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"T1197": {
|
||||||
|
"title": "T1197 Bits jobs",
|
||||||
|
"type": "bool",
|
||||||
|
"default": True,
|
||||||
|
"description": "Adversaries may abuse BITS to download, execute, "
|
||||||
|
"and even clean up after running malicious code."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,6 +14,7 @@ import ReportPage from 'components/pages/ReportPage';
|
||||||
import LicensePage from 'components/pages/LicensePage';
|
import LicensePage from 'components/pages/LicensePage';
|
||||||
import AuthComponent from 'components/AuthComponent';
|
import AuthComponent from 'components/AuthComponent';
|
||||||
import LoginPageComponent from 'components/pages/LoginPage';
|
import LoginPageComponent from 'components/pages/LoginPage';
|
||||||
|
import AttckPage from 'components/pages/AttckPage'
|
||||||
|
|
||||||
import 'normalize.css/normalize.css';
|
import 'normalize.css/normalize.css';
|
||||||
import 'react-data-components/css/table-twbs.css';
|
import 'react-data-components/css/table-twbs.css';
|
||||||
|
@ -161,6 +162,7 @@ class AppComponent extends AuthComponent {
|
||||||
|
|
||||||
<hr/>
|
<hr/>
|
||||||
<ul>
|
<ul>
|
||||||
|
<li><NavLink to="/attck">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>
|
||||||
|
@ -186,6 +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}/>)}
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
|
|
||||||
// ATT&CK component
|
|
||||||
class AttackComponent extends React.Component {
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<div className="data-table-container">
|
|
||||||
ATT&CK component
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default AttackComponent;
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
import React from 'react';
|
||||||
|
import Form from 'react-jsonschema-form';
|
||||||
|
import {Col, Nav, NavItem} from 'react-bootstrap';
|
||||||
|
import AuthComponent from '../AuthComponent';
|
||||||
|
import 'filepond/dist/filepond.min.css';
|
||||||
|
|
||||||
|
class AttckComponent extends AuthComponent {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.currentSection = 'ATT&CK matrix';
|
||||||
|
this.currentFormData = {};
|
||||||
|
this.sectionsOrder = ['ATT&CK matrix'];
|
||||||
|
// set schema from server
|
||||||
|
this.state = {
|
||||||
|
schema: {},
|
||||||
|
configuration: {},
|
||||||
|
lastAction: 'none',
|
||||||
|
sections: [],
|
||||||
|
selectedSection: 'ATT&CK matrix',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.authFetch('/api/attck')
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(res => {
|
||||||
|
let sections = [];
|
||||||
|
for (let sectionKey of this.sectionsOrder) {
|
||||||
|
sections.push({key: sectionKey, title: res.configuration.title});
|
||||||
|
}
|
||||||
|
this.setState({
|
||||||
|
schema: res.schema,
|
||||||
|
configuration: res.configuration,
|
||||||
|
sections: sections,
|
||||||
|
selectedSection: 'ATT&CK matrix'
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (<Col xs={12} lg={8}> Vakaris </Col>);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AttckComponent;
|
|
@ -3,7 +3,6 @@ import Form from 'react-jsonschema-form';
|
||||||
import {Col, Nav, NavItem} from 'react-bootstrap';
|
import {Col, Nav, NavItem} from 'react-bootstrap';
|
||||||
import fileDownload from 'js-file-download';
|
import fileDownload from 'js-file-download';
|
||||||
import AuthComponent from '../AuthComponent';
|
import AuthComponent from '../AuthComponent';
|
||||||
import AttackComponent from 'components/config-components/Att&ck'
|
|
||||||
import { FilePond } from 'react-filepond';
|
import { FilePond } from 'react-filepond';
|
||||||
import 'filepond/dist/filepond.min.css';
|
import 'filepond/dist/filepond.min.css';
|
||||||
|
|
||||||
|
@ -14,8 +13,6 @@ class ConfigurePageComponent extends AuthComponent {
|
||||||
this.PBAlinuxPond = null;
|
this.PBAlinuxPond = null;
|
||||||
this.currentSection = 'basic';
|
this.currentSection = 'basic';
|
||||||
this.currentFormData = {};
|
this.currentFormData = {};
|
||||||
this.sectionsOrder = ['basic', 'basic_network', 'monkey', 'cnc', 'network', 'exploits', 'internal', 'ATT&CK'];
|
|
||||||
|
|
||||||
this.sectionsOrder = ['basic', 'basic_network', 'monkey', 'cnc', 'network', 'exploits', 'internal'];
|
this.sectionsOrder = ['basic', 'basic_network', 'monkey', 'cnc', 'network', 'exploits', 'internal'];
|
||||||
this.uiSchema = {
|
this.uiSchema = {
|
||||||
behaviour: {
|
behaviour: {
|
||||||
|
@ -280,6 +277,7 @@ class ConfigurePageComponent extends AuthComponent {
|
||||||
displayedSchema = this.state.schema['properties'][this.state.selectedSection];
|
displayedSchema = this.state.schema['properties'][this.state.selectedSection];
|
||||||
displayedSchema['definitions'] = this.state.schema['definitions'];
|
displayedSchema['definitions'] = this.state.schema['definitions'];
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Col xs={12} lg={8}>
|
<Col xs={12} lg={8}>
|
||||||
<h1 className="page-title">Monkey Configuration</h1>
|
<h1 className="page-title">Monkey Configuration</h1>
|
||||||
|
@ -299,14 +297,11 @@ class ConfigurePageComponent extends AuthComponent {
|
||||||
</div>
|
</div>
|
||||||
: <div />
|
: <div />
|
||||||
}
|
}
|
||||||
{ this.state.selectedSection === 'ATT&CK' ?
|
{ this.state.selectedSection ?
|
||||||
<AttackComponent/> : this.state.selectedSection ?
|
|
||||||
<Form schema={displayedSchema}
|
<Form schema={displayedSchema}
|
||||||
uiSchema={this.uiSchema}
|
|
||||||
formData={this.state.configuration[this.state.selectedSection]}
|
formData={this.state.configuration[this.state.selectedSection]}
|
||||||
onSubmit={this.onSubmit}
|
onSubmit={this.onSubmit}
|
||||||
onChange={this.onChange}
|
onChange={this.onChange}>
|
||||||
noValidate={true}>
|
|
||||||
<div>
|
<div>
|
||||||
{ this.state.allMonkeysAreDead ?
|
{ this.state.allMonkeysAreDead ?
|
||||||
'' :
|
'' :
|
||||||
|
@ -369,6 +364,7 @@ class ConfigurePageComponent extends AuthComponent {
|
||||||
</div>
|
</div>
|
||||||
: ''}
|
: ''}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</Col>
|
</Col>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue