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'):
|
if config_json.has_key('reset'):
|
||||||
ConfigService.reset_config()
|
ConfigService.reset_config()
|
||||||
else:
|
else:
|
||||||
ConfigService.update_config(config_json)
|
ConfigService.update_config(config_json, should_encrypt=True)
|
||||||
return self.get()
|
return self.get()
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ from cc.database import mongo
|
||||||
from cc.services.config import ConfigService
|
from cc.services.config import ConfigService
|
||||||
from cc.services.edge import EdgeService
|
from cc.services.edge import EdgeService
|
||||||
from cc.services.node import NodeService
|
from cc.services.node import NodeService
|
||||||
|
from cc.encryptor import encryptor
|
||||||
|
|
||||||
__author__ = 'Barak'
|
__author__ = 'Barak'
|
||||||
|
|
||||||
|
@ -121,6 +122,8 @@ class Telemetry(flask_restful.Resource):
|
||||||
if new_exploit['result']:
|
if new_exploit['result']:
|
||||||
EdgeService.set_edge_exploited(edge)
|
EdgeService.set_edge_exploited(edge)
|
||||||
|
|
||||||
|
Telemetry.encrypt_exploit_creds(telemetry_json)
|
||||||
|
|
||||||
for attempt in telemetry_json['data']['attempts']:
|
for attempt in telemetry_json['data']['attempts']:
|
||||||
if attempt['result']:
|
if attempt['result']:
|
||||||
found_creds = {'user': attempt['user']}
|
found_creds = {'user': attempt['user']}
|
||||||
|
@ -163,25 +166,49 @@ class Telemetry(flask_restful.Resource):
|
||||||
def process_system_info_telemetry(telemetry_json):
|
def process_system_info_telemetry(telemetry_json):
|
||||||
if 'credentials' in telemetry_json['data']:
|
if 'credentials' in telemetry_json['data']:
|
||||||
creds = telemetry_json['data']['credentials']
|
creds = telemetry_json['data']['credentials']
|
||||||
for user in creds:
|
Telemetry.encrypt_system_info_creds(creds)
|
||||||
ConfigService.creds_add_username(user)
|
Telemetry.add_system_info_creds_to_config(creds)
|
||||||
if 'password' in creds[user]:
|
Telemetry.replace_user_dot_with_comma(creds)
|
||||||
ConfigService.creds_add_password(creds[user]['password'])
|
|
||||||
if 'lm_hash' in creds[user]:
|
|
||||||
ConfigService.creds_add_lm_hash(creds[user]['lm_hash'])
|
|
||||||
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
|
@staticmethod
|
||||||
def process_trace_telemetry(telemetry_json):
|
def process_trace_telemetry(telemetry_json):
|
||||||
# Nothing to do
|
# Nothing to do
|
||||||
return
|
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]:
|
||||||
|
ConfigService.creds_add_password(creds[user]['password'])
|
||||||
|
if 'lm_hash' in creds[user]:
|
||||||
|
ConfigService.creds_add_lm_hash(creds[user]['lm_hash'])
|
||||||
|
if 'ntlm_hash' in creds[user]:
|
||||||
|
ConfigService.creds_add_ntlm_hash(creds[user]['ntlm_hash'])
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
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 = \
|
TELEM_PROCESS_DICT = \
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
from cc.database import mongo
|
import copy
|
||||||
|
|
||||||
from jsonschema import Draft4Validator, validators
|
from jsonschema import Draft4Validator, validators
|
||||||
|
|
||||||
|
from cc.database import mongo
|
||||||
|
from cc.encryptor import encryptor
|
||||||
from cc.island_config import ISLAND_PORT
|
from cc.island_config import ISLAND_PORT
|
||||||
from cc.utils import local_ip_addresses
|
from cc.utils import local_ip_addresses
|
||||||
|
|
||||||
|
@ -17,60 +20,60 @@ SCHEMA = {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"SmbExploiter"
|
"SmbExploiter"
|
||||||
],
|
],
|
||||||
"title": "SMB Exploiter"
|
"title": "SMB Exploiter"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"WmiExploiter"
|
"WmiExploiter"
|
||||||
],
|
],
|
||||||
"title": "WMI Exploiter"
|
"title": "WMI Exploiter"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"RdpExploiter"
|
"RdpExploiter"
|
||||||
],
|
],
|
||||||
"title": "RDP Exploiter (UNSAFE)"
|
"title": "RDP Exploiter (UNSAFE)"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"Ms08_067_Exploiter"
|
"Ms08_067_Exploiter"
|
||||||
],
|
],
|
||||||
"title": "MS08-067 Exploiter (UNSAFE)"
|
"title": "MS08-067 Exploiter (UNSAFE)"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"SSHExploiter"
|
"SSHExploiter"
|
||||||
],
|
],
|
||||||
"title": "SSH Exploiter"
|
"title": "SSH Exploiter"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"ShellShockExploiter"
|
"ShellShockExploiter"
|
||||||
],
|
],
|
||||||
"title": "ShellShock Exploiter"
|
"title": "ShellShock Exploiter"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"SambaCryExploiter"
|
"SambaCryExploiter"
|
||||||
],
|
],
|
||||||
"title": "SambaCry Exploiter"
|
"title": "SambaCry Exploiter"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"ElasticGroovyExploiter"
|
"ElasticGroovyExploiter"
|
||||||
],
|
],
|
||||||
"title": "ElasticGroovy Exploiter"
|
"title": "ElasticGroovy Exploiter"
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -79,46 +82,46 @@ SCHEMA = {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"SMBFinger"
|
"SMBFinger"
|
||||||
],
|
],
|
||||||
"title": "SMBFinger"
|
"title": "SMBFinger"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"SSHFinger"
|
"SSHFinger"
|
||||||
],
|
],
|
||||||
"title": "SSHFinger"
|
"title": "SSHFinger"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"PingScanner"
|
"PingScanner"
|
||||||
],
|
],
|
||||||
"title": "PingScanner"
|
"title": "PingScanner"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"HTTPFinger"
|
"HTTPFinger"
|
||||||
],
|
],
|
||||||
"title": "HTTPFinger"
|
"title": "HTTPFinger"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"MySQLFinger"
|
"MySQLFinger"
|
||||||
],
|
],
|
||||||
"title": "MySQLFinger"
|
"title": "MySQLFinger"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"ElasticFinger"
|
"ElasticFinger"
|
||||||
],
|
],
|
||||||
"title": "ElasticFinger"
|
"title": "ElasticFinger"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -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:
|
class ConfigService:
|
||||||
|
default_config = None
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@staticmethod
|
@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 {}
|
config = mongo.db.config.find_one({'name': 'initial' if is_initial_config else 'newconfig'}) or {}
|
||||||
for field in ('name', '_id'):
|
for field in ('name', '_id'):
|
||||||
config.pop(field, None)
|
config.pop(field, None)
|
||||||
|
if should_decrypt and len(config) > 0:
|
||||||
|
ConfigService.decrypt_config(config)
|
||||||
return config
|
return config
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_config_value(config_key_as_arr, is_initial_config=False):
|
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_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})
|
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:
|
for config_key_part in config_key_as_arr:
|
||||||
config = config[config_key_part]
|
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
|
return config
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_flat_config(is_initial_config=False):
|
def get_flat_config(is_initial_config=False, should_decrypt=True):
|
||||||
config_json = ConfigService.get_config(is_initial_config)
|
config_json = ConfigService.get_config(is_initial_config, should_decrypt)
|
||||||
flat_config_json = {}
|
flat_config_json = {}
|
||||||
for i in config_json:
|
for i in config_json:
|
||||||
for j in config_json[i]:
|
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)
|
ConfigService.add_item_to_config_set('internal.exploits.exploit_ntlm_hash_list', ntlm_hash)
|
||||||
|
|
||||||
@staticmethod
|
@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)
|
mongo.db.config.update({'name': 'newconfig'}, {"$set": config_json}, upsert=True)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_default_config():
|
def init_default_config():
|
||||||
defaultValidatingDraft4Validator = ConfigService._extend_config_with_default(Draft4Validator)
|
if ConfigService.default_config is None:
|
||||||
config = {}
|
defaultValidatingDraft4Validator = ConfigService._extend_config_with_default(Draft4Validator)
|
||||||
defaultValidatingDraft4Validator(SCHEMA).validate(config)
|
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
|
return config
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def init_config():
|
def init_config():
|
||||||
if ConfigService.get_config() != {}:
|
if ConfigService.get_config(should_decrypt=False) != {}:
|
||||||
return
|
return
|
||||||
ConfigService.reset_config()
|
ConfigService.reset_config()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def reset_config():
|
def reset_config():
|
||||||
config = ConfigService.get_default_config()
|
config = ConfigService.get_default_config(should_decrypt=False)
|
||||||
ConfigService.set_server_ips_in_config(config)
|
ConfigService.set_server_ips_in_config(config)
|
||||||
ConfigService.update_config(config)
|
ConfigService.update_config(config, should_encrypt=False)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def set_server_ips_in_config(config):
|
def set_server_ips_in_config(config):
|
||||||
|
@ -922,3 +949,21 @@ class ConfigService:
|
||||||
return validators.extend(
|
return validators.extend(
|
||||||
validator_class, {"properties": set_defaults},
|
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