Merge pull request #1483 from guardicore/incorrect-attack-report-msgs

Fix incorrect ATT&CK report messages
This commit is contained in:
Mike Salvatore 2021-09-28 07:24:17 -04:00 committed by GitHub
commit 0839f04b1d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
49 changed files with 400 additions and 104 deletions

View File

@ -15,9 +15,6 @@
},
{
"type": "snippet",
"path": "monkey/monkey_island/cc/services/config_schema/definitions/post_breach_actions.py",
"comments": [],
"firstLineNumber": 56,
"lines": [
" \"Removes the file afterwards.\",",
" \"attack_techniques\": [\"T1166\"],",
@ -26,7 +23,7 @@
"+ # Swimmer: ADD DETAILS HERE!",
"* \"type\": \"string\",",
"* \"enum\": [\"ScheduleJobs\"],",
"* \"title\": \"Job scheduling\",",
"* \"title\": \"Job Scheduling\",",
"* \"safe\": True,",
"* \"info\": \"Attempts to create a scheduled job on the system and remove it.\",",
"* \"attack_techniques\": [\"T1168\", \"T1053\"],",
@ -34,7 +31,10 @@
" {",
" \"type\": \"string\",",
" \"enum\": [\"Timestomping\"],"
]
],
"firstLineNumber": 52,
"path": "monkey/monkey_island/cc/services/config_schema/definitions/post_breach_actions.py",
"comments": []
},
{
"type": "text",
@ -42,11 +42,11 @@
}
],
"symbols": {},
"file_version": "2.0.1",
"file_version": "2.0.3",
"meta": {
"app_version": "0.4.1-1",
"app_version": "0.5.7-0",
"file_blobs": {
"monkey/monkey_island/cc/services/config_schema/definitions/post_breach_actions.py": "ea9b18aba7f71da12c9c82ac39d8a0cf2c472a9c"
"monkey/monkey_island/cc/services/config_schema/definitions/post_breach_actions.py": "7d62ac36e875ca3c249d808250cb3268e4d3d68d"
}
}
}

View File

@ -77,10 +77,9 @@
" \"attack_techniques\": [\"T1082\"],",
" },",
"* {",
"+ # SWIMMER: Collector config goes here. Tip: Hostname collection relates to the T1082 and T1016 techniques.",
"* \"type\": \"string\",",
"* \"enum\": [HOSTNAME_COLLECTOR],",
"* \"title\": \"Hostname collector\",",
"* \"title\": \"Hostname Collector\",",
"* \"safe\": True,",
"* \"info\": \"Collects machine's hostname.\",",
"* \"attack_techniques\": [\"T1082\", \"T1016\"],",
@ -110,7 +109,7 @@
"type": "snippet",
"path": "monkey/monkey_island/cc/services/config_schema/monkey.py",
"comments": [],
"firstLineNumber": 92,
"firstLineNumber": 91,
"lines": [
" \"default\": [",
" ENVIRONMENT_COLLECTOR,",
@ -195,14 +194,14 @@
}
],
"symbols": {},
"file_version": "2.0.1",
"file_version": "2.0.3",
"meta": {
"app_version": "0.4.4-0",
"app_version": "0.5.7-0",
"file_blobs": {
"monkey/common/common_consts/system_info_collectors_names.py": "175a054e1408805a4cebbe27e2f9616db40988cf",
"monkey/infection_monkey/system_info/collectors/hostname_collector.py": "0aeecd9fb7bde83cccd4501ec03e0da199ec5fc3",
"monkey/monkey_island/cc/services/config_schema/definitions/system_info_collector_classes.py": "9a4a39050eb088876df4fa629e14faf820e714a0",
"monkey/monkey_island/cc/services/config_schema/monkey.py": "e745da5828c63e975625ac2e9b80ce9626324970",
"monkey/monkey_island/cc/services/config_schema/definitions/system_info_collector_classes.py": "072640352fc9d50fe09752cfc951dab7d99271af",
"monkey/monkey_island/cc/services/config_schema/monkey.py": "da06123a95eebf7f0a68861815ee644bb37c8db6",
"monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/hostname.py": "e2de4519cbd71bba70e81cf3ff61817437d95a21",
"monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/system_info_telemetry_dispatcher.py": "7ce4b6fcfbce0d6cd8a60297213c5be1699b22df"
}

View File

@ -14,6 +14,7 @@ Changelog](https://keepachangelog.com/en/1.0.0/).
### Changed
- The name of the "Communicate as new user" post-breach action to "Communicate
as backdoor user". #1410
- ATT&CK report messages (more accurate now). #1483
### Removed
- Internet access check on agent start. #1402

View File

@ -214,9 +214,10 @@ SCHEMA = {
"value": False,
"necessary": False,
"link": "https://attack.mitre.org/techniques/T1216",
"description": "Adversaries may use scripts signed with "
"trusted certificates to "
"proxy execution of malicious files on Windows systems.",
"description": "Adversaries may use scripts signed with trusted certificates "
"to proxy execution of malicious files on Windows systems. This behavior could "
"be abused by adversaries to execute malicious files that could bypass "
"application control and signature validation on systems.",
},
},
},

View File

