diff --git a/appConfig.py b/appConfig.py new file mode 100644 index 0000000..f54d9c0 --- /dev/null +++ b/appConfig.py @@ -0,0 +1,39 @@ + +live_logs_accepted_scope = { + 'events': ['add', 'edit', 'delete', 'restSearch',], + 'attributes': ['add', 'add_attachment', 'edit', 'revise_object', 'delete', 'restSearch',], + 'eventReports': ['add', 'edit', 'delete',], + 'tags': '*', +} + +user_activity_accepted_scope = { + 'events': ['view', 'add', 'edit', 'delete', 'restSearch',], + 'attributes': ['add', 'add_attachment', 'edit', 'delete', 'restSearch',], + 'objects': ['add', 'edit', 'revise_object', 'delete',], + 'eventReports': ['view', 'add', 'edit', 'delete',], + 'tags': '*', +} + +misp_settings = { + 'Plugin.ZeroMQ_enable': True, + 'Plugin.ZeroMQ_audit_notifications_enable': True, + 'Plugin.ZeroMQ_event_notifications_enable': True, + 'Plugin.ZeroMQ_attribute_notifications_enable': True, + 'MISP.log_new_audit': False, + 'MISP.log_paranoid': True, + 'MISP.log_paranoid_skip_db': True, + 'MISP.log_paranoid_include_post_body': True, + 'MISP.log_auth': True, + 'Security.allow_unsafe_cleartext_apikey_logging': True, +} + +import logging +logger = logging.getLogger('misp-exercise-dashboard') +format = '[%(levelname)s] %(asctime)s - %(message)s' +formatter = logging.Formatter(format) +logging.basicConfig(filename='misp-exercise-dashboard.log', encoding='utf-8', level=logging.DEBUG, format=format) +# create console handler and set level to debug +ch = logging.StreamHandler() +ch.setLevel(logging.INFO) +ch.setFormatter(formatter) +logger.addHandler(ch) diff --git a/config.py.sample b/config.py.sample index 7f27719..3998061 100644 --- a/config.py.sample +++ b/config.py.sample @@ -6,28 +6,3 @@ zmq_url = 'tcp://localhost:50000' misp_url = 'https://localhost/' misp_apikey = 'FI4gCRghRZvLVjlLPLTFZ852x2njkkgPSz0zQ3E0' misp_skipssl = True - -live_logs_accepted_scope = { - 'events': ['add', 'edit', 'delete', 'restSearch',], - 'attributes': ['add', 'add_attachment', 'edit', 'revise_object', 'delete', 'restSearch',], - 'eventReports': ['add', 'edit', 'delete',], - 'tags': '*', -} - -user_activity_accepted_scope = { - 'events': ['view', 'add', 'edit', 'delete', 'restSearch',], - 'attributes': ['add', 'add_attachment', 'edit', 'delete', 'restSearch',], - 'objects': ['add', 'edit', 'revise_object', 'delete',], - 'eventReports': ['view', 'add', 'edit', 'delete',], - 'tags': '*', -} - -import logging -logger = logging.getLogger('misp-exercise-dashboard') -format = '[%(levelname)s] %(asctime)s - %(message)s' -formatter = logging.Formatter(format) -logging.basicConfig(filename='misp-exercise-dashboard.log', encoding='utf-8', level=logging.DEBUG, format=format) -ch = logging.StreamHandler() -ch.setLevel(logging.INFO) -ch.setFormatter(formatter) -logger.addHandler(ch) diff --git a/exercise.py b/exercise.py index 6d124ee..c3db921 100644 --- a/exercise.py +++ b/exercise.py @@ -11,8 +11,7 @@ import jq import db from inject_evaluator import eval_data_filtering, eval_query_mirror, eval_query_search import misp_api -import config -from config import logger +from appConfig import logger ACTIVE_EXERCISES_DIR = "active_exercises" diff --git a/inject_evaluator.py b/inject_evaluator.py index ecab64e..9057d03 100644 --- a/inject_evaluator.py +++ b/inject_evaluator.py @@ -3,7 +3,7 @@ from typing import Union import jq import re import operator -from config import logger +from appConfig import logger def jq_extract(path: str, data: dict, extract_type='first'): diff --git a/misp_api.py b/misp_api.py index 9401bdd..557224e 100644 --- a/misp_api.py +++ b/misp_api.py @@ -11,7 +11,8 @@ from requests_cache import CachedSession from requests.packages.urllib3.exceptions import InsecureRequestWarning # type: ignore requests.packages.urllib3.disable_warnings(InsecureRequestWarning) -from config import misp_url, misp_apikey, misp_skipssl, logger +from config import misp_url, misp_apikey, misp_skipssl +from appConfig import logger, misp_settings requestSession = CachedSession(cache_name='misp_cache', expire_after=timedelta(seconds=5)) adapterCache = requests.adapters.HTTPAdapter(pool_connections=50, pool_maxsize=50) @@ -83,20 +84,24 @@ async def getVersion() -> Union[None, dict]: async def getSettings() -> Union[None, dict]: - SETTING_TO_QUERY = [ - 'Plugin.ZeroMQ_enable', - 'Plugin.ZeroMQ_audit_notifications_enable', - 'Plugin.ZeroMQ_event_notifications_enable', - 'Plugin.ZeroMQ_attribute_notifications_enable', - 'MISP.log_paranoid', - 'MISP.log_paranoid_skip_db', - 'MISP.log_paranoid_include_post_body', - 'MISP.log_auth', - 'Security.allow_unsafe_cleartext_apikey_logging', - ] settings = await get(f'/servers/serverSettings.json') if not settings: return None - return { - setting['setting']: setting['value'] for setting in settings.get('finalSettings', []) if setting['setting'] in SETTING_TO_QUERY - } \ No newline at end of file + data = {} + for settingName, expectedSettingValue in misp_settings.items(): + data[settingName] = { + 'expected_value': expectedSettingValue, + 'value': None + } + for setting in settings.get('finalSettings', []): + if setting['setting'] in misp_settings: + data[setting['setting']]['value'] = setting['value'] + return data + + +async def remediateSetting(setting) ->dict: + if setting in misp_settings: + payload = { + 'value': misp_settings[setting], + } + return await post(f'/servers/serverSettingsEdit/{setting}', payload) \ No newline at end of file diff --git a/notification.py b/notification.py index 3d88cdc..36126c1 100644 --- a/notification.py +++ b/notification.py @@ -5,6 +5,7 @@ import re from typing import Union import db import config +import appConfig from urllib.parse import parse_qs @@ -192,10 +193,10 @@ def is_accepted_notification(notification) -> bool: return False scope, action = get_scope_action_from_url(notification['url']) - if scope in config.live_logs_accepted_scope: - if config.live_logs_accepted_scope == '*': + if scope in appConfig.live_logs_accepted_scope: + if appConfig.live_logs_accepted_scope == '*': return True - elif action in config.live_logs_accepted_scope[scope]: + elif action in appConfig.live_logs_accepted_scope[scope]: return True return False @@ -209,9 +210,9 @@ def is_accepted_user_activity(notification) -> bool: return False scope, action = get_scope_action_from_url(notification['url']) - if scope in config.user_activity_accepted_scope: - if config.user_activity_accepted_scope == '*': + if scope in appConfig.user_activity_accepted_scope: + if appConfig.user_activity_accepted_scope == '*': return True - elif action in config.user_activity_accepted_scope[scope]: + elif action in appConfig.user_activity_accepted_scope[scope]: return True return False \ No newline at end of file diff --git a/server.py b/server.py index 4034b51..1dff2ef 100755 --- a/server.py +++ b/server.py @@ -14,7 +14,7 @@ import exercise as exercise_model import notification as notification_model import db import config -from config import logger +from appConfig import logger import misp_api @@ -123,6 +123,10 @@ async def toggle_verbose_mode(sid, payload): async def toggle_apiquery_mode(sid, payload): return notification_model.set_apiquery_mode(payload['apiquery']) +@sio.event +async def remediate_setting(sid, payload): + return await doSettingRemediation(payload['name']) + @sio.on('*') async def any_event(event, sid, data={}): logger.info('>> Unhandled event %s', event) @@ -201,6 +205,11 @@ async def getDiagnostic() -> dict: return diagnostic +async def doSettingRemediation(setting) -> dict: + result = await misp_api.remediateSetting(setting) + return result + + async def notification_history(): global ZMQ_MESSAGE_COUNT_LAST_TIMESPAN while True: diff --git a/src/components/TheAdminPanel.vue b/src/components/TheAdminPanel.vue index 03e9636..5b4a685 100644 --- a/src/components/TheAdminPanel.vue +++ b/src/components/TheAdminPanel.vue @@ -1,10 +1,11 @@ diff --git a/src/components/TheLiveLogs.vue b/src/components/TheLiveLogs.vue index 359206f..6134b54 100644 --- a/src/components/TheLiveLogs.vue +++ b/src/components/TheLiveLogs.vue @@ -76,7 +76,7 @@ - + diff --git a/src/components/elements/SettingIndicator.vue b/src/components/elements/SettingIndicator.vue new file mode 100644 index 0000000..e69de29 diff --git a/src/socket.js b/src/socket.js index 34b8bf9..95b7c3b 100644 --- a/src/socket.js +++ b/src/socket.js @@ -96,6 +96,18 @@ export function toggleApiQueryMode(enabled) { sendToggleApiQueryMode(enabled) } +export function remediateSetting(setting) { + sendRemediateSetting(setting, (result) => { + console.log(result); + if (result.success) { + state.diagnostic['settings'][setting].value = state.diagnostic['settings'][setting].expected_value + } else { + state.diagnostic['settings'][setting].error = true + state.diagnostic['settings'][setting].errorMessage = result.message + } + }) +} + export const debouncedGetProgress = debounce(getProgress, 200, {leading: true}) export const debouncedGetDiangostic = debounce(getDiangostic, 1000, {leading: true}) @@ -181,6 +193,15 @@ function sendToggleApiQueryMode(enabled) { socket.emit("toggle_apiquery_mode", payload, () => {}) } +function sendRemediateSetting(setting, cb) { + const payload = { + name: setting + } + socket.emit("remediate_setting", payload, (result) => { + cb(result) + }) +} + /* Event listener */ socket.on("connect", () => {
User Time