forked from p15670423/monkey
Selected technique is shown bellow matrix in attack report
This commit is contained in:
parent
111b762f23
commit
1e9c9c196b
|
@ -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;
|
||||||
|
|
|
@ -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>)
|
||||||
|
|
|
@ -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;
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in New Issue