Group recommendations by machine.

Show recommendation with collapsible incident
This commit is contained in:
Itay Mizeretz 2017-11-28 17:11:00 +02:00
parent 96972aeac9
commit da55b0b26b
3 changed files with 168 additions and 100 deletions

View File

@ -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():

View File

@ -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">

View File

@ -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;