Island: Remove attack config and enable all techniques by default

This commit is contained in:
Ilija Lazoroski 2021-11-19 15:03:41 +01:00
parent f07b7fafa2
commit 4e98baf6e3
20 changed files with 33 additions and 185 deletions

View File

@ -1,67 +0,0 @@
import logging
from monkey_island.cc.database import mongo
from monkey_island.cc.services.attack.attack_schema import SCHEMA
logger = logging.getLogger(__name__)
class AttackConfig(object):
def __init__(self):
pass
@staticmethod
def get_config():
config = mongo.db.attack.find_one({"name": "newconfig"})["properties"]
return config
@staticmethod
def get_technique(technique_id):
"""
Gets technique by id
:param technique_id: E.g. T1210
:return: Technique object or None if technique is not found
"""
attack_config = AttackConfig.get_config()
for config_key, attack_type in list(attack_config.items()):
for type_key, technique in list(attack_type["properties"].items()):
if type_key == technique_id:
return technique
return None
@staticmethod
def reset_config():
AttackConfig.update_config(SCHEMA)
@staticmethod
def update_config(config_json):
mongo.db.attack.update({"name": "newconfig"}, {"$set": config_json}, upsert=True)
return True
@staticmethod
def get_technique_values():
"""
Parses ATT&CK config into a dict of techniques and corresponding values.
:return: Dictionary of techniques. Format: {"T1110": True, "T1075": False, ...}
"""
attack_config = AttackConfig.get_config()
techniques = {}
for type_name, attack_type in list(attack_config.items()):
for key, technique in list(attack_type["properties"].items()):
techniques[key] = technique["value"]
return techniques
@staticmethod
def get_techniques_for_report():
"""
:return: Format: {"T1110": {"selected": True, "type": "Credential Access", "T1075": ...}
"""
attack_config = AttackConfig.get_config()
techniques = {}
for type_name, attack_type in list(attack_config.items()):
for key, technique in list(attack_type["properties"].items()):
techniques[key] = {
"selected": technique["value"],
"type": SCHEMA["properties"][type_name]["title"],
}
return techniques

View File

@ -2,7 +2,7 @@ import logging
from monkey_island.cc.database import mongo
from monkey_island.cc.models import Monkey
from monkey_island.cc.services.attack.attack_config import AttackConfig
from monkey_island.cc.services.attack.attack_schema import SCHEMA
from monkey_island.cc.services.attack.technique_reports import (
T1003,
T1005,
@ -102,7 +102,7 @@ class AttackReportService:
"meta": {"latest_monkey_modifytime": Monkey.get_latest_modifytime()},
"name": REPORT_NAME,
}
for tech_id, tech_info in list(AttackConfig.get_techniques_for_report().items()):
for tech_id, tech_info in list(AttackReportService.get_techniques_for_report().items()):
try:
technique_report_data = TECHNIQUES[tech_id].get_report_data()
technique_report_data.update(tech_info)
@ -146,3 +146,17 @@ class AttackReportService:
raise RuntimeError(
"Attack Report cache not cleared. DeleteResult: " + delete_result.raw_result
)
@staticmethod
def get_techniques_for_report():
"""
:return: Format: {"T1110": {"type": "Credential Access", "T1075": ...}
"""
attack_config = SCHEMA["properties"]
techniques = {}
for type_name, attack_type in list(attack_config.items()):
for key, technique in list(attack_type["properties"].items()):
techniques[key] = {
"type": SCHEMA["properties"][type_name]["title"],
}
return techniques

View File

