forked from p34709852/monkey
Implemented enabling/disabling array and boolean configuration fields according to ATT&CK matrix.
This commit is contained in:
parent
b3f7b29640
commit
5e73306b9c
|
@ -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():
|
||||
|
|
|
@ -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"]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -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"
|
||||
},
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
})
|
||||
|
|
|
@ -15,4 +15,5 @@ ipaddress
|
|||
enum34
|
||||
pycryptodome
|
||||
boto3
|
||||
awscli
|
||||
awscli
|
||||
dpath
|
||||
|
|
Loading…
Reference in New Issue