forked from p34709852/monkey
UI: Grab credentials from endpoint and render them
This commit is contained in:
parent
f99bd74cd4
commit
8ccdba7528
|
@ -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 Monkey’s
|
|
||||||
configuration.
|
|
||||||
</p>
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
this.state.report.overview.config_exploits.length > 0 ?
|
this.state.report.overview.config_exploits.length > 0 ?
|
||||||
|
(
|
||||||
<p>
|
<p>
|
||||||
The Monkey uses the following exploit methods:
|
The Monkey attempted the following exploitation methods:
|
||||||
<ul>
|
<ul>
|
||||||
{this.state.report.overview.config_exploits.map(x => <li key={x}>{x}</li>)}
|
{this.state.report.overview.config_exploits.map(x => <li key={x}>{x}</li>)}
|
||||||
</ul>
|
</ul>
|
||||||
</p>
|
</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;
|
||||||
|
|
Loading…
Reference in New Issue