Selected technique is shown bellow matrix in attack report

This commit is contained in:
VakarisZ 2019-11-25 17:44:27 +02:00
parent 111b762f23
commit 1e9c9c196b
4 changed files with 107 additions and 14 deletions

View File

@ -8,6 +8,7 @@ import AuthComponent from '../AuthComponent';
import {ScanStatus} from '../attack/techniques/Helpers'; import {ScanStatus} from '../attack/techniques/Helpers';
import Collapse from '@kunukn/react-collapse'; import Collapse from '@kunukn/react-collapse';
import Matrix from './attack/ReportMatrix'; import Matrix from './attack/ReportMatrix';
import SelectedTechnique from './attack/SelectedTechnique';
import T1210 from '../attack/techniques/T1210'; import T1210 from '../attack/techniques/T1210';
import T1197 from '../attack/techniques/T1197'; import T1197 from '../attack/techniques/T1197';
@ -34,7 +35,7 @@ import T1016 from '../attack/techniques/T1016';
import T1021 from '../attack/techniques/T1021'; import T1021 from '../attack/techniques/T1021';
import T1064 from '../attack/techniques/T1064'; import T1064 from '../attack/techniques/T1064';
const tech_components = { const techComponents = {
'T1210': T1210, 'T1210': T1210,
'T1197': T1197, 'T1197': T1197,
'T1110': T1110, 'T1110': T1110,
@ -63,14 +64,15 @@ const tech_components = {
const classNames = require('classnames'); const classNames = require('classnames');
class AttackReportPageComponent extends AuthComponent { class AttackReport extends AuthComponent {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
techniques: this.props.report['techniques'], techniques: this.props.report['techniques'],
schema: this.props.report['schema'], schema: this.props.report['schema'],
collapseOpen: '' selectedTechnique: false,
collapseOpen: '',
}; };
} }
@ -83,8 +85,17 @@ class AttackReportPageComponent extends AuthComponent {
onToggle = technique => onToggle = technique =>
this.setState(state => ({collapseOpen: state.collapseOpen === technique ? null : technique})); this.setState(state => ({collapseOpen: state.collapseOpen === technique ? null : technique}));
getComponentClass(tech_id) { onTechniqueSelect = (technique, value, mapped = false) => {
switch (this.state.techniques[tech_id].status) { //this.setState({selectedTechnique: technique});
let selectedTechnique = this.getTechniqueByTitle(technique);
if (selectedTechnique === false){
return;
}
this.setState({selectedTechnique: selectedTechnique.tech_id})
};
static getComponentClass(tech_id, techniques) {
switch (techniques[tech_id].status) {
case ScanStatus.SCANNED: case ScanStatus.SCANNED:
return 'collapse-info'; return 'collapse-info';
case ScanStatus.USED: case ScanStatus.USED:
@ -97,7 +108,8 @@ class AttackReportPageComponent extends AuthComponent {
getTechniqueCollapse(tech_id) { getTechniqueCollapse(tech_id) {
return ( return (
<div key={tech_id} className={classNames('collapse-item', {'item--active': this.state.collapseOpen === tech_id})}> <div key={tech_id} className={classNames('collapse-item', {'item--active': this.state.collapseOpen === tech_id})}>
<button className={classNames('btn-collapse', this.getComponentClass(tech_id))} onClick={() => this.onToggle(tech_id)}> <button className={classNames('btn-collapse', AttackReport.getComponentClass(tech_id, this.state.techniques))}
onClick={() => this.onToggle(tech_id)}>
<span>{this.state.techniques[tech_id].title}</span> <span>{this.state.techniques[tech_id].title}</span>
<span> <span>
<i className={classNames('fa', this.state.collapseOpen === tech_id ? 'fa-chevron-down' : 'fa-chevron-up')}></i> <i className={classNames('fa', this.state.collapseOpen === tech_id ? 'fa-chevron-down' : 'fa-chevron-up')}></i>
@ -118,7 +130,7 @@ class AttackReportPageComponent extends AuthComponent {
} }
createTechniqueContent(collapseState, technique) { createTechniqueContent(collapseState, technique) {
const TechniqueComponent = tech_components[technique]; const TechniqueComponent = techComponents[technique];
return ( return (
<div className={`content ${collapseState}`}> <div className={`content ${collapseState}`}>
<TechniqueComponent data={this.state.techniques[technique]}/> <TechniqueComponent data={this.state.techniques[technique]}/>
@ -161,7 +173,10 @@ class AttackReportPageComponent extends AuthComponent {
This report shows information about ATT&CK techniques used by Infection Monkey. This report shows information about ATT&CK techniques used by Infection Monkey.
</p> </p>
{this.renderLegend()} {this.renderLegend()}
<Matrix techniques={this.state.techniques} schema={this.state.schema}/> <Matrix techniques={this.state.techniques} schema={this.state.schema} onClick={this.onTechniqueSelect}/>
<SelectedTechnique techComponents={techComponents}
techniques={this.state.techniques}
selected={this.state.selectedTechnique}/>
<div> <div>
<section className="attack-report">{content}</section> <section className="attack-report">{content}</section>
</div> </div>
@ -170,6 +185,17 @@ class AttackReportPageComponent extends AuthComponent {
) )
} }
getTechniqueByTitle(title){
for (let tech_id in this.state.techniques){
let technique = this.state.techniques[tech_id];
if (technique.title === title){
technique['tech_id'] = tech_id;
return technique
}
}
return false;
}
render() { render() {
if (Object.keys(this.state.techniques).length === 0 && this.state.runStarted) { if (Object.keys(this.state.techniques).length === 0 && this.state.runStarted) {
return (<h1>No techniques were scanned</h1>); return (<h1>No techniques were scanned</h1>);
@ -179,4 +205,4 @@ class AttackReportPageComponent extends AuthComponent {
} }
} }
export default AttackReportPageComponent; export default AttackReport;

View File

@ -8,7 +8,7 @@ class MatrixComponent extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = {techniques: this.props.techniques, this.state = {techniques: this.props.techniques,
schema: this.props.schema} schema: this.props.schema};
} }
getColumns() { getColumns() {
@ -21,7 +21,7 @@ class MatrixComponent extends React.Component {
columns.push({ columns.push({
Header: () => (<a href={tech_type.link}>{tech_type.title}</a>), Header: () => (<a href={tech_type.link}>{tech_type.title}</a>),
id: type_key, id: type_key,
accessor: x => MatrixComponent.renderTechnique(x[tech_type.title]), accessor: x => this.renderTechnique(x[tech_type.title]),
style: {'whiteSpace': 'unset'} style: {'whiteSpace': 'unset'}
}); });
} }
@ -51,15 +51,15 @@ class MatrixComponent extends React.Component {
return rows; return rows;
} }
static renderTechnique(technique) { renderTechnique(technique) {
if (technique == null || typeof technique === undefined) { if (technique == null || typeof technique === undefined) {
return (<div/>) return (<div/>)
} else { } else {
return ( return (
<Checkbox checked={technique.selected} <Checkbox checked={technique.selected}
necessary={true} necessary={false}
name={technique.title} name={technique.title}
changeHandler={function(){}} changeHandler={this.props.onClick}
status={technique.status}> status={technique.status}>
{technique.title} {technique.title}
</Checkbox>) </Checkbox>)

View File

@ -0,0 +1,66 @@
import React from "react";
import Collapse from '@kunukn/react-collapse';
import AttackReport from '../AttackReport';
const classNames = require('classnames');
class SelectedTechnique extends React.Component {
constructor(props) {
super(props);
this.state = {
techniques: this.props.techniques,
techComponents: this.props.techComponents,
selectedTechnique: this.props.selected
};
}
componentDidUpdate(prevProps) {
if (this.props.selected !== prevProps.selected) {
this.setState({ selectedTechnique: this.props.selected })
}
}
getSelectedTechniqueComponent(tech_id) {
const TechniqueComponent = this.state.techComponents[tech_id];
return (
<div key={tech_id} className={classNames('collapse-item', {'item--active': true})}>
<button className={classNames('btn-collapse', AttackReport.getComponentClass(tech_id, this.state.techniques))}>
<span>{this.state.techniques[tech_id].title}</span>
</button>
<Collapse
className="collapse-comp"
isOpen={true}
render={() => {
return (<div className={`content ${tech_id}`}>
<TechniqueComponent data={this.state.techniques[tech_id]}/>
</div>)
}}/>
</div>
);
}
render(){
let content = {};
let selectedTechId = this.state.selectedTechnique;
if(selectedTechId === false){
content = "Select a technique from attack matrix";
} else {
content = this.getSelectedTechniqueComponent(selectedTechId)
}
return (
<div>
<h4 className="selected-technique-title">Selected technique:</h4>
<section className="attack-report selected-technique">
{content}
</section>
</div>
)
}
}
export default SelectedTechnique;

View File

@ -14,6 +14,7 @@ class CheckboxComponent extends React.PureComponent {
changeHandler(name, checked) function will be called with these parameters: changeHandler(name, checked) function will be called with these parameters:
this.props.name (the name of this component) and this.props.name (the name of this component) and
this.state.checked (boolean indicating if this component is checked or not) this.state.checked (boolean indicating if this component is checked or not)
this.props.status (int) adds a class "status-x" to this checkbox. Used for styling. this.props.status (int) adds a class "status-x" to this checkbox. Used for styling.
*/ */
constructor(props) { constructor(props) {