Files
osmedeus/lib/core/dbutils.py

327 lines
11 KiB
Python

from api.models import *
from workflow import general, direct, direct_list
from core import utils
def parse_special_line(line):
parts = line.split(';;')
jsonl = {}
for part in parts:
key = part.split('|')[0].lower()
value = ''.join(part.split('|')[1:])
jsonl[key] = value
return jsonl
def update_field(default, value, update_type='partial'):
final_value = ''
if update_type.lower() == 'full':
final_value = value
if default == 'N/A' or default == '' or default == 'None':
final_value = value.strip(',')
else:
final_value = default.strip(',') + ',' + value.strip(',')
if ',' in final_value:
results = [x.strip() for x in final_value.split(',')]
final_value = ",".join(list(set(results)))
return final_value
def clean_up(record):
model_fields = ['domain', 'ip_address', 'technologies', 'ports', 'workspace', 'paths', 'screenshot', 'note', 'checksum']
keys = list(record.keys())
for key in keys:
if key not in model_fields:
del record[key]
return record
def parse_summary_field(instance, jsonl, update_type):
# just something we don't want to update
blacklist = ['domain']
record = instance.as_json()
checksum = record.get('checksum')
for key, value in jsonl.items():
if key not in blacklist:
record[key] = update_field(record[key], str(value), update_type)
record = clean_up(record)
updated = Summaries.objects.filter(checksum=checksum).update(**record)
def import_domain_summary(jsonl, workspace, update_type):
# print(jsonl)
domain = jsonl.get('domain', None)
if domain is None:
domain = jsonl.get('ip_address')
instance, created = Summaries.objects.get_or_create(domain=domain, workspace=workspace)
parse_summary_field(instance, jsonl, update_type)
# Summaries part
def parse_domains(line):
if utils.is_json(line.strip()):
jsonl = utils.get_json(line)
elif ';;' in line.strip():
jsonl = parse_special_line(line)
else:
jsonl = {'domain': line.strip()}
return jsonl
# remove report part
def removeReport(speed):
if speed.lower() in 'report':
return True
else:
return False
def clean_input(raw_input, module='general'):
if 'general' in module.lower():
return utils.get_domain(raw_input)
elif 'dir' in module.lower():
return raw_input
def gen_default_config(config_path):
config_path = utils.absolute_path(config_path)
utils.file_copy(utils.TEMPLATE_SERVER_CONFIG, config_path)
configs = utils.just_read_config(config_path, raw=True)
workspaces = utils.join_path(utils.get_parent(
utils.DEAFULT_CONFIG_PATH), 'workspaces')
plugins_path = utils.join_path(utils.ROOT_PATH, 'plugins')
go_path = utils.join_path(utils.ROOT_PATH, 'plugins/go')
data_path = utils.join_path(utils.ROOT_PATH, 'data')
alias_path = utils.join_path(utils.ROOT_PATH, 'lib/alias')
# set some path
configs.set('Enviroments', 'workspaces', workspaces)
configs.set('Enviroments', 'plugins_path', plugins_path)
configs.set('Enviroments', 'data_path', data_path)
configs.set('Enviroments', 'alias_path', alias_path)
configs.set('Enviroments', 'go_path', go_path)
# set some tokens
github_api_key = utils.get_enviroment("GITHUB_API_KEY")
slack_bot_token = utils.get_enviroment("SLACK_BOT_TOKEN")
log_channel = utils.get_enviroment("LOG_CHANNEL")
status_channel = utils.get_enviroment("STATUS_CHANNEL")
report_channel = utils.get_enviroment("REPORT_CHANNEL")
stds_channel = utils.get_enviroment("STDS_CHANNEL")
verbose_report_channel = utils.get_enviroment("VERBOSE_REPORT_CHANNEL")
configs.set('Enviroments', 'github_api_key', github_api_key)
configs.set('Slack', 'slack_bot_token', slack_bot_token)
configs.set('Slack', 'log_channel', log_channel)
configs.set('Slack', 'status_channel', status_channel)
configs.set('Slack', 'report_channel', report_channel)
configs.set('Slack', 'stds_channel', stds_channel)
configs.set('Slack', 'verbose_report_channel', verbose_report_channel)
# monitor mode
backups = utils.join_path(utils.get_parent(
utils.DEAFULT_CONFIG_PATH), 'backups')
utils.make_directory(backups)
monitors = utils.join_path(utils.get_parent(
utils.DEAFULT_CONFIG_PATH), 'monitors')
utils.make_directory(monitors)
configs.set('Monitor', 'monitors', monitors)
configs.set('Monitor', 'backups', backups)
monitor_level = utils.get_enviroment("monitor_level", 'final')
configs.set('Monitor', 'monitor_level', monitor_level)
# monitor bot
slack_monitor_token = utils.get_enviroment("SLACK_MONITOR_TOKEN")
new_channel = utils.get_enviroment("NEW_CHANNEL")
new_name = utils.get_enviroment("NEW_NAME")
missing_channel = utils.get_enviroment("MISSING_CHANNEL")
missing_name = utils.get_enviroment("MISSING_NAME")
configs.set('Monitor', 'slack_monitor_token', slack_monitor_token)
configs.set('Monitor', 'new_channel', new_channel)
configs.set('Monitor', 'new_name', new_name)
configs.set('Monitor', 'missing_channel', missing_channel)
configs.set('Monitor', 'missing_name', missing_name)
# write it again
with open(config_path, 'w+') as configfile:
configs.write(configfile)
# read it again and return
options = utils.just_read_config(config_path)
return options
def load_default_config(config_file=None, forced_reload=False):
if not config_file:
config_file = '~/.osmedeus/server.conf'
options = utils.just_read_config(config_file)
# no config found generate one from default config
if not options:
options = gen_default_config(config_file)
if forced_reload:
options = gen_default_config(config_file)
# looping and adding field to db
for key, value in options.items():
item = {
'name': key,
'value': value,
'alias': key,
'desc': key,
}
instance, created = Configurations.objects.get_or_create(
name=key)
Configurations.objects.filter(name=key).update(**item)
return options
def get_stateless_options(config_file=None):
if config_file:
options = utils.just_read_config(config_file)
else:
raw_options = list(Configurations.objects.values_list('name', 'value'))
options = {}
for item in raw_options:
options[item[0]] = item[1]
return options
# get variable to replace in the command
def get_stateful_options(workspace):
# finding workspace in db
record = Workspaces.objects.filter(workspace=workspace)
if not record.first():
record = Workspaces.objects.filter(target=workspace)
if not record.first():
record = Workspaces.objects.filter(raw_target=workspace)
if not record.first():
return False
stateless_options = get_stateless_options()
# options = record.as_json()
options = {**record.first().as_json(), **stateless_options}
argument_options = {}
# just upper all key
for key in options.keys():
argument_options[key.upper()] = options.get(key)
return argument_options
# @TODO should be done dynamic later
def get_modules(mode='general'):
general = [
'SubdomainScanning',
'Recon',
'ScreenShot',
'TakeOverScanning',
'AssestFinding',
'IPSpace',
'CorsScan',
'PortScan',
'VulnScan'
]
if 'general' in mode.lower():
return ','.join(general)
# really parse command from classes
def really_commands(mode):
modules = utils.get_classes('workflow.{0}'.format(mode))
for module in modules:
# get RCE if you can edit general file in workflow folder :)
module_name = module[0].strip()
module_object = eval('{0}.{1}'.format(mode, module_name))
# parsing commands
try:
routines = module_object.commands
except:
continue
for routine, commands in routines.items():
for command in commands:
item = command
item['mode'] = mode
item['speed'] = routine
item['module'] = module_name
item['alias'] = module_name + "__" + routine.lower() + "__" + \
str(item.get('banner')).lower()
Commands.objects.create(**item)
reports = module_object.reports
parse_report(reports, module_name, mode)
def internal_parse_commands(override=True):
if override:
Commands.objects.all().delete()
ReportsSkeleton.objects.all().delete()
really_commands('general')
really_commands('direct')
really_commands('direct_list')
def parse_report(reports, module, mode):
if type(reports) == str:
item = {
'report_path': reports,
'report_type': 'bash',
'module': module,
'mode': mode,
}
ReportsSkeleton.objects.create(**item)
elif type(reports) == list:
for report in reports:
item = {
'report_path': report.get('path'),
'report_type': report.get('type', 'bash'),
'note': report.get('note', ''),
'module': module,
'mode': mode,
}
ReportsSkeleton.objects.create(**item)
# parsing skeleton commands
def parse_commands(command_path):
if not utils.not_empty_file(command_path):
return False
content = utils.just_read(command_path, get_json=True)
if not content:
return False
modules = content.keys()
for module in modules:
for speed, values in content.get(module).items():
if speed.lower() == 'report':
parse_report(values, module)
else:
for value in values:
if not value.get('cmd'):
continue
item = {
'cmd': value.get('cmd'),
'output_path': value.get('output_path'),
'std_path': value.get('std_path'),
'banner': str(value.get('banner')),
'module': module,
'cmd_type': value.get('cmd_type') if value.get('cmd_type') else 'single',
'speed': speed.lower(),
'alias': module + "__" + speed.lower() + "__" + str(value.get('banner')).lower(),
'chunk': value.get('chunk') if value.get('chunk') else 0,
}
Commands.objects.create(**item)
# print(modules)
return True