From cc1f46af32c6548dbc28330fc916602c8bfbd713 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Fri, 22 Nov 2019 18:30:08 +0200 Subject: [PATCH] Moved attack matrix to attack report page --- .../cc/resources/attack/attack_report.py | 10 ++- .../cc/services/attack/attack_config.py | 12 +++ .../cc/services/attack/attack_report.py | 15 ++-- .../report-components/AttackReport.js | 27 +++--- .../report-components/attack/Matrix.js | 82 +++++++++++++++++++ .../src/components/ui-components/Checkbox.js | 12 ++- 6 files changed, 138 insertions(+), 20 deletions(-) create mode 100644 monkey/monkey_island/cc/ui/src/components/report-components/attack/Matrix.js diff --git a/monkey/monkey_island/cc/resources/attack/attack_report.py b/monkey/monkey_island/cc/resources/attack/attack_report.py index a55137d7e..dc63f6747 100644 --- a/monkey/monkey_island/cc/resources/attack/attack_report.py +++ b/monkey/monkey_island/cc/resources/attack/attack_report.py @@ -1,7 +1,8 @@ import flask_restful -from flask import jsonify from monkey_island.cc.auth import jwt_required from monkey_island.cc.services.attack.attack_report import AttackReportService +from monkey_island.cc.services.attack.attack_schema import SCHEMA +from flask import json, current_app __author__ = "VakarisZ" @@ -10,4 +11,9 @@ class AttackReport(flask_restful.Resource): @jwt_required() def get(self): - return jsonify(AttackReportService.get_latest_report()['techniques']) + response_content = {'techniques': AttackReportService.get_latest_report()['techniques'], 'schema': SCHEMA} + return current_app.response_class(json.dumps(response_content, + indent=None, + separators=(",", ":"), + sort_keys=False) + "\n", + mimetype=current_app.config['JSONIFY_MIMETYPE']) diff --git a/monkey/monkey_island/cc/services/attack/attack_config.py b/monkey/monkey_island/cc/services/attack/attack_config.py index 6feff990e..f834f259b 100644 --- a/monkey/monkey_island/cc/services/attack/attack_config.py +++ b/monkey/monkey_island/cc/services/attack/attack_config.py @@ -173,3 +173,15 @@ class AttackConfig(object): for key, technique in list(attack_type['properties'].items()): techniques[key] = technique['value'] return techniques + + @staticmethod + def get_techniques_for_report(): + """ + :return: Format: {"T1110": {"selected": True, "type": "Credential Access", "T1075": ...} + """ + attack_config = AttackConfig.get_config() + techniques = {} + for type_name, attack_type in list(attack_config.items()): + for key, technique in list(attack_type['properties'].items()): + techniques[key] = {'selected': technique['value'], 'type': SCHEMA['properties'][type_name]['title']} + return techniques diff --git a/monkey/monkey_island/cc/services/attack/attack_report.py b/monkey/monkey_island/cc/services/attack/attack_report.py index 10005bd26..43cca0876 100644 --- a/monkey/monkey_island/cc/services/attack/attack_report.py +++ b/monkey/monkey_island/cc/services/attack/attack_report.py @@ -58,13 +58,14 @@ class AttackReportService: 'name': REPORT_NAME } - for tech_id, value in list(AttackConfig.get_technique_values().items()): - if value: - try: - report['techniques'].update({tech_id: TECHNIQUES[tech_id].get_report_data()}) - except KeyError as e: - LOG.error("Attack technique does not have it's report component added " - "to attack report service. %s" % e) + for tech_id, tech_info in list(AttackConfig.get_techniques_for_report().items()): + try: + technique_report_data = TECHNIQUES[tech_id].get_report_data() + technique_report_data.update(tech_info) + report['techniques'].update({tech_id: technique_report_data}) + except KeyError as e: + LOG.error("Attack technique does not have it's report component added " + "to attack report service. %s" % e) mongo.db.attack_report.replace_one({'name': REPORT_NAME}, report, upsert=True) return report diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/AttackReport.js b/monkey/monkey_island/cc/ui/src/components/report-components/AttackReport.js index add32ad4a..7c5f6cdc4 100644 --- a/monkey/monkey_island/cc/ui/src/components/report-components/AttackReport.js +++ b/monkey/monkey_island/cc/ui/src/components/report-components/AttackReport.js @@ -6,6 +6,7 @@ import '../../styles/Collapse.scss'; import AuthComponent from '../AuthComponent'; import {ScanStatus} from '../attack/techniques/Helpers'; import Collapse from '@kunukn/react-collapse'; +import Matrix from './attack/Matrix'; import T1210 from '../attack/techniques/T1210'; import T1197 from '../attack/techniques/T1197'; @@ -66,7 +67,8 @@ class AttackReportPageComponent extends AuthComponent { constructor(props) { super(props); this.state = { - report: this.props.report, + techniques: this.props.report['techniques'], + schema: this.props.report['schema'], collapseOpen: '' }; } @@ -81,7 +83,7 @@ class AttackReportPageComponent extends AuthComponent { this.setState(state => ({collapseOpen: state.collapseOpen === technique ? null : technique})); getComponentClass(tech_id) { - switch (this.state.report[tech_id].status) { + switch (this.state.techniques[tech_id].status) { case ScanStatus.SCANNED: return 'collapse-info'; case ScanStatus.USED: @@ -95,7 +97,7 @@ class AttackReportPageComponent extends AuthComponent { return (