Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
20 changes: 8 additions & 12 deletions .github/workflows/test_against_escu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
fail-fast: false
matrix:
python_version: ["3.11", "3.12", "3.13"]

operating_system: ["ubuntu-24.04", "macos-15"]
# Do not test against ESCU until known character encoding issue is resolved
# operating_system: ["ubuntu-20.04", "ubuntu-22.04", "macos-latest", "macos-14", "windows-2022"]
Expand All @@ -32,7 +32,7 @@ jobs:
# Checkout the develop (default) branch of security_content
- name: Checkout repo
uses: actions/checkout@v5
with:
with:
path: security_content
repository: splunk/security_content

Expand All @@ -42,30 +42,26 @@ jobs:
with:
python-version: ${{ matrix.python_version }}
architecture: "x64"

- name: Install Poetry
run:
python -m pip install poetry
run: python -m pip install poetry

- name: Install contentctl and activate the shell
run: |
poetry install --no-interaction


- name: Clone the AtomicRedTeam Repo and the Mitre/CTI repos for testing enrichments
- name: Clone the AtomicRedTeam Repo and the Mitre/CTI repos for testing
enrichments
run: |
cd security_content
git clone --single-branch https://github.com/redcanaryco/atomic-red-team external_repos/atomic-red-team
git clone --single-branch https://github.com/mitre/cti external_repos/cti
git clone --depth=1 --single-branch --branch="master" https://github.com/mitre-attack/attack-stix-data external_repos/cti


# We do not separately run validate and build
# We do not separately run validate and build
# since a build ALSO performs a validate
- name: Run contentctl build
run: |
cd security_content
poetry run contentctl build --enrichments

# Do not run a test - it will take far too long!
# Do not upload any artifacts

17 changes: 12 additions & 5 deletions contentctl/enrichments/attack_enrichment.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from contentctl.objects.annotated_types import MITRE_ATTACK_ID_TYPE
from contentctl.objects.config import validate
from contentctl.objects.constants import MITRE_ATTACK_VERSION
from contentctl.objects.mitre_attack_enrichment import (
MitreAttackEnrichment,
MitreTactics,
Expand Down Expand Up @@ -121,8 +122,13 @@ def get_attack_lookup(
flush=True,
)
enterprise_path = input_path / "enterprise-attack"
mobile_path = input_path / "ics-attack"
ics_path = input_path / "mobile-attack"
enterprise_file = (
enterprise_path / f"enterprise-attack-{MITRE_ATTACK_VERSION}.json"
)
mobile_path = input_path / "mobile-attack"
mobile_file = mobile_path / f"mobile-attack-{MITRE_ATTACK_VERSION}.json"
ics_path = input_path / "ics-attack"
ics_file = ics_path / f"ics-attack-{MITRE_ATTACK_VERSION}.json"
if not (
enterprise_path.is_dir() and mobile_path.is_dir() and ics_path.is_dir()
):
Expand All @@ -132,11 +138,12 @@ def get_attack_lookup(
f"Please ensure that the {input_path} directory "
"has been git cloned correctly."
)

lift = attack_client(
local_paths={
"enterprise": str(enterprise_path),
"mobile": str(mobile_path),
"ics": str(ics_path),
"enterprise": str(enterprise_file),
"mobile": str(mobile_file),
"ics": str(ics_file),
}
)

Expand Down
9 changes: 3 additions & 6 deletions contentctl/objects/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -491,12 +491,12 @@ def ensureEnrichmentReposPresent(self) -> Self:
missing_repos: list[str] = []
if not self.atomic_red_team_repo_path.is_dir():
missing_repos.append(
f"https://github.com/redcanaryco/atomic-red-team {self.atomic_red_team_repo_path}"
f"--single-branch https://github.com/redcanaryco/atomic-red-team {self.atomic_red_team_repo_path}"
)

if not self.mitre_cti_repo_path.is_dir():
missing_repos.append(
f"https://github.com/mitre/cti {self.mitre_cti_repo_path}"
f"""--depth=1 --single-branch --branch="master" https://github.com/mitre-attack/attack-stix-data {self.mitre_cti_repo_path}"""
)

if len(missing_repos) > 0:
Expand All @@ -506,10 +506,7 @@ def ensureEnrichmentReposPresent(self) -> Self:
"Please check them out using the following commands:"
]
msg_list.extend(
[
f"git clone --single-branch {repo_string}"
for repo_string in missing_repos
]
[f"git clone {repo_string}" for repo_string in missing_repos]
)
msg = "\n\t".join(msg_list)
raise FileNotFoundError(msg)
Expand Down
4 changes: 4 additions & 0 deletions contentctl/objects/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
"Command And Control": "Command and Control",
"Exfiltration": "Actions on Objectives",
"Impact": "Actions on Objectives",
"Stealth": "Exploitation",
"Defense Impairment": "Exploitation",
}

SES_CONTEXT_MAPPING = {
Expand Down Expand Up @@ -148,3 +150,5 @@

DEPRECATED_TEMPLATE = "**WARNING**, this {content_type} has been marked **DEPRECATED** by the Splunk Threat Research Team. This means that it will no longer be maintained or supported. If you have any questions feel free to email us at: research@splunk.com. {description}"
EXPERIMENTAL_TEMPLATE = "**WARNING**, this {content_type} is marked **EXPERIMENTAL** by the Splunk Threat Research Team. This means that the {content_type} has been manually tested but we do not have the associated attack data to perform automated testing or cannot share this attack dataset due to its sensitive nature. If you have any questions feel free to email us at: research@splunk.com. {description}"

MITRE_ATTACK_VERSION = "19.0"
2 changes: 2 additions & 0 deletions contentctl/objects/mitre_attack_enrichment.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ class MitreTactics(StrEnum):
COMMAND_AND_CONTROL = "Command And Control"
EXFILTRATION = "Exfiltration"
IMPACT = "Impact"
STEALTH = "Stealth"
DEFENSE_IMPAIRMENT = "Defense Impairment"


class AttackGroupMatrix(StrEnum):
Expand Down
4 changes: 3 additions & 1 deletion contentctl/output/attack_nav_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
from datetime import datetime
from typing import Any, TypedDict

from contentctl.objects.constants import MITRE_ATTACK_VERSION

# Third-party imports
from contentctl.objects.detection import Detection

Expand Down Expand Up @@ -88,7 +90,7 @@ def writeObjects(
layer: LayerData = {
"name": self.layer_name,
"versions": {
"attack": "17", # Update as needed
"attack": MITRE_ATTACK_VERSION,
"navigator": "5.1.0",
"layer": "4.5",
},
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[tool.poetry]
name = "contentctl"

version = "5.5.16"
version = "5.6.0"

description = "Splunk Content Control Tool"
authors = ["STRT <research@splunk.com>"]
Expand Down
Loading