Merge pull request #998 from guardicore/zerologon-password-reset-warning

Zerologon password reset warning
This commit is contained in:
Mike Salvatore 2021-03-02 07:01:03 -05:00 committed by GitHub
commit 1b73c56d67
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 481 additions and 266 deletions

View File

@ -7,12 +7,6 @@ tags: ["exploit", "windows"]
The Zerologon exploiter exploits [CVE-2020-1472](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-1472). The Zerologon exploiter exploits [CVE-2020-1472](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-1472).
This exploiter is unsafe.
* It will temporarily change the target domain controller's password.
* It may break the target domain controller's communication with other systems in the network, affecting functionality.
It is, therefore, **not** enabled by default.
### Description ### Description
@ -20,6 +14,60 @@ An elevation of privilege vulnerability exists when an attacker establishes a vu
To download the relevant security update and read more, click [here](https://msrc.microsoft.com/update-guide/en-US/vulnerability/CVE-2020-1472). To download the relevant security update and read more, click [here](https://msrc.microsoft.com/update-guide/en-US/vulnerability/CVE-2020-1472).
### A note on safety
This exploiter is not safe for production or other sensitive environments. It
is, therefore, **not** enabled by default.
During successful exploitation, the Zerologon exploiter:
* will temporarily change the target domain controller's password.
* may break the target domain controller's communication with other systems in the network, affecting functionality.
* may change the administrator's password.
* will *attempt* to revert all changes.
While the Zerologon exploiter is usually successful in reverting its changes
and restoring the original passwords, it sometimes fails. Restoring passwords
manually after the Zerologon exploiter has run is nontrivial. For information
on restoring the original passwords, see the section on manually restoring your
passwords.
To minimize the risk posed by this exploiter, it is recommended that this
exploiter be run _only_ against VMs with a recent snapshot and _only_ in
testing or staging environments.
### Manually restoring your password
This exploiter attempts to restore the original passwords after exploitation.
It is usually successful, but it sometimes fails. If this exploiter has changed
a password but was unable to restore the original, you can try the following
methods to restore the original password.
#### Restore the VM from a recent snapshot
If the affected system is a virtual machine, the simplest way to restore it to
a working state is to revert to a recent snapshot.
#### Restore the administrator's password
If you are unable to log in as the administrator, you can follow the
instructions
[here](https://www.top-password.com/knowledge/reset-windows-server-2019-password.html)
to regain access to the system.
#### Use Reset-ComputerMachinePassword
If you are able to login as the administrator, you can use the
[Reset-ComputerMachinePassword](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/reset-computermachinepassword?view=powershell-5.1)
powershell command to restore the domain controller's password.
#### Try a zerologon password restoration tool
If all other approaches fail, you can try the tools and steps found
[here](https://github.com/risksense/zerologon).
### Notes ### Notes

View File

@ -48,3 +48,7 @@ class VersionServerConnectionError(Exception):
class FindingWithoutDetailsError(Exception): class FindingWithoutDetailsError(Exception):
""" Raise when pulling events for a finding, but get none """ """ Raise when pulling events for a finding, but get none """
class DomainControllerNameFetchError(FailedExploitationError):
""" Raise on failed attempt to extract domain controller's name """

View File

@ -79,8 +79,8 @@ class HostExploiter(Plugin):
result = None result = None
try: try:
result = self._exploit_host() result = self._exploit_host()
except FailedExploitationError: except FailedExploitationError as e:
logger.debug('Exploiter failed.', exc_info=True) logger.debug(f'Exploiter failed: {e}.')
except Exception: except Exception:
logger.error('Exception in exploit_host', exc_info=True) logger.error('Exception in exploit_host', exc_info=True)
finally: finally:

View File

@ -1,6 +1,7 @@
import pytest import pytest
from nmb.NetBIOS import NetBIOS from nmb.NetBIOS import NetBIOS
from common.utils.exceptions import DomainControllerNameFetchError
from infection_monkey.exploit.zerologon_utils.vuln_assessment import \ from infection_monkey.exploit.zerologon_utils.vuln_assessment import \
get_dc_details get_dc_details
from infection_monkey.model.host import VictimHost from infection_monkey.model.host import VictimHost
@ -38,8 +39,5 @@ def test_get_dc_details_no_netbios_names(host, monkeypatch):
stub_queryIPForName = _get_stub_queryIPForName(NETBIOS_NAMES) stub_queryIPForName = _get_stub_queryIPForName(NETBIOS_NAMES)
monkeypatch.setattr(NetBIOS, "queryIPForName", stub_queryIPForName) monkeypatch.setattr(NetBIOS, "queryIPForName", stub_queryIPForName)
with pytest.raises(DomainControllerNameFetchError):
dc_ip, dc_name, dc_handle = get_dc_details(host) dc_ip, dc_name, dc_handle = get_dc_details(host)
assert dc_ip == IP
assert dc_name == ""
assert dc_handle == "\\\\"

View File

@ -38,6 +38,7 @@ class ZerologonExploiter(HostExploiter):
super().__init__(host) super().__init__(host)
self.vulnerable_port = None self.vulnerable_port = None
self.exploit_info["credentials"] = {} self.exploit_info["credentials"] = {}
self.exploit_info["password_restored"] = None
self._extracted_creds = {} self._extracted_creds = {}
def _exploit_host(self) -> bool: def _exploit_host(self) -> bool:
@ -62,9 +63,11 @@ class ZerologonExploiter(HostExploiter):
# Restore DC's original password. # Restore DC's original password.
if _exploited: if _exploited:
if self.restore_password(): if self.restore_password():
self.exploit_info["password_restored"] = True
self.store_extracted_creds_for_exploitation() self.store_extracted_creds_for_exploitation()
LOG.info("System exploited and password restored successfully.") LOG.info("System exploited and password restored successfully.")
else: else:
self.exploit_info["password_restored"] = False
LOG.info("System exploited but couldn't restore password!") LOG.info("System exploited but couldn't restore password!")
else: else:
LOG.info("System was not exploited.") LOG.info("System was not exploited.")

View File

@ -4,6 +4,9 @@ from typing import Optional
import nmb.NetBIOS import nmb.NetBIOS
from impacket.dcerpc.v5 import nrpc, rpcrt from impacket.dcerpc.v5 import nrpc, rpcrt
from common.common_consts.timeouts import MEDIUM_REQUEST_TIMEOUT
from common.utils.exceptions import DomainControllerNameFetchError
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
@ -18,14 +21,16 @@ def _get_dc_name(dc_ip: str) -> str:
""" """
Gets NetBIOS name of the Domain Controller (DC). Gets NetBIOS name of the Domain Controller (DC).
""" """
try: nb = nmb.NetBIOS.NetBIOS()
nb = nmb.NetBIOS.NetBIOS() name = nb.queryIPForName(
name = nb.queryIPForName( ip=dc_ip,
ip=dc_ip timeout=MEDIUM_REQUEST_TIMEOUT
) # returns either a list of NetBIOS names or None ) # returns either a list of NetBIOS names or None
return name[0] if name else ""
except BaseException as ex: if name:
LOG.info(f"Exception: {ex}") return name[0]
else:
raise DomainControllerNameFetchError("Couldn't get domain controller's name, maybe it's on external network?")
def is_exploitable(zerologon_exploiter_object) -> (bool, Optional[rpcrt.DCERPC_v5]): def is_exploitable(zerologon_exploiter_object) -> (bool, Optional[rpcrt.DCERPC_v5]):

View File

@ -2,166 +2,142 @@ from monkey_island.cc.services.utils.typographic_symbols import WARNING_SIGN
EXPLOITER_CLASSES = { EXPLOITER_CLASSES = {
"title": "Exploit class", "title": "Exploit class",
"description": "Click on exploiter to get more information about it." + WARNING_SIGN + "description": "Click on exploiter to get more information about it."
" Note that using unsafe exploits may cause crashes of the exploited machine/service.", + WARNING_SIGN
+ " Note that using unsafe exploits may cause crashes of the exploited machine/service.",
"type": "string", "type": "string",
"anyOf": [ "anyOf": [
{ {
"type": "string", "type": "string",
"enum": [ "enum": ["SmbExploiter"],
"SmbExploiter"
],
"title": "SMB Exploiter", "title": "SMB Exploiter",
"safe": True, "safe": True,
"attack_techniques": ["T1110", "T1075", "T1035"], "attack_techniques": ["T1110", "T1075", "T1035"],
"info": "Brute forces using credentials provided by user and" "info": "Brute forces using credentials provided by user and"
" hashes gathered by mimikatz.", " hashes gathered by mimikatz.",
"link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/smbexec/" "link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/smbexec/",
}, },
{ {
"type": "string", "type": "string",
"enum": [ "enum": ["WmiExploiter"],
"WmiExploiter"
],
"title": "WMI Exploiter", "title": "WMI Exploiter",
"safe": True, "safe": True,
"attack_techniques": ["T1110", "T1106"], "attack_techniques": ["T1110", "T1106"],
"info": "Brute forces WMI (Windows Management Instrumentation) " "info": "Brute forces WMI (Windows Management Instrumentation) "
"using credentials provided by user and hashes gathered by mimikatz.", "using credentials provided by user and hashes gathered by mimikatz.",
"link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/wmiexec/" "link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/wmiexec/",
}, },
{ {
"type": "string", "type": "string",
"enum": [ "enum": ["MSSQLExploiter"],
"MSSQLExploiter"
],
"title": "MSSQL Exploiter", "title": "MSSQL Exploiter",
"safe": True, "safe": True,
"attack_techniques": ["T1110"], "attack_techniques": ["T1110"],
"info": "Tries to brute force into MsSQL server and uses insecure " "info": "Tries to brute force into MsSQL server and uses insecure "
"configuration to execute commands on server.", "configuration to execute commands on server.",
"link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/mssql/" "link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/mssql/",
}, },
{ {
"type": "string", "type": "string",
"enum": [ "enum": ["Ms08_067_Exploiter"],
"Ms08_067_Exploiter"
],
"title": "MS08-067 Exploiter", "title": "MS08-067 Exploiter",
"safe": False, "safe": False,
"info": "Unsafe exploiter, that might cause system crash due to the use of buffer overflow. " "info": "Unsafe exploiter, that might cause system crash due to the use of buffer overflow. "
"Uses MS08-067 vulnerability.", "Uses MS08-067 vulnerability.",
"link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/ms08-067/" "link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/ms08-067/",
}, },
{ {
"type": "string", "type": "string",
"enum": [ "enum": ["SSHExploiter"],
"SSHExploiter"
],
"title": "SSH Exploiter", "title": "SSH Exploiter",
"safe": True, "safe": True,
"attack_techniques": ["T1110", "T1145", "T1106"], "attack_techniques": ["T1110", "T1145", "T1106"],
"info": "Brute forces using credentials provided by user and SSH keys gathered from systems.", "info": "Brute forces using credentials provided by user and SSH keys gathered from systems.",
"link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/sshexec/" "link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/sshexec/",
}, },
{ {
"type": "string", "type": "string",
"enum": [ "enum": ["ShellShockExploiter"],
"ShellShockExploiter"
],
"title": "ShellShock Exploiter", "title": "ShellShock Exploiter",
"safe": True, "safe": True,
"info": "CVE-2014-6271, based on logic from " "info": "CVE-2014-6271, based on logic from "
"https://github.com/nccgroup/shocker/blob/master/shocker.py .", "https://github.com/nccgroup/shocker/blob/master/shocker.py .",
"link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/shellshock/" "link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/shellshock/",
}, },
{ {
"type": "string", "type": "string",
"enum": [ "enum": ["SambaCryExploiter"],
"SambaCryExploiter"
],
"title": "SambaCry Exploiter", "title": "SambaCry Exploiter",
"safe": True, "safe": True,
"info": "Bruteforces and searches for anonymous shares. Uses Impacket.", "info": "Bruteforces and searches for anonymous shares. Uses Impacket.",
"link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/sambacry/" "link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/sambacry/",
}, },
{ {
"type": "string", "type": "string",
"enum": [ "enum": ["ElasticGroovyExploiter"],
"ElasticGroovyExploiter"
],
"title": "ElasticGroovy Exploiter", "title": "ElasticGroovy Exploiter",
"safe": True, "safe": True,
"info": "CVE-2015-1427. Logic is based on Metasploit module.", "info": "CVE-2015-1427. Logic is based on Metasploit module.",
"link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/elasticgroovy/" "link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/elasticgroovy/",
}, },
{ {
"type": "string", "type": "string",
"enum": [ "enum": ["Struts2Exploiter"],
"Struts2Exploiter"
],
"title": "Struts2 Exploiter", "title": "Struts2 Exploiter",
"safe": True, "safe": True,
"info": "Exploits struts2 java web framework. CVE-2017-5638. Logic based on " "info": "Exploits struts2 java web framework. CVE-2017-5638. Logic based on "
"https://www.exploit-db.com/exploits/41570 .", "https://www.exploit-db.com/exploits/41570 .",
"link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/struts2/" "link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/struts2/",
}, },
{ {
"type": "string", "type": "string",
"enum": [ "enum": ["WebLogicExploiter"],
"WebLogicExploiter"
],
"title": "WebLogic Exploiter", "title": "WebLogic Exploiter",
"safe": True, "safe": True,
"info": "Exploits CVE-2017-10271 and CVE-2019-2725 vulnerabilities on WebLogic server.", "info": "Exploits CVE-2017-10271 and CVE-2019-2725 vulnerabilities on WebLogic server.",
"link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/weblogic/" "link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/weblogic/",
}, },
{ {
"type": "string", "type": "string",
"enum": [ "enum": ["HadoopExploiter"],
"HadoopExploiter"
],
"title": "Hadoop/Yarn Exploiter", "title": "Hadoop/Yarn Exploiter",
"safe": True, "safe": True,
"info": "Remote code execution on HADOOP server with YARN and default settings. " "info": "Remote code execution on HADOOP server with YARN and default settings. "
"Logic based on https://github.com/vulhub/vulhub/tree/master/hadoop/unauthorized-yarn.", "Logic based on https://github.com/vulhub/vulhub/tree/master/hadoop/unauthorized-yarn.",
"link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/hadoop/" "link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/hadoop/",
}, },
{ {
"type": "string", "type": "string",
"enum": [ "enum": ["VSFTPDExploiter"],
"VSFTPDExploiter"
],
"title": "VSFTPD Exploiter", "title": "VSFTPD Exploiter",
"safe": True, "safe": True,
"info": "Exploits a malicious backdoor that was added to the VSFTPD download archive. " "info": "Exploits a malicious backdoor that was added to the VSFTPD download archive. "
"Logic based on Metasploit module.", "Logic based on Metasploit module.",
"link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/vsftpd/" "link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/vsftpd/",
}, },
{ {
"type": "string", "type": "string",
"enum": [ "enum": ["DrupalExploiter"],
"DrupalExploiter"
],
"title": "Drupal Exploiter", "title": "Drupal Exploiter",
"safe": True, "safe": True,
"info": "Exploits a remote command execution vulnerability in a Drupal server," "info": "Exploits a remote command execution vulnerability in a Drupal server,"
"for which certain modules (such as RESTful Web Services) are enabled.", "for which certain modules (such as RESTful Web Services) are enabled.",
"link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/drupal/" "link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/drupal/",
}, },
{ {
"type": "string", "type": "string",
"enum": [ "enum": ["ZerologonExploiter"],
"ZerologonExploiter"
],
"title": "Zerologon Exploiter", "title": "Zerologon Exploiter",
"safe": False, "safe": False,
"info": "Exploits a privilege escalation vulnerability (CVE-2020-1472) in a Windows " "info": "Exploits a privilege escalation vulnerability (CVE-2020-1472) in a Windows "
"server domain controller by using the Netlogon Remote Protocol (MS-NRPC). " "server domain controller by using the Netlogon Remote Protocol (MS-NRPC). "
"This exploiter changes the password of a Windows server domain controller " "This exploiter changes the password of a Windows server domain controller "
"account and could prevent the victim domain controller from communicating " "account and then attempts to restore it. The victim domain controller "
"with other domain controllers.", "will be unable to communicate with other domain controllers until the original "
"link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/zerologon/" "password has been restored. If Infection Monkey fails to restore the "
} "password automatically, you'll have to do it manually. For more "
] "information, see the documentation.",
"link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/zerologon/",
},
],
} }

View File

@ -65,6 +65,7 @@ class ReportService:
VSFTPD = 13 VSFTPD = 13
DRUPAL = 14 DRUPAL = 14
ZEROLOGON = 15 ZEROLOGON = 15
ZEROLOGON_PASSWORD_RESTORE_FAILED = 16
class WARNINGS_DICT(Enum): class WARNINGS_DICT(Enum):
CROSS_SEGMENT = 0 CROSS_SEGMENT = 0
@ -394,6 +395,7 @@ class ReportService:
def process_zerologon_exploit(exploit): def process_zerologon_exploit(exploit):
processed_exploit = ReportService.process_general_exploit(exploit) processed_exploit = ReportService.process_general_exploit(exploit)
processed_exploit['type'] = 'zerologon' processed_exploit['type'] = 'zerologon'
processed_exploit['password_restored'] = exploit['data']['info']['password_restored']
return processed_exploit return processed_exploit
@staticmethod @staticmethod
@ -713,6 +715,8 @@ class ReportService:
elif issue['type'] == 'drupal': elif issue['type'] == 'drupal':
issues_byte_array[ReportService.ISSUES_DICT.DRUPAL.value] = True issues_byte_array[ReportService.ISSUES_DICT.DRUPAL.value] = True
elif issue['type'] == 'zerologon': elif issue['type'] == 'zerologon':
if not issue['password_restored']:
issues_byte_array[ReportService.ISSUES_DICT.ZEROLOGON_PASSWORD_RESTORE_FAILED.value] = True
issues_byte_array[ReportService.ISSUES_DICT.ZEROLOGON.value] = True issues_byte_array[ReportService.ISSUES_DICT.ZEROLOGON.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':

View File

@ -13,9 +13,11 @@ import ReportHeader, {ReportTypes} from './common/ReportHeader';
import ReportLoader from './common/ReportLoader'; import ReportLoader from './common/ReportLoader';
import SecurityIssuesGlance from './common/SecurityIssuesGlance'; import SecurityIssuesGlance from './common/SecurityIssuesGlance';
import PrintReportButton from './common/PrintReportButton'; import PrintReportButton from './common/PrintReportButton';
import WarningIcon from '../ui-components/WarningIcon';
import {Button} from 'react-bootstrap';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
import { faMinus } from '@fortawesome/free-solid-svg-icons/faMinus'; import {faMinus} from '@fortawesome/free-solid-svg-icons/faMinus';
import guardicoreLogoImage from '../../images/guardicore-logo.png' import guardicoreLogoImage from '../../images/guardicore-logo.png'
import {faExclamationTriangle} from '@fortawesome/free-solid-svg-icons'; import {faExclamationTriangle} from '@fortawesome/free-solid-svg-icons';
import '../../styles/App.css'; import '../../styles/App.css';
@ -38,9 +40,14 @@ class ReportPageComponent extends AuthComponent {
HADOOP: 10, HADOOP: 10,
PTH_CRIT_SERVICES_ACCESS: 11, PTH_CRIT_SERVICES_ACCESS: 11,
MSSQL: 12, MSSQL: 12,
VSFTPD: 13 VSFTPD: 13,
DRUPAL: 14,
ZEROLOGON: 15,
ZEROLOGON_PASSWORD_RESTORE_FAILED: 16
}; };
NotThreats = [this.Issue.ZEROLOGON_PASSWORD_RESTORE_FAILED];
Warning = Warning =
{ {
CROSS_SEGMENT: 0, CROSS_SEGMENT: 0,
@ -78,7 +85,7 @@ class ReportPageComponent extends AuthComponent {
componentDidUpdate(prevProps) { componentDidUpdate(prevProps) {
if (this.props.report !== prevProps.report) { if (this.props.report !== prevProps.report) {
this.setState({ report: this.props.report }) this.setState({report: this.props.report})
} }
} }
@ -105,7 +112,7 @@ class ReportPageComponent extends AuthComponent {
print(); print();
}}/> }}/>
</div> </div>
<div className="report-page"> <div className='report-page'>
<ReportHeader report_type={ReportTypes.security}/> <ReportHeader report_type={ReportTypes.security}/>
<hr/> <hr/>
{content} {content}
@ -137,7 +144,7 @@ class ReportPageComponent extends AuthComponent {
generateReportOverviewSection() { generateReportOverviewSection() {
return ( return (
<div id="overview"> <div id='overview'>
<h2> <h2>
Overview Overview
</h2> </h2>
@ -146,7 +153,7 @@ class ReportPageComponent extends AuthComponent {
this.state.report.glance.exploited.length > 0 ? this.state.report.glance.exploited.length > 0 ?
'' ''
: :
<p className="alert alert-info"> <p className='alert alert-info'>
<FontAwesomeIcon icon={faExclamationTriangle} style={{'marginRight': '5px'}}/> <FontAwesomeIcon icon={faExclamationTriangle} style={{'marginRight': '5px'}}/>
To improve the monkey's detection rates, try adding users and passwords and enable the "Local To improve the monkey's detection rates, try adding users and passwords and enable the "Local
network network
@ -155,8 +162,8 @@ class ReportPageComponent extends AuthComponent {
} }
<p> <p>
The first monkey run was started on <span The first monkey run was started on <span
className="badge badge-info">{this.state.report.overview.monkey_start_time}</span>. After <span className='badge badge-info'>{this.state.report.overview.monkey_start_time}</span>. After <span
className="badge badge-info">{this.state.report.overview.monkey_duration}</span>, all monkeys finished className='badge badge-info'>{this.state.report.overview.monkey_duration}</span>, all monkeys finished
propagation attempts. propagation attempts.
</p> </p>
<p> <p>
@ -175,7 +182,7 @@ class ReportPageComponent extends AuthComponent {
Usernames used for brute-forcing: Usernames used for brute-forcing:
</p> </p>
<ul> <ul>
{this.state.report.overview.config_users.map(x => <li key={x}>{x}</li>)} {this.state.report.overview.config_users.map(x => <li key={x}>{x}</li>)}
</ul> </ul>
<p> <p>
Passwords used for brute-forcing: Passwords used for brute-forcing:
@ -233,7 +240,7 @@ class ReportPageComponent extends AuthComponent {
generateReportFindingsSection() { generateReportFindingsSection() {
return ( return (
<div id="findings"> <div id='findings'>
<h3> <h3>
Security Findings Security Findings
</h3> </h3>
@ -247,61 +254,114 @@ class ReportPageComponent extends AuthComponent {
}).length > 0 ? }).length > 0 ?
<div> <div>
During this simulated attack the Monkey uncovered <span During this simulated attack the Monkey uncovered <span
className="badge badge-warning"> className='badge badge-warning'>
{this.state.report.overview.issues.filter(function (x) { {this.getThreatCount()}
return x === true; </span>:
}).length} threats</span>:
<ul> <ul>
{this.state.report.overview.issues[this.Issue.STOLEN_SSH_KEYS] ? {this.state.report.overview.issues[this.Issue.STOLEN_SSH_KEYS] &&
<li>Stolen SSH keys are used to exploit other machines.</li> : null} <li>Stolen SSH keys are used to exploit other machines.</li>}
{this.state.report.overview.issues[this.Issue.STOLEN_CREDS] ? {this.state.report.overview.issues[this.Issue.STOLEN_CREDS] &&
<li>Stolen credentials are used to exploit other machines.</li> : null} <li>Stolen credentials are used to exploit other machines.</li>}
{this.state.report.overview.issues[this.Issue.ELASTIC] ? {this.state.report.overview.issues[this.Issue.ELASTIC] &&
<li>Elasticsearch servers are vulnerable to <a <li>Elasticsearch servers are vulnerable to
href="https://www.cvedetails.com/cve/cve-2015-1427">CVE-2015-1427</a>. <Button
</li> : null} variant={'link'}
{this.state.report.overview.issues[this.Issue.VSFTPD] ? href='https://www.cvedetails.com/cve/cve-2015-1427'
<li>VSFTPD is vulnerable to <a target={'_blank'}
href="https://www.rapid7.com/db/modules/exploit/unix/ftp/vsftpd_234_backdoor">CVE-2011-2523</a>. className={'security-report-link'}>
</li> : null} CVE-2015-1427
{this.state.report.overview.issues[this.Issue.SAMBACRY] ? </Button>.
<li>Samba servers are vulnerable to SambaCry (<a </li>}
href="https://www.samba.org/samba/security/CVE-2017-7494.html" {this.state.report.overview.issues[this.Issue.VSFTPD] &&
>CVE-2017-7494</a>).</li> : null} <li>VSFTPD is vulnerable to
{this.state.report.overview.issues[this.Issue.SHELLSHOCK] ? <Button
<li>Machines are vulnerable to Shellshock (<a variant={'link'}
href="https://www.cvedetails.com/cve/CVE-2014-6271">CVE-2014-6271</a>). href='https://www.rapid7.com/db/modules/exploit/unix/ftp/vsftpd_234_backdoor'
</li> : null} target={'_blank'}
{this.state.report.overview.issues[this.Issue.CONFICKER] ? className={'security-report-link'}>
<li>Machines are vulnerable to Conficker (<a CVE-2011-2523
href="https://docs.microsoft.com/en-us/security-updates/SecurityBulletins/2008/ms08-067" </Button>.
>MS08-067</a>).</li> : null} </li>}
{this.state.report.overview.issues[this.Issue.WEAK_PASSWORD] ? {this.state.report.overview.issues[this.Issue.SAMBACRY] &&
<li>Machines are accessible using passwords supplied by the user during the Monkeys <li>Samba servers are vulnerable to SambaCry (
configuration.</li> : null} <Button
{this.state.report.overview.issues[this.Issue.AZURE] ? variant={'link'}
<li>Azure machines expose plaintext passwords. (<a href='https://www.samba.org/samba/security/CVE-2017-7494.html'
href="https://www.guardicore.com/2018/03/recovering-plaintext-passwords-azure/" target={'_blank'}
>More info</a>)</li> : null} className={'security-report-link'}>
{this.state.report.overview.issues[this.Issue.STRUTS2] ? CVE-2017-7494
<li>Struts2 servers are vulnerable to remote code execution. (<a </Button>).
href="https://cwiki.apache.org/confluence/display/WW/S2-045"> </li>}
CVE-2017-5638</a>)</li> : null} {this.state.report.overview.issues[this.Issue.SHELLSHOCK] &&
{this.state.report.overview.issues[this.Issue.WEBLOGIC] ? <li>Machines are vulnerable to Shellshock (
<li>Oracle WebLogic servers are susceptible to a remote code execution vulnerability.</li> : null} <Button
{this.state.report.overview.issues[this.Issue.HADOOP] ? variant={'link'}
<li>Hadoop/Yarn servers are vulnerable to remote code execution.</li> : null} href='https://www.cvedetails.com/cve/CVE-2014-6271'
{this.state.report.overview.issues[this.Issue.PTH_CRIT_SERVICES_ACCESS] ? target={'_blank'}
<li>Mimikatz found login credentials of a user who has admin access to a server defined as className={'security-report-link'}>
critical.</li> : null} CVE-2014-6271
{this.state.report.overview.issues[this.Issue.MSSQL] ? </Button>).
<li>MS-SQL servers are vulnerable to remote code execution via xp_cmdshell command.</li> : null} </li>}
{this.state.report.overview.issues[this.Issue.CONFICKER] &&
<li>Machines are vulnerable to Conficker (
<Button
variant={'link'}
href='https://docs.microsoft.com/en-us/security-updates/SecurityBulletins/2008/ms08-067'
target={'_blank'}
className={'security-report-link'}>
MS08-067
</Button>).
</li>}
{this.state.report.overview.issues[this.Issue.WEAK_PASSWORD] &&
<li>Machines are accessible using passwords supplied by the user during the Monkeys
configuration.</li>}
{this.state.report.overview.issues[this.Issue.AZURE] &&
<li>Azure machines expose plaintext passwords (
<Button
variant={'link'}
href='https://www.guardicore.com/2018/03/recovering-plaintext-passwords-azure/'
target={'_blank'}
className={'security-report-link'}>
more info
</Button>).
</li>}
{this.state.report.overview.issues[this.Issue.STRUTS2] &&
<li>Struts2 servers are vulnerable to remote code execution (
<Button
variant={'link'}
href='https://cwiki.apache.org/confluence/display/WW/S2-045'
target={'_blank'}
className={'security-report-link'}>
CVE-2017-5638
</Button>).
</li>}
{this.state.report.overview.issues[this.Issue.WEBLOGIC] &&
<li>Oracle WebLogic servers are susceptible to a remote code execution vulnerability.</li>}
{this.state.report.overview.issues[this.Issue.HADOOP] &&
<li>Hadoop/Yarn servers are vulnerable to remote code execution.</li>}
{this.state.report.overview.issues[this.Issue.PTH_CRIT_SERVICES_ACCESS] &&
<li>Mimikatz found login credentials of a user who has admin access to a server defined as
critical.</li>}
{this.state.report.overview.issues[this.Issue.MSSQL] &&
<li>MS-SQL servers are vulnerable to remote code execution via xp_cmdshell command.</li>}
{this.state.report.overview.issues[this.Issue.DRUPAL] &&
<li>Drupal servers are susceptible to a remote code execution vulnerability
(<Button
variant={'link'}
href='https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-6340'
target={'_blank'}
className={'security-report-link'}>
CVE-2019-6340
</Button>).
</li>
}
{this.generateZerologonOverview()}
</ul> </ul>
</div> </div>
: :
<div> <div>
During this simulated attack the Monkey uncovered <span During this simulated attack the Monkey uncovered <span
className="badge badge-success">0 threats</span>. className='badge badge-success'>0 threats</span>.
</div> </div>
} }
</div> </div>
@ -317,12 +377,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 key={this.Warning.CROSS_SEGMENT}>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 key={this.Warning.TUNNEL}>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 key={this.Warning.SHARED_LOCAL_ADMIN}>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 key={this.Warning.SHARED_PASSWORDS}>Multiple users have the same password</li> : null} <li key={this.Warning.SHARED_PASSWORDS}>Multiple users have the same password</li> : null}
@ -353,9 +416,58 @@ class ReportPageComponent extends AuthComponent {
); );
} }
getThreatCount() {
let threatCount = this.state.report.overview.issues.filter(function (x) {
return x === true;
}).length
this.NotThreats.forEach(x => {
if (this.state.report.overview.issues[x] === true) {
threatCount -= 1;
}
});
if (threatCount === 1)
return "1 threat"
else
return threatCount + " threats"
}
generateZerologonOverview() {
let zerologonOverview = [];
if (this.state.report.overview.issues[this.Issue.ZEROLOGON]) {
zerologonOverview.push(<>
Some Windows domain controllers are vulnerable to 'Zerologon' (
<Button variant={'link'}
href='https://msrc.microsoft.com/update-guide/en-US/vulnerability/CVE-2020-1472'
target={'_blank'}
className={'security-report-link'}>
CVE-2020-1472
</Button>).
</>)
}
if (this.state.report.overview.issues[this.Issue.ZEROLOGON_PASSWORD_RESTORE_FAILED]) {
zerologonOverview.push(
<span className={'zero-logon-overview-pass-restore-failed'}><br/>
<WarningIcon/>
Automatic password restoration on a domain controller failed!
<Button variant={'link'}
href={'https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/zerologon/'}
target={'_blank'}
className={'security-report-link'}>
Restore your domain controller's password manually.
</Button>
</span>)
}
else {
return null;
}
return (<li>{zerologonOverview}</li>)
}
generateReportRecommendationsSection() { generateReportRecommendationsSection() {
return ( return (
<div id="recommendations"> <div id='recommendations'>
{/* Checks if there are any domain issues. If there are more then one: render the title. Otherwise, {/* Checks if there are any domain issues. If there are more then one: render the title. Otherwise,
* don't render it (since the issues themselves will be empty. */} * don't render it (since the issues themselves will be empty. */}
{Object.keys(this.state.report.recommendations.domain_issues).length !== 0 ? {Object.keys(this.state.report.recommendations.domain_issues).length !== 0 ?
@ -378,36 +490,36 @@ class ReportPageComponent extends AuthComponent {
let exploitPercentage = let exploitPercentage =
(100 * this.state.report.glance.exploited.length) / this.state.report.glance.scanned.length; (100 * this.state.report.glance.exploited.length) / this.state.report.glance.scanned.length;
return ( return (
<div id="glance"> <div id='glance'>
<h3> <h3>
The Network from the Monkey's Eyes The Network from the Monkey's Eyes
</h3> </h3>
<div> <div>
<p> <p>
The Monkey discovered <span The Monkey discovered <span
className="badge badge-warning">{this.state.report.glance.scanned.length}</span> machines and className='badge badge-warning'>{this.state.report.glance.scanned.length}</span> machines and
successfully breached <span successfully breached <span
className="badge badge-danger">{this.state.report.glance.exploited.length}</span> of them. className='badge badge-danger'>{this.state.report.glance.exploited.length}</span> of them.
</p> </p>
<div className="text-center" style={{margin: '10px'}}> <div className='text-center' style={{margin: '10px'}}>
<Line style={{width: '300px', marginRight: '5px'}} percent={exploitPercentage} strokeWidth="4" <Line style={{width: '300px', marginRight: '5px'}} percent={exploitPercentage} strokeWidth='4'
trailWidth="4" trailWidth='4'
strokeColor="#d9534f" trailColor="#f0ad4e"/> strokeColor='#d9534f' trailColor='#f0ad4e'/>
<b>{Math.round(exploitPercentage)}% of scanned machines exploited</b> <b>{Math.round(exploitPercentage)}% of scanned machines exploited</b>
</div> </div>
</div> </div>
<p> <p>
From the attacker's point of view, the network looks like this: From the attacker's point of view, the network looks like this:
</p> </p>
<div className="map-legend"> <div className='map-legend'>
<b>Legend: </b> <b>Legend: </b>
<span>Exploit <FontAwesomeIcon icon={faMinus} size="lg" style={{color: '#cc0200'}}/></span> <span>Exploit <FontAwesomeIcon icon={faMinus} size='lg' style={{color: '#cc0200'}}/></span>
<b style={{color: '#aeaeae'}}> | </b> <b style={{color: '#aeaeae'}}> | </b>
<span>Scan <FontAwesomeIcon icon={faMinus} size="lg" style={{color: '#ff9900'}}/></span> <span>Scan <FontAwesomeIcon icon={faMinus} size='lg' style={{color: '#ff9900'}}/></span>
<b style={{color: '#aeaeae'}}> | </b> <b style={{color: '#aeaeae'}}> | </b>
<span>Tunnel <FontAwesomeIcon icon={faMinus} size="lg" style={{color: '#0158aa'}}/></span> <span>Tunnel <FontAwesomeIcon icon={faMinus} size='lg' style={{color: '#0158aa'}}/></span>
<b style={{color: '#aeaeae'}}> | </b> <b style={{color: '#aeaeae'}}> | </b>
<span>Island Communication <FontAwesomeIcon icon={faMinus} size="lg" style={{color: '#a9aaa9'}}/></span> <span>Island Communication <FontAwesomeIcon icon={faMinus} size='lg' style={{color: '#a9aaa9'}}/></span>
</div> </div>
<div style={{position: 'relative', height: '80vh'}}> <div style={{position: 'relative', height: '80vh'}}>
<ReactiveGraph graph={this.state.graph} options={getOptions(this.state.nodeStateList)}/> <ReactiveGraph graph={this.state.graph} options={getOptions(this.state.nodeStateList)}/>
@ -437,17 +549,18 @@ class ReportPageComponent extends AuthComponent {
generateReportFooter() { generateReportFooter() {
return ( return (
<div id="footer" className="text-center" style={{marginTop: '20px'}}> <div id='footer' className='text-center' style={{marginTop: '20px'}}>
For questions, suggestions or any other feedback For questions, suggestions or any other feedback
contact: <a href="mailto://labs@guardicore.com" className="no-print">labs@guardicore.com</a> contact: <a href='mailto://labs@guardicore.com' className='no-print'>labs@guardicore.com</a>
<div className="force-print" style={{display: 'none'}}>labs@guardicore.com</div> <div className='force-print' style={{display: 'none'}}>labs@guardicore.com</div>
<img src={guardicoreLogoImage} alt="GuardiCore" className="center-block" style={{height: '50px'}}/> <img src={guardicoreLogoImage} alt='GuardiCore' className='center-block' style={{height: '50px'}}/>
</div> </div>
); );
} }
generateInfoBadges(data_array) { generateInfoBadges(data_array) {
return data_array.map(badge_data => <span key={badge_data} 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) {
@ -512,21 +625,21 @@ class ReportPageComponent extends AuthComponent {
} }
generateShellshockPathListBadges(paths) { generateShellshockPathListBadges(paths) {
return paths.map(path => <span className="badge badge-warning" style={{margin: '2px'}} key={path}>{path}</span>); return paths.map(path => <span className='badge badge-warning' style={{margin: '2px'}} key={path}>{path}</span>);
} }
generateSmbPasswordIssue(issue) { generateSmbPasswordIssue(issue) {
return ( return (
<> <>
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>
The machine <span className="badge badge-primary">{issue.machine}</span> (<span The machine <span className='badge badge-primary'>{issue.machine}</span> (<span
className="badge badge-info" style={{margin: '2px'}}>{issue.ip_address}</span>) is vulnerable to a <span className='badge badge-info' style={{margin: '2px'}}>{issue.ip_address}</span>) is vulnerable to a <span
className="badge badge-danger">SMB</span> attack. className='badge badge-danger'>SMB</span> attack.
<br/> <br/>
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>
</> </>
); );
@ -535,15 +648,15 @@ class ReportPageComponent extends AuthComponent {
generateSmbPthIssue(issue) { generateSmbPthIssue(issue) {
return ( return (
<> <>
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>
The machine <span className="badge badge-primary">{issue.machine}</span> (<span The machine <span className='badge badge-primary'>{issue.machine}</span> (<span
className="badge badge-info" style={{margin: '2px'}}>{issue.ip_address}</span>) is vulnerable to a <span className='badge badge-info' style={{margin: '2px'}}>{issue.ip_address}</span>) is vulnerable to a <span
className="badge badge-danger">SMB</span> attack. className='badge badge-danger'>SMB</span> attack.
<br/> <br/>
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>
</> </>
); );
@ -552,15 +665,15 @@ class ReportPageComponent extends AuthComponent {
generateWmiPasswordIssue(issue) { generateWmiPasswordIssue(issue) {
return ( return (
<> <>
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>
The machine <span className="badge badge-primary">{issue.machine}</span> (<span The machine <span className='badge badge-primary'>{issue.machine}</span> (<span
className="badge badge-info" style={{margin: '2px'}}>{issue.ip_address}</span>) is vulnerable to a <span className='badge badge-info' style={{margin: '2px'}}>{issue.ip_address}</span>) is vulnerable to a <span
className="badge badge-danger">WMI</span> attack. className='badge badge-danger'>WMI</span> attack.
<br/> <br/>
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>
</> </>
); );
@ -569,15 +682,15 @@ class ReportPageComponent extends AuthComponent {
generateWmiPthIssue(issue) { generateWmiPthIssue(issue) {
return ( return (
<> <>
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>
The machine <span className="badge badge-primary">{issue.machine}</span> (<span The machine <span className='badge badge-primary'>{issue.machine}</span> (<span
className="badge badge-info" style={{margin: '2px'}}>{issue.ip_address}</span>) is vulnerable to a <span className='badge badge-info' style={{margin: '2px'}}>{issue.ip_address}</span>) is vulnerable to a <span
className="badge badge-danger">WMI</span> attack. className='badge badge-danger'>WMI</span> attack.
<br/> <br/>
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>
</> </>
); );
@ -586,15 +699,15 @@ class ReportPageComponent extends AuthComponent {
generateSshIssue(issue) { generateSshIssue(issue) {
return ( return (
<> <>
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>
The machine <span className="badge badge-primary">{issue.machine}</span> (<span The machine <span className='badge badge-primary'>{issue.machine}</span> (<span
className="badge badge-info" style={{margin: '2px'}}>{issue.ip_address}</span>) is vulnerable to a <span className='badge badge-info' style={{margin: '2px'}}>{issue.ip_address}</span>) is vulnerable to a <span
className="badge badge-danger">SSH</span> attack. className='badge badge-danger'>SSH</span> attack.
<br/> <br/>
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>
</> </>
); );
@ -603,14 +716,14 @@ class ReportPageComponent extends AuthComponent {
generateSshKeysIssue(issue) { generateSshKeysIssue(issue) {
return ( return (
<> <>
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
className="badge badge-info" style={{margin: '2px'}}>{issue.ip_address}</span>) is vulnerable to a <span className='badge badge-info' style={{margin: '2px'}}>{issue.ip_address}</span>) is vulnerable to a <span
className="badge badge-danger">SSH</span> attack. className='badge badge-danger'>SSH</span> attack.
<br/> <br/>
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>
</> </>
); );
@ -620,17 +733,17 @@ class ReportPageComponent extends AuthComponent {
generateSambaCryIssue(issue) { generateSambaCryIssue(issue) {
return ( return (
<> <>
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/>
Update your Samba server to 4.4.14 and up, 4.5.10 and up, or 4.6.4 and up. Update your Samba server to 4.4.14 and up, 4.5.10 and up, or 4.6.4 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
className="badge badge-info" style={{margin: '2px'}}>{issue.ip_address}</span>) is vulnerable to a <span className='badge badge-info' style={{margin: '2px'}}>{issue.ip_address}</span>) is vulnerable to a <span
className="badge badge-danger">SambaCry</span> attack. className='badge badge-danger'>SambaCry</span> attack.
<br/> <br/>
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, and used the SambaCry className='badge badge-success'>{issue.username}</span> and its password, and used the SambaCry
vulnerability. vulnerability.
</CollapsibleWellComponent> </CollapsibleWellComponent>
</> </>
@ -642,20 +755,23 @@ class ReportPageComponent extends AuthComponent {
<> <>
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
className="badge badge-info" style={{margin: '2px'}}>{issue.ip_address}</span>) has a backdoor running at port <span className='badge badge-info' style={{margin: '2px'}}>{issue.ip_address}</span>) has a backdoor running at
className="badge badge-danger">6200</span>. port <span
className='badge badge-danger'>6200</span>.
<br/> <br/>
The attack was made possible because the VSFTPD server was not patched against CVE-2011-2523. The attack was made possible because the VSFTPD server was not patched against CVE-2011-2523.
<br/><br/>In July 2011, it was discovered that vsftpd version 2.3.4 downloadable from the master site had been <br/><br/>In July 2011, it was discovered that vsftpd version 2.3.4 downloadable from the master site had been
compromised. compromised.
Users logging into a compromised vsftpd-2.3.4 server may issue a ":)" smileyface as the username and gain a command Users logging into a compromised vsftpd-2.3.4 server may issue a ":)" smileyface as the username and gain a
command
shell on port 6200. shell on port 6200.
<br/><br/> <br/><br/>
The Monkey executed commands by first logging in with ":)" in the username and then sending commands to the backdoor The Monkey executed commands by first logging in with ":)" in the username and then sending commands to the
backdoor
at port 6200. at port 6200.
<br/><br/>Read more about the security issue and remediation <a <br/><br/>Read more about the security issue and remediation <a
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>
</> </>
@ -667,9 +783,9 @@ class ReportPageComponent extends AuthComponent {
<> <>
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
className="badge badge-info" style={{margin: '2px'}}>{issue.ip_address}</span>) is vulnerable to an <span className='badge badge-info' style={{margin: '2px'}}>{issue.ip_address}</span>) is vulnerable to an <span
className="badge badge-danger">Elastic Groovy</span> attack. className='badge badge-danger'>Elastic Groovy</span> attack.
<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>
@ -682,12 +798,12 @@ class ReportPageComponent extends AuthComponent {
<> <>
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
className="badge badge-info" style={{margin: '2px'}}>{issue.ip_address}</span>) is vulnerable to a <span className='badge badge-info' style={{margin: '2px'}}>{issue.ip_address}</span>) is vulnerable to a <span
className="badge badge-danger">ShellShock</span> attack. className='badge badge-danger'>ShellShock</span> attack.
<br/> <br/>
The attack was made possible because the HTTP server running on TCP port <span The attack was made possible because the HTTP server running on TCP port <span
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>
</> </>
@ -700,9 +816,9 @@ class ReportPageComponent extends AuthComponent {
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
className="badge badge-primary">{issue.machine}</span> for the following users <span className='badge badge-primary'>{issue.machine}</span> for the following users <span
className="badge badge-primary">{issue.users}</span>. Read more about the security issue and remediation <a className='badge badge-primary'>{issue.users}</span>. Read more about the security issue and remediation <a
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>
</> </>
@ -714,9 +830,9 @@ class ReportPageComponent extends AuthComponent {
<> <>
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
className="badge badge-info" style={{margin: '2px'}}>{issue.ip_address}</span>) is vulnerable to a <span className='badge badge-info' style={{margin: '2px'}}>{issue.ip_address}</span>) is vulnerable to a <span
className="badge badge-danger">Conficker</span> attack. className='badge badge-danger'>Conficker</span> attack.
<br/> <br/>
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.
@ -731,7 +847,7 @@ class ReportPageComponent extends AuthComponent {
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
className="badge badge-primary">{issue.machine}</span> in the className='badge badge-primary'>{issue.machine}</span> in the
networks {this.generateInfoBadges(issue.networks)} networks {this.generateInfoBadges(issue.networks)}
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)}.
@ -767,11 +883,12 @@ class ReportPageComponent extends AuthComponent {
generateSharedLocalAdminsIssue(issue) { generateSharedLocalAdminsIssue(issue) {
return ( return (
<> <>
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>
Here is a list of machines which the account <span Here is a list of machines which the account <span
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>
</> </>
@ -798,8 +915,8 @@ class ReportPageComponent extends AuthComponent {
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>
</> </>
); );
@ -810,13 +927,13 @@ class ReportPageComponent extends AuthComponent {
<> <>
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
className="badge badge-info" style={{margin: '2px'}}>{issue.ip_address}</span>) is vulnerable to <span className='badge badge-info' style={{margin: '2px'}}>{issue.ip_address}</span>) is vulnerable to <span
className="badge badge-danger">remote code execution</span> attack. className='badge badge-danger'>remote code execution</span> attack.
<br/> <br/>
The attack was made possible because the server is using an old version of Jakarta based file upload The attack was made possible because the server is using an old version of Jakarta based file upload
Multipart parser. For possible work-arounds and more info read <a Multipart parser. For possible work-arounds and more info read <a
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>
</> </>
@ -828,13 +945,13 @@ class ReportPageComponent extends AuthComponent {
<> <>
Upgrade Drupal server to versions 8.5.11, 8.6.10, or later. Upgrade Drupal server to versions 8.5.11, 8.6.10, or later.
<CollapsibleWellComponent> <CollapsibleWellComponent>
Drupal server at <span className="badge badge-primary">{issue.machine}</span> (<span 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-info' style={{margin: '2px'}}>{issue.ip_address}</span>) is vulnerable to <span
className="badge badge-danger">remote command execution</span> attack. className='badge badge-danger'>remote command execution</span> attack.
<br/> <br/>
The attack was made possible because the server is using an old version of Drupal, for which REST API is The attack was made possible because the server is using an old version of Drupal, for which REST API is
enabled. For possible workarounds, fixes and more info read enabled. For possible workarounds, fixes and more info read
<a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-6340">here</a>. <a href='https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-6340'>here</a>.
</CollapsibleWellComponent> </CollapsibleWellComponent>
</> </>
); );
@ -845,9 +962,9 @@ class ReportPageComponent extends AuthComponent {
<> <>
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
className="badge badge-info" style={{margin: '2px'}}>{issue.ip_address}</span>) is vulnerable to one of <span className='badge badge-info' style={{margin: '2px'}}>{issue.ip_address}</span>) is vulnerable to one of <span
className="badge badge-danger">remote code execution</span> attacks. className='badge badge-danger'>remote code execution</span> attacks.
<br/> <br/>
The attack was made possible due to one of the following vulnerabilities: The attack was made possible due to one of the following vulnerabilities:
<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
@ -861,12 +978,12 @@ class ReportPageComponent extends AuthComponent {
return ( return (
<> <>
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>).
<CollapsibleWellComponent> <CollapsibleWellComponent>
The Hadoop server at <span className="badge badge-primary">{issue.machine}</span> (<span The Hadoop 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-info' style={{margin: '2px'}}>{issue.ip_address}</span>) is vulnerable to <span
className="badge badge-danger">remote code execution</span> attack. className='badge badge-danger'>remote code execution</span> attack.
<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>
@ -879,14 +996,58 @@ class ReportPageComponent extends AuthComponent {
<> <>
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
className="badge badge-info" style={{margin: '2px'}}>{issue.ip_address}</span>) is vulnerable to a <span className='badge badge-info' style={{margin: '2px'}}>{issue.ip_address}</span>) is vulnerable to a <span
className="badge badge-danger">MSSQL exploit attack</span>. className='badge badge-danger'>MSSQL exploit attack</span>.
<br/> <br/>
The attack was made possible because the target machine used an outdated MSSQL server configuration allowing The attack was made possible because the target machine used an outdated MSSQL server configuration allowing
the usage of the xp_cmdshell command. To learn more about how to disable this feature, read <a the usage of the xp_cmdshell command. To learn more about how to disable this feature, read
href="https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/xp-cmdshell-server-configuration-option?view=sql-server-2017"> <Button
Microsoft's documentation. </a> variant={'link'}
href='https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/xp-cmdshell-server-configuration-option?view=sql-server-2017'
target={'_blank'}
className={'security-report-link'}>
Microsoft's documentation
</Button>.
</CollapsibleWellComponent>
</>
);
}
generateZerologonIssue(issue) {
return (
<>
Install Windows security updates.
<CollapsibleWellComponent>
The machine <span className='badge badge-primary'>{issue.machine}</span> (<span
className='badge badge-info' style={{margin: '2px'}}>{issue.ip_address}</span>) is vulnerable to a <span
className='badge badge-danger'>Zerologon exploit</span>.
<br/>
The attack was possible because the latest security updates from Microsoft
have not been applied to this machine. For more information about this
vulnerability, read
<Button
variant={'link'}
href='https://msrc.microsoft.com/update-guide/en-US/vulnerability/CVE-2020-1472'
target={'_blank'}
className={'security-report-link'}>
Microsoft's documentation
</Button>.
{!issue.password_restored &&
<div className={'info-pane-warning'} key={'warning'}>
<br/><WarningIcon/>
<span>
The domain controller's password was changed during the exploit and could not be restored successfully.
Instructions on how to manually reset the domain controller's password can be found
<Button
variant={'link'}
href='https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/zerologon/'
target={'_blank'}
className={'security-report-link'}>
here
</Button>.
</span>
</div>}
</CollapsibleWellComponent> </CollapsibleWellComponent>
</> </>
); );
@ -964,6 +1125,9 @@ class ReportPageComponent extends AuthComponent {
case 'drupal': case 'drupal':
issueData = this.generateDrupalIssue(issue); issueData = this.generateDrupalIssue(issue);
break; break;
case 'zerologon':
issueData = this.generateZerologonIssue(issue);
break;
} }
return <li key={JSON.stringify(issue)}>{issueData}</li>; return <li key={JSON.stringify(issue)}>{issueData}</li>;
}; };

View File

@ -7,15 +7,15 @@
font-size: large; font-size: large;
} }
.report-nav > li > a{ .report-nav > li > a {
height: 50px !important; height: 50px !important;
} }
.report-nav .nav-item > a{ .report-nav .nav-item > a {
color: $black; color: $black;
} }
.report-nav .nav-item > a.active{ .report-nav .nav-item > a.active {
font-weight: bold; font-weight: bold;
color: $black; color: $black;
} }
@ -72,16 +72,29 @@ div.report-wrapper {
padding-bottom: 20px; padding-bottom: 20px;
} }
div.report-wrapper .nav-tabs > .nav-item > a:hover:not(.active), .nav-tabs > .nav-item > a:focus:not(.active){ div.report-wrapper .nav-tabs > .nav-item > a:hover:not(.active), .nav-tabs > .nav-item > a:focus:not(.active) {
text-decoration: none; text-decoration: none;
background-color: $light-gray; background-color: $light-gray;
} }
ul.cross-segment-issues { ul.cross-segment-issues {
list-style-type: none; list-style-type: none;
padding: 0px; padding: 0px;
margin: 0px; margin: 0px;
} }
span.cross-segment-service { span.cross-segment-service {
text-transform: uppercase; text-transform: uppercase;
}
.report-page li a.btn,.security-report-link {
position: relative;
font-size: 1em;
padding: 0 5px;
line-height: 1em;
top: -3px;
}
.zero-logon-overview-pass-restore-failed svg {
margin: 0 10px 0 0;
} }