Skip to content
Open
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v6.2.0
with:
python-version: '3.11'
python-version: '3.13'

- name: Install dependencies
run: |
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/dependency_review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ jobs:
- name: 'Checkout Repository'
uses: actions/checkout@v6.0.2
- name: 'Dependency Review'
uses: actions/dependency-review-action@v4
uses: actions/dependency-review-action@v4
with:
allow-dependencies-licenses: pkg:pypi/ppdeep=Apache-2.0
2 changes: 1 addition & 1 deletion .github/workflows/pull_request_automation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v6.2.0
with:
python-version: 3.11
python-version: 3.13

- name: Install Dependencies
run: |
Expand Down
9 changes: 6 additions & 3 deletions api_app/analyzers_manager/classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,9 +230,12 @@ def filepath(self) -> str:
str: The file path.
"""
if not self.__filepath:
self.__filepath = self._job.analyzable.file.storage.retrieve(
file=self._job.analyzable.file, analyzer=self.analyzer_name
)
storage = self._job.analyzable.file.storage
retrieve = getattr(storage, "retrieve", None)
if callable(retrieve):
self.__filepath = retrieve(file=self._job.analyzable.file, analyzer=self.analyzer_name)
else:
self.__filepath = self._job.analyzable.file.path
return self.__filepath

def before_run(self):
Expand Down
10 changes: 5 additions & 5 deletions api_app/analyzers_manager/file_analyzers/file_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
# See the file 'LICENSE' for copying permission.

import logging
from pathlib import PosixPath
from pathlib import Path
from typing import Optional

import magic
import pydeep
import ppdeep
import tlsh
from django.conf import settings
from django.utils.functional import cached_property
Expand All @@ -19,8 +19,8 @@


class FileInfo(FileAnalyzer):
EXIF_TOOL_PATH: PosixPath = settings.BASE_DIR / "exiftool_download"
EXIF_TOOL_VERSION_PATH: PosixPath = EXIF_TOOL_PATH / "exiftool_version.txt"
EXIF_TOOL_PATH: Path = settings.BASE_DIR / "exiftool_download"
EXIF_TOOL_VERSION_PATH: Path = EXIF_TOOL_PATH / "exiftool_version.txt"

@cached_property
def exiftool_path(self) -> Optional[str]:
Expand All @@ -40,7 +40,7 @@ def run(self):
results["md5"] = calculate_md5(binary)
results["sha1"] = calculate_sha1(binary)
results["sha256"] = calculate_sha256(binary)
results["ssdeep"] = pydeep.hash_file(self.filepath).decode()
results["ssdeep"] = ppdeep.hash_from_file(self.filepath)
results["tlsh"] = tlsh.hash(binary)

if self.exiftool_path:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ def perform_request_to_form(self, form) -> Response:
return response

@staticmethod
def handle_3xx_response(response: Response) -> [str]:
def handle_3xx_response(response: Response) -> list[str]:
result: [] = []
# extract all redirection history
Comment thread
IshaanXCoder marked this conversation as resolved.
for history in response.history:
Expand Down
10 changes: 5 additions & 5 deletions api_app/analyzers_manager/observable_analyzers/maxmind.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@


class MaxmindDBManager:
_supported_dbs: [str] = ["GeoLite2-Country", "GeoLite2-City", "GeoLite2-ASN"]
_supported_dbs: list[str] = ["GeoLite2-Country", "GeoLite2-City", "GeoLite2-ASN"]
_default_db_extension: str = ".mmdb"

@classmethod
def get_supported_dbs(cls) -> [str]:
def get_supported_dbs(cls) -> list[str]:
return [db_name + cls._default_db_extension for db_name in cls._supported_dbs]

@classmethod
Expand Down Expand Up @@ -184,15 +184,15 @@ def run(self):
return maxmind_final_result

@classmethod
def get_db_names(cls) -> [str]:
def get_db_names(cls) -> list[str]:
return cls._maxmind_db_manager.get_supported_dbs()

@classmethod
def _get_api_key(cls):
for plugin in PluginConfig.objects.filter(
parameter__python_module=cls.python_module,
parameter__is_secret=True,
parameter__name="_api_key_name",
parameter__name="api_key_name",
):
if plugin.value:
return plugin.value
Expand All @@ -202,7 +202,7 @@ def _get_api_key(cls):
def update(cls) -> bool:
auth_token = cls._get_api_key()
if auth_token:
return cls._maxmind_db_manager.update_all_dbs(cls._api_key_name)
return cls._maxmind_db_manager.update_all_dbs(auth_token)
return False

def _update_data_model(self, data_model) -> None:
Expand Down
15 changes: 7 additions & 8 deletions api_app/choices.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import logging
import re
import typing
from pathlib import PosixPath

from django.db import models

Expand All @@ -15,17 +14,17 @@

class PythonModuleBasePaths(models.TextChoices):
ObservableAnalyzer = (
PosixPath("api_app.analyzers_manager.observable_analyzers"),
"api_app.analyzers_manager.observable_analyzers",
"Observable Analyzer",
)
FileAnalyzer = (
PosixPath("api_app.analyzers_manager.file_analyzers"),
"api_app.analyzers_manager.file_analyzers",
"File Analyzer",
)
Connector = PosixPath("api_app.connectors_manager.connectors"), "Connector"
Ingestor = PosixPath("api_app.ingestors_manager.ingestors"), "Ingestor"
Visualizer = PosixPath("api_app.visualizers_manager.visualizers"), "Visualizer"
Pivot = PosixPath("api_app.pivots_manager.pivots"), "Pivot"
Connector = "api_app.connectors_manager.connectors", "Connector"
Ingestor = "api_app.ingestors_manager.ingestors", "Ingestor"
Visualizer = "api_app.visualizers_manager.visualizers", "Visualizer"
Pivot = "api_app.pivots_manager.pivots", "Pivot"


class TLP(models.TextChoices):
Expand Down Expand Up @@ -79,7 +78,7 @@ class Status(models.TextChoices):
FAILED = "failed", "failed"

@classmethod
def get_enums_with_suffix(cls, suffix: str) -> typing.Generator[enum.Enum, None, None]:
def get_enums_with_suffix(cls, suffix: str) -> typing.Generator[enum.Enum]:
Comment thread
IshaanXCoder marked this conversation as resolved.
Outdated
for key in cls:
if key.name.endswith(suffix):
yield key
Expand Down
2 changes: 0 additions & 2 deletions api_app/classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,8 +230,6 @@ def after_run_failed(self, e: Exception):
self.disable_for_rate_limit()
else:
self.log_error(e)
if settings.STAGE_CI:
raise e

Comment thread
IshaanXCoder marked this conversation as resolved.
@abstractclassproperty
def report_model(cls) -> typing.Type[AbstractReport]:
Expand Down
2 changes: 1 addition & 1 deletion api_app/engines_manager/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class EngineConfig(SingletonModel):
help_text="List of modules used by the engine. Each module has syntax `name_file.name_class`",
)

def get_modules_signatures(self, job) -> Generator[Signature, None, None]:
def get_modules_signatures(self, job) -> Generator[Signature]:
Comment thread
IshaanXCoder marked this conversation as resolved.
Outdated
from api_app.engines_manager.tasks import execute_engine_module

for path in self.modules:
Expand Down
2 changes: 1 addition & 1 deletion api_app/interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ def create_jobs(
delay: datetime.timedelta = datetime.timedelta(),
send_task: bool = True,
parent_job=None,
) -> Generator["Job", None, None]:
) -> Generator["Job"]:
Comment thread
IshaanXCoder marked this conversation as resolved.
Outdated
"""
Creates jobs from the given playbook configuration.

