diff --git a/monkey_island/cc/services/report.py b/monkey_island/cc/services/report.py
index 5af051e72..01205e71a 100644
--- a/monkey_island/cc/services/report.py
+++ b/monkey_island/cc/services/report.py
@@ -252,8 +252,13 @@ class ReportService:
@staticmethod
def get_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)
- return issues
+ issues_dict = {}
+ 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
def get_report():
diff --git a/monkey_island/cc/ui/src/components/pages/ReportPage.js b/monkey_island/cc/ui/src/components/pages/ReportPage.js
index 6c9c7cde3..24c666c68 100644
--- a/monkey_island/cc/ui/src/components/pages/ReportPage.js
+++ b/monkey_island/cc/ui/src/components/pages/ReportPage.js
@@ -6,6 +6,7 @@ import {ReactiveGraph} from 'components/reactive-graph/ReactiveGraph';
import {options, edgeGroupToColor} from 'components/map/MapOptions';
import StolenPasswords from 'components/report-components/StolenPasswords';
import ScannedBreachedChart from 'components/report-components/ScannedBreachedChart';
+import CollapsableWellComponent from "../report-components/CollapsibleWell";
class ReportPageComponent extends React.Component {
@@ -70,20 +71,22 @@ class ReportPageComponent extends React.Component {
}
generateShellshockPathListBadges(paths) {
- return paths.map(path => {path});
+ return paths.map(path => {path});
}
generateSmbPasswordIssue(issue) {
return (
- The machine
{issue.machine} with the following IP address
{issue.ip_address} was vulnerable to a
SMB attack.
-
- The attack succeeded by authenticating over SMB protocol with user
{issue.username} and its password.
-
- In order to protect the machine, the following steps should be performed:
-
- - Use a complex one-use password that is not shared with other computers on the network.
-
+ Change
{issue.username}'s password to a complex one-use password
+ that is not shared with other computers on the network.
+
+ The machine {issue.machine} with the following IP address {issue.ip_address} was vulnerable to a SMB attack.
+
+ The attack succeeded by authenticating over SMB protocol with user {issue.username} and its password.
+
);
}
@@ -91,14 +94,16 @@ class ReportPageComponent extends React.Component {
generateSmbPthIssue(issue) {
return (
- The machine
{issue.machine} with the following IP address
{issue.ip_address} was vulnerable to a
SMB attack.
-
- The attack succeeded by using a pass-the-hash attack over SMB protocol with user
{issue.username}.
-
- In order to protect the machine, the following steps should be performed:
-
- - Use a complex one-use password that is not shared with other computers on the network.
-
+ Change
{issue.username}'s password to a complex one-use password
+ that is not shared with other computers on the network.
+
+ The machine {issue.machine} with the following IP address {issue.ip_address} was vulnerable to a SMB attack.
+
+ The attack succeeded by using a pass-the-hash attack over SMB protocol with user {issue.username}.
+
);
}
@@ -106,14 +111,16 @@ class ReportPageComponent extends React.Component {
generateWmiPasswordIssue(issue) {
return (
- The machine
{issue.machine} with the following IP address
{issue.ip_address} was vulnerable to a
WMI attack.
-
- The attack succeeded by authenticating over WMI protocol with user
{issue.username} and its password.
-
- In order to protect the machine, the following steps should be performed:
-
- - Use a complex one-use password that is not shared with other computers on the network.
-
+ Change
{issue.username}'s password to a complex one-use password
+ that is not shared with other computers on the network.
+
+ The machine {issue.machine} with the following IP address {issue.ip_address} was vulnerable to a WMI attack.
+
+ The attack succeeded by authenticating over WMI protocol with user {issue.username} and its password.
+
);
}
@@ -121,14 +128,16 @@ class ReportPageComponent extends React.Component {
generateWmiPthIssue(issue) {
return (
- The machine
{issue.machine} with the following IP address
{issue.ip_address} was vulnerable to a
WMI attack.
-
- The attack succeeded by using a pass-the-hash attack over WMI protocol with user
{issue.username}.
-
- In order to protect the machine, the following steps should be performed:
-
- - Use a complex one-use password that is not shared with other computers on the network.
-
+ Change
{issue.username}'s password to a complex one-use password
+ that is not shared with other computers on the network.
+
+ The machine {issue.machine} with the following IP address {issue.ip_address} was vulnerable to a WMI attack.
+
+ The attack succeeded by using a pass-the-hash attack over WMI protocol with user {issue.username}.
+
);
}
@@ -136,14 +145,16 @@ class ReportPageComponent extends React.Component {
generateSshIssue(issue) {
return (
- The machine
{issue.machine} with the following IP address
{issue.ip_address} was vulnerable to a
SSH attack.
-
- The attack succeeded by authenticating over SSH protocol with user
{issue.username} and its password.
-
- In order to protect the machine, the following steps should be performed:
-
- - Use a complex one-use password that is not shared with other computers on the network.
-
+ Change
{issue.username}'s password to a complex one-use password
+ that is not shared with other computers on the network.
+
+ The machine {issue.machine} with the following IP address {issue.ip_address} was vulnerable to a SSH attack.
+
+ The attack succeeded by authenticating over SSH protocol with user {issue.username} and its password.
+
);
}
@@ -151,14 +162,16 @@ class ReportPageComponent extends React.Component {
generateRdpIssue(issue) {
return (
- The machine
{issue.machine} with the following IP address
{issue.ip_address} was vulnerable to a
RDP attack.
-
- The attack succeeded by authenticating over RDP protocol with user
{issue.username} and its password.
-
- In order to protect the machine, the following steps should be performed:
-
- - Use a complex one-use password that is not shared with other computers on the network.
-
+ Change
{issue.username}'s password to a complex one-use password
+ that is not shared with other computers on the network.
+
+ The machine {issue.machine} with the following IP address {issue.ip_address} was vulnerable to a RDP attack.
+
+ The attack succeeded by authenticating over RDP protocol with user {issue.username} and its password.
+
);
}
@@ -166,15 +179,19 @@ class ReportPageComponent extends React.Component {
generateSambaCryIssue(issue) {
return (
- The machine
{issue.machine} with the following IP address
{issue.ip_address} was vulnerable to a
SambaCry attack.
-
- The attack succeeded by authenticating over SMB protocol with user
{issue.username} and its password, and by using the SambaCry vulnerability.
-
- In order to protect the machine, the following steps should be performed:
-
- - Update your Samba server to 4.4.14 and up, 4.5.10 and up, or 4.6.4 and up.
- - Use a complex one-use password that is not shared with other computers on the network.
-
+ Change
{issue.username}'s password to a complex one-use password
+ that is not shared with other computers on the network.
+
+ Update your Samba server to 4.4.14 and up, 4.5.10 and up, or 4.6.4 and up.
+
+ The machine {issue.machine} with the following IP address {issue.ip_address} was vulnerable to a SambaCry attack.
+
+ The attack succeeded by authenticating over SMB protocol with user {issue.username} and its password, and by using the SambaCry
+ vulnerability.
+
);
}
@@ -182,14 +199,14 @@ class ReportPageComponent extends React.Component {
generateElasticIssue(issue) {
return (
- The machine
{issue.machine} with the following IP address
{issue.ip_address} was vulnerable to an
Elastic Groovy attack.
-
- The attack succeeded because the Elastic Search server was not parched against CVE-2015-1427.
-
- In order to protect the machine, the following steps should be performed:
-
- - Update your Elastic Search server to version 1.4.3 and up.
-
+ Update your Elastic Search server to version 1.4.3 and up.
+
+ The machine {issue.machine} with the following IP address {issue.ip_address} was vulnerable to an Elastic Groovy attack.
+
+ The attack succeeded because the Elastic Search server was not parched against CVE-2015-1427.
+
);
}
@@ -197,14 +214,16 @@ class ReportPageComponent extends React.Component {
generateShellshockIssue(issue) {
return (
- The machine
{issue.machine} with the following IP address
{issue.ip_address} was vulnerable to a
ShellShock attack.
-
- The attack succeeded because the HTTP server running on port
{issue.port} was vulnerable to a shell injection attack on the paths: {this.generateShellshockPathListBadges(issue.paths)}.
-
- In order to protect the machine, the following steps should be performed:
-
- - Update your Bash to a ShellShock-patched version.
-
+ Update your Bash to a ShellShock-patched version.
+
+ The machine {issue.machine} with the following IP address {issue.ip_address} was vulnerable to a ShellShock attack.
+
+ The attack succeeded because the HTTP server running on port {issue.port} was vulnerable to a shell injection attack on the
+ paths: {this.generateShellshockPathListBadges(issue.paths)}.
+
);
}
@@ -212,14 +231,15 @@ class ReportPageComponent extends React.Component {
generateConfickerIssue(issue) {
return (
- The machine
{issue.machine} with the following address
{issue.ip_address} was vulnerable to a
Conficker attack.
-
- The attack succeeded because the target machine uses an outdated and unpatched operating system vulnerable to Conficker.
-
- In order to protect the machine, the following steps should be performed:
-
- - Install the latest Windows updates or upgrade to a newer operating system.
-
+ Install the latest Windows updates or upgrade to a newer operating system.
+
+ The machine {issue.machine} with the following address {issue.ip_address} was vulnerable to a Conficker attack.
+
+ The attack succeeded because the target machine uses an outdated and unpatched operating system vulnerable to
+ Conficker.
+
);
}
@@ -227,12 +247,14 @@ class ReportPageComponent extends React.Component {
generateCrossSegmentIssue(issue) {
return (
- The network can probably be segmented. A monkey instance on
{issue.machine} in the networks {this.generateInfoBadges(issue.networks)} could directly access the Monkey Island C&C server in the networks {this.generateInfoBadges(issue.server_networks)}.
-
- In order to protect the network, the following steps should be performed:
-
- - Segment your network. Make sure machines can't access machines from other segments.
-
+ Segment your network. Make sure machines can't access machines from other segments.
+
+ The network can probably be segmented. A monkey instance on {issue.machine} in the
+ networks {this.generateInfoBadges(issue.networks)}
+ could directly access the Monkey Island C&C server in the
+ networks {this.generateInfoBadges(issue.server_networks)}.
+
);
}
@@ -240,12 +262,12 @@ class ReportPageComponent extends React.Component {
generateTunnelIssue(issue) {
return (
- Machines are not locked down at port level. Network tunnel was set up from
{issue.machine} to
{issue.dest}.
-
- In order to protect the machine, the following steps should be performed:
-
- - Use micro-segmentation policies to disable communication other than the required.
-
+ Use micro-segmentation policies to disable communication other than the required.
+
+ Machines are not locked down at port level. Network tunnel was set up from {issue.machine} to {issue.dest}.
+
);
}
@@ -292,12 +314,23 @@ class ReportPageComponent extends React.Component {
}
return (
-
Issue #{index+1}
+ Recommendation #{index + 1}
{data}
);
};
+ generateIssues = (issues) => {
+ let issuesDivArray = [];
+ for (var machine of Object.keys(issues)) {
+ issuesDivArray.push(
+ {machine}
+ );
+ issuesDivArray.push(issues[machine].map(this.generateIssue));
+ }
+ return issuesDivArray;
+ };
+
render() {
let content;
if (Object.keys(this.state.report).length === 0) {
@@ -350,9 +383,9 @@ class ReportPageComponent extends React.Component {
Recommendations
-
- {this.state.report.recommendations.issues.map(this.generateIssue)}
-
+
+ {this.generateIssues(this.state.report.recommendations.issues)}
+
diff --git a/monkey_island/cc/ui/src/components/report-components/CollapsibleWell.js b/monkey_island/cc/ui/src/components/report-components/CollapsibleWell.js
new file mode 100644
index 000000000..0b92712db
--- /dev/null
+++ b/monkey_island/cc/ui/src/components/report-components/CollapsibleWell.js
@@ -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 (
+
+ );
+ }
+}
+
+export default CollapsibleWellComponent;