From 7e6009b52a65093f7bb73d3e7a4c2bc959f7e304 Mon Sep 17 00:00:00 2001 From: Davide Arcuri Date: Mon, 26 Feb 2024 14:29:39 +0100 Subject: [PATCH] python3.12 - go1.22 - ws updates --- .envs/.local/.django | 2 +- .pre-commit-config.yaml | 2 +- compose/local/dask/Dockerfile | 2 +- compose/local/django/Dockerfile | 8 +- compose/local/nginx/conf/default.conf | 4 +- config/routing.py | 10 +- config/settings/base.py | 2 +- orochi/templates/website/index.html | 3 +- orochi/utils/volatility_dask_elk.py | 64 +------- orochi/website/admin.py | 4 +- orochi/website/api/views.py | 10 +- orochi/website/consumers.py | 15 +- orochi/website/defaults.py | 165 ++++++++++++++++++++ orochi/website/middleware.py | 9 +- orochi/website/models.py | 217 ++++++++------------------ orochi/website/routing.py | 4 +- orochi/website/views.py | 16 +- requirements/base.txt | 24 ++- requirements/local.txt | 8 +- 19 files changed, 294 insertions(+), 275 deletions(-) create mode 100644 orochi/website/defaults.py diff --git a/.envs/.local/.django b/.envs/.local/.django index 8180f45e..b1b81839 100755 --- a/.envs/.local/.django +++ b/.envs/.local/.django @@ -52,4 +52,4 @@ no_proxy= # CSRF_TRUSTED_ORIGINS # ------------------------------------------------------------------------------ -CSRF_TRUSTED_ORIGINS=https://orochi.dev +CSRF_TRUSTED_ORIGINS=https://orochi.dev,https://localhost diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bd7c07f7..fce097c6 100755 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -11,7 +11,7 @@ repos: - id: check-yaml - repo: https://github.com/psf/black - rev: 24.1.1 + rev: 24.2.0 hooks: - id: black diff --git a/compose/local/dask/Dockerfile b/compose/local/dask/Dockerfile index 7ba87300..3eb103c2 100644 --- a/compose/local/dask/Dockerfile +++ b/compose/local/dask/Dockerfile @@ -1,4 +1,4 @@ -FROM daskdev/dask:2024.1.1-py3.11 +FROM daskdev/dask:dev-py3.12 ENV DEBIAN_FRONTEND noninteractive RUN echo "export VIRTUAL_ENV=`python -c 'import sys; print(sys.prefix)'`" >> /envfile diff --git a/compose/local/django/Dockerfile b/compose/local/django/Dockerfile index b46c5290..4830290d 100644 --- a/compose/local/django/Dockerfile +++ b/compose/local/django/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.11-slim-buster as common-base +FROM python:3.12-slim-bookworm as common-base ENV DJANGO_SETTINGS_MODULE config.settings.local ENV PYTHONUNBUFFERED 1 @@ -57,10 +57,8 @@ RUN python setup.py build FROM base-builder as go-builder WORKDIR / -RUN curl https://dl.google.com/go/go1.15.2.linux-amd64.tar.gz --output go1.15.2.linux-amd64.tar.gz \ - && tar -C /usr/local -xzf go1.15.2.linux-amd64.tar.gz -RUN curl https://dl.google.com/go/go1.15.2.linux-amd64.tar.gz --output go1.15.2.linux-amd64.tar.gz \ - && tar -C /usr/local -xzf go1.15.2.linux-amd64.tar.gz +RUN curl https://dl.google.com/go/go1.22.0.linux-amd64.tar.gz --output go1.22.0.linux-amd64.tar.gz \ + && tar -C /usr/local -xzf go1.22.0.linux-amd64.tar.gz RUN git clone https://github.com/volatilityfoundation/dwarf2json.git WORKDIR /dwarf2json RUN /usr/local/go/bin/go build diff --git a/compose/local/nginx/conf/default.conf b/compose/local/nginx/conf/default.conf index 336dbdb7..9000964a 100644 --- a/compose/local/nginx/conf/default.conf +++ b/compose/local/nginx/conf/default.conf @@ -23,8 +23,8 @@ server { } server { - listen 443 ssl http2; - listen [::]:443 ssl http2; + listen 443 ssl; + listen [::]:443 ssl; server_name orochi.dev; diff --git a/config/routing.py b/config/routing.py index e662ff08..ccb6943d 100644 --- a/config/routing.py +++ b/config/routing.py @@ -1,13 +1,15 @@ -import orochi.website.routing -from django.core.asgi import get_asgi_application from channels.auth import AuthMiddlewareStack from channels.routing import ProtocolTypeRouter, URLRouter +from channels.security.websocket import AllowedHostsOriginValidator +from django.core.asgi import get_asgi_application + +import orochi.website.routing application = ProtocolTypeRouter( { "http": get_asgi_application(), - "websocket": AuthMiddlewareStack( - URLRouter(orochi.website.routing.websocket_urlpatterns) + "websocket": AllowedHostsOriginValidator( + AuthMiddlewareStack(URLRouter(orochi.website.routing.websocket_urlpatterns)) ), } ) diff --git a/config/settings/base.py b/config/settings/base.py index a47917a0..bfb5a479 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -276,7 +276,7 @@ ASGI_APPLICATION = "config.routing.application" CHANNEL_LAYERS = { "default": { - "BACKEND": "channels_redis.pubsub.RedisPubSubChannelLayer", + "BACKEND": "channels_redis.core.RedisChannelLayer", "CONFIG": { "hosts": [(env("REDIS_SERVER"), env("REDIS_PORT"))], }, diff --git a/orochi/templates/website/index.html b/orochi/templates/website/index.html index e75d5f7a..11b95a2a 100644 --- a/orochi/templates/website/index.html +++ b/orochi/templates/website/index.html @@ -148,7 +148,8 @@
History Log
}); // WS, UPDATE NOTE - const chatSocket = new WebSocket(`ws://${window.location.host}/ws/notify/{{ user.pk }}/`); + var ws_scheme = window.location.protocol == "https:" ? "wss" : "ws"; + const chatSocket = new WebSocket(`${ws_scheme}://${window.location.host}/ws/notify/{{ user.pk }}/`); chatSocket.onmessage = function (e) { const data = JSON.parse(e.data); const text = data.message.split("||")[1]; diff --git a/orochi/utils/volatility_dask_elk.py b/orochi/utils/volatility_dask_elk.py index 6a6ae2ba..c1c7e4ad 100644 --- a/orochi/utils/volatility_dask_elk.py +++ b/orochi/utils/volatility_dask_elk.py @@ -21,15 +21,13 @@ import requests import volatility3.plugins import vt -from asgiref.sync import async_to_sync, sync_to_async +from asgiref.sync import sync_to_async from bs4 import BeautifulSoup -from channels.layers import DEFAULT_CHANNEL_LAYER, channel_layers from clamdpy import ClamdUnixSocket from distributed import fire_and_forget, get_client, rejoin, secede from django.conf import settings from elasticsearch import Elasticsearch, helpers from elasticsearch_dsl import Search -from guardian.shortcuts import get_users_with_perms from regipy.registry import RegistryHive from volatility3 import cli, framework from volatility3.cli.text_renderer import ( @@ -56,7 +54,7 @@ ListRequirement, ) -from orochi.website.models import ( +from orochi.website.defaults import ( DUMP_STATUS_COMPLETED, DUMP_STATUS_ERROR, DUMP_STATUS_MISSING_SYMBOLS, @@ -68,11 +66,8 @@ RESULT_STATUS_SUCCESS, RESULT_STATUS_UNSATISFIED, SERVICE_VIRUSTOTAL, - CustomRule, - Dump, - Result, - Service, ) +from orochi.website.models import CustomRule, Dump, Result, Service BANNER_REGEX = r'^"?Linux version (?P\S+) (?P.+) \(((?Pgcc.+)) #(?P\d+)(?P.+)$"?' @@ -83,16 +78,6 @@ "Changed Date": "#FFFF00", } -TOAST_COLORS = { - 0: "blue", - 1: "yellow", - 2: "green", - 3: "green", - 4: "orange", - 5: "red", - 6: "black", -} - class MuteProgress(object): """ @@ -326,41 +311,6 @@ def run_regipy(filepath): logging.error(e) -def send_to_ws(dump, result=None, plugin_name=None, message=None, color=None): - """ - Notifies plugin result to websocket - """ - - users = get_users_with_perms(dump, only_with_perms_in=["can_see"]) - channel_layer = channel_layers.make_backend(DEFAULT_CHANNEL_LAYER) - if not channel_layer: - return - for user in users: - if result and plugin_name: - async_to_sync(channel_layer.group_send)( - f"chat_{user.pk}", - { - "type": "chat_message", - "message": f"""{datetime.datetime.now().strftime("%d/%m/%Y %H:%M")}||""" - f"""Plugin {plugin_name} on dump {dump.name} ended
""" - f"""Status: {result.get_result_display()}""", - }, - ) - elif message and color: - async_to_sync(channel_layer.group_send)( - f"chat_{user.pk}", - { - "type": "chat_message", - "message": f"""{datetime.datetime.now().strftime("%d/%m/%Y %H:%M")}||""" - f"""Message on dump {dump.name}
{message}""", - }, - ) - try: - channel_layer.close() - except RuntimeError as excp: - logging.error(str(excp)) - - def run_plugin(dump_obj, plugin_obj, params=None, user_pk=None): """ Execute a single plugin on a dump with optional params. @@ -599,7 +549,6 @@ def run_plugin(dump_obj, plugin_obj, params=None, user_pk=None): result.save() logging.debug(f"[dump {dump_obj.pk} - plugin {plugin_obj.pk}] empty") - send_to_ws(dump_obj, result, plugin_obj.name) return 0 except Exception as excp: @@ -609,7 +558,6 @@ def run_plugin(dump_obj, plugin_obj, params=None, user_pk=None): result.result = RESULT_STATUS_ERROR result.description = "\n".join(fulltrace) result.save() - send_to_ws(dump_obj, result, plugin_obj.name) logging.error(f"[dump {dump_obj.pk} - plugin {plugin_obj.pk}] generic error") return 0 @@ -910,9 +858,6 @@ def unzip_then_run(dump_pk, user_pk, password, restart, move): for result in tasks_list: result.result = RESULT_STATUS_DISABLED result.save() - send_to_ws( - dump, message="Missing symbols! All plugin are disabled", color=4 - ) except Exception as excp: logging.error(f"[dump {dump_pk}] - {excp}") dump.description = excp @@ -926,6 +871,3 @@ def unzip_then_run(dump_pk, user_pk, password, restart, move): for result in tasks_list: result.result = RESULT_STATUS_DISABLED result.save() - send_to_ws( - dump, message="Error in file creation! All plugin are disabled", color=4 - ) diff --git a/orochi/website/admin.py b/orochi/website/admin.py index 9e876000..97af26bd 100644 --- a/orochi/website/admin.py +++ b/orochi/website/admin.py @@ -1,19 +1,17 @@ from allauth.socialaccount.models import SocialAccount, SocialApp, SocialToken from django.contrib import admin from django.contrib.auth.models import Group -from django.db import models from django_admin_listfilter_dropdown.filters import RelatedDropdownFilter from django_admin_multiple_choice_list_filter.list_filters import ( MultipleChoiceListFilter, ) from django_file_form.model_admin import FileFormAdmin from django_file_form.models import TemporaryUploadedFile -from django_json_widget.widgets import JSONEditorWidget from guardian.admin import GuardedModelAdmin +from orochi.website.defaults import RESULT from orochi.website.forms import PluginCreateAdminForm, PluginEditAdminForm from orochi.website.models import ( - RESULT, Bookmark, CustomRule, Dump, diff --git a/orochi/website/api/views.py b/orochi/website/api/views.py index 4f25fdec..57bdb212 100644 --- a/orochi/website/api/views.py +++ b/orochi/website/api/views.py @@ -36,14 +36,8 @@ ShortDumpSerializer, ShortResultSerializer, ) -from orochi.website.models import ( - RESULT_STATUS_NOT_STARTED, - RESULT_STATUS_RUNNING, - Dump, - Plugin, - Result, - UserPlugin, -) +from orochi.website.defaults import RESULT_STATUS_NOT_STARTED, RESULT_STATUS_RUNNING +from orochi.website.models import Dump, Plugin, Result, UserPlugin from orochi.website.views import index_f_and_f, plugin_f_and_f diff --git a/orochi/website/consumers.py b/orochi/website/consumers.py index 5fa42a49..48d3c67e 100644 --- a/orochi/website/consumers.py +++ b/orochi/website/consumers.py @@ -1,4 +1,5 @@ import json +import logging from channels.generic.websocket import AsyncWebsocketConsumer @@ -7,25 +8,27 @@ class NotifyConsumer(AsyncWebsocketConsumer): async def connect(self): # User connects to his update channel self.room_name = self.scope["url_route"]["kwargs"]["user_id"] - self.room_group_name = f"chat_{self.room_name}" - await self.channel_layer.group_add(self.room_group_name, self.channel_name) + await self.channel_layer.group_add(f"chat_{self.room_name}", self.channel_name) + logging.info(f"User connected to chat_{self.room_name} - {self.channel_name}") await self.accept() async def disconnect(self, close_code): # User leaves room group + logging.info( + f"User disconnected from {self.room_group_name} - {self.channel_name}" + ) await self.channel_layer.group_discard(self.room_group_name, self.channel_name) async def receive(self, text_data): # Receive message from WebSocket text_data_json = json.loads(text_data) - message = text_data_json["message"] # Send message to room group await self.channel_layer.group_send( - self.room_group_name, {"type": "chat_message", "message": message} + self.room_group_name, + {"type": "chat_message", "message": text_data_json["message"]}, ) async def chat_message(self, event): # Receive message from room group - message = event["message"] - await self.send(text_data=json.dumps({"message": message})) + await self.send(text_data=json.dumps({"message": event["message"]})) diff --git a/orochi/website/defaults.py b/orochi/website/defaults.py new file mode 100644 index 00000000..2c5dc032 --- /dev/null +++ b/orochi/website/defaults.py @@ -0,0 +1,165 @@ +OPERATING_SYSTEM = ( + ("Linux", "Linux"), + ("Windows", "Windows"), + ("Mac", "Mac"), + ("Other", "Other"), +) + +TOAST_RESULT_COLORS = { + 0: "blue", + 1: "yellow", + 2: "green", + 3: "green", + 4: "orange", + 5: "red", + 6: "black", +} + +TOAST_DUMP_COLORS = { + 1: "green", + 2: "green", + 3: "red", + 4: "red", + 5: "orange", +} + +SERVICE_VIRUSTOTAL = 1 +SERVICE_MISP = 2 +SERVICE_MAXMIND = 3 +SERVICES = ( + (SERVICE_VIRUSTOTAL, "VirusTotal"), + (SERVICE_MISP, "MISP"), + (SERVICE_MAXMIND, "MAXMIND"), +) + +DUMP_STATUS_CREATED = 1 +DUMP_STATUS_COMPLETED = 2 +DUMP_STATUS_DELETED = 3 +DUMP_STATUS_ERROR = 4 +DUMP_STATUS_MISSING_SYMBOLS = 5 +STATUS = ( + (DUMP_STATUS_CREATED, "Created"), + (DUMP_STATUS_COMPLETED, "Completed"), + (DUMP_STATUS_DELETED, "Deleted"), + (DUMP_STATUS_ERROR, "Error"), + (DUMP_STATUS_MISSING_SYMBOLS, "Missing Symbols"), +) + +RESULT_STATUS_NOT_STARTED = 0 +RESULT_STATUS_RUNNING = 1 +RESULT_STATUS_EMPTY = 2 +RESULT_STATUS_SUCCESS = 3 +RESULT_STATUS_UNSATISFIED = 4 +RESULT_STATUS_ERROR = 5 +RESULT_STATUS_DISABLED = 6 +RESULT = ( + (RESULT_STATUS_NOT_STARTED, "Not Started"), + (RESULT_STATUS_RUNNING, "Running"), + (RESULT_STATUS_EMPTY, "Empty"), + (RESULT_STATUS_SUCCESS, "Success"), + (RESULT_STATUS_UNSATISFIED, "Unsatisfied"), + (RESULT_STATUS_ERROR, "Error"), + (RESULT_STATUS_DISABLED, "Disabled"), +) +ICONS = ( + ("ss-arn", "Arabian Nights"), + ("ss-atq", "Antiquities"), + ("ss-leg", "Legends"), + ("ss-drk", "The Dark"), + ("ss-fem", "Fallen Empires"), + ("ss-hml", "Homelands"), + ("ss-ice", "Ice Age"), + ("ss-ice2", "Ice Age (Original)"), + ("ss-all", "Alliances"), + ("ss-csp", "Coldsnap"), + ("ss-mir", "Mirage"), + ("ss-vis", "Visions"), + ("ss-wth", "Weatherlight"), + ("ss-tmp", "Tempest"), + ("ss-sth", "Stronghold"), + ("ss-exo", "Exodus"), + ("ss-usg", "Urza's Saga"), + ("ss-ulg", "Urza's Legacy"), + ("ss-uds", "Urza's Destiny"), + ("ss-mmq", "Mercadian Masques"), + ("ss-nem", "Nemesis"), + ("ss-pcy", "Prophecy"), + ("ss-inv", "Invasion"), + ("ss-pls", "Planeshift"), + ("ss-apc", "Apocalypse"), + ("ss-ody", "Odyssey"), + ("ss-tor", "Torment"), + ("ss-jud", "Judgement"), + ("ss-ons", "Onslaught"), + ("ss-lgn", "Legions"), + ("ss-scg", "Scourge"), + ("ss-mrd", "Mirrodin"), + ("ss-dst", "Darksteel"), + ("ss-5dn", "Fifth Dawn"), + ("ss-chk", "Champions of Kamigawa"), + ("ss-bok", "Betrayers of Kamigawa"), + ("ss-sok", "Saviors of Kamigawa"), + ("ss-rav", "Ravnica"), + ("ss-gpt", "Guildpact"), + ("ss-dis", "Dissension"), + ("ss-tsp", "Time Spiral"), + ("ss-plc", "Planar Chaos"), + ("ss-fut", "Future Sight"), + ("ss-lrw", "Lorwyn"), + ("ss-mor", "Morningtide"), + ("ss-shm", "Shadowmoor"), + ("ss-eve", "Eventide"), + ("ss-ala", "Shards of Alara"), + ("ss-con", "Conflux"), + ("ss-arb", "Alara Reborn"), + ("ss-zen", "Zendikar"), + ("ss-wwk", "Worldwake"), + ("ss-roe", "Rise of the Eldrazi"), + ("ss-som", "Scars of Mirrodin"), + ("ss-mbs", "Mirrodin Besieged"), + ("ss-nph", "New Phyrexia"), + ("ss-isd", "Innistrad"), + ("ss-dka", "Dark Ascension"), + ("ss-avr", "Avacyn Restored"), + ("ss-rtr", "Return to Ravnica"), + ("ss-gtc", "Gatecrash"), + ("ss-dgm", "Dragon's Maze"), + ("ss-ths", "Theros"), + ("ss-bng", "Born of the Gods"), + ("ss-jou", "Journey into Nyx"), + ("ss-ktk", "Khans of Tarkir"), + ("ss-frf", "Fate Reforged"), + ("ss-dtk", "Dragons of Tarkir"), + ("ss-bfz", "Battle for Zendikar"), + ("ss-ogw", "Oath of the Gatewatch"), + ("ss-soi", "Shadows Over Innistrad"), + ("ss-emn", "Eldritch Moon"), + ("ss-kld", "Kaladesh"), + ("ss-aer", "Aether Revolt"), + ("ss-akh", "Amonkhet"), + ("ss-hou", "Hour of Devastation"), + ("ss-xln", "Ixalan"), + ("ss-rix", "Rivals of Ixalan"), + ("ss-dom", "Dominaria"), + ("ss-grn", "Guilds of Ravnica"), + ("ss-rna", "Ravnica Allegiance"), + ("ss-war", "War of the Spark"), + ("ss-eld", "Throne of Eldraine"), + ("ss-thb", "Theros: Beyond Death"), + ("ss-iko", "koria: Lair of Behemoths"), + ("ss-znr", "Zendikar Rising"), + ("ss-khm", "Kaldheim"), + ("ss-stx", "Strixhaven: School of Mages"), + ("ss-mid", "Innistrad: Midnight Hunt"), + ("ss-vow", "Innistrad: Crimson Vow"), + ("ss-neo", "Kamigawa: Neon Dynasty"), + ("ss-snc", "Streets of New Capenna"), + ("ss-dmu", "Dominaria United"), + ("ss-bro", "The Brothers' War"), + ("ss-one", "Phyrexia: All Will Be One"), + ("ss-mom", "March of the Machine"), + ("ss-mat", "March of the Machine: The Aftermath"), + ("ss-woe", "Wilds of Eldraine"), +) + +DEFAULT_YARA_PATH = "/yara/default.yara" diff --git a/orochi/website/middleware.py b/orochi/website/middleware.py index 712f20ff..168fef2e 100644 --- a/orochi/website/middleware.py +++ b/orochi/website/middleware.py @@ -3,12 +3,13 @@ from django.urls import reverse from guardian.shortcuts import get_objects_for_user -from orochi.website.models import ( +from orochi.website.defaults import ( RESULT_STATUS_DISABLED, RESULT_STATUS_NOT_STARTED, RESULT_STATUS_RUNNING, - Bookmark, + TOAST_RESULT_COLORS, ) +from orochi.website.models import Bookmark class UpdatesMiddleware: @@ -28,15 +29,13 @@ def process_template_response(self, request, response): ): news = [] - colors = {2: "green", 3: "green", 4: "yellow", 5: "red"} - dumps = get_objects_for_user(request.user, "website.can_see") for dump in dumps: news.extend( { "date": result.updated_at, "text": f"Plugin {result.plugin.name} on dump {dump.name} ended
" - f"Status: {result.get_result_display()}", + f"Status: {result.get_result_display()}", } for result in dump.result_set.exclude( result__in=[ diff --git a/orochi/website/models.py b/orochi/website/models.py index cd140ca5..5fae3808 100644 --- a/orochi/website/models.py +++ b/orochi/website/models.py @@ -1,5 +1,8 @@ import os +from datetime import datetime +from asgiref.sync import async_to_sync +from channels.layers import get_channel_layer from colorfield.fields import ColorField from django.conf import settings from django.contrib.auth import get_user_model @@ -7,157 +10,20 @@ from django.db import models from django.db.models.signals import post_save from django.dispatch import receiver -from guardian.shortcuts import assign_perm - -from orochi.ya.models import Ruleset - -OPERATING_SYSTEM = ( - ("Linux", "Linux"), - ("Windows", "Windows"), - ("Mac", "Mac"), - ("Other", "Other"), -) - -SERVICE_VIRUSTOTAL = 1 -SERVICE_MISP = 2 -SERVICE_MAXMIND = 3 -SERVICES = ( - (SERVICE_VIRUSTOTAL, "VirusTotal"), - (SERVICE_MISP, "MISP"), - (SERVICE_MAXMIND, "MAXMIND"), -) - -DUMP_STATUS_CREATED = 1 -DUMP_STATUS_COMPLETED = 2 -DUMP_STATUS_DELETED = 3 -DUMP_STATUS_ERROR = 4 -DUMP_STATUS_MISSING_SYMBOLS = 5 -STATUS = ( - (DUMP_STATUS_CREATED, "Created"), - (DUMP_STATUS_COMPLETED, "Completed"), - (DUMP_STATUS_DELETED, "Deleted"), - (DUMP_STATUS_ERROR, "Error"), - (DUMP_STATUS_MISSING_SYMBOLS, "Missing Symbols"), -) - -RESULT_STATUS_NOT_STARTED = 0 -RESULT_STATUS_RUNNING = 1 -RESULT_STATUS_EMPTY = 2 -RESULT_STATUS_SUCCESS = 3 -RESULT_STATUS_UNSATISFIED = 4 -RESULT_STATUS_ERROR = 5 -RESULT_STATUS_DISABLED = 6 -RESULT = ( - (RESULT_STATUS_NOT_STARTED, "Not Started"), - (RESULT_STATUS_RUNNING, "Running"), - (RESULT_STATUS_EMPTY, "Empty"), - (RESULT_STATUS_SUCCESS, "Success"), - (RESULT_STATUS_UNSATISFIED, "Unsatisfied"), - (RESULT_STATUS_ERROR, "Error"), - (RESULT_STATUS_DISABLED, "Disabled"), +from guardian.shortcuts import assign_perm, get_users_with_perms + +from orochi.website.defaults import ( + DEFAULT_YARA_PATH, + ICONS, + OPERATING_SYSTEM, + RESULT, + RESULT_STATUS_NOT_STARTED, + SERVICES, + STATUS, + TOAST_DUMP_COLORS, + TOAST_RESULT_COLORS, ) -ICONS = ( - ("ss-arn", "Arabian Nights"), - ("ss-atq", "Antiquities"), - ("ss-leg", "Legends"), - ("ss-drk", "The Dark"), - ("ss-fem", "Fallen Empires"), - ("ss-hml", "Homelands"), - ("ss-ice", "Ice Age"), - ("ss-ice2", "Ice Age (Original)"), - ("ss-all", "Alliances"), - ("ss-csp", "Coldsnap"), - ("ss-mir", "Mirage"), - ("ss-vis", "Visions"), - ("ss-wth", "Weatherlight"), - ("ss-tmp", "Tempest"), - ("ss-sth", "Stronghold"), - ("ss-exo", "Exodus"), - ("ss-usg", "Urza's Saga"), - ("ss-ulg", "Urza's Legacy"), - ("ss-uds", "Urza's Destiny"), - ("ss-mmq", "Mercadian Masques"), - ("ss-nem", "Nemesis"), - ("ss-pcy", "Prophecy"), - ("ss-inv", "Invasion"), - ("ss-pls", "Planeshift"), - ("ss-apc", "Apocalypse"), - ("ss-ody", "Odyssey"), - ("ss-tor", "Torment"), - ("ss-jud", "Judgement"), - ("ss-ons", "Onslaught"), - ("ss-lgn", "Legions"), - ("ss-scg", "Scourge"), - ("ss-mrd", "Mirrodin"), - ("ss-dst", "Darksteel"), - ("ss-5dn", "Fifth Dawn"), - ("ss-chk", "Champions of Kamigawa"), - ("ss-bok", "Betrayers of Kamigawa"), - ("ss-sok", "Saviors of Kamigawa"), - ("ss-rav", "Ravnica"), - ("ss-gpt", "Guildpact"), - ("ss-dis", "Dissension"), - ("ss-tsp", "Time Spiral"), - ("ss-plc", "Planar Chaos"), - ("ss-fut", "Future Sight"), - ("ss-lrw", "Lorwyn"), - ("ss-mor", "Morningtide"), - ("ss-shm", "Shadowmoor"), - ("ss-eve", "Eventide"), - ("ss-ala", "Shards of Alara"), - ("ss-con", "Conflux"), - ("ss-arb", "Alara Reborn"), - ("ss-zen", "Zendikar"), - ("ss-wwk", "Worldwake"), - ("ss-roe", "Rise of the Eldrazi"), - ("ss-som", "Scars of Mirrodin"), - ("ss-mbs", "Mirrodin Besieged"), - ("ss-nph", "New Phyrexia"), - ("ss-isd", "Innistrad"), - ("ss-dka", "Dark Ascension"), - ("ss-avr", "Avacyn Restored"), - ("ss-rtr", "Return to Ravnica"), - ("ss-gtc", "Gatecrash"), - ("ss-dgm", "Dragon's Maze"), - ("ss-ths", "Theros"), - ("ss-bng", "Born of the Gods"), - ("ss-jou", "Journey into Nyx"), - ("ss-ktk", "Khans of Tarkir"), - ("ss-frf", "Fate Reforged"), - ("ss-dtk", "Dragons of Tarkir"), - ("ss-bfz", "Battle for Zendikar"), - ("ss-ogw", "Oath of the Gatewatch"), - ("ss-soi", "Shadows Over Innistrad"), - ("ss-emn", "Eldritch Moon"), - ("ss-kld", "Kaladesh"), - ("ss-aer", "Aether Revolt"), - ("ss-akh", "Amonkhet"), - ("ss-hou", "Hour of Devastation"), - ("ss-xln", "Ixalan"), - ("ss-rix", "Rivals of Ixalan"), - ("ss-dom", "Dominaria"), - ("ss-grn", "Guilds of Ravnica"), - ("ss-rna", "Ravnica Allegiance"), - ("ss-war", "War of the Spark"), - ("ss-eld", "Throne of Eldraine"), - ("ss-thb", "Theros: Beyond Death"), - ("ss-iko", "koria: Lair of Behemoths"), - ("ss-znr", "Zendikar Rising"), - ("ss-khm", "Kaldheim"), - ("ss-stx", "Strixhaven: School of Mages"), - ("ss-mid", "Innistrad: Midnight Hunt"), - ("ss-vow", "Innistrad: Crimson Vow"), - ("ss-neo", "Kamigawa: Neon Dynasty"), - ("ss-snc", "Streets of New Capenna"), - ("ss-dmu", "Dominaria United"), - ("ss-bro", "The Brothers' War"), - ("ss-one", "Phyrexia: All Will Be One"), - ("ss-mom", "March of the Machine"), - ("ss-mat", "March of the Machine: The Aftermath"), - ("ss-woe", "Wilds of Eldraine"), -) - -DEFAULT_YARA_PATH = "/yara/default.yara" +from orochi.ya.models import Ruleset class Service(models.Model): @@ -354,3 +220,54 @@ def new_plugin(sender, instance, created, **kwargs): # Add new plugin to user for user in get_user_model().objects.all(): up, created = UserPlugin.objects.get_or_create(user=user, plugin=instance) + + +@staticmethod +@receiver(post_save, sender=Dump) +def dump_saved(sender, instance, created, **kwargs): + users = get_users_with_perms(instance, only_with_perms_in=["can_see"]) + if created: + message = f"Dump {instance.name} has been created" + else: + message = f"Dump {instance.name} has been updated." + + message = f"{datetime.now()} || {message}
Status: {instance.get_status_display()}" + + for user in users: + # Send message to room group + channel_layer = get_channel_layer() + async_to_sync(channel_layer.group_send)( + f"chat_{user.pk}", + { + "type": "chat_message", + "message": message, + }, + ) + + +@staticmethod +@receiver(post_save, sender=Result) +def result_saved(sender, instance, created, **kwargs): + dump = instance.dump + users = get_users_with_perms(dump, only_with_perms_in=["can_see"]) + if created: + message = ( + f"Plugin {instance.plugin.name} on {instance.dump.name} has been created" + ) + else: + message = ( + f"Plugin {instance.plugin.name} on {instance.dump.name} has been updated" + ) + + message = f"{datetime.now()} || {message}
Status: {instance.get_result_display()}" + + for user in users: + # Send message to room group + channel_layer = get_channel_layer() + async_to_sync(channel_layer.group_send)( + f"chat_{user.pk}", + { + "type": "chat_message", + "message": message, + }, + ) diff --git a/orochi/website/routing.py b/orochi/website/routing.py index 1ff257e3..63ca8754 100644 --- a/orochi/website/routing.py +++ b/orochi/website/routing.py @@ -1,7 +1,7 @@ from django.urls import re_path -from . import consumers +from orochi.website.consumers import NotifyConsumer websocket_urlpatterns = [ - re_path(r"ws/notify/(?P\w+)/$", consumers.NotifyConsumer.as_asgi()), + re_path(r"ws/notify/(?P\w+)/$", NotifyConsumer.as_asgi()), ] diff --git a/orochi/website/views.py b/orochi/website/views.py index e480cc2b..e0682ca6 100644 --- a/orochi/website/views.py +++ b/orochi/website/views.py @@ -49,6 +49,15 @@ run_plugin, unzip_then_run, ) +from orochi.website.defaults import ( + DUMP_STATUS_COMPLETED, + RESULT_STATUS_DISABLED, + RESULT_STATUS_EMPTY, + RESULT_STATUS_NOT_STARTED, + RESULT_STATUS_RUNNING, + RESULT_STATUS_SUCCESS, + SERVICE_MISP, +) from orochi.website.forms import ( BookmarkForm, DumpForm, @@ -62,13 +71,6 @@ SymbolUploadForm, ) from orochi.website.models import ( - DUMP_STATUS_COMPLETED, - RESULT_STATUS_DISABLED, - RESULT_STATUS_EMPTY, - RESULT_STATUS_NOT_STARTED, - RESULT_STATUS_RUNNING, - RESULT_STATUS_SUCCESS, - SERVICE_MISP, Bookmark, CustomRule, Dump, diff --git a/requirements/base.txt b/requirements/base.txt index daa0435a..b8a1f45b 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -28,7 +28,7 @@ channels_redis==4.2.0 # https://github.com/joke2k/django-environ django-environ==0.11.2 # https://github.com/pennersr/django-allauth -django-allauth==0.60.1 +django-allauth==0.61.1 # https://github.com/django-crispy-forms/django-crispy-forms django-crispy-forms==2.1 # https://github.com/jazzband/django-redis @@ -51,7 +51,7 @@ drf-yasg==1.21.7 # Django tweak # ------------------------------------------------------------------------------ # https://github.com/django-crispy-forms/crispy-bootstrap5 -crispy-bootstrap5==2023.10 +crispy-bootstrap5==2024.2 # https://github.com/fabiocaccamo/django-colorfield django-colorfield==0.11.0 # https://github.com/mbraak/django-file-form @@ -70,7 +70,7 @@ django-admin-multiple-choice-list-filter==0.1.1 # Elasticsearch # ------------------------------------------------------------------------------ # https://github.com/elastic/elasticsearch-py -elasticsearch==8.12.0 +elasticsearch==8.12.1 # https://github.com/elastic/elasticsearch-dsl-py elasticsearch-dsl==8.12.0 # https://github.com/jurismarches/luqum @@ -79,13 +79,11 @@ luqum==0.13.0 # Dask & co # ------------------------------------------------------------------------------ # https://github.com/dask/dask -dask==2024.1.1 +dask==2024.2.1 # https://github.com/dask/distributed -distributed==2024.1.1 +distributed==2024.2.1 # https://msgpack.org/ TO BE ALIGNED WITH SCHEDULER msgpack==1.0.7 -# https://github.com/blosc/python-blosc -blosc==1.11.1 # https://github.com/python-lz4/python-lz4 lz4==4.3.3 # https://numpy.org/ @@ -93,7 +91,7 @@ numpy==1.26.4 # https://github.com/cloudpipe/cloudpickle cloudpickle==3.0.0 # https://pypi.org/project/toolz/ -toolz==0.12.0 +toolz==0.12.1 # https://pypi.org/project/tornado/ tornado==6.4 @@ -101,7 +99,7 @@ tornado==6.4 # ------------------------------------------------------------------------------ # https://github.com/volatilityfoundation/ # volatility3==2.5.0 -volatility3 @ git+https://github.com/volatilityfoundation/volatility3.git@6d34e43667a4f709902f3c157a4e54ec4ed679ce#egg=volatility3 +volatility3 @ git+https://github.com/volatilityfoundation/volatility3.git@887747e3ceb1d40af936e8a91d65e05874f4c06a#egg=volatility3 # https://github.com/VirusTotal/yara-python #yara-python==4.1.0 # https://github.com/Viicos/clamdpy @@ -109,7 +107,7 @@ clamdpy==0.1.0.post1 # https://github.com/VirusTotal/vt-py vt-py==0.18.0 # https://github.com/mkorman90/regipy/ -regipy==3.1.6 +regipy==4.0.0 # http://www.capstone-engine.org/ capstone==5.0.1 # https://github.com/Julian/jsonschema @@ -122,9 +120,9 @@ geoip2==4.8.0 # Yara # ------------------------------------------------------------------------------ # https://github.com/gitpython-developers/GitPython -GitPython==3.1.41 +GitPython==3.1.42 # https://github.com/frostming/marko -marko==2.0.2 +marko==2.0.3 # symbols dwarf # ------------------------------------------------------------------------------ @@ -140,7 +138,7 @@ pefile==2023.2.7 # misp export # ------------------------------------------------------------------------------ # https://github.com/MISP/PyMISP -pymisp==2.4.184.2 +pymisp==2.4.185 # ldap # ------------------------------------------------------------------------------ diff --git a/requirements/local.txt b/requirements/local.txt index 9fc15249..3b873173 100644 --- a/requirements/local.txt +++ b/requirements/local.txt @@ -7,7 +7,7 @@ mypy==1.8.0 # https://github.com/typeddjango/django-stubs django-stubs==4.2.7 # https://github.com/pytest-dev/pytest -pytest==8.0.0 +pytest==8.0.2 # https://github.com/Frozenball/pytest-sugar pytest-sugar==1.0.0 @@ -18,13 +18,13 @@ flake8==7.0.0 # https://github.com/gforcada/flake8-isort flake8-isort==6.1.1 # https://github.com/nedbat/coveragepy -coverage==7.4.1 +coverage==7.4.3 # https://github.com/ambv/black -black==24.1.1 +black==24.2.0 # https://github.com/PyCQA/pylint-django pylint-django==2.5.5 # https://github.com/pre-commit/pre-commit -pre-commit==3.6.0 +pre-commit==3.6.2 # Django # ------------------------------------------------------------------------------