forked from p15670423/monkey
Merge branch 'attack_configuration' into attack_report
This commit is contained in:
commit
ef68bd9201
|
@ -101,7 +101,7 @@ def init_app(mongo_url):
|
||||||
|
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
database.init()
|
database.init()
|
||||||
Database.reset_db()
|
Database.init_db()
|
||||||
|
|
||||||
app.add_url_rule('/', 'serve_home', serve_home)
|
app.add_url_rule('/', 'serve_home', serve_home)
|
||||||
app.add_url_rule('/<path:static_path>', 'serve_static_file', serve_static_file)
|
app.add_url_rule('/<path:static_path>', 'serve_static_file', serve_static_file)
|
||||||
|
|
|
@ -23,3 +23,9 @@ class Database(object):
|
||||||
AttackConfig.reset_config()
|
AttackConfig.reset_config()
|
||||||
logger.info('DB was reset')
|
logger.info('DB was reset')
|
||||||
return jsonify(status='OK')
|
return jsonify(status='OK')
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def init_db():
|
||||||
|
if not mongo.db.collection_names():
|
||||||
|
Database.reset_db()
|
||||||
|
|
||||||
|
|
|
@ -96,24 +96,29 @@ class MatrixComponent extends AuthComponent {
|
||||||
return {'columns': columns, 'matrixTableData': matrixTableData, 'maxTechniques': maxTechniques}
|
return {'columns': columns, 'matrixTableData': matrixTableData, 'maxTechniques': maxTechniques}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
renderLegend = () => {
|
||||||
|
return (
|
||||||
|
<div id="header" className="row justify-content-between attack-legend">
|
||||||
|
<Col xs={4}>
|
||||||
|
<i className="fa fa-circle-thin icon-unchecked"></i>
|
||||||
|
<span> - Dissabled</span>
|
||||||
|
</Col>
|
||||||
|
<Col xs={4}>
|
||||||
|
<i className="fa fa-circle icon-checked"></i>
|
||||||
|
<span> - Enabled</span>
|
||||||
|
</Col>
|
||||||
|
<Col xs={4}>
|
||||||
|
<i className="fa fa-circle icon-mandatory"></i>
|
||||||
|
<span> - Mandatory</span>
|
||||||
|
</Col>
|
||||||
|
</div>)
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let tableData = this.getTableData(this.props.configuration);
|
let tableData = this.getTableData(this.props.configuration);
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div id="header" className="row justify-content-between attack-legend">
|
{this.renderLegend()}
|
||||||
<Col xs={4}>
|
|
||||||
<i className="fa fa-circle-thin icon-unchecked"></i>
|
|
||||||
<span> - Dissabled</span>
|
|
||||||
</Col>
|
|
||||||
<Col xs={4}>
|
|
||||||
<i className="fa fa-circle icon-checked"></i>
|
|
||||||
<span> - Enabled</span>
|
|
||||||
</Col>
|
|
||||||
<Col xs={4}>
|
|
||||||
<i className="fa fa-circle icon-mandatory"></i>
|
|
||||||
<span> - Mandatory</span>
|
|
||||||
</Col>
|
|
||||||
</div>
|
|
||||||
<div className={"attack-matrix"}>
|
<div className={"attack-matrix"}>
|
||||||
<ReactTable columns={tableData['columns']}
|
<ReactTable columns={tableData['columns']}
|
||||||
data={tableData['matrixTableData']}
|
data={tableData['matrixTableData']}
|
||||||
|
|
|
@ -21,7 +21,24 @@ class ConfigurePageComponent extends AuthComponent {
|
||||||
this.initialConfig = {};
|
this.initialConfig = {};
|
||||||
this.initialAttackConfig = {};
|
this.initialAttackConfig = {};
|
||||||
this.sectionsOrder = ['attack', 'basic', 'basic_network', 'monkey', 'cnc', 'network', 'exploits', 'internal'];
|
this.sectionsOrder = ['attack', 'basic', 'basic_network', 'monkey', 'cnc', 'network', 'exploits', 'internal'];
|
||||||
this.uiSchemas = {
|
this.uiSchemas = ConfigurePageComponent.getUiSchemas();
|
||||||
|
// set schema from server
|
||||||
|
this.state = {
|
||||||
|
schema: {},
|
||||||
|
configuration: {},
|
||||||
|
attackConfig: {},
|
||||||
|
lastAction: 'none',
|
||||||
|
sections: [],
|
||||||
|
selectedSection: 'attack',
|
||||||
|
allMonkeysAreDead: true,
|
||||||
|
PBAwinFile: [],
|
||||||
|
PBAlinuxFile: [],
|
||||||
|
showAttackAlert: false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static getUiSchemas(){
|
||||||
|
return ({
|
||||||
basic: {"ui:order": ["general", "credentials"]},
|
basic: {"ui:order": ["general", "credentials"]},
|
||||||
basic_network: {},
|
basic_network: {},
|
||||||
monkey: {
|
monkey: {
|
||||||
|
@ -54,20 +71,7 @@ class ConfigurePageComponent extends AuthComponent {
|
||||||
network: {},
|
network: {},
|
||||||
exploits: {},
|
exploits: {},
|
||||||
internal: {}
|
internal: {}
|
||||||
};
|
})
|
||||||
// set schema from server
|
|
||||||
this.state = {
|
|
||||||
schema: {},
|
|
||||||
configuration: {},
|
|
||||||
attackConfig: {},
|
|
||||||
lastAction: 'none',
|
|
||||||
sections: [],
|
|
||||||
selectedSection: 'attack',
|
|
||||||
allMonkeysAreDead: true,
|
|
||||||
PBAwinFile: [],
|
|
||||||
PBAlinuxFile: [],
|
|
||||||
showAttackAlert: false
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setInitialConfig(config) {
|
setInitialConfig(config) {
|
||||||
|
@ -138,7 +142,6 @@ class ConfigurePageComponent extends AuthComponent {
|
||||||
this.setState({lastAction: 'saved'})})
|
this.setState({lastAction: 'saved'})})
|
||||||
.then(this.updateConfig())
|
.then(this.updateConfig())
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
console.log('bad attack configuration');
|
|
||||||
this.setState({lastAction: 'invalid_configuration'});
|
this.setState({lastAction: 'invalid_configuration'});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -410,58 +413,79 @@ class ConfigurePageComponent extends AuthComponent {
|
||||||
return pbaFile
|
return pbaFile
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderMatrix = () => {
|
||||||
|
return (<MatrixComponent configuration={this.state.attackConfig}
|
||||||
|
submit={this.componentDidMount}
|
||||||
|
reset={this.resetConfig}
|
||||||
|
change={this.attackTechniqueChange}/>)
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
renderConfigContent = (displayedSchema) => {
|
||||||
|
return (<div>
|
||||||
|
{this.renderBasicNetworkWarning()}
|
||||||
|
<Form schema={displayedSchema}
|
||||||
|
uiSchema={this.uiSchemas[this.state.selectedSection]}
|
||||||
|
formData={this.state.configuration[this.state.selectedSection]}
|
||||||
|
onChange={this.onChange}
|
||||||
|
noValidate={true} >
|
||||||
|
<button type="submit" className={"hidden"}>Submit</button>
|
||||||
|
</Form>
|
||||||
|
</div> )
|
||||||
|
};
|
||||||
|
|
||||||
|
renderRunningMonkeysWarning = () => {
|
||||||
|
return (<div>
|
||||||
|
{ this.state.allMonkeysAreDead ?
|
||||||
|
'' :
|
||||||
|
<div className="alert alert-warning">
|
||||||
|
<i className="glyphicon glyphicon-warning-sign" style={{'marginRight': '5px'}}/>
|
||||||
|
Some monkeys are currently running. Note that changing the configuration will only apply to new
|
||||||
|
infections.
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>)
|
||||||
|
};
|
||||||
|
|
||||||
|
renderBasicNetworkWarning = () => {
|
||||||
|
if (this.state.selectedSection === 'basic_network'){
|
||||||
|
return (<div className="alert alert-info">
|
||||||
|
<i className="glyphicon glyphicon-info-sign" style={{'marginRight': '5px'}}/>
|
||||||
|
The Monkey scans its subnet if "Local network scan" is ticked. Additionally the monkey scans machines
|
||||||
|
according to its range class.
|
||||||
|
</div>)
|
||||||
|
} else {
|
||||||
|
return (<div />)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
renderNav = () => {
|
||||||
|
return (<Nav bsStyle="tabs" justified
|
||||||
|
activeKey={this.state.selectedSection} onSelect={this.setSelectedSection}
|
||||||
|
style={{'marginBottom': '2em'}}>
|
||||||
|
{this.state.sections.map(section => <NavItem key={section.key} eventKey={section.key}>{section.title}</NavItem>)}
|
||||||
|
</Nav>)
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let displayedSchema = {};
|
let displayedSchema = {};
|
||||||
if (this.state.schema.hasOwnProperty('properties') && this.state.selectedSection !== 'attack') {
|
if (this.state.schema.hasOwnProperty('properties') && this.state.selectedSection !== 'attack') {
|
||||||
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'];
|
||||||
}
|
}
|
||||||
let config_content = (<Form schema={displayedSchema}
|
|
||||||
uiSchema={this.uiSchemas[this.state.selectedSection]}
|
|
||||||
formData={this.state.configuration[this.state.selectedSection]}
|
|
||||||
onChange={this.onChange}
|
|
||||||
noValidate={true}>
|
|
||||||
<div>
|
|
||||||
{ this.state.allMonkeysAreDead ?
|
|
||||||
'' :
|
|
||||||
<div className="alert alert-warning">
|
|
||||||
<i className="glyphicon glyphicon-warning-sign" style={{'marginRight': '5px'}}/>
|
|
||||||
Some monkeys are currently running. Note that changing the configuration will only apply to new
|
|
||||||
infections.
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</Form>);
|
|
||||||
let attack_content = (<MatrixComponent configuration={this.state.attackConfig}
|
|
||||||
submit={this.componentDidMount}
|
|
||||||
reset={this.resetConfig}
|
|
||||||
change={this.attackTechniqueChange}/>);
|
|
||||||
let content = '';
|
let content = '';
|
||||||
if (this.state.selectedSection === 'attack' && Object.entries(this.state.attackConfig).length !== 0 ) {
|
if (this.state.selectedSection === 'attack' && Object.entries(this.state.attackConfig).length !== 0 ) {
|
||||||
content = attack_content
|
content = this.renderMatrix()
|
||||||
} else if(this.state.selectedSection !== 'attack') {
|
} else if(this.state.selectedSection !== 'attack') {
|
||||||
content = config_content
|
content = this.renderConfigContent(displayedSchema)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Col xs={12} lg={8}>
|
<Col xs={12} lg={8}>
|
||||||
{this.renderAttackAlertModal()}
|
{this.renderAttackAlertModal()}
|
||||||
<h1 className="page-title">Monkey Configuration</h1>
|
<h1 className="page-title">Monkey Configuration</h1>
|
||||||
<Nav bsStyle="tabs" justified
|
{this.renderNav()}
|
||||||
activeKey={this.state.selectedSection} onSelect={this.setSelectedSection}
|
{ this.renderRunningMonkeysWarning()}
|
||||||
style={{'marginBottom': '2em'}}>
|
|
||||||
{this.state.sections.map(section => <NavItem key={section.key} eventKey={section.key}>{section.title}</NavItem>)}
|
|
||||||
</Nav>
|
|
||||||
{
|
|
||||||
this.state.selectedSection === 'basic_network' ?
|
|
||||||
<div className="alert alert-info">
|
|
||||||
<i className="glyphicon glyphicon-info-sign" style={{'marginRight': '5px'}}/>
|
|
||||||
The Monkey scans its subnet if "Local network scan" is ticked. Additionally the monkey scans machines
|
|
||||||
according to its range class.
|
|
||||||
</div>
|
|
||||||
: <div />
|
|
||||||
}
|
|
||||||
{ content }
|
{ content }
|
||||||
<div className="text-center">
|
<div className="text-center">
|
||||||
<button type="submit" onClick={this.onSubmit} className="btn btn-success btn-lg" style={{margin: '5px'}}>
|
<button type="submit" onClick={this.onSubmit} className="btn btn-success btn-lg" style={{margin: '5px'}}>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
python-dateutil
|
python-dateutil
|
||||||
tornado
|
tornado==5.1.1
|
||||||
werkzeug
|
werkzeug
|
||||||
jinja2
|
jinja2
|
||||||
markupsafe
|
markupsafe
|
||||||
|
@ -9,14 +9,13 @@ flask
|
||||||
Flask-Pymongo
|
Flask-Pymongo
|
||||||
Flask-Restful
|
Flask-Restful
|
||||||
Flask-JWT
|
Flask-JWT
|
||||||
jsonschema
|
jsonschema==2.6.0
|
||||||
netifaces
|
netifaces
|
||||||
ipaddress
|
ipaddress
|
||||||
enum34
|
enum34
|
||||||
pycryptodome
|
pycryptodome
|
||||||
boto3
|
boto3
|
||||||
awscli
|
awscli
|
||||||
dpath
|
|
||||||
bson
|
bson
|
||||||
cffi
|
cffi
|
||||||
PyInstaller
|
PyInstaller
|
||||||
|
|
Loading…
Reference in New Issue