diff --git a/monkey/infection_monkey/exploit/mssqlexec.py b/monkey/infection_monkey/exploit/mssqlexec.py index 3f8af40fc..c7d29c8c2 100644 --- a/monkey/infection_monkey/exploit/mssqlexec.py +++ b/monkey/infection_monkey/exploit/mssqlexec.py @@ -124,10 +124,12 @@ class MSSQLExploiter(HostExploiter): conn = pymssql.connect(host, user, password, port=port, login_timeout=self.LOGIN_TIMEOUT) LOG.info('Successfully connected to host: {0}, ' 'using user: {1}, password: {2}'.format(host, user, password)) + self.add_vuln_port(MSSQLExploiter.SQL_DEFAULT_TCP_PORT) self.report_login_attempt(True, user, password) cursor = conn.cursor() return cursor except pymssql.OperationalError: + self.report_login_attempt(False, user, password) # Combo didn't work, hopping to the next one pass diff --git a/monkey/monkey_island/cc/resources/telemetry.py b/monkey/monkey_island/cc/resources/telemetry.py index 04a6ddbd1..5d63a96ca 100644 --- a/monkey/monkey_island/cc/resources/telemetry.py +++ b/monkey/monkey_island/cc/resources/telemetry.py @@ -119,6 +119,8 @@ class Telemetry(flask_restful.Resource): def process_exploit_telemetry(telemetry_json): edge = Telemetry.get_edge_by_scan_or_exploit_telemetry(telemetry_json) Telemetry.encrypt_exploit_creds(telemetry_json) + telemetry_json['data']['info']['started'] = dateutil.parser.parse(telemetry_json['data']['info']['started']) + telemetry_json['data']['info']['finished'] = dateutil.parser.parse(telemetry_json['data']['info']['finished']) new_exploit = copy.deepcopy(telemetry_json['data']) diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1110.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1110.py index b28b92e89..6f9bc1041 100644 --- a/monkey/monkey_island/cc/services/attack/technique_reports/T1110.py +++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1110.py @@ -1,6 +1,8 @@ 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" @@ -14,8 +16,55 @@ class T1110(AttackTechnique): @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}) - results = [result['data'] for result in results] - data.update({'services': results}) + 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 = [] + 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']: + succeeded = True + elif attempt_status: + attempted = True + + if succeeded: + data.update({'message': T1110.used_msg, 'status': ScanStatus.USED.name}) + elif attempted: + data.update({'message': T1110.scanned_msg, 'status': ScanStatus.SCANNED.name}) + else: + data.update({'message': T1110.unscanned_msg, 'status': ScanStatus.UNSCANNED.name}) + + data.update({'services': parsed_results}) 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): + username = attempt['user'] + if attempt['lm_hash']: + return '%s ; LM hash %s ...' % (username, encryptor.dec(attempt['lm_hash'])[0:5]) + if attempt['lm_hash']: + return '%s ; NTLM hash %s ...' % (username, encryptor.dec(attempt['ntlm_hash'])[0:20]) + if attempt['ssh_key']: + return '%s ; SSH key %s ...' % (username, encryptor.dec(attempt['ssh_key'])[0:15]) + if attempt['password']: + return '%s : %s' % (username, T1110.obfuscate_password(encryptor.dec(attempt['password']))) + + @staticmethod + def obfuscate_password(password, plain_chars=3): + return password[0:plain_chars] + '*' * (len(password) - plain_chars) diff --git a/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1110.js b/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1110.js index 31a12259c..e78347428 100644 --- a/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1110.js +++ b/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1110.js @@ -13,12 +13,12 @@ class T1110 extends React.Component { return ([{ columns: [ {Header: 'Machine', id: 'machine', accessor: x => this.renderMachine(x.machine), - style: { 'whiteSpace': 'unset' }, width: 200}, + style: { 'whiteSpace': 'unset' }, width: 160}, {Header: 'Service', id: 'service', accessor: x => x.info.display_name, style: { 'whiteSpace': 'unset' }, width: 170}, {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' }}, - {Header: 'Successful credentials', id: 'credentials', accessor: x => this.renderCredentials(x.attempts), style: { 'whiteSpace': 'unset' }}, + {Header: 'Successful credentials', id: 'credentials', accessor: x => x.successful_creds, style: { 'whiteSpace': 'unset' }}, ] }])}; @@ -28,28 +28,11 @@ class T1110 extends React.Component { ) }; - static renderCredentials(creds){ - let content = ''; - creds.forEach((cred) => { - if (cred.result){ - if (cred.ntlm_hash){ - content += {cred.user} ; NTLM hash: {cred.ntlm_hash} - } else if (cred.ssh_key){ - content += {cred.user} ; SSH key: {cred.ssh_key} - } else if (cred.lm_hash){ - content += {cred.user} ; LM hash: {cred.lm_hash} - } else if (cred.password){ - content += {cred.user} : {cred.password} - } - content += {cred.user} : {cred.password} - } - }) - } - render() { return (