Merge branch 'brute_force_report' into attack_pass_the_hash

This commit is contained in:
VakarisZ 2019-06-06 15:26:01 +03:00
commit ed23fd351d
4 changed files with 42 additions and 37 deletions

View File

@ -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': [],

View File

@ -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)

View File

@ -38,7 +38,7 @@ class AttackTechnique(object):
"""
pass
# noinspection PyMethodParameters
@staticmethod
@abstractstatic
def get_report_data():
"""

View File

@ -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>
);
}