diff --git a/vulnerabilities/api_v2.py b/vulnerabilities/api_v2.py
index 74975b819..ba7c475f0 100644
--- a/vulnerabilities/api_v2.py
+++ b/vulnerabilities/api_v2.py
@@ -31,6 +31,7 @@
from vulnerabilities.models import AdvisoryWeakness
from vulnerabilities.models import CodeFix
from vulnerabilities.models import CodeFixV2
+from vulnerabilities.models import DetectionRule
from vulnerabilities.models import ImpactedPackage
from vulnerabilities.models import Package
from vulnerabilities.models import PackageV2
@@ -1398,3 +1399,29 @@ def lookup(self, request):
qs = self.get_queryset().for_purls([purl]).with_is_vulnerable()
return Response(PackageV3Serializer(qs, many=True, context={"request": request}).data)
+
+
+class DetectionRuleFilter(filters.FilterSet):
+ advisory_avid = filters.CharFilter(field_name="advisory__avid", lookup_expr="exact")
+
+ rule_text_contains = filters.CharFilter(field_name="rule_text", lookup_expr="icontains")
+
+ class Meta:
+ model = DetectionRule
+ fields = ["rule_type"]
+
+
+class DetectionRuleSerializer(serializers.ModelSerializer):
+ advisory_avid = serializers.ReadOnlyField(source="advisory.avid", allow_null=True)
+
+ class Meta:
+ model = DetectionRule
+ fields = ["rule_type", "source_url", "rule_metadata", "rule_text", "advisory_avid"]
+
+
+class DetectionRuleViewSet(viewsets.ReadOnlyModelViewSet):
+ queryset = DetectionRule.objects.all()
+ serializer_class = DetectionRuleSerializer
+ throttle_classes = [AnonRateThrottle, PermissionBasedUserRateThrottle]
+ filter_backends = [filters.DjangoFilterBackend]
+ filterset_class = DetectionRuleFilter
diff --git a/vulnerabilities/forms.py b/vulnerabilities/forms.py
index 03829cd52..2bdd49232 100644
--- a/vulnerabilities/forms.py
+++ b/vulnerabilities/forms.py
@@ -13,6 +13,7 @@
from django_altcha import AltchaField
from vulnerabilities.models import ApiUser
+from vulnerabilities.models import DetectionRuleTypes
class PackageSearchForm(forms.Form):
@@ -43,6 +44,35 @@ class AdvisorySearchForm(forms.Form):
)
+class DetectionRuleSearchForm(forms.Form):
+ rule_type = forms.ChoiceField(
+ required=False,
+ label="Rule Type",
+ choices=[("", "All")] + DetectionRuleTypes.choices,
+ initial="",
+ )
+
+ advisory_avid = forms.CharField(
+ required=False,
+ label="Advisory avid",
+ widget=forms.TextInput(
+ attrs={
+ "placeholder": "Search by avid: github_osv_importer_v2/GHSA-7g5f-wrx8-5ccf",
+ }
+ ),
+ )
+
+ rule_text_contains = forms.CharField(
+ required=False,
+ label="Rule Text",
+ widget=forms.TextInput(
+ attrs={
+ "placeholder": "Search in rule text",
+ }
+ ),
+ )
+
+
class ApiUserCreationForm(forms.ModelForm):
"""Support a simplified creation for API-only users directly from the UI."""
diff --git a/vulnerabilities/improvers/__init__.py b/vulnerabilities/improvers/__init__.py
index 97c18e6f9..7c02cdf43 100644
--- a/vulnerabilities/improvers/__init__.py
+++ b/vulnerabilities/improvers/__init__.py
@@ -32,6 +32,7 @@
)
from vulnerabilities.pipelines.v2_improvers import flag_ghost_packages as flag_ghost_packages_v2
from vulnerabilities.pipelines.v2_improvers import relate_severities
+from vulnerabilities.pipelines.v2_improvers import sigma_rules
from vulnerabilities.pipelines.v2_improvers import unfurl_version_range as unfurl_version_range_v2
from vulnerabilities.utils import create_registry
@@ -74,5 +75,6 @@
compute_advisory_todo.ComputeToDo,
collect_ssvc_trees.CollectSSVCPipeline,
relate_severities.RelateSeveritiesPipeline,
+ sigma_rules.SigmaRulesImproverPipeline,
]
)
diff --git a/vulnerabilities/migrations/0116_detectionrule.py b/vulnerabilities/migrations/0116_detectionrule.py
new file mode 100644
index 000000000..04dadf6ed
--- /dev/null
+++ b/vulnerabilities/migrations/0116_detectionrule.py
@@ -0,0 +1,68 @@
+# Generated by Django 5.2.11 on 2026-03-07 14:44
+
+import django.db.models.deletion
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("vulnerabilities", "0115_impactedpackageaffecting_and_more"),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name="DetectionRule",
+ fields=[
+ (
+ "id",
+ models.AutoField(
+ auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
+ ),
+ ),
+ (
+ "rule_type",
+ models.CharField(
+ choices=[
+ ("yara", "Yara"),
+ ("yara-x", "Yara-X"),
+ ("sigma", "Sigma"),
+ ("clamav", "ClamAV"),
+ ("suricata", "Suricata"),
+ ],
+ help_text="The type of the detection rule content (e.g., YARA, Sigma).",
+ max_length=50,
+ ),
+ ),
+ (
+ "source_url",
+ models.URLField(
+ help_text="URL to the original source or reference for this rule.",
+ max_length=1024,
+ ),
+ ),
+ (
+ "rule_metadata",
+ models.JSONField(
+ blank=True,
+ help_text="Additional structured data such as tags, or author information.",
+ null=True,
+ ),
+ ),
+ (
+ "rule_text",
+ models.TextField(help_text="The content of the detection signature."),
+ ),
+ (
+ "advisory",
+ models.ForeignKey(
+ blank=True,
+ null=True,
+ on_delete=django.db.models.deletion.SET_NULL,
+ related_name="detection_rules",
+ to="vulnerabilities.advisoryv2",
+ ),
+ ),
+ ],
+ ),
+ ]
diff --git a/vulnerabilities/models.py b/vulnerabilities/models.py
index 1981a2861..6ca676d25 100644
--- a/vulnerabilities/models.py
+++ b/vulnerabilities/models.py
@@ -3649,3 +3649,45 @@ def __str__(self):
class Meta:
unique_together = ("vector", "source_advisory")
+
+
+class DetectionRuleTypes(models.TextChoices):
+ """Defines the supported formats for security detection rules."""
+
+ YARA = "yara", "Yara"
+ YARA_X = "yara-x", "Yara-X"
+ SIGMA = "sigma", "Sigma"
+ CLAMAV = "clamav", "ClamAV"
+ SURICATA = "suricata", "Suricata"
+
+
+class DetectionRule(models.Model):
+ """
+ A Detection Rule is code used to identify malicious activity or security threats.
+ """
+
+ rule_type = models.CharField(
+ max_length=50,
+ choices=DetectionRuleTypes.choices,
+ help_text="The type of the detection rule content (e.g., YARA, Sigma).",
+ )
+
+ source_url = models.URLField(
+ max_length=1024, help_text="URL to the original source or reference for this rule."
+ )
+
+ rule_metadata = models.JSONField(
+ null=True,
+ blank=True,
+ help_text="Additional structured data such as tags, or author information.",
+ )
+
+ rule_text = models.TextField(help_text="The content of the detection signature.")
+
+ advisory = models.ForeignKey(
+ AdvisoryV2,
+ related_name="detection_rules",
+ on_delete=models.SET_NULL,
+ null=True,
+ blank=True,
+ )
diff --git a/vulnerabilities/pipelines/v2_improvers/sigma_rules.py b/vulnerabilities/pipelines/v2_improvers/sigma_rules.py
new file mode 100644
index 000000000..b4248a884
--- /dev/null
+++ b/vulnerabilities/pipelines/v2_improvers/sigma_rules.py
@@ -0,0 +1,126 @@
+#
+# Copyright (c) nexB Inc. and others. All rights reserved.
+# VulnerableCode is a trademark of nexB Inc.
+# SPDX-License-Identifier: Apache-2.0
+# See http://www.apache.org/licenses/LICENSE-2.0 for the license text.
+# See https://github.com/aboutcode-org/vulnerablecode for support or download.
+# See https://aboutcode.org for more information about nexB OSS projects.
+#
+import datetime
+from pathlib import Path
+
+import yaml
+from aboutcode.pipeline import LoopProgress
+from fetchcode.vcs import fetch_via_vcs
+
+from vulnerabilities.models import AdvisoryAlias
+from vulnerabilities.models import DetectionRule
+from vulnerabilities.models import DetectionRuleTypes
+from vulnerabilities.pipelines import VulnerableCodePipeline
+from vulnerabilities.utils import find_all_cve
+
+
+class SigmaRulesImproverPipeline(VulnerableCodePipeline):
+ pipeline_id = "sigma_rules"
+ repo_url = "git+https://github.com/SigmaHQ/sigma"
+ license_url = "https://github.com/SigmaHQ/Detection-Rule-License"
+
+ @classmethod
+ def steps(cls):
+ return (
+ cls.clone_repo,
+ cls.collect_and_store_rules,
+ cls.clean_downloads,
+ )
+
+ def clone_repo(self):
+ self.log(f"Cloning `{self.repo_url}`")
+ self.vcs_response = fetch_via_vcs(self.repo_url)
+
+ def collect_and_store_rules(self):
+ """
+ Collect Sigma YAML rules from the destination directory and store/update
+ them as DetectionRule objects.
+ """
+
+ base_directory = Path(self.vcs_response.dest_dir)
+ yaml_files = [
+ p
+ for p in base_directory.rglob("**/*.yml")
+ if not any(part in [".github", "images", "documentation"] for part in p.parts)
+ ]
+
+ rules_count = len(yaml_files)
+ self.log(f"Enhancing the vulnerability with {rules_count:,d} rule records")
+ progress = LoopProgress(total_iterations=rules_count, logger=self.log)
+ for file_path in progress.iter(yaml_files):
+ raw_text = file_path.read_text(encoding="utf-8")
+ rule_documents = list(yaml.load_all(raw_text, yaml.FullLoader))
+
+ rule_metadata = extract_sigma_metadata(rule_documents)
+ rule_url = f"https://raw.githubusercontent.com/SigmaHQ/sigma/refs/heads/master/{file_path.relative_to(base_directory)}"
+ cve_ids = find_all_cve(str(file_path))
+
+ found_advisories = set()
+ for cve_id in cve_ids:
+ try:
+ alias = AdvisoryAlias.objects.get(alias=cve_id)
+ for adv in alias.advisories.all():
+ found_advisories.add(adv)
+ except AdvisoryAlias.DoesNotExist:
+ self.log(f"AdvisoryAlias {cve_id}: {file_path.name} not found.")
+ continue
+
+ for adv in found_advisories:
+ DetectionRule.objects.update_or_create(
+ rule_text=raw_text,
+ rule_type=DetectionRuleTypes.SIGMA,
+ defaults={
+ "rule_metadata": rule_metadata,
+ "source_url": rule_url,
+ "advisory": adv,
+ },
+ )
+
+ if not found_advisories:
+ DetectionRule.objects.update_or_create(
+ rule_text=raw_text,
+ rule_type=DetectionRuleTypes.SIGMA,
+ advisory=None,
+ defaults={
+ "rule_metadata": rule_metadata,
+ "source_url": rule_url,
+ },
+ )
+
+ def clean_downloads(self):
+ if self.vcs_response:
+ self.log(f"Removing cloned repository")
+ self.vcs_response.delete()
+
+ def on_failure(self):
+ self.clean_downloads()
+
+
+def extract_sigma_metadata(rule_documents):
+ """
+ Extract Sigma metadata from Sigma YAML rules
+ """
+ if not rule_documents:
+ return None
+
+ first_document = rule_documents[0]
+ metadata = {
+ "status": first_document.get("status"),
+ "author": first_document.get("author"),
+ "date": first_document.get("date"),
+ "title": first_document.get("title"),
+ "id": first_document.get("id"),
+ }
+
+ rule_date = metadata.get("date")
+
+ if isinstance(rule_date, (datetime.date, datetime.datetime)):
+ metadata["date"] = rule_date.isoformat()
+
+ return metadata
diff --git a/vulnerabilities/templates/detection_rules.html b/vulnerabilities/templates/detection_rules.html
new file mode 100644
index 000000000..04f8e0794
--- /dev/null
+++ b/vulnerabilities/templates/detection_rules.html
@@ -0,0 +1,65 @@
+{% extends "base.html" %}
+{% load humanize %}
+{% load widget_tweaks %}
+
+{% block title %}
+Detection Rule Search
+{% endblock %}
+
+{% block content %}
+
+ {% include "detection_rules_box.html" %}
+
+
+
+
+
+
+ {{ page_obj.paginator.count|intcomma }} results
+
+ {% if is_paginated %}
+ {% include 'includes/pagination.html' with page_obj=page_obj %}
+ {% endif %}
+
+
+
+
+
+
+
+
+
+ | Type |
+ Metadata |
+ Text |
+ Source URL |
+ Advisory ID |
+
+
+
+ {% for detection_rule in page_obj %}
+
+ | {{ detection_rule.rule_type }} |
+ {{ detection_rule.rule_metadata }} |
+ {{ detection_rule.rule_text|truncatewords:10 }} |
+ {{ detection_rule.source_url }} |
+ {{ detection_rule.advisory.avid }} |
+
+ {% empty %}
+
+ |
+ No detection rules found.
+ |
+
+ {% endfor %}
+
+
+
+
+
+ {% if is_paginated %}
+ {% include 'includes/pagination.html' with page_obj=page_obj %}
+ {% endif %}
+
+
+{% endblock %}
diff --git a/vulnerabilities/templates/detection_rules_box.html b/vulnerabilities/templates/detection_rules_box.html
new file mode 100644
index 000000000..d76efeaad
--- /dev/null
+++ b/vulnerabilities/templates/detection_rules_box.html
@@ -0,0 +1,46 @@
+{% load widget_tweaks %}
+
+
+
+
diff --git a/vulnerabilities/tests/pipelines/v2_improvers/test_sigma_rules.py b/vulnerabilities/tests/pipelines/v2_improvers/test_sigma_rules.py
new file mode 100644
index 000000000..9e7a6fc03
--- /dev/null
+++ b/vulnerabilities/tests/pipelines/v2_improvers/test_sigma_rules.py
@@ -0,0 +1,84 @@
+#
+# Copyright (c) nexB Inc. and others. All rights reserved.
+# VulnerableCode is a trademark of nexB Inc.
+# SPDX-License-Identifier: Apache-2.0
+# See http://www.apache.org/licenses/LICENSE-2.0 for the license text.
+# See https://github.com/aboutcode-org/vulnerablecode for support or download.
+# See https://aboutcode.org for more information about nexB OSS projects.
+#
+
+import os
+from datetime import datetime
+from unittest import mock
+from unittest.mock import MagicMock
+
+import pytest
+
+from vulnerabilities.models import AdvisoryAlias
+from vulnerabilities.models import AdvisoryV2
+from vulnerabilities.models import DetectionRule
+from vulnerabilities.pipelines.v2_improvers.sigma_rules import SigmaRulesImproverPipeline
+
+BASE_DIR = os.path.dirname(os.path.abspath(__file__))
+
+TEST_REPO_DIR = os.path.join(BASE_DIR, "../../test_data/sigma")
+
+
+@pytest.mark.django_db
+@mock.patch("vulnerabilities.pipelines.v2_improvers.sigma_rules.fetch_via_vcs")
+def test_sigma_rules_db_improver(mock_fetch_via_vcs):
+ mock_vcs = MagicMock()
+ mock_vcs.dest_dir = TEST_REPO_DIR
+ mock_vcs.delete = MagicMock()
+ mock_fetch_via_vcs.return_value = mock_vcs
+
+ adv1 = AdvisoryV2.objects.create(
+ advisory_id="VCIO-123-0001",
+ datasource_id="ds",
+ avid="ds/VCIO-123-0001",
+ unique_content_id="sgsdg45",
+ url="https://test.com",
+ date_collected=datetime.now(),
+ )
+ adv2 = AdvisoryV2.objects.create(
+ advisory_id="VCIO-123-1002",
+ datasource_id="ds",
+ avid="ds/VCIO-123-1002",
+ unique_content_id="6hd4d6f",
+ url="https://test.com",
+ date_collected=datetime.now(),
+ )
+ adv3 = AdvisoryV2.objects.create(
+ advisory_id="VCIO-123-1003",
+ datasource_id="ds",
+ avid="ds/VCIO-123-1003",
+ unique_content_id="sd6h4sh",
+ url="https://test.com",
+ date_collected=datetime.now(),
+ )
+
+ alias1 = AdvisoryAlias.objects.create(alias="CVE-2025-33053")
+ alias2 = AdvisoryAlias.objects.create(alias="CVE-2025-10035")
+ alias3 = AdvisoryAlias.objects.create(alias="CVE-2010-5278")
+ adv1.aliases.add(alias1)
+ adv2.aliases.add(alias2)
+ adv3.aliases.add(alias3)
+
+ improver = SigmaRulesImproverPipeline()
+ improver.execute()
+
+ assert len(DetectionRule.objects.all()) == 3
+ sigma_rule = DetectionRule.objects.first()
+ assert sigma_rule.rule_type == "sigma"
+ assert sigma_rule.rule_metadata == {
+ "author": "Swachchhanda Shrawan Poudel (Nextron Systems)",
+ "date": "2025-06-13",
+ "id": "04fc4b22-91a6-495a-879d-0144fec5ec03",
+ "status": "experimental",
+ "title": "Potential Exploitation of RCE Vulnerability CVE-2025-33053 - Image " "Load",
+ }
+ assert sigma_rule.advisory == adv1
+ assert (
+ sigma_rule.rule_text
+ == "title: Potential Exploitation of RCE Vulnerability CVE-2025-33053 - Image Load\nid: 04fc4b22-91a6-495a-879d-0144fec5ec03\nrelated:\n - id: abe06362-a5b9-4371-8724-ebd00cd48a04\n type: similar\n - id: 9a2d8b3e-f5a1-4c68-9e21-7d9e1cf8a123\n type: similar\nstatus: experimental\ndescription: |\n Detects potential exploitation of remote code execution vulnerability CVE-2025-33053\n by monitoring suspicious image loads from WebDAV paths. The exploit involves malicious executables from\n attacker-controlled WebDAV servers loading the Windows system DLLs like gdi32.dll, netapi32.dll, etc.\nreferences:\n - https://msrc.microsoft.com/update-guide/en-US/vulnerability/CVE-2025-33053\n - https://research.checkpoint.com/2025/stealth-falcon-zero-day/\nauthor: Swachchhanda Shrawan Poudel (Nextron Systems)\ndate: 2025-06-13\ntags:\n - attack.command-and-control\n - attack.execution\n - attack.defense-evasion\n - attack.t1218\n - attack.lateral-movement\n - attack.t1105\n - detection.emerging-threats\n - cve.2025-33053\nlogsource:\n category: image_load\n product: windows\ndetection:\n selection_img_path:\n Image|startswith: '\\\\\\\\'\n Image|contains: '\\DavWWWRoot\\'\n selection_img_bin:\n Image|endswith:\n - '\\route.exe'\n - '\\netsh.exe'\n - '\\makecab.exe'\n - '\\dxdiag.exe'\n - '\\ipconfig.exe'\n - '\\explorer.exe'\n condition: all of selection_*\nfalsepositives:\n - Unknown\nlevel: high"
+ )
diff --git a/vulnerabilities/tests/test_data/sigma/CVE-2010-5278/web_cve_2010_5278_exploitation_attempt.yml b/vulnerabilities/tests/test_data/sigma/CVE-2010-5278/web_cve_2010_5278_exploitation_attempt.yml
new file mode 100644
index 000000000..69f889e4d
--- /dev/null
+++ b/vulnerabilities/tests/test_data/sigma/CVE-2010-5278/web_cve_2010_5278_exploitation_attempt.yml
@@ -0,0 +1,26 @@
+title: CVE-2010-5278 Exploitation Attempt
+id: a4a899e8-fd7a-49dd-b5a8-7044def72d61
+status: test
+description: |
+ MODx manager - Local File Inclusion:Directory traversal vulnerability in manager/controllers/default/resource/tvs.php in MODx Revolution 2.0.2-pl, and possibly earlier,
+ when magic_quotes_gpc is disabled, allows remote attackers to read arbitrary files via a .. (dot dot) in the class_key parameter.
+references:
+ - https://github.com/projectdiscovery/nuclei-templates
+author: Subhash Popuri (@pbssubhash)
+date: 2021-08-25
+modified: 2023-01-02
+tags:
+ - attack.initial-access
+ - attack.t1190
+ - cve.2010-5278
+ - detection.emerging-threats
+logsource:
+ category: webserver
+detection:
+ selection:
+ cs-uri-query|contains: /manager/controllers/default/resource/tvs.php?class_key=../../../../../../../../../../windows/win.ini%00
+ condition: selection
+falsepositives:
+ - Scanning from Nuclei
+ - Unknown
+level: critical
\ No newline at end of file
diff --git a/vulnerabilities/tests/test_data/sigma/CVE-2025-10035/proc_creation_win_exploit_cve_2025_10035.yml b/vulnerabilities/tests/test_data/sigma/CVE-2025-10035/proc_creation_win_exploit_cve_2025_10035.yml
new file mode 100644
index 000000000..65ed3fc01
--- /dev/null
+++ b/vulnerabilities/tests/test_data/sigma/CVE-2025-10035/proc_creation_win_exploit_cve_2025_10035.yml
@@ -0,0 +1,78 @@
+title: Potential Exploitation of GoAnywhere MFT Vulnerability
+id: 6c76b3d0-afe4-4870-9443-ffe6773c5fef
+status: experimental
+description: |
+ Detects suspicious command execution by child processes of the GoAnywhere Managed File Transfer (MFT) application, which may indicate exploitation such as CVE-2025-10035.
+ This behavior is indicative of post-exploitation activity related to CVE-2025-10035, as observed in campaigns by the threat actor Storm-1175.
+references:
+ - https://www.microsoft.com/en-us/security/blog/2025/10/06/investigating-active-exploitation-of-cve-2025-10035-goanywhere-managed-file-transfer-vulnerability/
+author: MSFT (idea), Swachchhanda Shrawan Poudel (Nextron Systems)
+date: 2025-10-07
+tags:
+ - attack.initial-access
+ - attack.t1190
+ - attack.execution
+ - attack.t1059.001
+ - attack.persistence
+ - attack.t1133
+ - detection.emerging-threats
+ - cve.2025-10035
+logsource:
+ category: process_creation
+ product: windows
+detection:
+ # Detects the GoAnywhere Tomcat parent process based on path and command line arguments
+ selection_parent:
+ ParentImage|contains: '\GoAnywhere\tomcat\'
+ selection_powershell_img:
+ Image|endswith:
+ - '\powershell.exe'
+ - '\powershell_ise.exe'
+ - '\pwsh.exe'
+ selection_powershell_cmd:
+ - CommandLine|contains|all:
+ - 'IEX'
+ - 'enc'
+ - 'Hidden'
+ - 'bypass'
+ - CommandLine|re:
+ - 'net\s+user'
+ - 'net\s+group'
+ - 'query\s+session'
+ - CommandLine|contains:
+ - 'whoami'
+ - 'systeminfo'
+ - 'dsquery'
+ - 'localgroup administrators'
+ - 'nltest'
+ - 'samaccountname='
+ - 'adscredentials'
+ - 'o365accountconfiguration'
+ - '.DownloadString('
+ - '.DownloadFile('
+ - 'FromBase64String('
+ - 'System.IO.Compression'
+ - 'System.IO.MemoryStream'
+ - 'curl'
+ selection_child_cmd:
+ Image|endswith: '\cmd.exe'
+ CommandLine|contains:
+ - 'powershell'
+ - 'whoami'
+ - 'net.exe'
+ - 'net1.exe'
+ - 'rundll32'
+ - 'quser'
+ - 'nltest'
+ - 'curl'
+ selection_child_others:
+ CommandLine|contains:
+ - 'bitsadmin'
+ - 'certutil'
+ - 'mshta'
+ - 'cscript'
+ - 'wscript'
+ condition: selection_parent and (all of selection_powershell_* or 1 of selection_child_*)
+falsepositives:
+ - Legitimate administrative scripts or built-in GoAnywhere functions could potentially trigger this rule. Tuning may be required based on normal activity in your environment.
+level: high
\ No newline at end of file
diff --git a/vulnerabilities/tests/test_data/sigma/CVE-2025-33053/image_load_win_exploit_cve_2025_33053.yml b/vulnerabilities/tests/test_data/sigma/CVE-2025-33053/image_load_win_exploit_cve_2025_33053.yml
new file mode 100644
index 000000000..1be01da05
--- /dev/null
+++ b/vulnerabilities/tests/test_data/sigma/CVE-2025-33053/image_load_win_exploit_cve_2025_33053.yml
@@ -0,0 +1,45 @@
+title: Potential Exploitation of RCE Vulnerability CVE-2025-33053 - Image Load
+id: 04fc4b22-91a6-495a-879d-0144fec5ec03
+related:
+ - id: abe06362-a5b9-4371-8724-ebd00cd48a04
+ type: similar
+ - id: 9a2d8b3e-f5a1-4c68-9e21-7d9e1cf8a123
+ type: similar
+status: experimental
+description: |
+ Detects potential exploitation of remote code execution vulnerability CVE-2025-33053
+ by monitoring suspicious image loads from WebDAV paths. The exploit involves malicious executables from
+ attacker-controlled WebDAV servers loading the Windows system DLLs like gdi32.dll, netapi32.dll, etc.
+references:
+ - https://msrc.microsoft.com/update-guide/en-US/vulnerability/CVE-2025-33053
+ - https://research.checkpoint.com/2025/stealth-falcon-zero-day/
+author: Swachchhanda Shrawan Poudel (Nextron Systems)
+date: 2025-06-13
+tags:
+ - attack.command-and-control
+ - attack.execution
+ - attack.defense-evasion
+ - attack.t1218
+ - attack.lateral-movement
+ - attack.t1105
+ - detection.emerging-threats
+ - cve.2025-33053
+logsource:
+ category: image_load
+ product: windows
+detection:
+ selection_img_path:
+ Image|startswith: '\\\\'
+ Image|contains: '\DavWWWRoot\'
+ selection_img_bin:
+ Image|endswith:
+ - '\route.exe'
+ - '\netsh.exe'
+ - '\makecab.exe'
+ - '\dxdiag.exe'
+ - '\ipconfig.exe'
+ - '\explorer.exe'
+ condition: all of selection_*
+falsepositives:
+ - Unknown
+level: high
\ No newline at end of file
diff --git a/vulnerabilities/views.py b/vulnerabilities/views.py
index 860bde8eb..1390aceb7 100644
--- a/vulnerabilities/views.py
+++ b/vulnerabilities/views.py
@@ -18,6 +18,7 @@
from django.db.models import Count
from django.db.models import F
from django.db.models import Prefetch
+from django.db.models import Q
from django.http.response import Http404
from django.shortcuts import get_object_or_404
from django.shortcuts import redirect
@@ -33,6 +34,7 @@
from vulnerabilities.forms import AdminLoginForm
from vulnerabilities.forms import AdvisorySearchForm
from vulnerabilities.forms import ApiUserCreationForm
+from vulnerabilities.forms import DetectionRuleSearchForm
from vulnerabilities.forms import PackageSearchForm
from vulnerabilities.forms import PipelineSchedulePackageForm
from vulnerabilities.forms import VulnerabilitySearchForm
@@ -141,6 +143,37 @@ def get_queryset(self, query=None):
return self.model.objects.search(query=query).with_package_counts()
+class DetectionRuleSearch(ListView):
+ model = models.DetectionRule
+ template_name = "detection_rules.html"
+ paginate_by = PAGE_SIZE
+
+ def get_context_data(self, **kwargs):
+ context = super().get_context_data(**kwargs)
+ request_query = self.request.GET
+ context["detection_search_form"] = DetectionRuleSearchForm(request_query)
+ context["search"] = request_query.get("search")
+ return context
+
+ def get_queryset(self):
+ queryset = super().get_queryset()
+ form = DetectionRuleSearchForm(self.request.GET)
+ if form.is_valid():
+ rule_type = form.cleaned_data.get("rule_type")
+ advisory_avid = form.cleaned_data.get("advisory_avid")
+ rule_text = form.cleaned_data.get("rule_text_contains")
+
+ if rule_type:
+ queryset = queryset.filter(rule_type=rule_type)
+
+ if advisory_avid:
+ queryset = queryset.filter(advisory__avid=advisory_avid)
+
+ if rule_text:
+ queryset = queryset.filter(rule_text__icontains=rule_text)
+ return queryset
+
+
class PackageDetails(DetailView):
model = models.Package
template_name = "package_details.html"
diff --git a/vulnerablecode/urls.py b/vulnerablecode/urls.py
index 49948a3b9..3de51a59f 100644
--- a/vulnerablecode/urls.py
+++ b/vulnerablecode/urls.py
@@ -22,6 +22,7 @@
from vulnerabilities.api import VulnerabilityViewSet
from vulnerabilities.api_v2 import CodeFixV2ViewSet
from vulnerabilities.api_v2 import CodeFixViewSet
+from vulnerabilities.api_v2 import DetectionRuleViewSet
from vulnerabilities.api_v2 import PackageV2ViewSet
from vulnerabilities.api_v2 import PackageV3ViewSet
from vulnerabilities.api_v2 import PipelineScheduleV2ViewSet
@@ -30,6 +31,7 @@
from vulnerabilities.views import AdvisoryDetails
from vulnerabilities.views import AdvisoryPackagesDetails
from vulnerabilities.views import ApiUserCreateView
+from vulnerabilities.views import DetectionRuleSearch
from vulnerabilities.views import HomePage
from vulnerabilities.views import HomePageV2
from vulnerabilities.views import PackageDetails
@@ -71,6 +73,8 @@ def __init__(self, *args, **kwargs):
api_v3_router.register("packages", PackageV3ViewSet, basename="package-v3")
+api_v3_router.register("detection-rules", DetectionRuleViewSet, basename="detection-rule")
+
urlpatterns = [
path("admin/login/", AdminLoginView.as_view(), name="admin-login"),
path("api/v2/", include(api_v2_router.urls)),
@@ -114,6 +118,11 @@ def __init__(self, *args, **kwargs):
AdvisoryDetails.as_view(),
name="advisory_details",
),
+ path(
+ "rules/search/",
+ DetectionRuleSearch.as_view(),
+ name="detection_rule_search",
+ ),
path(
"packages/search/",
PackageSearch.as_view(),