Expand Down
8 changes: 4 additions & 4 deletions api_app/serializers/job.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ def plugins_to_execute(
self,
tlp,
plugins_requested: Union[List[Union[AnalyzerConfig, ConnectorConfig, VisualizerConfig]], QuerySet],
) -> Generator[Union[AnalyzerConfig, ConnectorConfig, VisualizerConfig], None, None]:
) -> Generator[Union[AnalyzerConfig, ConnectorConfig, VisualizerConfig]]:
Comment thread
IshaanXCoder marked this conversation as resolved.
Outdated
if not plugins_requested:
return
if isinstance(plugins_requested, QuerySet):
Expand Down Expand Up @@ -573,7 +573,7 @@ def get_investigation_name(self, instance: Job): # skipcq: PYL-R0201
return root_investigation.name
return instance.investigation

def get_analyzable_id(self, instance: Job) -> int:
def get_analyzable_id(self, instance: Job) -> int: # skipcq: PYL-R0201
return instance.analyzable.pk

def get_fields(self):
Expand All @@ -594,7 +594,7 @@ def get_fields(self):
)
return super().get_fields()

def get_data_model(self, instance: Job):
def get_data_model(self, instance: Job): # skipcq: PYL-R0201
if instance.data_model:
return instance.data_model.serialize()
return {}
Expand Down Expand Up @@ -1165,7 +1165,7 @@ class Meta:
model = Job
fields = ["playbook", "user", "date", "data_model", "id"]

