Implemented enabling/disabling array and boolean configuration fields according to ATT&CK matrix.

This commit is contained in:
VakarisZ 2019-03-28 17:05:29 +02:00
parent b3f7b29640
commit 5e73306b9c
5 changed files with 80 additions and 34 deletions

View File

@ -1,4 +1,5 @@
import logging
from dpath import util
from cc.database import mongo
from attack_schema import SCHEMA
from cc.services.config import ConfigService
@ -28,56 +29,96 @@ def update_config(config_json):
def apply_to_monkey_config():
"""
Applies ATT&CK matrix in the database to the monkey configuration
Applies ATT&CK matrix to the monkey configuration
:return:
"""
attack_techniques = get_techniques()
monkey_config = ConfigService.get_config(False, True, True)
monkey_schema = ConfigService.get_config_schema()
set_exploiters(attack_techniques, monkey_config, monkey_schema)
set_arrays(attack_techniques, monkey_config, monkey_schema)
set_booleans(attack_techniques, monkey_config, monkey_schema)
ConfigService.update_config(monkey_config, True)
def set_exploiters(attack_techniques, monkey_config, monkey_schema):
def set_arrays(attack_techniques, monkey_config, monkey_schema):
"""
Sets exploiters according to ATT&CK matrix
Sets exploiters/scanners/PBAs and other array type fields according to ATT&CK matrix
:param attack_techniques: ATT&CK techniques dict. Format: {'T1110': True, ...}
:param monkey_config: Monkey island's configuration
:param monkey_schema: Monkey configuration schema
"""
for exploiter in monkey_schema['definitions']['exploiter_classes']['anyOf']:
# Go trough each attack technique used by exploiter
for attack_technique in exploiter['attack_techniques']:
# If exploiter's attack technique is disabled, disable the exploiter
if not attack_techniques[attack_technique]:
remove_exploiter(exploiter['enum'][0], monkey_config)
break
# If exploiter's attack technique is enabled, enable the exploiter
else:
add_exploiter(exploiter['enum'][0], monkey_config)
for key, definition in monkey_schema['definitions'].items():
for array_field in definition['anyOf']:
# Go trough each attack technique used by exploiter/scanner/PBA
if 'attack_techniques' not in array_field:
continue
for attack_technique in array_field['attack_techniques']:
# Skip if exploiter is marked with not yet implemented technique
if attack_technique not in attack_techniques:
continue
# If exploiter's attack technique is disabled, disable the exploiter/scanner/PBA
if not attack_techniques[attack_technique]:
r_alter_array(monkey_config, key, array_field['enum'][0], remove=True)
break
# If exploiter's attack technique is enabled, enable the exploiter/scanner/PBA
else:
r_alter_array(monkey_config, key, array_field['enum'][0], remove=False)
def remove_exploiter(exploiter, monkey_config):
def set_booleans(attack_techniques, monkey_config, monkey_schema):
"""
Removes exploiter from monkey's configuration
:param exploiter: Exploiter class name found in SCHEMA->definitions->exploiter_classes -> anyOf -> enum
:param monkey_config: Monkey's configuration
Sets exploiters/scanners/PBAs and other array type fields according to ATT&CK matrix
:param attack_techniques: ATT&CK techniques dict. Format: {'T1110': True, ...}
:param monkey_config: Monkey island's configuration
:param monkey_schema: Monkey configuration schema
"""
if exploiter in monkey_config['exploits']['general']['exploiter_classes']:
monkey_config['exploits']['general']['exploiter_classes'].remove(exploiter)
for key, value in monkey_schema['properties'].items():
r_set_booleans([key], value, attack_techniques, monkey_config)
def add_exploiter(exploiter, monkey_config):
"""
Adds exploiter to monkey's configuration
:param exploiter: Exploiter class name found in SCHEMA->definitions->exploiter_classes -> anyOf -> enum
:param monkey_config: Monkey's configuration
"""
if not exploiter in monkey_config['exploits']['general']['exploiter_classes']:
monkey_config['exploits']['general']['exploiter_classes'].append(exploiter)
def r_set_booleans(path, value, attack_techniques, monkey_config):
if isinstance(value, dict):
dictionary = {}
if 'type' in value and value['type'] == 'boolean' and 'attack_techniques' in value:
set_bool_conf_val(path, should_enable_field(value['attack_techniques'], attack_techniques), monkey_config)
elif 'properties' in value:
dictionary = value['properties']
else:
dictionary = value
for key, item in dictionary.items():
path.append(key)
r_set_booleans(path, item, attack_techniques, monkey_config)
del path[-1]
def set_bool_conf_val(path, val, monkey_config):
util.set(monkey_config, '/'.join(path), val)
def should_enable_field(field_techniques, users_techniques):
for technique in field_techniques:
if not users_techniques[technique]:
return False
return True
def r_alter_array(config_value, array_name, field, remove=True):
if isinstance(config_value, dict):
if array_name in config_value and isinstance(config_value[array_name], list):
if remove and field in config_value[array_name]:
config_value[array_name].remove(field)
elif not remove and field not in config_value[array_name]:
config_value[array_name].append(field)
else:
for prop in config_value.items():
r_alter_array(prop[1], array_name, field, remove)
def get_techniques():
"""
Parses ATT&CK config into a dic of techniques.
:return: Dictionary of techniques. Format: {"T1110": True, "T1075": False, ...}
"""
attack_config = get_config()
techniques = {}
for key, attack_type in attack_config['properties'].items():

