From bc1be8e452686f3a392fd29167a78916130b9be1 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Fri, 28 Jun 2019 11:02:40 +0300 Subject: [PATCH 01/11] Implemented file deletion attack technique --- monkey/infection_monkey/monkey.py | 9 +++- .../telemetry/attack/t1107_telem.py | 19 ++++++++ monkey/infection_monkey/utils.py | 7 ++- .../cc/services/attack/attack_report.py | 7 +-- .../cc/services/attack/attack_schema.py | 9 ++++ .../attack/technique_reports/T1107.py | 32 +++++++++++++ .../attack/technique_reports/__init__.py | 12 ++--- .../components/attack/techniques/Helpers.js | 6 ++- .../src/components/attack/techniques/T1107.js | 47 +++++++++++++++++++ .../report-components/AttackReport.js | 4 +- 10 files changed, 139 insertions(+), 13 deletions(-) create mode 100644 monkey/infection_monkey/telemetry/attack/t1107_telem.py create mode 100644 monkey/monkey_island/cc/services/attack/technique_reports/T1107.py create mode 100644 monkey/monkey_island/cc/ui/src/components/attack/techniques/T1107.js diff --git a/monkey/infection_monkey/monkey.py b/monkey/infection_monkey/monkey.py index 06e0f267b..c6c5ee8b5 100644 --- a/monkey/infection_monkey/monkey.py +++ b/monkey/infection_monkey/monkey.py @@ -16,6 +16,7 @@ from infection_monkey.network.network_scanner import NetworkScanner from infection_monkey.system_info import SystemInfoCollector from infection_monkey.system_singleton import SystemSingleton from infection_monkey.telemetry.attack.victim_host_telem import VictimHostTelem +from infection_monkey.telemetry.attack.t1107_telem import T1107Telem from infection_monkey.windows_upgrader import WindowsUpgrader from infection_monkey.post_breach.post_breach_handler import PostBreach from common.utils.attack_utils import ScanStatus @@ -230,7 +231,6 @@ class InfectionMonkey(object): self.send_log() self._singleton.unlock() - utils.remove_monkey_dir() InfectionMonkey.self_delete() LOG.info("Monkey is shutting down") @@ -243,6 +243,11 @@ class InfectionMonkey(object): @staticmethod def self_delete(): + if utils.remove_monkey_dir(): + T1107Telem(ScanStatus.USED, utils.get_monkey_dir_path()).send() + else: + T1107Telem(ScanStatus.SCANNED, utils.get_monkey_dir_path()).send() + if WormConfiguration.self_delete_in_cleanup \ and -1 == sys.executable.find('python'): try: @@ -256,8 +261,10 @@ class InfectionMonkey(object): close_fds=True, startupinfo=startupinfo) else: os.remove(sys.executable) + T1107Telem(ScanStatus.USED, sys.executable).send() except Exception as exc: LOG.error("Exception in self delete: %s", exc) + T1107Telem(ScanStatus.SCANNED, sys.executable).send() def send_log(self): monkey_log_path = utils.get_monkey_log_path() diff --git a/monkey/infection_monkey/telemetry/attack/t1107_telem.py b/monkey/infection_monkey/telemetry/attack/t1107_telem.py new file mode 100644 index 000000000..ffb69b698 --- /dev/null +++ b/monkey/infection_monkey/telemetry/attack/t1107_telem.py @@ -0,0 +1,19 @@ +from infection_monkey.telemetry.attack.attack_telem import AttackTelem + + +class T1107Telem(AttackTelem): + def __init__(self, status, path): + """ + T1107 telemetry. + :param status: ScanStatus of technique + :param path: Path of deleted dir/file + """ + super(T1107Telem, self).__init__('T1107', status) + self.path = path + + def get_data(self): + data = super(T1107Telem, self).get_data() + data.update({ + 'path': self.path + }) + return data diff --git a/monkey/infection_monkey/utils.py b/monkey/infection_monkey/utils.py index 6eb3aefb5..f8b5cc56a 100644 --- a/monkey/infection_monkey/utils.py +++ b/monkey/infection_monkey/utils.py @@ -49,8 +49,13 @@ def create_monkey_dir(): def remove_monkey_dir(): """ Removes monkey's root directory + :return True if removed without errors and False otherwise """ - shutil.rmtree(get_monkey_dir_path(), ignore_errors=True) + try: + shutil.rmtree(get_monkey_dir_path()) + return True + except Exception: + return False def get_monkey_dir_path(): diff --git a/monkey/monkey_island/cc/services/attack/attack_report.py b/monkey/monkey_island/cc/services/attack/attack_report.py index 7bec85a32..ff038c092 100644 --- a/monkey/monkey_island/cc/services/attack/attack_report.py +++ b/monkey/monkey_island/cc/services/attack/attack_report.py @@ -1,6 +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.technique_reports import T1145, T1107 from monkey_island.cc.services.attack.attack_config import AttackConfig from monkey_island.cc.database import mongo @@ -17,7 +17,8 @@ TECHNIQUES = {'T1210': T1210.T1210, 'T1059': T1059.T1059, 'T1086': T1086.T1086, 'T1082': T1082.T1082, - 'T1145': T1145.T1145} + 'T1145': T1145.T1145, + 'T1107': T1107.T1107} REPORT_NAME = 'new_report' @@ -57,12 +58,12 @@ class AttackReportService: Gets latest report (by retrieving it from db or generating a new one). :return: report dict. """ + return AttackReportService.generate_new_report() if AttackReportService.is_report_generated(): telem_time = AttackReportService.get_latest_attack_telem_time() latest_report = mongo.db.attack_report.find_one({'name': REPORT_NAME}) if telem_time and latest_report['latest_telem_time'] and telem_time == latest_report['latest_telem_time']: return latest_report - return AttackReportService.generate_new_report() @staticmethod def is_report_generated(): diff --git a/monkey/monkey_island/cc/services/attack/attack_schema.py b/monkey/monkey_island/cc/services/attack/attack_schema.py index 00d3e9536..7a8cc7727 100644 --- a/monkey/monkey_island/cc/services/attack/attack_schema.py +++ b/monkey/monkey_island/cc/services/attack/attack_schema.py @@ -91,6 +91,15 @@ SCHEMA = { "necessary": True, "description": "Adversaries may abuse BITS to download, execute, " "and even clean up after running malicious code." + }, + "T1107": { + "title": "T1107 File Deletion", + "type": "bool", + "value": True, + "necessary": True, + "description": "Adversaries may remove files over the course of an intrusion " + "to keep their footprint low or remove them at the end as part " + "of the post-intrusion cleanup process." } } }, diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1107.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1107.py new file mode 100644 index 000000000..fd9f1ad10 --- /dev/null +++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1107.py @@ -0,0 +1,32 @@ +from monkey_island.cc.database import mongo +from monkey_island.cc.services.attack.technique_reports import AttackTechnique + +__author__ = "VakarisZ" + + +class T1107(AttackTechnique): + tech_id = "T1107" + unscanned_msg = "" + scanned_msg = "Monkey tried to delete files on a system in the network but failed." + used_msg = "Monkey successfully deleted files on systems in the network." + + query = [{'$match': {'telem_category': 'attack', + 'data.technique': 'T1107'}}, + {'$lookup': {'from': 'monkey', + 'localField': 'monkey_guid', + 'foreignField': 'guid', + 'as': 'monkey'}}, + {'$project': {'monkey': {'$arrayElemAt': ['$monkey', 0]}, + 'status': '$data.status', + 'path': '$data.path'}}, + {'$addFields': {'_id': 0, + 'machine': {'hostname': '$monkey.hostname', 'ips': '$monkey.ip_addresses'}, + 'monkey': 0}}, + {'$group': {'_id': {'machine': '$machine', 'status': '$status', 'path': '$path'}}}] + + @staticmethod + def get_report_data(): + data = T1107.get_tech_base_data() + deleted_files = list(mongo.db.telemetry.aggregate(T1107.query)) + data.update({'deleted_files': deleted_files}) + 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 edd180d50..81b7dd6bf 100644 --- a/monkey/monkey_island/cc/services/attack/technique_reports/__init__.py +++ b/monkey/monkey_island/cc/services/attack/technique_reports/__init__.py @@ -52,13 +52,13 @@ class AttackTechnique(object): Gets the status of a certain attack technique. :return: ScanStatus Enum object """ - if mongo.db.attack_results.find_one({'telem_category': 'attack', - 'status': ScanStatus.USED.value, - 'technique': cls.tech_id}): + if mongo.db.telemetry.find_one({'telem_category': 'attack', + 'data.status': ScanStatus.USED.value, + 'data.technique': cls.tech_id}): return ScanStatus.USED - elif mongo.db.attack_results.find_one({'telem_category': 'attack', - 'status': ScanStatus.SCANNED.value, - 'technique': cls.tech_id}): + elif mongo.db.telemetry.find_one({'telem_category': 'attack', + 'data.status': ScanStatus.SCANNED.value, + 'data.technique': cls.tech_id}): return ScanStatus.SCANNED else: return ScanStatus.UNSCANNED 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 9885219ad..1060f4b2d 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 @@ -11,7 +11,11 @@ export function renderMachine(val){ export function renderMachineFromSystemData(data) { let machineStr = data['hostname'] + " ( "; data['ips'].forEach(function(ipInfo){ - machineStr += ipInfo['addr'] + " "; + if(typeof ipInfo === "object"){ + machineStr += ipInfo['addr'] + " "; + } else { + machineStr += ipInfo + " "; + } }); return machineStr + ")" } diff --git a/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1107.js b/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1107.js new file mode 100644 index 000000000..acf513c2f --- /dev/null +++ b/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1107.js @@ -0,0 +1,47 @@ +import React from 'react'; +import '../../../styles/Collapse.scss' +import ReactTable from "react-table"; +import { renderMachineFromSystemData } from "./Helpers" + + +class T1107 extends React.Component { + + constructor(props) { + super(props); + } + + static renderDelete(status){ + if(status === 2){ + return Yes + } else { + return No + } + } + + static getDeletedFileColumns() { + return ([{ + columns: [ + {Header: 'Machine', id: 'machine', accessor: x => renderMachineFromSystemData(x._id.machine), style: { 'whiteSpace': 'unset' }}, + {Header: 'Path', id: 'path', accessor: x => x._id.path, style: { 'whiteSpace': 'unset' }}, + {Header: 'Deleted?', id: 'deleted', accessor: x => this.renderDelete(x._id.status), + style: { 'whiteSpace': 'unset' }, width: 160}] + }])}; + + render() { + return ( +
+
{this.props.data.message}
+
+ {this.props.data.deleted_files.length !== 0 ? + : ""} +
+ ); + } +} + +export default T1107; 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 348510175..0e9931f2d 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 @@ -14,6 +14,7 @@ import T1059 from "../attack/techniques/T1059"; import T1086 from "../attack/techniques/T1086"; import T1082 from "../attack/techniques/T1082"; import T1145 from "../attack/techniques/T1145"; +import T1107 from "../attack/techniques/T1107"; const tech_components = { 'T1210': T1210, @@ -24,7 +25,8 @@ const tech_components = { 'T1059': T1059, 'T1086': T1086, 'T1082': T1082, - 'T1145': T1145 + 'T1145': T1145, + 'T1107': T1107 }; const classNames = require('classnames'); From 452724c487e38a3a1e74c2e9f80aed9b7b97c22c Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Fri, 28 Jun 2019 12:17:39 +0300 Subject: [PATCH 02/11] Implemented service execution attack technique --- monkey/infection_monkey/exploit/smbexec.py | 4 +- .../telemetry/attack/t1035_telem.py | 19 ++++++++ .../cc/services/attack/attack_report.py | 5 ++- .../cc/services/attack/attack_schema.py | 9 ++++ .../attack/technique_reports/T1035.py | 31 +++++++++++++ .../attack/technique_reports/__init__.py | 12 ++--- .../cc/services/config_schema.py | 2 +- .../components/attack/techniques/Helpers.js | 6 ++- .../src/components/attack/techniques/T1035.js | 44 +++++++++++++++++++ .../report-components/AttackReport.js | 4 +- 10 files changed, 124 insertions(+), 12 deletions(-) create mode 100644 monkey/infection_monkey/telemetry/attack/t1035_telem.py create mode 100644 monkey/monkey_island/cc/services/attack/technique_reports/T1035.py create mode 100644 monkey/monkey_island/cc/ui/src/components/attack/techniques/T1035.js diff --git a/monkey/infection_monkey/exploit/smbexec.py b/monkey/infection_monkey/exploit/smbexec.py index d49e66ae8..ee865e533 100644 --- a/monkey/infection_monkey/exploit/smbexec.py +++ b/monkey/infection_monkey/exploit/smbexec.py @@ -10,6 +10,8 @@ from infection_monkey.network import SMBFinger from infection_monkey.network.tools import check_tcp_port from infection_monkey.exploit.tools import build_monkey_commandline from common.utils.exploit_enum import ExploitType +from infection_monkey.telemetry.attack.t1035_telem import T1035Telem +from common.utils.attack_utils import ScanStatus LOG = getLogger(__name__) @@ -129,7 +131,7 @@ class SmbExploiter(HostExploiter): resp = scmr.hRCreateServiceW(scmr_rpc, sc_handle, self._config.smb_service_name, self._config.smb_service_name, lpBinaryPathName=cmdline) service = resp['lpServiceHandle'] - + T1035Telem(ScanStatus.USED, "SMB exploiter ran the monkey by creating a service via MS-SCMR.").send() try: scmr.hRStartServiceW(scmr_rpc, service) except: diff --git a/monkey/infection_monkey/telemetry/attack/t1035_telem.py b/monkey/infection_monkey/telemetry/attack/t1035_telem.py new file mode 100644 index 000000000..3b0846609 --- /dev/null +++ b/monkey/infection_monkey/telemetry/attack/t1035_telem.py @@ -0,0 +1,19 @@ +from infection_monkey.telemetry.attack.attack_telem import AttackTelem + + +class T1035Telem(AttackTelem): + def __init__(self, status, usage): + """ + T1035 telemetry. + :param status: ScanStatus of technique + :param usage: Usage string + """ + super(T1035Telem, self).__init__('T1035', status) + self.usage = usage + + def get_data(self): + data = super(T1035Telem, self).get_data() + data.update({ + 'usage': self.usage + }) + return data diff --git a/monkey/monkey_island/cc/services/attack/attack_report.py b/monkey/monkey_island/cc/services/attack/attack_report.py index 7bec85a32..d33ad125e 100644 --- a/monkey/monkey_island/cc/services/attack/attack_report.py +++ b/monkey/monkey_island/cc/services/attack/attack_report.py @@ -1,6 +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.technique_reports import T1145, T1035 from monkey_island.cc.services.attack.attack_config import AttackConfig from monkey_island.cc.database import mongo @@ -17,7 +17,8 @@ TECHNIQUES = {'T1210': T1210.T1210, 'T1059': T1059.T1059, 'T1086': T1086.T1086, 'T1082': T1082.T1082, - 'T1145': T1145.T1145} + 'T1145': T1145.T1145, + 'T1035': T1035.T1035} 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 00d3e9536..9262b7536 100644 --- a/monkey/monkey_island/cc/services/attack/attack_schema.py +++ b/monkey/monkey_island/cc/services/attack/attack_schema.py @@ -98,6 +98,15 @@ SCHEMA = { "title": "Execution", "type": "object", "properties": { + "T1035": { + "title": "T1035 Service execution", + "type": "bool", + "value": True, + "necessary": False, + "description": "Adversaries may execute a binary, command, or script via a method " + "that interacts with Windows services, such as the Service Control Manager.", + "depends_on": ["T1210"] + }, "T1059": { "title": "T1059 Command line interface", "type": "bool", diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1035.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1035.py new file mode 100644 index 000000000..4dd2b7652 --- /dev/null +++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1035.py @@ -0,0 +1,31 @@ +from monkey_island.cc.database import mongo +from monkey_island.cc.services.attack.technique_reports import AttackTechnique + +__author__ = "VakarisZ" + + +class T1035(AttackTechnique): + tech_id = "T1035" + unscanned_msg = "Monkey didn't try to interact with Windows services." + scanned_msg = "Monkey tried to interact with Windows services, but failed." + used_msg = "Monkey successfully interacted with Windows services." + + query = [{'$match': {'telem_category': 'attack', + 'data.technique': tech_id}}, + {'$lookup': {'from': 'monkey', + 'localField': 'monkey_guid', + 'foreignField': 'guid', + 'as': 'monkey'}}, + {'$project': {'monkey': {'$arrayElemAt': ['$monkey', 0]}, + 'status': '$data.status', + 'usage': '$data.usage'}}, + {'$addFields': {'_id': 0, + 'machine': {'hostname': '$monkey.hostname', 'ips': '$monkey.ip_addresses'}, + 'monkey': 0}}, + {'$group': {'_id': {'machine': '$machine', 'status': '$status', 'usage': '$usage'}}}] + + @staticmethod + def get_report_data(): + data = T1035.get_tech_base_data() + data.update({'services': list(mongo.db.telemetry.aggregate(T1035.query))}) + 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 edd180d50..81b7dd6bf 100644 --- a/monkey/monkey_island/cc/services/attack/technique_reports/__init__.py +++ b/monkey/monkey_island/cc/services/attack/technique_reports/__init__.py @@ -52,13 +52,13 @@ class AttackTechnique(object): Gets the status of a certain attack technique. :return: ScanStatus Enum object """ - if mongo.db.attack_results.find_one({'telem_category': 'attack', - 'status': ScanStatus.USED.value, - 'technique': cls.tech_id}): + if mongo.db.telemetry.find_one({'telem_category': 'attack', + 'data.status': ScanStatus.USED.value, + 'data.technique': cls.tech_id}): return ScanStatus.USED - elif mongo.db.attack_results.find_one({'telem_category': 'attack', - 'status': ScanStatus.SCANNED.value, - 'technique': cls.tech_id}): + elif mongo.db.telemetry.find_one({'telem_category': 'attack', + 'data.status': ScanStatus.SCANNED.value, + 'data.technique': cls.tech_id}): return ScanStatus.SCANNED else: return ScanStatus.UNSCANNED diff --git a/monkey/monkey_island/cc/services/config_schema.py b/monkey/monkey_island/cc/services/config_schema.py index bc66fa8e7..34dea9a14 100644 --- a/monkey/monkey_island/cc/services/config_schema.py +++ b/monkey/monkey_island/cc/services/config_schema.py @@ -14,7 +14,7 @@ SCHEMA = { "SmbExploiter" ], "title": "SMB Exploiter", - "attack_techniques": ["T1110", "T1075"] + "attack_techniques": ["T1110", "T1075", "T1035"] }, { "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 9885219ad..1060f4b2d 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 @@ -11,7 +11,11 @@ export function renderMachine(val){ export function renderMachineFromSystemData(data) { let machineStr = data['hostname'] + " ( "; data['ips'].forEach(function(ipInfo){ - machineStr += ipInfo['addr'] + " "; + if(typeof ipInfo === "object"){ + machineStr += ipInfo['addr'] + " "; + } else { + machineStr += ipInfo + " "; + } }); return machineStr + ")" } diff --git a/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1035.js b/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1035.js new file mode 100644 index 000000000..b760226b8 --- /dev/null +++ b/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1035.js @@ -0,0 +1,44 @@ +import React from 'react'; +import '../../../styles/Collapse.scss' +import ReactTable from "react-table"; +import { renderMachineFromSystemData } from "./Helpers" + + +class T1035 extends React.Component { + + constructor(props) { + super(props); + } + + static getServiceColumns() { + return ([{ + columns: [ + {Header: 'Machine', + id: 'machine', + accessor: x => renderMachineFromSystemData(x._id.machine), + style: { 'whiteSpace': 'unset' }, + width: 300}, + {Header: 'Usage', + id: 'usage', + accessor: x => x._id.usage, + style: { 'whiteSpace': 'unset' }}] + }])}; + + render() { + return ( +
+
{this.props.data.message}
+
+ {this.props.data.services.length !== 0 ? + : ""} +
+ ); + } +} + +export default T1035; 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 348510175..a18754f1d 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 @@ -14,6 +14,7 @@ import T1059 from "../attack/techniques/T1059"; import T1086 from "../attack/techniques/T1086"; import T1082 from "../attack/techniques/T1082"; import T1145 from "../attack/techniques/T1145"; +import T1035 from "../attack/techniques/T1035"; const tech_components = { 'T1210': T1210, @@ -24,7 +25,8 @@ const tech_components = { 'T1059': T1059, 'T1086': T1086, 'T1082': T1082, - 'T1145': T1145 + 'T1145': T1145, + 'T1035': T1035 }; const classNames = require('classnames'); From d1f8e522664b38031c9ca904715a433a03149d86 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Mon, 1 Jul 2019 11:30:49 +0300 Subject: [PATCH 03/11] Implemented execution trough module load attack technique --- .../system_info/mimikatz_collector.py | 5 +++- .../telemetry/attack/t1035_telem.py | 14 ++------- .../telemetry/attack/t1129_telem.py | 11 +++++++ .../telemetry/attack/usage_telem.py | 20 +++++++++++++ .../cc/services/attack/attack_report.py | 7 +++-- .../cc/services/attack/attack_schema.py | 9 ++++++ .../attack/technique_reports/T1035.py | 16 +--------- .../attack/technique_reports/T1129.py | 17 +++++++++++ .../attack/technique_reports/__init__.py | 20 +++++++++++++ .../components/attack/techniques/Helpers.js | 16 ++++++++++ .../src/components/attack/techniques/T1035.js | 18 ++---------- .../src/components/attack/techniques/T1129.js | 29 +++++++++++++++++++ .../report-components/AttackReport.js | 4 ++- 13 files changed, 139 insertions(+), 47 deletions(-) create mode 100644 monkey/infection_monkey/telemetry/attack/t1129_telem.py create mode 100644 monkey/infection_monkey/telemetry/attack/usage_telem.py create mode 100644 monkey/monkey_island/cc/services/attack/technique_reports/T1129.py create mode 100644 monkey/monkey_island/cc/ui/src/components/attack/techniques/T1129.js diff --git a/monkey/infection_monkey/system_info/mimikatz_collector.py b/monkey/infection_monkey/system_info/mimikatz_collector.py index 4ef764251..4f2348531 100644 --- a/monkey/infection_monkey/system_info/mimikatz_collector.py +++ b/monkey/infection_monkey/system_info/mimikatz_collector.py @@ -5,7 +5,8 @@ import socket import zipfile import infection_monkey.config - +from common.utils.attack_utils import ScanStatus +from infection_monkey.telemetry.attack.t1129_telem import T1129Telem from infection_monkey.pyinstaller_utils import get_binary_file_path, get_binaries_dir_path __author__ = 'itay.mizeretz' @@ -49,8 +50,10 @@ class MimikatzCollector(object): self._get = get_proto(("get", self._dll)) self._get_text_output_proto = get_text_output_proto(("getTextOutput", self._dll)) self._isInit = True + T1129Telem(ScanStatus.USED, "Windows module loader was used to load Mimikatz DLL.").send() except Exception: LOG.exception("Error initializing mimikatz collector") + T1129Telem(ScanStatus.SCANNED, "Monkey tried to load Mimikatz DLL, but failed.").send() def get_logon_info(self): """ diff --git a/monkey/infection_monkey/telemetry/attack/t1035_telem.py b/monkey/infection_monkey/telemetry/attack/t1035_telem.py index 3b0846609..b3d7c90de 100644 --- a/monkey/infection_monkey/telemetry/attack/t1035_telem.py +++ b/monkey/infection_monkey/telemetry/attack/t1035_telem.py @@ -1,19 +1,11 @@ -from infection_monkey.telemetry.attack.attack_telem import AttackTelem +from infection_monkey.telemetry.attack.usage_telem import UsageTelem -class T1035Telem(AttackTelem): +class T1035Telem(UsageTelem): def __init__(self, status, usage): """ T1035 telemetry. :param status: ScanStatus of technique :param usage: Usage string """ - super(T1035Telem, self).__init__('T1035', status) - self.usage = usage - - def get_data(self): - data = super(T1035Telem, self).get_data() - data.update({ - 'usage': self.usage - }) - return data + super(T1035Telem, self).__init__('T1035', status, usage) diff --git a/monkey/infection_monkey/telemetry/attack/t1129_telem.py b/monkey/infection_monkey/telemetry/attack/t1129_telem.py new file mode 100644 index 000000000..fb7d776c6 --- /dev/null +++ b/monkey/infection_monkey/telemetry/attack/t1129_telem.py @@ -0,0 +1,11 @@ +from infection_monkey.telemetry.attack.usage_telem import UsageTelem + + +class T1129Telem(UsageTelem): + def __init__(self, status, usage): + """ + T1129 telemetry. + :param status: ScanStatus of technique + :param usage: Usage string + """ + super(T1129Telem, self).__init__("T1129", status, usage) diff --git a/monkey/infection_monkey/telemetry/attack/usage_telem.py b/monkey/infection_monkey/telemetry/attack/usage_telem.py new file mode 100644 index 000000000..48ff5431c --- /dev/null +++ b/monkey/infection_monkey/telemetry/attack/usage_telem.py @@ -0,0 +1,20 @@ +from infection_monkey.telemetry.attack.attack_telem import AttackTelem + + +class UsageTelem(AttackTelem): + + def __init__(self, technique, status, usage): + """ + T1035 telemetry. + :param status: ScanStatus of technique + :param usage: Usage string + """ + super(UsageTelem, self).__init__(technique, status) + self.usage = usage + + def get_data(self): + data = super(UsageTelem, self).get_data() + data.update({ + 'usage': self.usage + }) + return data diff --git a/monkey/monkey_island/cc/services/attack/attack_report.py b/monkey/monkey_island/cc/services/attack/attack_report.py index d33ad125e..ab5b82245 100644 --- a/monkey/monkey_island/cc/services/attack/attack_report.py +++ b/monkey/monkey_island/cc/services/attack/attack_report.py @@ -1,6 +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, T1035 +from monkey_island.cc.services.attack.technique_reports import T1145, T1035, T1129 from monkey_island.cc.services.attack.attack_config import AttackConfig from monkey_island.cc.database import mongo @@ -18,7 +18,8 @@ TECHNIQUES = {'T1210': T1210.T1210, 'T1086': T1086.T1086, 'T1082': T1082.T1082, 'T1145': T1145.T1145, - 'T1035': T1035.T1035} + 'T1035': T1035.T1035, + 'T1129': T1129.T1129} REPORT_NAME = 'new_report' @@ -58,12 +59,12 @@ class AttackReportService: Gets latest report (by retrieving it from db or generating a new one). :return: report dict. """ + return AttackReportService.generate_new_report() if AttackReportService.is_report_generated(): telem_time = AttackReportService.get_latest_attack_telem_time() latest_report = mongo.db.attack_report.find_one({'name': REPORT_NAME}) if telem_time and latest_report['latest_telem_time'] and telem_time == latest_report['latest_telem_time']: return latest_report - return AttackReportService.generate_new_report() @staticmethod def is_report_generated(): diff --git a/monkey/monkey_island/cc/services/attack/attack_schema.py b/monkey/monkey_island/cc/services/attack/attack_schema.py index 9262b7536..957731251 100644 --- a/monkey/monkey_island/cc/services/attack/attack_schema.py +++ b/monkey/monkey_island/cc/services/attack/attack_schema.py @@ -107,6 +107,15 @@ SCHEMA = { "that interacts with Windows services, such as the Service Control Manager.", "depends_on": ["T1210"] }, + "T1129": { + "title": "T1129 Execution through module load", + "type": "bool", + "value": True, + "necessary": False, + "description": "The Windows module loader can be instructed to load DLLs from arbitrary " + "local paths and arbitrary Universal Naming Convention (UNC) network paths.", + "depends_on": ["T1078", "T1003"] + }, "T1059": { "title": "T1059 Command line interface", "type": "bool", diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1035.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1035.py index 4dd2b7652..a651a8288 100644 --- a/monkey/monkey_island/cc/services/attack/technique_reports/T1035.py +++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1035.py @@ -10,22 +10,8 @@ class T1035(AttackTechnique): scanned_msg = "Monkey tried to interact with Windows services, but failed." used_msg = "Monkey successfully interacted with Windows services." - query = [{'$match': {'telem_category': 'attack', - 'data.technique': tech_id}}, - {'$lookup': {'from': 'monkey', - 'localField': 'monkey_guid', - 'foreignField': 'guid', - 'as': 'monkey'}}, - {'$project': {'monkey': {'$arrayElemAt': ['$monkey', 0]}, - 'status': '$data.status', - 'usage': '$data.usage'}}, - {'$addFields': {'_id': 0, - 'machine': {'hostname': '$monkey.hostname', 'ips': '$monkey.ip_addresses'}, - 'monkey': 0}}, - {'$group': {'_id': {'machine': '$machine', 'status': '$status', 'usage': '$usage'}}}] - @staticmethod def get_report_data(): data = T1035.get_tech_base_data() - data.update({'services': list(mongo.db.telemetry.aggregate(T1035.query))}) + data.update({'services': list(mongo.db.telemetry.aggregate(T1035.get_usage_query()))}) return data diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1129.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1129.py new file mode 100644 index 000000000..7d9fa9dd0 --- /dev/null +++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1129.py @@ -0,0 +1,17 @@ +from monkey_island.cc.database import mongo +from monkey_island.cc.services.attack.technique_reports import AttackTechnique + +__author__ = "VakarisZ" + + +class T1129(AttackTechnique): + tech_id = "T1129" + unscanned_msg = "Monkey didn't try to load any DLL's." + scanned_msg = "Monkey tried to load DLL's, but failed." + used_msg = "Monkey successfully loaded DLL's using Windows module loader." + + @staticmethod + def get_report_data(): + data = T1129.get_tech_base_data() + data.update({'dlls': list(mongo.db.telemetry.aggregate(T1129.get_usage_query()))}) + 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 81b7dd6bf..b3b3ce77b 100644 --- a/monkey/monkey_island/cc/services/attack/technique_reports/__init__.py +++ b/monkey/monkey_island/cc/services/attack/technique_reports/__init__.py @@ -112,3 +112,23 @@ class AttackTechnique(object): data = cls.get_message_and_status(status) data.update({'title': cls.technique_title()}) return data + + @classmethod + def get_usage_query(cls): + """ + :return: Query that parses attack telems for simple report component + (gets machines and attack technique usage). + """ + return [{'$match': {'telem_category': 'attack', + 'data.technique': cls.tech_id}}, + {'$lookup': {'from': 'monkey', + 'localField': 'monkey_guid', + 'foreignField': 'guid', + 'as': 'monkey'}}, + {'$project': {'monkey': {'$arrayElemAt': ['$monkey', 0]}, + 'status': '$data.status', + 'usage': '$data.usage'}}, + {'$addFields': {'_id': 0, + 'machine': {'hostname': '$monkey.hostname', 'ips': '$monkey.ip_addresses'}, + 'monkey': 0}}, + {'$group': {'_id': {'machine': '$machine', 'status': '$status', 'usage': '$usage'}}}] 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 1060f4b2d..fad2087d9 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 @@ -19,3 +19,19 @@ export function renderMachineFromSystemData(data) { }); return machineStr + ")" } + +/* Formats telemetry data that contains _id.machine and _id.usage fields into columns + for react table. */ +export function getUsageColumns() { + return ([{ + columns: [ + {Header: 'Machine', + id: 'machine', + accessor: x => renderMachineFromSystemData(x._id.machine), + style: { 'whiteSpace': 'unset' }, + width: 300}, + {Header: 'Usage', + id: 'usage', + accessor: x => x._id.usage, + style: { 'whiteSpace': 'unset' }}] + }])} diff --git a/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1035.js b/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1035.js index b760226b8..7345ca497 100644 --- a/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1035.js +++ b/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1035.js @@ -1,7 +1,7 @@ import React from 'react'; import '../../../styles/Collapse.scss' import ReactTable from "react-table"; -import { renderMachineFromSystemData } from "./Helpers" +import { getUsageColumns } from "./Helpers" class T1035 extends React.Component { @@ -10,20 +10,6 @@ class T1035 extends React.Component { super(props); } - static getServiceColumns() { - return ([{ - columns: [ - {Header: 'Machine', - id: 'machine', - accessor: x => renderMachineFromSystemData(x._id.machine), - style: { 'whiteSpace': 'unset' }, - width: 300}, - {Header: 'Usage', - id: 'usage', - accessor: x => x._id.usage, - style: { 'whiteSpace': 'unset' }}] - }])}; - render() { return (
@@ -31,7 +17,7 @@ class T1035 extends React.Component {
{this.props.data.services.length !== 0 ? +
{this.props.data.message}
+
+ {this.props.data.dlls.length !== 0 ? + : ""} +
+ ); + } +} + +export default T1129; 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 a18754f1d..57ac66f87 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 @@ -15,6 +15,7 @@ import T1086 from "../attack/techniques/T1086"; import T1082 from "../attack/techniques/T1082"; import T1145 from "../attack/techniques/T1145"; import T1035 from "../attack/techniques/T1035"; +import T1129 from "../attack/techniques/T1129"; const tech_components = { 'T1210': T1210, @@ -26,7 +27,8 @@ const tech_components = { 'T1086': T1086, 'T1082': T1082, 'T1145': T1145, - 'T1035': T1035 + 'T1035': T1035, + 'T1129': T1129 }; const classNames = require('classnames'); From 9415f6e73c6996f1d3dc22e3a629cd1c0c73928f Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Mon, 1 Jul 2019 16:52:57 +0300 Subject: [PATCH 04/11] Execution trough WinAPI attack technique implemented --- monkey/infection_monkey/dropper.py | 4 +++ .../system_info/mimikatz_collector.py | 7 +++-- monkey/infection_monkey/system_singleton.py | 6 +++- .../telemetry/attack/t1106_telem.py | 11 +++++++ .../cc/services/attack/attack_report.py | 5 ++-- .../cc/services/attack/attack_schema.py | 9 ++++++ .../attack/technique_reports/T1106.py | 17 +++++++++++ .../cc/services/config_schema.py | 4 +-- .../src/components/attack/techniques/T1106.js | 30 +++++++++++++++++++ .../report-components/AttackReport.js | 4 ++- 10 files changed, 89 insertions(+), 8 deletions(-) create mode 100644 monkey/infection_monkey/telemetry/attack/t1106_telem.py create mode 100644 monkey/monkey_island/cc/services/attack/technique_reports/T1106.py create mode 100644 monkey/monkey_island/cc/ui/src/components/attack/techniques/T1106.js diff --git a/monkey/infection_monkey/dropper.py b/monkey/infection_monkey/dropper.py index cc065a745..e39860d50 100644 --- a/monkey/infection_monkey/dropper.py +++ b/monkey/infection_monkey/dropper.py @@ -14,6 +14,8 @@ from infection_monkey.config import WormConfiguration from infection_monkey.exploit.tools import build_monkey_commandline_explicitly from infection_monkey.model import MONKEY_CMDLINE_WINDOWS, MONKEY_CMDLINE_LINUX, GENERAL_CMDLINE_LINUX from infection_monkey.system_info import SystemInfoCollector, OperatingSystem +from infection_monkey.telemetry.attack.t1106_telem import T1106Telem +from common.utils.attack_utils import ScanStatus if "win32" == sys.platform: from win32process import DETACHED_PROCESS @@ -156,5 +158,7 @@ class MonkeyDrops(object): else: LOG.debug("Dropper source file '%s' is marked for deletion on next boot", self._config['source_path']) + T1106Telem(ScanStatus.USED, "WinAPI was used to mark monkey files" + " for deletion on next boot.").send() except AttributeError: LOG.error("Invalid configuration options. Failing") diff --git a/monkey/infection_monkey/system_info/mimikatz_collector.py b/monkey/infection_monkey/system_info/mimikatz_collector.py index 4f2348531..96b53be35 100644 --- a/monkey/infection_monkey/system_info/mimikatz_collector.py +++ b/monkey/infection_monkey/system_info/mimikatz_collector.py @@ -7,6 +7,7 @@ import zipfile import infection_monkey.config from common.utils.attack_utils import ScanStatus from infection_monkey.telemetry.attack.t1129_telem import T1129Telem +from infection_monkey.telemetry.attack.t1106_telem import T1106Telem from infection_monkey.pyinstaller_utils import get_binary_file_path, get_binaries_dir_path __author__ = 'itay.mizeretz' @@ -46,6 +47,7 @@ class MimikatzCollector(object): collect_proto = ctypes.WINFUNCTYPE(ctypes.c_int) get_proto = ctypes.WINFUNCTYPE(MimikatzCollector.LogonData) get_text_output_proto = ctypes.WINFUNCTYPE(ctypes.c_wchar_p) + T1106Telem(ScanStatus.USED, "WinAPI was called to load mimikatz.").send() self._collect = collect_proto(("collect", self._dll)) self._get = get_proto(("get", self._dll)) self._get_text_output_proto = get_text_output_proto(("getTextOutput", self._dll)) @@ -54,6 +56,7 @@ class MimikatzCollector(object): except Exception: LOG.exception("Error initializing mimikatz collector") T1129Telem(ScanStatus.SCANNED, "Monkey tried to load Mimikatz DLL, but failed.").send() + T1106Telem(ScanStatus.SCANNED, "Monkey tried to call WinAPI to load mimikatz.").send() def get_logon_info(self): """ @@ -70,7 +73,7 @@ class MimikatzCollector(object): logon_data_dictionary = {} hostname = socket.gethostname() - + self.mimikatz_text = self._get_text_output_proto() for i in range(entry_count): @@ -105,7 +108,7 @@ class MimikatzCollector(object): except Exception: LOG.exception("Error getting logon info") return {} - + def get_mimikatz_text(self): return self.mimikatz_text diff --git a/monkey/infection_monkey/system_singleton.py b/monkey/infection_monkey/system_singleton.py index 9f56c238e..06a2ea689 100644 --- a/monkey/infection_monkey/system_singleton.py +++ b/monkey/infection_monkey/system_singleton.py @@ -4,6 +4,8 @@ import sys from abc import ABCMeta, abstractmethod from infection_monkey.config import WormConfiguration +from infection_monkey.telemetry.attack.t1106_telem import T1106Telem +from common.utils.attack_utils import ScanStatus __author__ = 'itamar' @@ -46,6 +48,8 @@ class WindowsSystemSingleton(_SystemSingleton): if not handle: LOG.error("Cannot acquire system singleton %r, unknown error %d", self._mutex_name, last_error) + T1106Telem(ScanStatus.SCANNED, "WinAPI call to acquire system singleton " + "for monkey process wasn't successful.").send() return False @@ -56,7 +60,7 @@ class WindowsSystemSingleton(_SystemSingleton): return False self._mutex_handle = handle - + T1106Telem(ScanStatus.USED, "WinAPI was called to acquire system singleton for monkey's process.").send() LOG.debug("Global singleton mutex %r acquired", self._mutex_name) diff --git a/monkey/infection_monkey/telemetry/attack/t1106_telem.py b/monkey/infection_monkey/telemetry/attack/t1106_telem.py new file mode 100644 index 000000000..30cad6072 --- /dev/null +++ b/monkey/infection_monkey/telemetry/attack/t1106_telem.py @@ -0,0 +1,11 @@ +from infection_monkey.telemetry.attack.usage_telem import UsageTelem + + +class T1106Telem(UsageTelem): + def __init__(self, status, usage): + """ + T1129 telemetry. + :param status: ScanStatus of technique + :param usage: Usage string + """ + super(T1106Telem, self).__init__("T1106", status, usage) diff --git a/monkey/monkey_island/cc/services/attack/attack_report.py b/monkey/monkey_island/cc/services/attack/attack_report.py index ab5b82245..8e7d44905 100644 --- a/monkey/monkey_island/cc/services/attack/attack_report.py +++ b/monkey/monkey_island/cc/services/attack/attack_report.py @@ -1,6 +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, T1035, T1129 +from monkey_island.cc.services.attack.technique_reports import T1145, T1035, T1129, T1106 from monkey_island.cc.services.attack.attack_config import AttackConfig from monkey_island.cc.database import mongo @@ -19,7 +19,8 @@ TECHNIQUES = {'T1210': T1210.T1210, 'T1082': T1082.T1082, 'T1145': T1145.T1145, 'T1035': T1035.T1035, - 'T1129': T1129.T1129} + 'T1129': T1129.T1129, + 'T1106': T1106.T1106} 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 957731251..4a4402dc1 100644 --- a/monkey/monkey_island/cc/services/attack/attack_schema.py +++ b/monkey/monkey_island/cc/services/attack/attack_schema.py @@ -116,6 +116,15 @@ SCHEMA = { "local paths and arbitrary Universal Naming Convention (UNC) network paths.", "depends_on": ["T1078", "T1003"] }, + "T1106": { + "title": "T1106 Execution through API", + "type": "bool", + "value": True, + "necessary": False, + "description": "Adversary tools may directly use the Windows application " + "programming interface (API) to execute binaries.", + "depends_on": ["T1210"] + }, "T1059": { "title": "T1059 Command line interface", "type": "bool", diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1106.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1106.py new file mode 100644 index 000000000..b24d10bd9 --- /dev/null +++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1106.py @@ -0,0 +1,17 @@ +from monkey_island.cc.database import mongo +from monkey_island.cc.services.attack.technique_reports import AttackTechnique + +__author__ = "VakarisZ" + + +class T1106(AttackTechnique): + tech_id = "T1106" + unscanned_msg = "Monkey didn't try to directly use WinAPI." + scanned_msg = "Monkey tried to use WinAPI, but failed." + used_msg = "Monkey successfully used WinAPI." + + @staticmethod + def get_report_data(): + data = T1106.get_tech_base_data() + data.update({'api_uses': list(mongo.db.telemetry.aggregate(T1106.get_usage_query()))}) + return data diff --git a/monkey/monkey_island/cc/services/config_schema.py b/monkey/monkey_island/cc/services/config_schema.py index 34dea9a14..c79b14eaa 100644 --- a/monkey/monkey_island/cc/services/config_schema.py +++ b/monkey/monkey_island/cc/services/config_schema.py @@ -22,7 +22,7 @@ SCHEMA = { "WmiExploiter" ], "title": "WMI Exploiter", - "attack_techniques": ["T1110"] + "attack_techniques": ["T1110", "T1106"] }, { "type": "string", @@ -54,7 +54,7 @@ SCHEMA = { "SSHExploiter" ], "title": "SSH Exploiter", - "attack_techniques": ["T1110", "T1145"] + "attack_techniques": ["T1110", "T1145", "T1106"] }, { "type": "string", diff --git a/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1106.js b/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1106.js new file mode 100644 index 000000000..a3210b73c --- /dev/null +++ b/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1106.js @@ -0,0 +1,30 @@ +import React from 'react'; +import '../../../styles/Collapse.scss' +import ReactTable from "react-table"; +import { getUsageColumns } from "./Helpers" + + +class T1106 extends React.Component { + + constructor(props) { + super(props); + } + + render() { + return ( +
+
{this.props.data.message}
+
+ {this.props.data.api_uses.length !== 0 ? + : ""} +
+ ); + } +} + +export default T1106; 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 57ac66f87..58e234b82 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 @@ -16,6 +16,7 @@ import T1082 from "../attack/techniques/T1082"; import T1145 from "../attack/techniques/T1145"; import T1035 from "../attack/techniques/T1035"; import T1129 from "../attack/techniques/T1129"; +import T1106 from "../attack/techniques/T1106"; const tech_components = { 'T1210': T1210, @@ -28,7 +29,8 @@ const tech_components = { 'T1082': T1082, 'T1145': T1145, 'T1035': T1035, - 'T1129': T1129 + 'T1129': T1129, + 'T1106': T1106 }; const classNames = require('classnames'); From 9c41556cb0a2ce034e400df230e3da1c0a351903 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Wed, 3 Jul 2019 14:11:15 +0300 Subject: [PATCH 05/11] Fixed tunneling bug where local machine gets set as island. --- monkey/infection_monkey/monkey.py | 7 +++++-- monkey/infection_monkey/network/network_scanner.py | 3 +++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/monkey/infection_monkey/monkey.py b/monkey/infection_monkey/monkey.py index 06e0f267b..572b527df 100644 --- a/monkey/infection_monkey/monkey.py +++ b/monkey/infection_monkey/monkey.py @@ -175,8 +175,11 @@ class InfectionMonkey(object): if monkey_tunnel: monkey_tunnel.set_tunnel_for_host(machine) if self._default_server: - machine.set_default_server(get_interface_to_target(machine.ip_addr) + - (':'+self._default_server_port if self._default_server_port else '')) + if self._network.on_island(self._default_server): + machine.set_default_server(get_interface_to_target(machine.ip_addr) + + (':'+self._default_server_port if self._default_server_port else '')) + else: + machine.set_default_server(self._default_server) LOG.debug("Default server: %s set to machine: %r" % (self._default_server, machine)) # Order exploits according to their type diff --git a/monkey/infection_monkey/network/network_scanner.py b/monkey/infection_monkey/network/network_scanner.py index 5f65e4228..837add48a 100644 --- a/monkey/infection_monkey/network/network_scanner.py +++ b/monkey/infection_monkey/network/network_scanner.py @@ -118,3 +118,6 @@ class NetworkScanner(object): if NetworkRange.get_range_obj(subnet_str).is_in_range(ip_address): return True return False + + def on_island(self, server): + return bool([x for x in self._ip_addresses if x in server]) From 967fec8487df40e9398f6b320d5960344a5e5ccb Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Mon, 8 Jul 2019 13:44:15 +0300 Subject: [PATCH 06/11] Refactored scan status to use numeric value and other PR fixes --- monkey/infection_monkey/monkey.py | 6 ++---- .../monkey_island/cc/services/attack/attack_report.py | 2 +- .../cc/services/attack/technique_reports/T1107.py | 2 +- .../cc/services/attack/technique_reports/__init__.py | 10 +++++----- .../cc/ui/src/components/attack/techniques/Helpers.js | 6 ++++++ .../cc/ui/src/components/attack/techniques/T1003.js | 3 ++- .../cc/ui/src/components/attack/techniques/T1059.js | 4 ++-- .../cc/ui/src/components/attack/techniques/T1075.js | 4 ++-- .../cc/ui/src/components/attack/techniques/T1082.js | 4 ++-- .../cc/ui/src/components/attack/techniques/T1086.js | 4 ++-- .../cc/ui/src/components/attack/techniques/T1107.js | 2 +- .../cc/ui/src/components/attack/techniques/T1110.js | 4 ++-- .../cc/ui/src/components/attack/techniques/T1145.js | 4 ++-- .../src/components/report-components/AttackReport.js | 5 +++-- 14 files changed, 33 insertions(+), 27 deletions(-) diff --git a/monkey/infection_monkey/monkey.py b/monkey/infection_monkey/monkey.py index c6c5ee8b5..37ac2c434 100644 --- a/monkey/infection_monkey/monkey.py +++ b/monkey/infection_monkey/monkey.py @@ -243,10 +243,8 @@ class InfectionMonkey(object): @staticmethod def self_delete(): - if utils.remove_monkey_dir(): - T1107Telem(ScanStatus.USED, utils.get_monkey_dir_path()).send() - else: - T1107Telem(ScanStatus.SCANNED, utils.get_monkey_dir_path()).send() + status = ScanStatus.USED if utils.remove_monkey_dir() else ScanStatus.SCANNED + T1107Telem(status, utils.get_monkey_dir_path()).send() if WormConfiguration.self_delete_in_cleanup \ and -1 == sys.executable.find('python'): diff --git a/monkey/monkey_island/cc/services/attack/attack_report.py b/monkey/monkey_island/cc/services/attack/attack_report.py index ff038c092..ce918aa60 100644 --- a/monkey/monkey_island/cc/services/attack/attack_report.py +++ b/monkey/monkey_island/cc/services/attack/attack_report.py @@ -58,12 +58,12 @@ class AttackReportService: Gets latest report (by retrieving it from db or generating a new one). :return: report dict. """ - return AttackReportService.generate_new_report() if AttackReportService.is_report_generated(): telem_time = AttackReportService.get_latest_attack_telem_time() latest_report = mongo.db.attack_report.find_one({'name': REPORT_NAME}) if telem_time and latest_report['latest_telem_time'] and telem_time == latest_report['latest_telem_time']: return latest_report + return AttackReportService.generate_new_report() @staticmethod def is_report_generated(): diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1107.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1107.py index fd9f1ad10..9448c2e6b 100644 --- a/monkey/monkey_island/cc/services/attack/technique_reports/T1107.py +++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1107.py @@ -7,7 +7,7 @@ __author__ = "VakarisZ" class T1107(AttackTechnique): tech_id = "T1107" unscanned_msg = "" - scanned_msg = "Monkey tried to delete files on a system in the network but failed." + scanned_msg = "Monkey tried to delete files on systems in the network, but failed." used_msg = "Monkey successfully deleted files on systems in the network." query = [{'$match': {'telem_category': 'attack', 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 81b7dd6bf..15ce5ac19 100644 --- a/monkey/monkey_island/cc/services/attack/technique_reports/__init__.py +++ b/monkey/monkey_island/cc/services/attack/technique_reports/__init__.py @@ -55,13 +55,13 @@ class AttackTechnique(object): if mongo.db.telemetry.find_one({'telem_category': 'attack', 'data.status': ScanStatus.USED.value, 'data.technique': cls.tech_id}): - return ScanStatus.USED + return ScanStatus.USED.value elif mongo.db.telemetry.find_one({'telem_category': 'attack', 'data.status': ScanStatus.SCANNED.value, 'data.technique': cls.tech_id}): - return ScanStatus.SCANNED + return ScanStatus.SCANNED.value else: - return ScanStatus.UNSCANNED + return ScanStatus.UNSCANNED.value @classmethod def get_message_and_status(cls, status): @@ -70,7 +70,7 @@ class AttackTechnique(object): :param status: Enum type value from common/attack_utils.py :return: Dict with message and status """ - return {'message': cls.get_message_by_status(status), 'status': status.name} + return {'message': cls.get_message_by_status(status), 'status': status.value} @classmethod def get_message_by_status(cls, status): @@ -102,7 +102,7 @@ class AttackTechnique(object): data = {} status = cls.technique_status() title = cls.technique_title() - data.update({'status': status.name, + data.update({'status': status, 'title': title, 'message': cls.get_message_by_status(status)}) 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 1060f4b2d..b620e82d7 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 @@ -19,3 +19,9 @@ export function renderMachineFromSystemData(data) { }); return machineStr + ")" } + +export const scanStatus = { + UNSCANNED: 0, + SCANNED: 1, + USED: 2 +}; diff --git a/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1003.js b/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1003.js index d7783714a..208840cf3 100644 --- a/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1003.js +++ b/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1003.js @@ -2,6 +2,7 @@ import React from 'react'; import '../../../styles/Collapse.scss' import '../../report-components/StolenPasswords' import StolenPasswordsComponent from "../../report-components/StolenPasswords"; +import {scanStatus} from "./Helpers" class T1003 extends React.Component { @@ -15,7 +16,7 @@ class T1003 extends React.Component {
{this.props.data.message}

- {this.props.data.status === 'USED' ? + {this.props.data.status === scanStatus.USED ? : ""}
diff --git a/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1059.js b/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1059.js index 57d5bcb2c..8d5585829 100644 --- a/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1059.js +++ b/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1059.js @@ -1,7 +1,7 @@ import React from 'react'; import '../../../styles/Collapse.scss' import ReactTable from "react-table"; -import { renderMachine } from "./Helpers" +import { renderMachine, scanStatus } from "./Helpers" class T1059 extends React.Component { @@ -25,7 +25,7 @@ class T1059 extends React.Component {
{this.props.data.message}

- {this.props.data.status === 'USED' ? + {this.props.data.status === scanStatus.USED ?
{this.props.data.message}

- {this.props.data.status === 'USED' ? + {this.props.data.status !== scanStatus.UNSCANNED ?
{this.props.data.message}

- {this.props.data.status === 'USED' ? + {this.props.data.status === scanStatus.USED ?
{this.props.data.message}

- {this.props.data.status === 'USED' ? + {this.props.data.status === scanStatus.USED ?
{this.props.data.message}

- {(this.props.data.status === 'SCANNED' || this.props.data.status === 'USED') ? + {this.props.data.status !== scanStatus.UNSCANNED ?
{this.props.data.message}

- {this.props.data.status === 'USED' ? + {this.props.data.status === scanStatus.USED ? Date: Mon, 8 Jul 2019 14:51:57 +0300 Subject: [PATCH 07/11] small fixes --- .../cc/services/attack/technique_reports/__init__.py | 4 ++-- .../cc/ui/src/components/attack/techniques/T1107.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) 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 15ce5ac19..d765b5f09 100644 --- a/monkey/monkey_island/cc/services/attack/technique_reports/__init__.py +++ b/monkey/monkey_island/cc/services/attack/technique_reports/__init__.py @@ -50,7 +50,7 @@ class AttackTechnique(object): def technique_status(cls): """ Gets the status of a certain attack technique. - :return: ScanStatus Enum object + :return: ScanStatus numeric value """ if mongo.db.telemetry.find_one({'telem_category': 'attack', 'data.status': ScanStatus.USED.value, @@ -97,7 +97,7 @@ class AttackTechnique(object): def get_tech_base_data(cls): """ Gathers basic attack technique data into a dict. - :return: dict E.g. {'message': 'Brute force used', 'status': 'Used', 'title': 'T1110 Brute force'} + :return: dict E.g. {'message': 'Brute force used', 'status': 2, 'title': 'T1110 Brute force'} """ data = {} status = cls.technique_status() diff --git a/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1107.js b/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1107.js index 73b512706..56edd685a 100644 --- a/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1107.js +++ b/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1107.js @@ -11,7 +11,7 @@ class T1107 extends React.Component { } static renderDelete(status){ - if(status === 2){ + if(status === scanStatus.USED){ return Yes } else { return No From f5ed7e742223d7549b0e20e74a0facc69c36fa20 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Mon, 8 Jul 2019 15:17:26 +0300 Subject: [PATCH 08/11] PR fix (smb exploiters sends telem if service execution failed) --- monkey/infection_monkey/exploit/smbexec.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/monkey/infection_monkey/exploit/smbexec.py b/monkey/infection_monkey/exploit/smbexec.py index ee865e533..6f1667c64 100644 --- a/monkey/infection_monkey/exploit/smbexec.py +++ b/monkey/infection_monkey/exploit/smbexec.py @@ -131,10 +131,12 @@ class SmbExploiter(HostExploiter): resp = scmr.hRCreateServiceW(scmr_rpc, sc_handle, self._config.smb_service_name, self._config.smb_service_name, lpBinaryPathName=cmdline) service = resp['lpServiceHandle'] - T1035Telem(ScanStatus.USED, "SMB exploiter ran the monkey by creating a service via MS-SCMR.").send() try: scmr.hRStartServiceW(scmr_rpc, service) + T1035Telem(ScanStatus.USED, "SMB exploiter ran the monkey by creating a service via MS-SCMR.").send() except: + T1035Telem(ScanStatus.SCANNED, + "SMB exploiter failed to run the monkey by creating a service via MS-SCMR.").send() pass scmr.hRDeleteService(scmr_rpc, service) scmr.hRCloseServiceHandle(scmr_rpc, service) From c093f0509af8ee2f32157c171908ac23db875cfd Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Mon, 8 Jul 2019 17:22:28 +0300 Subject: [PATCH 09/11] renames exploit_host to _exploit_host in weblogic exploiter --- monkey/infection_monkey/exploit/weblogic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monkey/infection_monkey/exploit/weblogic.py b/monkey/infection_monkey/exploit/weblogic.py index 620657fb6..87ea58477 100644 --- a/monkey/infection_monkey/exploit/weblogic.py +++ b/monkey/infection_monkey/exploit/weblogic.py @@ -36,7 +36,7 @@ class WebLogicExploiter(HostExploiter): _TARGET_OS_TYPE = ['linux', 'windows'] _EXPLOITED_SERVICE = 'Weblogic' - def exploit_host(self): + def _exploit_host(self): exploiters = [WebLogic20192725, WebLogic201710271] for exploiter in exploiters: if exploiter(self.host).exploit_host(): From 25efdef7d3359b28c0a20b613514227bb12a89fc Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Mon, 8 Jul 2019 17:50:48 +0300 Subject: [PATCH 10/11] Changes report components to use ScanStatus value --- .../cc/services/attack/technique_reports/T1003.py | 4 ++-- .../cc/services/attack/technique_reports/T1059.py | 4 ++-- .../cc/services/attack/technique_reports/T1065.py | 2 +- .../cc/services/attack/technique_reports/T1075.py | 6 +++--- .../cc/services/attack/technique_reports/T1082.py | 4 ++-- .../cc/services/attack/technique_reports/T1086.py | 4 ++-- .../cc/services/attack/technique_reports/T1110.py | 6 +++--- .../cc/services/attack/technique_reports/T1145.py | 4 ++-- .../cc/services/attack/technique_reports/T1210.py | 6 +++--- .../cc/services/attack/technique_reports/__init__.py | 8 ++++---- 10 files changed, 24 insertions(+), 24 deletions(-) diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1003.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1003.py index a92758cbc..d9aaeaa47 100644 --- a/monkey/monkey_island/cc/services/attack/technique_reports/T1003.py +++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1003.py @@ -20,8 +20,8 @@ class T1003(AttackTechnique): def get_report_data(): data = {'title': T1003.technique_title()} if mongo.db.telemetry.count_documents(T1003.query): - status = ScanStatus.USED + status = ScanStatus.USED.value else: - status = ScanStatus.UNSCANNED + status = ScanStatus.UNSCANNED.value data.update(T1003.get_message_and_status(status)) return data diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1059.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1059.py index 328c11112..ef15dd9fd 100644 --- a/monkey/monkey_island/cc/services/attack/technique_reports/T1059.py +++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1059.py @@ -27,8 +27,8 @@ class T1059(AttackTechnique): cmd_data = list(mongo.db.telemetry.aggregate(T1059.query)) data = {'title': T1059.technique_title(), 'cmds': cmd_data} if cmd_data: - status = ScanStatus.USED + status = ScanStatus.USED.value else: - status = ScanStatus.UNSCANNED + status = ScanStatus.UNSCANNED.value data.update(T1059.get_message_and_status(status)) return data diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1065.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1065.py index fd34e80e9..7d8ceb93e 100644 --- a/monkey/monkey_island/cc/services/attack/technique_reports/T1065.py +++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1065.py @@ -17,4 +17,4 @@ class T1065(AttackTechnique): def get_report_data(): port = ConfigService.get_config_value(['cnc', 'servers', 'current_server']).split(':')[1] T1065.used_msg = T1065.message % port - return T1065.get_base_data_by_status(ScanStatus.USED) + return T1065.get_base_data_by_status(ScanStatus.USED.value) diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1075.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1075.py index fa65a66c2..623d157ae 100644 --- a/monkey/monkey_island/cc/services/attack/technique_reports/T1075.py +++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1075.py @@ -35,10 +35,10 @@ class T1075(AttackTechnique): successful_logins = list(mongo.db.telemetry.aggregate(T1075.query)) data.update({'successful_logins': successful_logins}) if successful_logins: - status = ScanStatus.USED + status = ScanStatus.USED.value elif mongo.db.telemetry.count_documents(T1075.login_attempt_query): - status = ScanStatus.SCANNED + status = ScanStatus.SCANNED.value else: - status = ScanStatus.UNSCANNED + status = ScanStatus.UNSCANNED.value data.update(T1075.get_message_and_status(status)) return data 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 79020c048..f59b63286 100644 --- a/monkey/monkey_island/cc/services/attack/technique_reports/T1082.py +++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1082.py @@ -40,8 +40,8 @@ class T1082(AttackTechnique): system_info = list(mongo.db.telemetry.aggregate(T1082.query)) data.update({'system_info': system_info}) if system_info: - status = ScanStatus.USED + status = ScanStatus.USED.value else: - status = ScanStatus.UNSCANNED + status = ScanStatus.UNSCANNED.value data.update(T1082.get_message_and_status(status)) return data diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1086.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1086.py index 4114047c5..dd5d64d25 100644 --- a/monkey/monkey_island/cc/services/attack/technique_reports/T1086.py +++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1086.py @@ -29,8 +29,8 @@ class T1086(AttackTechnique): cmd_data = list(mongo.db.telemetry.aggregate(T1086.query)) data = {'title': T1086.technique_title(), 'cmds': cmd_data} if cmd_data: - status = ScanStatus.USED + status = ScanStatus.USED.value else: - status = ScanStatus.UNSCANNED + status = ScanStatus.UNSCANNED.value data.update(T1086.get_message_and_status(status)) return 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 91d785bc3..b918de7f4 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,11 @@ class T1110(AttackTechnique): result['successful_creds'].append(T1110.parse_creds(attempt)) if succeeded: - status = ScanStatus.USED + status = ScanStatus.USED.value elif attempts: - status = ScanStatus.SCANNED + status = ScanStatus.SCANNED.value else: - status = ScanStatus.UNSCANNED + status = ScanStatus.UNSCANNED.value 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']] 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 9b525873f..89ac44117 100644 --- a/monkey/monkey_island/cc/services/attack/technique_reports/T1145.py +++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1145.py @@ -23,9 +23,9 @@ class T1145(AttackTechnique): ssh_info = list(mongo.db.telemetry.aggregate(T1145.query)) if ssh_info: - status = ScanStatus.USED + status = ScanStatus.USED.value else: - status = ScanStatus.UNSCANNED + status = ScanStatus.UNSCANNED.value 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/T1210.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1210.py index 6e89bc6ab..eeae183f5 100644 --- a/monkey/monkey_island/cc/services/attack/technique_reports/T1210.py +++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1210.py @@ -18,11 +18,11 @@ class T1210(AttackTechnique): scanned_services = T1210.get_scanned_services() exploited_services = T1210.get_exploited_services() if exploited_services: - status = ScanStatus.USED + status = ScanStatus.USED.value elif scanned_services: - status = ScanStatus.SCANNED + status = ScanStatus.SCANNED.value else: - status = ScanStatus.UNSCANNED + status = ScanStatus.UNSCANNED.value data.update(T1210.get_message_and_status(status)) data.update({'scanned_services': scanned_services, 'exploited_services': exploited_services}) 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 d765b5f09..a18444b4e 100644 --- a/monkey/monkey_island/cc/services/attack/technique_reports/__init__.py +++ b/monkey/monkey_island/cc/services/attack/technique_reports/__init__.py @@ -67,7 +67,7 @@ class AttackTechnique(object): def get_message_and_status(cls, status): """ Returns a dict with attack technique's message and status. - :param status: Enum type value from common/attack_utils.py + :param status: Enum from common/attack_utils.py integer value :return: Dict with message and status """ return {'message': cls.get_message_by_status(status), 'status': status.value} @@ -76,12 +76,12 @@ class AttackTechnique(object): def get_message_by_status(cls, status): """ Picks a message to return based on status. - :param status: Enum type value from common/attack_utils.py + :param status: Enum from common/attack_utils.py integer value :return: message string """ - if status == ScanStatus.UNSCANNED: + if status == ScanStatus.UNSCANNED.value: return cls.unscanned_msg - elif status == ScanStatus.SCANNED: + elif status == ScanStatus.SCANNED.value: return cls.scanned_msg else: return cls.used_msg From 8c9787f2c70297bff0ade33b443aaa0d79b0c635 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Mon, 8 Jul 2019 17:50:48 +0300 Subject: [PATCH 11/11] Changes report components to use ScanStatus value --- .../cc/services/attack/technique_reports/T1003.py | 4 ++-- .../cc/services/attack/technique_reports/T1059.py | 4 ++-- .../cc/services/attack/technique_reports/T1065.py | 2 +- .../cc/services/attack/technique_reports/T1075.py | 6 +++--- .../cc/services/attack/technique_reports/T1082.py | 4 ++-- .../cc/services/attack/technique_reports/T1086.py | 4 ++-- .../cc/services/attack/technique_reports/T1110.py | 6 +++--- .../cc/services/attack/technique_reports/T1145.py | 4 ++-- .../cc/services/attack/technique_reports/T1210.py | 6 +++--- .../cc/services/attack/technique_reports/__init__.py | 10 +++++----- 10 files changed, 25 insertions(+), 25 deletions(-) diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1003.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1003.py index a92758cbc..d9aaeaa47 100644 --- a/monkey/monkey_island/cc/services/attack/technique_reports/T1003.py +++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1003.py @@ -20,8 +20,8 @@ class T1003(AttackTechnique): def get_report_data(): data = {'title': T1003.technique_title()} if mongo.db.telemetry.count_documents(T1003.query): - status = ScanStatus.USED + status = ScanStatus.USED.value else: - status = ScanStatus.UNSCANNED + status = ScanStatus.UNSCANNED.value data.update(T1003.get_message_and_status(status)) return data diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1059.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1059.py index 328c11112..ef15dd9fd 100644 --- a/monkey/monkey_island/cc/services/attack/technique_reports/T1059.py +++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1059.py @@ -27,8 +27,8 @@ class T1059(AttackTechnique): cmd_data = list(mongo.db.telemetry.aggregate(T1059.query)) data = {'title': T1059.technique_title(), 'cmds': cmd_data} if cmd_data: - status = ScanStatus.USED + status = ScanStatus.USED.value else: - status = ScanStatus.UNSCANNED + status = ScanStatus.UNSCANNED.value data.update(T1059.get_message_and_status(status)) return data diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1065.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1065.py index fd34e80e9..7d8ceb93e 100644 --- a/monkey/monkey_island/cc/services/attack/technique_reports/T1065.py +++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1065.py @@ -17,4 +17,4 @@ class T1065(AttackTechnique): def get_report_data(): port = ConfigService.get_config_value(['cnc', 'servers', 'current_server']).split(':')[1] T1065.used_msg = T1065.message % port - return T1065.get_base_data_by_status(ScanStatus.USED) + return T1065.get_base_data_by_status(ScanStatus.USED.value) diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1075.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1075.py index fa65a66c2..623d157ae 100644 --- a/monkey/monkey_island/cc/services/attack/technique_reports/T1075.py +++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1075.py @@ -35,10 +35,10 @@ class T1075(AttackTechnique): successful_logins = list(mongo.db.telemetry.aggregate(T1075.query)) data.update({'successful_logins': successful_logins}) if successful_logins: - status = ScanStatus.USED + status = ScanStatus.USED.value elif mongo.db.telemetry.count_documents(T1075.login_attempt_query): - status = ScanStatus.SCANNED + status = ScanStatus.SCANNED.value else: - status = ScanStatus.UNSCANNED + status = ScanStatus.UNSCANNED.value data.update(T1075.get_message_and_status(status)) return data 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 79020c048..f59b63286 100644 --- a/monkey/monkey_island/cc/services/attack/technique_reports/T1082.py +++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1082.py @@ -40,8 +40,8 @@ class T1082(AttackTechnique): system_info = list(mongo.db.telemetry.aggregate(T1082.query)) data.update({'system_info': system_info}) if system_info: - status = ScanStatus.USED + status = ScanStatus.USED.value else: - status = ScanStatus.UNSCANNED + status = ScanStatus.UNSCANNED.value data.update(T1082.get_message_and_status(status)) return data diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1086.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1086.py index 4114047c5..dd5d64d25 100644 --- a/monkey/monkey_island/cc/services/attack/technique_reports/T1086.py +++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1086.py @@ -29,8 +29,8 @@ class T1086(AttackTechnique): cmd_data = list(mongo.db.telemetry.aggregate(T1086.query)) data = {'title': T1086.technique_title(), 'cmds': cmd_data} if cmd_data: - status = ScanStatus.USED + status = ScanStatus.USED.value else: - status = ScanStatus.UNSCANNED + status = ScanStatus.UNSCANNED.value data.update(T1086.get_message_and_status(status)) return 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 91d785bc3..b918de7f4 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,11 @@ class T1110(AttackTechnique): result['successful_creds'].append(T1110.parse_creds(attempt)) if succeeded: - status = ScanStatus.USED + status = ScanStatus.USED.value elif attempts: - status = ScanStatus.SCANNED + status = ScanStatus.SCANNED.value else: - status = ScanStatus.UNSCANNED + status = ScanStatus.UNSCANNED.value 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']] 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 9b525873f..89ac44117 100644 --- a/monkey/monkey_island/cc/services/attack/technique_reports/T1145.py +++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1145.py @@ -23,9 +23,9 @@ class T1145(AttackTechnique): ssh_info = list(mongo.db.telemetry.aggregate(T1145.query)) if ssh_info: - status = ScanStatus.USED + status = ScanStatus.USED.value else: - status = ScanStatus.UNSCANNED + status = ScanStatus.UNSCANNED.value 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/T1210.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1210.py index 6e89bc6ab..eeae183f5 100644 --- a/monkey/monkey_island/cc/services/attack/technique_reports/T1210.py +++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1210.py @@ -18,11 +18,11 @@ class T1210(AttackTechnique): scanned_services = T1210.get_scanned_services() exploited_services = T1210.get_exploited_services() if exploited_services: - status = ScanStatus.USED + status = ScanStatus.USED.value elif scanned_services: - status = ScanStatus.SCANNED + status = ScanStatus.SCANNED.value else: - status = ScanStatus.UNSCANNED + status = ScanStatus.UNSCANNED.value data.update(T1210.get_message_and_status(status)) data.update({'scanned_services': scanned_services, 'exploited_services': exploited_services}) 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 d765b5f09..3e92417d3 100644 --- a/monkey/monkey_island/cc/services/attack/technique_reports/__init__.py +++ b/monkey/monkey_island/cc/services/attack/technique_reports/__init__.py @@ -67,21 +67,21 @@ class AttackTechnique(object): def get_message_and_status(cls, status): """ Returns a dict with attack technique's message and status. - :param status: Enum type value from common/attack_utils.py + :param status: Enum from common/attack_utils.py integer value :return: Dict with message and status """ - return {'message': cls.get_message_by_status(status), 'status': status.value} + return {'message': cls.get_message_by_status(status), 'status': status} @classmethod def get_message_by_status(cls, status): """ Picks a message to return based on status. - :param status: Enum type value from common/attack_utils.py + :param status: Enum from common/attack_utils.py integer value :return: message string """ - if status == ScanStatus.UNSCANNED: + if status == ScanStatus.UNSCANNED.value: return cls.unscanned_msg - elif status == ScanStatus.SCANNED: + elif status == ScanStatus.SCANNED.value: return cls.scanned_msg else: return cls.used_msg