From 9c52ad3617ecb544b90333523353fa037523a668 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Wed, 12 Jun 2019 11:59:55 +0300 Subject: [PATCH 1/5] system info technique implementation started --- .../attack/technique_reports/T1082.py | 37 +++++++++++++++++++ monkey/monkey_island/cc/ui/package-lock.json | 5 +-- 2 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 monkey/monkey_island/cc/services/attack/technique_reports/T1082.py diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1082.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1082.py new file mode 100644 index 000000000..76ed2a7af --- /dev/null +++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1082.py @@ -0,0 +1,37 @@ +from monkey_island.cc.services.attack.technique_reports import AttackTechnique +from common.utils.attack_utils import ScanStatus +from monkey_island.cc.database import mongo + +__author__ = "VakarisZ" + + +class T1082(AttackTechnique): + + tech_id = "T1082" + unscanned_msg = "Monkey didn't gather any system info on the network." + scanned_msg = "" + used_msg = "Monkey gathered system info from machines in the network." + + # Gets data about successful PTH logins + query = [{'$match': {'telem_type': 'system_info_collection'}, + {'$project': {'_id': 0, + 'machine': {'hostname': '$data.hostname', 'ips': '$data.network_info.networks'}, + 'info': {'aws': '$data.aws', + 'process_list': '$data.process_list.1' + 'attempt_cnt': {'$size': '$data.attempts'}, + 'attempts': {'$filter': {'input': '$data.attempts', + 'as': 'attempt', + 'cond': {'$eq': ['$$attempt.result', True]}}}}}] + + @staticmethod + def get_report_data(): + data = {'title': T1082.technique_title(T1082.tech_id)} + successful_logins = list(mongo.db.telemetry.aggregate(T1082.query)) + data.update({'successful_logins': successful_logins}) + if successful_logins: + data.update({'message': T1082.used_msg, 'status': ScanStatus.USED.name}) + elif mongo.db.telemetry.count_documents(T1082.login_attempt_query): + data.update({'message': T1082.scanned_msg, 'status': ScanStatus.SCANNED.name}) + else: + data.update({'message': T1082.unscanned_msg, 'status': ScanStatus.UNSCANNED.name}) + return data diff --git a/monkey/monkey_island/cc/ui/package-lock.json b/monkey/monkey_island/cc/ui/package-lock.json index 296a34897..81c77609f 100644 --- a/monkey/monkey_island/cc/ui/package-lock.json +++ b/monkey/monkey_island/cc/ui/package-lock.json @@ -8563,7 +8563,7 @@ "dev": true, "optional": true, "requires": { - "minimatch": "^3.0.4" + "minimatch": "3.0.4" } }, "inflight": { @@ -8614,8 +8614,7 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "minipass": { "version": "2.2.4", From c28420944e8d4bd2f7981be8c6ca232fd9e6f66e Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Thu, 13 Jun 2019 17:19:04 +0300 Subject: [PATCH 2/5] System info technique implemented --- .../cc/services/attack/attack_report.py | 5 +- .../cc/services/attack/attack_schema.py | 15 +++++ .../attack/technique_reports/T1082.py | 37 ++++++++----- .../cc/services/config_schema.py | 1 + .../src/components/attack/techniques/T1082.js | 55 +++++++++++++++++++ .../report-components/AttackReport.js | 4 +- 6 files changed, 100 insertions(+), 17 deletions(-) create mode 100644 monkey/monkey_island/cc/ui/src/components/attack/techniques/T1082.js diff --git a/monkey/monkey_island/cc/services/attack/attack_report.py b/monkey/monkey_island/cc/services/attack/attack_report.py index 9a5e57633..9a40e1728 100644 --- a/monkey/monkey_island/cc/services/attack/attack_report.py +++ b/monkey/monkey_island/cc/services/attack/attack_report.py @@ -1,5 +1,5 @@ import logging -from monkey_island.cc.services.attack.technique_reports import T1210, T1197, T1110, T1075, T1003, T1059, T1086 +from monkey_island.cc.services.attack.technique_reports import T1210, T1197, T1110, T1075, T1003, T1059, T1086, T1082 from monkey_island.cc.services.attack.attack_telem import AttackTelemService from monkey_island.cc.services.attack.attack_config import AttackConfig from monkey_island.cc.database import mongo @@ -15,7 +15,8 @@ TECHNIQUES = {'T1210': T1210.T1210, 'T1075': T1075.T1075, 'T1003': T1003.T1003, 'T1059': T1059.T1059, - 'T1086': T1086.T1086} + 'T1086': T1086.T1086, + 'T1082': T1082.T1082} REPORT_NAME = 'new_report' diff --git a/monkey/monkey_island/cc/services/attack/attack_schema.py b/monkey/monkey_island/cc/services/attack/attack_schema.py index 24c8cf1c6..4d979a682 100644 --- a/monkey/monkey_island/cc/services/attack/attack_schema.py +++ b/monkey/monkey_island/cc/services/attack/attack_schema.py @@ -106,5 +106,20 @@ SCHEMA = { } } }, + "discovery": { + "title": "Discovery", + "type": "object", + "properties": { + "T1082": { + "title": "T1082 System information discovery", + "type": "bool", + "value": True, + "necessary": False, + "description": "An adversary may attempt to get detailed information about the " + "operating system and hardware, including version, patches, hotfixes, " + "service packs, and architecture." + } + } + }, } } diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1082.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1082.py index 76ed2a7af..9a73cf13c 100644 --- a/monkey/monkey_island/cc/services/attack/technique_reports/T1082.py +++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1082.py @@ -12,26 +12,35 @@ class T1082(AttackTechnique): scanned_msg = "" used_msg = "Monkey gathered system info from machines in the network." - # Gets data about successful PTH logins - query = [{'$match': {'telem_type': 'system_info_collection'}, + query = [{'$match': {'telem_type': 'system_info_collection'}}, + {'$project': {'machine': {'hostname': '$data.hostname', 'ips': '$data.network_info.networks'}, + 'aws': '$data.aws', + 'netstat': '$data.network_info.netstat', + 'process_list': '$data.process_list', + 'ssh_info': '$data.ssh_info', + 'azure_info': '$data.Azure'}}, {'$project': {'_id': 0, - 'machine': {'hostname': '$data.hostname', 'ips': '$data.network_info.networks'}, - 'info': {'aws': '$data.aws', - 'process_list': '$data.process_list.1' - 'attempt_cnt': {'$size': '$data.attempts'}, - 'attempts': {'$filter': {'input': '$data.attempts', - 'as': 'attempt', - 'cond': {'$eq': ['$$attempt.result', True]}}}}}] + 'machine': 1, + 'collections': [ + {'used': {'$and': [{'$ifNull': ['$netstat', False]}, {'$gt': ['$aws', {}]}]}, + 'name': {'$literal': 'Amazon Web Services info'}}, + {'used': {'$and': [{'$ifNull': ['$process_list', False]}, {'$gt': ['$process_list', {}]}]}, + 'name': {'$literal': 'Running process list'}}, + {'used': {'$and': [{'$ifNull': ['$netstat', False]}, {'$ne': ['$netstat', []]}]}, + 'name': {'$literal': 'Network connections'}}, + {'used': {'$and': [{'$ifNull': ['$ssh_info', False]}, {'$ne': ['$ssh_info', []]}]}, + 'name': {'$literal': 'SSH info'}}, + {'used': {'$and': [{'$ifNull': ['$azure_info', False]}, {'$ne': ['$azure_info', []]}]}, + 'name': {'$literal': 'Azure info'}} + ]}}] @staticmethod def get_report_data(): data = {'title': T1082.technique_title(T1082.tech_id)} - successful_logins = list(mongo.db.telemetry.aggregate(T1082.query)) - data.update({'successful_logins': successful_logins}) - if successful_logins: + system_info = list(mongo.db.telemetry.aggregate(T1082.query)) + data.update({'system_info': system_info}) + if system_info: data.update({'message': T1082.used_msg, 'status': ScanStatus.USED.name}) - elif mongo.db.telemetry.count_documents(T1082.login_attempt_query): - data.update({'message': T1082.scanned_msg, 'status': ScanStatus.SCANNED.name}) else: data.update({'message': T1082.unscanned_msg, 'status': ScanStatus.UNSCANNED.name}) return data diff --git a/monkey/monkey_island/cc/services/config_schema.py b/monkey/monkey_island/cc/services/config_schema.py index 8a96a0d78..57ad95944 100644 --- a/monkey/monkey_island/cc/services/config_schema.py +++ b/monkey/monkey_island/cc/services/config_schema.py @@ -422,6 +422,7 @@ SCHEMA = { "title": "Collect system info", "type": "boolean", "default": True, + "attack_techniques": ["T1082"], "description": "Determines whether to collect system info" }, "should_use_mimikatz": { diff --git a/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1082.js b/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1082.js new file mode 100644 index 000000000..3b3f1df7c --- /dev/null +++ b/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1082.js @@ -0,0 +1,55 @@ +import React from 'react'; +import '../../../styles/Collapse.scss' +import ReactTable from "react-table"; + + +class T1082 extends React.Component { + + constructor(props) { + super(props); + } + + static renderMachineString(data){ + let machineStr = data['hostname'] + " ( "; + data['ips'].forEach(function(ipInfo){ + machineStr += ipInfo['addr'] + " "; + }); + return machineStr + ")" + } + + static renderCollections(collections){ + let output = []; + collections.forEach(function(collection){ + if(collection['used']){ + output.push(
{collection['name']}
) + } + }); + return (
{output}
); + } + + static getSystemInfoColumns() { + return ([{ + columns: [ + {Header: 'Machine', id: 'machine', accessor: x => T1082.renderMachineString(x.machine), style: { 'whiteSpace': 'unset' }}, + {Header: 'Gathered info', id: 'info', accessor: x => T1082.renderCollections(x.collections), style: { 'whiteSpace': 'unset' }}, + ] + }])}; + + render() { + return ( +
+
{this.props.data.message}
+
+ {this.props.data.status === 'USED' ? + : ""} +
+ ); + } +} + +export default T1082; diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/AttackReport.js b/monkey/monkey_island/cc/ui/src/components/report-components/AttackReport.js index 87f6f0a38..6543ec389 100644 --- a/monkey/monkey_island/cc/ui/src/components/report-components/AttackReport.js +++ b/monkey/monkey_island/cc/ui/src/components/report-components/AttackReport.js @@ -12,6 +12,7 @@ import T1075 from "../attack/techniques/T1075"; import T1003 from "../attack/techniques/T1003"; import T1059 from "../attack/techniques/T1059"; import T1086 from "../attack/techniques/T1086"; +import T1082 from "../attack/techniques/T1082"; const tech_components = { 'T1210': T1210, @@ -20,7 +21,8 @@ const tech_components = { 'T1075': T1075, 'T1003': T1003, 'T1059': T1059, - 'T1086': T1086 + 'T1086': T1086, + 'T1082': T1082 }; const classNames = require('classnames'); From cc786b9ce8dd8ed607b0ab27d116457b039b694c Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Fri, 14 Jun 2019 11:43:48 +0300 Subject: [PATCH 3/5] Private keys attack technique implemented --- .../cc/services/attack/attack_report.py | 4 +- .../cc/services/attack/attack_schema.py | 10 ++++ .../attack/technique_reports/T1110.py | 50 ++++++++++++----- .../attack/technique_reports/T1145.py | 31 +++++++++++ .../attack/technique_reports/__init__.py | 15 ++++++ .../cc/services/config_schema.py | 2 +- .../components/attack/techniques/Helpers.js | 10 +++- .../src/components/attack/techniques/T1082.js | 11 +--- .../src/components/attack/techniques/T1145.js | 53 +++++++++++++++++++ .../report-components/AttackReport.js | 4 +- 10 files changed, 163 insertions(+), 27 deletions(-) create mode 100644 monkey/monkey_island/cc/services/attack/technique_reports/T1145.py create mode 100644 monkey/monkey_island/cc/ui/src/components/attack/techniques/T1145.js diff --git a/monkey/monkey_island/cc/services/attack/attack_report.py b/monkey/monkey_island/cc/services/attack/attack_report.py index 9a40e1728..a86db9042 100644 --- a/monkey/monkey_island/cc/services/attack/attack_report.py +++ b/monkey/monkey_island/cc/services/attack/attack_report.py @@ -1,5 +1,6 @@ import logging from monkey_island.cc.services.attack.technique_reports import T1210, T1197, T1110, T1075, T1003, T1059, T1086, T1082 +from monkey_island.cc.services.attack.technique_reports import T1145 from monkey_island.cc.services.attack.attack_telem import AttackTelemService from monkey_island.cc.services.attack.attack_config import AttackConfig from monkey_island.cc.database import mongo @@ -16,7 +17,8 @@ TECHNIQUES = {'T1210': T1210.T1210, 'T1003': T1003.T1003, 'T1059': T1059.T1059, 'T1086': T1086.T1086, - 'T1082': T1082.T1082} + 'T1082': T1082.T1082, + 'T1145': T1145.T1145} REPORT_NAME = 'new_report' diff --git a/monkey/monkey_island/cc/services/attack/attack_schema.py b/monkey/monkey_island/cc/services/attack/attack_schema.py index 4d979a682..00d3e9536 100644 --- a/monkey/monkey_island/cc/services/attack/attack_schema.py +++ b/monkey/monkey_island/cc/services/attack/attack_schema.py @@ -67,6 +67,16 @@ SCHEMA = { "information, normally in the form of a hash or a clear text password, " "from the operating system and software.", "depends_on": ["T1078"] + }, + "T1145": { + "title": "T1145 Private keys", + "type": "bool", + "value": True, + "necessary": False, + "description": "Adversaries may gather private keys from compromised systems for use in " + "authenticating to Remote Services like SSH or for use in decrypting " + "other collected files such as email.", + "depends_on": ["T1110", "T1210"] } } }, 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 040b05be2..7fe5ac90f 100644 --- a/monkey/monkey_island/cc/services/attack/technique_reports/T1110.py +++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1110.py @@ -35,11 +35,15 @@ class T1110(AttackTechnique): result['successful_creds'].append(T1110.parse_creds(attempt)) if succeeded: - data = {'message': T1110.used_msg, 'status': ScanStatus.USED.name} + data = T1110.get_message_and_status(T1110, ScanStatus.USED) elif attempts: - data = {'message': T1110.scanned_msg, 'status': ScanStatus.SCANNED.name} + data = T1110.get_message_and_status(T1110, ScanStatus.SCANNED) else: - data = {'message': T1110.unscanned_msg, 'status': ScanStatus.UNSCANNED.name} + data = T1110.get_message_and_status(T1110, ScanStatus.UNSCANNED) + + # Remove data with no successful brute force attempts + attempts = [attempt for attempt in attempts if attempt['attempts']] + data.update({'services': attempts, 'title': T1110.technique_title(T1110.tech_id)}) return data @@ -51,21 +55,39 @@ class T1110(AttackTechnique): :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]) - if attempt['ntlm_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']))) + creds = {'lm_hash': {'type': 'LM hash', 'output': T1110.censor_hash(attempt['lm_hash'])}, + 'ntlm_hash': {'type': 'NTLM hash', 'output': T1110.censor_hash(attempt['ntlm_hash'], 20)}, + 'ssh_key': {'type': 'SSH key', 'output': attempt['ssh_key']}, + 'password': {'type': 'Plaintext password', 'output': T1110.censor_password(attempt['password'])}} + for key, cred in creds.items(): + if attempt[key]: + return '%s ; %s : %s' % (username, + cred['type'], + cred['output']) @staticmethod - def obfuscate_password(password, plain_chars=3): + def censor_password(password, plain_chars=3, secret_chars=5): """ - Obfuscates password by changing characters to * + Decrypts and 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 + :param secret_chars: How many * symbols should be used to hide the remainder of the password :return: Obfuscated string e.g. Pass**** """ - return password[0:plain_chars] + '*' * (len(password) - plain_chars) + if not password: + return "" + password = encryptor.dec(password) + return password[0:plain_chars] + '*' * secret_chars + + @staticmethod + def censor_hash(hash_, plain_chars=5): + """ + Decrypts and obfuscates hash by only showing a part of it + :param hash_: Hash to obfuscate + :param plain_chars: How many chars of hash should be shown + :return: Obfuscated string + """ + if not hash_: + return "" + hash_ = encryptor.dec(hash_) + return hash_[0: plain_chars] + ' ...' diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1145.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1145.py new file mode 100644 index 000000000..29b4e97c0 --- /dev/null +++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1145.py @@ -0,0 +1,31 @@ +from monkey_island.cc.database import mongo +from monkey_island.cc.services.attack.technique_reports import AttackTechnique +from common.utils.attack_utils import ScanStatus + +__author__ = "VakarisZ" + + +class T1145(AttackTechnique): + tech_id = "T1145" + unscanned_msg = "Monkey didn't find any shh keys." + scanned_msg = "" + used_msg = "Monkey found ssh keys on machines in the network." + + # Gets data about ssh keys found + query = [{'$match': {'telem_type': 'system_info_collection', + 'data.ssh_info': {'$elemMatch': {'private_key': {'$exists': True}}}}}, + {'$project': {'_id': 0, + 'machine': {'hostname': '$data.hostname', 'ips': '$data.network_info.networks'}, + 'ssh_info': '$data.ssh_info'}}] + + @staticmethod + def get_report_data(): + ssh_info = list(mongo.db.telemetry.aggregate(T1145.query)) + + if ssh_info: + data = T1145.get_base_data_by_status(T1145, ScanStatus.USED) + else: + data = T1145.get_base_data_by_status(T1145, ScanStatus.UNSCANNED) + + data.update({'ssh_info': ssh_info}) + return data diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/__init__.py b/monkey/monkey_island/cc/services/attack/technique_reports/__init__.py index 0346a1857..1e152fd3f 100644 --- a/monkey/monkey_island/cc/services/attack/technique_reports/__init__.py +++ b/monkey/monkey_island/cc/services/attack/technique_reports/__init__.py @@ -60,6 +60,15 @@ class AttackTechnique(object): else: return ScanStatus.UNSCANNED + @staticmethod + def get_message_and_status(technique, status): + if status == ScanStatus.UNSCANNED: + return {'message': technique.unscanned_msg, 'status': ScanStatus.UNSCANNED.name} + elif status == ScanStatus.SCANNED: + return {'message': technique.scanned_msg, 'status': ScanStatus.SCANNED.name} + else: + return {'message': technique.used_msg, 'status': ScanStatus.USED.name} + @staticmethod def technique_title(technique): """ @@ -86,3 +95,9 @@ class AttackTechnique(object): else: data.update({'message': technique.used_msg}) return data + + @staticmethod + def get_base_data_by_status(technique, status): + data = technique.get_message_and_status(technique, status) + data.update({'title': technique.technique_title(technique.tech_id)}) + return data diff --git a/monkey/monkey_island/cc/services/config_schema.py b/monkey/monkey_island/cc/services/config_schema.py index 90d4f120f..bc66fa8e7 100644 --- a/monkey/monkey_island/cc/services/config_schema.py +++ b/monkey/monkey_island/cc/services/config_schema.py @@ -54,7 +54,7 @@ SCHEMA = { "SSHExploiter" ], "title": "SSH Exploiter", - "attack_techniques": ["T1110"] + "attack_techniques": ["T1110", "T1145"] }, { "type": "string", diff --git a/monkey/monkey_island/cc/ui/src/components/attack/techniques/Helpers.js b/monkey/monkey_island/cc/ui/src/components/attack/techniques/Helpers.js index b15bba693..9c976461c 100644 --- a/monkey/monkey_island/cc/ui/src/components/attack/techniques/Helpers.js +++ b/monkey/monkey_island/cc/ui/src/components/attack/techniques/Helpers.js @@ -4,4 +4,12 @@ export function RenderMachine(val){ return ( {val.ip_addr} {(val.domain_name ? " (".concat(val.domain_name, ")") : "")} ) -}; +} + +export function renderMachineFromSystemData(data) { + let machineStr = data['hostname'] + " ( "; + data['ips'].forEach(function(ipInfo){ + machineStr += ipInfo['addr'] + " "; + }); + return machineStr + ")" +} diff --git a/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1082.js b/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1082.js index 3b3f1df7c..739c69bc5 100644 --- a/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1082.js +++ b/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1082.js @@ -1,6 +1,7 @@ import React from 'react'; import '../../../styles/Collapse.scss' import ReactTable from "react-table"; +import { renderMachineFromSystemData } from "./Helpers" class T1082 extends React.Component { @@ -9,14 +10,6 @@ class T1082 extends React.Component { super(props); } - static renderMachineString(data){ - let machineStr = data['hostname'] + " ( "; - data['ips'].forEach(function(ipInfo){ - machineStr += ipInfo['addr'] + " "; - }); - return machineStr + ")" - } - static renderCollections(collections){ let output = []; collections.forEach(function(collection){ @@ -30,7 +23,7 @@ class T1082 extends React.Component { static getSystemInfoColumns() { return ([{ columns: [ - {Header: 'Machine', id: 'machine', accessor: x => T1082.renderMachineString(x.machine), style: { 'whiteSpace': 'unset' }}, + {Header: 'Machine', id: 'machine', accessor: x => renderMachineFromSystemData(x.machine), style: { 'whiteSpace': 'unset' }}, {Header: 'Gathered info', id: 'info', accessor: x => T1082.renderCollections(x.collections), style: { 'whiteSpace': 'unset' }}, ] }])}; diff --git a/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1145.js b/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1145.js new file mode 100644 index 000000000..c34f436e2 --- /dev/null +++ b/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1145.js @@ -0,0 +1,53 @@ +import React from 'react'; +import '../../../styles/Collapse.scss' +import ReactTable from "react-table"; +import { renderMachineFromSystemData } from "./Helpers" + + +class T1145 extends React.Component { + + constructor(props) { + super(props); + } + + static renderSSHKeys(keys){ + let output = []; + keys.forEach(function(keyInfo){ + output.push(
+ SSH key pair used by {keyInfo['name']} user found in {keyInfo['home_dir']}
) + }); + return (
{output}
); + } + + static getKeysInfoColumns() { + return ([{ + columns: [ + {Header: 'Machine', + id: 'machine', + accessor: x => renderMachineFromSystemData(x.machine), + style: { 'whiteSpace': 'unset' }}, + {Header: 'Keys found', + id: 'keys', + accessor: x => T1145.renderSSHKeys(x.ssh_info), + style: { 'whiteSpace': 'unset' }}, + ] + }])}; + + render() { + return ( +
+
{this.props.data.message}
+
+ {this.props.data.status === 'USED' ? + : ""} +
+ ); + } +} + +export default T1145; diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/AttackReport.js b/monkey/monkey_island/cc/ui/src/components/report-components/AttackReport.js index 6543ec389..348510175 100644 --- a/monkey/monkey_island/cc/ui/src/components/report-components/AttackReport.js +++ b/monkey/monkey_island/cc/ui/src/components/report-components/AttackReport.js @@ -13,6 +13,7 @@ import T1003 from "../attack/techniques/T1003"; import T1059 from "../attack/techniques/T1059"; import T1086 from "../attack/techniques/T1086"; import T1082 from "../attack/techniques/T1082"; +import T1145 from "../attack/techniques/T1145"; const tech_components = { 'T1210': T1210, @@ -22,7 +23,8 @@ const tech_components = { 'T1003': T1003, 'T1059': T1059, 'T1086': T1086, - 'T1082': T1082 + 'T1082': T1082, + 'T1145': T1145 }; const classNames = require('classnames'); From 592abc77b32c971ef5df4f7bb95b21cf5c1a89e1 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Wed, 26 Jun 2019 17:00:30 +0300 Subject: [PATCH 4/5] Updated system info gathering technique. --- monkey/monkey_island/cc/services/attack/attack_report.py | 3 +-- .../cc/services/attack/technique_reports/T1082.py | 9 +++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/monkey/monkey_island/cc/services/attack/attack_report.py b/monkey/monkey_island/cc/services/attack/attack_report.py index 02d840e61..a7a40e727 100644 --- a/monkey/monkey_island/cc/services/attack/attack_report.py +++ b/monkey/monkey_island/cc/services/attack/attack_report.py @@ -1,6 +1,5 @@ import logging -from monkey_island.cc.services.attack.technique_reports import T1210, T1197, T1110, T1075, T1003, T1059, T1086 -from monkey_island.cc.services.attack.attack_telem import AttackTelemService +from monkey_island.cc.services.attack.technique_reports import T1210, T1197, T1110, T1075, T1003, T1059, T1086, T1082 from monkey_island.cc.services.attack.attack_config import AttackConfig from monkey_island.cc.database import mongo diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1082.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1082.py index 9a73cf13c..79020c048 100644 --- a/monkey/monkey_island/cc/services/attack/technique_reports/T1082.py +++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1082.py @@ -12,7 +12,7 @@ class T1082(AttackTechnique): scanned_msg = "" used_msg = "Monkey gathered system info from machines in the network." - query = [{'$match': {'telem_type': 'system_info_collection'}}, + query = [{'$match': {'telem_category': 'system_info_collection'}}, {'$project': {'machine': {'hostname': '$data.hostname', 'ips': '$data.network_info.networks'}, 'aws': '$data.aws', 'netstat': '$data.network_info.netstat', @@ -36,11 +36,12 @@ class T1082(AttackTechnique): @staticmethod def get_report_data(): - data = {'title': T1082.technique_title(T1082.tech_id)} + data = {'title': T1082.technique_title()} system_info = list(mongo.db.telemetry.aggregate(T1082.query)) data.update({'system_info': system_info}) if system_info: - data.update({'message': T1082.used_msg, 'status': ScanStatus.USED.name}) + status = ScanStatus.USED else: - data.update({'message': T1082.unscanned_msg, 'status': ScanStatus.UNSCANNED.name}) + status = ScanStatus.UNSCANNED + data.update(T1082.get_message_and_status(status)) return data From a8a355afb29c8638ed7a479808abeb21d8577b0b Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Wed, 26 Jun 2019 17:32:31 +0300 Subject: [PATCH 5/5] Updated private keys attack technique --- monkey/monkey_island/cc/services/attack/attack_report.py | 1 - .../cc/services/attack/technique_reports/T1110.py | 4 ++-- .../cc/services/attack/technique_reports/T1145.py | 8 ++++---- .../cc/services/attack/technique_reports/__init__.py | 8 ++++---- .../cc/ui/src/components/attack/techniques/Helpers.js | 2 ++ 5 files changed, 12 insertions(+), 11 deletions(-) diff --git a/monkey/monkey_island/cc/services/attack/attack_report.py b/monkey/monkey_island/cc/services/attack/attack_report.py index 3efe0007f..7bec85a32 100644 --- a/monkey/monkey_island/cc/services/attack/attack_report.py +++ b/monkey/monkey_island/cc/services/attack/attack_report.py @@ -1,7 +1,6 @@ import logging from monkey_island.cc.services.attack.technique_reports import T1210, T1197, T1110, T1075, T1003, T1059, T1086, T1082 from monkey_island.cc.services.attack.technique_reports import T1145 -from monkey_island.cc.services.attack.attack_telem import AttackTelemService from monkey_island.cc.services.attack.attack_config import AttackConfig from monkey_island.cc.database import mongo 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 60ae14c0b..91d785bc3 100644 --- a/monkey/monkey_island/cc/services/attack/technique_reports/T1110.py +++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1110.py @@ -40,11 +40,11 @@ class T1110(AttackTechnique): status = ScanStatus.SCANNED else: status = ScanStatus.UNSCANNED - data = T1110.get_message_and_status(status) + data = T1110.get_base_data_by_status(status) # Remove data with no successful brute force attempts attempts = [attempt for attempt in attempts if attempt['attempts']] - data.update({'services': attempts, 'title': T1110.technique_title()}) + data.update({'services': attempts}) return data @staticmethod diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1145.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1145.py index 29b4e97c0..9b525873f 100644 --- a/monkey/monkey_island/cc/services/attack/technique_reports/T1145.py +++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1145.py @@ -12,7 +12,7 @@ class T1145(AttackTechnique): used_msg = "Monkey found ssh keys on machines in the network." # Gets data about ssh keys found - query = [{'$match': {'telem_type': 'system_info_collection', + query = [{'$match': {'telem_category': 'system_info_collection', 'data.ssh_info': {'$elemMatch': {'private_key': {'$exists': True}}}}}, {'$project': {'_id': 0, 'machine': {'hostname': '$data.hostname', 'ips': '$data.network_info.networks'}, @@ -23,9 +23,9 @@ class T1145(AttackTechnique): ssh_info = list(mongo.db.telemetry.aggregate(T1145.query)) if ssh_info: - data = T1145.get_base_data_by_status(T1145, ScanStatus.USED) + status = ScanStatus.USED else: - data = T1145.get_base_data_by_status(T1145, ScanStatus.UNSCANNED) - + status = ScanStatus.UNSCANNED + data = T1145.get_base_data_by_status(status) data.update({'ssh_info': ssh_info}) return data diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/__init__.py b/monkey/monkey_island/cc/services/attack/technique_reports/__init__.py index 95483e790..edd180d50 100644 --- a/monkey/monkey_island/cc/services/attack/technique_reports/__init__.py +++ b/monkey/monkey_island/cc/services/attack/technique_reports/__init__.py @@ -107,8 +107,8 @@ class AttackTechnique(object): 'message': cls.get_message_by_status(status)}) return data - @staticmethod - def get_base_data_by_status(technique, status): - data = technique.get_message_and_status(technique, status) - data.update({'title': technique.technique_title(technique.tech_id)}) + @classmethod + def get_base_data_by_status(cls, status): + data = cls.get_message_and_status(status) + data.update({'title': cls.technique_title()}) return data diff --git a/monkey/monkey_island/cc/ui/src/components/attack/techniques/Helpers.js b/monkey/monkey_island/cc/ui/src/components/attack/techniques/Helpers.js index 9d2fdfa62..9885219ad 100644 --- a/monkey/monkey_island/cc/ui/src/components/attack/techniques/Helpers.js +++ b/monkey/monkey_island/cc/ui/src/components/attack/techniques/Helpers.js @@ -6,6 +6,8 @@ export function renderMachine(val){ ) } +/* Function takes data gathered from system info collector and creates a + string representation of machine from that data. */ export function renderMachineFromSystemData(data) { let machineStr = data['hostname'] + " ( "; data['ips'].forEach(function(ipInfo){