From dd50f9d4aa3970797eb78897518a32833344f365 Mon Sep 17 00:00:00 2001 From: Shay Nehmad Date: Mon, 20 Jul 2020 18:38:15 +0300 Subject: [PATCH] Fix some key prop errors so that our pages don't have errors It might avoid some bugs in the future as well: https://stackoverflow.com/questions/28329382/understanding-unique-keys-for-array-children-in-react-js --- .../cc/ui/src/components/pages/ReportPage.js | 2 +- .../ui/src/components/pages/RunMonkeyPage.js | 4 +- .../report-components/SecurityReport.js | 183 +++++++++--------- .../report-components/common/RenderArrays.js | 8 + .../security/BreachedServers.js | 8 +- .../report-components/security/PostBreach.js | 9 +- .../security/ScannedServers.js | 8 +- .../report-components/security/StrongUsers.js | 5 +- 8 files changed, 109 insertions(+), 118 deletions(-) create mode 100644 monkey/monkey_island/cc/ui/src/components/report-components/common/RenderArrays.js diff --git a/monkey/monkey_island/cc/ui/src/components/pages/ReportPage.js b/monkey/monkey_island/cc/ui/src/components/pages/ReportPage.js index 3c2bbf09b..131190905 100644 --- a/monkey/monkey_island/cc/ui/src/components/pages/ReportPage.js +++ b/monkey/monkey_island/cc/ui/src/components/pages/ReportPage.js @@ -121,7 +121,7 @@ class ReportPageComponent extends AuthComponent { renderNavButton = (section) => { return ( - + { diff --git a/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage.js b/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage.js index ff2b15442..155dca40b 100644 --- a/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage.js +++ b/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage.js @@ -277,7 +277,7 @@ class RunMonkeyPageComponent extends AuthComponent { this.state.ips.length > 1 ? :
} @@ -400,7 +400,7 @@ class RunMonkeyPageComponent extends AuthComponent { diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/SecurityReport.js b/monkey/monkey_island/cc/ui/src/components/report-components/SecurityReport.js index a3c29f163..e0d433537 100644 --- a/monkey/monkey_island/cc/ui/src/components/report-components/SecurityReport.js +++ b/monkey/monkey_island/cc/ui/src/components/report-components/SecurityReport.js @@ -161,25 +161,29 @@ class ReportPageComponent extends AuthComponent {

The monkey started propagating from the following machines where it was manually installed: -

    - {this.state.report.overview.manual_monkeys.map(x =>
  • {x}
  • )} -

+
    + {this.state.report.overview.manual_monkeys.map(x =>
  • {x}
  • )} +

The monkeys were run with the following configuration:

{ this.state.report.overview.config_users.length > 0 ? -

- Usernames used for brute-forcing: + <> +

+ Usernames used for brute-forcing: +

    - {this.state.report.overview.config_users.map(x =>
  • {x}
  • )} + {this.state.report.overview.config_users.map(x =>
  • {x}
  • )}
- Passwords used for brute-forcing: +

+ Passwords used for brute-forcing: +

    - {this.state.report.overview.config_passwords.map(x =>
  • {x.substr(0, 3) + '******'}
  • )} + {this.state.report.overview.config_passwords.map(x =>
  • {x.substr(0, 3) + '******'}
  • )}
-

+ :

Brute forcing uses stolen credentials only. No credentials were supplied during Monkey’s @@ -195,7 +199,7 @@ class ReportPageComponent extends AuthComponent {

The Monkey uses the following exploit methods:

    - {this.state.report.overview.config_exploits.map(x =>
  • {x}
  • )} + {this.state.report.overview.config_exploits.map(x =>
  • {x}
  • )}

) @@ -209,7 +213,7 @@ class ReportPageComponent extends AuthComponent {

The Monkey scans the following IPs:

    - {this.state.report.overview.config_ips.map(x =>
  • {x}
  • )} + {this.state.report.overview.config_ips.map(x =>
  • {x}
  • )}

: @@ -313,15 +317,15 @@ class ReportPageComponent extends AuthComponent { The Monkey uncovered the following possible set of issues:
    {this.state.report.overview.warnings[this.Warning.CROSS_SEGMENT] ? -
  • Weak segmentation - Machines from different segments are able to +
  • Weak segmentation - Machines from different segments are able to communicate.
  • : null} {this.state.report.overview.warnings[this.Warning.TUNNEL] ? -
  • Weak segmentation - Machines were able to communicate over unused ports.
  • : null} +
  • Weak segmentation - Machines were able to communicate over unused ports.
  • : null} {this.state.report.overview.warnings[this.Warning.SHARED_LOCAL_ADMIN] ? -
  • Shared local administrator account - Different machines have the same account as a local +
  • Shared local administrator account - Different machines have the same account as a local administrator.
  • : null} {this.state.report.overview.warnings[this.Warning.SHARED_PASSWORDS] ? -
  • Multiple users have the same password
  • : null} +
  • Multiple users have the same password
  • : null}
: @@ -443,21 +447,22 @@ class ReportPageComponent extends AuthComponent { } generateInfoBadges(data_array) { - return data_array.map(badge_data => {badge_data}); + return data_array.map(badge_data => {badge_data}); } generateCrossSegmentIssue(crossSegmentIssue) { - return
  • - {'Communication possible from ' + crossSegmentIssue['source_subnet'] + ' to ' + crossSegmentIssue['target_subnet']} + let crossSegmentIssueOverview = 'Communication possible from ' + crossSegmentIssue['source_subnet'] + ' to ' + crossSegmentIssue['target_subnet'] + return
  • + {crossSegmentIssueOverview}
      {crossSegmentIssue['issues'].map(x => x['is_self'] ? -
    • +
    • {'Machine ' + x['hostname'] + ' has both ips: ' + x['source'] + ' and ' + x['target']}
    • : -
    • +
    • {'IP ' + x['source'] + ' (' + x['hostname'] + ') connected to IP ' + x['target'] + ' using the services: ' + Object.keys(x['services']).join(', ')}
    • @@ -473,7 +478,7 @@ class ReportPageComponent extends AuthComponent { generateSmbPasswordIssue(issue) { return ( -
    • + <> Change {issue.username}'s password to a complex one-use password that is not shared with other computers on the network. @@ -484,13 +489,13 @@ class ReportPageComponent extends AuthComponent { The Monkey authenticated over the SMB protocol with user {issue.username} and its password. -
    • + ); } generateSmbPthIssue(issue) { return ( -
    • + <> Change {issue.username}'s password to a complex one-use password that is not shared with other computers on the network. @@ -501,13 +506,13 @@ class ReportPageComponent extends AuthComponent { The Monkey used a pass-the-hash attack over SMB protocol with user {issue.username}. -
    • + ); } generateWmiPasswordIssue(issue) { return ( -
    • + <> Change {issue.username}'s password to a complex one-use password that is not shared with other computers on the network. @@ -518,13 +523,13 @@ class ReportPageComponent extends AuthComponent { The Monkey authenticated over the WMI protocol with user {issue.username} and its password. -
    • + ); } generateWmiPthIssue(issue) { return ( -
    • + <> Change {issue.username}'s password to a complex one-use password that is not shared with other computers on the network. @@ -535,13 +540,13 @@ class ReportPageComponent extends AuthComponent { The Monkey used a pass-the-hash attack over WMI protocol with user {issue.username}. -
    • + ); } generateSshIssue(issue) { return ( -
    • + <> Change {issue.username}'s password to a complex one-use password that is not shared with other computers on the network. @@ -552,13 +557,13 @@ class ReportPageComponent extends AuthComponent { The Monkey authenticated over the SSH protocol with user {issue.username} and its password. -
    • + ); } generateSshKeysIssue(issue) { return ( -
    • + <> Protect {issue.ssh_key} private key with a pass phrase. The machine {issue.machine} ({issue.ssh_key}. -
    • + ); } generateSambaCryIssue(issue) { return ( -
    • + <> Change {issue.username}'s password to a complex one-use password that is not shared with other computers on the network.
      @@ -589,13 +594,13 @@ class ReportPageComponent extends AuthComponent { className="badge badge-success">{issue.username} and its password, and used the SambaCry vulnerability. -
    • + ); } generateVsftpdBackdoorIssue(issue) { return ( -
    • + <> Update your VSFTPD server to the latest version vsftpd-3.0.3. The machine {issue.machine} (here. -
    • + ); } generateElasticIssue(issue) { return ( -
    • + <> Update your Elastic Search server to version 1.4.3 and up. The machine {issue.machine} ( The attack was made possible because the Elastic Search server was not patched against CVE-2015-1427. -
    • + ); } generateShellshockIssue(issue) { return ( -
    • + <> Update your Bash to a ShellShock-patched version. The machine {issue.machine} ({issue.port} was vulnerable to a shell injection attack on the paths: {this.generateShellshockPathListBadges(issue.paths)}. -
    • + ); } generateAzureIssue(issue) { return ( -
    • + <> Delete VM Access plugin configuration files. Credentials could be stolen from here. -
    • + ); } generateConfickerIssue(issue) { return ( -
    • + <> Install the latest Windows updates or upgrade to a newer operating system. The machine {issue.machine} ( -
    • + ); } generateIslandCrossSegmentIssue(issue) { return ( -
    • + <> Segment your network and make sure there is no communication between machines from different segments. The network can probably be segmented. A monkey instance on -
    • + ); } generateSharedCredsDomainIssue(issue) { return ( -
    • + <> Some domain users are sharing passwords, this should be fixed by changing passwords. These users are sharing access password: {this.generateInfoBadges(issue.shared_with)}. -
    • + ); } generateSharedCredsIssue(issue) { return ( -
    • + <> Some users are sharing passwords, this should be fixed by changing passwords. These users are sharing access password: {this.generateInfoBadges(issue.shared_with)}. -
    • + ); } generateSharedLocalAdminsIssue(issue) { return ( -
    • + <> Make sure the right administrator accounts are managing the right machines, and that there isn’t an unintentional local admin sharing. @@ -730,13 +735,13 @@ class ReportPageComponent extends AuthComponent { className="badge badge-primary">{issue.username} is defined as an administrator: {this.generateInfoBadges(issue.shared_machines)} -
    • + ); } generateStrongUsersOnCritIssue(issue) { return ( -
    • + <> This critical machine is open to attacks via strong users with access to it. The services: {this.generateInfoBadges(issue.services)} have been found on the machine @@ -744,26 +749,26 @@ class ReportPageComponent extends AuthComponent { These users has access to it: {this.generateInfoBadges(issue.threatening_users)}. -
    • + ); } generateTunnelIssue(issue) { return ( -
    • + <> 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}. -
    • + ); } generateStruts2Issue(issue) { return ( -
    • + <> Upgrade Struts2 to version 2.3.32 or 2.5.10.1 or any later versions. Struts2 server at {issue.machine} (here. -
    • + ); } generateWebLogicIssue(issue) { return ( -
    • + <> Update Oracle WebLogic server to the latest supported version. Oracle WebLogic server at {issue.machine} ( CVE-2017-10271 or CVE-2019-2725 -
    • + ); } generateHadoopIssue(issue) { return ( -
    • + <> Run Hadoop in secure mode ( add Kerberos authentication). @@ -809,13 +814,13 @@ class ReportPageComponent extends AuthComponent {
      The attack was made possible due to default Hadoop/Yarn configuration being insecure. -
    • + ); } generateMSSQLIssue(issue) { return ( -
    • + <> Disable the xp_cmdshell option. The machine {issue.machine} ( Microsoft's documentation. -
    • + ); } generateIssue = (issue) => { - let data; + let issueData; switch (issue.type) { case 'vsftp': - data = this.generateVsftpdBackdoorIssue(issue); + issueData = this.generateVsftpdBackdoorIssue(issue); break; case 'smb_password': - data = this.generateSmbPasswordIssue(issue); + issueData = this.generateSmbPasswordIssue(issue); break; case 'smb_pth': - data = this.generateSmbPthIssue(issue); + issueData = this.generateSmbPthIssue(issue); break; case 'wmi_password': - data = this.generateWmiPasswordIssue(issue); + issueData = this.generateWmiPasswordIssue(issue); break; case 'wmi_pth': - data = this.generateWmiPthIssue(issue); + issueData = this.generateWmiPthIssue(issue); break; case 'ssh': - data = this.generateSshIssue(issue); + issueData = this.generateSshIssue(issue); break; case 'ssh_key': - data = this.generateSshKeysIssue(issue); + issueData = this.generateSshKeysIssue(issue); break; case 'sambacry': - data = this.generateSambaCryIssue(issue); + issueData = this.generateSambaCryIssue(issue); break; case 'elastic': - data = this.generateElasticIssue(issue); + issueData = this.generateElasticIssue(issue); break; case 'shellshock': - data = this.generateShellshockIssue(issue); + issueData = this.generateShellshockIssue(issue); break; case 'conficker': - data = this.generateConfickerIssue(issue); + issueData = this.generateConfickerIssue(issue); break; case 'island_cross_segment': - data = this.generateIslandCrossSegmentIssue(issue); + issueData = this.generateIslandCrossSegmentIssue(issue); break; case 'shared_passwords': - data = this.generateSharedCredsIssue(issue); + issueData = this.generateSharedCredsIssue(issue); break; case 'shared_passwords_domain': - data = this.generateSharedCredsDomainIssue(issue); + issueData = this.generateSharedCredsDomainIssue(issue); break; case 'shared_admins_domain': - data = this.generateSharedLocalAdminsIssue(issue); + issueData = this.generateSharedLocalAdminsIssue(issue); break; case 'strong_users_on_crit': - data = this.generateStrongUsersOnCritIssue(issue); + issueData = this.generateStrongUsersOnCritIssue(issue); break; case 'tunnel': - data = this.generateTunnelIssue(issue); + issueData = this.generateTunnelIssue(issue); break; case 'azure_password': - data = this.generateAzureIssue(issue); + issueData = this.generateAzureIssue(issue); break; case 'struts2': - data = this.generateStruts2Issue(issue); + issueData = this.generateStruts2Issue(issue); break; case 'weblogic': - data = this.generateWebLogicIssue(issue); + issueData = this.generateWebLogicIssue(issue); break; case 'hadoop': - data = this.generateHadoopIssue(issue); + issueData = this.generateHadoopIssue(issue); break; case 'mssql': - data = this.generateMSSQLIssue(issue); + issueData = this.generateMSSQLIssue(issue); break; } - return data; + return
    • {issueData}
    • ; }; generateIssues = (issues) => { let issuesDivArray = []; for (let machine of Object.keys(issues)) { issuesDivArray.push( -
    • +
    • {machine}

        {issues[machine].map(this.generateIssue)} diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/common/RenderArrays.js b/monkey/monkey_island/cc/ui/src/components/report-components/common/RenderArrays.js new file mode 100644 index 000000000..936a2825b --- /dev/null +++ b/monkey/monkey_island/cc/ui/src/components/report-components/common/RenderArrays.js @@ -0,0 +1,8 @@ +import React from "react"; + +export let renderArray = function (val) { + return <>{val.map(x =>
        {x}
        )}; +}; +export let renderIpAddresses = function (val) { + return
        {renderArray(val.ip_addresses)} {(val.domain_name ? ' ('.concat(val.domain_name, ')') : '')}
        ; +}; diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/security/BreachedServers.js b/monkey/monkey_island/cc/ui/src/components/report-components/security/BreachedServers.js index fdd9398fb..1a4b02efe 100644 --- a/monkey/monkey_island/cc/ui/src/components/report-components/security/BreachedServers.js +++ b/monkey/monkey_island/cc/ui/src/components/report-components/security/BreachedServers.js @@ -1,14 +1,8 @@ import React from 'react'; import ReactTable from 'react-table'; import Pluralize from 'pluralize'; +import {renderArray, renderIpAddresses} from "../common/RenderArrays"; -let renderArray = function (val) { - return
        {val.map(x =>
        {x}
        )}
        ; -}; - -let renderIpAddresses = function (val) { - return
        {renderArray(val.ip_addresses)} {(val.domain_name ? ' ('.concat(val.domain_name, ')') : '')}
        ; -}; const columns = [ { diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/security/PostBreach.js b/monkey/monkey_island/cc/ui/src/components/report-components/security/PostBreach.js index 6bbe6b809..cc9ea1c20 100644 --- a/monkey/monkey_island/cc/ui/src/components/report-components/security/PostBreach.js +++ b/monkey/monkey_island/cc/ui/src/components/report-components/security/PostBreach.js @@ -1,14 +1,7 @@ import React from 'react'; import ReactTable from 'react-table'; import Pluralize from 'pluralize'; - -let renderArray = function (val) { - return {val.map(x => {x})}; -}; - -let renderIpAddresses = function (val) { - return {renderArray(val.ip_addresses)} {(val.domain_name ? ' ('.concat(val.domain_name, ')') : '')} ; -}; +import {renderIpAddresses} from "../common/RenderArrays"; let renderMachine = function (data) { return
        {data.label} ( {renderIpAddresses(data)} )
        diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/security/ScannedServers.js b/monkey/monkey_island/cc/ui/src/components/report-components/security/ScannedServers.js index 94c3d4a0e..bf0eee7d6 100644 --- a/monkey/monkey_island/cc/ui/src/components/report-components/security/ScannedServers.js +++ b/monkey/monkey_island/cc/ui/src/components/report-components/security/ScannedServers.js @@ -1,14 +1,8 @@ import React from 'react'; import ReactTable from 'react-table'; import Pluralize from 'pluralize'; +import {renderArray, renderIpAddresses} from "../common/RenderArrays"; -let renderArray = function (val) { - return
        {val.map(x =>
        {x}
        )}
        ; -}; - -let renderIpAddresses = function (val) { - return
        {renderArray(val.ip_addresses)} {(val.domain_name ? ' ('.concat(val.domain_name, ')') : '')}
        ; -}; const columns = [ { diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/security/StrongUsers.js b/monkey/monkey_island/cc/ui/src/components/report-components/security/StrongUsers.js index 2c2a79c07..013426657 100644 --- a/monkey/monkey_island/cc/ui/src/components/report-components/security/StrongUsers.js +++ b/monkey/monkey_island/cc/ui/src/components/report-components/security/StrongUsers.js @@ -1,10 +1,7 @@ import React from 'react'; import ReactTable from 'react-table' +import {renderArray} from "../common/RenderArrays"; -let renderArray = function (val) { - console.log(val); - return
        {val.map(x =>
        {x}
        )}
        ; -}; const columns = [ {