UI: Grab credentials from endpoint and render them

This commit is contained in:
Ilija Lazoroski 2022-07-14 16:50:04 +02:00
parent f99bd74cd4
commit 8ccdba7528
1 changed files with 76 additions and 32 deletions

View File

@ -45,6 +45,8 @@ import {
zerologonOverviewWithFailedPassResetWarning zerologonOverviewWithFailedPassResetWarning
} from './security/issues/ZerologonIssue'; } from './security/issues/ZerologonIssue';
import {powershellIssueOverview, powershellIssueReport} from './security/issues/PowershellIssue'; import {powershellIssueOverview, powershellIssueReport} from './security/issues/PowershellIssue';
import {getCredentialsSecrets, getCredentialsUsernames} from './credentialParsing';
import UsedCredentials from './security/UsedCredentials.tsx';
class ReportPageComponent extends AuthComponent { class ReportPageComponent extends AuthComponent {
@ -161,15 +163,31 @@ class ReportPageComponent extends AuthComponent {
this.state = { this.state = {
report: props.report, report: props.report,
graph: {nodes: [], edges: []}, graph: {nodes: [], edges: []},
nodeStateList: [] nodeStateList: [],
stolenCredentials: [],
configuredCredentials: []
}; };
} }
componentDidMount() { componentDidMount() {
this.getNodeStateListFromServer(); this.getNodeStateListFromServer();
this.getCredentialsFromServer();
this.updateMapFromServer(); 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 = () => { getNodeStateListFromServer = () => {
this.authFetch('/api/netmap/node-states') this.authFetch('/api/netmap/node-states')
.then(res => res.json()) .then(res => res.json())
@ -184,10 +202,19 @@ 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.updateReport(this.props.report);
} }
} }
updateReport(report) {
let newReport = this.addIssuesToOverviewIssues(report);
this.setState({
report: newReport
})
}
render() { render() {
let content; let content;
@ -273,39 +300,20 @@ class ReportPageComponent extends AuthComponent {
<p> <p>
The monkeys were run with the following configuration: The monkeys were run with the following configuration:
</p> </p>
{ <UsedCredentials stolen={this.state.stolenCredentials} configured={this.state.configuredCredentials}/>
this.state.report.overview.config_users.length > 0 ?
<>
<p>
Usernames used for brute-forcing:
</p>
<ul>
{this.state.report.overview.config_users.map(x => <li key={x}>{x}</li>)}
</ul>
<p>
Passwords used for brute-forcing:
</p>
<ul>
{this.state.report.overview.config_passwords.map(x => <li key={x}>{x.substr(0, 3) + '******'}</li>)}
</ul>
</>
:
<p>
Brute forcing uses stolen credentials only. No credentials were supplied during Monkeys
configuration.
</p>
}
{ {
this.state.report.overview.config_exploits.length > 0 ? this.state.report.overview.config_exploits.length > 0 ?
<p> (
The Monkey uses the following exploit methods: <p>
<ul> The Monkey attempted the following exploitation methods:
{this.state.report.overview.config_exploits.map(x => <li key={x}>{x}</li>)} <ul>
</ul> {this.state.report.overview.config_exploits.map(x => <li key={x}>{x}</li>)}
</p> </ul>
</p>
)
: :
<p> <p>
No exploits are used by the Monkey. No exploiters were enabled.
</p> </p>
} }
{ {
@ -535,7 +543,7 @@ class ReportPageComponent extends AuthComponent {
</div> </div>
<div style={{marginBottom: '20px'}}> <div style={{marginBottom: '20px'}}>
<StolenPasswords data={this.state.report.glance.stolen_creds}/> <StolenPasswords data={this.state.stolenCredentials}/>
</div> </div>
<div> <div>
<StrongUsers data={this.state.report.glance.strong_users}/> <StrongUsers data={this.state.report.glance.strong_users}/>
@ -582,6 +590,42 @@ class ReportPageComponent extends AuthComponent {
} }
return <ul>{issuesDivArray}</ul>; return <ul>{issuesDivArray}</ul>;
}; };
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; export default ReportPageComponent;