@ -6,6 +6,7 @@ from monkey_island.cc.services.reporting.report import ReportService
class T1003(AttackTechnique):
tech_id = "T1003"
relevant_systems = ["Linux", "Windows"]
unscanned_msg = (
"Monkey tried to obtain credentials from systems in the network but didn't "
"find any or failed."

View File

@ -4,6 +4,7 @@ from monkey_island.cc.services.attack.technique_reports import AttackTechnique
class T1005(AttackTechnique):
tech_id = "T1005"
relevant_systems = ["Linux", "Windows"]
unscanned_msg = "Monkey didn't gather any sensitive data from local system."
scanned_msg = ""
used_msg = "Monkey successfully gathered sensitive data from local system."

View File

@ -5,6 +5,7 @@ from monkey_island.cc.services.attack.technique_reports import AttackTechnique
class T1016(AttackTechnique):
tech_id = "T1016"
relevant_systems = ["Linux", "Windows"]
unscanned_msg = "Monkey didn't gather network configurations."
scanned_msg = ""
used_msg = "Monkey gathered network configurations on systems in the network."

View File

@ -5,6 +5,7 @@ from monkey_island.cc.services.attack.technique_reports import AttackTechnique
class T1018(AttackTechnique):
tech_id = "T1018"
relevant_systems = ["Linux", "Windows"]
unscanned_msg = "Monkey didn't find any machines on the network."
scanned_msg = ""
used_msg = "Monkey found machines on the network."

View File

@ -6,6 +6,7 @@ from monkey_island.cc.services.attack.technique_reports.technique_report_tools i
class T1021(AttackTechnique):
tech_id = "T1021"
relevant_systems = ["Linux", "Windows"]
unscanned_msg = "Monkey didn't try to login to any remote services."
scanned_msg = "Monkey tried to login to remote services with valid credentials, but failed."
used_msg = "Monkey successfully logged into remote services on the network."

View File

@ -3,10 +3,8 @@ from monkey_island.cc.services.attack.technique_reports.usage_technique import U
class T1035(UsageTechnique):
tech_id = "T1035"
unscanned_msg = (
"Monkey didn't try to interact with Windows services since it didn't run on "
"any Windows machines."
)
relevant_systems = ["Windows"]
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."

View File

@ -5,6 +5,7 @@ from monkey_island.cc.services.attack.technique_reports import AttackTechnique
class T1041(AttackTechnique):
tech_id = "T1041"
relevant_systems = ["Linux", "Windows"]
unscanned_msg = "Monkey didn't exfiltrate any info through command and control channel."
scanned_msg = ""
used_msg = "Monkey exfiltrated info through command and control channel."

View File

@ -4,9 +4,8 @@ from monkey_island.cc.services.attack.technique_reports.pba_technique import Pos
class T1053(PostBreachTechnique):
tech_id = "T1053"
unscanned_msg = (
"Monkey didn't try scheduling a job on Windows since it didn't run on any Windows machines."
)
scanned_msg = "Monkey tried scheduling a job on the Windows system but failed."
used_msg = "Monkey scheduled a job on the Windows system."
relevant_systems = ["Windows"]
unscanned_msg = "Monkey didn't try scheduling a job on any Windows system."
scanned_msg = "Monkey tried scheduling a job on a Windows system but failed."
used_msg = "Monkey scheduled a job on a Windows system."
pba_names = [POST_BREACH_JOB_SCHEDULING]

View File

@ -5,7 +5,8 @@ from monkey_island.cc.services.attack.technique_reports import AttackTechnique
class T1059(AttackTechnique):
tech_id = "T1059"
unscanned_msg = "Monkey didn't exploit any machines to run commands at."
relevant_systems = ["Linux", "Windows"]
unscanned_msg = "Monkey didn't exploit any machines to run commands on."
scanned_msg = ""
used_msg = "Monkey successfully ran commands on exploited machines in the network."

View File

@ -4,6 +4,7 @@ from monkey_island.cc.services.attack.technique_reports.usage_technique import U
class T1064(UsageTechnique):
tech_id = "T1064"
relevant_systems = ["Linux", "Windows"]
unscanned_msg = "Monkey didn't run scripts or tried to run and failed."
scanned_msg = ""
used_msg = "Monkey ran scripts on machines in the network."

View File

@ -6,6 +6,7 @@ from monkey_island.cc.services.config import ConfigService
class T1065(AttackTechnique):
tech_id = "T1065"
relevant_systems = ["Linux", "Windows"]
unscanned_msg = ""
scanned_msg = ""
used_msg = ""

View File

@ -5,9 +5,8 @@ from monkey_island.cc.services.attack.technique_reports import AttackTechnique
class T1075(AttackTechnique):
tech_id = "T1075"
unscanned_msg = (
"Monkey didn't try to use pass the hash attack since it didn't run on any Windows machines."
)
relevant_systems = ["Windows"]
unscanned_msg = "Monkey didn't try to use pass the hash attack."
scanned_msg = "Monkey tried to use hashes while logging in but didn't succeed."
used_msg = "Monkey successfully used hashed credentials."

View File

@ -5,6 +5,7 @@ from monkey_island.cc.services.attack.technique_reports import AttackTechnique
class T1082(AttackTechnique):
tech_id = "T1082"
relevant_systems = ["Linux", "Windows"]
unscanned_msg = "Monkey didn't gather any system info on the network."
scanned_msg = ""
used_msg = "Monkey gathered system info from machines in the network."

View File

@ -5,9 +5,10 @@ from monkey_island.cc.services.attack.technique_reports import AttackTechnique
class T1086(AttackTechnique):
tech_id = "T1086"
unscanned_msg = "Monkey didn't run powershell since it didn't run on any Windows machines."
relevant_systems = ["Windows"]
unscanned_msg = "Monkey didn't run PowerShell."
scanned_msg = ""
used_msg = "Monkey successfully ran powershell commands on exploited machines in the network."
used_msg = "Monkey successfully ran PowerShell commands on exploited machines in the network."
query = [
{

View File

@ -4,6 +4,7 @@ from monkey_island.cc.services.attack.technique_reports.pba_technique import Pos
class T1087(PostBreachTechnique):
tech_id = "T1087"
relevant_systems = ["Linux", "Windows"]
unscanned_msg = "Monkey didn't try to get a listing of user accounts."
scanned_msg = "Monkey tried to get a listing of user accounts but failed to do so."
used_msg = "Monkey got a listing of user accounts successfully."

View File

@ -5,6 +5,7 @@ from monkey_island.cc.services.attack.technique_reports import AttackTechnique
class T1090(AttackTechnique):
tech_id = "T1090"
relevant_systems = ["Linux", "Windows"]
unscanned_msg = "Monkey didn't use connection proxy."
scanned_msg = ""
used_msg = "Monkey used connection proxy to communicate with machines on the network."

View File

@ -4,6 +4,7 @@ from monkey_island.cc.services.attack.technique_reports.pba_technique import Pos
class T1099(PostBreachTechnique):
tech_id = "T1099"
relevant_systems = ["Linux", "Windows"]
unscanned_msg = "Monkey didn't try changing any file's time attributes."
scanned_msg = "Monkey tried changing a file's time attributes but failed."
used_msg = "Monkey successfully changed a file's time attributes."

View File

@ -4,6 +4,7 @@ from monkey_island.cc.services.attack.technique_reports import AttackTechnique
class T1105(AttackTechnique):
tech_id = "T1105"
relevant_systems = ["Linux", "Windows"]
unscanned_msg = "Monkey didn't try to copy files to any systems."
scanned_msg = "Monkey tried to copy files, but failed."
used_msg = "Monkey successfully copied files to systems on the network."

View File

@ -3,6 +3,7 @@ from monkey_island.cc.services.attack.technique_reports.usage_technique import U
class T1106(UsageTechnique):
tech_id = "T1106"
relevant_systems = ["Windows"]
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."

View File

@ -4,6 +4,7 @@ from monkey_island.cc.services.attack.technique_reports import AttackTechnique
class T1107(AttackTechnique):
tech_id = "T1107"
relevant_systems = ["Linux", "Windows"]
unscanned_msg = ""
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."

View File

@ -6,6 +6,7 @@ from monkey_island.cc.services.attack.technique_reports.technique_report_tools i
class T1110(AttackTechnique):
tech_id = "T1110"
relevant_systems = ["Linux", "Windows"]
unscanned_msg = "Monkey didn't try to brute force any services."
scanned_msg = "Monkey tried to brute force some services, but failed."
used_msg = "Monkey successfully used brute force in the network."

View File

@ -4,6 +4,7 @@ from monkey_island.cc.services.attack.technique_reports.pba_technique import Pos
class T1136(PostBreachTechnique):
tech_id = "T1136"
relevant_systems = ["Linux", "Windows"]
unscanned_msg = "Monkey didn't try creating a new user on the network's systems."
scanned_msg = "Monkey tried creating a new user on the network's systems, but failed."
used_msg = "Monkey created a new user on the network's systems."

View File

@ -5,9 +5,10 @@ from monkey_island.cc.services.attack.technique_reports import AttackTechnique
class T1145(AttackTechnique):
tech_id = "T1145"
unscanned_msg = "Monkey didn't find any shh keys."
relevant_systems = ["Linux", "Windows"]
unscanned_msg = "Monkey didn't find any SSH keys."
scanned_msg = ""
used_msg = "Monkey found ssh keys on machines in the network."
used_msg = "Monkey found SSH keys on machines in the network."
# Gets data about ssh keys found
query = [

View File

@ -4,11 +4,13 @@ from monkey_island.cc.services.attack.technique_reports.pba_technique import Pos
class T1146(PostBreachTechnique):
tech_id = "T1146"
unscanned_msg = (
"Monkey didn't try clearing the command history since it didn't run on any Linux machines."
relevant_systems = ["Linux"]
unscanned_msg = "Monkey didn't try clearing the command history on a Linux system."
scanned_msg = "Monkey tried clearing the command history on a Linux system but failed."
used_msg = (
"Monkey successfully cleared the command history on a Linux system (and then "
"restored it back)."
)
scanned_msg = "Monkey tried clearing the command history but failed."
used_msg = "Monkey successfully cleared the command history (and then restored it back)."
pba_names = [POST_BREACH_CLEAR_CMD_HISTORY]
@staticmethod

View File

@ -4,7 +4,8 @@ from monkey_island.cc.services.attack.technique_reports.pba_technique import Pos
class T1154(PostBreachTechnique):
tech_id = "T1154"
unscanned_msg = "Monkey didn't use the trap command since it didn't run on any Linux machines."
relevant_systems = ["Linux"]
unscanned_msg = "Monkey didn't use the trap command."
scanned_msg = "Monkey tried using the trap command but failed."
used_msg = "Monkey used the trap command successfully."
pba_names = [POST_BREACH_TRAP_COMMAND]

View File

@ -4,9 +4,8 @@ from monkey_island.cc.services.attack.technique_reports.pba_technique import Pos
class T1156(PostBreachTechnique):
tech_id = "T1156"
unscanned_msg = (
"Monkey didn't try modifying bash startup files since it didn't run on any Linux machines."
)
relevant_systems = ["Linux"]
unscanned_msg = "Monkey didn't try modifying bash startup files."
scanned_msg = "Monkey tried modifying bash startup files but failed."
used_msg = "Monkey successfully modified bash startup files."
pba_names = [POST_BREACH_SHELL_STARTUP_FILE_MODIFICATION]

View File

@ -4,6 +4,7 @@ from monkey_island.cc.services.attack.technique_reports.pba_technique import Pos
class T1158(PostBreachTechnique):
tech_id = "T1158"
relevant_systems = ["Linux", "Windows"]
unscanned_msg = "Monkey didn't try creating hidden files or folders."
scanned_msg = "Monkey tried creating hidden files and folders on the system but failed."
used_msg = "Monkey created hidden files and folders on the system."

View File

@ -4,10 +4,8 @@ from monkey_island.cc.services.attack.technique_reports.pba_technique import Pos
class T1166(PostBreachTechnique):
tech_id = "T1166"
unscanned_msg = (
"Monkey didn't try setting the setuid or setgid bits since it didn't run on "
"any Linux machines."
)
relevant_systems = ["Linux"]
unscanned_msg = "Monkey didn't try setting the setuid or setgid bits."
scanned_msg = "Monkey tried setting the setuid or setgid bits but failed."
used_msg = "Monkey successfully set the setuid or setgid bits."
pba_names = [POST_BREACH_SETUID_SETGID]

View File

@ -4,9 +4,8 @@ from monkey_island.cc.services.attack.technique_reports.pba_technique import Pos
class T1168(PostBreachTechnique):
tech_id = "T1168"
unscanned_msg = (
"Monkey didn't try scheduling a job on Linux since it didn't run on any Linux machines."
)
relevant_systems = ["Linux"]
unscanned_msg = "Monkey didn't try scheduling a job on Linux."
scanned_msg = "Monkey tried scheduling a job on the Linux system but failed."
used_msg = "Monkey scheduled a job on the Linux system."
pba_names = [POST_BREACH_JOB_SCHEDULING]

View File

@ -5,6 +5,7 @@ from monkey_island.cc.services.attack.technique_reports import AttackTechnique
class T1188(AttackTechnique):
tech_id = "T1188"
relevant_systems = ["Linux", "Windows"]
unscanned_msg = "Monkey didn't use multi-hop proxy."
scanned_msg = ""
used_msg = "Monkey used multi-hop proxy."

View File

@ -4,9 +4,8 @@ from monkey_island.cc.services.attack.technique_reports import AttackTechnique
class T1197(AttackTechnique):
tech_id = "T1197"
unscanned_msg = (
"Monkey didn't try to use any bits jobs since it didn't run on any Windows machines."
)
relevant_systems = ["Windows"]
unscanned_msg = "Monkey didn't try to use any bits jobs."
scanned_msg = "Monkey tried to use bits jobs but failed."
used_msg = "Monkey successfully used bits jobs at least once in the network."

View File

@ -5,6 +5,7 @@ from monkey_island.cc.services.attack.technique_reports import AttackTechnique
class T1210(AttackTechnique):
tech_id = "T1210"
relevant_systems = ["Linux", "Windows"]
unscanned_msg = (
"Monkey didn't scan any remote services. Maybe it didn't find any machines on the network?"
)

View File

@ -4,24 +4,17 @@ from monkey_island.cc.services.attack.technique_reports.pba_technique import Pos
class T1216(PostBreachTechnique):
tech_id = "T1216"
relevant_systems = ["Windows"]
unscanned_msg = (
"Monkey didn't attempt to execute an arbitrary program with the help of a "
+ "pre-existing signed script since it didn't run on any Windows machines. "
+ "If successful, this behavior could be abused by adversaries to execute malicious "
"files that could " + "bypass application control and signature validation on "
"systems."
"pre-existing signed script. "
)
scanned_msg = (
"Monkey attempted to execute an arbitrary program with the help of a "
+ "pre-existing signed script on Windows but failed. "
+ "If successful, this behavior could be abused by adversaries to execute malicious "
"files that could " + "bypass application control and signature validation on "
"systems."
"pre-existing signed script on Windows but failed. "
)
used_msg = (
"Monkey executed an arbitrary program with the help of a pre-existing signed script "
"on Windows. "
+ "This behavior could be abused by adversaries to execute malicious files that could "
+ "bypass application control and signature validation on systems."
)
pba_names = [POST_BREACH_SIGNED_SCRIPT_PROXY_EXEC]

View File

@ -5,6 +5,7 @@ from monkey_island.cc.services.attack.technique_reports import AttackTechnique
class T1222(AttackTechnique):
tech_id = "T1222"
relevant_systems = ["Linux", "Windows"]
unscanned_msg = "Monkey didn't try to change any file permissions."
scanned_msg = "Monkey tried to change file permissions, but failed."
used_msg = "Monkey successfully changed file permissions in network systems."

View File

@ -4,12 +4,10 @@ from monkey_island.cc.services.attack.technique_reports.pba_technique import Pos
class T1504(PostBreachTechnique):
tech_id = "T1504"
unscanned_msg = (
"Monkey didn't try modifying powershell startup files since it didn't run on "
"any Windows machines."
)
scanned_msg = "Monkey tried modifying powershell startup files but failed."
used_msg = "Monkey successfully modified powershell startup files."
relevant_systems = ["Windows"]
unscanned_msg = "Monkey didn't try modifying PowerShell startup files."
scanned_msg = "Monkey tried modifying PowerShell startup files but failed."
used_msg = "Monkey successfully modified PowerShell startup files."
pba_names = [POST_BREACH_SHELL_STARTUP_FILE_MODIFICATION]
@staticmethod

View File

@ -1,11 +1,16 @@
import abc
import logging
from typing import Dict, List
from common.utils.attack_utils import ScanStatus
from common.utils.code_utils import abstractstatic
from monkey_island.cc.database import mongo
from monkey_island.cc.models.attack.attack_mitigations import AttackMitigations
from monkey_island.cc.services.attack.attack_config import AttackConfig
from monkey_island.cc.services.config_schema.config_schema import SCHEMA
from monkey_island.cc.services.config_schema.config_schema_per_attack_technique import (
get_config_schema_per_attack_technique,
)
logger = logging.getLogger(__name__)
@ -18,13 +23,15 @@ disabled_msg = (
class AttackTechnique(object, metaclass=abc.ABCMeta):
""" Abstract class for ATT&CK report components """
config_schema_per_attack_technique = None
@property
@abc.abstractmethod
def unscanned_msg(self):
"""
:return: Message that will be displayed in case attack technique was not scanned.
"""
pass
...
@property
@abc.abstractmethod
@ -32,7 +39,7 @@ class AttackTechnique(object, metaclass=abc.ABCMeta):
"""
:return: Message that will be displayed in case attack technique was scanned.
"""
pass
...
@property
@abc.abstractmethod
@ -40,7 +47,7 @@ class AttackTechnique(object, metaclass=abc.ABCMeta):
"""
:return: Message that will be displayed in case attack technique was used by the scanner.
"""
pass
...
@property
@abc.abstractmethod
@ -48,7 +55,17 @@ class AttackTechnique(object, metaclass=abc.ABCMeta):
"""
:return: Id of attack technique. E.g. T1003
"""
pass
...
@property
@abc.abstractmethod
def relevant_systems(self) -> List[str]:
"""
:return: systems on which the technique is relevant
(examples: 1. "Trap Command" PBA (technique T1154) is Linux only.
2. "Job Scheduling" PBA has different techniques for Windows and Linux.
"""
...
@staticmethod
@abstractstatic
@ -56,7 +73,7 @@ class AttackTechnique(object, metaclass=abc.ABCMeta):
"""
:return: Report data aggregated from the database.
"""
pass
...
@classmethod
def technique_status(cls):
@ -104,12 +121,52 @@ class AttackTechnique(object, metaclass=abc.ABCMeta):
if status == ScanStatus.DISABLED.value:
return disabled_msg
if status == ScanStatus.UNSCANNED.value:
return cls.unscanned_msg
if not cls.config_schema_per_attack_technique:
cls.config_schema_per_attack_technique = get_config_schema_per_attack_technique(
SCHEMA
)
unscanned_msg = cls._get_unscanned_msg_with_reasons(
cls.unscanned_msg, cls.config_schema_per_attack_technique
)
return unscanned_msg
elif status == ScanStatus.SCANNED.value:
return cls.scanned_msg
else:
return cls.used_msg
@classmethod
def _get_unscanned_msg_with_reasons(
cls, unscanned_msg: str, config_schema_per_attack_technique: Dict
):
reasons = []
if len(cls.relevant_systems) == 1:
reasons.append(f"- Monkey did not run on any {cls.relevant_systems[0]} systems.")
if cls.tech_id in config_schema_per_attack_technique:
reasons.append(
"- The following configuration options were disabled:<br/>"
f"{cls._get_relevant_config_values(config_schema_per_attack_technique)}"
)
if reasons:
unscanned_msg = (
unscanned_msg.strip(".")
+ " due to one of the following reasons:\n"
+ "\n".join(reasons)
)
return unscanned_msg
@classmethod
def _get_relevant_config_values(cls, config_schema_per_attack_technique: Dict):
config_options = ""
for config_type in config_schema_per_attack_technique[cls.tech_id]:
config_options += (
f"- {config_type}"
f"{', '.join(config_schema_per_attack_technique[cls.tech_id][config_type])}<br/>"
)
return config_options
@classmethod
def technique_title(cls):
"""

View File

@ -15,7 +15,7 @@ class PostBreachTechnique(AttackTechnique, metaclass=abc.ABCMeta):
"""
:return: names of post breach action
"""
pass
...
@classmethod
def get_pba_query(cls, post_breach_action_names):

View File

@ -0,0 +1,36 @@
from typing import Dict, List
def get_config_schema_per_attack_technique(schema: Dict) -> Dict[str, Dict[str, List[str]]]:
"""
:return: dictionary mapping each attack technique to relevant config fields; example -
{
"T1003": {
"System Info Collectors": [
"Mimikatz collector",
"Azure credential collector"
]
}
}
"""
reverse_schema = {}
definitions = schema["definitions"]
for definition in definitions:
definition_type = definitions[definition]["title"]
for field in definitions[definition]["anyOf"]:
config_field = field["title"]
for attack_technique in field.get("attack_techniques", []):
_add_config_field_to_reverse_schema(
definition_type, config_field, attack_technique, reverse_schema
)
return reverse_schema
def _add_config_field_to_reverse_schema(
definition_type: str, config_field: str, attack_technique: str, reverse_schema: Dict
) -> None:
reverse_schema.setdefault(attack_technique, {})
reverse_schema[attack_technique].setdefault(definition_type, [])
reverse_schema[attack_technique][definition_type].append(config_field)

View File

@ -1,7 +1,7 @@
from monkey_island.cc.services.utils.typographic_symbols import WARNING_SIGN
EXPLOITER_CLASSES = {
"title": "Exploit class",
"title": "Exploiters",
"description": "Click on exploiter to get more information about it."
+ WARNING_SIGN
+ " Note that using unsafe exploits may cause crashes of the exploited "
@ -163,7 +163,7 @@ EXPLOITER_CLASSES = {
"computers.",
"safe": True,
"link": "https://www.guardicore.com/infectionmonkey"
"/docs/reference/exploiters/", # TODO: Change link once documentation is updated
"/docs/reference/exploiters/powershell",
},
],
}

View File

@ -1,5 +1,5 @@
FINGER_CLASSES = {
"title": "Fingerprint class",
"title": "Fingerprinters",
"description": "Fingerprint modules collect info about external services "
"Infection Monkey scans.",
"type": "string",
@ -7,7 +7,7 @@ FINGER_CLASSES = {
{
"type": "string",
"enum": ["SMBFinger"],
"title": "SMBFinger",
"title": "SMB Fingerprinter",
"safe": True,
"info": "Figures out if SMB is running and what's the version of it.",
"attack_techniques": ["T1210"],
@ -15,7 +15,7 @@ FINGER_CLASSES = {
{
"type": "string",
"enum": ["SSHFinger"],
"title": "SSHFinger",
"title": "SSH Fingerprinter",
"safe": True,
"info": "Figures out if SSH is running.",
"attack_techniques": ["T1210"],
@ -23,21 +23,21 @@ FINGER_CLASSES = {
{
"type": "string",
"enum": ["PingScanner"],
"title": "PingScanner",
"title": "Ping Scanner",
"safe": True,
"info": "Tries to identify if host is alive and which OS it's running by ping scan.",
},
{
"type": "string",
"enum": ["HTTPFinger"],
"title": "HTTPFinger",
"title": "HTTP Fingerprinter",
"safe": True,
"info": "Checks if host has HTTP/HTTPS ports open.",
},
{
"type": "string",
"enum": ["MySQLFinger"],
"title": "MySQLFinger",
"title": "MySQL Fingerprinter",
"safe": True,
"info": "Checks if MySQL server is running and tries to get it's version.",
"attack_techniques": ["T1210"],
@ -45,7 +45,7 @@ FINGER_CLASSES = {
{
"type": "string",
"enum": ["MSSQLFinger"],
"title": "MSSQLFinger",
"title": "MSSQL Fingerprinter",
"safe": True,
"info": "Checks if Microsoft SQL service is running and tries to gather "
"information about it.",
@ -54,7 +54,7 @@ FINGER_CLASSES = {
{
"type": "string",
"enum": ["ElasticFinger"],
"title": "ElasticFinger",
"title": "Elastic Fingerprinter",
"safe": True,
"info": "Checks if ElasticSearch is running and attempts to find it's " "version.",
"attack_techniques": ["T1210"],

View File

@ -1,14 +1,13 @@
POST_BREACH_ACTIONS = {
"title": "Post breach actions",
"title": "Post-Breach Actions",
"description": "Runs scripts/commands on infected machines. These actions safely simulate what "
"an adversary"
"might do after breaching a new machine. Used in ATT&CK and Zero trust reports.",
"an adversary might do after breaching a new machine. Used in ATT&CK and Zero trust reports.",
"type": "string",
"anyOf": [
{
"type": "string",
"enum": ["CommunicateAsBackdoorUser"],
"title": "Communicate as backdoor user",
"title": "Communicate as Backdoor User",
"safe": True,
"info": "Attempts to create a new user, create HTTPS requests as that "
"user and delete the user "
@ -18,7 +17,7 @@ POST_BREACH_ACTIONS = {
{
"type": "string",
"enum": ["ModifyShellStartupFiles"],
"title": "Modify shell startup files",
"title": "Modify Shell Startup Files",
"safe": True,
"info": "Attempts to modify shell startup files, like ~/.profile, "
"~/.bashrc, ~/.bash_profile "
@ -29,7 +28,7 @@ POST_BREACH_ACTIONS = {
{
"type": "string",
"enum": ["HiddenFiles"],
"title": "Hidden files and directories",
"title": "Hidden Files and Directories",
"safe": True,
"info": "Attempts to create a hidden file and remove it afterward.",
"attack_techniques": ["T1158"],
@ -37,11 +36,10 @@ POST_BREACH_ACTIONS = {
{
"type": "string",
"enum": ["TrapCommand"],
"title": "Trap",
"title": "Trap Command",
"safe": True,
"info": "On Linux systems, attempts to trap a terminate signal in order "
"to execute a command "
"upon receiving that signal. Removes the trap afterwards.",
"to execute a command upon receiving that signal. Removes the trap afterwards.",
"attack_techniques": ["T1154"],
},
{
@ -57,7 +55,7 @@ POST_BREACH_ACTIONS = {
{
"type": "string",
"enum": ["ScheduleJobs"],
"title": "Job scheduling",
"title": "Job Scheduling",
"safe": True,
"info": "Attempts to create a scheduled job on the system and remove it.",
"attack_techniques": ["T1168", "T1053"],
@ -74,7 +72,7 @@ POST_BREACH_ACTIONS = {
{
"type": "string",
"enum": ["SignedScriptProxyExecution"],
"title": "Signed script proxy execution",
"title": "Signed Script Proxy Execution",
"safe": False,
"info": "On Windows systems, attempts to execute an arbitrary file "
"with the help of a pre-existing signed script.",
@ -91,7 +89,7 @@ POST_BREACH_ACTIONS = {
{
"type": "string",
"enum": ["ClearCommandHistory"],
"title": "Clear command history",
"title": "Clear Command History",
"safe": False,
"info": "Attempts to clear the command history.",
"attack_techniques": ["T1146"],

View File

@ -15,7 +15,7 @@ SYSTEM_INFO_COLLECTOR_CLASSES = {
{
"type": "string",
"enum": [ENVIRONMENT_COLLECTOR],
"title": "Environment collector",
"title": "Environment Collector",
"safe": True,
"info": "Collects information about machine's environment (on " "premise/GCP/AWS).",
"attack_techniques": ["T1082"],
@ -23,7 +23,7 @@ SYSTEM_INFO_COLLECTOR_CLASSES = {
{
"type": "string",
"enum": [MIMIKATZ_COLLECTOR],
"title": "Mimikatz collector",
"title": "Mimikatz Collector",
"safe": True,
"info": "Collects credentials from Windows credential manager.",
"attack_techniques": ["T1003", "T1005"],
@ -31,7 +31,7 @@ SYSTEM_INFO_COLLECTOR_CLASSES = {
{
"type": "string",
"enum": [AWS_COLLECTOR],
"title": "AWS collector",
"title": "AWS Collector",
"safe": True,
"info": "If on AWS, collects more information about the AWS instance "
"currently running on.",
@ -40,7 +40,7 @@ SYSTEM_INFO_COLLECTOR_CLASSES = {
{
"type": "string",
"enum": [HOSTNAME_COLLECTOR],
"title": "Hostname collector",
"title": "Hostname Collector",
"safe": True,
"info": "Collects machine's hostname.",
"attack_techniques": ["T1082", "T1016"],
@ -48,7 +48,7 @@ SYSTEM_INFO_COLLECTOR_CLASSES = {
{
"type": "string",
"enum": [PROCESS_LIST_COLLECTOR],
"title": "Process list collector",
"title": "Process List Collector",
"safe": True,
"info": "Collects a list of running processes on the machine.",
"attack_techniques": ["T1082"],
@ -56,7 +56,7 @@ SYSTEM_INFO_COLLECTOR_CLASSES = {
{
"type": "string",
"enum": [AZURE_CRED_COLLECTOR],
"title": "Azure credential collector",
"title": "Azure Credential Collector",
"safe": True,
"info": "Collects password credentials from Azure VMs",
"attack_techniques": ["T1003", "T1005"],

View File

@ -0,0 +1,129 @@
from enum import Enum
import pytest
from common.utils.attack_utils import ScanStatus
from monkey_island.cc.services.attack.technique_reports.__init__ import (
AttackTechnique,
disabled_msg,
)
FAKE_CONFIG_SCHEMA_PER_ATTACK_TECHNIQUE = {
"T0000": {
"Definition Type 1": ["Config Option 1", "Config Option 2"],
"Definition Type 2": ["Config Option 5", "Config Option 6"],
},
"T0001": {
"Definition Type 1": ["Config Option 1"],
"Definition Type 2": ["Config Option 5"],
},
}
@pytest.fixture(scope="function", autouse=True)
def mock_config_schema_per_attack_technique(monkeypatch, fake_schema):
monkeypatch.setattr(
("monkey_island.cc.services.attack.technique_reports." "__init__.SCHEMA"),
fake_schema,
)
class FakeAttackTechnique_TwoRelevantSystems(AttackTechnique):
tech_id = "T0001"
relevant_systems = ["System 1", "System 2"]
unscanned_msg = "UNSCANNED"
scanned_msg = "SCANNED"
used_msg = "USED"
def get_report_data():
pass
class ExpectedMsgs_TwoRelevantSystems(Enum):
UNSCANNED: str = (
"UNSCANNED due to one of the following reasons:\n"
"- The following configuration options were disabled:<br/>"
"- Definition Type 1 — Config Option 1<br/>"
"- Definition Type 2 — Config Option 5<br/>"
)
SCANNED: str = "SCANNED"
USED: str = "USED"
class FakeAttackTechnique_OneRelevantSystem(AttackTechnique):
tech_id = "T0001"
relevant_systems = ["System 1"]
unscanned_msg = "UNSCANNED"
scanned_msg = "SCANNED"
used_msg = "USED"
def get_report_data():
pass
class ExpectedMsgs_OneRelevantSystem(Enum):
UNSCANNED: str = (
"UNSCANNED due to one of the following reasons:\n"
"- Monkey did not run on any System 1 systems.\n"
"- The following configuration options were disabled:<br/>"
"- Definition Type 1 — Config Option 1<br/>"
"- Definition Type 2 — Config Option 5<br/>"
)
SCANNED: str = "SCANNED"
USED: str = "USED"
def test_get_message_by_status_disabled_two_relevant_systems():
technique_msg = FakeAttackTechnique_TwoRelevantSystems.get_message_by_status(
ScanStatus.DISABLED.value
)
assert technique_msg == disabled_msg
def test_get_message_by_status_unscanned_two_relevant_systems():
technique_msg = FakeAttackTechnique_TwoRelevantSystems.get_message_by_status(
ScanStatus.UNSCANNED.value
)
assert technique_msg == ExpectedMsgs_TwoRelevantSystems.UNSCANNED.value
def test_get_message_by_status_scanned_two_relevant_systems():
technique_msg = FakeAttackTechnique_TwoRelevantSystems.get_message_by_status(
ScanStatus.SCANNED.value
)
assert technique_msg == ExpectedMsgs_TwoRelevantSystems.SCANNED.value
def test_get_message_by_status_used_two_relevant_systems():
technique_msg = FakeAttackTechnique_TwoRelevantSystems.get_message_by_status(
ScanStatus.USED.value
)
assert technique_msg == ExpectedMsgs_TwoRelevantSystems.USED.value
def test_get_message_by_status_disabled_one_relevant_system():
technique_msg = FakeAttackTechnique_OneRelevantSystem.get_message_by_status(
ScanStatus.DISABLED.value
)
assert technique_msg == disabled_msg
def test_get_message_by_status_unscanned_one_relevant_system():
technique_msg = FakeAttackTechnique_OneRelevantSystem.get_message_by_status(
ScanStatus.UNSCANNED.value
)
assert technique_msg == ExpectedMsgs_OneRelevantSystem.UNSCANNED.value
def test_get_message_by_status_scanned_one_relevant_system():
technique_msg = FakeAttackTechnique_OneRelevantSystem.get_message_by_status(
ScanStatus.SCANNED.value
)
assert technique_msg == ExpectedMsgs_OneRelevantSystem.SCANNED.value
def test_get_message_by_status_used_one_relevant_system():
technique_msg = FakeAttackTechnique_OneRelevantSystem.get_message_by_status(
ScanStatus.USED.value
)
assert technique_msg == ExpectedMsgs_OneRelevantSystem.USED.value

View File

@ -0,0 +1,18 @@
from monkey_island.cc.services.config_schema.config_schema_per_attack_technique import (
get_config_schema_per_attack_technique,
)
REVERSE_FAKE_SCHEMA = {
"T0000": {
"Definition Type 1": ["Config Option 1", "Config Option 2"],
"Definition Type 2": ["Config Option 5", "Config Option 6"],
},
"T0001": {
"Definition Type 1": ["Config Option 1"],
"Definition Type 2": ["Config Option 5"],
},
}
def test_get_config_schema_per_attack_technique(monkeypatch, fake_schema):
assert get_config_schema_per_attack_technique(fake_schema) == REVERSE_FAKE_SCHEMA

View File

@ -20,3 +20,51 @@ def config(monkeypatch, IPS, PORT):
monkeypatch.setattr(Environment, "_ISLAND_PORT", PORT)
config = ConfigService.get_default_config(True)
return config
@pytest.fixture
def fake_schema():
return {
"definitions": {
"definition_type_1": {
"title": "Definition Type 1",
"anyOf": [
{
"title": "Config Option 1",
"attack_techniques": ["T0000", "T0001"],
},
{
"title": "Config Option 2",
"attack_techniques": ["T0000"],
},
{
"title": "Config Option 3",
"attack_techniques": [],
},
{
"title": "Config Option 4",
},
],
},
"definition_type_2": {
"title": "Definition Type 2",
"anyOf": [
{
"title": "Config Option 5",
"attack_techniques": ["T0000", "T0001"],
},
{
"title": "Config Option 6",
"attack_techniques": ["T0000"],
},
{
"title": "Config Option 7",
"attack_techniques": [],
},
{
"title": "Config Option 8",
},
],
},
}
}