View File

@ -14,7 +14,7 @@ SCHEMA = {
"description": "Adversaries may steal the credentials of a specific user or service account using "
"Credential Access techniques or capture credentials earlier in their "
"reconnaissance process.",
"mapped_to": ["T1003"]
"depends_on": ["T1003"]
}
}
},
@ -61,7 +61,7 @@ SCHEMA = {
"description": "Credential dumping is the process of obtaining account login and password "
"information, normally in the form of a hash or a clear text password, "
"from the operating system and software.",
"mapped_to": ["T1078"]
"depends_on": ["T1078"]
}
}
},

View File

@ -116,6 +116,7 @@ SCHEMA = {
"BackdoorUser"
],
"title": "Back door user",
"attack_techniques": ["T1110"]
},
],
},
@ -135,7 +136,8 @@ SCHEMA = {
"enum": [
"SSHFinger"
],
"title": "SSHFinger"
"title": "SSHFinger",
"attack_techniques": ["T1110"]
},
{
"type": "string",
@ -393,6 +395,7 @@ SCHEMA = {
"title": "Harvest Azure Credentials",
"type": "boolean",
"default": True,
"attack_techniques": ["T1110", "T1078"],
"description":
"Determine if the Monkey should try to harvest password credentials from Azure VMs"
},
@ -406,6 +409,7 @@ SCHEMA = {
"title": "Should use Mimikatz",
"type": "boolean",
"default": True,
"attack_techniques": ["T1110", "T1078"],
"description": "Determines whether to use Mimikatz"
},
}

View File

@ -138,9 +138,9 @@ class MatrixComponent extends AuthComponent {
let tempMatrix = this.state.configData;
tempMatrix[techType[0]].properties[technique].value = value;
// Toggle all mapped techniques
if (! mapped && tempMatrix[techType[0]].properties[technique].hasOwnProperty('mapped_to')){
if (! mapped && tempMatrix[techType[0]].properties[technique].hasOwnProperty('depends_on')){
console.log("Triggered");
tempMatrix[techType[0]].properties[technique].mapped_to.forEach(mappedTechnique => {
tempMatrix[techType[0]].properties[technique].depends_on.forEach(mappedTechnique => {
console.log(mappedTechnique)
this.handleTechniqueChange(mappedTechnique, value, true)
})

View File

@ -15,4 +15,5 @@ ipaddress
enum34
pycryptodome
boto3
awscli
awscli
dpath