This commit is contained in:
VakarisZ 2019-07-15 15:58:22 +03:00
parent 526a235c8e
commit 30c7b99e95
10 changed files with 57 additions and 23 deletions

View File

@ -10,6 +10,13 @@ class ScanStatus(Enum):
USED = 2 USED = 2
class UsageEnum(Enum):
SMB = {ScanStatus.USED.value: "SMB exploiter ran the monkey by creating a service via MS-SCMR.",
ScanStatus.SCANNED.value: "SMB exploiter failed to run the monkey by creating a service via MS-SCMR."}
MIMIKATZ = {ScanStatus.USED.value: "Windows module loader was used to load Mimikatz DLL.",
ScanStatus.SCANNED.value: "Monkey tried to load Mimikatz DLL, but failed."}
# Dict that describes what BITS job was used for # Dict that describes what BITS job was used for
BITS_UPLOAD_STRING = "BITS job was used to upload monkey to a remote system." BITS_UPLOAD_STRING = "BITS job was used to upload monkey to a remote system."

View File

@ -11,7 +11,7 @@ from infection_monkey.network.tools import check_tcp_port
from infection_monkey.exploit.tools import build_monkey_commandline from infection_monkey.exploit.tools import build_monkey_commandline
from common.utils.exploit_enum import ExploitType from common.utils.exploit_enum import ExploitType
from infection_monkey.telemetry.attack.t1035_telem import T1035Telem from infection_monkey.telemetry.attack.t1035_telem import T1035Telem
from common.utils.attack_utils import ScanStatus from common.utils.attack_utils import ScanStatus, UsageEnum
LOG = getLogger(__name__) LOG = getLogger(__name__)
@ -133,11 +133,11 @@ class SmbExploiter(HostExploiter):
service = resp['lpServiceHandle'] service = resp['lpServiceHandle']
try: try:
scmr.hRStartServiceW(scmr_rpc, service) scmr.hRStartServiceW(scmr_rpc, service)
T1035Telem(ScanStatus.USED, "SMB exploiter ran the monkey by creating a service via MS-SCMR.").send() status = ScanStatus.USED
except: except:
T1035Telem(ScanStatus.SCANNED, status = ScanStatus.SCANNED
"SMB exploiter failed to run the monkey by creating a service via MS-SCMR.").send()
pass pass
T1035Telem(status, UsageEnum.SMB.name).send()
scmr.hRDeleteService(scmr_rpc, service) scmr.hRDeleteService(scmr_rpc, service)
scmr.hRCloseServiceHandle(scmr_rpc, service) scmr.hRCloseServiceHandle(scmr_rpc, service)

View File

@ -5,7 +5,7 @@ import socket
import zipfile import zipfile
import infection_monkey.config import infection_monkey.config
from common.utils.attack_utils import ScanStatus from common.utils.attack_utils import ScanStatus, UsageEnum
from infection_monkey.telemetry.attack.t1129_telem import T1129Telem from infection_monkey.telemetry.attack.t1129_telem import T1129Telem
from infection_monkey.pyinstaller_utils import get_binary_file_path, get_binaries_dir_path from infection_monkey.pyinstaller_utils import get_binary_file_path, get_binaries_dir_path
@ -50,10 +50,11 @@ class MimikatzCollector(object):
self._get = get_proto(("get", self._dll)) self._get = get_proto(("get", self._dll))
self._get_text_output_proto = get_text_output_proto(("getTextOutput", self._dll)) self._get_text_output_proto = get_text_output_proto(("getTextOutput", self._dll))
self._isInit = True self._isInit = True
T1129Telem(ScanStatus.USED, "Windows module loader was used to load Mimikatz DLL.").send() status = ScanStatus.USED
except Exception: except Exception:
LOG.exception("Error initializing mimikatz collector") LOG.exception("Error initializing mimikatz collector")
T1129Telem(ScanStatus.SCANNED, "Monkey tried to load Mimikatz DLL, but failed.").send() status = ScanStatus.SCANNED
T1129Telem(status, UsageEnum.MIMIKATZ.name).send()
def get_logon_info(self): def get_logon_info(self):
""" """

View File

@ -6,6 +6,6 @@ class T1035Telem(UsageTelem):
""" """
T1035 telemetry. T1035 telemetry.
:param status: ScanStatus of technique :param status: ScanStatus of technique
:param usage: Usage string :param usage: Enum name of UsageEnum
""" """
super(T1035Telem, self).__init__('T1035', status, usage) super(T1035Telem, self).__init__('T1035', status, usage)

View File

@ -6,6 +6,6 @@ class T1129Telem(UsageTelem):
""" """
T1129 telemetry. T1129 telemetry.
:param status: ScanStatus of technique :param status: ScanStatus of technique
:param usage: Usage string :param usage: Enum name of UsageEnum
""" """
super(T1129Telem, self).__init__("T1129", status, usage) super(T1129Telem, self).__init__("T1129", status, usage)

View File

@ -5,9 +5,9 @@ class UsageTelem(AttackTelem):
def __init__(self, technique, status, usage): def __init__(self, technique, status, usage):
""" """
T1035 telemetry. :param technique: Id of technique
:param status: ScanStatus of technique :param status: ScanStatus of technique
:param usage: Usage string :param usage: Enum name of UsageEnum
""" """
super(UsageTelem, self).__init__(technique, status) super(UsageTelem, self).__init__(technique, status)
self.usage = usage self.usage = usage

