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 @@
@@ -131,23 +138,54 @@
-
-
-
-
-
+
+
+
+ Setting |
+ Value |
+ Expected Value |
+ Action |
+
+
+
+
+ {{ setting }} |
+
+ - none -
+ {{ settingValues.value }}
+ |
+ {{ settingValues.expected_value }} |
+
+ Error: {{ settingValues.errorMessage }}
+
+
+
+ OK
+
+ |
+
+
+
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 @@
-
+
|
User |
Time |
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", () => {