def get_data_model(self, instance: Job):
def get_data_model(self, instance: Job): # skipcq: PYL-R0201
logger.debug(f"{instance=}")
logger.debug(f"{instance.analyzable=}")

Expand Down
3 changes: 2 additions & 1 deletion async_tests/test_websocket.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ async def connect_communicator(self, job_id: int, user: User = None):
finally:
await communicator.disconnect()

def _pre_setup(self):
@classmethod
def _pre_setup(cls):
super()._pre_setup()
# force channel layers backend reset, this may avoid some RuntimeError
channel_layers.backends = {}
Expand Down
2 changes: 1 addition & 1 deletion docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ RUN npm install npm@latest --location=global \
&& PUBLIC_URL=/static/reactapp/ npm run build

# Stage 2: Backend
FROM python:3.11.7 AS backend-build
FROM python:3.13.12 AS backend-build

ENV PYTHONUNBUFFERED=1
ENV DJANGO_SETTINGS_MODULE=intel_owl.settings
Expand Down
1 change: 0 additions & 1 deletion docker/test.override.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ services:
- DEBUG=True
- DJANGO_TEST_SERVER=True
- DJANGO_WATCHMAN_TIMEOUT=60

daphne:
image: intelowlproject/intelowl:test
volumes:
Expand Down
2 changes: 1 addition & 1 deletion integrations/malware_tools_analyzers/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM python:3.11-slim
FROM python:3.13.12
Comment thread
IshaanXCoder marked this conversation as resolved.
Outdated

ARG TARGETARCH

Expand Down
2 changes: 1 addition & 1 deletion integrations/tor_analyzers/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM python:3.14-slim
FROM python:3.13.12
Comment thread
IshaanXCoder marked this conversation as resolved.
Outdated

ENV PROJECT_PATH=/opt/deploy
ENV LOG_PATH=/var/log/intel_owl/tor_analyzers
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.ruff]
line-length = 110
target-version = "py311"
target-version = "py313"

