From 8ccdba7528fbdd8ff9a304c6ff35e6a2d1590ef4 Mon Sep 17 00:00:00 2001 From: Ilija Lazoroski Date: Thu, 14 Jul 2022 16:50:04 +0200 Subject: [PATCH] UI: Grab credentials from endpoint and render them --- .../report-components/SecurityReport.js | 108 ++++++++++++------ 1 file changed, 76 insertions(+), 32 deletions(-) diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/SecurityReport.js b/monkey/monkey_island/cc/ui/src/components/report-components/SecurityReport.js index d91d2d0fc..04b05f04f 100644 --- a/monkey/monkey_island/cc/ui/src/components/report-components/SecurityReport.js +++ b/monkey/monkey_island/cc/ui/src/components/report-components/SecurityReport.js @@ -45,6 +45,8 @@ import { zerologonOverviewWithFailedPassResetWarning } from './security/issues/ZerologonIssue'; import {powershellIssueOverview, powershellIssueReport} from './security/issues/PowershellIssue'; +import {getCredentialsSecrets, getCredentialsUsernames} from './credentialParsing'; +import UsedCredentials from './security/UsedCredentials.tsx'; class ReportPageComponent extends AuthComponent { @@ -161,15 +163,31 @@ class ReportPageComponent extends AuthComponent { this.state = { report: props.report, graph: {nodes: [], edges: []}, - nodeStateList: [] + nodeStateList: [], + stolenCredentials: [], + configuredCredentials: [] }; } componentDidMount() { this.getNodeStateListFromServer(); + this.getCredentialsFromServer(); this.updateMapFromServer(); } + getCredentialsFromServer = () => { + this.authFetch('/api/propagation-credentials/stolen-credentials') + .then(res => res.json()) + .then(creds => { + this.setState({stolenCredentials: creds}); + }) + this.authFetch('/api/propagation-credentials/configured-credentials') + .then(res => res.json()) + .then(creds => { + this.setState({configuredCredentials: creds}); + }) + } + getNodeStateListFromServer = () => { this.authFetch('/api/netmap/node-states') .then(res => res.json()) @@ -184,10 +202,19 @@ class ReportPageComponent extends AuthComponent { componentDidUpdate(prevProps) { if (this.props.report !== prevProps.report) { - this.setState({report: this.props.report}) + this.updateReport(this.props.report); } } + updateReport(report) { + let newReport = this.addIssuesToOverviewIssues(report); + + this.setState({ + report: newReport + }) + } + + render() { let content; @@ -273,39 +300,20 @@ class ReportPageComponent extends AuthComponent {

The monkeys were run with the following configuration:

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

- Usernames used for brute-forcing: -

- -

- Passwords used for brute-forcing: -

- - - : -

- Brute forcing uses stolen credentials only. No credentials were supplied during Monkey’s - configuration. -

- } + { this.state.report.overview.config_exploits.length > 0 ? -

- The Monkey uses the following exploit methods: -

-

+ ( +

+ The Monkey attempted the following exploitation methods: +

+

+ ) :

- No exploits are used by the Monkey. + No exploiters were enabled.

} { @@ -535,7 +543,7 @@ class ReportPageComponent extends AuthComponent {
- +
@@ -582,6 +590,42 @@ class ReportPageComponent extends AuthComponent { } return
    {issuesDivArray}
; }; + + addIssuesToOverviewIssues(report) { + let issues = report.overview.issues; + let overview_issues = []; + + for(let i=0; i < issues.length; i++) { + if (this.isWeakCredentialsIssue(issues[i])) { + overview_issues.push('weak_password') + } else if (this.isStolenCredentialsIssue(issues[i])) { + overview_issues.push('stolen_creds'); + } else { + overview_issues.push(issues[i]) + } + } + + const newOverview = { ...report.overview, issues : overview_issues }; + + const newReport = { ...report, overview : newOverview }; + + + return newReport; + } + + isWeakCredentialsIssue(issue) { + return (Object.prototype.hasOwnProperty.call(issue, 'credential_type') && + issue.credential_type === 'PASSWORD' && + getCredentialsSecrets(this.state.configuredCredentials, 'password').includes(issue.password) && + getCredentialsUsernames(this.state.configuredCredentials).includes(issue.username)) + } + + isStolenCredentialsIssue(issue) { + return ( Object.prototype.hasOwnProperty.call(issue, 'credential_type') && + (issue.credential_type === 'PASSWORD' || + issue.credential_type === 'NT_HASH' || + issue.credential_type === 'LM_HASH')) + } } export default ReportPageComponent;