forked from p15670423/monkey
encrypt credentials in config+telemetry
This commit is contained in:
parent
29e85100d2
commit
06a2e4f18d
|
@ -18,6 +18,6 @@ class MonkeyConfiguration(flask_restful.Resource):
|
|||
if config_json.has_key('reset'):
|
||||
ConfigService.reset_config()
|
||||
else:
|
||||
ConfigService.update_config(config_json)
|
||||
ConfigService.update_config(config_json, should_encrypt=True)
|
||||
return self.get()
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ from cc.database import mongo
|
|||
from cc.services.config import ConfigService
|
||||
from cc.services.edge import EdgeService
|
||||
from cc.services.node import NodeService
|
||||
from cc.encryptor import encryptor
|
||||
|
||||
__author__ = 'Barak'
|
||||
|
||||
|
@ -121,6 +122,8 @@ class Telemetry(flask_restful.Resource):
|
|||
if new_exploit['result']:
|
||||
EdgeService.set_edge_exploited(edge)
|
||||
|
||||
Telemetry.encrypt_exploit_creds(telemetry_json)
|
||||
|
||||
for attempt in telemetry_json['data']['attempts']:
|
||||
if attempt['result']:
|
||||
found_creds = {'user': attempt['user']}
|
||||
|
@ -163,6 +166,31 @@ class Telemetry(flask_restful.Resource):
|
|||
def process_system_info_telemetry(telemetry_json):
|
||||
if 'credentials' in telemetry_json['data']:
|
||||
creds = telemetry_json['data']['credentials']
|
||||
Telemetry.encrypt_system_info_creds(creds)
|
||||
Telemetry.add_system_info_creds_to_config(creds)
|
||||
Telemetry.replace_user_dot_with_comma(creds)
|
||||
|
||||
@staticmethod
|
||||
def process_trace_telemetry(telemetry_json):
|
||||
# Nothing to do
|
||||
return
|
||||
|
||||
@staticmethod
|
||||
def replace_user_dot_with_comma(creds):
|
||||
for user in creds:
|
||||
if -1 != user.find('.'):
|
||||
new_user = user.replace('.', ',')
|
||||
creds[new_user] = creds.pop(user)
|
||||
|
||||
@staticmethod
|
||||
def encrypt_system_info_creds(creds):
|
||||
for user in creds:
|
||||
for field in ['password', 'lm_hash', 'ntlm_hash']:
|
||||
if field in creds[user]:
|
||||
creds[user][field] = encryptor.enc(creds[user][field])
|
||||
|
||||
@staticmethod
|
||||
def add_system_info_creds_to_config(creds):
|
||||
for user in creds:
|
||||
ConfigService.creds_add_username(user)
|
||||
if 'password' in creds[user]:
|
||||
|
@ -172,15 +200,14 @@ class Telemetry(flask_restful.Resource):
|
|||
if 'ntlm_hash' in creds[user]:
|
||||
ConfigService.creds_add_ntlm_hash(creds[user]['ntlm_hash'])
|
||||
|
||||
for user in creds:
|
||||
if -1 != user.find('.'):
|
||||
new_user = user.replace('.', ',')
|
||||
creds[new_user] = creds.pop(user)
|
||||
|
||||
@staticmethod
|
||||
def process_trace_telemetry(telemetry_json):
|
||||
# Nothing to do
|
||||
return
|
||||
def encrypt_exploit_creds(telemetry_json):
|
||||
attempts = telemetry_json['data']['attempts']
|
||||
for i in range(len(attempts)):
|
||||
for field in ['password', 'lm_hash', 'ntlm_hash']:
|
||||
credential = attempts[i][field]
|
||||
if len(credential) > 0:
|
||||
attempts[i][field] = encryptor.enc(credential)
|
||||
|
||||
|
||||
TELEM_PROCESS_DICT = \
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
from cc.database import mongo
|
||||
import copy
|
||||
|
||||
from jsonschema import Draft4Validator, validators
|
||||
|
||||
from cc.database import mongo
|
||||
from cc.encryptor import encryptor
|
||||
from cc.island_config import ISLAND_PORT
|
||||
from cc.utils import local_ip_addresses
|
||||
|
||||
|
@ -794,29 +797,42 @@ SCHEMA = {
|
|||
}
|
||||
}
|
||||
|
||||
ENCRYPTED_CONFIG_ARRAYS = \
|
||||
[
|
||||
['basic', 'credentials', 'exploit_password_list'],
|
||||
['internal', 'exploits', 'exploit_lm_hash_list'],
|
||||
['internal', 'exploits', 'exploit_ntlm_hash_list']
|
||||
]
|
||||
|
||||
|
||||
class ConfigService:
|
||||
default_config = None
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def get_config(is_initial_config=False):
|
||||
def get_config(is_initial_config=False, should_decrypt=True):
|
||||
config = mongo.db.config.find_one({'name': 'initial' if is_initial_config else 'newconfig'}) or {}
|
||||
for field in ('name', '_id'):
|
||||
config.pop(field, None)
|
||||
if should_decrypt and len(config) > 0:
|
||||
ConfigService.decrypt_config(config)
|
||||
return config
|
||||
|
||||
@staticmethod
|
||||
def get_config_value(config_key_as_arr, is_initial_config=False):
|
||||
config_key = reduce(lambda x, y: x+'.'+y, config_key_as_arr)
|
||||
def get_config_value(config_key_as_arr, is_initial_config=False, should_decrypt=True):
|
||||
config_key = reduce(lambda x, y: x + '.' + y, config_key_as_arr)
|
||||
config = mongo.db.config.find_one({'name': 'initial' if is_initial_config else 'newconfig'}, {config_key: 1})
|
||||
for config_key_part in config_key_as_arr:
|
||||
config = config[config_key_part]
|
||||
if should_decrypt and (config_key_as_arr in ENCRYPTED_CONFIG_ARRAYS):
|
||||
config = [encryptor.dec(x) for x in config]
|
||||
return config
|
||||
|
||||
@staticmethod
|
||||
def get_flat_config(is_initial_config=False):
|
||||
config_json = ConfigService.get_config(is_initial_config)
|
||||
def get_flat_config(is_initial_config=False, should_decrypt=True):
|
||||
config_json = ConfigService.get_config(is_initial_config, should_decrypt)
|
||||
flat_config_json = {}
|
||||
for i in config_json:
|
||||
for j in config_json[i]:
|
||||
|
@ -860,27 +876,38 @@ class ConfigService:
|
|||
ConfigService.add_item_to_config_set('internal.exploits.exploit_ntlm_hash_list', ntlm_hash)
|
||||
|
||||
@staticmethod
|
||||
def update_config(config_json):
|
||||
def update_config(config_json, should_encrypt):
|
||||
if should_encrypt:
|
||||
ConfigService.encrypt_config(config_json)
|
||||
mongo.db.config.update({'name': 'newconfig'}, {"$set": config_json}, upsert=True)
|
||||
|
||||
@staticmethod
|
||||
def get_default_config():
|
||||
def init_default_config():
|
||||
if ConfigService.default_config is None:
|
||||
defaultValidatingDraft4Validator = ConfigService._extend_config_with_default(Draft4Validator)
|
||||
config = {}
|
||||
defaultValidatingDraft4Validator(SCHEMA).validate(config)
|
||||
ConfigService.default_config = config
|
||||
|
||||
@staticmethod
|
||||
def get_default_config(should_decrypt=True):
|
||||
ConfigService.init_default_config()
|
||||
config = copy.deepcopy(ConfigService.default_config)
|
||||
if not should_decrypt:
|
||||
ConfigService.encrypt_config(config)
|
||||
return config
|
||||
|
||||
@staticmethod
|
||||
def init_config():
|
||||
if ConfigService.get_config() != {}:
|
||||
if ConfigService.get_config(should_decrypt=False) != {}:
|
||||
return
|
||||
ConfigService.reset_config()
|
||||
|
||||
@staticmethod
|
||||
def reset_config():
|
||||
config = ConfigService.get_default_config()
|
||||
config = ConfigService.get_default_config(should_decrypt=False)
|
||||
ConfigService.set_server_ips_in_config(config)
|
||||
ConfigService.update_config(config)
|
||||
ConfigService.update_config(config, should_encrypt=False)
|
||||
|
||||
@staticmethod
|
||||
def set_server_ips_in_config(config):
|
||||
|
@ -922,3 +949,21 @@ class ConfigService:
|
|||
return validators.extend(
|
||||
validator_class, {"properties": set_defaults},
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def decrypt_config(config):
|
||||
ConfigService._encrypt_config(config, True)
|
||||
|
||||
@staticmethod
|
||||
def encrypt_config(config):
|
||||
ConfigService._encrypt_config(config, False)
|
||||
|
||||
@staticmethod
|
||||
def _encrypt_config(config, is_decrypt=False):
|
||||
for config_arr_as_array in ENCRYPTED_CONFIG_ARRAYS:
|
||||
config_arr = config
|
||||
for config_key_part in config_arr_as_array:
|
||||
config_arr = config_arr[config_key_part]
|
||||
|
||||
for i in range(len(config_arr)):
|
||||
config_arr[i] = encryptor.dec(config_arr[i]) if is_decrypt else encryptor.enc(config_arr[i])
|
||||
|
|
Loading…
Reference in New Issue