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
that is not shared with other computers on the network.
<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 a <span
className="label label-danger">SMB</span> attack.
<br/> <br/>
The attack succeeded by authenticating over SMB protocol with user <span className="label label-success">{issue.username}</span> and its password. The attack succeeded by authenticating over SMB protocol with user <span
<br /> className="label label-success">{issue.username}</span> and its password.
In order to protect the machine, the following steps should be performed: </CollapsableWellComponent>
<ul className="report">
<li className="report">Use a complex one-use password that is not shared with other computers on the network.</li>
</ul>
</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
that is not shared with other computers on the network.
<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 a <span
className="label label-danger">SMB</span> attack.
<br/> <br/>
The attack succeeded by using a pass-the-hash attack over SMB protocol with user <span className="label label-success">{issue.username}</span>. The attack succeeded by using a pass-the-hash attack over SMB protocol with user <span
<br /> className="label label-success">{issue.username}</span>.
In order to protect the machine, the following steps should be performed: </CollapsableWellComponent>
<ul className="report">
<li className="report">Use a complex one-use password that is not shared with other computers on the network.</li>
</ul>
</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
that is not shared with other computers on the network.
<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 a <span
className="label label-danger">WMI</span> attack.
<br/> <br/>
The attack succeeded by authenticating over WMI protocol with user <span className="label label-success">{issue.username}</span> and its password. The attack succeeded by authenticating over WMI protocol with user <span
<br /> className="label label-success">{issue.username}</span> and its password.
In order to protect the machine, the following steps should be performed: </CollapsableWellComponent>
<ul className="report">
<li className="report">Use a complex one-use password that is not shared with other computers on the network.</li>
</ul>
</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
that is not shared with other computers on the network.
<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 a <span
className="label label-danger">WMI</span> attack.
<br/> <br/>
The attack succeeded by using a pass-the-hash attack over WMI protocol with user <span className="label label-success">{issue.username}</span>. The attack succeeded by using a pass-the-hash attack over WMI protocol with user <span
<br /> className="label label-success">{issue.username}</span>.
In order to protect the machine, the following steps should be performed: </CollapsableWellComponent>
<ul className="report">
<li className="report">Use a complex one-use password that is not shared with other computers on the network.</li>
</ul>
</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
that is not shared with other computers on the network.
<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 a <span
className="label label-danger">SSH</span> attack.
<br/> <br/>
The attack succeeded by authenticating over SSH protocol with user <span className="label label-success">{issue.username}</span> and its password. The attack succeeded by authenticating over SSH protocol with user <span
<br /> className="label label-success">{issue.username}</span> and its password.
In order to protect the machine, the following steps should be performed: </CollapsableWellComponent>
<ul className="report">
<li className="report">Use a complex one-use password that is not shared with other computers on the network.</li>
</ul>
</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
that is not shared with other computers on the network.
<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 a <span
className="label label-danger">RDP</span> attack.
<br/> <br/>
The attack succeeded by authenticating over RDP protocol with user <span className="label label-success">{issue.username}</span> and its password. The attack succeeded by authenticating over RDP protocol with user <span
<br /> className="label label-success">{issue.username}</span> and its password.
In order to protect the machine, the following steps should be performed: </CollapsableWellComponent>
<ul className="report">
<li className="report">Use a complex one-use password that is not shared with other computers on the network.</li>
</ul>
</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
that is not shared with other computers on the network.
<br/> <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. Update your Samba server to 4.4.14 and up, 4.5.10 and up, or 4.6.4 and up.
<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 a <span
className="label label-danger">SambaCry</span> attack.
<br/> <br/>
In order to protect the machine, the following steps should be performed: The attack succeeded by authenticating over SMB protocol with user <span
<ul className="report"> className="label label-success">{issue.username}</span> and its password, and by using the SambaCry
<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> vulnerability.
<li className="report">Use a complex one-use password that is not shared with other computers on the network.</li> </CollapsableWellComponent>
</ul>
</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.
<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/> <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.
<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 a <span
className="label label-danger">ShellShock</span> attack.
<br/> <br/>
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 attack succeeded because the HTTP server running on port <span
<br /> className="label label-info">{issue.port}</span> was vulnerable to a shell injection attack on the
In order to protect the machine, the following steps should be performed: paths: {this.generateShellshockPathListBadges(issue.paths)}.
<ul className="report"> </CollapsableWellComponent>
<li className="report">Update your Bash to a ShellShock-patched version.</li>
</ul>
</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.
<CollapsableWellComponent>
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.
<br/> <br/>
The attack succeeded because the target machine uses an outdated and unpatched operating system vulnerable to Conficker. The attack succeeded because the target machine uses an outdated and unpatched operating system vulnerable to
<br /> Conficker.
In order to protect the machine, the following steps should be performed: </CollapsableWellComponent>
<ul className="report">
<li className="report">Install the latest Windows updates or upgrade to a newer operating system.</li>
</ul>
</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;