From 9415f6e73c6996f1d3dc22e3a629cd1c0c73928f Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Mon, 1 Jul 2019 16:52:57 +0300 Subject: [PATCH] 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');