Add a detailed issue to the security report

This commit is contained in:
ophirharpazg 2020-08-30 18:04:26 +03:00
parent 3df5078ec1
commit 1e259fc131
2 changed files with 132 additions and 100 deletions

View File

@ -1,22 +1,25 @@
import functools import functools
import ipaddress
import itertools import itertools
import logging import logging
import ipaddress
from bson import json_util
from enum import Enum from enum import Enum
from bson import json_util
from common.network.network_range import NetworkRange from common.network.network_range import NetworkRange
from common.network.segmentation_utils import get_ip_in_src_and_not_in_dst from common.network.segmentation_utils import get_ip_in_src_and_not_in_dst
from monkey_island.cc.database import mongo from monkey_island.cc.database import mongo
from monkey_island.cc.models import Monkey from monkey_island.cc.models import Monkey
from monkey_island.cc.network_utils import get_subnets, local_ip_addresses
from monkey_island.cc.services.config import ConfigService from monkey_island.cc.services.config import ConfigService
from monkey_island.cc.services.configuration.utils import get_config_network_segments_as_subnet_groups from monkey_island.cc.services.configuration.utils import \
get_config_network_segments_as_subnet_groups
from monkey_island.cc.services.node import NodeService from monkey_island.cc.services.node import NodeService
from monkey_island.cc.services.reporting.pth_report import PTHReportService from monkey_island.cc.services.reporting.pth_report import PTHReportService
from monkey_island.cc.services.reporting.report_exporter_manager import ReportExporterManager from monkey_island.cc.services.reporting.report_exporter_manager import \
from monkey_island.cc.services.reporting.report_generation_synchronisation import safe_generate_regular_report ReportExporterManager
from monkey_island.cc.network_utils import local_ip_addresses, get_subnets from monkey_island.cc.services.reporting.report_generation_synchronisation import \
safe_generate_regular_report
__author__ = "itay.mizeretz" __author__ = "itay.mizeretz"
@ -59,6 +62,7 @@ class ReportService:
PTH_CRIT_SERVICES_ACCESS = 11 PTH_CRIT_SERVICES_ACCESS = 11
MSSQL = 12 MSSQL = 12
VSFTPD = 13 VSFTPD = 13
DRUPAL = 14
class WARNINGS_DICT(Enum): class WARNINGS_DICT(Enum):
CROSS_SEGMENT = 0 CROSS_SEGMENT = 0
@ -623,7 +627,7 @@ class ReportService:
@staticmethod @staticmethod
def get_config_exploits(): def get_config_exploits():
exploits_config_value = ['exploits', 'general', 'exploiter_classes'] exploits_config_value = ['basic', 'exploiters', 'exploiter_classes']
default_exploits = ConfigService.get_default_config(False) default_exploits = ConfigService.get_default_config(False)
for namespace in exploits_config_value: for namespace in exploits_config_value:
default_exploits = default_exploits[namespace] default_exploits = default_exploits[namespace]
@ -637,11 +641,11 @@ class ReportService:
@staticmethod @staticmethod
def get_config_ips(): def get_config_ips():
return ConfigService.get_config_value(['basic_network', 'general', 'subnet_scan_list'], True, True) return ConfigService.get_config_value(['basic_network', 'scope', 'subnet_scan_list'], True, True)
@staticmethod @staticmethod
def get_config_scan(): def get_config_scan():
return ConfigService.get_config_value(['basic_network', 'general', 'local_network_scan'], True, True) return ConfigService.get_config_value(['basic_network', 'scope', 'local_network_scan'], True, True)
@staticmethod @staticmethod
def get_issues_overview(issues, config_users, config_passwords): def get_issues_overview(issues, config_users, config_passwords):
@ -671,6 +675,8 @@ class ReportService:
issues_byte_array[ReportService.ISSUES_DICT.MSSQL.value] = True issues_byte_array[ReportService.ISSUES_DICT.MSSQL.value] = True
elif issue['type'] == 'hadoop': elif issue['type'] == 'hadoop':
issues_byte_array[ReportService.ISSUES_DICT.HADOOP.value] = True issues_byte_array[ReportService.ISSUES_DICT.HADOOP.value] = True
elif issue['type'] == 'drupal':
issues_byte_array[ReportService.ISSUES_DICT.DRUPAL.value] = True
elif issue['type'].endswith('_password') and issue['password'] in config_passwords and \ elif issue['type'].endswith('_password') and issue['password'] in config_passwords and \
issue['username'] in config_users or issue['type'] == 'ssh': issue['username'] in config_users or issue['type'] == 'ssh':
issues_byte_array[ReportService.ISSUES_DICT.WEAK_PASSWORD.value] = True issues_byte_array[ReportService.ISSUES_DICT.WEAK_PASSWORD.value] = True

