encrypt credentials in config+telemetry

This commit is contained in:
Itay Mizeretz 2018-02-13 16:34:37 +02:00
parent 29e85100d2
commit 06a2e4f18d
3 changed files with 170 additions and 98 deletions

View File

@ -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()

View File

@ -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 = \

View File

@ -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])