@ -10,8 +10,6 @@ SCHEMA = {
"T1059": {
"title": "Command line interface",
"type": "bool",
"value": True,
"necessary": True,
"link": "https://attack.mitre.org/techniques/T1059",
"description": "Adversaries may use command-line interfaces to interact with "
"systems "
@ -20,8 +18,6 @@ SCHEMA = {
"T1106": {
"title": "Execution through API",
"type": "bool",
"value": True,
"necessary": False,
"link": "https://attack.mitre.org/techniques/T1106",
"description": "Adversary tools may directly use the Windows application "
"programming interface (API) to execute binaries.",
@ -30,8 +26,6 @@ SCHEMA = {
"T1086": {
"title": "PowerShell",
"type": "bool",
"value": True,
"necessary": True,
"link": "https://attack.mitre.org/techniques/T1086",
"description": "Adversaries can use PowerShell to perform a number of actions,"
" including discovery of information and execution of code.",
@ -39,8 +33,6 @@ SCHEMA = {
"T1064": {
"title": "Scripting",
"type": "bool",
"value": True,
"necessary": True,
"link": "https://attack.mitre.org/techniques/T1064",
"description": "Adversaries may use scripts to aid in operations and "
"perform multiple actions that would otherwise be manual.",
@ -48,8 +40,6 @@ SCHEMA = {
"T1035": {
"title": "Service execution",
"type": "bool",
"value": True,
"necessary": False,
"link": "https://attack.mitre.org/techniques/T1035",
"description": "Adversaries may execute a binary, command, or script via a "
"method "
@ -60,8 +50,6 @@ SCHEMA = {
"T1154": {
"title": "Trap",
"type": "bool",
"value": True,
"necessary": False,
"link": "https://attack.mitre.org/techniques/T1154",
"description": "Adversaries can use the trap command to register code to be "
"executed "
@ -77,8 +65,6 @@ SCHEMA = {
"T1156": {
"title": ".bash_profile and .bashrc",
"type": "bool",
"value": True,
"necessary": False,
"link": "https://attack.mitre.org/techniques/T1156",
"description": "Adversaries may abuse shell scripts by "
"inserting arbitrary shell commands to gain persistence, which "
@ -89,8 +75,6 @@ SCHEMA = {
"T1136": {
"title": "Create account",
"type": "bool",
"value": True,
"necessary": False,
"link": "https://attack.mitre.org/techniques/T1136",
"description": "Adversaries with a sufficient level of access "
"may create a local system, domain, or cloud tenant account.",
@ -98,8 +82,6 @@ SCHEMA = {
"T1158": {
"title": "Hidden files and directories",
"type": "bool",
"value": True,
"necessary": False,
"link": "https://attack.mitre.org/techniques/T1158",
"description": "Adversaries can hide files and folders on the system "
"and evade a typical user or system analysis that does not "
@ -108,8 +90,6 @@ SCHEMA = {
"T1168": {
"title": "Local job scheduling",
"type": "bool",
"value": True,
"necessary": False,
"link": "https://attack.mitre.org/techniques/T1168/",
"description": "Linux supports multiple methods for creating pre-scheduled and "
"periodic background jobs. Job scheduling can be used by "
@ -121,8 +101,6 @@ SCHEMA = {
"T1504": {
"title": "PowerShell profile",
"type": "bool",
"value": True,
"necessary": False,
"link": "https://attack.mitre.org/techniques/T1504",
"description": "Adversaries may gain persistence and elevate privileges "
"in certain situations by abusing PowerShell profiles which "
@ -132,8 +110,6 @@ SCHEMA = {
"T1053": {
"title": "Scheduled task",
"type": "bool",
"value": True,
"necessary": False,
"link": "https://attack.mitre.org/techniques/T1053",
"description": "Windows utilities can be used to schedule programs or scripts "
"to "
@ -146,8 +122,6 @@ SCHEMA = {
"T1166": {
"title": "Setuid and Setgid",
"type": "bool",
"value": True,
"necessary": False,
"link": "https://attack.mitre.org/techniques/T1166",
"description": "Adversaries can set the setuid or setgid bits to get code "
"running in "
@ -163,8 +137,6 @@ SCHEMA = {
"T1197": {
"title": "BITS jobs",
"type": "bool",
"value": True,
"necessary": True,
"link": "https://attack.mitre.org/techniques/T1197",
"description": "Adversaries may abuse BITS to download, execute, "
"and even clean up after running malicious code.",
@ -172,8 +144,6 @@ SCHEMA = {
"T1146": {
"title": "Clear command history",
"type": "bool",
"value": False,
"necessary": False,
"link": "https://attack.mitre.org/techniques/T1146",
"description": "Adversaries may clear/disable command history of a compromised "
"account to conceal the actions undertaken during an intrusion.",
@ -181,8 +151,6 @@ SCHEMA = {
"T1107": {
"title": "File Deletion",
"type": "bool",
"value": True,
"necessary": True,
"link": "https://attack.mitre.org/techniques/T1107",
"description": "Adversaries may remove files over the course of an intrusion "
"to keep their footprint low or remove them at the end as part "
@ -191,8 +159,6 @@ SCHEMA = {
"T1222": {
"title": "File permissions modification",
"type": "bool",
"value": True,
"necessary": True,
"link": "https://attack.mitre.org/techniques/T1222",
"description": "Adversaries may modify file permissions/attributes to evade "
"intended DACLs.",
@ -200,8 +166,6 @@ SCHEMA = {
"T1099": {
"title": "Timestomping",
"type": "bool",
"value": True,
"necessary": False,
"link": "https://attack.mitre.org/techniques/T1099",
"description": "Adversaries may modify file time attributes to hide "
"new/changes to existing "
@ -211,8 +175,6 @@ SCHEMA = {
"T1216": {
"title": "Signed script proxy execution",
"type": "bool",
"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. This behavior could "
@ -229,8 +191,6 @@ SCHEMA = {
"T1110": {
"title": "Brute force",
"type": "bool",
"value": True,
"necessary": False,
"link": "https://attack.mitre.org/techniques/T1110",
"description": "Adversaries may use brute force techniques to attempt access "
"to accounts "
@ -241,8 +201,6 @@ SCHEMA = {
"T1003": {
"title": "Credential dumping",
"type": "bool",
"value": True,
"necessary": False,
"link": "https://attack.mitre.org/techniques/T1003",
"description": "Mapped with T1078 Valid Accounts because "
"both techniques require"
@ -257,8 +215,6 @@ SCHEMA = {
"T1145": {
"title": "Private keys",
"type": "bool",
"value": True,
"necessary": False,
"link": "https://attack.mitre.org/techniques/T1145",
"description": "Adversaries may gather private keys from compromised systems "
"for use in "
@ -277,8 +233,6 @@ SCHEMA = {
"T1087": {
"title": "Account Discovery",
"type": "bool",
"value": True,
"necessary": False,
"link": "https://attack.mitre.org/techniques/T1087",
"description": "Adversaries may attempt to get a listing of accounts on a "
"system or "
@ -289,8 +243,6 @@ SCHEMA = {
"T1018": {
"title": "Remote System Discovery",
"type": "bool",
"value": True,
"necessary": True,
"link": "https://attack.mitre.org/techniques/T1018",
"description": "Adversaries will likely attempt to get a listing of other "
"systems by IP address, "
@ -300,8 +252,6 @@ SCHEMA = {
"T1082": {
"title": "System information discovery",
"type": "bool",
"value": True,
"necessary": False,
"link": "https://attack.mitre.org/techniques/T1082",
"depends_on": ["T1016", "T1005"],
"description": "An adversary may attempt to get detailed information about the "
@ -312,8 +262,6 @@ SCHEMA = {
"T1016": {
"title": "System network configuration discovery",
"type": "bool",
"value": True,
"necessary": False,
"link": "https://attack.mitre.org/techniques/T1016",
"depends_on": ["T1005", "T1082"],
"description": "Adversaries will likely look for details about the network "
@ -332,8 +280,6 @@ SCHEMA = {
"T1210": {
"title": "Exploitation of Remote services",
"type": "bool",
"value": True,
"necessary": False,
"link": "https://attack.mitre.org/techniques/T1210",
"description": "Exploitation of a software vulnerability occurs when an "
"adversary "
@ -345,8 +291,6 @@ SCHEMA = {
"T1075": {
"title": "Pass the hash",
"type": "bool",
"value": True,
"necessary": False,
"link": "https://attack.mitre.org/techniques/T1075",
"description": "Pass the hash (PtH) is a method of authenticating as a user "
"without "
@ -355,8 +299,6 @@ SCHEMA = {
"T1105": {
"title": "Remote file copy",
"type": "bool",
"value": True,
"necessary": True,
"link": "https://attack.mitre.org/techniques/T1105",
"description": "Files may be copied from one system to another to stage "
"adversary tools or other files over the course of an operation.",
@ -364,8 +306,6 @@ SCHEMA = {
"T1021": {
"title": "Remote services",
"type": "bool",
"value": True,
"necessary": False,
"link": "https://attack.mitre.org/techniques/T1021",
"depends_on": ["T1110"],
"description": "An adversary may use Valid Accounts to log into a service"
@ -381,8 +321,6 @@ SCHEMA = {
"T1005": {
"title": "Data from local system",
"type": "bool",
"value": True,
"necessary": False,
"link": "https://attack.mitre.org/techniques/T1005",
"depends_on": ["T1016", "T1082"],
"description": "Sensitive data can be collected from local system sources, "
@ -400,8 +338,6 @@ SCHEMA = {
"T1090": {
"title": "Connection proxy",
"type": "bool",
"value": True,
"necessary": True,
"link": "https://attack.mitre.org/techniques/T1090",
"description": "A connection proxy is used to direct network traffic between "
"systems "
@ -410,8 +346,6 @@ SCHEMA = {
"T1065": {
"title": "Uncommonly used port",
"type": "bool",
"value": True,
"necessary": True,
"link": "https://attack.mitre.org/techniques/T1065",
"description": "Adversaries may conduct C2 communications over a non-standard "
"port to bypass proxies and firewalls that have been improperly "
@ -420,8 +354,6 @@ SCHEMA = {
"T1188": {
"title": "Multi-hop proxy",
"type": "bool",
"value": True,
"necessary": True,
"link": "https://attack.mitre.org/techniques/T1188",
"description": "To disguise the source of malicious traffic, "
"adversaries may chain together multiple proxies.",
@ -436,8 +368,6 @@ SCHEMA = {
"T1041": {
"title": "Exfiltration Over Command and Control Channel",
"type": "bool",
"value": True,
"necessary": True,
"link": "https://attack.mitre.org/techniques/T1041",
"description": "Data exfiltration is performed over the Command and Control "
"channel.",

View File

@ -35,7 +35,6 @@ class T1003(AttackTechnique):
@staticmethod
def get_report_data():
@T1003.is_status_disabled
def get_technique_status_and_data():
if mongo.db.telemetry.count_documents(T1003.query):
status = ScanStatus.USED.value

View File

@ -36,7 +36,6 @@ class T1016(AttackTechnique):
@staticmethod
def get_report_data():
@T1016.is_status_disabled
def get_technique_status_and_data():
network_info = list(mongo.db.telemetry.aggregate(T1016.query))
status = ScanStatus.USED.value if network_info else ScanStatus.UNSCANNED.value

View File

@ -40,7 +40,6 @@ class T1018(AttackTechnique):
@staticmethod
def get_report_data():
@T1018.is_status_disabled
def get_technique_status_and_data():
scan_info = list(mongo.db.telemetry.aggregate(T1018.query))
if scan_info:

View File

@ -35,7 +35,6 @@ class T1021(AttackTechnique):
@staticmethod
def get_report_data():
@T1021.is_status_disabled
def get_technique_status_and_data():
attempts = []
if mongo.db.telemetry.count_documents(T1021.scanned_query):

View File

@ -12,7 +12,6 @@ class T1041(AttackTechnique):
@staticmethod
def get_report_data():
@T1041.is_status_disabled
def get_technique_status_and_data():
monkeys = list(Monkey.objects())
info = [

View File

@ -26,7 +26,6 @@ class T1059(AttackTechnique):
@staticmethod
def get_report_data():
@T1059.is_status_disabled
def get_technique_status_and_data():
cmd_data = list(mongo.db.telemetry.aggregate(T1059.query))
if cmd_data:

View File

@ -51,7 +51,6 @@ class T1075(AttackTechnique):
@staticmethod
def get_report_data():
@T1075.is_status_disabled
def get_technique_status_and_data():
successful_logins = list(mongo.db.telemetry.aggregate(T1075.query))
if successful_logins:

View File

@ -64,7 +64,6 @@ class T1082(AttackTechnique):
@staticmethod
def get_report_data():
@T1082.is_status_disabled
def get_technique_status_and_data():
system_info = list(mongo.db.telemetry.aggregate(T1082.query))
if system_info:

View File

@ -60,7 +60,6 @@ class T1086(AttackTechnique):
@staticmethod
def get_report_data():
@T1086.is_status_disabled
def get_technique_status_and_data():
exploit_cmd_data = list(mongo.db.telemetry.aggregate(T1086.query_for_exploits))
pba_cmd_data = list(mongo.db.telemetry.aggregate(T1086.query_for_pbas))

View File

@ -12,7 +12,6 @@ class T1090(AttackTechnique):
@staticmethod
def get_report_data():
@T1090.is_status_disabled
def get_technique_status_and_data():
monkeys = Monkey.get_tunneled_monkeys()
monkeys = [monkey.get_network_info() for monkey in monkeys]

View File

@ -33,7 +33,6 @@ class T1110(AttackTechnique):
@staticmethod
def get_report_data():
@T1110.is_status_disabled
def get_technique_status_and_data():
attempts = list(mongo.db.telemetry.aggregate(T1110.query))
succeeded = False

View File

@ -29,7 +29,6 @@ class T1145(AttackTechnique):
@staticmethod
def get_report_data():
@T1145.is_status_disabled
def get_technique_status_and_data():
ssh_info = list(mongo.db.telemetry.aggregate(T1145.query))
if ssh_info:

View File

@ -12,7 +12,6 @@ class T1188(AttackTechnique):
@staticmethod
def get_report_data():
@T1188.is_status_disabled
def get_technique_status_and_data():
monkeys = Monkey.get_tunneled_monkeys()
hops = []

View File

@ -16,7 +16,6 @@ class T1210(AttackTechnique):
@staticmethod
def get_report_data():
@T1210.is_status_disabled
def get_technique_status_and_data():
scanned_services = T1210.get_scanned_services()
exploited_services = T1210.get_exploited_services()
@ -30,10 +29,8 @@ class T1210(AttackTechnique):
status_and_data = get_technique_status_and_data()
status = status_and_data[0]
if status == ScanStatus.DISABLED.value:
scanned_services, exploited_services = [], []
else:
scanned_services, exploited_services = status_and_data[1], status_and_data[2]
scanned_services, exploited_services = status_and_data[1], status_and_data[2]
data = {"title": T1210.technique_title()}
data.update(T1210.get_message_and_status(status))

View File

@ -6,19 +6,14 @@ 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.attack.attack_schema import SCHEMA as ATTACK_SCHEMA
from monkey_island.cc.services.config_schema.config_schema_per_attack_technique import (
ConfigSchemaPerAttackTechnique,
)
logger = logging.getLogger(__name__)
disabled_msg = (
"This technique has been disabled. "
+ "You can enable it from the [configuration page](../../configure)."
)
class AttackTechnique(object, metaclass=abc.ABCMeta):
""" Abstract class for ATT&CK report components """
@ -81,9 +76,7 @@ class AttackTechnique(object, metaclass=abc.ABCMeta):
Gets the status of a certain attack technique.
:return: ScanStatus numeric value
"""
if not cls._is_enabled_in_config():
return ScanStatus.DISABLED.value
elif mongo.db.telemetry.find_one(
if mongo.db.telemetry.find_one(
{
"telem_category": "attack",
"data.status": ScanStatus.USED.value,
@ -118,8 +111,6 @@ class AttackTechnique(object, metaclass=abc.ABCMeta):
:param status: Enum from common/attack_utils.py integer value
:return: message string
"""
if status == ScanStatus.DISABLED.value:
return disabled_msg
if status == ScanStatus.UNSCANNED.value:
if not cls.config_schema_per_attack_technique:
cls.config_schema_per_attack_technique = (
@ -172,7 +163,7 @@ class AttackTechnique(object, metaclass=abc.ABCMeta):
"""
:return: techniques title. E.g. "T1110 Brute force"
"""
return AttackConfig.get_technique(cls.tech_id)["title"]
return get_technique(cls.tech_id)["title"]
@classmethod
def get_tech_base_data(cls):
@ -205,17 +196,16 @@ class AttackTechnique(object, metaclass=abc.ABCMeta):
else:
return {}
@classmethod
def is_status_disabled(cls, get_technique_status_and_data) -> bool:
def check_if_disabled_in_config():
return (
(ScanStatus.DISABLED.value, [])
if not cls._is_enabled_in_config()
else get_technique_status_and_data()
)
return check_if_disabled_in_config
@classmethod
def _is_enabled_in_config(cls) -> bool:
return AttackConfig.get_technique_values()[cls.tech_id]
def get_technique(technique_id):
"""
Gets technique by id
:param technique_id: E.g. T1210
:return: Technique object or None if technique is not found
"""
attack_config = ATTACK_SCHEMA["properties"]
for config_key, attack_type in list(attack_config.items()):
for type_key, technique in list(attack_type["properties"].items()):
if type_key == technique_id:
return technique
return None

View File

@ -54,7 +54,6 @@ class PostBreachTechnique(AttackTechnique, metaclass=abc.ABCMeta):
:return: Technique's report data aggregated from the database
"""
@cls.is_status_disabled
def get_technique_status_and_data():
info = list(
mongo.db.telemetry.aggregate(cls.get_pba_query(cls.pba_names, cls.relevant_systems))

View File

@ -4,7 +4,6 @@ from flask import jsonify
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 import ConfigService
logger = logging.getLogger(__name__)
@ -24,7 +23,6 @@ class Database(object):
if not x.startswith("system.") and not x == AttackMitigations.COLLECTION_NAME
]
ConfigService.init_config()
AttackConfig.reset_config()
logger.info("DB was reset")
return jsonify(status="OK")