View File

@ -161,25 +161,29 @@ class ReportPageComponent extends AuthComponent {
</p> </p>
<p> <p>
The monkey started propagating from the following machines where it was manually installed: The monkey started propagating from the following machines where it was manually installed:
<ul>
{this.state.report.overview.manual_monkeys.map(x => <li>{x}</li>)}
</ul>
</p> </p>
<ul>
{this.state.report.overview.manual_monkeys.map(x => <li key={x}>{x}</li>)}
</ul>
<p> <p>
The monkeys were run with the following configuration: The monkeys were run with the following configuration:
</p> </p>
{ {
this.state.report.overview.config_users.length > 0 ? this.state.report.overview.config_users.length > 0 ?
<p> <>
Usernames used for brute-forcing: <p>
Usernames used for brute-forcing:
</p>
<ul> <ul>
{this.state.report.overview.config_users.map(x => <li>{x}</li>)} {this.state.report.overview.config_users.map(x => <li key={x}>{x}</li>)}
</ul> </ul>
Passwords used for brute-forcing: <p>
Passwords used for brute-forcing:
</p>
<ul> <ul>
{this.state.report.overview.config_passwords.map(x => <li>{x.substr(0, 3) + '******'}</li>)} {this.state.report.overview.config_passwords.map(x => <li key={x}>{x.substr(0, 3) + '******'}</li>)}
</ul> </ul>
</p> </>
: :
<p> <p>
Brute forcing uses stolen credentials only. No credentials were supplied during Monkeys Brute forcing uses stolen credentials only. No credentials were supplied during Monkeys
@ -195,7 +199,7 @@ class ReportPageComponent extends AuthComponent {
<p> <p>
The Monkey uses the following exploit methods: The Monkey uses the following exploit methods:
<ul> <ul>
{this.state.report.overview.config_exploits.map(x => <li>{x}</li>)} {this.state.report.overview.config_exploits.map(x => <li key={x}>{x}</li>)}
</ul> </ul>
</p> </p>
) )
@ -209,7 +213,7 @@ class ReportPageComponent extends AuthComponent {
<p> <p>
The Monkey scans the following IPs: The Monkey scans the following IPs:
<ul> <ul>
{this.state.report.overview.config_ips.map(x => <li>{x}</li>)} {this.state.report.overview.config_ips.map(x => <li key={x}>{x}</li>)}
</ul> </ul>
</p> </p>
: :
@ -313,15 +317,15 @@ class ReportPageComponent extends AuthComponent {
The Monkey uncovered the following possible set of issues: The Monkey uncovered the following possible set of issues:
<ul> <ul>
{this.state.report.overview.warnings[this.Warning.CROSS_SEGMENT] ? {this.state.report.overview.warnings[this.Warning.CROSS_SEGMENT] ?
<li>Weak segmentation - Machines from different segments are able to <li key={this.Warning.CROSS_SEGMENT}>Weak segmentation - Machines from different segments are able to
communicate.</li> : null} communicate.</li> : null}
{this.state.report.overview.warnings[this.Warning.TUNNEL] ? {this.state.report.overview.warnings[this.Warning.TUNNEL] ?
<li>Weak segmentation - Machines were able to communicate over unused ports.</li> : null} <li key={this.Warning.TUNNEL}>Weak segmentation - Machines were able to communicate over unused ports.</li> : null}
{this.state.report.overview.warnings[this.Warning.SHARED_LOCAL_ADMIN] ? {this.state.report.overview.warnings[this.Warning.SHARED_LOCAL_ADMIN] ?
<li>Shared local administrator account - Different machines have the same account as a local <li key={this.Warning.SHARED_LOCAL_ADMIN}>Shared local administrator account - Different machines have the same account as a local
administrator.</li> : null} administrator.</li> : null}
{this.state.report.overview.warnings[this.Warning.SHARED_PASSWORDS] ? {this.state.report.overview.warnings[this.Warning.SHARED_PASSWORDS] ?
<li>Multiple users have the same password</li> : null} <li key={this.Warning.SHARED_PASSWORDS}>Multiple users have the same password</li> : null}
</ul> </ul>
</div> </div>
: :
@ -443,21 +447,22 @@ class ReportPageComponent extends AuthComponent {
} }
generateInfoBadges(data_array) { generateInfoBadges(data_array) {
return data_array.map(badge_data => <span className="badge badge-info" style={{margin: '2px'}}>{badge_data}</span>); return data_array.map(badge_data => <span key={badge_data} className="badge badge-info" style={{margin: '2px'}}>{badge_data}</span>);
} }
generateCrossSegmentIssue(crossSegmentIssue) { generateCrossSegmentIssue(crossSegmentIssue) {
return <li> let crossSegmentIssueOverview = 'Communication possible from ' + crossSegmentIssue['source_subnet'] + ' to ' + crossSegmentIssue['target_subnet']
{'Communication possible from ' + crossSegmentIssue['source_subnet'] + ' to ' + crossSegmentIssue['target_subnet']} return <li key={crossSegmentIssueOverview}>
{crossSegmentIssueOverview}
<CollapsibleWellComponent> <CollapsibleWellComponent>
<ul> <ul>
{crossSegmentIssue['issues'].map(x => {crossSegmentIssue['issues'].map(x =>
x['is_self'] ? x['is_self'] ?
<li> <li key={x['hostname']}>
{'Machine ' + x['hostname'] + ' has both ips: ' + x['source'] + ' and ' + x['target']} {'Machine ' + x['hostname'] + ' has both ips: ' + x['source'] + ' and ' + x['target']}
</li> </li>
: :
<li> <li key={x['source'] + x['target']}>
{'IP ' + x['source'] + ' (' + x['hostname'] + ') connected to IP ' + x['target'] {'IP ' + x['source'] + ' (' + x['hostname'] + ') connected to IP ' + x['target']
+ ' using the services: ' + Object.keys(x['services']).join(', ')} + ' using the services: ' + Object.keys(x['services']).join(', ')}
</li> </li>
@ -468,12 +473,12 @@ class ReportPageComponent extends AuthComponent {
} }
generateShellshockPathListBadges(paths) { generateShellshockPathListBadges(paths) {
return paths.map(path => <span className="badge badge-warning" style={{margin: '2px'}}>{path}</span>); return paths.map(path => <span className="badge badge-warning" style={{margin: '2px'}} key={path}>{path}</span>);
} }
generateSmbPasswordIssue(issue) { generateSmbPasswordIssue(issue) {
return ( return (
<li> <>
Change <span className="badge badge-success">{issue.username}</span>'s password to a complex one-use password Change <span className="badge badge-success">{issue.username}</span>'s password to a complex one-use password
that is not shared with other computers on the network. that is not shared with other computers on the network.
<CollapsibleWellComponent> <CollapsibleWellComponent>
@ -484,13 +489,13 @@ class ReportPageComponent extends AuthComponent {
The Monkey authenticated over the SMB protocol with user <span The Monkey authenticated over the SMB protocol with user <span
className="badge badge-success">{issue.username}</span> and its password. className="badge badge-success">{issue.username}</span> and its password.
</CollapsibleWellComponent> </CollapsibleWellComponent>
</li> </>
); );
} }
generateSmbPthIssue(issue) { generateSmbPthIssue(issue) {
return ( return (
<li> <>
Change <span className="badge badge-success">{issue.username}</span>'s password to a complex one-use password Change <span className="badge badge-success">{issue.username}</span>'s password to a complex one-use password
that is not shared with other computers on the network. that is not shared with other computers on the network.
<CollapsibleWellComponent> <CollapsibleWellComponent>
@ -501,13 +506,13 @@ class ReportPageComponent extends AuthComponent {
The Monkey used a pass-the-hash attack over SMB protocol with user <span The Monkey used a pass-the-hash attack over SMB protocol with user <span
className="badge badge-success">{issue.username}</span>. className="badge badge-success">{issue.username}</span>.
</CollapsibleWellComponent> </CollapsibleWellComponent>
</li> </>
); );
} }
generateWmiPasswordIssue(issue) { generateWmiPasswordIssue(issue) {
return ( return (
<li> <>
Change <span className="badge badge-success">{issue.username}</span>'s password to a complex one-use password Change <span className="badge badge-success">{issue.username}</span>'s password to a complex one-use password
that is not shared with other computers on the network. that is not shared with other computers on the network.
<CollapsibleWellComponent> <CollapsibleWellComponent>
@ -518,13 +523,13 @@ class ReportPageComponent extends AuthComponent {
The Monkey authenticated over the WMI protocol with user <span The Monkey authenticated over the WMI protocol with user <span
className="badge badge-success">{issue.username}</span> and its password. className="badge badge-success">{issue.username}</span> and its password.
</CollapsibleWellComponent> </CollapsibleWellComponent>
</li> </>
); );
} }
generateWmiPthIssue(issue) { generateWmiPthIssue(issue) {
return ( return (
<li> <>
Change <span className="badge badge-success">{issue.username}</span>'s password to a complex one-use password Change <span className="badge badge-success">{issue.username}</span>'s password to a complex one-use password
that is not shared with other computers on the network. that is not shared with other computers on the network.
<CollapsibleWellComponent> <CollapsibleWellComponent>
@ -535,13 +540,13 @@ class ReportPageComponent extends AuthComponent {
The Monkey used a pass-the-hash attack over WMI protocol with user <span The Monkey used a pass-the-hash attack over WMI protocol with user <span
className="badge badge-success">{issue.username}</span>. className="badge badge-success">{issue.username}</span>.
</CollapsibleWellComponent> </CollapsibleWellComponent>
</li> </>
); );
} }
generateSshIssue(issue) { generateSshIssue(issue) {
return ( return (
<li> <>
Change <span className="badge badge-success">{issue.username}</span>'s password to a complex one-use password Change <span className="badge badge-success">{issue.username}</span>'s password to a complex one-use password
that is not shared with other computers on the network. that is not shared with other computers on the network.
<CollapsibleWellComponent> <CollapsibleWellComponent>
@ -552,13 +557,13 @@ class ReportPageComponent extends AuthComponent {
The Monkey authenticated over the SSH protocol with user <span The Monkey authenticated over the SSH protocol with user <span
className="badge badge-success">{issue.username}</span> and its password. className="badge badge-success">{issue.username}</span> and its password.
</CollapsibleWellComponent> </CollapsibleWellComponent>
</li> </>
); );
} }
generateSshKeysIssue(issue) { generateSshKeysIssue(issue) {
return ( return (
<li> <>
Protect <span className="badge badge-success">{issue.ssh_key}</span> private key with a pass phrase. Protect <span className="badge badge-success">{issue.ssh_key}</span> private key with a pass phrase.
<CollapsibleWellComponent> <CollapsibleWellComponent>
The machine <span className="badge badge-primary">{issue.machine}</span> (<span The machine <span className="badge badge-primary">{issue.machine}</span> (<span
@ -568,14 +573,14 @@ class ReportPageComponent extends AuthComponent {
The Monkey authenticated over the SSH protocol with private key <span The Monkey authenticated over the SSH protocol with private key <span
className="badge badge-success">{issue.ssh_key}</span>. className="badge badge-success">{issue.ssh_key}</span>.
</CollapsibleWellComponent> </CollapsibleWellComponent>
</li> </>
); );
} }
generateSambaCryIssue(issue) { generateSambaCryIssue(issue) {
return ( return (
<li> <>
Change <span className="badge badge-success">{issue.username}</span>'s password to a complex one-use password Change <span className="badge badge-success">{issue.username}</span>'s password to a complex one-use password
that is not shared with other computers on the network. that is not shared with other computers on the network.
<br/> <br/>
@ -589,13 +594,13 @@ class ReportPageComponent extends AuthComponent {
className="badge badge-success">{issue.username}</span> and its password, and used the SambaCry className="badge badge-success">{issue.username}</span> and its password, and used the SambaCry
vulnerability. vulnerability.
</CollapsibleWellComponent> </CollapsibleWellComponent>
</li> </>
); );
} }
generateVsftpdBackdoorIssue(issue) { generateVsftpdBackdoorIssue(issue) {
return ( return (
<li> <>
Update your VSFTPD server to the latest version vsftpd-3.0.3. Update your VSFTPD server to the latest version vsftpd-3.0.3.
<CollapsibleWellComponent> <CollapsibleWellComponent>
The machine <span className="badge badge-primary">{issue.machine}</span> (<span The machine <span className="badge badge-primary">{issue.machine}</span> (<span
@ -614,13 +619,13 @@ class ReportPageComponent extends AuthComponent {
href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-2523" href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-2523"
>here</a>. >here</a>.
</CollapsibleWellComponent> </CollapsibleWellComponent>
</li> </>
); );
} }
generateElasticIssue(issue) { generateElasticIssue(issue) {
return ( return (
<li> <>
Update your Elastic Search server to version 1.4.3 and up. Update your Elastic Search server to version 1.4.3 and up.
<CollapsibleWellComponent> <CollapsibleWellComponent>
The machine <span className="badge badge-primary">{issue.machine}</span> (<span The machine <span className="badge badge-primary">{issue.machine}</span> (<span
@ -629,13 +634,13 @@ class ReportPageComponent extends AuthComponent {
<br/> <br/>
The attack was made possible because the Elastic Search server was not patched against CVE-2015-1427. The attack was made possible because the Elastic Search server was not patched against CVE-2015-1427.
</CollapsibleWellComponent> </CollapsibleWellComponent>
</li> </>
); );
} }
generateShellshockIssue(issue) { generateShellshockIssue(issue) {
return ( return (
<li> <>
Update your Bash to a ShellShock-patched version. Update your Bash to a ShellShock-patched version.
<CollapsibleWellComponent> <CollapsibleWellComponent>
The machine <span className="badge badge-primary">{issue.machine}</span> (<span The machine <span className="badge badge-primary">{issue.machine}</span> (<span
@ -646,13 +651,13 @@ class ReportPageComponent extends AuthComponent {
className="badge badge-info">{issue.port}</span> was vulnerable to a shell injection attack on the className="badge badge-info">{issue.port}</span> was vulnerable to a shell injection attack on the
paths: {this.generateShellshockPathListBadges(issue.paths)}. paths: {this.generateShellshockPathListBadges(issue.paths)}.
</CollapsibleWellComponent> </CollapsibleWellComponent>
</li> </>
); );
} }
generateAzureIssue(issue) { generateAzureIssue(issue) {
return ( return (
<li> <>
Delete VM Access plugin configuration files. Delete VM Access plugin configuration files.
<CollapsibleWellComponent> <CollapsibleWellComponent>
Credentials could be stolen from <span Credentials could be stolen from <span
@ -661,13 +666,13 @@ class ReportPageComponent extends AuthComponent {
href="https://www.guardicore.com/2018/03/recovering-plaintext-passwords-azure/" href="https://www.guardicore.com/2018/03/recovering-plaintext-passwords-azure/"
>here</a>. >here</a>.
</CollapsibleWellComponent> </CollapsibleWellComponent>
</li> </>
); );
} }
generateConfickerIssue(issue) { generateConfickerIssue(issue) {
return ( return (
<li> <>
Install the latest Windows updates or upgrade to a newer operating system. Install the latest Windows updates or upgrade to a newer operating system.
<CollapsibleWellComponent> <CollapsibleWellComponent>
The machine <span className="badge badge-primary">{issue.machine}</span> (<span The machine <span className="badge badge-primary">{issue.machine}</span> (<span
@ -677,13 +682,13 @@ class ReportPageComponent extends AuthComponent {
The attack was made possible because the target machine used an outdated and unpatched operating system The attack was made possible because the target machine used an outdated and unpatched operating system
vulnerable to Conficker. vulnerable to Conficker.
</CollapsibleWellComponent> </CollapsibleWellComponent>
</li> </>
); );
} }
generateIslandCrossSegmentIssue(issue) { generateIslandCrossSegmentIssue(issue) {
return ( return (
<li> <>
Segment your network and make sure there is no communication between machines from different segments. Segment your network and make sure there is no communication between machines from different segments.
<CollapsibleWellComponent> <CollapsibleWellComponent>
The network can probably be segmented. A monkey instance on <span The network can probably be segmented. A monkey instance on <span
@ -692,37 +697,37 @@ class ReportPageComponent extends AuthComponent {
could directly access the Monkey Island server in the could directly access the Monkey Island server in the
networks {this.generateInfoBadges(issue.server_networks)}. networks {this.generateInfoBadges(issue.server_networks)}.
</CollapsibleWellComponent> </CollapsibleWellComponent>
</li> </>
); );
} }
generateSharedCredsDomainIssue(issue) { generateSharedCredsDomainIssue(issue) {
return ( return (
<li> <>
Some domain users are sharing passwords, this should be fixed by changing passwords. Some domain users are sharing passwords, this should be fixed by changing passwords.
<CollapsibleWellComponent> <CollapsibleWellComponent>
These users are sharing access password: These users are sharing access password:
{this.generateInfoBadges(issue.shared_with)}. {this.generateInfoBadges(issue.shared_with)}.
</CollapsibleWellComponent> </CollapsibleWellComponent>
</li> </>
); );
} }
generateSharedCredsIssue(issue) { generateSharedCredsIssue(issue) {
return ( return (
<li> <>
Some users are sharing passwords, this should be fixed by changing passwords. Some users are sharing passwords, this should be fixed by changing passwords.
<CollapsibleWellComponent> <CollapsibleWellComponent>
These users are sharing access password: These users are sharing access password:
{this.generateInfoBadges(issue.shared_with)}. {this.generateInfoBadges(issue.shared_with)}.
</CollapsibleWellComponent> </CollapsibleWellComponent>
</li> </>
); );
} }
generateSharedLocalAdminsIssue(issue) { generateSharedLocalAdminsIssue(issue) {
return ( return (
<li> <>
Make sure the right administrator accounts are managing the right machines, and that there isnt an unintentional local Make sure the right administrator accounts are managing the right machines, and that there isnt an unintentional local
admin sharing. admin sharing.
<CollapsibleWellComponent> <CollapsibleWellComponent>
@ -730,13 +735,13 @@ class ReportPageComponent extends AuthComponent {
className="badge badge-primary">{issue.username}</span> is defined as an administrator: className="badge badge-primary">{issue.username}</span> is defined as an administrator:
{this.generateInfoBadges(issue.shared_machines)} {this.generateInfoBadges(issue.shared_machines)}
</CollapsibleWellComponent> </CollapsibleWellComponent>
</li> </>
); );
} }
generateStrongUsersOnCritIssue(issue) { generateStrongUsersOnCritIssue(issue) {
return ( return (
<li> <>
This critical machine is open to attacks via strong users with access to it. This critical machine is open to attacks via strong users with access to it.
<CollapsibleWellComponent> <CollapsibleWellComponent>
The services: {this.generateInfoBadges(issue.services)} have been found on the machine 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: These users has access to it:
{this.generateInfoBadges(issue.threatening_users)}. {this.generateInfoBadges(issue.threatening_users)}.
</CollapsibleWellComponent> </CollapsibleWellComponent>
</li> </>
); );
} }
generateTunnelIssue(issue) { generateTunnelIssue(issue) {
return ( return (
<li> <>
Use micro-segmentation policies to disable communication other than the required. Use micro-segmentation policies to disable communication other than the required.
<CollapsibleWellComponent> <CollapsibleWellComponent>
Machines are not locked down at port level. Network tunnel was set up from <span Machines are not locked down at port level. Network tunnel was set up from <span
className="badge badge-primary">{issue.machine}</span> to <span className="badge badge-primary">{issue.machine}</span> to <span
className="badge badge-primary">{issue.dest}</span>. className="badge badge-primary">{issue.dest}</span>.
</CollapsibleWellComponent> </CollapsibleWellComponent>
</li> </>
); );
} }
generateStruts2Issue(issue) { generateStruts2Issue(issue) {
return ( return (
<li> <>
Upgrade Struts2 to version 2.3.32 or 2.5.10.1 or any later versions. Upgrade Struts2 to version 2.3.32 or 2.5.10.1 or any later versions.
<CollapsibleWellComponent> <CollapsibleWellComponent>
Struts2 server at <span className="badge badge-primary">{issue.machine}</span> (<span Struts2 server at <span className="badge badge-primary">{issue.machine}</span> (<span
@ -775,13 +780,31 @@ class ReportPageComponent extends AuthComponent {
href="https://cwiki.apache.org/confluence/display/WW/S2-045" href="https://cwiki.apache.org/confluence/display/WW/S2-045"
>here</a>. >here</a>.
</CollapsibleWellComponent> </CollapsibleWellComponent>
</li> </>
);
}
generateDrupalIssue(issue) {
return (
<>
Upgrade Drupal server to versions 8.5.11, 8.6.10, or later.
<CollapsibleWellComponent>
Drupal server at <span className="badge badge-primary">{issue.machine}</span> (<span
className="badge badge-info" style={{margin: '2px'}}>{issue.ip_address}</span>) is vulnerable to <span
className="badge badge-danger">remote command execution</span> attack.
<br/>
The attack was made possible because the server is using an old version of Drupal.
For possible workarounds and more info read <a
href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-6340"
>here</a>.
</CollapsibleWellComponent>
</>
); );
} }
generateWebLogicIssue(issue) { generateWebLogicIssue(issue) {
return ( return (
<li> <>
Update Oracle WebLogic server to the latest supported version. Update Oracle WebLogic server to the latest supported version.
<CollapsibleWellComponent> <CollapsibleWellComponent>
Oracle WebLogic server at <span className="badge badge-primary">{issue.machine}</span> (<span Oracle WebLogic server at <span className="badge badge-primary">{issue.machine}</span> (<span
@ -792,13 +815,13 @@ class ReportPageComponent extends AuthComponent {
<a href={'https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-10271'}> CVE-2017-10271</a> or <a href={'https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-10271'}> CVE-2017-10271</a> or
<a href={'https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2725'}> CVE-2019-2725</a> <a href={'https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2725'}> CVE-2019-2725</a>
</CollapsibleWellComponent> </CollapsibleWellComponent>
</li> </>
); );
} }
generateHadoopIssue(issue) { generateHadoopIssue(issue) {
return ( return (
<li> <>
Run Hadoop in secure mode (<a Run Hadoop in secure mode (<a
href="http://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-common/SecureMode.html"> href="http://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-common/SecureMode.html">
add Kerberos authentication</a>). add Kerberos authentication</a>).
@ -809,13 +832,13 @@ class ReportPageComponent extends AuthComponent {
<br/> <br/>
The attack was made possible due to default Hadoop/Yarn configuration being insecure. The attack was made possible due to default Hadoop/Yarn configuration being insecure.
</CollapsibleWellComponent> </CollapsibleWellComponent>
</li> </>
); );
} }
generateMSSQLIssue(issue) { generateMSSQLIssue(issue) {
return ( return (
<li> <>
Disable the xp_cmdshell option. Disable the xp_cmdshell option.
<CollapsibleWellComponent> <CollapsibleWellComponent>
The machine <span className="badge badge-primary">{issue.machine}</span> (<span The machine <span className="badge badge-primary">{issue.machine}</span> (<span
@ -827,88 +850,91 @@ class ReportPageComponent extends AuthComponent {
href="https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/xp-cmdshell-server-configuration-option?view=sql-server-2017"> href="https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/xp-cmdshell-server-configuration-option?view=sql-server-2017">
Microsoft's documentation. </a> Microsoft's documentation. </a>
</CollapsibleWellComponent> </CollapsibleWellComponent>
</li> </>
); );
} }
generateIssue = (issue) => { generateIssue = (issue) => {
let data; let issueData;
switch (issue.type) { switch (issue.type) {
case 'vsftp': case 'vsftp':
data = this.generateVsftpdBackdoorIssue(issue); issueData = this.generateVsftpdBackdoorIssue(issue);
break; break;
case 'smb_password': case 'smb_password':
data = this.generateSmbPasswordIssue(issue); issueData = this.generateSmbPasswordIssue(issue);
break; break;
case 'smb_pth': case 'smb_pth':
data = this.generateSmbPthIssue(issue); issueData = this.generateSmbPthIssue(issue);
break; break;
case 'wmi_password': case 'wmi_password':
data = this.generateWmiPasswordIssue(issue); issueData = this.generateWmiPasswordIssue(issue);
break; break;
case 'wmi_pth': case 'wmi_pth':
data = this.generateWmiPthIssue(issue); issueData = this.generateWmiPthIssue(issue);
break; break;
case 'ssh': case 'ssh':
data = this.generateSshIssue(issue); issueData = this.generateSshIssue(issue);
break; break;
case 'ssh_key': case 'ssh_key':
data = this.generateSshKeysIssue(issue); issueData = this.generateSshKeysIssue(issue);
break; break;
case 'sambacry': case 'sambacry':
data = this.generateSambaCryIssue(issue); issueData = this.generateSambaCryIssue(issue);
break; break;
case 'elastic': case 'elastic':
data = this.generateElasticIssue(issue); issueData = this.generateElasticIssue(issue);
break; break;
case 'shellshock': case 'shellshock':
data = this.generateShellshockIssue(issue); issueData = this.generateShellshockIssue(issue);
break; break;
case 'conficker': case 'conficker':
data = this.generateConfickerIssue(issue); issueData = this.generateConfickerIssue(issue);
break; break;
case 'island_cross_segment': case 'island_cross_segment':
data = this.generateIslandCrossSegmentIssue(issue); issueData = this.generateIslandCrossSegmentIssue(issue);
break; break;
case 'shared_passwords': case 'shared_passwords':
data = this.generateSharedCredsIssue(issue); issueData = this.generateSharedCredsIssue(issue);
break; break;
case 'shared_passwords_domain': case 'shared_passwords_domain':
data = this.generateSharedCredsDomainIssue(issue); issueData = this.generateSharedCredsDomainIssue(issue);
break; break;
case 'shared_admins_domain': case 'shared_admins_domain':
data = this.generateSharedLocalAdminsIssue(issue); issueData = this.generateSharedLocalAdminsIssue(issue);
break; break;
case 'strong_users_on_crit': case 'strong_users_on_crit':
data = this.generateStrongUsersOnCritIssue(issue); issueData = this.generateStrongUsersOnCritIssue(issue);
break; break;
case 'tunnel': case 'tunnel':
data = this.generateTunnelIssue(issue); issueData = this.generateTunnelIssue(issue);
break; break;
case 'azure_password': case 'azure_password':
data = this.generateAzureIssue(issue); issueData = this.generateAzureIssue(issue);
break; break;
case 'struts2': case 'struts2':
data = this.generateStruts2Issue(issue); issueData = this.generateStruts2Issue(issue);
break; break;
case 'weblogic': case 'weblogic':
data = this.generateWebLogicIssue(issue); issueData = this.generateWebLogicIssue(issue);
break; break;
case 'hadoop': case 'hadoop':
data = this.generateHadoopIssue(issue); issueData = this.generateHadoopIssue(issue);
break; break;
case 'mssql': case 'mssql':
data = this.generateMSSQLIssue(issue); issueData = this.generateMSSQLIssue(issue);
break;
case 'drupal':
issueData = this.generateDrupalIssue(issue);
break; break;
} }
return data; return <li key={JSON.stringify(issue)}>{issueData}</li>;
}; };
generateIssues = (issues) => { generateIssues = (issues) => {
let issuesDivArray = []; let issuesDivArray = [];
for (let machine of Object.keys(issues)) { for (let machine of Object.keys(issues)) {
issuesDivArray.push( issuesDivArray.push(
<li> <li key={JSON.stringify(machine)}>
<h4><b>{machine}</b></h4> <h4><b>{machine}</b></h4>
<ol> <ol>
{issues[machine].map(this.generateIssue)} {issues[machine].map(this.generateIssue)}