forked from p15670423/monkey
Refactored matrix parsing, added comments
This commit is contained in:
parent
5e73306b9c
commit
300f821b4c
|
@ -5,6 +5,8 @@ from flask import jsonify, request
|
|||
from cc.auth import jwt_required
|
||||
from cc.services.attack.attack_config import *
|
||||
|
||||
__author__ = "VakarisZ"
|
||||
|
||||
|
||||
class AttackConfiguration(flask_restful.Resource):
|
||||
@jwt_required()
|
||||
|
|
|
@ -42,32 +42,28 @@ def apply_to_monkey_config():
|
|||
|
||||
def set_arrays(attack_techniques, monkey_config, monkey_schema):
|
||||
"""
|
||||
Sets exploiters/scanners/PBAs and other array type fields according to ATT&CK matrix
|
||||
Sets exploiters/scanners/PBAs and other array type fields in monkey's config 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 key, definition in monkey_schema['definitions'].items():
|
||||
for array_field in definition['anyOf']:
|
||||
# Go trough each attack technique used by exploiter/scanner/PBA
|
||||
# Check if current array field has attack_techniques assigned to it
|
||||
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)
|
||||
try:
|
||||
should_remove = not should_enable_field(array_field['attack_techniques'], attack_techniques)
|
||||
except KeyError:
|
||||
# Monkey schema field contains not yet implemented technique
|
||||
continue
|
||||
# If exploiter's attack technique is disabled, disable the exploiter/scanner/PBA
|
||||
r_alter_array(monkey_config, key, array_field['enum'][0], remove=should_remove)
|
||||
|
||||
|
||||
def set_booleans(attack_techniques, monkey_config, monkey_schema):
|
||||
"""
|
||||
Sets exploiters/scanners/PBAs and other array type fields according to ATT&CK matrix
|
||||
Sets boolean type fields, like "should use mimikatz?" in monkey's config 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
|
||||
|
@ -77,10 +73,24 @@ def set_booleans(attack_techniques, monkey_config, monkey_schema):
|
|||
|
||||
|
||||
def r_set_booleans(path, value, attack_techniques, monkey_config):
|
||||
"""
|
||||
Recursively walks trough monkey configuration (DFS) to find which boolean fields needs to be set and sets them
|
||||
according to ATT&CK matrix.
|
||||
:param path: Property names that leads to current value. E.g. ['monkey', 'system_info', 'should_use_mimikatz']
|
||||
:param value: Value of config property
|
||||
:param attack_techniques: ATT&CK techniques dict. Format: {'T1110': True, ...}
|
||||
:param monkey_config: Monkey island's configuration
|
||||
"""
|
||||
if isinstance(value, dict):
|
||||
dictionary = {}
|
||||
# If 'value' is a boolean value that should be set:
|
||||
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)
|
||||
try:
|
||||
set_bool_conf_val(path, should_enable_field(value['attack_techniques'], attack_techniques), monkey_config)
|
||||
except KeyError:
|
||||
# Monkey schema has a technique that is not yet implemented
|
||||
pass
|
||||
# If 'value' is dict, we go over each of it's fields to search for booleans
|
||||
elif 'properties' in value:
|
||||
dictionary = value['properties']
|
||||
else:
|
||||
|
@ -88,14 +98,30 @@ def r_set_booleans(path, value, attack_techniques, monkey_config):
|
|||
for key, item in dictionary.items():
|
||||
path.append(key)
|
||||
r_set_booleans(path, item, attack_techniques, monkey_config)
|
||||
# Method enumerated everything in current path, goes back a level.
|
||||
del path[-1]
|
||||
|
||||
|
||||
def set_bool_conf_val(path, val, monkey_config):
|
||||
"""
|
||||
Changes monkey's configuration by setting one of its boolean fields value
|
||||
:param path: Path to boolean value in monkey's configuration. E.g. ['monkey', 'system_info', 'should_use_mimikatz']
|
||||
:param val: Boolean
|
||||
:param monkey_config: Monkey's configuration
|
||||
"""
|
||||
util.set(monkey_config, '/'.join(path), val)
|
||||
|
||||
|
||||
def should_enable_field(field_techniques, users_techniques):
|
||||
"""
|
||||
Determines whether a single config field should be enabled or not.
|
||||
:param field_techniques: ATT&CK techniques that field uses
|
||||
:param users_techniques: ATT&CK techniques that user chose
|
||||
:return: True, if user enabled all techniques used by the field, false otherwise
|
||||
"""
|
||||
# Method can't decide field value because it has no attack techniques assign to it.
|
||||
if not field_techniques:
|
||||
raise KeyError
|
||||
for technique in field_techniques:
|
||||
if not users_techniques[technique]:
|
||||
return False
|
||||
|
@ -103,6 +129,13 @@ def should_enable_field(field_techniques, users_techniques):
|
|||
|
||||
|
||||
def r_alter_array(config_value, array_name, field, remove=True):
|
||||
"""
|
||||
Recursively searches config (DFS) for array and removes/adds a field.
|
||||
:param config_value: Some object/value from config
|
||||
:param array_name: Name of array this method should search
|
||||
:param field: Field in array that this method should add/remove
|
||||
:param remove: Removes field from array if true, adds it if false
|
||||
"""
|
||||
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]:
|
||||
|
|
|
@ -14,7 +14,7 @@ SCHEMA = {
|
|||
"SmbExploiter"
|
||||
],
|
||||
"title": "SMB Exploiter",
|
||||
"attack_techniques": ["T1110", "T1210", "T1021", "T1035", "T1075"]
|
||||
"attack_techniques": ["T1110", "T1210", "T1021", "T1035", "T1075", "T16616161"]
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
|
@ -409,7 +409,7 @@ SCHEMA = {
|
|||
"title": "Should use Mimikatz",
|
||||
"type": "boolean",
|
||||
"default": True,
|
||||
"attack_techniques": ["T1110", "T1078"],
|
||||
"attack_techniques": ["T1110", "T1078", "T123123123"],
|
||||
"description": "Determines whether to use Mimikatz"
|
||||
},
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue