Report file structure created

This commit is contained in:
VakarisZ 2019-04-02 17:55:08 +03:00
parent 6da9b46167
commit bc09d59eb4
12 changed files with 183 additions and 4 deletions

View File

@ -33,6 +33,7 @@ from monkey_island.cc.consts import MONKEY_ISLAND_ABS_PATH
from monkey_island.cc.resources.pba_file_upload import FileUpload
from monkey_island.cc.resources.attack_telem import AttackTelem
from monkey_island.cc.resources.attack_config import AttackConfiguration
from monkey_island.cc.resources.attack_report import AttackReport
__author__ = 'Barak'
@ -126,7 +127,8 @@ 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(AttackConfiguration, '/api/attack')
api.add_resource(AttackTelem, '/api/attack/<string:technique>')
api.add_resource(AttackReport, '/api/attack/report')
api.add_resource(AttackConfiguration, '/api/attack')
return app

View File

@ -0,0 +1,13 @@
import flask_restful
from flask import jsonify
from cc.auth import jwt_required
from cc.services.attack.attack_report import AttackReportService
__author__ = "itay.mizeretz"
class AttackReport(flask_restful.Resource):
@jwt_required()
def get(self):
return jsonify(AttackReportService.get_report())

View File

@ -0,0 +1,18 @@
import logging
from cc.services.attack.technique_reports import T1210
__author__ = "VakarisZ"
logger = logging.getLogger(__name__)
class AttackReportService:
def __init__(self):
pass
@staticmethod
def get_report():
report = {}
report.update({'T1210': T1210.get_report_data()})
return report

View File

@ -0,0 +1,28 @@
from monkey_island.cc.services.attack.technique_reports.technique_service import technique_status, technique_title
from common.utils.attack_status_enum import ScanStatus
from cc.services.report import ReportService
__author__ = "VakarisZ"
TECHNIQUE = "T1210"
UNSCANNED_MSG = "Monkey didn't scan any remote services. Maybe it didn't find any machines on the network?"
SCANNED_MSG = "Monkey scanned for remote services on the network, but couldn't exploit any of them."
USED_MSG = "Monkey scanned for remote services and exploited some on the network."
def get_report_data():
data = {}
status = technique_status(TECHNIQUE)
title = technique_title(TECHNIQUE)
data.update({'status': status.name, 'title': title})
if status == ScanStatus.UNSCANNED:
data.update({'message': UNSCANNED_MSG})
return data
elif status == ScanStatus.SCANNED:
data.update({'message': SCANNED_MSG})
else:
data.update({'message': USED_MSG})
data.update({'scanned_machines': ReportService.get_scanned()})
data.update({'exploited_machines': ReportService.get_exploited()})
return data

View File

@ -0,0 +1,17 @@
from cc.database import mongo
from common.utils.attack_status_enum import ScanStatus
__author__ = "VakarisZ"
def technique_status(technique):
if mongo.db.attack_results.find_one({'status': ScanStatus.USED.value, 'technique': technique}):
return ScanStatus.USED
elif mongo.db.attack_results.find_one({'status': ScanStatus.SCANNED.value, 'technique': technique}):
return ScanStatus.SCANNED
else:
return ScanStatus.UNSCANNED
def technique_title(technique):
return technique+" title from SCHEMA"

View File