exclude = [
"venv",
Expand Down
30 changes: 15 additions & 15 deletions requirements/project-requirements.txt
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# django libs
Django==4.2.27
psycopg2-binary==2.9.6
Django==5.2.11
psycopg2-binary==2.9.11
django-auth-ldap==5.1.0
django-radius==1.5.0
django-filter==25.1
django-storages==1.14
django-celery-beat==2.7.0
django-celery-results==2.5.0
django-celery-beat==2.8.1
django-celery-results==2.6.0
django-ses == 4.6.0
django-iam-dbauth==0.2.1
django-prettyjson==0.4.1
Expand All @@ -17,19 +17,19 @@ django_extensions==3.2.3
jsonschema==4.25.1
# django rest framework libs
Authlib==1.6.5
djangorestframework==3.15.2
djangorestframework==3.16.1
djangorestframework-filters==1.0.0.dev2
drf-spectacular==0.28.0
django-rest-email-auth==4.0.0
django-rest-email-auth==5.0.0

# infra
boto3==1.39.4
celery[sqs,redis]==5.4.0
celery[sqs,redis]==5.6.0
dataclasses==0.6
# https://github.com/advisories/GHSA-q4qm-xhf9-4p8f
# unpatched CVE: noproblem, we just use this for debugging purposes
flower==2.0.0
uWSGI==2.0.28
uWSGI==2.0.31
uwsgitop==0.12
whitenoise==6.9.0
daphne==4.2.1
Expand All @@ -42,10 +42,10 @@ GitPython==3.1.41
checkdmarc==5.13.1
dnspython==2.8.0
dnstwist[full]==20250130
google>=3.0.0
google==3.0.0
google-cloud-webrisk==1.20.0
intezer-sdk==1.24.0
lief==0.15.1
lief==0.17.3
maxminddb==2.6.0
geoip2==4.8.0
mwdblib==4.6.0
Expand All @@ -54,8 +54,8 @@ OTXv2==1.5.12
peepdf-fork==0.4.3
pdfid==1.1.0
pefile==2024.8.26
Pillow==11.0.0
pydeep==0.4
Pillow==12.1.1
ppdeep==20251115
pyelftools==0.31
PyExifTool==0.5.0
pyhashlookup==1.2.0
Expand All @@ -67,7 +67,7 @@ pypssl==2.2
pysafebrowsing==0.1.1
PySocks==1.7.1
py-tlsh==4.7.2
quark-engine==25.1.1
quark-engine==26.1.1
speakeasy-emulator==1.5.9
telfhash==0.9.8
yara-python==4.5.1
Expand All @@ -76,11 +76,11 @@ XLMMacroDeobfuscator[secure]==0.2.3
thinkst-zippy==0.1.2
querycontacts==2.0.0
hfinger==0.2.2
blint==2.3.2
blint==3.1.1
permhash==0.1.4
ail_typo_squatting==2.7.4
iocextract==1.16.1
ioc-finder==7.0.0
ioc-finder==7.3.0
polyswarm-api==3.16.0
knock-subdomains==8.0.0
dotnetfile==0.2.4
Expand Down
4 changes: 2 additions & 2 deletions tests/api_app/analyzers_manager/test_signals.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import json

from django.test import override_settings
from django_celery_beat.models import CrontabSchedule

from api_app.choices import PythonModuleBasePaths
Expand All @@ -8,6 +9,7 @@


class AnalyzerConfigSignalsTestCase(CustomTestCase):
@override_settings(REPO_DOWNLOADER_ENABLED=False)
def test_pre_save_analyzer_config(self):
pm = PythonModule.objects.get(
base_path=PythonModuleBasePaths.ObservableAnalyzer.value,
Expand All @@ -22,8 +24,6 @@ def test_pre_save_analyzer_config(self):
self.assertIsNotNone(pm.update_task)
self.assertEqual(pm.update_task.name, pm.python_complete_path + "Update")
self.assertEqual(pm.update_task.task, "intel_owl.tasks.update")
# this is false because in the tests we have
# REPO_DOWNLOADER_ENABLED set to False
self.assertFalse(pm.update_task.enabled)
self.assertEqual(pm.update_task.queue, pm.configs.first().queue)
self.assertEqual(json.loads(pm.update_task.kwargs)["python_module_pk"], pm.pk)
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class BaseFileAnalyzerTest(TestCase):
"application/zip": "test.zip",
"application/x-dex": "sample.dex",
"application/x-mach-binary": "macho_sample",
"application/x-elf": "ping.elf",
}

@classmethod
Expand Down
Loading
Loading