View File

@ -1,10 +1,10 @@
from monkey_island.cc.database import mongo from monkey_island.cc.database import mongo
from monkey_island.cc.services.attack.technique_reports import AttackTechnique from monkey_island.cc.services.attack.technique_reports import UsageTechnique
__author__ = "VakarisZ" __author__ = "VakarisZ"
class T1035(AttackTechnique): class T1035(UsageTechnique):
tech_id = "T1035" tech_id = "T1035"
unscanned_msg = "Monkey didn't try to interact with Windows services." unscanned_msg = "Monkey didn't try to interact with Windows services."
scanned_msg = "Monkey tried to interact with Windows services, but failed." scanned_msg = "Monkey tried to interact with Windows services, but failed."
@ -13,5 +13,7 @@ class T1035(AttackTechnique):
@staticmethod @staticmethod
def get_report_data(): def get_report_data():
data = T1035.get_tech_base_data() data = T1035.get_tech_base_data()
data.update({'services': list(mongo.db.telemetry.aggregate(T1035.get_usage_query()))}) services = list(mongo.db.telemetry.aggregate(T1035.get_usage_query()))
services = list(map(T1035.parse_usages, services))
data.update({'services': services})
return data return data

View File

@ -1,10 +1,10 @@
from monkey_island.cc.database import mongo from monkey_island.cc.database import mongo
from monkey_island.cc.services.attack.technique_reports import AttackTechnique from monkey_island.cc.services.attack.technique_reports import UsageTechnique
__author__ = "VakarisZ" __author__ = "VakarisZ"
class T1129(AttackTechnique): class T1129(UsageTechnique):
tech_id = "T1129" tech_id = "T1129"
unscanned_msg = "Monkey didn't try to load any DLL's." unscanned_msg = "Monkey didn't try to load any DLL's."
scanned_msg = "Monkey tried to load DLL's, but failed." scanned_msg = "Monkey tried to load DLL's, but failed."
@ -13,5 +13,7 @@ class T1129(AttackTechnique):
@staticmethod @staticmethod
def get_report_data(): def get_report_data():
data = T1129.get_tech_base_data() data = T1129.get_tech_base_data()
data.update({'dlls': list(mongo.db.telemetry.aggregate(T1129.get_usage_query()))}) dlls = list(mongo.db.telemetry.aggregate(T1129.get_usage_query()))
dlls = list(map(T1129.parse_usages, dlls))
data.update({'dlls': dlls})
return data return data

View File

@ -1,10 +1,13 @@
import abc import abc
import logging
from monkey_island.cc.database import mongo from monkey_island.cc.database import mongo
from common.utils.attack_utils import ScanStatus from common.utils.attack_utils import ScanStatus, UsageEnum
from monkey_island.cc.services.attack.attack_config import AttackConfig from monkey_island.cc.services.attack.attack_config import AttackConfig
from common.utils.code_utils import abstractstatic from common.utils.code_utils import abstractstatic
logger = logging.getLogger(__name__)
class AttackTechnique(object): class AttackTechnique(object):
""" Abstract class for ATT&CK report components """ """ Abstract class for ATT&CK report components """
@ -113,6 +116,24 @@ class AttackTechnique(object):
data.update({'title': cls.technique_title()}) data.update({'title': cls.technique_title()})
return data return data
class UsageTechnique(AttackTechnique):
__metaclass__ = abc.ABCMeta
@staticmethod
def parse_usages(usage):
"""
Parses data from database and translates usage enums into strings
:param usage:
:return:
"""
try:
usage['usage'] = UsageEnum[usage['usage']].value[usage['status']]
except KeyError:
logger.error("Error translating usage enum. into string. "
"Check if usage enum field exists and covers all telem. statuses.")
return usage
@classmethod @classmethod
def get_usage_query(cls): def get_usage_query(cls):
""" """
@ -131,4 +152,5 @@ class AttackTechnique(object):
{'$addFields': {'_id': 0, {'$addFields': {'_id': 0,
'machine': {'hostname': '$monkey.hostname', 'ips': '$monkey.ip_addresses'}, 'machine': {'hostname': '$monkey.hostname', 'ips': '$monkey.ip_addresses'},
'monkey': 0}}, 'monkey': 0}},
{'$group': {'_id': {'machine': '$machine', 'status': '$status', 'usage': '$usage'}}}] {'$group': {'_id': {'machine': '$machine', 'status': '$status', 'usage': '$usage'}}},
{"$replaceRoot": {"newRoot": "$_id"}}]

View File

@ -27,12 +27,12 @@ export function getUsageColumns() {
columns: [ columns: [
{Header: 'Machine', {Header: 'Machine',
id: 'machine', id: 'machine',
accessor: x => renderMachineFromSystemData(x._id.machine), accessor: x => renderMachineFromSystemData(x.machine),
style: { 'whiteSpace': 'unset' }, style: { 'whiteSpace': 'unset' },
width: 300}, width: 300},
{Header: 'Usage', {Header: 'Usage',
id: 'usage', id: 'usage',
accessor: x => x._id.usage, accessor: x => x.usage,
style: { 'whiteSpace': 'unset' }}] style: { 'whiteSpace': 'unset' }}]
}])} }])}