Group recommendations by machine.
Show recommendation with collapsible incident
This commit is contained in:
parent
96972aeac9
commit
da55b0b26b
|
@ -252,8 +252,13 @@ class ReportService:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_issues():
|
def get_issues():
|
||||||
issues = ReportService.get_exploits() + ReportService.get_tunnels() + ReportService.get_cross_segment_issues()
|
issues = ReportService.get_exploits() + ReportService.get_tunnels() + ReportService.get_cross_segment_issues()
|
||||||
issues.sort(lambda x, y: 1 if x['machine'] > y['machine'] else -1 if x['machine'] < y['machine'] else 0)
|
issues_dict = {}
|
||||||
return issues
|
for issue in issues:
|
||||||
|
machine = issue['machine']
|
||||||
|
if machine not in issues_dict:
|
||||||
|
issues_dict[machine] = []
|
||||||
|
issues_dict[machine].append(issue)
|
||||||
|
return issues_dict
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_report():
|
def get_report():
|
||||||
|
|
|
@ -6,6 +6,7 @@ import {ReactiveGraph} from 'components/reactive-graph/ReactiveGraph';
|
||||||
import {options, edgeGroupToColor} from 'components/map/MapOptions';
|
import {options, edgeGroupToColor} from 'components/map/MapOptions';
|
||||||
import StolenPasswords from 'components/report-components/StolenPasswords';
|
import StolenPasswords from 'components/report-components/StolenPasswords';
|
||||||
import ScannedBreachedChart from 'components/report-components/ScannedBreachedChart';
|
import ScannedBreachedChart from 'components/report-components/ScannedBreachedChart';
|
||||||
|
import CollapsableWellComponent from "../report-components/CollapsibleWell";
|
||||||
|
|
||||||
class ReportPageComponent extends React.Component {
|
class ReportPageComponent extends React.Component {
|
||||||
|
|
||||||
|
@ -76,14 +77,16 @@ class ReportPageComponent extends React.Component {
|
||||||
generateSmbPasswordIssue(issue) {
|
generateSmbPasswordIssue(issue) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
The machine <span className="label label-primary">{issue.machine}</span> with the following IP address <span className="label label-info" style={{margin: '2px'}}>{issue.ip_address}</span> was vulnerable to a <span className="label label-danger">SMB</span> attack.
|
Change <span className="label label-success">{issue.username}</span>'s password to a complex one-use password
|
||||||
<br />
|
that is not shared with other computers on the network.
|
||||||
The attack succeeded by authenticating over SMB protocol with user <span className="label label-success">{issue.username}</span> and its password.
|
<CollapsableWellComponent>
|
||||||
<br />
|
The machine <span className="label label-primary">{issue.machine}</span> with the following IP address <span
|
||||||
In order to protect the machine, the following steps should be performed:
|
className="label label-info" style={{margin: '2px'}}>{issue.ip_address}</span> was vulnerable to a <span
|
||||||
<ul className="report">
|
className="label label-danger">SMB</span> attack.
|
||||||
<li className="report">Use a complex one-use password that is not shared with other computers on the network.</li>
|
<br/>
|
||||||
</ul>
|
The attack succeeded by authenticating over SMB protocol with user <span
|
||||||
|
className="label label-success">{issue.username}</span> and its password.
|
||||||
|
</CollapsableWellComponent>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -91,14 +94,16 @@ class ReportPageComponent extends React.Component {
|
||||||
generateSmbPthIssue(issue) {
|
generateSmbPthIssue(issue) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
The machine <span className="label label-primary">{issue.machine}</span> with the following IP address <span className="label label-info" style={{margin: '2px'}}>{issue.ip_address}</span> was vulnerable to a <span className="label label-danger">SMB</span> attack.
|
Change <span className="label label-success">{issue.username}</span>'s password to a complex one-use password
|
||||||
<br />
|
that is not shared with other computers on the network.
|
||||||
The attack succeeded by using a pass-the-hash attack over SMB protocol with user <span className="label label-success">{issue.username}</span>.
|
<CollapsableWellComponent>
|
||||||
<br />
|
The machine <span className="label label-primary">{issue.machine}</span> with the following IP address <span
|
||||||
In order to protect the machine, the following steps should be performed:
|
className="label label-info" style={{margin: '2px'}}>{issue.ip_address}</span> was vulnerable to a <span
|
||||||
<ul className="report">
|
className="label label-danger">SMB</span> attack.
|
||||||
<li className="report">Use a complex one-use password that is not shared with other computers on the network.</li>
|
<br/>
|
||||||
</ul>
|
The attack succeeded by using a pass-the-hash attack over SMB protocol with user <span
|
||||||
|
className="label label-success">{issue.username}</span>.
|
||||||
|
</CollapsableWellComponent>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -106,14 +111,16 @@ class ReportPageComponent extends React.Component {
|
||||||
generateWmiPasswordIssue(issue) {
|
generateWmiPasswordIssue(issue) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
The machine <span className="label label-primary">{issue.machine}</span> with the following IP address <span className="label label-info" style={{margin: '2px'}}>{issue.ip_address}</span> was vulnerable to a <span className="label label-danger">WMI</span> attack.
|
Change <span className="label label-success">{issue.username}</span>'s password to a complex one-use password
|
||||||
<br />
|
that is not shared with other computers on the network.
|
||||||
The attack succeeded by authenticating over WMI protocol with user <span className="label label-success">{issue.username}</span> and its password.
|
<CollapsableWellComponent>
|
||||||
<br />
|
The machine <span className="label label-primary">{issue.machine}</span> with the following IP address <span
|
||||||
In order to protect the machine, the following steps should be performed:
|
className="label label-info" style={{margin: '2px'}}>{issue.ip_address}</span> was vulnerable to a <span
|
||||||
<ul className="report">
|
className="label label-danger">WMI</span> attack.
|
||||||
<li className="report">Use a complex one-use password that is not shared with other computers on the network.</li>
|
<br/>
|
||||||
</ul>
|
The attack succeeded by authenticating over WMI protocol with user <span
|
||||||
|
className="label label-success">{issue.username}</span> and its password.
|
||||||
|
</CollapsableWellComponent>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -121,14 +128,16 @@ class ReportPageComponent extends React.Component {
|
||||||
generateWmiPthIssue(issue) {
|
generateWmiPthIssue(issue) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
The machine <span className="label label-primary">{issue.machine}</span> with the following IP address <span className="label label-info" style={{margin: '2px'}}>{issue.ip_address}</span> was vulnerable to a <span className="label label-danger">WMI</span> attack.
|
Change <span className="label label-success">{issue.username}</span>'s password to a complex one-use password
|
||||||
<br />
|
that is not shared with other computers on the network.
|
||||||
The attack succeeded by using a pass-the-hash attack over WMI protocol with user <span className="label label-success">{issue.username}</span>.
|
<CollapsableWellComponent>
|
||||||
<br />
|
The machine <span className="label label-primary">{issue.machine}</span> with the following IP address <span
|
||||||
In order to protect the machine, the following steps should be performed:
|
className="label label-info" style={{margin: '2px'}}>{issue.ip_address}</span> was vulnerable to a <span
|
||||||
<ul className="report">
|
className="label label-danger">WMI</span> attack.
|
||||||
<li className="report">Use a complex one-use password that is not shared with other computers on the network.</li>
|
<br/>
|
||||||
</ul>
|
The attack succeeded by using a pass-the-hash attack over WMI protocol with user <span
|
||||||
|
className="label label-success">{issue.username}</span>.
|
||||||
|
</CollapsableWellComponent>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -136,14 +145,16 @@ class ReportPageComponent extends React.Component {
|
||||||
generateSshIssue(issue) {
|
generateSshIssue(issue) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
The machine <span className="label label-primary">{issue.machine}</span> with the following IP address <span className="label label-info" style={{margin: '2px'}}>{issue.ip_address}</span> was vulnerable to a <span className="label label-danger">SSH</span> attack.
|
Change <span className="label label-success">{issue.username}</span>'s password to a complex one-use password
|
||||||
<br />
|
that is not shared with other computers on the network.
|
||||||
The attack succeeded by authenticating over SSH protocol with user <span className="label label-success">{issue.username}</span> and its password.
|
<CollapsableWellComponent>
|
||||||
<br />
|
The machine <span className="label label-primary">{issue.machine}</span> with the following IP address <span
|
||||||
In order to protect the machine, the following steps should be performed:
|
className="label label-info" style={{margin: '2px'}}>{issue.ip_address}</span> was vulnerable to a <span
|
||||||
<ul className="report">
|
className="label label-danger">SSH</span> attack.
|
||||||
<li className="report">Use a complex one-use password that is not shared with other computers on the network.</li>
|
<br/>
|
||||||
</ul>
|
The attack succeeded by authenticating over SSH protocol with user <span
|
||||||
|
className="label label-success">{issue.username}</span> and its password.
|
||||||
|
</CollapsableWellComponent>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -151,14 +162,16 @@ class ReportPageComponent extends React.Component {
|
||||||
generateRdpIssue(issue) {
|
generateRdpIssue(issue) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
The machine <span className="label label-primary">{issue.machine}</span> with the following IP address <span className="label label-info" style={{margin: '2px'}}>{issue.ip_address}</span> was vulnerable to a <span className="label label-danger">RDP</span> attack.
|
Change <span className="label label-success">{issue.username}</span>'s password to a complex one-use password
|
||||||
<br />
|
that is not shared with other computers on the network.
|
||||||
The attack succeeded by authenticating over RDP protocol with user <span className="label label-success">{issue.username}</span> and its password.
|
<CollapsableWellComponent>
|
||||||
<br />
|
The machine <span className="label label-primary">{issue.machine}</span> with the following IP address <span
|
||||||
In order to protect the machine, the following steps should be performed:
|
className="label label-info" style={{margin: '2px'}}>{issue.ip_address}</span> was vulnerable to a <span
|
||||||
<ul className="report">
|
className="label label-danger">RDP</span> attack.
|
||||||
<li className="report">Use a complex one-use password that is not shared with other computers on the network.</li>
|
<br/>
|
||||||
</ul>
|
The attack succeeded by authenticating over RDP protocol with user <span
|
||||||
|
className="label label-success">{issue.username}</span> and its password.
|
||||||
|
</CollapsableWellComponent>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -166,15 +179,19 @@ class ReportPageComponent extends React.Component {
|
||||||
generateSambaCryIssue(issue) {
|
generateSambaCryIssue(issue) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
The machine <span className="label label-primary">{issue.machine}</span> with the following IP address <span className="label label-info" style={{margin: '2px'}}>{issue.ip_address}</span> was vulnerable to a <span className="label label-danger">SambaCry</span> attack.
|
Change <span className="label label-success">{issue.username}</span>'s password to a complex one-use password
|
||||||
<br />
|
that is not shared with other computers on the network.
|
||||||
The attack succeeded by authenticating over SMB protocol with user <span className="label label-success">{issue.username}</span> and its password, and by using the SambaCry vulnerability.
|
<br/>
|
||||||
<br />
|
Update your Samba server to 4.4.14 and up, 4.5.10 and up, or 4.6.4 and up.
|
||||||
In order to protect the machine, the following steps should be performed:
|
<CollapsableWellComponent>
|
||||||
<ul className="report">
|
The machine <span className="label label-primary">{issue.machine}</span> with the following IP address <span
|
||||||
<li className="report">Update your Samba server to 4.4.14 and up, 4.5.10 and up, or 4.6.4 and up.</li>
|
className="label label-info" style={{margin: '2px'}}>{issue.ip_address}</span> was vulnerable to a <span
|
||||||
<li className="report">Use a complex one-use password that is not shared with other computers on the network.</li>
|
className="label label-danger">SambaCry</span> attack.
|
||||||
</ul>
|
<br/>
|
||||||
|
The attack succeeded by authenticating over SMB protocol with user <span
|
||||||
|
className="label label-success">{issue.username}</span> and its password, and by using the SambaCry
|
||||||
|
vulnerability.
|
||||||
|
</CollapsableWellComponent>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -182,14 +199,14 @@ class ReportPageComponent extends React.Component {
|
||||||
generateElasticIssue(issue) {
|
generateElasticIssue(issue) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
The machine <span className="label label-primary">{issue.machine}</span> with the following IP address <span className="label label-info" style={{margin: '2px'}}>{issue.ip_address}</span> was vulnerable to an <span className="label label-danger">Elastic Groovy</span> attack.
|
Update your Elastic Search server to version 1.4.3 and up.
|
||||||
<br />
|
<CollapsableWellComponent>
|
||||||
|
The machine <span className="label label-primary">{issue.machine}</span> with the following IP address <span
|
||||||
|
className="label label-info" style={{margin: '2px'}}>{issue.ip_address}</span> was vulnerable to an <span
|
||||||
|
className="label label-danger">Elastic Groovy</span> attack.
|
||||||
|
<br/>
|
||||||
The attack succeeded because the Elastic Search server was not parched against CVE-2015-1427.
|
The attack succeeded because the Elastic Search server was not parched against CVE-2015-1427.
|
||||||
<br />
|
</CollapsableWellComponent>
|
||||||
In order to protect the machine, the following steps should be performed:
|
|
||||||
<ul className="report">
|
|
||||||
<li className="report">Update your Elastic Search server to version 1.4.3 and up.</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -197,14 +214,16 @@ class ReportPageComponent extends React.Component {
|
||||||
generateShellshockIssue(issue) {
|
generateShellshockIssue(issue) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
The machine <span className="label label-primary">{issue.machine}</span> with the following IP address <span className="label label-info" style={{margin: '2px'}}>{issue.ip_address}</span> was vulnerable to a <span className="label label-danger">ShellShock</span> attack.
|
Update your Bash to a ShellShock-patched version.
|
||||||
<br />
|
<CollapsableWellComponent>
|
||||||
The attack succeeded because the HTTP server running on port <span className="label label-info">{issue.port}</span> was vulnerable to a shell injection attack on the paths: {this.generateShellshockPathListBadges(issue.paths)}.
|
The machine <span className="label label-primary">{issue.machine}</span> with the following IP address <span
|
||||||
<br />
|
className="label label-info" style={{margin: '2px'}}>{issue.ip_address}</span> was vulnerable to a <span
|
||||||
In order to protect the machine, the following steps should be performed:
|
className="label label-danger">ShellShock</span> attack.
|
||||||
<ul className="report">
|
<br/>
|
||||||
<li className="report">Update your Bash to a ShellShock-patched version.</li>
|
The attack succeeded because the HTTP server running on port <span
|
||||||
</ul>
|
className="label label-info">{issue.port}</span> was vulnerable to a shell injection attack on the
|
||||||
|
paths: {this.generateShellshockPathListBadges(issue.paths)}.
|
||||||
|
</CollapsableWellComponent>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -212,14 +231,15 @@ class ReportPageComponent extends React.Component {
|
||||||
generateConfickerIssue(issue) {
|
generateConfickerIssue(issue) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
The machine <span className="label label-primary">{issue.machine}</span> with the following address <span className="label label-info" style={{margin: '2px'}}>{issue.ip_address}</span> was vulnerable to a <span className="label label-danger">Conficker</span> attack.
|
Install the latest Windows updates or upgrade to a newer operating system.
|
||||||
<br />
|
<CollapsableWellComponent>
|
||||||
The attack succeeded because the target machine uses an outdated and unpatched operating system vulnerable to Conficker.
|
The machine <span className="label label-primary">{issue.machine}</span> with the following address <span
|
||||||
<br />
|
className="label label-info" style={{margin: '2px'}}>{issue.ip_address}</span> was vulnerable to a <span
|
||||||
In order to protect the machine, the following steps should be performed:
|
className="label label-danger">Conficker</span> attack.
|
||||||
<ul className="report">
|
<br/>
|
||||||
<li className="report">Install the latest Windows updates or upgrade to a newer operating system.</li>
|
The attack succeeded because the target machine uses an outdated and unpatched operating system vulnerable to
|
||||||
</ul>
|
Conficker.
|
||||||
|
</CollapsableWellComponent>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -227,12 +247,14 @@ class ReportPageComponent extends React.Component {
|
||||||
generateCrossSegmentIssue(issue) {
|
generateCrossSegmentIssue(issue) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
The network can probably be segmented. A monkey instance on <span className="label label-primary">{issue.machine}</span> in the networks {this.generateInfoBadges(issue.networks)} could directly access the Monkey Island C&C server in the networks {this.generateInfoBadges(issue.server_networks)}.
|
Segment your network. Make sure machines can't access machines from other segments.
|
||||||
<br />
|
<CollapsableWellComponent>
|
||||||
In order to protect the network, the following steps should be performed:
|
The network can probably be segmented. A monkey instance on <span
|
||||||
<ul className="report">
|
className="label label-primary">{issue.machine}</span> in the
|
||||||
<li className="report">Segment your network. Make sure machines can't access machines from other segments.</li>
|
networks {this.generateInfoBadges(issue.networks)}
|
||||||
</ul>
|
could directly access the Monkey Island C&C server in the
|
||||||
|
networks {this.generateInfoBadges(issue.server_networks)}.
|
||||||
|
</CollapsableWellComponent>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -240,12 +262,12 @@ class ReportPageComponent extends React.Component {
|
||||||
generateTunnelIssue(issue) {
|
generateTunnelIssue(issue) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
Machines are not locked down at port level. Network tunnel was set up from <span className="label label-primary">{issue.machine}</span> to <span className="label label-primary">{issue.dest}</span>.
|
Use micro-segmentation policies to disable communication other than the required.
|
||||||
<br />
|
<CollapsableWellComponent>
|
||||||
In order to protect the machine, the following steps should be performed:
|
Machines are not locked down at port level. Network tunnel was set up from <span
|
||||||
<ul className="report">
|
className="label label-primary">{issue.machine}</span> to <span
|
||||||
<li className="report">Use micro-segmentation policies to disable communication other than the required.</li>
|
className="label label-primary">{issue.dest}</span>.
|
||||||
</ul>
|
</CollapsableWellComponent>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -292,12 +314,23 @@ class ReportPageComponent extends React.Component {
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h4><b><i>Issue #{index+1}</i></b></h4>
|
<h5><b><i>Recommendation #{index + 1}</i></b></h5>
|
||||||
{data}
|
{data}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
generateIssues = (issues) => {
|
||||||
|
let issuesDivArray = [];
|
||||||
|
for (var machine of Object.keys(issues)) {
|
||||||
|
issuesDivArray.push(
|
||||||
|
<h4><b>{machine}</b></h4>
|
||||||
|
);
|
||||||
|
issuesDivArray.push(issues[machine].map(this.generateIssue));
|
||||||
|
}
|
||||||
|
return issuesDivArray;
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let content;
|
let content;
|
||||||
if (Object.keys(this.state.report).length === 0) {
|
if (Object.keys(this.state.report).length === 0) {
|
||||||
|
@ -351,7 +384,7 @@ class ReportPageComponent extends React.Component {
|
||||||
Recommendations
|
Recommendations
|
||||||
</h1>
|
</h1>
|
||||||
<div>
|
<div>
|
||||||
{this.state.report.recommendations.issues.map(this.generateIssue)}
|
{this.generateIssues(this.state.report.recommendations.issues)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="glance">
|
<div id="glance">
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
import React from 'react';
|
||||||
|
import {Collapse, Well} from 'react-bootstrap';
|
||||||
|
|
||||||
|
class CollapsibleWellComponent extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
open: false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<a onClick={() => this.setState({ open: !this.state.open })}>
|
||||||
|
Read More...
|
||||||
|
</a>
|
||||||
|
<Collapse in={this.state.open}>
|
||||||
|
<div>
|
||||||
|
<Well style={{margin: '10px'}}>
|
||||||
|
{this.props.children}
|
||||||
|
</Well>
|
||||||
|
</div>
|
||||||
|
</Collapse>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CollapsibleWellComponent;
|
Loading…
Reference in New Issue