@ -221,6 +221,11 @@
}
}
},
"@kunukn/react-collapse": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/@kunukn/react-collapse/-/react-collapse-1.0.5.tgz",
"integrity": "sha512-688uUFLgwXWf9+rtE3hvYn3f43cjG6v/LzWDgcEGjoAV0b22VGbhDe5T1BAqujmjJ89IcJXKz1L8QW+5nu0fMQ=="
},
"@webassemblyjs/ast": {
"version": "1.7.8",
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.7.8.tgz",

View File

@ -64,6 +64,7 @@
"webpack-dev-server": "^3.1.9"
},
"dependencies": {
"@kunukn/react-collapse": "^1.0.5",
"bootstrap": "3.3.7",
"core-js": "^2.5.7",
"downloadjs": "^1.4.7",

View File

@ -15,6 +15,7 @@ import LicensePage from 'components/pages/LicensePage';
import AuthComponent from 'components/AuthComponent';
import LoginPageComponent from 'components/pages/LoginPage';
import AttckPage from 'components/pages/AttackPage'
import AttackReportPage from 'components/pages/AttackReportPage';
import 'normalize.css/normalize.css';
import 'react-data-components/css/table-twbs.css';
@ -156,7 +157,7 @@ class AppComponent extends AuthComponent {
<li>
<NavLink to="/attack_report">
<span className="number">5.</span>
Security Report
ATT&CK report
{this.state.completedSteps.attack_report_done ?
<Icon name="check" className="pull-right checkmark text-success"/>
: ''}
@ -197,6 +198,7 @@ class AppComponent extends AuthComponent {
{this.renderRoute('/infection/telemetry', <TelemetryPage onStatusChange={this.updateStatus}/>)}
{this.renderRoute('/start-over', <StartOverPage onStatusChange={this.updateStatus}/>)}
{this.renderRoute('/report', <ReportPage onStatusChange={this.updateStatus}/>)}
{this.renderRoute('/attack_report', <AttackReportPage onStatusChange={this.updateStatus}/>)}
{this.renderRoute('/license', <LicensePage onStatusChange={this.updateStatus}/>)}
{this.renderRoute('/attack', <AttckPage onStatusChange={this.updateStatus}/>)}
</Col>

View File

@ -0,0 +1,33 @@
import React from 'react';
import ReactTable from 'react-table'
import '../../styles/Collapse.scss'
import Collapse from '@kunukn/react-collapse';
let renderArray = function(val) {
return <div>{val.map(x => <div>{x}</div>)}</div>;
};
let renderIpAddresses = function (val) {
return <div>{renderArray(val.ip_addresses)} {(val.domain_name ? " (".concat(val.domain_name, ")") : "")} </div>;
};
const columns = [
];
const pageSize = 10;
class T1210 extends React.Component {
constructor(props) {
super(props);
}
render() {
console.log(this.props);
return (
<Collapse isOpen={true || false}>
<div>{this.props.data.message}</div>
</Collapse>
);
}
}
export default T1210;

View File

@ -3,21 +3,77 @@ import {Button, Col} from 'react-bootstrap';
import {ReactiveGraph} from 'components/reactive-graph/ReactiveGraph';
import {edgeGroupToColor, options} from 'components/map/MapOptions';
import AuthComponent from '../AuthComponent';
import T1210 from '../attack/T1210'
class AttackReportPageComponent extends AuthComponent {
constructor(props) {
super(props);
this.state = {
report: {},
allMonkeysAreDead: false,
runStarted: true
};
}
componentDidMount() {
this.updateMonkeysRunning().then(res => this.getReportFromServer(res));
}
updateMonkeysRunning = () => {
return this.authFetch('/api')
.then(res => res.json())
.then(res => {
// This check is used to prevent unnecessary re-rendering
this.setState({
allMonkeysAreDead: (!res['completed_steps']['run_monkey']) || (res['completed_steps']['infection_done']),
runStarted: res['completed_steps']['run_monkey']
});
return res;
});
};
getReportFromServer(res) {
if (res['completed_steps']['run_monkey']) {
this.authFetch('/api/attack/report')
.then(res => res.json())
.then(res => {
this.setState({
report: res
});
});
}
}
generateReportContent(){
let content = '';
Object.keys(this.state.report).forEach((Technique) => {
content = <T1210 data={this.state.report[Technique]} />;
});
return content
}
render() {
console.log(React.version);
let content;
if (Object.keys(this.state.report).length === 0) {
if (this.state.runStarted) {
content = (<h1>Generating Report...</h1>);
} else {
content =
<p className="alert alert-warning">
<i className="glyphicon glyphicon-warning-sign" style={{'marginRight': '5px'}}/>
You have to run a monkey before generating a report!
</p>;
}
} else {
content = this.generateReportContent();
}
return (
<Col xs={12} lg={8}>
<h1 className="page-title no-print">5.ATT&CK techniques report</h1>
<h1 className="page-title no-print">5. ATT&CK Report</h1>
<div style={{'fontSize': '1.2em'}}>
ATT&CK techniques report
{content}
</div>
</Col>
);

View File

@ -0,0 +1,4 @@
.collapse-css-transition {
transition: height 300ms cubic-bezier(0.4, 0, 0.2, 1);
overflow: hidden;
}