forked from p34709852/monkey
Merge branch 'brute_force_report' into attack_pass_the_hash
This commit is contained in:
commit
ed23fd351d
|
@ -21,7 +21,6 @@ class HostExploiter(object):
|
|||
def __init__(self, host):
|
||||
self._config = infection_monkey.config.WormConfiguration
|
||||
self._exploit_info = {'display_name': self._EXPLOITED_SERVICE,
|
||||
'exploit_type': self.EXPLOIT_TYPE.name,
|
||||
'started': '',
|
||||
'finished': '',
|
||||
'vulnerable_urls': [],
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
from monkey_island.cc.database import mongo
|
||||
from monkey_island.cc.services.attack.technique_reports import AttackTechnique
|
||||
from common.utils.attack_utils import ScanStatus
|
||||
from common.utils.exploit_enum import ExploitType
|
||||
from monkey_island.cc.encryptor import encryptor
|
||||
|
||||
__author__ = "VakarisZ"
|
||||
|
@ -13,48 +12,44 @@ class T1110(AttackTechnique):
|
|||
scanned_msg = "Monkey tried to brute force some services, but failed."
|
||||
used_msg = "Monkey successfully used brute force in the network."
|
||||
|
||||
# Gets data about brute force attempts
|
||||
query = [{'$match': {'telem_type': 'exploit',
|
||||
'data.attempts': {'$not': {'$size': 0}}}},
|
||||
{'$project': {'_id': 0,
|
||||
'machine': '$data.machine',
|
||||
'info': '$data.info',
|
||||
'attempt_cnt': {'$size': '$data.attempts'},
|
||||
'attempts': {'$filter': {'input': '$data.attempts',
|
||||
'as': 'attempt',
|
||||
'cond': {'$eq': ['$$attempt.result', True]}}}}}]
|
||||
|
||||
@staticmethod
|
||||
def get_report_data():
|
||||
data = {'title': T1110.technique_title(T1110.tech_id)}
|
||||
results = mongo.db.telemetry.find({'telem_type': 'exploit',
|
||||
'data.info.exploit_type': ExploitType.BRUTE_FORCE.name,
|
||||
'data.attempts': {'$ne': '[]'}},
|
||||
{'data.machine': 1, 'data.info': 1, 'data.attempts': 1})
|
||||
parsed_results = []
|
||||
attempts = list(mongo.db.telemetry.aggregate(T1110.query))
|
||||
succeeded = False
|
||||
attempted = False
|
||||
|
||||
for result in results:
|
||||
parsed_result, attempt_status = T1110.parse_exploiter_result(result)
|
||||
parsed_results.append(parsed_result)
|
||||
if parsed_result['successful_creds']:
|
||||
for result in attempts:
|
||||
result['successful_creds'] = []
|
||||
for attempt in result['attempts']:
|
||||
succeeded = True
|
||||
elif attempt_status:
|
||||
attempted = True
|
||||
result['successful_creds'].append(T1110.parse_creds(attempt))
|
||||
|
||||
if succeeded:
|
||||
data.update({'message': T1110.used_msg, 'status': ScanStatus.USED.name})
|
||||
elif attempted:
|
||||
data.update({'message': T1110.scanned_msg, 'status': ScanStatus.SCANNED.name})
|
||||
data = {'message': T1110.used_msg, 'status': ScanStatus.USED.name}
|
||||
elif attempts:
|
||||
data = {'message': T1110.scanned_msg, 'status': ScanStatus.SCANNED.name}
|
||||
else:
|
||||
data.update({'message': T1110.unscanned_msg, 'status': ScanStatus.UNSCANNED.name})
|
||||
|
||||
data.update({'services': parsed_results})
|
||||
data = {'message': T1110.unscanned_msg, 'status': ScanStatus.UNSCANNED.name}
|
||||
data.update({'services': attempts, 'title': T1110.technique_title(T1110.tech_id)})
|
||||
return data
|
||||
|
||||
@staticmethod
|
||||
def parse_exploiter_result(result):
|
||||
attempted = False
|
||||
successful_creds = []
|
||||
for attempt in result['data']['attempts']:
|
||||
attempted = True
|
||||
if attempt['result']:
|
||||
successful_creds.append(T1110.parse_creds(attempt))
|
||||
result['data']['successful_creds'] = successful_creds
|
||||
return result['data'], attempted
|
||||
|
||||
@staticmethod
|
||||
def parse_creds(attempt):
|
||||
"""
|
||||
Parses used credentials into a string
|
||||
:param attempt: login attempt from database
|
||||
:return: string with username and used password/hash
|
||||
"""
|
||||
username = attempt['user']
|
||||
if attempt['lm_hash']:
|
||||
return '%s ; LM hash %s ...' % (username, encryptor.dec(attempt['lm_hash'])[0:5])
|
||||
|
@ -67,4 +62,10 @@ class T1110(AttackTechnique):
|
|||
|
||||
@staticmethod
|
||||
def obfuscate_password(password, plain_chars=3):
|
||||
"""
|
||||
Obfuscates password by changing characters to *
|
||||
:param password: Password or string to obfuscate
|
||||
:param plain_chars: How many plain-text characters should be kept at the start of the string
|
||||
:return: Obfuscated string e.g. Pass****
|
||||
"""
|
||||
return password[0:plain_chars] + '*' * (len(password) - plain_chars)
|
||||
|
|
|
@ -38,7 +38,7 @@ class AttackTechnique(object):
|
|||
"""
|
||||
pass
|
||||
|
||||
# noinspection PyMethodParameters
|
||||
@staticmethod
|
||||
@abstractstatic
|
||||
def get_report_data():
|
||||
"""
|
||||
|
|
|
@ -17,11 +17,15 @@ class T1110 extends React.Component {
|
|||
{Header: 'Service', id: 'service', accessor: x => x.info.display_name, style: { 'whiteSpace': 'unset' }, width: 100},
|
||||
{Header: 'Started', id: 'started', accessor: x => x.info.started, style: { 'whiteSpace': 'unset' }},
|
||||
{Header: 'Finished', id: 'finished', accessor: x => x.info.finished, style: { 'whiteSpace': 'unset' }},
|
||||
{Header: 'Attempts', id: 'attempts', accessor: x => x.attempts.length, style: { 'whiteSpace': 'unset' }, width: 160},
|
||||
{Header: 'Successful credentials', id: 'credentials', accessor: x => x.successful_creds, style: { 'whiteSpace': 'unset' }},
|
||||
{Header: 'Attempts', id: 'attempts', accessor: x => x.attempt_cnt, style: { 'whiteSpace': 'unset' }, width: 160},
|
||||
{Header: 'Successful credentials', id: 'credentials', accessor: x => this.renderCreds(x.successful_creds), style: { 'whiteSpace': 'unset' }},
|
||||
]
|
||||
}])};
|
||||
|
||||
static renderCreds(creds) {
|
||||
return <span>{creds.map(cred => <div>{cred}</div>)}</span>
|
||||
};
|
||||
|
||||
static renderMachine(val){
|
||||
return (
|
||||
<span>{val.ip_addr} {(val.domain_name ? " (".concat(val.domain_name, ")") : "")}</span>
|
||||
|
@ -33,12 +37,13 @@ class T1110 extends React.Component {
|
|||
<div>
|
||||
<div>{this.props.data.message}</div>
|
||||
<br/>
|
||||
<ReactTable
|
||||
{(this.props.data.status === 'SCANNED' || this.props.data.status === 'USED') ?
|
||||
<ReactTable
|
||||
columns={T1110.getServiceColumns()}
|
||||
data={this.props.data.services}
|
||||
showPagination={false}
|
||||
defaultPageSize={this.props.data.services.length}
|
||||
/>
|
||||
/> : ""}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue