diff --git a/bin/contentctl/contentctl/contentctl/application/adapter/adapter.py b/bin/contentctl/contentctl/contentctl/application/adapter/adapter.py
new file mode 100644
index 0000000000..924e2653d0
--- /dev/null
+++ b/bin/contentctl/contentctl/contentctl/application/adapter/adapter.py
@@ -0,0 +1,27 @@
+import abc
+
+class Adapter(abc.ABC):
+
+ @abc.abstractmethod
+ def writeDetections(self, detections: list, output_folder: str) -> None:
+ pass
+
+ @abc.abstractmethod
+ def writeStories(self, stories: list, output_folder: str) -> None:
+ pass
+
+ @abc.abstractmethod
+ def writeBaselines(self, baselines: list, output_folder: str) -> None:
+ pass
+
+ @abc.abstractmethod
+ def writeInvestigations(self, investigations: list, output_folder: str) -> None:
+ pass
+
+ @abc.abstractmethod
+ def writeLookups(self, lookups: list, output_folder: str, security_content_path: str) -> None:
+ pass
+
+ @abc.abstractmethod
+ def writeMacros(self, macros: list, output_folder: str) -> None:
+ pass
\ No newline at end of file
diff --git a/bin/contentctl/contentctl/contentctl/application/builder/baseline_builder.py b/bin/contentctl/contentctl/contentctl/application/builder/baseline_builder.py
new file mode 100644
index 0000000000..c9787b41b3
--- /dev/null
+++ b/bin/contentctl/contentctl/contentctl/application/builder/baseline_builder.py
@@ -0,0 +1,25 @@
+import abc
+
+from contentctl.contentctl.domain.entities.enums.enums import SecurityContentType
+from contentctl.contentctl.domain.entities.baseline import Baseline
+from contentctl.contentctl.domain.entities.enums.enums import SecurityContentProduct
+from contentctl.contentctl.domain.entities.security_content_object import SecurityContentObject
+
+
+class BaselineBuilder(abc.ABC):
+
+ @abc.abstractmethod
+ def addDeployment(self, deployments: list) -> None:
+ pass
+
+ @abc.abstractmethod
+ def setObject(self, path: str, type: SecurityContentType) -> None:
+ pass
+
+ @abc.abstractmethod
+ def reset(self) -> None:
+ pass
+
+ @abc.abstractmethod
+ def getObject(self) -> SecurityContentObject:
+ pass
\ No newline at end of file
diff --git a/bin/contentctl/contentctl/contentctl/application/builder/basic_builder.py b/bin/contentctl/contentctl/contentctl/application/builder/basic_builder.py
index e3bbd1f4e7..f5f4b693a1 100644
--- a/bin/contentctl/contentctl/contentctl/application/builder/basic_builder.py
+++ b/bin/contentctl/contentctl/contentctl/application/builder/basic_builder.py
@@ -17,4 +17,6 @@ class BasicBuilder(abc.ABC):
@abc.abstractmethod
def getObject(self) -> SecurityContentObject:
- pass
\ No newline at end of file
+ pass
+
+
\ No newline at end of file
diff --git a/bin/contentctl/contentctl/contentctl/application/builder/detection_builder.py b/bin/contentctl/contentctl/contentctl/application/builder/detection_builder.py
index cc37005d60..488c4d233a 100644
--- a/bin/contentctl/contentctl/contentctl/application/builder/detection_builder.py
+++ b/bin/contentctl/contentctl/contentctl/application/builder/detection_builder.py
@@ -1,13 +1,15 @@
import abc
from contentctl.contentctl.domain.entities.enums.enums import SecurityContentProduct
+from contentctl.contentctl.domain.entities.security_content_object import SecurityContentObject
+from contentctl.contentctl.domain.entities.enums.enums import SecurityContentType
# https://refactoring.guru/design-patterns/builder
class DetectionBuilder(abc.ABC):
@abc.abstractmethod
- def addDeployment(self, deployments: list, product: SecurityContentProduct) -> None:
+ def addDeployment(self, deployments: list) -> None:
pass
@abc.abstractmethod
@@ -18,6 +20,10 @@ class DetectionBuilder(abc.ABC):
def addNesFields(self) -> None:
pass
+ @abc.abstractmethod
+ def addMappings(self) -> None:
+ pass
+
@abc.abstractmethod
def addAnnotations(self) -> None:
pass
@@ -29,3 +35,15 @@ class DetectionBuilder(abc.ABC):
@abc.abstractmethod
def addBaseline(self, baselines: list) -> None:
pass
+
+ @abc.abstractmethod
+ def setObject(self, path: str, type: SecurityContentType) -> None:
+ pass
+
+ @abc.abstractmethod
+ def reset(self) -> None:
+ pass
+
+ @abc.abstractmethod
+ def getObject(self) -> SecurityContentObject:
+ pass
\ No newline at end of file
diff --git a/bin/contentctl/contentctl/contentctl/application/builder/director.py b/bin/contentctl/contentctl/contentctl/application/builder/director.py
index be4344da66..6b11cba7a2 100644
--- a/bin/contentctl/contentctl/contentctl/application/builder/director.py
+++ b/bin/contentctl/contentctl/contentctl/application/builder/director.py
@@ -1,12 +1,43 @@
+import abc
+from contentctl.contentctl.application.builder.basic_builder import BasicBuilder
+from contentctl.contentctl.application.builder.detection_builder import DetectionBuilder
+from contentctl.contentctl.application.builder.baseline_builder import BaselineBuilder
+from contentctl.contentctl.application.builder.investigation_builder import InvestigationBuilder
+from contentctl.contentctl.application.builder.story_builder import StoryBuilder
+from contentctl.contentctl.domain.entities.enums.enums import SecurityContentProduct
-from contentctl.contentctl.application.builder.builder import Builder
+class Director(abc.ABC):
-class SecurityContentDirector():
- builder: Builder
-
- def constructTTPDetections(builder: Builder) -> None:
+ @abc.abstractmethod
+ def constructDetection(self, builder: DetectionBuilder, path: str, deployments: list, playbooks: list, baselines: list) -> None:
pass
- def constructAnomalyDetections(builder: Builder) -> None:
- pass
\ No newline at end of file
+ @abc.abstractmethod
+ def constructBaseline(self, builder: BaselineBuilder, path: str, deployments: list) -> None:
+ pass
+
+ @abc.abstractmethod
+ def constructDeployment(self, builder: BasicBuilder, path: str) -> None:
+ pass
+
+ @abc.abstractmethod
+ def constructLookup(self, builder: BasicBuilder, path: str) -> None:
+ pass
+
+ @abc.abstractmethod
+ def constructMacro(self, builder: BasicBuilder, path: str) -> None:
+ pass
+
+ @abc.abstractmethod
+ def constructPlaybook(self, builder: BasicBuilder, path: str) -> None:
+ pass
+
+ @abc.abstractmethod
+ def constructStory(self, builder: StoryBuilder, path: str, detections: list, baselines: list, investigations: list) -> None:
+ pass
+
+ @abc.abstractmethod
+ def constructInvestigation(self, builder: InvestigationBuilder, path: str) -> None:
+ pass
+
\ No newline at end of file
diff --git a/bin/contentctl/contentctl/contentctl/application/builder/investigation_builder.py b/bin/contentctl/contentctl/contentctl/application/builder/investigation_builder.py
new file mode 100644
index 0000000000..5323bc15d7
--- /dev/null
+++ b/bin/contentctl/contentctl/contentctl/application/builder/investigation_builder.py
@@ -0,0 +1,12 @@
+import abc
+
+
+class InvestigationBuilder(abc.ABC):
+
+ @abc.abstractmethod
+ def addInputs(self) -> None:
+ pass
+
+ @abc.abstractmethod
+ def addLowercaseName(self) -> None:
+ pass
\ No newline at end of file
diff --git a/bin/contentctl/contentctl/contentctl/application/builder/story_builder.py b/bin/contentctl/contentctl/contentctl/application/builder/story_builder.py
index 07cbe89a90..b5e90aab59 100644
--- a/bin/contentctl/contentctl/contentctl/application/builder/story_builder.py
+++ b/bin/contentctl/contentctl/contentctl/application/builder/story_builder.py
@@ -1,39 +1,33 @@
import abc
-from contentctl.contentctl.domain.entities.detection import Detection
+from contentctl.contentctl.domain.entities.security_content_object import SecurityContentObject
from contentctl.contentctl.domain.entities.enums.enums import SecurityContentType
-from contentctl.contentctl.domain.entities.enums.enums import SecurityContentProduct
-# https://refactoring.guru/design-patterns/builder
-class DetectionBuilder(abc.ABC):
+class StoryBuilder(abc.ABC):
@abc.abstractmethod
- def setObject(self, path: str) -> None:
+ def addDetections(self, detections: list) -> None:
pass
@abc.abstractmethod
- def addDeployment(self, deployments: list, product: SecurityContentProduct) -> None:
+ def addInvestigations(self, investigations: list) -> None:
pass
@abc.abstractmethod
- def addRBA(self) -> None:
+ def addAuthorCompanyName(self) -> None:
pass
@abc.abstractmethod
- def addNesFields(self) -> None:
+ def addBaselines(self, baselines: list) -> None:
+ pass
+
+ @abc.abstractmethod
+ def addInvestigations(self, investigations: list) -> None:
pass
@abc.abstractmethod
- def addAnnotations(self) -> None:
- pass
-
- @abc.abstractmethod
- def addPlaybook(self, playbooks: list) -> None:
- pass
-
- @abc.abstractmethod
- def addBaseline(self, baselines: list) -> None:
+ def setObject(self, path: str, type: SecurityContentType) -> None:
pass
@abc.abstractmethod
@@ -41,5 +35,5 @@ class DetectionBuilder(abc.ABC):
pass
@abc.abstractmethod
- def getObject(self) -> Detection:
+ def getObject(self) -> SecurityContentObject:
pass
\ No newline at end of file
diff --git a/bin/contentctl/contentctl/contentctl/application/factory/factory.py b/bin/contentctl/contentctl/contentctl/application/factory/factory.py
new file mode 100644
index 0000000000..34553ccf6a
--- /dev/null
+++ b/bin/contentctl/contentctl/contentctl/application/factory/factory.py
@@ -0,0 +1,107 @@
+import os
+
+from dataclasses import dataclass
+
+from contentctl.contentctl.domain.entities.enums.enums import SecurityContentProduct
+from contentctl.contentctl.domain.entities.enums.enums import SecurityContentType
+from contentctl.contentctl.application.builder.basic_builder import BasicBuilder
+from contentctl.contentctl.application.builder.detection_builder import DetectionBuilder
+from contentctl.contentctl.application.builder.story_builder import StoryBuilder
+from contentctl.contentctl.application.builder.baseline_builder import BaselineBuilder
+from contentctl.contentctl.application.builder.investigation_builder import InvestigationBuilder
+from contentctl.contentctl.application.builder.director import Director
+from contentctl.contentctl.application.factory.utils.utils import Utils
+
+
+@dataclass(frozen=True)
+class FactoryInputDto:
+ input_path: str
+ basic_builder: BasicBuilder
+ detection_builder: DetectionBuilder
+ story_builder: StoryBuilder
+ baseline_builder: BaselineBuilder
+ investigation_builder: InvestigationBuilder
+ director: Director
+ product: SecurityContentProduct
+
+
+@dataclass(frozen=True)
+class FactoryOutputDto:
+ detections: list
+ stories: list
+ baselines: list
+ investigations: list
+ playbooks: list
+ deployments: list
+ macros: list
+ lookups: list
+
+
+class Factory():
+ input_dto: FactoryInputDto
+ output_dto: FactoryOutputDto
+
+
+ def __init__(self, output_dto: FactoryOutputDto) -> None:
+ self.output_dto = output_dto
+
+
+ def execute(self, input_dto: FactoryInputDto) -> None:
+ self.input_dto = input_dto
+
+ # order matters to load and enrich security content types
+ self.createSecurityContent(SecurityContentType.lookups)
+ self.createSecurityContent(SecurityContentType.macros)
+ self.createSecurityContent(SecurityContentType.deployments)
+ self.createSecurityContent(SecurityContentType.playbooks)
+ self.createSecurityContent(SecurityContentType.baselines)
+ self.createSecurityContent(SecurityContentType.investigations)
+ self.createSecurityContent(SecurityContentType.detections)
+ self.createSecurityContent(SecurityContentType.stories)
+
+
+ def createSecurityContent(self, type: SecurityContentType) -> list:
+ objects = []
+ if type == SecurityContentType.deployments:
+ files = Utils.get_all_yml_files_from_directory(os.path.join(self.input_dto.input_path, str(type.name), str(self.input_dto.product)))
+ else:
+ files = Utils.get_all_yml_files_from_directory(os.path.join(self.input_dto.input_path, str(type.name)))
+
+ for file in files:
+ if type == SecurityContentType.lookups:
+ self.input_dto.director.constructLookup(self.input_dto.basic_builder, file)
+ self.output_dto.lookups.append(self.input_dto.basic_builder.getObject())
+
+ elif type == SecurityContentType.macros:
+ self.input_dto.director.constructMacro(self.input_dto.basic_builder, file)
+ self.output_dto.macros.append(self.input_dto.basic_builder.getObject())
+
+ elif type == SecurityContentType.deployments:
+ self.input_dto.director.constructDeployment(self.input_dto.basic_builder, file)
+ self.output_dto.deployments.append(self.input_dto.basic_builder.getObject())
+
+ elif type == SecurityContentType.playbooks:
+ self.input_dto.director.constructPlaybook(self.input_dto.basic_builder, file)
+ self.output_dto.playbooks.append(self.input_dto.basic_builder.getObject())
+
+ elif type == SecurityContentType.baselines:
+ self.input_dto.director.constructBaseline(self.input_dto.baseline_builder, file)
+ self.output_dto.baselines.append(self.input_dto.baseline_builder.getObject())
+
+ elif type == SecurityContentType.investigations:
+ self.input_dto.director.constructInvestigation(self.input_dto.investigation_builder, file)
+ self.output_dto.investigations.append(self.input_dto.investigation_builder.getObject())
+
+ elif type == SecurityContentType.detections:
+ self.input_dto.director.constructDetection(self.input_dto.detection_builder, file,
+ self.output_dto.deployments, self.output_dto.playbooks, self.output_dto.baselines)
+ self.output_dto.detections.append(self.input_dto.detection_builder.getObject())
+
+ elif type == SecurityContentType.stories:
+ self.input_dto.director.constructStory(self.input_dto.story_builder, file,
+ self.output_dto.detections, self.output_dto.baselines, self.output_dto.investigations)
+ self.output_dto.stories.append(self.input_dto.story_builder.getObject())
+
+
+ def getObjects(self) -> FactoryOutputDto:
+ return self.output_dto
\ No newline at end of file
diff --git a/bin/contentctl/contentctl/contentctl/application/use_cases/utils/__init__.py b/bin/contentctl/contentctl/contentctl/application/factory/utils/__init__.py
similarity index 100%
rename from bin/contentctl/contentctl/contentctl/application/use_cases/utils/__init__.py
rename to bin/contentctl/contentctl/contentctl/application/factory/utils/__init__.py
diff --git a/bin/contentctl/contentctl/contentctl/application/factory/utils/utils.py b/bin/contentctl/contentctl/contentctl/application/factory/utils/utils.py
new file mode 100644
index 0000000000..2a3b1819dc
--- /dev/null
+++ b/bin/contentctl/contentctl/contentctl/application/factory/utils/utils.py
@@ -0,0 +1,13 @@
+import os
+
+class Utils:
+
+ @staticmethod
+ def get_all_yml_files_from_directory(path: str) -> list:
+ listOfFiles = list()
+ for (dirpath, dirnames, filenames) in os.walk(path):
+ for file in filenames:
+ if file.endswith(".yml"):
+ listOfFiles.append(os.path.join(dirpath, file))
+
+ return listOfFiles
\ No newline at end of file
diff --git a/bin/contentctl/contentctl/contentctl/application/use_cases/generate.py b/bin/contentctl/contentctl/contentctl/application/use_cases/generate.py
index c5240008b2..e393b85334 100644
--- a/bin/contentctl/contentctl/contentctl/application/use_cases/generate.py
+++ b/bin/contentctl/contentctl/contentctl/application/use_cases/generate.py
@@ -5,12 +5,23 @@ from dataclasses import dataclass
from contentctl.contentctl.domain.entities.enums.enums import SecurityContentType
from contentctl.contentctl.domain.entities.detection import Detection
-from contentctl.contentctl.application.use_cases.utils.utils import Utils
+from contentctl.contentctl.application.builder.basic_builder import BasicBuilder
+from contentctl.contentctl.application.builder.detection_builder import DetectionBuilder
+from contentctl.contentctl.application.builder.story_builder import StoryBuilder
+from contentctl.contentctl.application.builder.baseline_builder import BaselineBuilder
+from contentctl.contentctl.application.builder.investigation_builder import InvestigationBuilder
+from contentctl.contentctl.application.builder.director import Director
@dataclass(frozen=True)
class GenerateInputDto:
input_path: str
output_path: str
+ basic_builder: BasicBuilder
+ detection_builder: DetectionBuilder
+ story_builder: StoryBuilder
+ baseline_builder: BaselineBuilder
+ investigation_builder: InvestigationBuilder
+ director: Director
@dataclass(frozen=True)
@@ -25,21 +36,14 @@ class GenerateOutputBoundary(abc.ABC):
class Generate:
-
- def test():
+ input_dto: GenerateInputDto
+
+ def __init__(self, output_boundary: GenerateOutputBoundary) -> None:
+ self.output_boundary = output_boundary
+
+ def execute(self, input_dto: GenerateInputDto) -> None:
+ self.input_dto = input_dto
+
+
+ def read_security_content_objects(self, type: SecurityContentType) -> list:
pass
-
- # def __init__(self, output_boundary: GenerateOutputBoundary, security_content_repo: SecurityContentRepository) -> None:
- # self.output_boundary = output_boundary
- # self.security_content_repository = security_content_repo
-
- # def execute(self, input_dto: GenerateInputDto) -> None:
- # self.input_dto = input_dto
- # detections = self.read_security_content_objects(SecurityContentType.detections)
- # stories = self.read_security_content_objects(SecurityContentType.stories)
-
- # def read_security_content_objects(self, type: SecurityContentType) -> list:
- # files = Utils.get_all_files_from_directory(os.path.join(self.input_dto.input_path, str(type.name)))
- # security_content_objects = []
- # for file in files:
- # security_content_objects.append(self.security_content_repository.get(file, type))
diff --git a/bin/contentctl/contentctl/contentctl/application/use_cases/utils/utils.py b/bin/contentctl/contentctl/contentctl/application/use_cases/utils/utils.py
deleted file mode 100644
index c03da79742..0000000000
--- a/bin/contentctl/contentctl/contentctl/application/use_cases/utils/utils.py
+++ /dev/null
@@ -1,11 +0,0 @@
-import os
-
-class Utils:
-
- @staticmethod
- def get_all_files_from_directory(path: str) -> list:
- listOfFiles = list()
- for (dirpath, dirnames, filenames) in os.walk(path):
- listOfFiles += [os.path.join(dirpath, file) for file in filenames]
-
- return listOfFiles
\ No newline at end of file
diff --git a/bin/contentctl/contentctl/contentctl/domain/entities/baseline.py b/bin/contentctl/contentctl/contentctl/domain/entities/baseline.py
new file mode 100644
index 0000000000..cb2be62762
--- /dev/null
+++ b/bin/contentctl/contentctl/contentctl/domain/entities/baseline.py
@@ -0,0 +1,97 @@
+import string
+import uuid
+import requests
+
+from pydantic import BaseModel, validator, ValidationError
+from dataclasses import dataclass
+from datetime import datetime
+
+from contentctl.contentctl.domain.entities.security_content_object import SecurityContentObject
+from contentctl.contentctl.domain.entities.enums.enums import DataModel
+from contentctl.contentctl.domain.entities.baseline_tags import BaselineTags
+from contentctl.contentctl.domain.entities.deployment import Deployment
+
+
+class Baseline(BaseModel, SecurityContentObject):
+ name: str
+ id: str
+ version: int
+ date: str
+ author: str
+ type: str
+ datamodel: list
+ description: str
+ search: str
+ how_to_implement: str
+ known_false_positives: str
+ references: list
+ tags: BaselineTags
+ deployment: Deployment = None
+
+
+ @validator('name')
+ def name_max_length(cls, v):
+ if len(v) > 75:
+ raise ValueError('name is longer then 75 chars: ' + v)
+ return v
+
+ @validator('name')
+ def name_invalid_chars(cls, v):
+ invalidChars = set(string.punctuation.replace("-", ""))
+ if any(char in invalidChars for char in v):
+ raise ValueError('invalid chars used in name: ' + v)
+ return v
+
+ @validator('id')
+ def id_check(cls, v, values):
+ try:
+ uuid.UUID(str(v))
+ except:
+ raise ValueError('uuid is not valid: ' + values["name"])
+ return v
+
+ @validator('date')
+ def date_valid(cls, v, values):
+ try:
+ datetime.strptime(v, "%Y-%m-%d")
+ except:
+ raise ValueError('date is not in format YYYY-MM-DD: ' + values["name"])
+ return v
+
+ @validator('type')
+ def type_valid(cls, v, values):
+ if v != "Baseline":
+ raise ValueError('not valid analytics type: ' + values["name"])
+ return v
+
+ @validator('datamodel')
+ def datamodel_valid(cls, v, values):
+ for datamodel in v:
+ if datamodel not in [el.name for el in DataModel]:
+ raise ValueError('not valid data model: ' + values["name"])
+ return v
+
+ @validator('description', 'how_to_implement')
+ def encode_error(cls, v, values, field):
+ try:
+ v.encode('ascii')
+ except UnicodeEncodeError:
+ raise ValueError('encoding error in ' + field.name + ': ' + values["name"])
+ return v
+
+ @validator('references')
+ def references_check(cls, v, values):
+ for reference in v:
+ try:
+ get = requests.get(reference)
+ if not get.status_code == 200:
+ raise ValueError('Reference ' + reference + ' is not reachable: ' + values["name"])
+ except requests.exceptions.RequestException as e:
+ raise ValueError('Reference ' + reference + ' is not reachable: ' + values["name"])
+
+ return v
+
+ @validator('search')
+ def search_validate(cls, v, values):
+ # write search validator
+ return v
diff --git a/bin/contentctl/contentctl/contentctl/domain/entities/baseline_tags.py b/bin/contentctl/contentctl/contentctl/domain/entities/baseline_tags.py
new file mode 100644
index 0000000000..161afbe71e
--- /dev/null
+++ b/bin/contentctl/contentctl/contentctl/domain/entities/baseline_tags.py
@@ -0,0 +1,25 @@
+
+from pydantic import BaseModel, validator, ValidationError
+
+
+
+class BaselineTags(BaseModel):
+ analytic_story: list
+ deployments: list = None
+ detections: list
+ product: list
+ required_fields: list
+ security_domain: str
+
+
+ @validator('product')
+ def tags_product(cls, v, values):
+ valid_products = [
+ "Splunk Enterprise", "Splunk Enterprise Security", "Splunk Cloud",
+ "Splunk Security Analytics for AWS", "Splunk Behavioral Analytics"
+ ]
+
+ for value in v:
+ if value not in valid_products:
+ raise ValueError('product is not valid for ' + values['name'] + '. valid products are ' + str(valid_products))
+ return v
\ No newline at end of file
diff --git a/bin/contentctl/contentctl/contentctl/domain/entities/detection.py b/bin/contentctl/contentctl/contentctl/domain/entities/detection.py
index 5504844f22..cd88aa3026 100644
--- a/bin/contentctl/contentctl/contentctl/domain/entities/detection.py
+++ b/bin/contentctl/contentctl/contentctl/domain/entities/detection.py
@@ -28,11 +28,13 @@ class Detection(BaseModel, SecurityContentObject):
known_false_positives: str
references: list
tags: DetectionTags
+ deprecated: bool
deployment: Deployment = None
annotations: dict = None
risk: list = None
playbooks: list = None
baselines: list = None
+ mappings: dict = None
@validator('name')
diff --git a/bin/contentctl/contentctl/contentctl/domain/entities/enums/enums.py b/bin/contentctl/contentctl/contentctl/domain/entities/enums/enums.py
index 85288211d1..9b8378bf58 100644
--- a/bin/contentctl/contentctl/contentctl/domain/entities/enums/enums.py
+++ b/bin/contentctl/contentctl/contentctl/domain/entities/enums/enums.py
@@ -5,9 +5,7 @@ class AnalyticsType(enum.Enum):
TTP = 1
anomaly = 2
hunting = 3
- baseline = 4
- investigation = 5
- correlation = 6
+ correlation = 4
class DataModel(enum.Enum):
Endpoint = 1
@@ -25,11 +23,13 @@ class DataModel(enum.Enum):
class SecurityContentType(enum.Enum):
detections = 1
- stories = 2
- playbooks = 3
- macros = 4
- lookups = 5
- deployments = 6
+ baselines = 2
+ stories = 3
+ playbooks = 4
+ macros = 5
+ lookups = 6
+ deployments = 7
+ investigations = 8
class SecurityContentProduct(enum.Enum):
ESCU = 1
diff --git a/bin/contentctl/contentctl/contentctl/domain/entities/investigation.py b/bin/contentctl/contentctl/contentctl/domain/entities/investigation.py
new file mode 100644
index 0000000000..bb72522a12
--- /dev/null
+++ b/bin/contentctl/contentctl/contentctl/domain/entities/investigation.py
@@ -0,0 +1,94 @@
+import enum
+import uuid
+import string
+import re
+import requests
+
+from pydantic import BaseModel, validator, ValidationError
+from dataclasses import dataclass
+from datetime import datetime
+
+from contentctl.contentctl.domain.entities.security_content_object import SecurityContentObject
+from contentctl.contentctl.domain.entities.enums.enums import AnalyticsType
+from contentctl.contentctl.domain.entities.enums.enums import DataModel
+from contentctl.contentctl.domain.entities.investigation_tags import InvestigationTags
+
+
+class Investigation(BaseModel, SecurityContentObject):
+ name: str
+ id: str
+ version: int
+ date: str
+ author: str
+ type: str
+ datamodel: list
+ description: str
+ search: str
+ how_to_implement: str
+ known_false_positives: str
+ references: list
+ tags: InvestigationTags
+ inputs: list = None
+ lowercase_name: str = None
+
+
+ @validator('name')
+ def name_max_length(cls, v):
+ if len(v) > 75:
+ raise ValueError('name is longer then 75 chars: ' + v)
+ return v
+
+ @validator('name')
+ def name_invalid_chars(cls, v):
+ invalidChars = set(string.punctuation.replace("-", ""))
+ if any(char in invalidChars for char in v):
+ raise ValueError('invalid chars used in name: ' + v)
+ return v
+
+ @validator('id')
+ def id_check(cls, v, values):
+ try:
+ uuid.UUID(str(v))
+ except:
+ raise ValueError('uuid is not valid: ' + values["name"])
+ return v
+
+ @validator('date')
+ def date_valid(cls, v, values):
+ try:
+ datetime.strptime(v, "%Y-%m-%d")
+ except:
+ raise ValueError('date is not in format YYYY-MM-DD: ' + values["name"])
+ return v
+
+ @validator('datamodel')
+ def datamodel_valid(cls, v, values):
+ for datamodel in v:
+ if datamodel not in [el.name for el in DataModel]:
+ raise ValueError('not valid data model: ' + values["name"])
+ return v
+
+ @validator('description', 'how_to_implement')
+ def encode_error(cls, v, values, field):
+ try:
+ v.encode('ascii')
+ except UnicodeEncodeError:
+ raise ValueError('encoding error in ' + field.name + ': ' + values["name"])
+ return v
+
+ @validator('references')
+ def references_check(cls, v, values):
+ for reference in v:
+ try:
+ get = requests.get(reference)
+ if not get.status_code == 200:
+ raise ValueError('Reference ' + reference + ' is not reachable: ' + values["name"])
+ except requests.exceptions.RequestException as e:
+ raise ValueError('Reference ' + reference + ' is not reachable: ' + values["name"])
+
+ return v
+
+ @validator('search')
+ def search_validate(cls, v, values):
+ # write search validator
+ return v
\ No newline at end of file
diff --git a/bin/contentctl/contentctl/contentctl/domain/entities/investigation_tags.py b/bin/contentctl/contentctl/contentctl/domain/entities/investigation_tags.py
new file mode 100644
index 0000000000..a6a0334f2a
--- /dev/null
+++ b/bin/contentctl/contentctl/contentctl/domain/entities/investigation_tags.py
@@ -0,0 +1,9 @@
+
+from pydantic import BaseModel, validator, ValidationError
+
+
+class InvestigationTags(BaseModel):
+ analytic_story: list
+ product: list
+ required_fields: list
+ security_domain: str
\ No newline at end of file
diff --git a/bin/contentctl/contentctl/contentctl/domain/entities/lookup.py b/bin/contentctl/contentctl/contentctl/domain/entities/lookup.py
index b1181d879d..97d1f7c027 100644
--- a/bin/contentctl/contentctl/contentctl/domain/entities/lookup.py
+++ b/bin/contentctl/contentctl/contentctl/domain/entities/lookup.py
@@ -8,7 +8,7 @@ class Lookup(BaseModel, SecurityContentObject):
name: str
description: str
collection: str = None
- fields_list: list = None
+ fields_list: str = None
filename: str = None
default_match: str = None
match_type: str = None
diff --git a/bin/contentctl/contentctl/contentctl/domain/entities/story.py b/bin/contentctl/contentctl/contentctl/domain/entities/story.py
index 9a93becabf..b56d903240 100644
--- a/bin/contentctl/contentctl/contentctl/domain/entities/story.py
+++ b/bin/contentctl/contentctl/contentctl/domain/entities/story.py
@@ -18,6 +18,12 @@ class Story(BaseModel, SecurityContentObject):
narrative: str
references: list
tags: StoryTags
+ detection_names: list = None
+ investigation_names: list = None
+ baseline_names: list = None
+ author_company: str = None
+ author_name: str = None
+
@validator('name')
def name_invalid_chars(cls, v):
diff --git a/bin/contentctl/contentctl/contentctl/tests/application/factory/test_factory.py b/bin/contentctl/contentctl/contentctl/tests/application/factory/test_factory.py
new file mode 100644
index 0000000000..29a9842eb2
--- /dev/null
+++ b/bin/contentctl/contentctl/contentctl/tests/application/factory/test_factory.py
@@ -0,0 +1,34 @@
+import os
+
+from contentctl.contentctl.application.factory.factory import FactoryInputDto
+from contentctl.contentctl.application.factory.factory import FactoryOutputDto
+from contentctl.contentctl.application.factory.factory import Factory
+from contentctl_infrastructure.contentctl_infrastructure.builder.security_content_director import SecurityContentDirector
+from contentctl_infrastructure.contentctl_infrastructure.builder.security_content_basic_builder import SecurityContentBasicBuilder
+from contentctl_infrastructure.contentctl_infrastructure.builder.security_content_detection_builder import SecurityContentDetectionBuilder
+from contentctl_infrastructure.contentctl_infrastructure.builder.security_content_story_builder import SecurityContentStoryBuilder
+from contentctl.contentctl.domain.entities.enums.enums import SecurityContentProduct
+from contentctl_infrastructure.contentctl_infrastructure.builder.security_content_investigation_builder import SecurityContentInvestigationBuilder
+from contentctl_infrastructure.contentctl_infrastructure.builder.security_content_baseline_builder import SecurityContentBaselineBuilder
+
+
+def test_factory_ESCU():
+ input_path = os.path.join(os.path.dirname(__file__), '../../../../../../..')
+
+ input_dto = FactoryInputDto(
+ input_path,
+ SecurityContentBasicBuilder(),
+ SecurityContentDetectionBuilder(),
+ SecurityContentStoryBuilder(),
+ SecurityContentBaselineBuilder(),
+ SecurityContentInvestigationBuilder(),
+ SecurityContentDirector(),
+ SecurityContentProduct.ESCU
+ )
+
+ output_dto = FactoryOutputDto([],[],[],[],[],[],[],[])
+
+ factory = Factory(output_dto)
+ factory.execute(input_dto)
+
+ print(len(output_dto.detections))
diff --git a/bin/contentctl/contentctl/requirements-dev.txt b/bin/contentctl/contentctl/requirements-dev.txt
deleted file mode 100644
index 568ac170eb..0000000000
--- a/bin/contentctl/contentctl/requirements-dev.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-pydantic
-pytest
-requests
\ No newline at end of file
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/conf_writer.py b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/conf_writer.py
new file mode 100644
index 0000000000..fec0fea0dc
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/conf_writer.py
@@ -0,0 +1,55 @@
+import datetime
+import os
+from jinja2 import Environment, FileSystemLoader
+
+from contentctl.contentctl.domain.entities.security_content_object import SecurityContentObject
+
+class ConfWriter():
+
+ @staticmethod
+ def writeConfFileHeader(output_path : str) -> None:
+ utc_time = datetime.datetime.utcnow().replace(microsecond=0).isoformat()
+ j2_env = Environment(
+ loader=FileSystemLoader(os.path.join(os.path.dirname(__file__), 'templates')),
+ trim_blocks=True)
+
+ template = j2_env.get_template('header.j2')
+ output = template.render(time=utc_time)
+ with open(output_path, 'w') as f:
+ output = output.encode('ascii', 'ignore').decode('ascii')
+ f.write(output)
+
+
+ @staticmethod
+ def writeConfFile(template_name : str, output_path : str, objects : list) -> None:
+
+ def custom_jinja2_enrichment_filter(string, object):
+ customized_string = string
+
+ for key in dir(object):
+ if type(key) is not str:
+ key = key.decode()
+ if not key.startswith('__') and not key == "_abc_impl" and not callable(getattr(object, key)):
+ if hasattr(object, key):
+ customized_string = customized_string.replace("%" + key + "%", str(getattr(object, key)))
+
+ for key in dir(object.tags):
+ if type(key) is not str:
+ key = key.decode()
+ if not key.startswith('__') and not key == "_abc_impl" and not callable(getattr(object.tags, key)):
+ if hasattr(object.tags, key):
+ customized_string = customized_string.replace("%" + key + "%", str(getattr(object.tags, key)))
+
+ return customized_string
+
+ j2_env = Environment(
+ loader=FileSystemLoader(os.path.join(os.path.dirname(__file__), 'templates')),
+ trim_blocks=True)
+
+ j2_env.filters['custom_jinja2_enrichment_filter'] = custom_jinja2_enrichment_filter
+ template = j2_env.get_template(template_name)
+ output = template.render(objects=objects)
+ with open(output_path, 'a') as f:
+ output = output.encode('ascii', 'ignore').decode('ascii')
+ f.write(output)
+
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/obj_to_conf_adapter.py b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/obj_to_conf_adapter.py
new file mode 100644
index 0000000000..035a5a61ee
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/obj_to_conf_adapter.py
@@ -0,0 +1,93 @@
+import os
+import glob
+import shutil
+
+from contentctl.contentctl.application.adapter.adapter import Adapter
+from contentctl_infrastructure.contentctl_infrastructure.adapter.conf_writer import ConfWriter
+
+
+class ObjToConfAdapter(Adapter):
+
+ def writeHeaders(self, output_folder: str) -> None:
+ ConfWriter.writeConfFileHeader(os.path.join(output_folder, 'default/analyticstories.conf'))
+ ConfWriter.writeConfFileHeader(os.path.join(output_folder, 'default/savedsearches.conf'))
+ ConfWriter.writeConfFileHeader(os.path.join(output_folder, 'default/collections.conf'))
+ ConfWriter.writeConfFileHeader(os.path.join(output_folder, 'default/es_investigations.conf'))
+ ConfWriter.writeConfFileHeader(os.path.join(output_folder, 'default/macros.conf'))
+ ConfWriter.writeConfFileHeader(os.path.join(output_folder, 'default/transforms.conf'))
+ ConfWriter.writeConfFileHeader(os.path.join(output_folder, 'default/workflow_actions.conf'))
+
+
+ def writeDetections(self, detections: list, output_folder: str) -> None:
+ ConfWriter.writeConfFile('savedsearches_detections.j2',
+ os.path.join(output_folder, 'default/savedsearches.conf'),
+ detections)
+
+ ConfWriter.writeConfFile('analyticstories_detections.j2',
+ os.path.join(output_folder, 'default/analyticstories.conf'),
+ detections)
+
+ ConfWriter.writeConfFile('macros_detections.j2',
+ os.path.join(output_folder, 'default/macros.conf'),
+ detections)
+
+
+ def writeStories(self, stories: list, output_folder: str) -> None:
+ ConfWriter.writeConfFile('analyticstories_stories.j2',
+ os.path.join(output_folder, 'default/analyticstories.conf'),
+ stories)
+
+
+ def writeBaselines(self, baselines: list, output_folder: str) -> None:
+ ConfWriter.writeConfFile('savedsearches_baselines.j2',
+ os.path.join(output_folder, 'default/savedsearches.conf'),
+ baselines)
+
+
+ def writeInvestigations(self, investigations: list, output_folder: str) -> None:
+ ConfWriter.writeConfFile('savedsearches_investigations.j2',
+ os.path.join(output_folder, 'default/savedsearches.conf'),
+ investigations)
+
+ workbench_panels = []
+ for investigation in investigations:
+ if investigation.inputs:
+ response_file_name_xml = investigation.lowercase_name + "___response_task.xml"
+ workbench_panels.append(investigation)
+ investigation.search = investigation.search.replace(">",">")
+ investigation.search = investigation.search.replace("<","<")
+ ConfWriter.writeConfFileHeader(os.path.join(output_folder,
+ 'default/data/ui/panels/', str("workbench_panel_" + response_file_name_xml)))
+ ConfWriter.writeConfFile('panel.j2',
+ os.path.join(output_folder,
+ 'default/data/ui/panels/', str("workbench_panel_" + response_file_name_xml)),
+ [investigation.search])
+
+ ConfWriter.writeConfFile('es_investigations_investigations.j2',
+ os.path.join(output_folder, 'default/es_investigations.conf'),
+ workbench_panels)
+
+ ConfWriter.writeConfFile('workflow_actions.j2',
+ os.path.join(output_folder, 'default/workflow_actions.conf'),
+ workbench_panels)
+
+
+ def writeLookups(self, lookups: list, output_folder: str, security_content_path: str) -> None:
+ ConfWriter.writeConfFile('collections.j2',
+ os.path.join(output_folder, 'default/collections.conf'),
+ lookups)
+
+ ConfWriter.writeConfFile('transforms.j2',
+ os.path.join(output_folder, 'default/transforms.conf'),
+ lookups)
+
+ files = glob.iglob(os.path.join(security_content_path, 'lookups', '*.csv'))
+ for file in files:
+ if os.path.isfile(file):
+ shutil.copy(file, os.path.join(output_folder, 'lookups'))
+
+
+ def writeMacros(self, macros: list, output_folder: str) -> None:
+ ConfWriter.writeConfFile('macros.j2',
+ os.path.join(output_folder, 'default/macros.conf'),
+ macros)
\ No newline at end of file
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/templates/analyticstories_detections.j2 b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/templates/analyticstories_detections.j2
new file mode 100644
index 0000000000..088139df56
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/templates/analyticstories_detections.j2
@@ -0,0 +1,22 @@
+
+### DETECTIONS ###
+
+{% for detection in objects %}
+{% if (detection.type == 'TTP' or detection.type == 'Anomaly' or detection.type == 'Hunting' or detection.type == 'Correlation') %}
+[savedsearch://ESCU - {{ detection.name }} - Rule]
+type = detection
+asset_type = {{ detection.tags.asset_type }}
+confidence = medium
+explanation = {{ detection.description }}
+{% if detection.how_to_implement is defined %}
+how_to_implement = {{ detection.how_to_implement }}
+{% else %}
+how_to_implement = none
+{% endif %}
+annotations = {{ detection.mappings | tojson }}
+known_false_positives = {{ detection.known_false_positives }}
+providing_technologies = []
+
+{% endif %}
+{% endfor %}
+### END DETECTIONS ###
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/templates/analyticstories_stories.j2 b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/templates/analyticstories_stories.j2
new file mode 100644
index 0000000000..b6543567e7
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/templates/analyticstories_stories.j2
@@ -0,0 +1,21 @@
+
+
+### STORIES ###
+
+{% for story in objects %}
+[analytic_story://{{ story.name }}]
+category = {{ story.tags.category[0] }}
+last_updated = {{ story.date }}
+version = {{ story.version }}
+references = {{ story.references | tojson }}
+maintainers = [{"company": "{{ story.author_company }}", "email": "-", "name": "{{ story.author_name }}"}]
+spec_version = 3
+searches = {{ (story.detection_names + story.investigation_names) | tojson }}
+description = {{ story.description }}
+{% if story.narrative is defined %}
+narrative = {{ story.narrative }}
+{% endif %}
+
+{% endfor %}
+### END STORIES ###
+
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/templates/collections.j2 b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/templates/collections.j2
new file mode 100644
index 0000000000..62bc43152f
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/templates/collections.j2
@@ -0,0 +1,7 @@
+
+{% for lookup in objects %}
+[{{ lookup.name }}]
+enforceTypes = false
+replicate = false
+
+{% endfor %}
\ No newline at end of file
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/templates/es_investigations_investigations.j2 b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/templates/es_investigations_investigations.j2
new file mode 100644
index 0000000000..883af41898
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/templates/es_investigations_investigations.j2
@@ -0,0 +1,38 @@
+
+{% for response_task in objects %}
+[panel://workbench_panel_{{ response_task.lowercase_name }}___response_task]
+label = {{ response_task.name }}
+description = {{ response_task.description }}
+disabled = 0
+tokens = {\
+{% for token in response_task.inputs %}
+{% if token == 'user' %}
+ "user": {\
+ "valuePrefix": "\"",\
+ "valueSuffix": "\"",\
+ "delimiter": " OR {{ token }}=",\
+ "valueType": "primitive",\
+ "value": "identity",\
+ "default": "null"\
+ }{% elif token == 'dest'%}
+ "dest": {\
+ "valuePrefix": "\"",\
+ "valueSuffix": "\"",\
+ "delimiter": " OR {{ token }}=",\
+ "valueType": "primitive",\
+ "value": "asset",\
+ "default": "null"\
+ }{% else %}
+ "{{ token }}": {\
+ "valuePrefix": "\"",\
+ "valueSuffix": "\"",\
+ "delimiter": " OR {{ token }}=",\
+ "valueType": "primitive",\
+ "value": "file",\
+ "default": "null"\
+ }{% endif %}{{ "," if not loop.last }}\
+{% endfor %}
+}\
+
+
+{% endfor %}
\ No newline at end of file
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/templates/es_investigations_stories.j2 b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/templates/es_investigations_stories.j2
new file mode 100644
index 0000000000..da0268a0c6
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/templates/es_investigations_stories.j2
@@ -0,0 +1,14 @@
+
+{% for story in objects %}
+[panel_group://workbench_panel_group_{{ story.lowercase_name}}]
+label = {{ story.name }}
+description = {{ story.description }}
+disabled = 0
+
+{% if story.workbench_panels is defined %}
+panels = {{ story.workbench_panels | tojson }}
+{% else %}
+panels = ["panel://workbench_panel_get_notable_history___response_task"]
+{% endif %}
+
+{% endfor %}
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/templates/header.j2 b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/templates/header.j2
new file mode 100644
index 0000000000..308455116f
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/templates/header.j2
@@ -0,0 +1,7 @@
+#############
+# Automatically generated by generator.py in splunk/security_content
+# On Date: {{ time }} UTC
+# Author: Splunk Security Research
+# Contact: research@splunk.com
+#############
+
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/templates/macros.j2 b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/templates/macros.j2
new file mode 100644
index 0000000000..a9fb11cf35
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/templates/macros.j2
@@ -0,0 +1,15 @@
+
+{% for macro in objects %}
+[{{ macro.name }}{% if macro.arguments is not none %}({{ macro.arguments|length }}){% endif %}]
+{% if macro.arguments is not none %}
+args = {% for arg in macro.arguments %}{{ arg }}{{ ", " if not loop.last }}
+{% endfor %}
+{% endif %}
+{% if macro.definition is not none %}
+definition = {{ macro.definition }}
+{% else %}
+definition =
+{% endif %}
+description = {{ macro.description }}
+
+{% endfor %}
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/templates/macros_detections.j2 b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/templates/macros_detections.j2
new file mode 100644
index 0000000000..dbfd54c526
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/templates/macros_detections.j2
@@ -0,0 +1,7 @@
+
+{% for detection in objects %}
+[{{ detection.name | replace(' ', '_') | replace('-', '_') | replace('.', '_') | replace('/', '_') | lower + '_filter' }}]
+definition = search *
+description = Update this macro to limit the output results to filter out false positives.
+
+{% endfor %}
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/templates/panel.j2 b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/templates/panel.j2
new file mode 100644
index 0000000000..2f46685448
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/templates/panel.j2
@@ -0,0 +1,11 @@
+{% for search in objects %}
+
+
+
+ {{ search }}
+
+
+
+
+
+{% endfor %}
\ No newline at end of file
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/templates/savedsearches_baselines.j2 b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/templates/savedsearches_baselines.j2
new file mode 100644
index 0000000000..aa7d1a408b
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/templates/savedsearches_baselines.j2
@@ -0,0 +1,49 @@
+
+
+### ESCU BASELINES ###
+
+{% for detection in objects %}
+{% if (detection.type == 'Baseline') %}
+[ESCU - {{ detection.name }}]
+action.escu = 0
+action.escu.enabled = 1
+action.escu.search_type = support
+action.escu.full_search_name = ESCU - {{ detection.name }}
+description = {{ detection.description }}
+action.escu.creation_date = {{ detection.date }}
+action.escu.modification_date = {{ detection.date }}
+{% if detection.tags.analytic_story is defined %}
+action.escu.analytic_story = {{ detection.tags.analytic_story | tojson }}
+{% else %}
+action.escu.analytic_story = []
+{% endif %}
+action.escu.data_models = {{ detection.datamodel | tojson }}
+cron_schedule = {{ detection.deployment.scheduling.cron_schedule }}
+enableSched = 1
+dispatch.earliest_time = {{ detection.deployment.scheduling.earliest_time }}
+dispatch.latest_time = {{ detection.deployment.scheduling.latest_time }}
+{% if detection.deployment.scheduling.schedule_window is defined %}
+schedule_window = {{ detection.deployment.scheduling.schedule_window }}
+{% endif %}
+{% if detection.providing_technologies is defined %}
+action.escu.providing_technologies = {{ detection.providing_technologies | tojson }}
+{% else %}
+action.escu.providing_technologies = []
+{% endif %}
+action.escu.eli5 = {{ detection.description }}
+{% if detection.how_to_implement is defined %}
+action.escu.how_to_implement = {{ detection.how_to_implement }}
+{% else %}
+action.escu.how_to_implement = none
+{% endif %}
+{% if detection.disabled is defined %}
+disabled = false
+{% else %}
+disabled = true
+{% endif %}
+is_visible = false
+search = {{ detection.search }}
+
+{% endif %}
+{% endfor %}
+
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/templates/savedsearches_detections.j2 b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/templates/savedsearches_detections.j2
new file mode 100644
index 0000000000..04b13be58b
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/templates/savedsearches_detections.j2
@@ -0,0 +1,111 @@
+### ESCU DETECTIONS ###
+
+{% for detection in objects %}
+{% if (detection.type == 'TTP' or detection.type == 'Anomaly' or detection.type == 'Hunting' or detection.type == 'Correlation') %}
+[ESCU - {{ detection.name }} - Rule]
+action.escu = 0
+action.escu.enabled = 1
+{% if detection.deprecated %}
+description = WARNING, this detection 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. {{ detection.description }}
+{% else %}
+description = {{ detection.description }}
+{% endif %}
+action.escu.mappings = {{ detection.mappings | tojson }}
+action.escu.data_models = {{ detection.datamodel | tojson }}
+action.escu.eli5 = {{ detection.description }}
+{% if detection.how_to_implement is defined %}
+action.escu.how_to_implement = {{ detection.how_to_implement }}
+{% else %}
+action.escu.how_to_implement = none
+{% endif %}
+{% if detection.known_false_positives is defined %}
+action.escu.known_false_positives = {{ detection.known_false_positives }}
+{% else %}
+action.escu.known_false_positives = None
+{% endif %}
+action.escu.creation_date = {{ detection.date }}
+action.escu.modification_date = {{ detection.date }}
+action.escu.confidence = high
+action.escu.full_search_name = ESCU - {{ detection.name }} - Rule
+action.escu.search_type = detection
+{% if detection.tags.product is defined %}
+action.escu.product = {{ detection.tags.product | tojson }}
+{% endif %}
+{% if detection.providing_technologies is defined %}
+action.escu.providing_technologies = {{ detection.providing_technologies | tojson }}
+{% else %}
+action.escu.providing_technologies = []
+{% endif %}
+{% if detection.tags.analytic_story is defined %}
+action.escu.analytic_story = {{ detection.tags.analytic_story | tojson }}
+{% if detection.tags.risk_score is defined %}
+action.risk = 1
+action.risk.param._risk_message = {{ detection.tags.message }}
+action.risk.param._risk = {{ detection.risk | tojson }}
+action.risk.param.verbose = 0
+{% endif %}
+{% else %}
+action.escu.analytic_story = []
+{% endif %}
+cron_schedule = {{ detection.deployment.scheduling.cron_schedule }}
+dispatch.earliest_time = {{ detection.deployment.scheduling.earliest_time }}
+dispatch.latest_time = {{ detection.deployment.scheduling.latest_time }}
+action.correlationsearch.enabled = 1
+{% if detection.deprecated %}
+action.correlationsearch.label = ESCU - Deprecated - {{ detection.name }} - Rule
+{% else %}
+action.correlationsearch.label = ESCU - {{ detection.name }} - Rule
+{% endif %}
+action.correlationsearch.annotations = {{ detection.annotations | tojson }}
+{% if detection.deployment.scheduling.schedule_window is defined %}
+schedule_window = {{ detection.deployment.scheduling.schedule_window }}
+{% endif %}
+{% if detection.deployment is defined %}
+{% if detection.deployment.notable.rule_title is defined %}
+action.notable = 1
+{% if detection.deployment.notable.nes_fields is defined %}
+action.notable.param.nes_fields = {{ detection.deployment.notable.nes_fields }}
+{% endif %}
+action.notable.param.rule_description = {{ detection.deployment.notable.rule_description | custom_jinja2_enrichment_filter(detection) }}
+action.notable.param.rule_title = {{ detection.deployment.notable.rule_title | custom_jinja2_enrichment_filter(detection) }}
+action.notable.param.security_domain = {{ detection.tags.security_domain }}
+action.notable.param.severity = high
+{% endif %}
+{% if detection.deployment.email.to is defined %}
+action.email.subject.alert = {{ detection.deployment.email.subject | custom_jinja2_enrichment_filter(detection) }}
+action.email.to = {{ detection.deployment.email.to }}
+action.email.message.alert = {{ detection.deployment.email.message | custom_jinja2_enrichment_filter(detection) }}
+action.email.useNSSubject = 1
+{% endif %}
+{% if detection.deployment.slack.channel is defined %}
+action.slack = 1
+action.slack.param.channel = {{ detection.deployment.slack.channel | custom_jinja2_enrichment_filter(detection) }}
+action.slack.param.message = {{ detection.deployment.slack.message | custom_jinja2_enrichment_filter(detection) }}
+{% endif %}
+{% if detection.deployment.phantom.phantom_server is defined %}
+action.sendtophantom = 1
+action.sendtophantom.param._cam_workers = {{ detection.deployment.phantom.cam_workers | custom_jinja2_enrichment_filter(detection) }}
+action.sendtophantom.param.label = {{ detection.deployment.phantom.label | custom_jinja2_enrichment_filter(detection) }}
+action.sendtophantom.param.phantom_server = {{ detection.deployment.phantom.phantom_server | custom_jinja2_enrichment_filter(detection) }}
+action.sendtophantom.param.sensitivity = {{ detection.deployment.phantom.sensitivity | custom_jinja2_enrichment_filter(detection) }}
+action.sendtophantom.param.severity = {{ detection.deployment.phantom.severity | custom_jinja2_enrichment_filter(detection) }}
+{% endif %}
+{% endif %}
+alert.digest_mode = 1
+{% if detection.disabled is defined %}
+disabled = false
+{% else %}
+disabled = true
+{% endif %}
+enableSched = 1
+allow_skew = 100%
+counttype = number of events
+relation = greater than
+quantity = 0
+realtime_schedule = 0
+is_visible = false
+search = {{ detection.search }}
+
+{% endif %}
+{% endfor %}
+### END ESCU DETECTIONS ###
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/templates/savedsearches_investigations.j2 b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/templates/savedsearches_investigations.j2
new file mode 100644
index 0000000000..5b674e6b79
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/templates/savedsearches_investigations.j2
@@ -0,0 +1,38 @@
+
+
+### ESCU RESPONSE TASKS ###
+
+{% for detection in objects %}
+{% if (detection.type == 'Investigation') %}
+{% if detection.search is defined %}
+[ESCU - {{ detection.name }} - Response Task]
+action.escu = 0
+action.escu.enabled = 1
+action.escu.search_type = investigative
+action.escu.full_search_name = ESCU - {{ detection.name }} - Response Task
+description = {{ detection.description }}
+action.escu.creation_date = {{ detection.date }}
+action.escu.modification_date = {{ detection.date }}
+{% if detection.tags.analytic_story is defined %}
+action.escu.analytic_story = {{ detection.tags.analytic_story | tojson }}
+{% else %}
+action.escu.analytic_story = []
+{% endif %}
+action.escu.earliest_time_offset = 3600
+action.escu.latest_time_offset = 86400
+action.escu.providing_technologies = []
+action.escu.data_models = {{ detection.datamodel | tojson }}
+action.escu.eli5 = {{ detection.description }}
+action.escu.how_to_implement = none
+action.escu.known_false_positives = None at this time
+disabled = true
+schedule_window = auto
+is_visible = false
+search = {{ detection.search }}
+
+{% endif %}
+{% endif %}
+{% endfor %}
+
+
+### END ESCU RESPONSE TASKS ###
\ No newline at end of file
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/templates/transforms.j2 b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/templates/transforms.j2
new file mode 100644
index 0000000000..576fa8d198
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/templates/transforms.j2
@@ -0,0 +1,40 @@
+
+{% for lookup in objects %}
+[{{ lookup.name }}]
+{% if lookup.filename is defined %}
+filename = {{ lookup.filename }}
+{% else %}
+collection = {{ lookup.collection }}
+external_type = kvstore
+{% endif %}
+{% if lookup.default_match is defined %}
+default_match = {{ lookup.default_match }}
+{% endif %}
+{% if lookup.case_sensitive_match is defined %}
+case_sensitive_match = {{ lookup.case_sensitive_match }}
+{% endif %}
+{% if lookup.description is defined %}
+# description = {{ lookup.description }}
+{% endif %}
+{% if lookup.match_type is defined %}
+match_type = {{ lookup.match_type }}
+{% endif %}
+{% if lookup.max_matches is defined %}
+max_matches = {{ lookup.max_matches }}
+{% endif %}
+{% if lookup.min_matches is defined %}
+min_matches = {{ lookup.min_matches }}
+{% endif %}
+{% if lookup.fields_list is defined %}
+fields_list = {{ lookup.fields_list }}
+{% endif %}
+{% if lookup.filter is defined %}
+filter = {{ lookup.filter }}
+{% endif %}
+
+{% endfor %}
+
+### Default transforms definitions for the lookup files we ship ###
+[mitre_enrichment]
+filename = mitre_enrichment.csv
+# description = A lookup file that is created by generate.py
\ No newline at end of file
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/templates/workflow_actions.j2 b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/templates/workflow_actions.j2
new file mode 100644
index 0000000000..b3b0378219
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/adapter/templates/workflow_actions.j2
@@ -0,0 +1,18 @@
+
+{% for response_task in objects %}
+{% if response_task.inputs|length == 1 %}
+[workbench_panel_{{ response_task.lowercase_name }}___response_task]
+label = Workbench - {{ response_task.name }}
+type = link
+fields = {{ response_task.inputs[0] }}
+display_location = field_menu
+{% if response_task.inputs[0] == "user" %}
+link.uri = /app/$@namespace$/ess_workbench_panel?type_identity=$@field_value$&panel=workbench_panel_{{ response_task.lowercase_name }}___response_task&drilldown_field=$@field_name$&use_drilldown_time=true
+{% else %}
+link.uri = /app/$@namespace$/ess_workbench_panel?type_asset=$@field_value$&panel=workbench_panel_{{ response_task.lowercase_name }}___response_task&drilldown_field=$@field_name$&use_drilldown_time=true
+{% endif %}
+link.target = blank
+link.method = get
+{% endif %}
+
+{% endfor %}
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/builder/security_content_baseline_builder.py b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/builder/security_content_baseline_builder.py
new file mode 100644
index 0000000000..57aaf10e4b
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/builder/security_content_baseline_builder.py
@@ -0,0 +1,49 @@
+
+
+from contentctl.contentctl.application.builder.baseline_builder import BaselineBuilder
+from contentctl_infrastructure.contentctl_infrastructure.builder.yml_reader import YmlReader
+from contentctl.contentctl.domain.entities.baseline import Baseline
+from contentctl.contentctl.domain.entities.enums.enums import SecurityContentType
+from contentctl.contentctl.domain.entities.enums.enums import SecurityContentProduct
+
+
+class SecurityContentBaselineBuilder(BaselineBuilder):
+ baseline : Baseline
+
+ def setObject(self, path: str, type: SecurityContentType) -> None:
+ yml_dict = YmlReader.load_file(path)
+ if type == SecurityContentType.baselines:
+ yml_dict["tags"]["name"] = yml_dict["name"]
+ self.baseline = Baseline.parse_obj(yml_dict)
+
+
+ def addDeployment(self, deployments: list) -> None:
+ matched_deployments = []
+
+ for d in deployments:
+ d_tags = dict(d.tags)
+ for d_tag in d_tags.keys():
+ for attr in dir(self.baseline):
+ if not (attr.startswith('__') or attr.startswith('_')):
+ if attr == d_tag:
+ if type(self.baseline.__getattribute__(attr)) is str:
+ attr_values = [self.baseline.__getattribute__(attr)]
+ else:
+ attr_values = self.baseline.__getattribute__(attr)
+
+ for attr_value in attr_values:
+ if attr_value == d_tags[d_tag]:
+ matched_deployments.append(d)
+
+ if len(matched_deployments) == 0:
+ raise ValueError('No deployment found for baseline: ' + self.baseline.name)
+
+ self.baseline.deployment = matched_deployments[-1]
+
+
+ def reset(self) -> None:
+ self.baseline = None
+
+
+ def getObject(self) -> Baseline:
+ return self.baseline
\ No newline at end of file
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/builder/security_content_basic_builder.py b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/builder/security_content_basic_builder.py
index ce2d799c49..a8dd7b8332 100644
--- a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/builder/security_content_basic_builder.py
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/builder/security_content_basic_builder.py
@@ -7,6 +7,8 @@ from contentctl.contentctl.domain.entities.deployment import Deployment
from contentctl.contentctl.domain.entities.macro import Macro
from contentctl.contentctl.domain.entities.lookup import Lookup
from contentctl.contentctl.domain.entities.playbook import Playbook
+from contentctl.contentctl.domain.entities.baseline import Baseline
+from contentctl.contentctl.domain.entities.investigation import Investigation
class SecurityContentBasicBuilder(BasicBuilder):
@@ -16,9 +18,10 @@ class SecurityContentBasicBuilder(BasicBuilder):
def setObject(self, path: str, type: SecurityContentType) -> None:
yml_dict = YmlReader.load_file(path)
if type == SecurityContentType.deployments:
- alert_action_dict = yml_dict["alert_action"]
- for key in alert_action_dict.keys():
- yml_dict[key] = yml_dict["alert_action"][key]
+ if "alert_action" in yml_dict:
+ alert_action_dict = yml_dict["alert_action"]
+ for key in alert_action_dict.keys():
+ yml_dict[key] = yml_dict["alert_action"][key]
self.security_content_obj = Deployment.parse_obj(yml_dict)
elif type == SecurityContentType.playbooks:
self.security_content_obj = Playbook.parse_obj(yml_dict)
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/builder/security_content_detection_builder.py b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/builder/security_content_detection_builder.py
index 3519bb9d20..3893dfa418 100644
--- a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/builder/security_content_detection_builder.py
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/builder/security_content_detection_builder.py
@@ -1,7 +1,6 @@
from contentctl.contentctl.application.builder.detection_builder import DetectionBuilder
-from contentctl.contentctl.application.builder.basic_builder import BasicBuilder
from contentctl_infrastructure.contentctl_infrastructure.builder.yml_reader import YmlReader
from contentctl.contentctl.domain.entities.detection import Detection
from contentctl.contentctl.domain.entities.story import Story
@@ -9,21 +8,22 @@ from contentctl.contentctl.domain.entities.deployment import Deployment
from contentctl.contentctl.domain.entities.macro import Macro
from contentctl.contentctl.domain.entities.lookup import Lookup
from contentctl.contentctl.domain.entities.enums.enums import SecurityContentType
+from contentctl.contentctl.domain.entities.enums.enums import AnalyticsType
from contentctl.contentctl.domain.entities.enums.enums import SecurityContentProduct
from contentctl.contentctl.domain.entities.security_content_object import SecurityContentObject
-class SecurityContentDetectionBuilder(DetectionBuilder, BasicBuilder):
+class SecurityContentDetectionBuilder(DetectionBuilder):
security_content_obj : SecurityContentObject
- def setObject(self, path: str, type: SecurityContentType) -> None:
+ def setObject(self, path: str, type: AnalyticsType) -> None:
yml_dict = YmlReader.load_file(path)
if type == SecurityContentType.detections:
yml_dict["tags"]["name"] = yml_dict["name"]
self.security_content_obj = Detection.parse_obj(yml_dict)
- def addDeployment(self, deployments: list, product: SecurityContentProduct) -> None:
+ def addDeployment(self, deployments: list) -> None:
matched_deployments = []
for d in deployments:
@@ -89,6 +89,19 @@ class SecurityContentDetectionBuilder(DetectionBuilder, BasicBuilder):
self.security_content_obj.deployment.notable.nes_fields = nes_fields_matches
+ def addMappings(self) -> None:
+ keys = ['mitre_attack', 'kill_chain_phases', 'cis20', 'nist']
+ mappings = {}
+ for key in keys:
+ if key == 'mitre_attack':
+ if hasattr(self.security_content_obj.tags, 'mitre_attack_id'):
+ mappings[key] = self.security_content_obj.tags.mitre_attack_id
+ else:
+ if hasattr(self.security_content_obj.tags, key):
+ mappings[key] = self.security_content_obj.tags.__getattribute__(key)
+ self.security_content_obj.mappings = mappings
+
+
def addAnnotations(self) -> None:
annotations = {}
annotation_keys = ['mitre_attack', 'kill_chain_phases', 'cis20', 'nist',
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/builder/security_content_director.py b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/builder/security_content_director.py
new file mode 100644
index 0000000000..73e37c4f32
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/builder/security_content_director.py
@@ -0,0 +1,65 @@
+import os
+
+from contentctl.contentctl.application.builder.director import Director
+from contentctl.contentctl.application.builder.basic_builder import BasicBuilder
+from contentctl.contentctl.application.builder.detection_builder import DetectionBuilder
+from contentctl.contentctl.application.builder.story_builder import StoryBuilder
+from contentctl.contentctl.application.builder.investigation_builder import InvestigationBuilder
+from contentctl.contentctl.application.builder.baseline_builder import BaselineBuilder
+from contentctl.contentctl.domain.entities.enums.enums import SecurityContentType
+from contentctl.contentctl.domain.entities.enums.enums import SecurityContentProduct
+
+class SecurityContentDirector(Director):
+
+ def constructDetection(self, builder: DetectionBuilder, path: str, deployments: list, playbooks: list, baselines: list) -> None:
+ builder.reset()
+ builder.setObject(os.path.join(os.path.dirname(__file__), path), SecurityContentType.detections)
+ builder.addDeployment(deployments)
+ builder.addRBA()
+ builder.addNesFields()
+ builder.addAnnotations()
+ builder.addMappings()
+ builder.addBaseline(baselines)
+ builder.addPlaybook(playbooks)
+
+
+ def constructStory(self, builder: StoryBuilder, path: str, detections: list, baselines: list, investigations: list) -> None:
+ builder.reset()
+ builder.setObject(os.path.join(os.path.dirname(__file__), path), SecurityContentType.stories)
+ builder.addDetections(detections)
+ builder.addInvestigations(investigations)
+ builder.addBaselines(baselines)
+ builder.addAuthorCompanyName()
+
+
+ def constructBaseline(self, builder: BaselineBuilder, path: str, deployments: list) -> None:
+ builder.reset()
+ builder.setObject(os.path.join(os.path.dirname(__file__), path), SecurityContentType.baselines)
+ builder.addDeployment(deployments)
+
+
+ def constructDeployment(self, builder: BasicBuilder, path: str) -> None:
+ builder.reset()
+ builder.setObject(os.path.join(os.path.dirname(__file__), path), SecurityContentType.deployments)
+
+
+ def constructLookup(self, builder: BasicBuilder, path: str) -> None:
+ builder.reset()
+ builder.setObject(os.path.join(os.path.dirname(__file__), path), SecurityContentType.lookups)
+
+
+ def constructMacro(self, builder: BasicBuilder, path: str) -> None:
+ builder.reset()
+ builder.setObject(os.path.join(os.path.dirname(__file__), path), SecurityContentType.macros)
+
+
+ def constructPlaybook(self, builder: BasicBuilder, path: str) -> None:
+ builder.reset()
+ builder.setObject(os.path.join(os.path.dirname(__file__), path), SecurityContentType.playbooks)
+
+
+ def constructInvestigation(self, builder: InvestigationBuilder, path: str) -> None:
+ builder.reset()
+ builder.setObject(os.path.join(os.path.dirname(__file__), path), SecurityContentType.investigations)
+ builder.addInputs()
+ builder.addLowercaseName()
\ No newline at end of file
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/builder/security_content_investigation_builder.py b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/builder/security_content_investigation_builder.py
new file mode 100644
index 0000000000..b7011c931a
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/builder/security_content_investigation_builder.py
@@ -0,0 +1,37 @@
+import re
+
+from contentctl.contentctl.application.builder.investigation_builder import InvestigationBuilder
+from contentctl.contentctl.domain.entities.investigation import Investigation
+from contentctl_infrastructure.contentctl_infrastructure.builder.yml_reader import YmlReader
+from contentctl.contentctl.domain.entities.enums.enums import SecurityContentType
+
+
+class SecurityContentInvestigationBuilder(InvestigationBuilder):
+ investigation: Investigation
+
+
+ def setObject(self, path: str, type: SecurityContentType) -> None:
+ yml_dict = YmlReader.load_file(path)
+ self.investigation = Investigation.parse_obj(yml_dict)
+
+
+ def reset(self) -> None:
+ self.investigation = None
+
+
+ def getObject(self) -> Investigation:
+ return self.investigation
+
+
+ def addInputs(self) -> None:
+ pattern = r"\$([^\s.]*)\$"
+ inputs = []
+
+ for input in re.findall(pattern, self.investigation.search):
+ inputs.append(input)
+
+ self.investigation.inputs = inputs
+
+
+ def addLowercaseName(self) -> None:
+ self.investigation.lowercase_name = self.investigation.name.replace(' ', '_').replace('-','_').replace('.','_').replace('/','_').lower().replace(' ', '_').replace('-','_').replace('.','_').replace('/','_').lower()
\ No newline at end of file
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/builder/security_content_story_builder.py b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/builder/security_content_story_builder.py
new file mode 100644
index 0000000000..32bf75ba92
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/builder/security_content_story_builder.py
@@ -0,0 +1,61 @@
+import re
+
+from contentctl.contentctl.application.builder.story_builder import StoryBuilder
+from contentctl.contentctl.domain.entities.story import Story
+from contentctl.contentctl.domain.entities.enums.enums import SecurityContentType
+from contentctl_infrastructure.contentctl_infrastructure.builder.yml_reader import YmlReader
+
+
+class SecurityContentStoryBuilder(StoryBuilder):
+ story: Story
+
+ def setObject(self, path: str, type: SecurityContentType) -> None:
+ yml_dict = YmlReader.load_file(path)
+ if type == SecurityContentType.stories:
+ self.story = Story.parse_obj(yml_dict)
+
+ def reset(self) -> None:
+ self.story = None
+
+ def getObject(self) -> Story:
+ return self.story
+
+ def addDetections(self, detections: list) -> None:
+ matched_detection_names = []
+ for detection in detections:
+ for detection_analytic_story in detection.tags.analytic_story:
+ if detection_analytic_story == self.story.name:
+ matched_detection_names.append(str('ESCU - ' + detection.name + ' - Rule'))
+
+ self.story.detection_names = matched_detection_names
+
+ def addBaselines(self, baselines: list) -> None:
+ matched_baseline_names = []
+ for baseline in baselines:
+ for baseline_analytic_story in baseline.tags.analytic_story:
+ if baseline_analytic_story == self.story.name:
+ matched_baseline_names.append(str('ESCU - ' + baseline.name))
+
+ self.story.baseline_names = matched_baseline_names
+
+ def addInvestigations(self, investigations: list) -> None:
+ matched_investigation_names = []
+ for investigation in investigations:
+ for investigation_analytic_story in investigation.tags.analytic_story:
+ if investigation_analytic_story == self.story.name:
+ matched_investigation_names.append(str('ESCU - ' + investigation.name + ' - Response Task'))
+
+ self.story.investigation_names = matched_investigation_names
+
+ def addAuthorCompanyName(self) -> None:
+ match_author = re.search(r'^([^,]+)', self.story.author)
+ if match_author is None:
+ self.story.author_name = 'no'
+ else:
+ self.story.author_name = match_author.group(1)
+
+ match_company = re.search(r',\s?(.*)$', self.story.author)
+ if match_company is None:
+ self.story.author_company = 'no'
+ else:
+ self.story.author_company = match_company.group(1)
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/builder/yml_reader.py b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/builder/yml_reader.py
index c67b2dd209..5bca676049 100644
--- a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/builder/yml_reader.py
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/builder/yml_reader.py
@@ -20,4 +20,9 @@ class YmlReader():
print(exc)
sys.exit(1)
+ if 'deprecated' in file_path:
+ yml_obj['deprecated'] = True
+ else:
+ yml_obj['deprecated'] = False
+
return yml_obj
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/conf/savedsearches.conf b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/conf/savedsearches.conf
new file mode 100644
index 0000000000..a8937133f2
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/conf/savedsearches.conf
@@ -0,0 +1,54 @@
+#############
+# Automatically generated by generator.py in splunk/security_content
+# On Date: 2020-12-25T17:05:55 UTC
+# Author: Splunk Security Research
+# Contact: research@splunk.com
+#############
+### ESCU DETECTIONS ###
+
+[ESCU - Attempted Credential Dump From Registry via Reg exe - Rule]
+action.escu = 0
+action.escu.enabled = 1
+description = Monitor for execution of reg.exe with parameters specifying an export of keys that contain hashed credentials that attackers may try to crack offline.
+action.escu.mappings = {"cis20": ["CIS 3", "CIS 5", "CIS 16"], "kill_chain_phases": ["Actions on Objectives"], "mitre_attack": ["T1003.002", "T1003"], "nist": ["DE.CM"]}
+action.escu.data_models = ["Endpoint"]
+action.escu.eli5 = Monitor for execution of reg.exe with parameters specifying an export of keys that contain hashed credentials that attackers may try to crack offline.
+action.escu.how_to_implement = To successfully implement this search you need to be ingesting information on process that include the name of the process responsible for the changes from your endpoints into the `Endpoint` datamodel in the `Processes` node. In addition, confirm the latest CIM App 4.20 or higher is installed and the latest TA for the endpoint product.
+action.escu.known_false_positives = None identified.
+action.escu.creation_date = 2021-09-16
+action.escu.modification_date = 2021-09-16
+action.escu.confidence = high
+action.escu.full_search_name = ESCU - Attempted Credential Dump From Registry via Reg exe - Rule
+action.escu.search_type = detection
+action.escu.product = ["Splunk Enterprise", "Splunk Enterprise Security", "Splunk Cloud"]
+action.escu.providing_technologies = []
+action.escu.analytic_story = ["Credential Dumping", "DarkSide Ransomware"]
+action.risk = 1
+action.risk.param._risk_message = An instance of $parent_process_name$ spawning $process_name$ was identified on endpoint $dest$ by user $user$ attempting to export the registry keys.
+action.risk.param._risk = [{"risk_object_field": "user", "risk_object_type": "user", "risk_score": 90}, {"risk_object_field": "dest", "risk_object_type": "system", "risk_score": 90}, {"threat_object_field": "parent_process_name", "threat_object_type": "process"}, {"threat_object_field": "process_name", "threat_object_type": "process"}]
+action.risk.param.verbose = 0
+cron_schedule = 0 * * * *
+dispatch.earliest_time = -70m@m
+dispatch.latest_time = -10m@m
+action.correlationsearch.enabled = 1
+action.correlationsearch.label = ESCU - Attempted Credential Dump From Registry via Reg exe - Rule
+action.correlationsearch.annotations = {"analytic_story": ["Credential Dumping", "DarkSide Ransomware"], "cis20": ["CIS 3", "CIS 5", "CIS 16"], "confidence": 100, "context": ["Source:Endpoint", "Stage:Credential Access"], "impact": 90, "kill_chain_phases": ["Actions on Objectives"], "mitre_attack": ["T1003.002", "T1003"], "nist": ["DE.CM"], "observable": [{"name": "user", "role": ["Victim"], "type": "User"}, {"name": "dest", "role": ["Victim"], "type": "Hostname"}, {"name": "parent_process_name", "role": ["Parent Process"], "type": "Process"}, {"name": "process_name", "role": ["Child Process"], "type": "Process"}]}
+schedule_window = auto
+action.notable = 1
+action.notable.param.nes_fields = ['user', 'dest']
+action.notable.param.rule_description = Monitor for execution of reg.exe with parameters specifying an export of keys that contain hashed credentials that attackers may try to crack offline.
+action.notable.param.rule_title = Attempted Credential Dump From Registry via Reg exe
+action.notable.param.security_domain = endpoint
+action.notable.param.severity = high
+alert.digest_mode = 1
+disabled = true
+enableSched = 1
+allow_skew = 100%
+counttype = number of events
+relation = greater than
+quantity = 0
+realtime_schedule = 0
+is_visible = false
+search = | tstats `security_content_summariesonly` count min(_time) as firstTime max(_time) as lastTime from datamodel=Endpoint.Processes where `process_reg` OR `process_cmd` Processes.process=*save* (Processes.process=*HKEY_LOCAL_MACHINE\\Security* OR Processes.process=*HKEY_LOCAL_MACHINE\\SAM* OR Processes.process=*HKEY_LOCAL_MACHINE\\System* OR Processes.process=*HKLM\\Security* OR Processes.process=*HKLM\\System* OR Processes.process=*HKLM\\SAM*) by Processes.dest Processes.user Processes.parent_process Processes.process_name Processes.original_file_name Processes.process Processes.process_id Processes.parent_process_id | `drop_dm_object_name(Processes)` | `security_content_ctime(firstTime)`| `security_content_ctime(lastTime)` | `attempted_credential_dump_from_registry_via_reg_exe_filter`
+
+### END ESCU DETECTIONS ###
\ No newline at end of file
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default/analyticstories.conf b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default/analyticstories.conf
new file mode 100644
index 0000000000..d771ede17b
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default/analyticstories.conf
@@ -0,0 +1,45 @@
+#############
+# Automatically generated by generator.py in splunk/security_content
+# On Date: 2020-12-25T17:05:55 UTC
+# Author: Splunk Security Research
+# Contact: research@splunk.com
+#############
+
+### DETECTIONS ###
+
+[savedsearch://ESCU - Attempted Credential Dump From Registry via Reg exe - Rule]
+type = detection
+asset_type = Endpoint
+confidence = medium
+explanation = Monitor for execution of reg.exe with parameters specifying an export of keys that contain hashed credentials that attackers may try to crack offline.
+how_to_implement = To successfully implement this search you need to be ingesting information on process that include the name of the process responsible for the changes from your endpoints into the `Endpoint` datamodel in the `Processes` node. In addition, confirm the latest CIM App 4.20 or higher is installed and the latest TA for the endpoint product.
+annotations = {"cis20": ["CIS 3", "CIS 5", "CIS 16"], "kill_chain_phases": ["Actions on Objectives"], "mitre_attack": ["T1003.002", "T1003"], "nist": ["DE.CM"]}
+known_false_positives = None identified.
+providing_technologies = []
+
+[savedsearch://ESCU - Detect new user AWS Console Login - Rule]
+type = detection
+asset_type = AWS Instance
+confidence = medium
+explanation = This search looks for AWS CloudTrail events wherein a console login event by a user was recorded within the last hour, then compares the event to a lookup file of previously seen users (by ARN values) who have logged into the console. The alert is fired if the user has logged into the console for the first time within the last hour. Deprecated now this search is updated to use the Authentication datamodel.
+how_to_implement = You must install the AWS App for Splunk (version 5.1.0 or later) and Splunk Add-on for AWS (version 4.4.0 or later), then configure your AWS CloudTrail inputs. Run the "Previously seen users in AWS CloudTrail" support search only once to create a baseline of previously seen IAM users within the last 30 days. Run "Update previously seen users in AWS CloudTrail" hourly (or more frequently depending on how often you run the detection searches) to refresh the baselines.
+annotations = {"cis20": ["CIS 16"], "kill_chain_phases": ["Actions on Objectives"], "mitre_attack": ["T1078.004"], "nist": ["DE.DP", "DE.AE"]}
+known_false_positives = When a legitimate new user logins for the first time, this activity will be detected. Check how old the account is and verify that the user activity is legitimate.
+providing_technologies = []
+
+### END DETECTIONS ###
+
+### STORIES ###
+
+[analytic_story://DarkSide Ransomware]
+category = Malware
+last_updated = 2021-05-12
+version = 1
+references = ["https://www.splunk.com/en_us/blog/security/the-darkside-of-the-ransomware-pipeline.htmlbig-game-hunting-with-ryuk-another-lucrative-targeted-ransomware/", "https://www.fireeye.com/blog/threat-research/2021/05/shining-a-light-on-darkside-ransomware-operations.html"]
+maintainers = [{"company": "Splunk", "email": "-", "name": "Bhavin Patel"}]
+spec_version = 3
+searches = ["ESCU - Attempted Credential Dump From Registry via Reg exe - Rule", "ESCU - Get Parent Process Info - Response Task"]
+description = Leverage searches that allow you to detect and investigate unusual activities that might relate to the DarkSide Ransomware
+narrative = This story addresses Darkside ransomware. This ransomware payload has many similarities to common ransomware however there are certain items particular to it. The creation of a .TXT log that shows every item being encrypted as well as the creation of ransomware notes and files adding a machine ID created based on CRC32 checksum algorithm. This ransomware payload leaves machines in minimal operation level,enough to browse the attackers websites. A customized URI with leaked information is presented to each victim.This is the ransomware payload that shut down the Colonial pipeline. The story is composed of several detection searches covering similar items to other ransomware payloads and those particular to Darkside payload.
+
+### END STORIES ###
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default/collections.conf b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default/collections.conf
new file mode 100644
index 0000000000..f2a4d0813b
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default/collections.conf
@@ -0,0 +1,11 @@
+#############
+# Automatically generated by generator.py in splunk/security_content
+# On Date: 2020-12-25T17:05:55 UTC
+# Author: Splunk Security Research
+# Contact: research@splunk.com
+#############
+
+[previously_seen_aws_regions]
+enforceTypes = false
+replicate = false
+
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default/data/ui/panels/workbench_panel_get_parent_process_info___response_task.xml b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default/data/ui/panels/workbench_panel_get_parent_process_info___response_task.xml
new file mode 100644
index 0000000000..113cb41bc5
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default/data/ui/panels/workbench_panel_get_parent_process_info___response_task.xml
@@ -0,0 +1,15 @@
+#############
+# Automatically generated by generator.py in splunk/security_content
+# On Date: 2020-12-25T17:05:55 UTC
+# Author: Splunk Security Research
+# Contact: research@splunk.com
+#############
+
+
+
+ | tstats `security_content_summariesonly` count values(Processes.process) as process min(_time) as firstTime max(_time) as lastTime FROM datamodel=Endpoint.Processes by Processes.user Processes.parent_process_name Processes.process_name Processes.dest | `drop_dm_object_name("Processes")` | search parent_process_name= $parent_process_name$ |search dest = $dest$ | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`
+
+
+
+
+
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default/es_investigations.conf b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default/es_investigations.conf
new file mode 100644
index 0000000000..f9cc970895
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default/es_investigations.conf
@@ -0,0 +1,31 @@
+#############
+# Automatically generated by generator.py in splunk/security_content
+# On Date: 2020-12-25T17:05:55 UTC
+# Author: Splunk Security Research
+# Contact: research@splunk.com
+#############
+
+[panel://workbench_panel_get_parent_process_info___response_task]
+label = Get Parent Process Info
+description = This search queries the Endpoint data model to give you details about the parent process of a process running on a host which is under investigation. Enter the values of the process name in question and the dest
+disabled = 0
+tokens = {\
+ "parent_process_name": {\
+ "valuePrefix": "\"",\
+ "valueSuffix": "\"",\
+ "delimiter": " OR parent_process_name=",\
+ "valueType": "primitive",\
+ "value": "file",\
+ "default": "null"\
+ },\
+ "dest": {\
+ "valuePrefix": "\"",\
+ "valueSuffix": "\"",\
+ "delimiter": " OR dest=",\
+ "valueType": "primitive",\
+ "value": "asset",\
+ "default": "null"\
+ }\
+}\
+
+
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default/macros.conf b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default/macros.conf
new file mode 100644
index 0000000000..adb2275bf2
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default/macros.conf
@@ -0,0 +1,21 @@
+#############
+# Automatically generated by generator.py in splunk/security_content
+# On Date: 2020-12-25T17:05:55 UTC
+# Author: Splunk Security Research
+# Contact: research@splunk.com
+#############
+
+[attempted_credential_dump_from_registry_via_reg_exe_filter]
+definition = search *
+description = Update this macro to limit the output results to filter out false positives.
+
+[detect_new_user_aws_console_login_filter]
+definition = search *
+description = Update this macro to limit the output results to filter out false positives.
+
+
+[security_content_ctime(1)]
+args = field
+definition = convert timeformat="%Y-%m-%dT%H:%M:%S" ctime($field$)
+description = convert epoch time to string
+
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default/savedsearches.conf b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default/savedsearches.conf
new file mode 100644
index 0000000000..f6a3eadc10
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default/savedsearches.conf
@@ -0,0 +1,152 @@
+#############
+# Automatically generated by generator.py in splunk/security_content
+# On Date: 2020-12-25T17:05:55 UTC
+# Author: Splunk Security Research
+# Contact: research@splunk.com
+#############
+### ESCU DETECTIONS ###
+
+[ESCU - Attempted Credential Dump From Registry via Reg exe - Rule]
+action.escu = 0
+action.escu.enabled = 1
+description = Monitor for execution of reg.exe with parameters specifying an export of keys that contain hashed credentials that attackers may try to crack offline.
+action.escu.mappings = {"cis20": ["CIS 3", "CIS 5", "CIS 16"], "kill_chain_phases": ["Actions on Objectives"], "mitre_attack": ["T1003.002", "T1003"], "nist": ["DE.CM"]}
+action.escu.data_models = ["Endpoint"]
+action.escu.eli5 = Monitor for execution of reg.exe with parameters specifying an export of keys that contain hashed credentials that attackers may try to crack offline.
+action.escu.how_to_implement = To successfully implement this search you need to be ingesting information on process that include the name of the process responsible for the changes from your endpoints into the `Endpoint` datamodel in the `Processes` node. In addition, confirm the latest CIM App 4.20 or higher is installed and the latest TA for the endpoint product.
+action.escu.known_false_positives = None identified.
+action.escu.creation_date = 2021-09-16
+action.escu.modification_date = 2021-09-16
+action.escu.confidence = high
+action.escu.full_search_name = ESCU - Attempted Credential Dump From Registry via Reg exe - Rule
+action.escu.search_type = detection
+action.escu.product = ["Splunk Enterprise", "Splunk Enterprise Security", "Splunk Cloud"]
+action.escu.providing_technologies = []
+action.escu.analytic_story = ["Credential Dumping", "DarkSide Ransomware"]
+action.risk = 1
+action.risk.param._risk_message = An instance of $parent_process_name$ spawning $process_name$ was identified on endpoint $dest$ by user $user$ attempting to export the registry keys.
+action.risk.param._risk = [{"risk_object_field": "user", "risk_object_type": "user", "risk_score": 90}, {"risk_object_field": "dest", "risk_object_type": "system", "risk_score": 90}, {"threat_object_field": "parent_process_name", "threat_object_type": "process"}, {"threat_object_field": "process_name", "threat_object_type": "process"}]
+action.risk.param.verbose = 0
+cron_schedule = 0 * * * *
+dispatch.earliest_time = -70m@m
+dispatch.latest_time = -10m@m
+action.correlationsearch.enabled = 1
+action.correlationsearch.label = ESCU - Attempted Credential Dump From Registry via Reg exe - Rule
+action.correlationsearch.annotations = {"analytic_story": ["Credential Dumping", "DarkSide Ransomware"], "cis20": ["CIS 3", "CIS 5", "CIS 16"], "confidence": 100, "context": ["Source:Endpoint", "Stage:Credential Access"], "impact": 90, "kill_chain_phases": ["Actions on Objectives"], "mitre_attack": ["T1003.002", "T1003"], "nist": ["DE.CM"], "observable": [{"name": "user", "role": ["Victim"], "type": "User"}, {"name": "dest", "role": ["Victim"], "type": "Hostname"}, {"name": "parent_process_name", "role": ["Parent Process"], "type": "Process"}, {"name": "process_name", "role": ["Child Process"], "type": "Process"}]}
+schedule_window = auto
+action.notable = 1
+action.notable.param.nes_fields = ['user']
+action.notable.param.rule_description = Monitor for execution of reg.exe with parameters specifying an export of keys that contain hashed credentials that attackers may try to crack offline.
+action.notable.param.rule_title = Attempted Credential Dump From Registry via Reg exe
+action.notable.param.security_domain = endpoint
+action.notable.param.severity = high
+alert.digest_mode = 1
+disabled = true
+enableSched = 1
+allow_skew = 100%
+counttype = number of events
+relation = greater than
+quantity = 0
+realtime_schedule = 0
+is_visible = false
+search = | tstats `security_content_summariesonly` count min(_time) as firstTime max(_time) as lastTime from datamodel=Endpoint.Processes where `process_reg` OR `process_cmd` Processes.process=*save* (Processes.process=*HKEY_LOCAL_MACHINE\\Security* OR Processes.process=*HKEY_LOCAL_MACHINE\\SAM* OR Processes.process=*HKEY_LOCAL_MACHINE\\System* OR Processes.process=*HKLM\\Security* OR Processes.process=*HKLM\\System* OR Processes.process=*HKLM\\SAM*) by Processes.dest Processes.user Processes.parent_process Processes.process_name Processes.original_file_name Processes.process Processes.process_id Processes.parent_process_id | `drop_dm_object_name(Processes)` | `security_content_ctime(firstTime)`| `security_content_ctime(lastTime)` | `attempted_credential_dump_from_registry_via_reg_exe_filter`
+
+[ESCU - Detect new user AWS Console Login - Rule]
+action.escu = 0
+action.escu.enabled = 1
+description = WARNING, this detection 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. This search looks for AWS CloudTrail events wherein a console login event by a user was recorded within the last hour, then compares the event to a lookup file of previously seen users (by ARN values) who have logged into the console. The alert is fired if the user has logged into the console for the first time within the last hour. Deprecated now this search is updated to use the Authentication datamodel.
+action.escu.mappings = {"cis20": ["CIS 16"], "kill_chain_phases": ["Actions on Objectives"], "mitre_attack": ["T1078.004"], "nist": ["DE.DP", "DE.AE"]}
+action.escu.data_models = []
+action.escu.eli5 = This search looks for AWS CloudTrail events wherein a console login event by a user was recorded within the last hour, then compares the event to a lookup file of previously seen users (by ARN values) who have logged into the console. The alert is fired if the user has logged into the console for the first time within the last hour. Deprecated now this search is updated to use the Authentication datamodel.
+action.escu.how_to_implement = You must install the AWS App for Splunk (version 5.1.0 or later) and Splunk Add-on for AWS (version 4.4.0 or later), then configure your AWS CloudTrail inputs. Run the "Previously seen users in AWS CloudTrail" support search only once to create a baseline of previously seen IAM users within the last 30 days. Run "Update previously seen users in AWS CloudTrail" hourly (or more frequently depending on how often you run the detection searches) to refresh the baselines.
+action.escu.known_false_positives = When a legitimate new user logins for the first time, this activity will be detected. Check how old the account is and verify that the user activity is legitimate.
+action.escu.creation_date = 2020-07-21
+action.escu.modification_date = 2020-07-21
+action.escu.confidence = high
+action.escu.full_search_name = ESCU - Detect new user AWS Console Login - Rule
+action.escu.search_type = detection
+action.escu.product = ["Splunk Enterprise", "Splunk Enterprise Security", "Splunk Cloud"]
+action.escu.providing_technologies = []
+action.escu.analytic_story = ["Suspicious AWS Login Activities"]
+action.risk = 1
+action.risk.param._risk_message = tbd
+action.risk.param._risk = [{"risk_object_field": "user", "risk_object_type": "user", "risk_score": 90}]
+action.risk.param.verbose = 0
+cron_schedule = 0 * * * *
+dispatch.earliest_time = -70m@m
+dispatch.latest_time = -10m@m
+action.correlationsearch.enabled = 1
+action.correlationsearch.label = ESCU - Deprecated - Detect new user AWS Console Login - Rule
+action.correlationsearch.annotations = {"analytic_story": ["Suspicious AWS Login Activities"], "cis20": ["CIS 16"], "confidence": 100, "context": ["Source:Endpoint", "Stage:Credential Access"], "impact": 90, "kill_chain_phases": ["Actions on Objectives"], "mitre_attack": ["T1078.004"], "nist": ["DE.DP", "DE.AE"], "observable": [{"name": "user", "role": ["Victim"], "type": "User"}]}
+schedule_window = auto
+action.notable = 1
+action.notable.param.nes_fields = ['user']
+action.notable.param.rule_description = This search looks for AWS CloudTrail events wherein a console login event by a user was recorded within the last hour, then compares the event to a lookup file of previously seen users (by ARN values) who have logged into the console. The alert is fired if the user has logged into the console for the first time within the last hour. Deprecated now this search is updated to use the Authentication datamodel.
+action.notable.param.rule_title = Detect new user AWS Console Login
+action.notable.param.security_domain = network
+action.notable.param.severity = high
+alert.digest_mode = 1
+disabled = true
+enableSched = 1
+allow_skew = 100%
+counttype = number of events
+relation = greater than
+quantity = 0
+realtime_schedule = 0
+is_visible = false
+search = `cloudtrail` eventName=ConsoleLogin | rename userIdentity.arn as user | stats earliest(_time) as firstTime latest(_time) as lastTime by user | inputlookup append=t previously_seen_users_console_logins_cloudtrail | stats min(firstTime) as firstTime max(lastTime) as lastTime by user | eval userStatus=if(firstTime >= relative_time(now(), "-70m@m"), "First Time Logging into AWS Console","Previously Seen User") | `security_content_ctime(firstTime)`|`security_content_ctime(lastTime)`| where userStatus ="First Time Logging into AWS Console" | `detect_new_user_aws_console_login_filter`
+
+### END ESCU DETECTIONS ###
+
+### ESCU BASELINES ###
+
+[ESCU - Previously Seen Users In CloudTrail - Update]
+action.escu = 0
+action.escu.enabled = 1
+action.escu.search_type = support
+action.escu.full_search_name = ESCU - Previously Seen Users In CloudTrail - Update
+description = This search looks for CloudTrail events where a user logs into the console, then updates the baseline of the latest and earliest times, City, Region, and Country we have encountered this user in our dataset, grouped by user, within the last hour.
+action.escu.creation_date = 2020-05-28
+action.escu.modification_date = 2020-05-28
+action.escu.analytic_story = ["Suspicious Cloud Authentication Activities"]
+action.escu.data_models = ["Authentication"]
+cron_schedule = 0 * * * *
+enableSched = 1
+dispatch.earliest_time = -70m@m
+dispatch.latest_time = -10m@m
+schedule_window = auto
+action.escu.providing_technologies = []
+action.escu.eli5 = This search looks for CloudTrail events where a user logs into the console, then updates the baseline of the latest and earliest times, City, Region, and Country we have encountered this user in our dataset, grouped by user, within the last hour.
+action.escu.how_to_implement = You must install and configure the Splunk Add-on for AWS (version 5.1.0 or later) and Enterprise Security 6.2, which contains the required updates to the Authentication data model for cloud use cases. Validate the user name entries in `previously_seen_users_console_logins`, which is a lookup file created by this support search.
+disabled = true
+is_visible = false
+search = | tstats earliest(_time) as firstTime latest(_time) as lastTime from datamodel=Authentication where Authentication.signature=ConsoleLogin by Authentication.user Authentication.src | iplocation Authentication.src | rename Authentication.user as user Authentication.src as src | table user src City Region Country firstTime lastTime | inputlookup append=t previously_seen_users_console_logins | stats min(firstTime) as firstTime max(lastTime) as lastTime by user src City Region Country | outputlookup previously_seen_users_console_logins
+
+
+
+### ESCU RESPONSE TASKS ###
+
+[ESCU - Get Parent Process Info - Response Task]
+action.escu = 0
+action.escu.enabled = 1
+action.escu.search_type = investigative
+action.escu.full_search_name = ESCU - Get Parent Process Info - Response Task
+description = This search queries the Endpoint data model to give you details about the parent process of a process running on a host which is under investigation. Enter the values of the process name in question and the dest
+action.escu.creation_date = 2019-02-28
+action.escu.modification_date = 2019-02-28
+action.escu.analytic_story = ["Collection and Staging", "Command and Control", "DHS Report TA18-074A", "Disabling Security Tools", "Emotet Malware DHS Report TA18-201A ", "Hidden Cobra Malware", "Lateral Movement", "Malicious PowerShell", "Monitor for Unauthorized Software", "Netsh Abuse", "Orangeworm Attack Group", "Phishing Payloads", "Possible Backdoor Activity Associated With MUDCARP Espionage Campaigns", "Prohibited Traffic Allowed or Protocol Mismatch", "Ransomware", "SamSam Ransomware", "Suspicious Command-Line Executions", "Suspicious DNS Traffic", "Suspicious MSHTA Activity", "Suspicious WMI Use", "Suspicious Windows Registry Activities", "Unusual Processes", "Windows Defense Evasion Tactics", "Windows File Extension and Association Abuse", "Windows Log Manipulation", "Windows Persistence Techniques", "Windows Privilege Escalation", "Windows Service Abuse", "DarkSide Ransomware"]
+action.escu.earliest_time_offset = 3600
+action.escu.latest_time_offset = 86400
+action.escu.providing_technologies = []
+action.escu.data_models = ["Endpoint"]
+action.escu.eli5 = This search queries the Endpoint data model to give you details about the parent process of a process running on a host which is under investigation. Enter the values of the process name in question and the dest
+action.escu.how_to_implement = none
+action.escu.known_false_positives = None at this time
+disabled = true
+schedule_window = auto
+is_visible = false
+search = | tstats `security_content_summariesonly` count values(Processes.process) as process min(_time) as firstTime max(_time) as lastTime FROM datamodel=Endpoint.Processes by Processes.user Processes.parent_process_name Processes.process_name Processes.dest | `drop_dm_object_name("Processes")` | search parent_process_name= $parent_process_name$ |search dest = $dest$ | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`
+
+
+
+### END ESCU RESPONSE TASKS ###
\ No newline at end of file
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default/transforms.conf b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default/transforms.conf
new file mode 100644
index 0000000000..c51e10f66d
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default/transforms.conf
@@ -0,0 +1,21 @@
+#############
+# Automatically generated by generator.py in splunk/security_content
+# On Date: 2020-12-25T17:05:55 UTC
+# Author: Splunk Security Research
+# Contact: research@splunk.com
+#############
+
+[previously_seen_aws_regions]
+filename = previously_seen_aws_regions.csv
+default_match = false
+case_sensitive_match = None
+# description = A place holder for a list of used AWS regions
+match_type = None
+min_matches = 1
+fields_list = None
+
+
+### Default transforms definitions for the lookup files we ship ###
+[mitre_enrichment]
+filename = mitre_enrichment.csv
+# description = A lookup file that is created by generate.py
\ No newline at end of file
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default/workflow_actions.conf b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default/workflow_actions.conf
new file mode 100644
index 0000000000..84d0e23fc4
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default/workflow_actions.conf
@@ -0,0 +1,8 @@
+#############
+# Automatically generated by generator.py in splunk/security_content
+# On Date: 2020-12-25T17:05:55 UTC
+# Author: Splunk Security Research
+# Contact: research@splunk.com
+#############
+
+
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default_reference/analyticstories.conf b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default_reference/analyticstories.conf
new file mode 100644
index 0000000000..d771ede17b
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default_reference/analyticstories.conf
@@ -0,0 +1,45 @@
+#############
+# Automatically generated by generator.py in splunk/security_content
+# On Date: 2020-12-25T17:05:55 UTC
+# Author: Splunk Security Research
+# Contact: research@splunk.com
+#############
+
+### DETECTIONS ###
+
+[savedsearch://ESCU - Attempted Credential Dump From Registry via Reg exe - Rule]
+type = detection
+asset_type = Endpoint
+confidence = medium
+explanation = Monitor for execution of reg.exe with parameters specifying an export of keys that contain hashed credentials that attackers may try to crack offline.
+how_to_implement = To successfully implement this search you need to be ingesting information on process that include the name of the process responsible for the changes from your endpoints into the `Endpoint` datamodel in the `Processes` node. In addition, confirm the latest CIM App 4.20 or higher is installed and the latest TA for the endpoint product.
+annotations = {"cis20": ["CIS 3", "CIS 5", "CIS 16"], "kill_chain_phases": ["Actions on Objectives"], "mitre_attack": ["T1003.002", "T1003"], "nist": ["DE.CM"]}
+known_false_positives = None identified.
+providing_technologies = []
+
+[savedsearch://ESCU - Detect new user AWS Console Login - Rule]
+type = detection
+asset_type = AWS Instance
+confidence = medium
+explanation = This search looks for AWS CloudTrail events wherein a console login event by a user was recorded within the last hour, then compares the event to a lookup file of previously seen users (by ARN values) who have logged into the console. The alert is fired if the user has logged into the console for the first time within the last hour. Deprecated now this search is updated to use the Authentication datamodel.
+how_to_implement = You must install the AWS App for Splunk (version 5.1.0 or later) and Splunk Add-on for AWS (version 4.4.0 or later), then configure your AWS CloudTrail inputs. Run the "Previously seen users in AWS CloudTrail" support search only once to create a baseline of previously seen IAM users within the last 30 days. Run "Update previously seen users in AWS CloudTrail" hourly (or more frequently depending on how often you run the detection searches) to refresh the baselines.
+annotations = {"cis20": ["CIS 16"], "kill_chain_phases": ["Actions on Objectives"], "mitre_attack": ["T1078.004"], "nist": ["DE.DP", "DE.AE"]}
+known_false_positives = When a legitimate new user logins for the first time, this activity will be detected. Check how old the account is and verify that the user activity is legitimate.
+providing_technologies = []
+
+### END DETECTIONS ###
+
+### STORIES ###
+
+[analytic_story://DarkSide Ransomware]
+category = Malware
+last_updated = 2021-05-12
+version = 1
+references = ["https://www.splunk.com/en_us/blog/security/the-darkside-of-the-ransomware-pipeline.htmlbig-game-hunting-with-ryuk-another-lucrative-targeted-ransomware/", "https://www.fireeye.com/blog/threat-research/2021/05/shining-a-light-on-darkside-ransomware-operations.html"]
+maintainers = [{"company": "Splunk", "email": "-", "name": "Bhavin Patel"}]
+spec_version = 3
+searches = ["ESCU - Attempted Credential Dump From Registry via Reg exe - Rule", "ESCU - Get Parent Process Info - Response Task"]
+description = Leverage searches that allow you to detect and investigate unusual activities that might relate to the DarkSide Ransomware
+narrative = This story addresses Darkside ransomware. This ransomware payload has many similarities to common ransomware however there are certain items particular to it. The creation of a .TXT log that shows every item being encrypted as well as the creation of ransomware notes and files adding a machine ID created based on CRC32 checksum algorithm. This ransomware payload leaves machines in minimal operation level,enough to browse the attackers websites. A customized URI with leaked information is presented to each victim.This is the ransomware payload that shut down the Colonial pipeline. The story is composed of several detection searches covering similar items to other ransomware payloads and those particular to Darkside payload.
+
+### END STORIES ###
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default_reference/collections.conf b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default_reference/collections.conf
new file mode 100644
index 0000000000..f2a4d0813b
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default_reference/collections.conf
@@ -0,0 +1,11 @@
+#############
+# Automatically generated by generator.py in splunk/security_content
+# On Date: 2020-12-25T17:05:55 UTC
+# Author: Splunk Security Research
+# Contact: research@splunk.com
+#############
+
+[previously_seen_aws_regions]
+enforceTypes = false
+replicate = false
+
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default_reference/data/ui/panels/workbench_panel_get_parent_process_info___response_task.xml b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default_reference/data/ui/panels/workbench_panel_get_parent_process_info___response_task.xml
new file mode 100644
index 0000000000..113cb41bc5
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default_reference/data/ui/panels/workbench_panel_get_parent_process_info___response_task.xml
@@ -0,0 +1,15 @@
+#############
+# Automatically generated by generator.py in splunk/security_content
+# On Date: 2020-12-25T17:05:55 UTC
+# Author: Splunk Security Research
+# Contact: research@splunk.com
+#############
+
+
+
+ | tstats `security_content_summariesonly` count values(Processes.process) as process min(_time) as firstTime max(_time) as lastTime FROM datamodel=Endpoint.Processes by Processes.user Processes.parent_process_name Processes.process_name Processes.dest | `drop_dm_object_name("Processes")` | search parent_process_name= $parent_process_name$ |search dest = $dest$ | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`
+
+
+
+
+
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default_reference/es_investigations.conf b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default_reference/es_investigations.conf
new file mode 100644
index 0000000000..f9cc970895
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default_reference/es_investigations.conf
@@ -0,0 +1,31 @@
+#############
+# Automatically generated by generator.py in splunk/security_content
+# On Date: 2020-12-25T17:05:55 UTC
+# Author: Splunk Security Research
+# Contact: research@splunk.com
+#############
+
+[panel://workbench_panel_get_parent_process_info___response_task]
+label = Get Parent Process Info
+description = This search queries the Endpoint data model to give you details about the parent process of a process running on a host which is under investigation. Enter the values of the process name in question and the dest
+disabled = 0
+tokens = {\
+ "parent_process_name": {\
+ "valuePrefix": "\"",\
+ "valueSuffix": "\"",\
+ "delimiter": " OR parent_process_name=",\
+ "valueType": "primitive",\
+ "value": "file",\
+ "default": "null"\
+ },\
+ "dest": {\
+ "valuePrefix": "\"",\
+ "valueSuffix": "\"",\
+ "delimiter": " OR dest=",\
+ "valueType": "primitive",\
+ "value": "asset",\
+ "default": "null"\
+ }\
+}\
+
+
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default_reference/macros.conf b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default_reference/macros.conf
new file mode 100644
index 0000000000..adb2275bf2
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default_reference/macros.conf
@@ -0,0 +1,21 @@
+#############
+# Automatically generated by generator.py in splunk/security_content
+# On Date: 2020-12-25T17:05:55 UTC
+# Author: Splunk Security Research
+# Contact: research@splunk.com
+#############
+
+[attempted_credential_dump_from_registry_via_reg_exe_filter]
+definition = search *
+description = Update this macro to limit the output results to filter out false positives.
+
+[detect_new_user_aws_console_login_filter]
+definition = search *
+description = Update this macro to limit the output results to filter out false positives.
+
+
+[security_content_ctime(1)]
+args = field
+definition = convert timeformat="%Y-%m-%dT%H:%M:%S" ctime($field$)
+description = convert epoch time to string
+
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default_reference/savedsearches.conf b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default_reference/savedsearches.conf
new file mode 100644
index 0000000000..f6a3eadc10
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default_reference/savedsearches.conf
@@ -0,0 +1,152 @@
+#############
+# Automatically generated by generator.py in splunk/security_content
+# On Date: 2020-12-25T17:05:55 UTC
+# Author: Splunk Security Research
+# Contact: research@splunk.com
+#############
+### ESCU DETECTIONS ###
+
+[ESCU - Attempted Credential Dump From Registry via Reg exe - Rule]
+action.escu = 0
+action.escu.enabled = 1
+description = Monitor for execution of reg.exe with parameters specifying an export of keys that contain hashed credentials that attackers may try to crack offline.
+action.escu.mappings = {"cis20": ["CIS 3", "CIS 5", "CIS 16"], "kill_chain_phases": ["Actions on Objectives"], "mitre_attack": ["T1003.002", "T1003"], "nist": ["DE.CM"]}
+action.escu.data_models = ["Endpoint"]
+action.escu.eli5 = Monitor for execution of reg.exe with parameters specifying an export of keys that contain hashed credentials that attackers may try to crack offline.
+action.escu.how_to_implement = To successfully implement this search you need to be ingesting information on process that include the name of the process responsible for the changes from your endpoints into the `Endpoint` datamodel in the `Processes` node. In addition, confirm the latest CIM App 4.20 or higher is installed and the latest TA for the endpoint product.
+action.escu.known_false_positives = None identified.
+action.escu.creation_date = 2021-09-16
+action.escu.modification_date = 2021-09-16
+action.escu.confidence = high
+action.escu.full_search_name = ESCU - Attempted Credential Dump From Registry via Reg exe - Rule
+action.escu.search_type = detection
+action.escu.product = ["Splunk Enterprise", "Splunk Enterprise Security", "Splunk Cloud"]
+action.escu.providing_technologies = []
+action.escu.analytic_story = ["Credential Dumping", "DarkSide Ransomware"]
+action.risk = 1
+action.risk.param._risk_message = An instance of $parent_process_name$ spawning $process_name$ was identified on endpoint $dest$ by user $user$ attempting to export the registry keys.
+action.risk.param._risk = [{"risk_object_field": "user", "risk_object_type": "user", "risk_score": 90}, {"risk_object_field": "dest", "risk_object_type": "system", "risk_score": 90}, {"threat_object_field": "parent_process_name", "threat_object_type": "process"}, {"threat_object_field": "process_name", "threat_object_type": "process"}]
+action.risk.param.verbose = 0
+cron_schedule = 0 * * * *
+dispatch.earliest_time = -70m@m
+dispatch.latest_time = -10m@m
+action.correlationsearch.enabled = 1
+action.correlationsearch.label = ESCU - Attempted Credential Dump From Registry via Reg exe - Rule
+action.correlationsearch.annotations = {"analytic_story": ["Credential Dumping", "DarkSide Ransomware"], "cis20": ["CIS 3", "CIS 5", "CIS 16"], "confidence": 100, "context": ["Source:Endpoint", "Stage:Credential Access"], "impact": 90, "kill_chain_phases": ["Actions on Objectives"], "mitre_attack": ["T1003.002", "T1003"], "nist": ["DE.CM"], "observable": [{"name": "user", "role": ["Victim"], "type": "User"}, {"name": "dest", "role": ["Victim"], "type": "Hostname"}, {"name": "parent_process_name", "role": ["Parent Process"], "type": "Process"}, {"name": "process_name", "role": ["Child Process"], "type": "Process"}]}
+schedule_window = auto
+action.notable = 1
+action.notable.param.nes_fields = ['user']
+action.notable.param.rule_description = Monitor for execution of reg.exe with parameters specifying an export of keys that contain hashed credentials that attackers may try to crack offline.
+action.notable.param.rule_title = Attempted Credential Dump From Registry via Reg exe
+action.notable.param.security_domain = endpoint
+action.notable.param.severity = high
+alert.digest_mode = 1
+disabled = true
+enableSched = 1
+allow_skew = 100%
+counttype = number of events
+relation = greater than
+quantity = 0
+realtime_schedule = 0
+is_visible = false
+search = | tstats `security_content_summariesonly` count min(_time) as firstTime max(_time) as lastTime from datamodel=Endpoint.Processes where `process_reg` OR `process_cmd` Processes.process=*save* (Processes.process=*HKEY_LOCAL_MACHINE\\Security* OR Processes.process=*HKEY_LOCAL_MACHINE\\SAM* OR Processes.process=*HKEY_LOCAL_MACHINE\\System* OR Processes.process=*HKLM\\Security* OR Processes.process=*HKLM\\System* OR Processes.process=*HKLM\\SAM*) by Processes.dest Processes.user Processes.parent_process Processes.process_name Processes.original_file_name Processes.process Processes.process_id Processes.parent_process_id | `drop_dm_object_name(Processes)` | `security_content_ctime(firstTime)`| `security_content_ctime(lastTime)` | `attempted_credential_dump_from_registry_via_reg_exe_filter`
+
+[ESCU - Detect new user AWS Console Login - Rule]
+action.escu = 0
+action.escu.enabled = 1
+description = WARNING, this detection 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. This search looks for AWS CloudTrail events wherein a console login event by a user was recorded within the last hour, then compares the event to a lookup file of previously seen users (by ARN values) who have logged into the console. The alert is fired if the user has logged into the console for the first time within the last hour. Deprecated now this search is updated to use the Authentication datamodel.
+action.escu.mappings = {"cis20": ["CIS 16"], "kill_chain_phases": ["Actions on Objectives"], "mitre_attack": ["T1078.004"], "nist": ["DE.DP", "DE.AE"]}
+action.escu.data_models = []
+action.escu.eli5 = This search looks for AWS CloudTrail events wherein a console login event by a user was recorded within the last hour, then compares the event to a lookup file of previously seen users (by ARN values) who have logged into the console. The alert is fired if the user has logged into the console for the first time within the last hour. Deprecated now this search is updated to use the Authentication datamodel.
+action.escu.how_to_implement = You must install the AWS App for Splunk (version 5.1.0 or later) and Splunk Add-on for AWS (version 4.4.0 or later), then configure your AWS CloudTrail inputs. Run the "Previously seen users in AWS CloudTrail" support search only once to create a baseline of previously seen IAM users within the last 30 days. Run "Update previously seen users in AWS CloudTrail" hourly (or more frequently depending on how often you run the detection searches) to refresh the baselines.
+action.escu.known_false_positives = When a legitimate new user logins for the first time, this activity will be detected. Check how old the account is and verify that the user activity is legitimate.
+action.escu.creation_date = 2020-07-21
+action.escu.modification_date = 2020-07-21
+action.escu.confidence = high
+action.escu.full_search_name = ESCU - Detect new user AWS Console Login - Rule
+action.escu.search_type = detection
+action.escu.product = ["Splunk Enterprise", "Splunk Enterprise Security", "Splunk Cloud"]
+action.escu.providing_technologies = []
+action.escu.analytic_story = ["Suspicious AWS Login Activities"]
+action.risk = 1
+action.risk.param._risk_message = tbd
+action.risk.param._risk = [{"risk_object_field": "user", "risk_object_type": "user", "risk_score": 90}]
+action.risk.param.verbose = 0
+cron_schedule = 0 * * * *
+dispatch.earliest_time = -70m@m
+dispatch.latest_time = -10m@m
+action.correlationsearch.enabled = 1
+action.correlationsearch.label = ESCU - Deprecated - Detect new user AWS Console Login - Rule
+action.correlationsearch.annotations = {"analytic_story": ["Suspicious AWS Login Activities"], "cis20": ["CIS 16"], "confidence": 100, "context": ["Source:Endpoint", "Stage:Credential Access"], "impact": 90, "kill_chain_phases": ["Actions on Objectives"], "mitre_attack": ["T1078.004"], "nist": ["DE.DP", "DE.AE"], "observable": [{"name": "user", "role": ["Victim"], "type": "User"}]}
+schedule_window = auto
+action.notable = 1
+action.notable.param.nes_fields = ['user']
+action.notable.param.rule_description = This search looks for AWS CloudTrail events wherein a console login event by a user was recorded within the last hour, then compares the event to a lookup file of previously seen users (by ARN values) who have logged into the console. The alert is fired if the user has logged into the console for the first time within the last hour. Deprecated now this search is updated to use the Authentication datamodel.
+action.notable.param.rule_title = Detect new user AWS Console Login
+action.notable.param.security_domain = network
+action.notable.param.severity = high
+alert.digest_mode = 1
+disabled = true
+enableSched = 1
+allow_skew = 100%
+counttype = number of events
+relation = greater than
+quantity = 0
+realtime_schedule = 0
+is_visible = false
+search = `cloudtrail` eventName=ConsoleLogin | rename userIdentity.arn as user | stats earliest(_time) as firstTime latest(_time) as lastTime by user | inputlookup append=t previously_seen_users_console_logins_cloudtrail | stats min(firstTime) as firstTime max(lastTime) as lastTime by user | eval userStatus=if(firstTime >= relative_time(now(), "-70m@m"), "First Time Logging into AWS Console","Previously Seen User") | `security_content_ctime(firstTime)`|`security_content_ctime(lastTime)`| where userStatus ="First Time Logging into AWS Console" | `detect_new_user_aws_console_login_filter`
+
+### END ESCU DETECTIONS ###
+
+### ESCU BASELINES ###
+
+[ESCU - Previously Seen Users In CloudTrail - Update]
+action.escu = 0
+action.escu.enabled = 1
+action.escu.search_type = support
+action.escu.full_search_name = ESCU - Previously Seen Users In CloudTrail - Update
+description = This search looks for CloudTrail events where a user logs into the console, then updates the baseline of the latest and earliest times, City, Region, and Country we have encountered this user in our dataset, grouped by user, within the last hour.
+action.escu.creation_date = 2020-05-28
+action.escu.modification_date = 2020-05-28
+action.escu.analytic_story = ["Suspicious Cloud Authentication Activities"]
+action.escu.data_models = ["Authentication"]
+cron_schedule = 0 * * * *
+enableSched = 1
+dispatch.earliest_time = -70m@m
+dispatch.latest_time = -10m@m
+schedule_window = auto
+action.escu.providing_technologies = []
+action.escu.eli5 = This search looks for CloudTrail events where a user logs into the console, then updates the baseline of the latest and earliest times, City, Region, and Country we have encountered this user in our dataset, grouped by user, within the last hour.
+action.escu.how_to_implement = You must install and configure the Splunk Add-on for AWS (version 5.1.0 or later) and Enterprise Security 6.2, which contains the required updates to the Authentication data model for cloud use cases. Validate the user name entries in `previously_seen_users_console_logins`, which is a lookup file created by this support search.
+disabled = true
+is_visible = false
+search = | tstats earliest(_time) as firstTime latest(_time) as lastTime from datamodel=Authentication where Authentication.signature=ConsoleLogin by Authentication.user Authentication.src | iplocation Authentication.src | rename Authentication.user as user Authentication.src as src | table user src City Region Country firstTime lastTime | inputlookup append=t previously_seen_users_console_logins | stats min(firstTime) as firstTime max(lastTime) as lastTime by user src City Region Country | outputlookup previously_seen_users_console_logins
+
+
+
+### ESCU RESPONSE TASKS ###
+
+[ESCU - Get Parent Process Info - Response Task]
+action.escu = 0
+action.escu.enabled = 1
+action.escu.search_type = investigative
+action.escu.full_search_name = ESCU - Get Parent Process Info - Response Task
+description = This search queries the Endpoint data model to give you details about the parent process of a process running on a host which is under investigation. Enter the values of the process name in question and the dest
+action.escu.creation_date = 2019-02-28
+action.escu.modification_date = 2019-02-28
+action.escu.analytic_story = ["Collection and Staging", "Command and Control", "DHS Report TA18-074A", "Disabling Security Tools", "Emotet Malware DHS Report TA18-201A ", "Hidden Cobra Malware", "Lateral Movement", "Malicious PowerShell", "Monitor for Unauthorized Software", "Netsh Abuse", "Orangeworm Attack Group", "Phishing Payloads", "Possible Backdoor Activity Associated With MUDCARP Espionage Campaigns", "Prohibited Traffic Allowed or Protocol Mismatch", "Ransomware", "SamSam Ransomware", "Suspicious Command-Line Executions", "Suspicious DNS Traffic", "Suspicious MSHTA Activity", "Suspicious WMI Use", "Suspicious Windows Registry Activities", "Unusual Processes", "Windows Defense Evasion Tactics", "Windows File Extension and Association Abuse", "Windows Log Manipulation", "Windows Persistence Techniques", "Windows Privilege Escalation", "Windows Service Abuse", "DarkSide Ransomware"]
+action.escu.earliest_time_offset = 3600
+action.escu.latest_time_offset = 86400
+action.escu.providing_technologies = []
+action.escu.data_models = ["Endpoint"]
+action.escu.eli5 = This search queries the Endpoint data model to give you details about the parent process of a process running on a host which is under investigation. Enter the values of the process name in question and the dest
+action.escu.how_to_implement = none
+action.escu.known_false_positives = None at this time
+disabled = true
+schedule_window = auto
+is_visible = false
+search = | tstats `security_content_summariesonly` count values(Processes.process) as process min(_time) as firstTime max(_time) as lastTime FROM datamodel=Endpoint.Processes by Processes.user Processes.parent_process_name Processes.process_name Processes.dest | `drop_dm_object_name("Processes")` | search parent_process_name= $parent_process_name$ |search dest = $dest$ | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`
+
+
+
+### END ESCU RESPONSE TASKS ###
\ No newline at end of file
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default_reference/transforms.conf b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default_reference/transforms.conf
new file mode 100644
index 0000000000..c51e10f66d
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default_reference/transforms.conf
@@ -0,0 +1,21 @@
+#############
+# Automatically generated by generator.py in splunk/security_content
+# On Date: 2020-12-25T17:05:55 UTC
+# Author: Splunk Security Research
+# Contact: research@splunk.com
+#############
+
+[previously_seen_aws_regions]
+filename = previously_seen_aws_regions.csv
+default_match = false
+case_sensitive_match = None
+# description = A place holder for a list of used AWS regions
+match_type = None
+min_matches = 1
+fields_list = None
+
+
+### Default transforms definitions for the lookup files we ship ###
+[mitre_enrichment]
+filename = mitre_enrichment.csv
+# description = A lookup file that is created by generate.py
\ No newline at end of file
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default_reference/workflow_actions.conf b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default_reference/workflow_actions.conf
new file mode 100644
index 0000000000..84d0e23fc4
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/default_reference/workflow_actions.conf
@@ -0,0 +1,8 @@
+#############
+# Automatically generated by generator.py in splunk/security_content
+# On Date: 2020-12-25T17:05:55 UTC
+# Author: Splunk Security Research
+# Contact: research@splunk.com
+#############
+
+
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/lookups/attacker_tools.csv b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/lookups/attacker_tools.csv
new file mode 100644
index 0000000000..2f95dfb054
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/lookups/attacker_tools.csv
@@ -0,0 +1,27 @@
+attacker_tool_names,description
+remcom.exe,This process is an open source replacement to psexec and is not typically seen in an enterprise environment.
+pwdump.exe,This process is associated with a tool used to dump password hashes on a Windows system.
+pwdump2.exe,This process is associated with a tool used to dump password hashes on a Windows system.
+nc.exe,This process is an open source tool used for network communications.
+wce.exe,This process is associated with a tool used to dump hashes and execute pass-the-hash and pass-the-ticket attacks.
+cain.exe,This process is associated with a tool used to collect user credentials and execute attacks.
+nmap.exe,This process is an open source network mapping tool used to identify hosts and listening services on a network.
+kidlogger.exe,This process is associated with a tool used to collect keyboard input on a host.
+isass.exe,This process name is used by attackers to hide in plain sight and look like a legitimate Windows system process.
+svch0st.exe,This process name is used by attackers to hide in plain sight and look like a legitimate Windows system process.
+at.exe,This process is used to schedule other processes to run. schtasks.exe should be used instead as it provides more flexibility.
+getmail.exe,This process is seen to be used by attackers to extract email files from host machines.
+ntdll.exe,This process was identified as malicious by DHS Alert TA18-074A.
+netpass.exe,This process was identified as malicious by DHS Alert TA18-201A and attackers use this tool to recover all network passwords stored on your system for the current logged-on user.
+WebBrowserPassView.exe,This process was identified as malicious by DHS Alert TA18-201A and is used by attackers as a password recovery tool that reveals the passwords stored in Web Browsers.
+OutlookAddressBookView.exe,This process was identified as malicious by DHS Alert TA18-201A and is used by attackers to steal the details of all recipients stored in the address books of Microsoft Outlook.
+mailpv.exe,This process was identified by DHS Alert TA18-201A and attackers use this tool is a password-recovery tool that reveals the passwords and other account details from various email clients.
+NLBrute.exe,A RDP brute force tool found in botnets for further expansion and and acquisition of targets. This process was identified in the SamSam Ransomware Campaign and attackers use this tool to brute force RDP instances with a range of commonly used passwords.
+selfdel.exe,This executable was delivered in the SamSam Ransomware Campain and the attackers levereged this binary to delete its malicilous activities.
+masscan.exe,This executable was delivered in the XMRig Crypto Miner
+Massscan_GUI.exe,This executable was delivered in the XMRig Crypto Miner
+KPortScan3.exe,This executable was delivered in the XMRig Crypto Miner and is commonly used by attackers to scan the internet
+NLAChecker.exe,A scanner tool that checks for Windows hosts for Network Level Authentication. This tool allows attackers to detect Windows Servers with RDP without NLA enabled which facilitates the use of brute force non microsoft rdp tools or exploits
+ns.exe,A commonly used tool used by attackers to scan and map file shares
+SilverBullet.exe,Malware was discovered in our monitoring of honey pots that abuses this open source software for scanning and connecting to hosts.
+kportscan3.exe, KPortScan 3.0 is a widely used port scanning tool on Hacking Forums, to perform network scanning on the internal networks.
\ No newline at end of file
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/lookups/mitre_enrichment.csv b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/lookups/mitre_enrichment.csv
new file mode 100644
index 0000000000..749099c77b
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/data/lookups/mitre_enrichment.csv
@@ -0,0 +1,579 @@
+"mitre_id","technique","tactics","groups"
+"T1564.009","Resource Forking","Defense Evasion","no"
+"T1562.010","Downgrade Attack","Defense Evasion","no"
+"T1547.015","Login Items","Persistence|Privilege Escalation","no"
+"T1620","Reflective Code Loading","Defense Evasion","no"
+"T1619","Cloud Storage Object Discovery","Discovery","no"
+"T1218.014","MMC","Defense Evasion","no"
+"T1218.013","Mavinject","Defense Evasion","no"
+"T1614.001","System Language Discovery","Discovery","no"
+"T1615","Group Policy Discovery","Discovery","Turla"
+"T1036.007","Double File Extension","Defense Evasion","Mustang Panda"
+"T1562.009","Safe Mode Boot","Defense Evasion","no"
+"T1564.008","Email Hiding Rules","Defense Evasion","FIN4"
+"T1505.004","IIS Components","Persistence","no"
+"T1027.006","HTML Smuggling","Defense Evasion","no"
+"T1213.003","Code Repositories","Collection","APT29"
+"T1553.006","Code Signing Policy Modification","Defense Evasion","Turla|APT39"
+"T1614","System Location Discovery","Discovery","no"
+"T1613","Container and Resource Discovery","Discovery","TeamTNT"
+"T1552.007","Container API","Credential Access","no"
+"T1612","Build Image on Host","Defense Evasion","no"
+"T1611","Escape to Host","Privilege Escalation","TeamTNT"
+"T1204.003","Malicious Image","Execution","TeamTNT"
+"T1053.007","Container Orchestration Job","Execution|Persistence|Privilege Escalation","no"
+"T1610","Deploy Container","Defense Evasion|Execution","TeamTNT"
+"T1609","Container Administration Command","Execution","TeamTNT"
+"T1608.005","Link Target","Resource Development","Silent Librarian"
+"T1608.004","Drive-by Target","Resource Development","Transparent Tribe|APT32|Threat Group-3390"
+"T1608.003","Install Digital Certificate","Resource Development","no"
+"T1608.002","Upload Tool","Resource Development","Threat Group-3390"
+"T1608.001","Upload Malware","Resource Development","TeamTNT|APT32"
+"T1608","Stage Capabilities","Resource Development","no"
+"T1016.001","Internet Connection Discovery","Discovery","APT29|UNC2452|Turla"
+"T1553.005","Mark-of-the-Web Bypass","Defense Evasion","TA505"
+"T1555.005","Password Managers","Credential Access","Fox Kitten|Operation Wocao"
+"T1484.002","Domain Trust Modification","Defense Evasion|Privilege Escalation","APT29|UNC2452"
+"T1484.001","Group Policy Modification","Defense Evasion|Privilege Escalation","Indrik Spider"
+"T1547.014","Active Setup","Persistence|Privilege Escalation","no"
+"T1606.002","SAML Tokens","Credential Access","APT29|UNC2452"
+"T1606.001","Web Cookies","Credential Access","APT29|UNC2452"
+"T1606","Forge Web Credentials","Credential Access","no"
+"T1555.004","Windows Credential Manager","Credential Access","Stealth Falcon|OilRig|Turla"
+"T1059.008","Network Device CLI","Execution","no"
+"T1602.002","Network Device Configuration Dump","Collection","no"
+"T1542.005","TFTP Boot","Defense Evasion|Persistence","no"
+"T1542.004","ROMMONkit","Defense Evasion|Persistence","no"
+"T1602.001","SNMP (MIB Dump)","Collection","no"
+"T1602","Data from Configuration Repository","Collection","no"
+"T1601.002","Downgrade System Image","Defense Evasion","no"
+"T1601.001","Patch System Image","Defense Evasion","no"
+"T1601","Modify System Image","Defense Evasion","no"
+"T1600.002","Disable Crypto Hardware","Defense Evasion","no"
+"T1600.001","Reduce Key Space","Defense Evasion","no"
+"T1600","Weaken Encryption","Defense Evasion","no"
+"T1556.004","Network Device Authentication","Credential Access|Defense Evasion|Persistence","no"
+"T1599.001","Network Address Translation Traversal","Defense Evasion","no"
+"T1599","Network Boundary Bridging","Defense Evasion","no"
+"T1020.001","Traffic Duplication","Exfiltration","no"
+"T1557.002","ARP Cache Poisoning","Credential Access|Collection","Cleaver"
+"T1588.006","Vulnerabilities","Resource Development","Sandworm Team"
+"T1053.006","Systemd Timers","Execution|Persistence|Privilege Escalation","no"
+"T1562.008","Disable Cloud Logs","Defense Evasion","no"
+"T1547.012","Print Processors","Persistence|Privilege Escalation","no"
+"T1598.003","Spearphishing Link","Reconnaissance","Magic Hound|Silent Librarian|Sidewinder|Sandworm Team|APT32|Kimsuky"
+"T1598.002","Spearphishing Attachment","Reconnaissance","Sidewinder"
+"T1598.001","Spearphishing Service","Reconnaissance","no"
+"T1598","Phishing for Information","Reconnaissance","ZIRCONIUM|APT28"
+"T1597.002","Purchase Technical Data","Reconnaissance","no"
+"T1597.001","Threat Intel Vendors","Reconnaissance","no"
+"T1597","Search Closed Sources","Reconnaissance","no"
+"T1596.005","Scan Databases","Reconnaissance","no"
+"T1596.004","CDNs","Reconnaissance","no"
+"T1596.003","Digital Certificates","Reconnaissance","no"
+"T1596.001","DNS/Passive DNS","Reconnaissance","no"
+"T1596.002","WHOIS","Reconnaissance","no"
+"T1596","Search Open Technical Databases","Reconnaissance","no"
+"T1595.002","Vulnerability Scanning","Reconnaissance","TeamTNT|APT29|Volatile Cedar|APT28|Sandworm Team"
+"T1595.001","Scanning IP Blocks","Reconnaissance","TeamTNT"
+"T1595","Active Scanning","Reconnaissance","no"
+"T1594","Search Victim-Owned Websites","Reconnaissance","Silent Librarian|Sandworm Team"
+"T1593.002","Search Engines","Reconnaissance","no"
+"T1593.001","Social Media","Reconnaissance","Kimsuky"
+"T1593","Search Open Websites/Domains","Reconnaissance","Sandworm Team"
+"T1592.004","Client Configurations","Reconnaissance","HAFNIUM"
+"T1592.003","Firmware","Reconnaissance","no"
+"T1592.002","Software","Reconnaissance","Andariel|Sandworm Team"
+"T1592.001","Hardware","Reconnaissance","no"
+"T1592","Gather Victim Host Information","Reconnaissance","no"
+"T1591.004","Identify Roles","Reconnaissance","no"
+"T1591.003","Identify Business Tempo","Reconnaissance","no"
+"T1591.001","Determine Physical Locations","Reconnaissance","no"
+"T1591.002","Business Relationships","Reconnaissance","Sandworm Team"
+"T1591","Gather Victim Org Information","Reconnaissance","no"
+"T1590.006","Network Security Appliances","Reconnaissance","no"
+"T1590.005","IP Addresses","Reconnaissance","Andariel|HAFNIUM"
+"T1590.004","Network Topology","Reconnaissance","no"
+"T1590.003","Network Trust Dependencies","Reconnaissance","no"
+"T1590.002","DNS","Reconnaissance","no"
+"T1590.001","Domain Properties","Reconnaissance","Sandworm Team"
+"T1590","Gather Victim Network Information","Reconnaissance","HAFNIUM"
+"T1589.003","Employee Names","Reconnaissance","Silent Librarian|Sandworm Team"
+"T1589.002","Email Addresses","Reconnaissance","Kimsuky|Magic Hound|TA551|MuddyWater|HAFNIUM|APT32|Silent Librarian|Sandworm Team"
+"T1589.001","Credentials","Reconnaissance","Leviathan|APT28|Magic Hound|Chimera"
+"T1589","Gather Victim Identity Information","Reconnaissance","Magic Hound|APT32"
+"T1588.005","Exploits","Resource Development","no"
+"T1588.004","Digital Certificates","Resource Development","Lazarus Group|Silent Librarian"
+"T1588.003","Code Signing Certificates","Resource Development","Wizard Spider"
+"T1588.002","Tool","Resource Development","CostaRicto|Night Dragon|DarkVishnya|FIN5|Gorgon Group|Patchwork|Chimera|Dragonfly|Blue Mockingbird|Whitefly|APT41|FIN6|TEMP.Veles|Kimsuky|PittyTiger|Cobalt Group|APT29|Thrip|Ke3chang|DarkHydrus|APT32|APT38|BRONZE BUTLER|Carbanak|Cleaver|Inception|Leafminer|Threat Group-3390|Ferocious Kitten|IndigoZebra|BackdoorDiplomacy|menuPass|APT-C-36|Magic Hound|APT28|Wizard Spider|Frankenstein|Silence|WIRTE|Turla|APT33|APT19|FIN10|CopyKittens|APT39|APT1|MuddyWater|Silent Librarian|GALLIUM|Sandworm Team"
+"T1588.001","Malware","Resource Development","Andariel|BackdoorDiplomacy|Turla|APT1"
+"T1588","Obtain Capabilities","Resource Development","no"
+"T1587.004","Exploits","Resource Development","no"
+"T1587.003","Digital Certificates","Resource Development","APT29|PROMETHIUM"
+"T1587.002","Code Signing Certificates","Resource Development","PROMETHIUM|Patchwork"
+"T1587.001","Malware","Resource Development","TeamTNT|APT29|Lazarus Group|UNC2452|Sandworm Team|Turla|FIN7|Night Dragon|Cleaver"
+"T1587","Develop Capabilities","Resource Development","Kimsuky"
+"T1586.002","Email Accounts","Resource Development","IndigoZebra|Leviathan|Magic Hound|Kimsuky"
+"T1586.001","Social Media Accounts","Resource Development","Leviathan"
+"T1586","Compromise Accounts","Resource Development","no"
+"T1585.002","Email Accounts","Resource Development","Leviathan|Magic Hound|Silent Librarian|Sandworm Team|APT1"
+"T1585.001","Social Media Accounts","Resource Development","Leviathan|Magic Hound|Fox Kitten|Sandworm Team|APT32|Cleaver"
+"T1585","Establish Accounts","Resource Development","Fox Kitten|APT17"
+"T1584.006","Web Services","Resource Development","Turla"
+"T1584.005","Botnet","Resource Development","no"
+"T1584.004","Server","Resource Development","Indrik Spider|Turla|APT16"
+"T1584.003","Virtual Private Server","Resource Development","Turla"
+"T1584.002","DNS Server","Resource Development","no"
+"T1584.001","Domains","Resource Development","Transparent Tribe|Magic Hound|APT29|UNC2452|APT1"
+"T1583.006","Web Services","Resource Development","IndigoZebra|ZIRCONIUM|MuddyWater|HAFNIUM|Lazarus Group|Turla|APT32|APT17|APT29"
+"T1583.005","Botnet","Resource Development","no"
+"T1583.004","Server","Resource Development","GALLIUM|Sandworm Team"
+"T1583.003","Virtual Private Server","Resource Development","HAFNIUM|TEMP.Veles"
+"T1583.002","DNS Server","Resource Development","no"
+"T1584","Compromise Infrastructure","Resource Development","no"
+"T1583.001","Domains","Resource Development","IndigoZebra|TeamTNT|Ferocious Kitten|FIN7|Transparent Tribe|Leviathan|Magic Hound|APT29|Mustang Panda|ZIRCONIUM|UNC2452|Lazarus Group|Silent Librarian|menuPass|Sandworm Team|APT32|Kimsuky|APT1|APT28"
+"T1583","Acquire Infrastructure","Resource Development","no"
+"T1564.007","VBA Stomping","Defense Evasion","no"
+"T1558.004","AS-REP Roasting","Credential Access","no"
+"T1580","Cloud Infrastructure Discovery","Discovery","no"
+"T1218.012","Verclsid","Defense Evasion","no"
+"T1205.001","Port Knocking","Defense Evasion|Persistence|Command And Control","PROMETHIUM"
+"T1564.006","Run Virtual Instance","Defense Evasion","no"
+"T1564.005","Hidden File System","Defense Evasion","Strider|Equation"
+"T1556.003","Pluggable Authentication Modules","Credential Access|Defense Evasion|Persistence","no"
+"T1574.012","COR_PROFILER","Persistence|Privilege Escalation|Defense Evasion","Blue Mockingbird"
+"T1562.007","Disable or Modify Cloud Firewall","Defense Evasion","no"
+"T1098.004","SSH Authorized Keys","Persistence","TeamTNT"
+"T1480.001","Environmental Keying","Defense Evasion","APT41|Equation"
+"T1059.007","JavaScript","Execution","Indrik Spider|MuddyWater|Turla|Higaisa|Sidewinder|Evilnum|Kimsuky|FIN6|APT32|FIN7|Cobalt Group|Molerats|TA505|Silence|Leafminer"
+"T1578.004","Revert Cloud Instance","Defense Evasion","no"
+"T1578.003","Delete Cloud Instance","Defense Evasion","no"
+"T1578.001","Create Snapshot","Defense Evasion","no"
+"T1578.002","Create Cloud Instance","Defense Evasion","no"
+"T1127.001","MSBuild","Defense Evasion","Frankenstein"
+"T1027.005","Indicator Removal from Tools","Defense Evasion","Operation Wocao|GALLIUM|TEMP.Veles|Patchwork|APT3|Turla|OilRig|Deep Panda"
+"T1562.006","Indicator Blocking","Defense Evasion","no"
+"T1573.002","Asymmetric Cryptography","Command And Control","Operation Wocao|Tropic Trooper|Cobalt Group|OilRig|FIN8|FIN6"
+"T1573.001","Symmetric Cryptography","Command And Control","Mustang Panda|Darkhotel|ZIRCONIUM|Higaisa|Frankenstein|Inception|APT28|APT33|BRONZE BUTLER|Stealth Falcon|Lazarus Group"
+"T1573","Encrypted Channel","Command And Control","Tropic Trooper"
+"T1027.004","Compile After Delivery","Defense Evasion","Gamaredon Group|Rocke|MuddyWater"
+"T1574.004","Dylib Hijacking","Persistence|Privilege Escalation|Defense Evasion","no"
+"T1546.015","Component Object Model Hijacking","Privilege Escalation|Persistence","APT28"
+"T1071.004","DNS","Command And Control","Chimera|APT39|Tropic Trooper|OilRig|Ke3chang|Cobalt Group|APT18|APT41|FIN7"
+"T1071.003","Mail Protocols","Command And Control","Turla|Kimsuky|APT32|SilverTerrier|APT28"
+"T1071.002","File Transfer Protocols","Command And Control","Kimsuky|APT41|SilverTerrier|Honeybee"
+"T1071.001","Web Protocols","Command And Control","TeamTNT|FIN8|APT29|Mustang Panda|Windshift|TA551|Higaisa|HAFNIUM|Sidewinder|Chimera|UNC2452|Sandworm Team|TA505|Rocke|APT39|Tropic Trooper|MuddyWater|Wizard Spider|Inception|APT41|SilverTerrier|APT28|WIRTE|APT33|FIN4|Night Dragon|APT18|APT38|Rancor|Ke3chang|Orangeworm|APT37|APT19|Cobalt Group|Threat Group-3390|Dark Caracal|Turla|Lazarus Group|BRONZE BUTLER|Magic Hound|APT32|OilRig|Gamaredon Group|Stealth Falcon"
+"T1572","Protocol Tunneling","Command And Control","Leviathan|CostaRicto|Chimera|Fox Kitten|OilRig|Cobalt Group|FIN6"
+"T1048.003","Exfiltration Over Unencrypted/Obfuscated Non-C2 Protocol","Exfiltration","Wizard Spider|FIN6|APT32|APT33|Thrip|FIN8|OilRig|Lazarus Group"
+"T1048.002","Exfiltration Over Asymmetric Encrypted Non-C2 Protocol","Exfiltration","APT28|APT29|UNC2452"
+"T1048.001","Exfiltration Over Symmetric Encrypted Non-C2 Protocol","Exfiltration","no"
+"T1001.003","Protocol Impersonation","Command And Control","Higaisa|Lazarus Group"
+"T1001.002","Steganography","Command And Control","APT29|Axiom"
+"T1001.001","Junk Data","Command And Control","APT28"
+"T1132.002","Non-Standard Encoding","Command And Control","no"
+"T1132.001","Standard Encoding","Command And Control","HAFNIUM|TA551|Sandworm Team|Tropic Trooper|MuddyWater|APT33|APT19|Lazarus Group|BRONZE BUTLER|Patchwork"
+"T1090.004","Domain Fronting","Command And Control","APT29"
+"T1090.003","Multi-hop Proxy","Command And Control","Leviathan|CostaRicto|APT28|Operation Wocao|Inception|FIN4|APT29"
+"T1090.002","External Proxy","Command And Control","Tonto Team|APT39|Silence|GALLIUM|MuddyWater|APT3|FIN5|Lazarus Group|menuPass|APT28"
+"T1090.001","Internal Proxy","Command And Control","APT29|Higaisa|UNC2452|Operation Wocao|APT39|Strider"
+"T1102.003","One-Way Communication","Command And Control","Leviathan"
+"T1102.002","Bidirectional Communication","Command And Control","ZIRCONIUM|MuddyWater|APT28|APT29|Sandworm Team|APT39|APT12|Turla|FIN7|APT37|Magic Hound|Carbanak"
+"T1102.001","Dead Drop Resolver","Command And Control","Rocke|APT41|BRONZE BUTLER|RTM|Patchwork"
+"T1571","Non-Standard Port","Command And Control","Sandworm Team|Rocke|DarkVishnya|Silence|APT-C-36|Magic Hound|APT33|APT32|TEMP.Veles|Lazarus Group|FIN7"
+"T1074.002","Remote Data Staging","Collection","Leviathan|APT28|APT29|Chimera|UNC2452|Threat Group-3390|menuPass|FIN6|Night Dragon|FIN8"
+"T1074.001","Local Data Staging","Collection","Indrik Spider|BackdoorDiplomacy|Mustang Panda|Sidewinder|Chimera|Kimsuky|APT39|Operation Wocao|GALLIUM|TEMP.Veles|Patchwork|Honeybee|Dragonfly 2.0|Leviathan|APT3|FIN5|menuPass|Lazarus Group|Threat Group-3390|APT28"
+"T1078.004","Cloud Accounts","Defense Evasion|Persistence|Privilege Escalation|Initial Access","APT28|APT33"
+"T1564.004","NTFS File Attributes","Defense Evasion","APT32"
+"T1564.003","Hidden Window","Defense Evasion","Nomadic Octopus|Higaisa|Gorgon Group|Deep Panda|DarkHydrus|CopyKittens|APT19|APT32|APT28|APT3|Magic Hound"
+"T1078.003","Local Accounts","Defense Evasion|Persistence|Privilege Escalation|Initial Access","Kimsuky|HAFNIUM|Turla|Operation Wocao|PROMETHIUM|Tropic Trooper|FIN10|Stolen Pencil|APT32"
+"T1078.002","Domain Accounts","Defense Evasion|Persistence|Privilege Escalation|Initial Access","Naikon|Indrik Spider|Chimera|Operation Wocao|Sandworm Team|Wizard Spider|APT29|TA505|APT3|Threat Group-1314"
+"T1078.001","Default Accounts","Defense Evasion|Persistence|Privilege Escalation|Initial Access","no"
+"T1564.002","Hidden Users","Defense Evasion","Dragonfly 2.0"
+"T1574.006","Dynamic Linker Hijacking","Persistence|Privilege Escalation|Defense Evasion","APT41|Rocke"
+"T1574.002","DLL Side-Loading","Persistence|Privilege Escalation|Defense Evasion","Mustang Panda|Higaisa|BlackTech|Sidewinder|Chimera|BRONZE BUTLER|Naikon|APT41|GALLIUM|Tropic Trooper|APT19|Patchwork|APT32|APT3|menuPass|Threat Group-3390"
+"T1574.001","DLL Search Order Hijacking","Persistence|Privilege Escalation|Defense Evasion","BackdoorDiplomacy|Tonto Team|Evilnum|APT41|Whitefly|RTM|Threat Group-3390|menuPass"
+"T1574.008","Path Interception by Search Order Hijacking","Persistence|Privilege Escalation|Defense Evasion","no"
+"T1574.007","Path Interception by PATH Environment Variable","Persistence|Privilege Escalation|Defense Evasion","no"
+"T1574.009","Path Interception by Unquoted Path","Persistence|Privilege Escalation|Defense Evasion","no"
+"T1574.011","Services Registry Permissions Weakness","Persistence|Privilege Escalation|Defense Evasion","no"
+"T1574.005","Executable Installer File Permissions Weakness","Persistence|Privilege Escalation|Defense Evasion","no"
+"T1574.010","Services File Permissions Weakness","Persistence|Privilege Escalation|Defense Evasion","no"
+"T1574","Hijack Execution Flow","Persistence|Privilege Escalation|Defense Evasion","no"
+"T1069.001","Local Groups","Discovery","Tonto Team|Chimera|Operation Wocao|Turla|OilRig|admin@338"
+"T1570","Lateral Tool Transfer","Lateral Movement","Sandworm Team|Chimera|GALLIUM|Operation Wocao|APT32|Wizard Spider|Turla|FIN10"
+"T1568.003","DNS Calculation","Command And Control","APT12"
+"T1204.002","Malicious File","Execution","Nomadic Octopus|Indrik Spider|APT38|Andariel|Ferocious Kitten|IndigoZebra|Transparent Tribe|Tonto Team|Magic Hound|Ajax Security Team|Mustang Panda|TA551|Higaisa|Sidewinder|Kimsuky|FIN6|PROMETHIUM|APT30|Windshift|APT33|Sandworm Team|Naikon|Whitefly|Tropic Trooper|Gamaredon Group|Sharpshooter|Molerats|Wizard Spider|Mofang|Frankenstein|RTM|Inception|BlackTech|APT-C-36|Machete|admin@338|APT12|TA505|Silence|The White Company|APT39|FIN4|Darkhotel|Gallmaker|Dragonfly 2.0|FIN7|BRONZE BUTLER|Gorgon Group|OilRig|Dark Caracal|Cobalt Group|DarkHydrus|Rancor|Patchwork|APT32|APT19|MuddyWater|Lazarus Group|menuPass|APT37|Leviathan|TA459|APT29|APT28|FIN8|PLATINUM|Elderwood"
+"T1204.001","Malicious Link","Execution","FIN7|Transparent Tribe|APT3|Magic Hound|APT28|APT29|Mustang Panda|Sidewinder|ZIRCONIUM|MuddyWater|Evilnum|Sandworm Team|Wizard Spider|Patchwork|Windshift|APT32|Molerats|Mofang|BlackTech|TA505|OilRig|Machete|Leviathan|FIN8|FIN4|Elderwood|Dragonfly 2.0|Cobalt Group|APT39|Night Dragon|Turla|APT33"
+"T1195.003","Compromise Hardware Supply Chain","Initial Access","no"
+"T1195.002","Compromise Software Supply Chain","Initial Access","APT29|UNC2452|Cobalt Group|GOLD SOUTHFIELD|Dragonfly|Sandworm Team|APT41"
+"T1195.001","Compromise Software Dependencies and Development Tools","Initial Access","no"
+"T1568.001","Fast Flux DNS","Command And Control","menuPass|TA505"
+"T1052.001","Exfiltration over USB","Exfiltration","Mustang Panda|Tropic Trooper"
+"T1569.002","Service Execution","Execution","APT38|Chimera|Operation Wocao|Wizard Spider|Blue Mockingbird|APT39|APT41|Silence|FIN6|APT32|Honeybee|Ke3chang"
+"T1569.001","Launchctl","Execution","no"
+"T1569","System Services","Execution","no"
+"T1568.002","Domain Generation Algorithms","Command And Control","TA551|APT41"
+"T1568","Dynamic Resolution","Command And Control","Transparent Tribe|APT29|UNC2452"
+"T1011.001","Exfiltration Over Bluetooth","Exfiltration","no"
+"T1567.002","Exfiltration to Cloud Storage","Exfiltration","FIN7|ZIRCONIUM|HAFNIUM|Chimera|Leviathan|Turla"
+"T1567.001","Exfiltration to Code Repository","Exfiltration","no"
+"T1059.006","Python","Execution","Tonto Team|APT37|ZIRCONIUM|MuddyWater|Turla|Operation Wocao|Kimsuky|APT29|Rocke|BRONZE BUTLER|APT39|Dragonfly 2.0|Machete"
+"T1059.005","Visual Basic","Execution","OilRig|APT38|Transparent Tribe|APT29|Mustang Panda|Windshift|Higaisa|Sidewinder|APT39|Machete|Operation Wocao|Kimsuky|APT33|Sandworm Team|Gamaredon Group|Sharpshooter|Molerats|Frankenstein|Inception|APT-C-36|Rancor|Patchwork|MuddyWater|Honeybee|FIN7|APT37|BRONZE BUTLER|APT32|Turla|TA505|Silence|WIRTE|FIN4|Cobalt Group|Gorgon Group|Leviathan|TA459|Magic Hound"
+"T1059.004","Unix Shell","Execution","TeamTNT|Rocke|APT41"
+"T1059.003","Windows Command Shell","Execution","Sandworm Team|Nomadic Octopus|TeamTNT|APT29|Mustang Panda|ZIRCONIUM|TA551|Higaisa|Indrik Spider|Chimera|UNC2452|Fox Kitten|Machete|Operation Wocao|Wizard Spider|FIN6|TA505|Blue Mockingbird|Tropic Trooper|Frankenstein|OilRig|Lazarus Group|Honeybee|Cobalt Group|FIN7|APT41|GALLIUM|Turla|Silence|APT32|Darkhotel|MuddyWater|APT18|APT38|Gorgon Group|Dark Caracal|Ke3chang|Dragonfly 2.0|Rancor|FIN8|APT28|APT37|Magic Hound|BRONZE BUTLER|Sowbug|menuPass|FIN10|Threat Group-3390|Gamaredon Group|Patchwork|Suckfly|Threat Group-1314|APT3|admin@338|APT1"
+"T1059.002","AppleScript","Execution","no"
+"T1059.001","PowerShell","Execution","Nomadic Octopus|TeamTNT|APT38|Tonto Team|Mustang Panda|Indrik Spider|HAFNIUM|Sidewinder|UNC2452|Fox Kitten|GOLD SOUTHFIELD|Sandworm Team|Operation Wocao|Chimera|Blue Mockingbird|APT39|DarkVishnya|Molerats|Wizard Spider|Frankenstein|Inception|Silence|APT41|Kimsuky|GALLIUM|TA505|WIRTE|TEMP.Veles|APT33|Gallmaker|Turla|Thrip|Cobalt Group|APT28|DarkHydrus|Dragonfly 2.0|APT19|Gorgon Group|TA459|Leviathan|MuddyWater|FIN8|CopyKittens|OilRig|Magic Hound|BRONZE BUTLER|FIN7|APT32|menuPass|FIN10|Threat Group-3390|Patchwork|Stealth Falcon|FIN6|Poseidon Group|APT3|APT29|Deep Panda"
+"T1567","Exfiltration Over Web Service","Exfiltration","APT28"
+"T1497.003","Time Based Evasion","Defense Evasion|Discovery","no"
+"T1497.002","User Activity Based Checks","Defense Evasion|Discovery","Darkhotel|FIN7"
+"T1497.001","System Checks","Defense Evasion|Discovery","OilRig|Darkhotel|Evilnum|Frankenstein"
+"T1498.002","Reflection Amplification","Impact","no"
+"T1498.001","Direct Network Flood","Impact","no"
+"T1566.003","Spearphishing via Service","Initial Access","APT29|Ajax Security Team|Magic Hound|Windshift|FIN6|OilRig|Dark Caracal"
+"T1566.002","Spearphishing Link","Initial Access","Transparent Tribe|FIN7|APT3|Mustang Panda|ZIRCONIUM|MuddyWater|Sidewinder|Evilnum|Sandworm Team|Wizard Spider|APT1|Windshift|Molerats|Mofang|BlackTech|Machete|Kimsuky|TA505|Stolen Pencil|APT39|FIN4|APT32|Night Dragon|APT28|Cobalt Group|Turla|Dragonfly 2.0|OilRig|Elderwood|APT33|APT29|Leviathan|FIN8|Patchwork|Magic Hound"
+"T1566.001","Spearphishing Attachment","Initial Access","APT38|Andariel|Ferocious Kitten|IndigoZebra|Transparent Tribe|Nomadic Octopus|Tonto Team|Ajax Security Team|Mustang Panda|TA551|Higaisa|Sidewinder|APT1|FIN6|APT30|Windshift|APT33|Sandworm Team|Naikon|Gamaredon Group|Sharpshooter|Molerats|Mofang|Wizard Spider|RTM|Frankenstein|Inception|BlackTech|APT-C-36|APT41|Machete|admin@338|Kimsuky|APT12|TA505|Silence|The White Company|APT39|FIN4|Darkhotel|Gallmaker|Tropic Trooper|DarkHydrus|Lazarus Group|Gorgon Group|OilRig|BRONZE BUTLER|APT19|APT32|Cobalt Group|Rancor|FIN7|Dragonfly 2.0|MuddyWater|APT28|TA459|APT29|APT37|Leviathan|FIN8|Patchwork|menuPass|Elderwood|PLATINUM"
+"T1566","Phishing","Initial Access","GOLD SOUTHFIELD|Dragonfly"
+"T1565.003","Runtime Data Manipulation","Impact","APT38"
+"T1565.002","Transmitted Data Manipulation","Impact","APT38"
+"T1565.001","Stored Data Manipulation","Impact","APT38"
+"T1565","Data Manipulation","Impact","no"
+"T1564.001","Hidden Files and Directories","Defense Evasion","Transparent Tribe|Mustang Panda|Rocke|APT32|Tropic Trooper|APT28|Lazarus Group"
+"T1564","Hide Artifacts","Defense Evasion","no"
+"T1563.002","RDP Hijacking","Lateral Movement","no"
+"T1563.001","SSH Hijacking","Lateral Movement","no"
+"T1563","Remote Service Session Hijacking","Lateral Movement","no"
+"T1518.001","Security Software Discovery","Discovery","TeamTNT|APT38|Windshift|Sidewinder|Operation Wocao|Wizard Spider|Turla|Rocke|Frankenstein|The White Company|Cobalt Group|Darkhotel|MuddyWater|Tropic Trooper|FIN8|Patchwork|Naikon"
+"T1069.003","Cloud Groups","Discovery","no"
+"T1069.002","Domain Groups","Discovery","Turla|Inception|OilRig|Dragonfly 2.0|Ke3chang"
+"T1087.004","Cloud Account","Discovery","no"
+"T1087.003","Email Account","Discovery","Sandworm Team|TA505"
+"T1087.002","Domain Account","Discovery","MuddyWater|Fox Kitten|Operation Wocao|Wizard Spider|Chimera|Turla|Sandworm Team|Dragonfly 2.0|OilRig|BRONZE BUTLER|menuPass|FIN6|Poseidon Group|Ke3chang"
+"T1087.001","Local Account","Discovery","Chimera|Fox Kitten|Turla|Poseidon Group|OilRig|Ke3chang|APT32|APT1|Threat Group-3390|APT3|admin@338"
+"T1553.004","Install Root Certificate","Defense Evasion","no"
+"T1562.004","Disable or Modify System Firewall","Defense Evasion","TeamTNT|APT38|APT29|UNC2452|Operation Wocao|Rocke|Lazarus Group|Kimsuky|Dragonfly 2.0|Carbanak"
+"T1562.003","Impair Command History Logging","Defense Evasion","APT38"
+"T1562.002","Disable Windows Event Logging","Defense Evasion","Sandworm Team|APT29|UNC2452|Threat Group-3390"
+"T1562.001","Disable or Modify Tools","Defense Evasion","TeamTNT|Indrik Spider|APT29|MuddyWater|UNC2452|Wizard Spider|FIN6|Gamaredon Group|BRONZE BUTLER|Rocke|Kimsuky|Turla|Night Dragon|Gorgon Group|Lazarus Group|Putter Panda"
+"T1562","Impair Defenses","Defense Evasion","no"
+"T1003.004","LSA Secrets","Credential Access","OilRig|MuddyWater|menuPass|Leafminer|Ke3chang|Dragonfly 2.0|APT33|Threat Group-3390"
+"T1003.005","Cached Domain Credentials","Credential Access","OilRig|MuddyWater|Leafminer|APT33"
+"T1561.002","Disk Structure Wipe","Impact","Sandworm Team|Lazarus Group|APT38|APT37"
+"T1561.001","Disk Content Wipe","Impact","Lazarus Group"
+"T1561","Disk Wipe","Impact","no"
+"T1560.003","Archive via Custom Method","Collection","Mustang Panda|Lazarus Group|Kimsuky|CopyKittens|FIN6"
+"T1560.002","Archive via Library","Collection","Lazarus Group|Threat Group-3390"
+"T1560.001","Archive via Utility","Collection","APT28|APT29|Mustang Panda|HAFNIUM|UNC2452|Fox Kitten|Operation Wocao|Chimera|APT41|GALLIUM|Turla|Gallmaker|APT33|APT39|MuddyWater|Magic Hound|FIN8|BRONZE BUTLER|CopyKittens|Sowbug|APT3|menuPass|APT1|Ke3chang"
+"T1560","Archive Collected Data","Collection","Leviathan|menuPass|APT32|Honeybee|Patchwork|APT28|Dragonfly 2.0|FIN6|Lazarus Group|Ke3chang"
+"T1499.004","Application or System Exploitation","Impact","no"
+"T1499.003","Application Exhaustion Flood","Impact","no"
+"T1499.002","Service Exhaustion Flood","Impact","no"
+"T1499.001","OS Exhaustion Flood","Impact","no"
+"T1491.002","External Defacement","Impact","Sandworm Team"
+"T1491.001","Internal Defacement","Impact","Lazarus Group"
+"T1114.003","Email Forwarding Rule","Collection","Silent Librarian|Kimsuky"
+"T1114.002","Remote Email Collection","Collection","APT29|HAFNIUM|Chimera|UNC2452|APT1|FIN4|Ke3chang|Leafminer|Dragonfly 2.0|APT28"
+"T1114.001","Local Email Collection","Collection","Chimera|Magic Hound|APT1"
+"T1134.005","SID-History Injection","Defense Evasion|Privilege Escalation","no"
+"T1134.004","Parent PID Spoofing","Defense Evasion|Privilege Escalation","no"
+"T1134.003","Make and Impersonate Token","Defense Evasion|Privilege Escalation","no"
+"T1134.002","Create Process with Token","Defense Evasion|Privilege Escalation","Turla|Lazarus Group"
+"T1134.001","Token Impersonation/Theft","Defense Evasion|Privilege Escalation","FIN8|APT28"
+"T1213.002","Sharepoint","Collection","Chimera|Ke3chang|APT28"
+"T1213.001","Confluence","Collection","no"
+"T1555.003","Credentials from Web Browsers","Credential Access","Ajax Security Team|ZIRCONIUM|FIN6|Sandworm Team|Inception|Stealth Falcon|OilRig|Leafminer|APT33|APT3|Kimsuky|TA505|Stolen Pencil|MuddyWater|APT37|Patchwork|Molerats"
+"T1555.002","Securityd Memory","Credential Access","no"
+"T1555.001","Keychain","Credential Access","no"
+"T1559.002","Dynamic Data Exchange","Execution","Leviathan|Sidewinder|Sharpshooter|TA505|MuddyWater|Gallmaker|Patchwork|Cobalt Group|APT37|FIN7|APT28"
+"T1559.001","Component Object Model","Execution","Gamaredon Group|MuddyWater"
+"T1559","Inter-Process Communication","Execution","no"
+"T1558.002","Silver Ticket","Credential Access","no"
+"T1558.001","Golden Ticket","Credential Access","Ke3chang"
+"T1558","Steal or Forge Kerberos Tickets","Credential Access","no"
+"T1557.001","LLMNR/NBT-NS Poisoning and SMB Relay","Credential Access|Collection","Wizard Spider"
+"T1557","Adversary-in-the-Middle","Credential Access|Collection","Kimsuky"
+"T1556.002","Password Filter DLL","Credential Access|Defense Evasion|Persistence","Strider"
+"T1556.001","Domain Controller Authentication","Credential Access|Defense Evasion|Persistence","Chimera"
+"T1556","Modify Authentication Process","Credential Access|Defense Evasion|Persistence","no"
+"T1056.004","Credential API Hooking","Collection|Credential Access","PLATINUM"
+"T1056.003","Web Portal Capture","Collection|Credential Access","no"
+"T1056.002","GUI Input Capture","Collection|Credential Access","FIN4"
+"T1056.001","Keylogging","Collection|Credential Access","Tonto Team|Ajax Security Team|Operation Wocao|APT32|Sandworm Team|APT39|APT41|Kimsuky|menuPass|Stolen Pencil|FIN4|APT38|OilRig|Ke3chang|PLATINUM|Sowbug|Magic Hound|Group5|Lazarus Group|Threat Group-3390|APT3|Darkhotel|APT28"
+"T1555","Credentials from Password Stores","Credential Access","APT29|Evilnum|UNC2452|FIN6|APT39|OilRig|MuddyWater|Leafminer|APT33|Stealth Falcon"
+"T1552.005","Cloud Instance Metadata API","Credential Access","TeamTNT"
+"T1003.008","/etc/passwd and /etc/shadow","Credential Access","no"
+"T1003.007","Proc Filesystem","Credential Access","no"
+"T1003.006","DCSync","Credential Access","APT29|UNC2452|Operation Wocao"
+"T1558.003","Kerberoasting","Credential Access","FIN7|APT29|UNC2452|Operation Wocao|Wizard Spider"
+"T1552.006","Group Policy Preferences","Credential Access","APT33"
+"T1003.003","NTDS","Credential Access","APT28|Mustang Panda|HAFNIUM|Fox Kitten|menuPass|Wizard Spider|Chimera|FIN6|Dragonfly 2.0"
+"T1003.002","Security Account Manager","Credential Access","Wizard Spider|Threat Group-3390|Ke3chang|GALLIUM|Night Dragon|Dragonfly 2.0|menuPass"
+"T1003.001","LSASS Memory","Credential Access","Indrik Spider|HAFNIUM|Fox Kitten|Operation Wocao|Kimsuky|Sandworm Team|Whitefly|Blue Mockingbird|Silence|Threat Group-3390|Leviathan|APT41|GALLIUM|TEMP.Veles|APT33|APT39|Stolen Pencil|APT32|Leafminer|Magic Hound|FIN8|PLATINUM|MuddyWater|OilRig|BRONZE BUTLER|FIN6|APT3|APT28|APT1|Ke3chang|Cleaver"
+"T1110.004","Credential Stuffing","Credential Access","Chimera"
+"T1110.003","Password Spraying","Credential Access","Sandworm Team|APT29|Silent Librarian|Chimera|APT28|APT33|Leafminer|Lazarus Group"
+"T1110.002","Password Cracking","Credential Access","FIN6|APT41|Dragonfly 2.0|APT3"
+"T1110.001","Password Guessing","Credential Access","APT28"
+"T1021.006","Windows Remote Management","Lateral Movement","APT29|UNC2452|Chimera|Wizard Spider|Threat Group-3390"
+"T1021.005","VNC","Lateral Movement","FIN7|Fox Kitten|GCMAN"
+"T1021.004","SSH","Lateral Movement","TeamTNT|FIN7|Fox Kitten|Rocke|TEMP.Veles|Leviathan|APT39|OilRig|menuPass|GCMAN"
+"T1021.003","Distributed Component Object Model","Lateral Movement","no"
+"T1021.002","SMB/Windows Admin Shares","Lateral Movement","Sandworm Team|APT28|Fox Kitten|APT41|Operation Wocao|Wizard Spider|Chimera|Blue Mockingbird|APT39|APT32|Orangeworm|FIN8|APT3|Lazarus Group|Threat Group-1314|Turla|Deep Panda|Ke3chang"
+"T1021.001","Remote Desktop Protocol","Lateral Movement","Kimsuky|FIN7|Fox Kitten|Chimera|Blue Mockingbird|Wizard Spider|Silence|APT41|TEMP.Veles|Leviathan|APT39|Stolen Pencil|Cobalt Group|Dragonfly 2.0|FIN8|APT3|OilRig|FIN10|menuPass|Patchwork|FIN6|Lazarus Group|APT1|Axiom"
+"T1554","Compromise Client Software Binary","Persistence","no"
+"T1036.006","Space after Filename","Defense Evasion","no"
+"T1036.005","Match Legitimate Name or Location","Defense Evasion","APT28|Ferocious Kitten|FIN7|BackdoorDiplomacy|Transparent Tribe|Naikon|APT29|Mustang Panda|Sidewinder|Darkhotel|Lazarus Group|Indrik Spider|UNC2452|Fox Kitten|Machete|Chimera|PROMETHIUM|Rocke|Sandworm Team|APT39|Blue Mockingbird|Whitefly|Tropic Trooper|Silence|APT41|menuPass|TEMP.Veles|MuddyWater|Sowbug|BRONZE BUTLER|APT32|Patchwork|Poseidon Group|admin@338|Carbanak|APT1"
+"T1036.004","Masquerade Task or Service","Defense Evasion","BackdoorDiplomacy|APT41|Naikon|ZIRCONIUM|APT29|Higaisa|UNC2452|Fox Kitten|Kimsuky|PROMETHIUM|Wizard Spider|APT-C-36|Carbanak|APT32|FIN6|FIN7"
+"T1036.003","Rename System Utilities","Defense Evasion","menuPass|APT32|GALLIUM"
+"T1036.002","Right-to-Left Override","Defense Evasion","Ferocious Kitten|BRONZE BUTLER|BlackTech|Ke3chang|Scarlet Mimic"
+"T1036.001","Invalid Code Signature","Defense Evasion","Windshift|APT37"
+"T1553.003","SIP and Trust Provider Hijacking","Defense Evasion","no"
+"T1553.002","Code Signing","Defense Evasion","menuPass|APT29|GALLIUM|UNC2452|Wizard Spider|Kimsuky|PROMETHIUM|Patchwork|Silence|APT41|FIN6|TA505|FIN7|Honeybee|Leviathan|CopyKittens|Winnti Group|Suckfly|Molerats|Darkhotel"
+"T1553.001","Gatekeeper Bypass","Defense Evasion","no"
+"T1553","Subvert Trust Controls","Defense Evasion","no"
+"T1027.003","Steganography","Defense Evasion","Andariel|Leviathan|TA551|BRONZE BUTLER|Tropic Trooper|MuddyWater|APT37"
+"T1027.002","Software Packing","Defense Evasion","Sandworm Team|Kimsuky|TeamTNT|ZIRCONIUM|TA505|Rocke|GALLIUM|The White Company|APT39|APT38|Dark Caracal|Elderwood|APT3|Patchwork|APT29|Night Dragon"
+"T1027.001","Binary Padding","Defense Evasion","APT29|Mustang Panda|Higaisa|Gamaredon Group|Patchwork|APT32|Leviathan|BRONZE BUTLER|Moafee"
+"T1222.002","Linux and Mac File and Directory Permissions Modification","Defense Evasion","TeamTNT|Rocke|APT32"
+"T1222.001","Windows File and Directory Permissions Modification","Defense Evasion","Wizard Spider"
+"T1552.004","Private Keys","Credential Access","TeamTNT|APT29|UNC2452|Operation Wocao|Rocke"
+"T1552.003","Bash History","Credential Access","no"
+"T1552.002","Credentials in Registry","Credential Access","APT32"
+"T1552.001","Credentials In Files","Credential Access","TeamTNT|Kimsuky|Fox Kitten|Leafminer|APT33|OilRig|TA505|Stolen Pencil|MuddyWater|APT3"
+"T1552","Unsecured Credentials","Credential Access","no"
+"T1216.001","PubPrn","Defense Evasion","APT32"
+"T1070.006","Timestomp","Defense Evasion","APT38|APT29|UNC2452|Chimera|Kimsuky|Rocke|TEMP.Veles|APT32|Lazarus Group|APT28"
+"T1070.005","Network Share Connection Removal","Defense Evasion","Threat Group-3390"
+"T1070.004","File Deletion","Defense Evasion","TeamTNT|APT39|Mustang Panda|Chimera|Evilnum|UNC2452|Operation Wocao|FIN6|Sandworm Team|Rocke|Tropic Trooper|Gamaredon Group|Wizard Spider|APT41|Kimsuky|Silence|The White Company|TEMP.Veles|APT32|APT38|Cobalt Group|Dragonfly 2.0|Honeybee|Patchwork|menuPass|FIN8|OilRig|FIN5|BRONZE BUTLER|APT3|Magic Hound|Threat Group-3390|APT28|FIN10|Group5|Lazarus Group|APT18|APT29"
+"T1070.003","Clear Command History","Defense Evasion","TeamTNT|menuPass|APT41"
+"T1550.004","Web Session Cookie","Defense Evasion|Lateral Movement","APT29|UNC2452"
+"T1550.001","Application Access Token","Defense Evasion|Lateral Movement","APT28"
+"T1550.003","Pass the Ticket","Defense Evasion|Lateral Movement","APT32|BRONZE BUTLER|APT29"
+"T1550.002","Pass the Hash","Defense Evasion|Lateral Movement","Chimera|Kimsuky|GALLIUM|APT32|Night Dragon|APT28|APT1"
+"T1550","Use Alternate Authentication Material","Defense Evasion|Lateral Movement","APT29|UNC2452"
+"T1548.004","Elevated Execution with Prompt","Privilege Escalation|Defense Evasion","no"
+"T1548.003","Sudo and Sudo Caching","Privilege Escalation|Defense Evasion","no"
+"T1548.002","Bypass User Account Control","Privilege Escalation|Defense Evasion","Evilnum|APT37|MuddyWater|Threat Group-3390|Honeybee|Cobalt Group|BRONZE BUTLER|Patchwork|APT29"
+"T1548.001","Setuid and Setgid","Privilege Escalation|Defense Evasion","no"
+"T1548","Abuse Elevation Control Mechanism","Privilege Escalation|Defense Evasion","no"
+"T1136.003","Cloud Account","Persistence","no"
+"T1070.002","Clear Linux or Mac System Logs","Defense Evasion","TeamTNT|Rocke"
+"T1070.001","Clear Windows Event Logs","Defense Evasion","Indrik Spider|Chimera|Operation Wocao|APT41|APT38|Dragonfly 2.0|APT32|FIN8|FIN5|APT28"
+"T1136.002","Domain Account","Persistence","Sandworm Team|HAFNIUM|GALLIUM"
+"T1136.001","Local Account","Persistence","TeamTNT|Fox Kitten|APT39|APT41|Leafminer|Dragonfly 2.0|APT3"
+"T1547.011","Plist Modification","Persistence|Privilege Escalation","no"
+"T1547.010","Port Monitors","Persistence|Privilege Escalation","no"
+"T1547.009","Shortcut Modification","Persistence|Privilege Escalation","APT39|Darkhotel|APT29|Gorgon Group|Dragonfly 2.0|Lazarus Group|Leviathan"
+"T1547.008","LSASS Driver","Persistence|Privilege Escalation","no"
+"T1547.007","Re-opened Applications","Persistence|Privilege Escalation","no"
+"T1547.006","Kernel Modules and Extensions","Persistence|Privilege Escalation","no"
+"T1547.005","Security Support Provider","Persistence|Privilege Escalation","no"
+"T1547.004","Winlogon Helper DLL","Persistence|Privilege Escalation","Wizard Spider|Tropic Trooper|Turla"
+"T1547.003","Time Providers","Persistence|Privilege Escalation","no"
+"T1546.014","Emond","Privilege Escalation|Persistence","no"
+"T1546.013","PowerShell Profile","Privilege Escalation|Persistence","Turla"
+"T1546.012","Image File Execution Options Injection","Privilege Escalation|Persistence","TEMP.Veles"
+"T1218.008","Odbcconf","Defense Evasion","Cobalt Group"
+"T1546.011","Application Shimming","Privilege Escalation|Persistence","FIN7"
+"T1547.002","Authentication Package","Persistence|Privilege Escalation","no"
+"T1546.010","AppInit DLLs","Privilege Escalation|Persistence","APT39"
+"T1546.009","AppCert DLLs","Privilege Escalation|Persistence","Honeybee"
+"T1218.007","Msiexec","Defense Evasion","ZIRCONIUM|Molerats|Machete|TA505|Rancor"
+"T1546.008","Accessibility Features","Privilege Escalation|Persistence","Fox Kitten|APT41|APT3|APT29|Deep Panda|Axiom"
+"T1546.007","Netsh Helper DLL","Privilege Escalation|Persistence","no"
+"T1546.006","LC_LOAD_DYLIB Addition","Privilege Escalation|Persistence","no"
+"T1546.005","Trap","Privilege Escalation|Persistence","no"
+"T1546.004","Unix Shell Configuration Modification","Privilege Escalation|Persistence","no"
+"T1546.003","Windows Management Instrumentation Event Subscription","Privilege Escalation|Persistence","FIN8|Mustang Panda|UNC2452|APT33|Blue Mockingbird|Turla|Leviathan|APT29"
+"T1546.002","Screensaver","Privilege Escalation|Persistence","no"
+"T1546.001","Change Default File Association","Privilege Escalation|Persistence","Kimsuky"
+"T1547.001","Registry Run Keys / Startup Folder","Persistence|Privilege Escalation","TeamTNT|Naikon|Windshift|Mustang Panda|ZIRCONIUM|Higaisa|Sidewinder|APT28|Wizard Spider|PROMETHIUM|Rocke|Tropic Trooper|Gamaredon Group|Sharpshooter|Molerats|Silence|RTM|Inception|APT41|Kimsuky|APT33|APT39|APT32|APT18|Dark Caracal|Threat Group-3390|Honeybee|Turla|Cobalt Group|Ke3chang|Dragonfly 2.0|APT19|Gorgon Group|MuddyWater|APT37|Leviathan|BRONZE BUTLER|APT3|Magic Hound|FIN10|FIN7|Patchwork|FIN6|Lazarus Group|Putter Panda|APT29|Darkhotel"
+"T1218.002","Control Panel","Defense Evasion","no"
+"T1218.010","Regsvr32","Defense Evasion","TA551|Blue Mockingbird|Inception|WIRTE|Cobalt Group|APT19|Leviathan|APT32|Deep Panda"
+"T1218.009","Regsvcs/Regasm","Defense Evasion","no"
+"T1218.005","Mshta","Defense Evasion","Mustang Panda|TA551|Sidewinder|Inception|Kimsuky|APT32|MuddyWater|FIN7"
+"T1218.004","InstallUtil","Defense Evasion","Mustang Panda|menuPass"
+"T1218.001","Compiled HTML File","Defense Evasion","APT41|Silence|Dark Caracal|OilRig|Lazarus Group"
+"T1218.003","CMSTP","Defense Evasion","Cobalt Group|MuddyWater"
+"T1218.011","Rundll32","Defense Evasion","APT38|HAFNIUM|TA551|UNC2452|APT41|Gamaredon Group|APT32|Sandworm Team|Blue Mockingbird|TA505|MuddyWater|APT29|APT19|CopyKittens|APT3|Carbanak|APT28"
+"T1547","Boot or Logon Autostart Execution","Persistence|Privilege Escalation","no"
+"T1546","Event Triggered Execution","Privilege Escalation|Persistence","no"
+"T1098.003","Add Office 365 Global Administrator Role","Persistence","no"
+"T1098.002","Exchange Email Delegate Permissions","Persistence","APT28|APT29|UNC2452|Magic Hound"
+"T1098.001","Additional Cloud Credentials","Persistence","APT29|UNC2452"
+"T1543.004","Launch Daemon","Persistence|Privilege Escalation","no"
+"T1543.003","Windows Service","Persistence|Privilege Escalation","TeamTNT|APT38|PROMETHIUM|Blue Mockingbird|DarkVishnya|Wizard Spider|APT32|APT41|Kimsuky|Tropic Trooper|Cobalt Group|Ke3chang|FIN7|APT19|Threat Group-3390|Honeybee|APT3|Lazarus Group|Carbanak"
+"T1543.002","Systemd Service","Persistence|Privilege Escalation","TeamTNT|Rocke"
+"T1543.001","Launch Agent","Persistence|Privilege Escalation","no"
+"T1037.005","Startup Items","Persistence|Privilege Escalation","no"
+"T1037.004","RC Scripts","Persistence|Privilege Escalation","no"
+"T1055.012","Process Hollowing","Defense Evasion|Privilege Escalation","Threat Group-3390|menuPass|Gorgon Group|Patchwork"
+"T1055.013","Process Doppelgänging","Defense Evasion|Privilege Escalation","Leafminer"
+"T1055.011","Extra Window Memory Injection","Defense Evasion|Privilege Escalation","no"
+"T1055.014","VDSO Hijacking","Defense Evasion|Privilege Escalation","no"
+"T1055.009","Proc Memory","Defense Evasion|Privilege Escalation","no"
+"T1055.008","Ptrace System Calls","Defense Evasion|Privilege Escalation","no"
+"T1055.005","Thread Local Storage","Defense Evasion|Privilege Escalation","no"
+"T1055.004","Asynchronous Procedure Call","Defense Evasion|Privilege Escalation","FIN8"
+"T1055.003","Thread Execution Hijacking","Defense Evasion|Privilege Escalation","no"
+"T1055.002","Portable Executable Injection","Defense Evasion|Privilege Escalation","Rocke|Gorgon Group"
+"T1055.001","Dynamic-link Library Injection","Defense Evasion|Privilege Escalation","BackdoorDiplomacy|Leviathan|Wizard Spider|TA505|Turla|Tropic Trooper|Lazarus Group|Putter Panda"
+"T1037.003","Network Logon Script","Persistence|Privilege Escalation","no"
+"T1543","Create or Modify System Process","Persistence|Privilege Escalation","no"
+"T1037.002","Logon Script (Mac)","Persistence|Privilege Escalation","no"
+"T1037.001","Logon Script (Windows)","Persistence|Privilege Escalation","Cobalt Group|APT28"
+"T1542.003","Bootkit","Persistence|Defense Evasion","APT41|Lazarus Group|APT28"
+"T1542.002","Component Firmware","Persistence|Defense Evasion","Equation"
+"T1542.001","System Firmware","Persistence|Defense Evasion","no"
+"T1505.003","Web Shell","Persistence","BackdoorDiplomacy|APT38|APT29|APT28|Tonto Team|Sandworm Team|HAFNIUM|Volatile Cedar|Fox Kitten|Operation Wocao|Kimsuky|Tropic Trooper|GALLIUM|Threat Group-3390|TEMP.Veles|Leviathan|APT39|Dragonfly 2.0|APT32|OilRig|Deep Panda"
+"T1505.002","Transport Agent","Persistence","no"
+"T1505.001","SQL Stored Procedures","Persistence","Sandworm Team"
+"T1053.003","Cron","Execution|Persistence|Privilege Escalation","APT38|Rocke"
+"T1053.004","Launchd","Execution|Persistence|Privilege Escalation","no"
+"T1053.001","At (Linux)","Execution|Persistence|Privilege Escalation","no"
+"T1053.005","Scheduled Task","Execution|Persistence|Privilege Escalation","APT37|APT38|Naikon|CostaRicto|Mustang Panda|Higaisa|UNC2452|Fox Kitten|Molerats|Machete|Operation Wocao|Chimera|Gamaredon Group|Blue Mockingbird|MuddyWater|Wizard Spider|Frankenstein|APT-C-36|BRONZE BUTLER|APT41|GALLIUM|Silence|TEMP.Veles|APT33|APT39|Rancor|OilRig|Patchwork|Dragonfly 2.0|Cobalt Group|FIN8|menuPass|FIN10|FIN7|APT32|Stealth Falcon|FIN6|APT3|APT29"
+"T1053.002","At (Windows)","Execution|Persistence|Privilege Escalation","BRONZE BUTLER|Threat Group-3390|APT18"
+"T1542","Pre-OS Boot","Defense Evasion|Persistence","no"
+"T1137.001","Office Template Macros","Persistence","MuddyWater"
+"T1137.004","Outlook Home Page","Persistence","OilRig"
+"T1137.003","Outlook Forms","Persistence","no"
+"T1137.005","Outlook Rules","Persistence","no"
+"T1137.006","Add-ins","Persistence","Naikon"
+"T1137.002","Office Test","Persistence","APT28"
+"T1531","Account Access Removal","Impact","no"
+"T1539","Steal Web Session Cookie","Credential Access","Evilnum"
+"T1529","System Shutdown/Reboot","Impact","Lazarus Group|APT38|APT37"
+"T1518","Software Discovery","Discovery","Mustang Panda|Windshift|MuddyWater|Windigo|Sidewinder|Operation Wocao|BRONZE BUTLER|Tropic Trooper|Inception"
+"T1547.013","XDG Autostart Entries","Persistence|Privilege Escalation","no"
+"T1534","Internal Spearphishing","Lateral Movement","Leviathan|Gamaredon Group"
+"T1528","Steal Application Access Token","Credential Access","APT28"
+"T1535","Unused/Unsupported Cloud Regions","Defense Evasion","no"
+"T1525","Implant Internal Image","Persistence","no"
+"T1538","Cloud Service Dashboard","Discovery","no"
+"T1530","Data from Cloud Storage Object","Collection","Fox Kitten"
+"T1578","Modify Cloud Compute Infrastructure","Defense Evasion","no"
+"T1537","Transfer Data to Cloud Account","Exfiltration","no"
+"T1526","Cloud Service Discovery","Discovery","no"
+"T1505","Server Software Component","Persistence","no"
+"T1499","Endpoint Denial of Service","Impact","Sandworm Team"
+"T1497","Virtualization/Sandbox Evasion","Defense Evasion|Discovery","Darkhotel"
+"T1498","Network Denial of Service","Impact","APT28"
+"T1496","Resource Hijacking","Impact","TeamTNT|Blue Mockingbird|Rocke|APT41"
+"T1495","Firmware Corruption","Impact","no"
+"T1491","Defacement","Impact","no"
+"T1490","Inhibit System Recovery","Impact","no"
+"T1489","Service Stop","Impact","Indrik Spider|Wizard Spider|Lazarus Group"
+"T1486","Data Encrypted for Impact","Impact","FIN7|Indrik Spider|APT41|TA505|APT38"
+"T1485","Data Destruction","Impact","Sandworm Team|Lazarus Group|APT38"
+"T1484","Domain Policy Modification","Defense Evasion|Privilege Escalation","no"
+"T1482","Domain Trust Discovery","Discovery","FIN8|APT29|Chimera|UNC2452"
+"T1480","Execution Guardrails","Defense Evasion","no"
+"T1221","Template Injection","Defense Evasion","Gamaredon Group|Frankenstein|Inception|APT28|Tropic Trooper|DarkHydrus|Dragonfly 2.0"
+"T1222","File and Directory Permissions Modification","Defense Evasion","no"
+"T1220","XSL Script Processing","Defense Evasion","Higaisa|Cobalt Group"
+"T1217","Browser Bookmark Discovery","Discovery","APT38|Chimera|Fox Kitten"
+"T1212","Exploitation for Credential Access","Credential Access","no"
+"T1189","Drive-by Compromise","Initial Access","Transparent Tribe|Andariel|Leviathan|Machete|Windigo|Dragonfly|PROMETHIUM|Turla|Windshift|RTM|Darkhotel|APT38|APT19|Lazarus Group|Threat Group-3390|BRONZE BUTLER|APT32|Dark Caracal|Dragonfly 2.0|Leafminer|Patchwork|APT37|Elderwood|PLATINUM"
+"T1211","Exploitation for Defense Evasion","Defense Evasion","APT28"
+"T1197","BITS Jobs","Defense Evasion|Persistence","APT39|Patchwork|APT41|Leviathan"
+"T1203","Exploitation for Client Execution","Execution","Andariel|Transparent Tribe|APT3|Tonto Team|Mustang Panda|Darkhotel|Higaisa|HAFNIUM|Sidewinder|Sandworm Team|MuddyWater|Frankenstein|Inception|BlackTech|APT41|admin@338|Threat Group-3390|APT12|The White Company|APT33|APT32|APT28|Tropic Trooper|BRONZE BUTLER|Cobalt Group|Lazarus Group|Patchwork|Elderwood|APT29|TA459|APT37|Leviathan"
+"T1201","Password Policy Discovery","Discovery","Chimera|Turla|OilRig"
+"T1195","Supply Chain Compromise","Initial Access","no"
+"T1199","Trusted Relationship","Initial Access","APT29|Sandworm Team|GOLD SOUTHFIELD|APT28|menuPass"
+"T1218","Signed Binary Proxy Execution","Defense Evasion","no"
+"T1204","User Execution","Execution","no"
+"T1213","Data from Information Repositories","Collection","APT28|Fox Kitten|FIN6|Turla"
+"T1190","Exploit Public-Facing Application","Initial Access","BackdoorDiplomacy|menuPass|Volatile Cedar|UNC2452|Fox Kitten|Operation Wocao|APT28|APT29|GOLD SOUTHFIELD|Blue Mockingbird|Rocke|APT39|BlackTech|APT41|GALLIUM|Night Dragon|Axiom"
+"T1210","Exploitation of Remote Services","Lateral Movement","Tonto Team|FIN7|Fox Kitten|menuPass|Wizard Spider|Threat Group-3390|APT28"
+"T1200","Hardware Additions","Initial Access","DarkVishnya"
+"T1202","Indirect Command Execution","Defense Evasion","no"
+"T1219","Remote Access Software","Command And Control","TeamTNT|Mustang Panda|MuddyWater|Evilnum|GOLD SOUTHFIELD|Sandworm Team|DarkVishnya|RTM|Kimsuky|Night Dragon|Cobalt Group|Thrip|Carbanak"
+"T1207","Rogue Domain Controller","Defense Evasion","no"
+"T1216","Signed Script Proxy Execution","Defense Evasion","no"
+"T1205","Traffic Signaling","Defense Evasion|Persistence|Command And Control","no"
+"T1176","Browser Extensions","Persistence","Kimsuky|Stolen Pencil"
+"T1187","Forced Authentication","Credential Access","DarkHydrus|Dragonfly 2.0"
+"T1175","Component Object Model and Distributed COM","Lateral Movement|Execution","no"
+"T1185","Browser Session Hijacking","Collection","no"
+"T1140","Deobfuscate/Decode Files or Information","Defense Evasion","APT39|APT29|ZIRCONIUM|Higaisa|UNC2452|Rocke|Sandworm Team|Gamaredon Group|Molerats|Frankenstein|Turla|WIRTE|Darkhotel|Tropic Trooper|Honeybee|Gorgon Group|Threat Group-3390|menuPass|APT19|Leviathan|MuddyWater|APT28|OilRig|BRONZE BUTLER"
+"T1134","Access Token Manipulation","Defense Evasion|Privilege Escalation","FIN6|Blue Mockingbird"
+"T1149","LC_MAIN Hijacking","Defense Evasion","no"
+"T1136","Create Account","Persistence","Sandworm Team|Indrik Spider"
+"T1135","Network Share Discovery","Discovery","Tonto Team|APT38|Chimera|Operation Wocao|Wizard Spider|APT32|APT39|DarkVishnya|APT41|Tropic Trooper|APT1|Dragonfly 2.0|Sowbug"
+"T1137","Office Application Startup","Persistence","Gamaredon Group|APT32"
+"T1153","Source","Execution","no"
+"T1133","External Remote Services","Persistence|Initial Access","TeamTNT|Leviathan|APT28|APT29|UNC2452|Operation Wocao|Wizard Spider|Kimsuky|GOLD SOUTHFIELD|Chimera|Sandworm Team|APT41|GALLIUM|TEMP.Veles|Night Dragon|Ke3chang|OilRig|Dragonfly 2.0|FIN5|Threat Group-3390|APT18"
+"T1132","Data Encoding","Command And Control","no"
+"T1129","Shared Modules","Execution","no"
+"T1127","Trusted Developer Utilities Proxy Execution","Defense Evasion","no"
+"T1125","Video Capture","Collection","Silence|FIN7"
+"T1124","System Time Discovery","Discovery","Darkhotel|ZIRCONIUM|Higaisa|Sidewinder|Chimera|Operation Wocao|The White Company|Lazarus Group|BRONZE BUTLER|Turla"
+"T1123","Audio Capture","Collection","APT37"
+"T1120","Peripheral Device Discovery","Discovery","OilRig|BackdoorDiplomacy|Operation Wocao|Turla|APT37|Gamaredon Group|Equation|APT28"
+"T1119","Automated Collection","Collection","Mustang Panda|Sidewinder|Chimera|menuPass|Operation Wocao|Gamaredon Group|Tropic Trooper|Frankenstein|APT1|APT28|Patchwork|OilRig|FIN5|Threat Group-3390|FIN6"
+"T1115","Clipboard Data","Collection","Operation Wocao|APT39|APT38"
+"T1114","Email Collection","Collection","Magic Hound|Silent Librarian"
+"T1113","Screen Capture","Collection","GOLD SOUTHFIELD|Gamaredon Group|APT39|Silence|MuddyWater|Dragonfly 2.0|OilRig|Dark Caracal|FIN7|BRONZE BUTLER|Magic Hound|Group5|APT28"
+"T1112","Modify Registry","Defense Evasion","Operation Wocao|Kimsuky|Gamaredon Group|Blue Mockingbird|Wizard Spider|Silence|APT41|Turla|APT32|APT38|Patchwork|Gorgon Group|Threat Group-3390|Dragonfly 2.0|APT19|Honeybee|FIN8"
+"T1111","Two-Factor Authentication Interception","Credential Access","Chimera|Operation Wocao"
+"T1110","Brute Force","Credential Access","APT38|APT28|Fox Kitten|DarkVishnya|APT39|OilRig|FIN5|Turla"
+"T1108","Redundant Access","Defense Evasion|Persistence","no"
+"T1106","Native API","Execution","APT38|Higaisa|menuPass|Operation Wocao|Chimera|Gamaredon Group|Tropic Trooper|Sharpshooter|Turla|Silence|APT37|Gorgon Group"
+"T1105","Ingress Tool Transfer","Command And Control","TeamTNT|Nomadic Octopus|IndigoZebra|Andariel|BackdoorDiplomacy|Tonto Team|HAFNIUM|APT29|Ajax Security Team|Mustang Panda|Windshift|Darkhotel|ZIRCONIUM|TA551|Volatile Cedar|Indrik Spider|Evilnum|Sidewinder|UNC2452|Fox Kitten|Kimsuky|Operation Wocao|Chimera|Sandworm Team|Whitefly|Rocke|APT39|Tropic Trooper|Sharpshooter|Molerats|Frankenstein|Silence|APT-C-36|APT41|GALLIUM|TA505|WIRTE|APT33|MuddyWater|APT18|APT38|Rancor|Gorgon Group|OilRig|Turla|Cobalt Group|Dragonfly 2.0|FIN8|PLATINUM|APT37|Elderwood|Leviathan|APT32|Magic Hound|BRONZE BUTLER|APT3|menuPass|FIN7|Gamaredon Group|Patchwork|Lazarus Group|Threat Group-3390|APT28"
+"T1104","Multi-Stage Channels","Command And Control","APT41|MuddyWater|APT3"
+"T1102","Web Service","Command And Control","TeamTNT|FIN8|Fox Kitten|Turla|APT32|Gamaredon Group|Rocke|Inception|FIN6"
+"T1098","Account Manipulation","Persistence","Sandworm Team|APT3|Dragonfly 2.0|Lazarus Group"
+"T1095","Non-Application Layer Protocol","Command And Control","BackdoorDiplomacy|HAFNIUM|Operation Wocao|FIN6|APT29|PLATINUM|APT3"
+"T1092","Communication Through Removable Media","Command And Control","APT28"
+"T1091","Replication Through Removable Media","Lateral Movement|Initial Access","Mustang Panda|Tropic Trooper|Darkhotel|APT28"
+"T1090","Proxy","Command And Control","Windigo|Fox Kitten|Operation Wocao|Sandworm Team|Blue Mockingbird|APT41|Turla"
+"T1087","Account Discovery","Discovery","APT29|UNC2452"
+"T1083","File and Directory Discovery","Discovery","APT38|APT29|Mustang Panda|Darkhotel|Windigo|Sidewinder|Chimera|UNC2452|Fox Kitten|menuPass|APT39|Sandworm Team|Operation Wocao|Gamaredon Group|Tropic Trooper|Inception|APT41|Kimsuky|APT32|MuddyWater|APT18|Leafminer|Honeybee|Dark Caracal|Dragonfly 2.0|APT3|Sowbug|Magic Hound|BRONZE BUTLER|APT28|Patchwork|Lazarus Group|Dust Storm|admin@338|Turla|Ke3chang"
+"T1082","System Information Discovery","Discovery","TeamTNT|APT38|APT29|Mustang Panda|Windshift|ZIRCONIUM|Higaisa|Windigo|Sidewinder|UNC2452|Chimera|Operation Wocao|Wizard Spider|Rocke|Sandworm Team|Blue Mockingbird|Tropic Trooper|Frankenstein|Inception|Kimsuky|Darkhotel|MuddyWater|APT18|APT32|APT37|Honeybee|APT19|Magic Hound|Sowbug|OilRig|APT3|Gamaredon Group|Patchwork|Stealth Falcon|Lazarus Group|admin@338|Turla|Ke3chang"
+"T1080","Taint Shared Content","Lateral Movement","Gamaredon Group|BRONZE BUTLER|Darkhotel"
+"T1078","Valid Accounts","Defense Evasion|Persistence|Privilege Escalation|Initial Access","FIN7|Leviathan|APT29|Silent Librarian|UNC2452|Fox Kitten|Operation Wocao|Chimera|Sandworm Team|Wizard Spider|Silence|APT41|GALLIUM|TEMP.Veles|APT39|FIN4|Night Dragon|Dragonfly 2.0|FIN8|APT33|FIN5|OilRig|APT28|menuPass|FIN10|Suckfly|FIN6|Threat Group-3390|APT18|PittyTiger|Carbanak"
+"T1074","Data Staged","Collection","Wizard Spider"
+"T1072","Software Deployment Tools","Execution|Lateral Movement","Silence|APT32|Threat Group-1314"
+"T1071","Application Layer Protocol","Command And Control","TeamTNT|Rocke|Magic Hound|Dragonfly 2.0"
+"T1070","Indicator Removal on Host","Defense Evasion","APT29|UNC2452"
+"T1069","Permission Groups Discovery","Discovery","APT29|UNC2452|TA505|APT3"
+"T1068","Exploitation for Privilege Escalation","Privilege Escalation","Tonto Team|ZIRCONIUM|Turla|Whitefly|APT33|Cobalt Group|PLATINUM|FIN8|APT32|Threat Group-3390|FIN6|APT28"
+"T1064","Scripting","Defense Evasion|Execution","no"
+"T1062","Hypervisor","Persistence","no"
+"T1061","Graphical User Interface","Execution","no"
+"T1059","Command and Scripting Interpreter","Execution","APT37|Windigo|Fox Kitten|APT32|Whitefly|APT39|Dragonfly 2.0|FIN7|APT19|OilRig|FIN5|Stealth Falcon|FIN6|Ke3chang"
+"T1057","Process Discovery","Discovery","TeamTNT|Andariel|APT29|Mustang Panda|Windshift|Higaisa|Sidewinder|Chimera|UNC2452|Operation Wocao|Rocke|Frankenstein|Inception|Darkhotel|MuddyWater|APT1|APT38|Tropic Trooper|APT37|Honeybee|OilRig|APT3|Magic Hound|APT28|Winnti Group|Stealth Falcon|Poseidon Group|Lazarus Group|Molerats|Turla|Deep Panda|Ke3chang"
+"T1056","Input Capture","Collection|Credential Access","APT39"
+"T1055","Process Injection","Defense Evasion|Privilege Escalation","Operation Wocao|APT32|Sharpshooter|Silence|APT41|Kimsuky|Cobalt Group|Turla|APT37|Honeybee|PLATINUM"
+"T1053","Scheduled Task/Job","Execution|Persistence|Privilege Escalation","no"
+"T1052","Exfiltration Over Physical Medium","Exfiltration","no"
+"T1051","Shared Webroot","Lateral Movement","no"
+"T1049","System Network Connections Discovery","Discovery","TeamTNT|Andariel|BackdoorDiplomacy|Mustang Panda|MuddyWater|Chimera|Sandworm Team|Operation Wocao|Tropic Trooper|APT41|APT38|GALLIUM|APT32|APT1|OilRig|APT3|menuPass|Threat Group-3390|Poseidon Group|admin@338|Turla|Ke3chang"
+"T1048","Exfiltration Over Alternative Protocol","Exfiltration","no"
+"T1047","Windows Management Instrumentation","Execution","Sandworm Team|FIN7|Indrik Spider|Naikon|Mustang Panda|Windshift|UNC2452|Operation Wocao|Chimera|Blue Mockingbird|Wizard Spider|Frankenstein|APT41|FIN6|GALLIUM|APT32|MuddyWater|Threat Group-3390|OilRig|FIN8|Leviathan|menuPass|Stealth Falcon|Lazarus Group|APT29|Deep Panda"
+"T1046","Network Service Scanning","Discovery","TeamTNT|BackdoorDiplomacy|Naikon|CostaRicto|Chimera|Fox Kitten|Operation Wocao|Rocke|DarkVishnya|APT41|Tropic Trooper|APT39|APT32|OilRig|Cobalt Group|Leafminer|menuPass|Suckfly|FIN6|Threat Group-3390"
+"T1043","Commonly Used Port","Command And Control","OilRig|APT28|TEMP.Veles|Night Dragon|APT29|APT18|FIN7|APT19|Dragonfly 2.0|FIN8|APT37|APT3|Magic Hound|Lazarus Group|Threat Group-3390"
+"T1041","Exfiltration Over C2 Channel","Exfiltration","Leviathan|ZIRCONIUM|Higaisa|Chimera|APT39|Operation Wocao|Sandworm Team|MuddyWater|Wizard Spider|Frankenstein|Kimsuky|GALLIUM|APT32|APT3|Gamaredon Group|Stealth Falcon|Lazarus Group|Ke3chang"
+"T1040","Network Sniffing","Credential Access|Discovery","Kimsuky|Sandworm Team|DarkVishnya|APT33|Stolen Pencil|APT28"
+"T1039","Data from Network Shared Drive","Collection","APT28|Chimera|Fox Kitten|Gamaredon Group|BRONZE BUTLER|Sowbug|menuPass"
+"T1037","Boot or Logon Initialization Scripts","Persistence|Privilege Escalation","Rocke"
+"T1036","Masquerading","Defense Evasion","APT28|Nomadic Octopus|OilRig|APT29|ZIRCONIUM|TA551|UNC2452|Windshift|APT32|BRONZE BUTLER|menuPass|PLATINUM|Dragonfly 2.0"
+"T1034","Path Interception","Persistence|Privilege Escalation","no"
+"T1033","System Owner/User Discovery","Discovery","APT38|Windshift|ZIRCONIUM|Sidewinder|Chimera|Sandworm Team|Operation Wocao|Wizard Spider|Frankenstein|APT41|GALLIUM|Tropic Trooper|APT39|MuddyWater|APT37|Dragonfly 2.0|APT19|APT32|Magic Hound|OilRig|FIN10|Gamaredon Group|Patchwork|Stealth Falcon|Lazarus Group|APT3"
+"T1030","Data Transfer Size Limits","Exfiltration","APT28|Threat Group-3390"
+"T1029","Scheduled Transfer","Exfiltration","Higaisa"
+"T1027","Obfuscated Files or Information","Defense Evasion","TeamTNT|BackdoorDiplomacy|Transparent Tribe|APT39|Mustang Panda|Windshift|TA551|Higaisa|Sidewinder|UNC2452|Fox Kitten|GOLD SOUTHFIELD|Operation Wocao|Kimsuky|FIN6|Chimera|Gamaredon Group|Rocke|Sandworm Team|Blue Mockingbird|Whitefly|Molerats|Wizard Spider|Mofang|Frankenstein|Inception|APT-C-36|APT41|GALLIUM|Turla|TA505|Silence|APT33|Night Dragon|Darkhotel|Gallmaker|APT29|APT18|Tropic Trooper|Patchwork|menuPass|APT37|Threat Group-3390|Cobalt Group|Dark Caracal|Leafminer|Honeybee|APT19|BlackOasis|Leviathan|FIN8|MuddyWater|FIN7|Elderwood|OilRig|Magic Hound|APT3|APT32|Group5|Dust Storm|Lazarus Group|Putter Panda|APT28"
+"T1026","Multiband Communication","Command And Control","Lazarus Group"
+"T1025","Data from Removable Media","Collection","Turla|Gamaredon Group|APT28"
+"T1021","Remote Services","Lateral Movement","no"
+"T1020","Automated Exfiltration","Exfiltration","Sidewinder|Gamaredon Group|Tropic Trooper|Frankenstein|Honeybee"
+"T1018","Remote System Discovery","Discovery","Indrik Spider|Naikon|APT29|UNC2452|Chimera|Fox Kitten|Operation Wocao|Sandworm Team|Rocke|Wizard Spider|Silence|GALLIUM|APT39|APT32|Deep Panda|Ke3chang|Threat Group-3390|Dragonfly 2.0|Leafminer|FIN8|FIN5|APT3|BRONZE BUTLER|menuPass|FIN6|Turla"
+"T1016","System Network Configuration Discovery","Discovery","TeamTNT|ZIRCONIUM|Mustang Panda|Higaisa|Sidewinder|Chimera|Operation Wocao|Wizard Spider|Sandworm Team|Tropic Trooper|Frankenstein|APT41|GALLIUM|APT32|Darkhotel|MuddyWater|APT1|APT19|Dragonfly 2.0|Magic Hound|OilRig|Threat Group-3390|menuPass|Stealth Falcon|Lazarus Group|APT3|Naikon|admin@338|Turla|Ke3chang"
+"T1014","Rootkit","Defense Evasion","TeamTNT|Rocke|APT41|APT28|Winnti Group"
+"T1012","Query Registry","Discovery","ZIRCONIUM|Chimera|Fox Kitten|APT39|Operation Wocao|APT32|Dragonfly 2.0|Threat Group-3390|OilRig|Stealth Falcon|Lazarus Group|Turla"
+"T1011","Exfiltration Over Other Network Medium","Exfiltration","no"
+"T1010","Application Window Discovery","Discovery","Lazarus Group"
+"T1008","Fallback Channels","Command And Control","FIN7|APT41|OilRig|Lazarus Group"
+"T1007","System Service Discovery","Discovery","Indrik Spider|Chimera|Operation Wocao|BRONZE BUTLER|APT1|OilRig|Poseidon Group|admin@338|Turla|Ke3chang"
+"T1006","Direct Volume Access","Defense Evasion","no"
+"T1005","Data from Local System","Collection","FIN7|APT41|APT38|Andariel|APT29|Windigo|UNC2452|Fox Kitten|Sandworm Team|Operation Wocao|FIN6|Gamaredon Group|APT39|Frankenstein|Inception|Kimsuky|GALLIUM|Turla|menuPass|Dark Caracal|Dragonfly 2.0|Honeybee|APT37|APT28|APT3|BRONZE BUTLER|Patchwork|Stealth Falcon|Lazarus Group|Dust Storm|Threat Group-3390|APT1|Ke3chang"
+"T1003","OS Credential Dumping","Credential Access","Tonto Team|APT39|Frankenstein|APT32|APT28|Leviathan|Sowbug|Suckfly|Poseidon Group|Axiom"
+"T1001","Data Obfuscation","Command And Control","Operation Wocao|Axiom"
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/test_obj_to_conf_adapter.py b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/test_obj_to_conf_adapter.py
new file mode 100644
index 0000000000..a41e90a3f0
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/adapter/test_obj_to_conf_adapter.py
@@ -0,0 +1,106 @@
+import os
+import datetime
+import pytest
+import filecmp
+
+from contentctl_infrastructure.contentctl_infrastructure.adapter.obj_to_conf_adapter import ObjToConfAdapter
+from contentctl_infrastructure.contentctl_infrastructure.builder.security_content_director import SecurityContentDirector
+from contentctl_infrastructure.contentctl_infrastructure.builder.security_content_basic_builder import SecurityContentBasicBuilder
+from contentctl_infrastructure.contentctl_infrastructure.builder.security_content_detection_builder import SecurityContentDetectionBuilder
+from contentctl_infrastructure.contentctl_infrastructure.builder.security_content_story_builder import SecurityContentStoryBuilder
+from contentctl.contentctl.domain.entities.enums.enums import SecurityContentProduct
+from contentctl_infrastructure.contentctl_infrastructure.builder.security_content_investigation_builder import SecurityContentInvestigationBuilder
+from contentctl_infrastructure.contentctl_infrastructure.builder.security_content_baseline_builder import SecurityContentBaselineBuilder
+
+
+FAKE_TIME = datetime.datetime(2020, 12, 25, 17, 5, 55)
+
+@pytest.fixture
+def patch_datetime_now(monkeypatch):
+
+ class mydatetime():
+ @classmethod
+ def utcnow(cls):
+ return FAKE_TIME
+
+ monkeypatch.setattr(datetime, 'datetime', mydatetime)
+
+
+def test_write_conf_files(patch_datetime_now):
+ director = SecurityContentDirector()
+
+ lookup_builder = SecurityContentBasicBuilder()
+ director.constructLookup(lookup_builder, os.path.join(os.path.dirname(__file__),
+ '../builder/test_data/lookups/previously_seen_aws_regions.yml'))
+ lookup = lookup_builder.getObject()
+
+ macro_builder = SecurityContentBasicBuilder()
+ director.constructMacro(macro_builder, os.path.join(os.path.dirname(__file__),
+ '../builder/test_data/macro/security_content_ctime.yml'))
+ macro = macro_builder.getObject()
+
+ deployment_builder = SecurityContentBasicBuilder()
+ director.constructDeployment(deployment_builder, os.path.join(os.path.dirname(__file__),
+ '../builder/test_data/deployment/ESCU/00_default_ttp.yml'))
+ deployment = deployment_builder.getObject()
+
+ director.constructDeployment(deployment_builder, os.path.join(os.path.dirname(__file__),
+ '../builder/test_data/deployment/ESCU/00_default_baseline.yml'))
+ deployment_baseline = deployment_builder.getObject()
+
+ playbook_builder = SecurityContentBasicBuilder()
+ director.constructPlaybook(playbook_builder, os.path.join(os.path.dirname(__file__),
+ '../builder/test_data/playbook/example_playbook.yml'))
+ playbook = playbook_builder.getObject()
+
+ baseline_builder = SecurityContentBaselineBuilder()
+ director.constructBaseline(baseline_builder, os.path.join(os.path.dirname(__file__),
+ '../builder/test_data/baseline/baseline.yml'), [deployment_baseline])
+ baseline = baseline_builder.getObject()
+
+ detection_builder = SecurityContentDetectionBuilder()
+ director.constructDetection(detection_builder, os.path.join(os.path.dirname(__file__),
+ '../builder/test_data/detection/valid.yml'), [deployment], [playbook], [baseline])
+ detection = detection_builder.getObject()
+
+ director.constructDetection(detection_builder, os.path.join(os.path.dirname(__file__),
+ '../builder/test_data/detection/deprecated/detect_new_user_aws_console_login.yml'), [deployment], [playbook], [baseline])
+ detection_deprecated = detection_builder.getObject()
+
+ investigation_builder = SecurityContentInvestigationBuilder()
+ director.constructInvestigation(investigation_builder, os.path.join(os.path.dirname(__file__),
+ '../builder/test_data/investigation/investigation.yml'))
+ investigation = investigation_builder.getObject()
+
+ story_builder = SecurityContentStoryBuilder()
+ director.constructStory(story_builder, os.path.join(os.path.dirname(__file__),
+ '../builder/test_data/story/ransomware_darkside.yml'),
+ [detection], [baseline], [investigation])
+ story = story_builder.getObject()
+
+ output_path = os.path.join(os.path.dirname(__file__), 'data')
+ adapter = ObjToConfAdapter()
+ adapter.writeHeaders(output_path)
+ adapter.writeDetections([detection, detection_deprecated], output_path)
+ adapter.writeStories([story], output_path)
+ adapter.writeBaselines([baseline], output_path)
+ adapter.writeInvestigations([investigation], output_path)
+ adapter.writeLookups([lookup], output_path, os.path.join(os.path.dirname(__file__),
+ '../builder/test_data'))
+ adapter.writeMacros([macro], output_path)
+
+ files_to_compare = [
+ 'data/ui/panels/workbench_panel_get_parent_process_info___response_task.xml',
+ 'analyticstories.conf',
+ 'collections.conf',
+ 'es_investigations.conf',
+ 'macros.conf',
+ 'savedsearches.conf',
+ 'transforms.conf',
+ 'workflow_actions.conf'
+ ]
+
+ for file in files_to_compare:
+ path = os.path.join(os.path.dirname(__file__), 'data/default', file)
+ path_ref = os.path.join(os.path.dirname(__file__), 'data/default_reference', file)
+ assert filecmp.cmp(path, path_ref, shallow=False)
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_data/detection/baseline.yml b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_data/baseline/baseline.yml
similarity index 100%
rename from bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_data/detection/baseline.yml
rename to bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_data/baseline/baseline.yml
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_data/baseline/baseline2.yml b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_data/baseline/baseline2.yml
new file mode 100644
index 0000000000..80ed44837c
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_data/baseline/baseline2.yml
@@ -0,0 +1,55 @@
+name: Baseline Of Cloud Instances Launched
+id: b01bd274-f661-4f9c-bd9f-cf23ff6ae0bc
+version: 1
+date: '2020-08-14'
+author: David Dorsey, Splunk
+type: Baseline
+datamodel:
+- Change
+description: This search is used to build a Machine Learning Toolkit (MLTK) model
+ for how many instances are created in the environment. By default, the search uses
+ the last 90 days of data to build the model and the model is rebuilt weekly. The
+ model created by this search is then used in the corresponding detection search,
+ which identifies subsequent outliers in the number of instances created in a small
+ time window.
+search: '| tstats count as instances_launched from datamodel=Change where (All_Changes.action=created)
+ AND All_Changes.status=success AND All_Changes.object_category=instance by _time
+ span=1h | makecontinuous span=1h _time | eval instances_launched=coalesce(instances_launched,
+ (random()%2)*0.0000000001) | eval HourOfDay=strftime(_time, "%H") | eval HourOfDay=floor(HourOfDay/4)*4
+ | eval DayOfWeek=strftime(_time, "%w") | eval isWeekend=if(DayOfWeek >= 1 AND DayOfWeek
+ <= 5, 0, 1) | table _time instances_launched, HourOfDay, isWeekend | fit DensityFunction
+ instances_launched by "HourOfDay,isWeekend" into cloud_excessive_instances_created_v1
+ dist=expon show_density=true'
+how_to_implement: 'You must have Enterprise Security 6.0 or later, if not you will
+ need to verify that the Machine Learning Toolkit (MLTK) version 4.2 or later is
+ installed, along with any required dependencies. Depending on the number of users
+ in your environment, you may also need to adjust the value for max_inputs in the
+ MLTK settings for the DensityFunction algorithm, then ensure that the search completes
+ in a reasonable timeframe. By default, the search builds the model using the past
+ 90 days of data. You can modify the search window to build the model over a longer
+ period of time, which may give you better results. You may also want to periodically
+ re-run this search to rebuild the model with the latest data.\
+
+ More information on the algorithm used in the search can be found at `https://docs.splunk.com/Documentation/MLApp/4.2.0/User/Algorithms#DensityFunction`.'
+known_false_positives: none
+references: []
+tags:
+ analytic_story:
+ - Cloud Cryptomining
+ - Suspicious Cloud Instance Activities
+ - DarkSide Ransomware
+ deployments:
+ - Weekly Model Rebuild 90 Day Lookback
+ detections:
+ - Abnormally High Number Of Cloud Instances Launched
+ product:
+ - Splunk Security Analytics for AWS
+ - Splunk Enterprise
+ - Splunk Enterprise Security
+ - Splunk Cloud
+ required_fields:
+ - _time
+ - All_Changes.action
+ - All_Changes.status
+ - All_Changes.object_category
+ security_domain: network
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_data/deployment/ESCU/00_default_baseline.yml b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_data/deployment/ESCU/00_default_baseline.yml
index 51d9757bd9..10bdc8d357 100644
--- a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_data/deployment/ESCU/00_default_baseline.yml
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_data/deployment/ESCU/00_default_baseline.yml
@@ -10,4 +10,3 @@ scheduling:
schedule_window: auto
tags:
type: Baseline
- product: ESCU
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_data/deployment/ESCU/00_default_ttp.yml b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_data/deployment/ESCU/00_default_ttp.yml
index a46309dcd2..94d690b648 100644
--- a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_data/deployment/ESCU/00_default_ttp.yml
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_data/deployment/ESCU/00_default_ttp.yml
@@ -20,5 +20,4 @@ alert_action:
rba:
enabled: 'true'
tags:
- type: 'TTP'
- product: ESCU
+ type: TTP
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_data/detection/deprecated/detect_new_user_aws_console_login.yml b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_data/detection/deprecated/detect_new_user_aws_console_login.yml
new file mode 100644
index 0000000000..e256cb7c1f
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_data/detection/deprecated/detect_new_user_aws_console_login.yml
@@ -0,0 +1,62 @@
+name: Detect new user AWS Console Login
+id: ada0f478-84a8-4641-a3f3-d82362dffd75
+version: 2
+date: '2020-07-21'
+author: Bhavin Patel, Splunk
+type: TTP
+datamodel: []
+description: This search looks for AWS CloudTrail events wherein a console login event
+ by a user was recorded within the last hour, then compares the event to a lookup
+ file of previously seen users (by ARN values) who have logged into the console.
+ The alert is fired if the user has logged into the console for the first time within
+ the last hour. Deprecated now this search is updated to use the Authentication datamodel.
+search: '`cloudtrail` eventName=ConsoleLogin | rename userIdentity.arn as user | stats
+ earliest(_time) as firstTime latest(_time) as lastTime by user | inputlookup append=t
+ previously_seen_users_console_logins_cloudtrail | stats min(firstTime) as firstTime
+ max(lastTime) as lastTime by user | eval userStatus=if(firstTime >= relative_time(now(),
+ "-70m@m"), "First Time Logging into AWS Console","Previously Seen User") | `security_content_ctime(firstTime)`|`security_content_ctime(lastTime)`|
+ where userStatus ="First Time Logging into AWS Console" | `detect_new_user_aws_console_login_filter`'
+how_to_implement: You must install the AWS App for Splunk (version 5.1.0 or later)
+ and Splunk Add-on for AWS (version 4.4.0 or later), then configure your AWS CloudTrail
+ inputs. Run the "Previously seen users in AWS CloudTrail" support search only once
+ to create a baseline of previously seen IAM users within the last 30 days. Run "Update
+ previously seen users in AWS CloudTrail" hourly (or more frequently depending on
+ how often you run the detection searches) to refresh the baselines.
+known_false_positives: When a legitimate new user logins for the first time, this
+ activity will be detected. Check how old the account is and verify that the user
+ activity is legitimate.
+references: []
+tags:
+ analytic_story:
+ - Suspicious AWS Login Activities
+ asset_type: AWS Instance
+ cis20:
+ - CIS 16
+ confidence: 100
+ context:
+ - Source:Endpoint
+ - Stage:Credential Access
+ impact: 90
+ kill_chain_phases:
+ - Actions on Objectives
+ mitre_attack_id:
+ - T1078.004
+ nist:
+ - DE.DP
+ - DE.AE
+ observable:
+ - name: user
+ type: User
+ role:
+ - Victim
+ product:
+ - Splunk Enterprise
+ - Splunk Enterprise Security
+ - Splunk Cloud
+ message: tbd
+ required_fields:
+ - _time
+ - eventName
+ - userIdentity.arn
+ risk_score: 90
+ security_domain: network
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_data/investigation/investigation.yml b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_data/investigation/investigation.yml
new file mode 100644
index 0000000000..da4318ba76
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_data/investigation/investigation.yml
@@ -0,0 +1,62 @@
+name: Get Parent Process Info
+id: fecf2918-670d-4f1c-872b-3d7317a41bf9
+version: 2
+date: '2019-02-28'
+author: Bhavin Patel, Splunk
+type: Investigation
+datamodel:
+- Endpoint
+description: This search queries the Endpoint data model to give you details about
+ the parent process of a process running on a host which is under investigation.
+ Enter the values of the process name in question and the dest
+search: '| tstats `security_content_summariesonly` count values(Processes.process)
+ as process min(_time) as firstTime max(_time) as lastTime FROM datamodel=Endpoint.Processes
+ by Processes.user Processes.parent_process_name Processes.process_name Processes.dest
+ | `drop_dm_object_name("Processes")` | search parent_process_name= $parent_process_name$
+ |search dest = $dest$ | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`'
+how_to_implement: You must be ingesting endpoint data that tracks process activity,
+ including parent-child relationships from your endpoints to populate the Endpoint
+ data model in the Processes node. The command-line arguments are mapped to the "process"
+ field in the Endpoint data model.
+known_false_positives: ''
+references: []
+tags:
+ analytic_story:
+ - Collection and Staging
+ - Command and Control
+ - DHS Report TA18-074A
+ - Disabling Security Tools
+ - 'Emotet Malware DHS Report TA18-201A '
+ - Hidden Cobra Malware
+ - Lateral Movement
+ - Malicious PowerShell
+ - Monitor for Unauthorized Software
+ - Netsh Abuse
+ - Orangeworm Attack Group
+ - Phishing Payloads
+ - Possible Backdoor Activity Associated With MUDCARP Espionage Campaigns
+ - Prohibited Traffic Allowed or Protocol Mismatch
+ - Ransomware
+ - SamSam Ransomware
+ - Suspicious Command-Line Executions
+ - Suspicious DNS Traffic
+ - Suspicious MSHTA Activity
+ - Suspicious WMI Use
+ - Suspicious Windows Registry Activities
+ - Unusual Processes
+ - Windows Defense Evasion Tactics
+ - Windows File Extension and Association Abuse
+ - Windows Log Manipulation
+ - Windows Persistence Techniques
+ - Windows Privilege Escalation
+ - Windows Service Abuse
+ - DarkSide Ransomware
+ product:
+ - Splunk Phantom
+ required_fields:
+ - _time
+ - Processes.user
+ - Processes.parent_process_name
+ - Processes.process_name
+ - Processes.dest
+ security_domain: endpoint
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_data/lookups/attacker_tools.csv b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_data/lookups/attacker_tools.csv
new file mode 100644
index 0000000000..2f95dfb054
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_data/lookups/attacker_tools.csv
@@ -0,0 +1,27 @@
+attacker_tool_names,description
+remcom.exe,This process is an open source replacement to psexec and is not typically seen in an enterprise environment.
+pwdump.exe,This process is associated with a tool used to dump password hashes on a Windows system.
+pwdump2.exe,This process is associated with a tool used to dump password hashes on a Windows system.
+nc.exe,This process is an open source tool used for network communications.
+wce.exe,This process is associated with a tool used to dump hashes and execute pass-the-hash and pass-the-ticket attacks.
+cain.exe,This process is associated with a tool used to collect user credentials and execute attacks.
+nmap.exe,This process is an open source network mapping tool used to identify hosts and listening services on a network.
+kidlogger.exe,This process is associated with a tool used to collect keyboard input on a host.
+isass.exe,This process name is used by attackers to hide in plain sight and look like a legitimate Windows system process.
+svch0st.exe,This process name is used by attackers to hide in plain sight and look like a legitimate Windows system process.
+at.exe,This process is used to schedule other processes to run. schtasks.exe should be used instead as it provides more flexibility.
+getmail.exe,This process is seen to be used by attackers to extract email files from host machines.
+ntdll.exe,This process was identified as malicious by DHS Alert TA18-074A.
+netpass.exe,This process was identified as malicious by DHS Alert TA18-201A and attackers use this tool to recover all network passwords stored on your system for the current logged-on user.
+WebBrowserPassView.exe,This process was identified as malicious by DHS Alert TA18-201A and is used by attackers as a password recovery tool that reveals the passwords stored in Web Browsers.
+OutlookAddressBookView.exe,This process was identified as malicious by DHS Alert TA18-201A and is used by attackers to steal the details of all recipients stored in the address books of Microsoft Outlook.
+mailpv.exe,This process was identified by DHS Alert TA18-201A and attackers use this tool is a password-recovery tool that reveals the passwords and other account details from various email clients.
+NLBrute.exe,A RDP brute force tool found in botnets for further expansion and and acquisition of targets. This process was identified in the SamSam Ransomware Campaign and attackers use this tool to brute force RDP instances with a range of commonly used passwords.
+selfdel.exe,This executable was delivered in the SamSam Ransomware Campain and the attackers levereged this binary to delete its malicilous activities.
+masscan.exe,This executable was delivered in the XMRig Crypto Miner
+Massscan_GUI.exe,This executable was delivered in the XMRig Crypto Miner
+KPortScan3.exe,This executable was delivered in the XMRig Crypto Miner and is commonly used by attackers to scan the internet
+NLAChecker.exe,A scanner tool that checks for Windows hosts for Network Level Authentication. This tool allows attackers to detect Windows Servers with RDP without NLA enabled which facilitates the use of brute force non microsoft rdp tools or exploits
+ns.exe,A commonly used tool used by attackers to scan and map file shares
+SilverBullet.exe,Malware was discovered in our monitoring of honey pots that abuses this open source software for scanning and connecting to hosts.
+kportscan3.exe, KPortScan 3.0 is a widely used port scanning tool on Hacking Forums, to perform network scanning on the internal networks.
\ No newline at end of file
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_data/lookups/mitre_enrichment.csv b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_data/lookups/mitre_enrichment.csv
new file mode 100644
index 0000000000..749099c77b
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_data/lookups/mitre_enrichment.csv
@@ -0,0 +1,579 @@
+"mitre_id","technique","tactics","groups"
+"T1564.009","Resource Forking","Defense Evasion","no"
+"T1562.010","Downgrade Attack","Defense Evasion","no"
+"T1547.015","Login Items","Persistence|Privilege Escalation","no"
+"T1620","Reflective Code Loading","Defense Evasion","no"
+"T1619","Cloud Storage Object Discovery","Discovery","no"
+"T1218.014","MMC","Defense Evasion","no"
+"T1218.013","Mavinject","Defense Evasion","no"
+"T1614.001","System Language Discovery","Discovery","no"
+"T1615","Group Policy Discovery","Discovery","Turla"
+"T1036.007","Double File Extension","Defense Evasion","Mustang Panda"
+"T1562.009","Safe Mode Boot","Defense Evasion","no"
+"T1564.008","Email Hiding Rules","Defense Evasion","FIN4"
+"T1505.004","IIS Components","Persistence","no"
+"T1027.006","HTML Smuggling","Defense Evasion","no"
+"T1213.003","Code Repositories","Collection","APT29"
+"T1553.006","Code Signing Policy Modification","Defense Evasion","Turla|APT39"
+"T1614","System Location Discovery","Discovery","no"
+"T1613","Container and Resource Discovery","Discovery","TeamTNT"
+"T1552.007","Container API","Credential Access","no"
+"T1612","Build Image on Host","Defense Evasion","no"
+"T1611","Escape to Host","Privilege Escalation","TeamTNT"
+"T1204.003","Malicious Image","Execution","TeamTNT"
+"T1053.007","Container Orchestration Job","Execution|Persistence|Privilege Escalation","no"
+"T1610","Deploy Container","Defense Evasion|Execution","TeamTNT"
+"T1609","Container Administration Command","Execution","TeamTNT"
+"T1608.005","Link Target","Resource Development","Silent Librarian"
+"T1608.004","Drive-by Target","Resource Development","Transparent Tribe|APT32|Threat Group-3390"
+"T1608.003","Install Digital Certificate","Resource Development","no"
+"T1608.002","Upload Tool","Resource Development","Threat Group-3390"
+"T1608.001","Upload Malware","Resource Development","TeamTNT|APT32"
+"T1608","Stage Capabilities","Resource Development","no"
+"T1016.001","Internet Connection Discovery","Discovery","APT29|UNC2452|Turla"
+"T1553.005","Mark-of-the-Web Bypass","Defense Evasion","TA505"
+"T1555.005","Password Managers","Credential Access","Fox Kitten|Operation Wocao"
+"T1484.002","Domain Trust Modification","Defense Evasion|Privilege Escalation","APT29|UNC2452"
+"T1484.001","Group Policy Modification","Defense Evasion|Privilege Escalation","Indrik Spider"
+"T1547.014","Active Setup","Persistence|Privilege Escalation","no"
+"T1606.002","SAML Tokens","Credential Access","APT29|UNC2452"
+"T1606.001","Web Cookies","Credential Access","APT29|UNC2452"
+"T1606","Forge Web Credentials","Credential Access","no"
+"T1555.004","Windows Credential Manager","Credential Access","Stealth Falcon|OilRig|Turla"
+"T1059.008","Network Device CLI","Execution","no"
+"T1602.002","Network Device Configuration Dump","Collection","no"
+"T1542.005","TFTP Boot","Defense Evasion|Persistence","no"
+"T1542.004","ROMMONkit","Defense Evasion|Persistence","no"
+"T1602.001","SNMP (MIB Dump)","Collection","no"
+"T1602","Data from Configuration Repository","Collection","no"
+"T1601.002","Downgrade System Image","Defense Evasion","no"
+"T1601.001","Patch System Image","Defense Evasion","no"
+"T1601","Modify System Image","Defense Evasion","no"
+"T1600.002","Disable Crypto Hardware","Defense Evasion","no"
+"T1600.001","Reduce Key Space","Defense Evasion","no"
+"T1600","Weaken Encryption","Defense Evasion","no"
+"T1556.004","Network Device Authentication","Credential Access|Defense Evasion|Persistence","no"
+"T1599.001","Network Address Translation Traversal","Defense Evasion","no"
+"T1599","Network Boundary Bridging","Defense Evasion","no"
+"T1020.001","Traffic Duplication","Exfiltration","no"
+"T1557.002","ARP Cache Poisoning","Credential Access|Collection","Cleaver"
+"T1588.006","Vulnerabilities","Resource Development","Sandworm Team"
+"T1053.006","Systemd Timers","Execution|Persistence|Privilege Escalation","no"
+"T1562.008","Disable Cloud Logs","Defense Evasion","no"
+"T1547.012","Print Processors","Persistence|Privilege Escalation","no"
+"T1598.003","Spearphishing Link","Reconnaissance","Magic Hound|Silent Librarian|Sidewinder|Sandworm Team|APT32|Kimsuky"
+"T1598.002","Spearphishing Attachment","Reconnaissance","Sidewinder"
+"T1598.001","Spearphishing Service","Reconnaissance","no"
+"T1598","Phishing for Information","Reconnaissance","ZIRCONIUM|APT28"
+"T1597.002","Purchase Technical Data","Reconnaissance","no"
+"T1597.001","Threat Intel Vendors","Reconnaissance","no"
+"T1597","Search Closed Sources","Reconnaissance","no"
+"T1596.005","Scan Databases","Reconnaissance","no"
+"T1596.004","CDNs","Reconnaissance","no"
+"T1596.003","Digital Certificates","Reconnaissance","no"
+"T1596.001","DNS/Passive DNS","Reconnaissance","no"
+"T1596.002","WHOIS","Reconnaissance","no"
+"T1596","Search Open Technical Databases","Reconnaissance","no"
+"T1595.002","Vulnerability Scanning","Reconnaissance","TeamTNT|APT29|Volatile Cedar|APT28|Sandworm Team"
+"T1595.001","Scanning IP Blocks","Reconnaissance","TeamTNT"
+"T1595","Active Scanning","Reconnaissance","no"
+"T1594","Search Victim-Owned Websites","Reconnaissance","Silent Librarian|Sandworm Team"
+"T1593.002","Search Engines","Reconnaissance","no"
+"T1593.001","Social Media","Reconnaissance","Kimsuky"
+"T1593","Search Open Websites/Domains","Reconnaissance","Sandworm Team"
+"T1592.004","Client Configurations","Reconnaissance","HAFNIUM"
+"T1592.003","Firmware","Reconnaissance","no"
+"T1592.002","Software","Reconnaissance","Andariel|Sandworm Team"
+"T1592.001","Hardware","Reconnaissance","no"
+"T1592","Gather Victim Host Information","Reconnaissance","no"
+"T1591.004","Identify Roles","Reconnaissance","no"
+"T1591.003","Identify Business Tempo","Reconnaissance","no"
+"T1591.001","Determine Physical Locations","Reconnaissance","no"
+"T1591.002","Business Relationships","Reconnaissance","Sandworm Team"
+"T1591","Gather Victim Org Information","Reconnaissance","no"
+"T1590.006","Network Security Appliances","Reconnaissance","no"
+"T1590.005","IP Addresses","Reconnaissance","Andariel|HAFNIUM"
+"T1590.004","Network Topology","Reconnaissance","no"
+"T1590.003","Network Trust Dependencies","Reconnaissance","no"
+"T1590.002","DNS","Reconnaissance","no"
+"T1590.001","Domain Properties","Reconnaissance","Sandworm Team"
+"T1590","Gather Victim Network Information","Reconnaissance","HAFNIUM"
+"T1589.003","Employee Names","Reconnaissance","Silent Librarian|Sandworm Team"
+"T1589.002","Email Addresses","Reconnaissance","Kimsuky|Magic Hound|TA551|MuddyWater|HAFNIUM|APT32|Silent Librarian|Sandworm Team"
+"T1589.001","Credentials","Reconnaissance","Leviathan|APT28|Magic Hound|Chimera"
+"T1589","Gather Victim Identity Information","Reconnaissance","Magic Hound|APT32"
+"T1588.005","Exploits","Resource Development","no"
+"T1588.004","Digital Certificates","Resource Development","Lazarus Group|Silent Librarian"
+"T1588.003","Code Signing Certificates","Resource Development","Wizard Spider"
+"T1588.002","Tool","Resource Development","CostaRicto|Night Dragon|DarkVishnya|FIN5|Gorgon Group|Patchwork|Chimera|Dragonfly|Blue Mockingbird|Whitefly|APT41|FIN6|TEMP.Veles|Kimsuky|PittyTiger|Cobalt Group|APT29|Thrip|Ke3chang|DarkHydrus|APT32|APT38|BRONZE BUTLER|Carbanak|Cleaver|Inception|Leafminer|Threat Group-3390|Ferocious Kitten|IndigoZebra|BackdoorDiplomacy|menuPass|APT-C-36|Magic Hound|APT28|Wizard Spider|Frankenstein|Silence|WIRTE|Turla|APT33|APT19|FIN10|CopyKittens|APT39|APT1|MuddyWater|Silent Librarian|GALLIUM|Sandworm Team"
+"T1588.001","Malware","Resource Development","Andariel|BackdoorDiplomacy|Turla|APT1"
+"T1588","Obtain Capabilities","Resource Development","no"
+"T1587.004","Exploits","Resource Development","no"
+"T1587.003","Digital Certificates","Resource Development","APT29|PROMETHIUM"
+"T1587.002","Code Signing Certificates","Resource Development","PROMETHIUM|Patchwork"
+"T1587.001","Malware","Resource Development","TeamTNT|APT29|Lazarus Group|UNC2452|Sandworm Team|Turla|FIN7|Night Dragon|Cleaver"
+"T1587","Develop Capabilities","Resource Development","Kimsuky"
+"T1586.002","Email Accounts","Resource Development","IndigoZebra|Leviathan|Magic Hound|Kimsuky"
+"T1586.001","Social Media Accounts","Resource Development","Leviathan"
+"T1586","Compromise Accounts","Resource Development","no"
+"T1585.002","Email Accounts","Resource Development","Leviathan|Magic Hound|Silent Librarian|Sandworm Team|APT1"
+"T1585.001","Social Media Accounts","Resource Development","Leviathan|Magic Hound|Fox Kitten|Sandworm Team|APT32|Cleaver"
+"T1585","Establish Accounts","Resource Development","Fox Kitten|APT17"
+"T1584.006","Web Services","Resource Development","Turla"
+"T1584.005","Botnet","Resource Development","no"
+"T1584.004","Server","Resource Development","Indrik Spider|Turla|APT16"
+"T1584.003","Virtual Private Server","Resource Development","Turla"
+"T1584.002","DNS Server","Resource Development","no"
+"T1584.001","Domains","Resource Development","Transparent Tribe|Magic Hound|APT29|UNC2452|APT1"
+"T1583.006","Web Services","Resource Development","IndigoZebra|ZIRCONIUM|MuddyWater|HAFNIUM|Lazarus Group|Turla|APT32|APT17|APT29"
+"T1583.005","Botnet","Resource Development","no"
+"T1583.004","Server","Resource Development","GALLIUM|Sandworm Team"
+"T1583.003","Virtual Private Server","Resource Development","HAFNIUM|TEMP.Veles"
+"T1583.002","DNS Server","Resource Development","no"
+"T1584","Compromise Infrastructure","Resource Development","no"
+"T1583.001","Domains","Resource Development","IndigoZebra|TeamTNT|Ferocious Kitten|FIN7|Transparent Tribe|Leviathan|Magic Hound|APT29|Mustang Panda|ZIRCONIUM|UNC2452|Lazarus Group|Silent Librarian|menuPass|Sandworm Team|APT32|Kimsuky|APT1|APT28"
+"T1583","Acquire Infrastructure","Resource Development","no"
+"T1564.007","VBA Stomping","Defense Evasion","no"
+"T1558.004","AS-REP Roasting","Credential Access","no"
+"T1580","Cloud Infrastructure Discovery","Discovery","no"
+"T1218.012","Verclsid","Defense Evasion","no"
+"T1205.001","Port Knocking","Defense Evasion|Persistence|Command And Control","PROMETHIUM"
+"T1564.006","Run Virtual Instance","Defense Evasion","no"
+"T1564.005","Hidden File System","Defense Evasion","Strider|Equation"
+"T1556.003","Pluggable Authentication Modules","Credential Access|Defense Evasion|Persistence","no"
+"T1574.012","COR_PROFILER","Persistence|Privilege Escalation|Defense Evasion","Blue Mockingbird"
+"T1562.007","Disable or Modify Cloud Firewall","Defense Evasion","no"
+"T1098.004","SSH Authorized Keys","Persistence","TeamTNT"
+"T1480.001","Environmental Keying","Defense Evasion","APT41|Equation"
+"T1059.007","JavaScript","Execution","Indrik Spider|MuddyWater|Turla|Higaisa|Sidewinder|Evilnum|Kimsuky|FIN6|APT32|FIN7|Cobalt Group|Molerats|TA505|Silence|Leafminer"
+"T1578.004","Revert Cloud Instance","Defense Evasion","no"
+"T1578.003","Delete Cloud Instance","Defense Evasion","no"
+"T1578.001","Create Snapshot","Defense Evasion","no"
+"T1578.002","Create Cloud Instance","Defense Evasion","no"
+"T1127.001","MSBuild","Defense Evasion","Frankenstein"
+"T1027.005","Indicator Removal from Tools","Defense Evasion","Operation Wocao|GALLIUM|TEMP.Veles|Patchwork|APT3|Turla|OilRig|Deep Panda"
+"T1562.006","Indicator Blocking","Defense Evasion","no"
+"T1573.002","Asymmetric Cryptography","Command And Control","Operation Wocao|Tropic Trooper|Cobalt Group|OilRig|FIN8|FIN6"
+"T1573.001","Symmetric Cryptography","Command And Control","Mustang Panda|Darkhotel|ZIRCONIUM|Higaisa|Frankenstein|Inception|APT28|APT33|BRONZE BUTLER|Stealth Falcon|Lazarus Group"
+"T1573","Encrypted Channel","Command And Control","Tropic Trooper"
+"T1027.004","Compile After Delivery","Defense Evasion","Gamaredon Group|Rocke|MuddyWater"
+"T1574.004","Dylib Hijacking","Persistence|Privilege Escalation|Defense Evasion","no"
+"T1546.015","Component Object Model Hijacking","Privilege Escalation|Persistence","APT28"
+"T1071.004","DNS","Command And Control","Chimera|APT39|Tropic Trooper|OilRig|Ke3chang|Cobalt Group|APT18|APT41|FIN7"
+"T1071.003","Mail Protocols","Command And Control","Turla|Kimsuky|APT32|SilverTerrier|APT28"
+"T1071.002","File Transfer Protocols","Command And Control","Kimsuky|APT41|SilverTerrier|Honeybee"
+"T1071.001","Web Protocols","Command And Control","TeamTNT|FIN8|APT29|Mustang Panda|Windshift|TA551|Higaisa|HAFNIUM|Sidewinder|Chimera|UNC2452|Sandworm Team|TA505|Rocke|APT39|Tropic Trooper|MuddyWater|Wizard Spider|Inception|APT41|SilverTerrier|APT28|WIRTE|APT33|FIN4|Night Dragon|APT18|APT38|Rancor|Ke3chang|Orangeworm|APT37|APT19|Cobalt Group|Threat Group-3390|Dark Caracal|Turla|Lazarus Group|BRONZE BUTLER|Magic Hound|APT32|OilRig|Gamaredon Group|Stealth Falcon"
+"T1572","Protocol Tunneling","Command And Control","Leviathan|CostaRicto|Chimera|Fox Kitten|OilRig|Cobalt Group|FIN6"
+"T1048.003","Exfiltration Over Unencrypted/Obfuscated Non-C2 Protocol","Exfiltration","Wizard Spider|FIN6|APT32|APT33|Thrip|FIN8|OilRig|Lazarus Group"
+"T1048.002","Exfiltration Over Asymmetric Encrypted Non-C2 Protocol","Exfiltration","APT28|APT29|UNC2452"
+"T1048.001","Exfiltration Over Symmetric Encrypted Non-C2 Protocol","Exfiltration","no"
+"T1001.003","Protocol Impersonation","Command And Control","Higaisa|Lazarus Group"
+"T1001.002","Steganography","Command And Control","APT29|Axiom"
+"T1001.001","Junk Data","Command And Control","APT28"
+"T1132.002","Non-Standard Encoding","Command And Control","no"
+"T1132.001","Standard Encoding","Command And Control","HAFNIUM|TA551|Sandworm Team|Tropic Trooper|MuddyWater|APT33|APT19|Lazarus Group|BRONZE BUTLER|Patchwork"
+"T1090.004","Domain Fronting","Command And Control","APT29"
+"T1090.003","Multi-hop Proxy","Command And Control","Leviathan|CostaRicto|APT28|Operation Wocao|Inception|FIN4|APT29"
+"T1090.002","External Proxy","Command And Control","Tonto Team|APT39|Silence|GALLIUM|MuddyWater|APT3|FIN5|Lazarus Group|menuPass|APT28"
+"T1090.001","Internal Proxy","Command And Control","APT29|Higaisa|UNC2452|Operation Wocao|APT39|Strider"
+"T1102.003","One-Way Communication","Command And Control","Leviathan"
+"T1102.002","Bidirectional Communication","Command And Control","ZIRCONIUM|MuddyWater|APT28|APT29|Sandworm Team|APT39|APT12|Turla|FIN7|APT37|Magic Hound|Carbanak"
+"T1102.001","Dead Drop Resolver","Command And Control","Rocke|APT41|BRONZE BUTLER|RTM|Patchwork"
+"T1571","Non-Standard Port","Command And Control","Sandworm Team|Rocke|DarkVishnya|Silence|APT-C-36|Magic Hound|APT33|APT32|TEMP.Veles|Lazarus Group|FIN7"
+"T1074.002","Remote Data Staging","Collection","Leviathan|APT28|APT29|Chimera|UNC2452|Threat Group-3390|menuPass|FIN6|Night Dragon|FIN8"
+"T1074.001","Local Data Staging","Collection","Indrik Spider|BackdoorDiplomacy|Mustang Panda|Sidewinder|Chimera|Kimsuky|APT39|Operation Wocao|GALLIUM|TEMP.Veles|Patchwork|Honeybee|Dragonfly 2.0|Leviathan|APT3|FIN5|menuPass|Lazarus Group|Threat Group-3390|APT28"
+"T1078.004","Cloud Accounts","Defense Evasion|Persistence|Privilege Escalation|Initial Access","APT28|APT33"
+"T1564.004","NTFS File Attributes","Defense Evasion","APT32"
+"T1564.003","Hidden Window","Defense Evasion","Nomadic Octopus|Higaisa|Gorgon Group|Deep Panda|DarkHydrus|CopyKittens|APT19|APT32|APT28|APT3|Magic Hound"
+"T1078.003","Local Accounts","Defense Evasion|Persistence|Privilege Escalation|Initial Access","Kimsuky|HAFNIUM|Turla|Operation Wocao|PROMETHIUM|Tropic Trooper|FIN10|Stolen Pencil|APT32"
+"T1078.002","Domain Accounts","Defense Evasion|Persistence|Privilege Escalation|Initial Access","Naikon|Indrik Spider|Chimera|Operation Wocao|Sandworm Team|Wizard Spider|APT29|TA505|APT3|Threat Group-1314"
+"T1078.001","Default Accounts","Defense Evasion|Persistence|Privilege Escalation|Initial Access","no"
+"T1564.002","Hidden Users","Defense Evasion","Dragonfly 2.0"
+"T1574.006","Dynamic Linker Hijacking","Persistence|Privilege Escalation|Defense Evasion","APT41|Rocke"
+"T1574.002","DLL Side-Loading","Persistence|Privilege Escalation|Defense Evasion","Mustang Panda|Higaisa|BlackTech|Sidewinder|Chimera|BRONZE BUTLER|Naikon|APT41|GALLIUM|Tropic Trooper|APT19|Patchwork|APT32|APT3|menuPass|Threat Group-3390"
+"T1574.001","DLL Search Order Hijacking","Persistence|Privilege Escalation|Defense Evasion","BackdoorDiplomacy|Tonto Team|Evilnum|APT41|Whitefly|RTM|Threat Group-3390|menuPass"
+"T1574.008","Path Interception by Search Order Hijacking","Persistence|Privilege Escalation|Defense Evasion","no"
+"T1574.007","Path Interception by PATH Environment Variable","Persistence|Privilege Escalation|Defense Evasion","no"
+"T1574.009","Path Interception by Unquoted Path","Persistence|Privilege Escalation|Defense Evasion","no"
+"T1574.011","Services Registry Permissions Weakness","Persistence|Privilege Escalation|Defense Evasion","no"
+"T1574.005","Executable Installer File Permissions Weakness","Persistence|Privilege Escalation|Defense Evasion","no"
+"T1574.010","Services File Permissions Weakness","Persistence|Privilege Escalation|Defense Evasion","no"
+"T1574","Hijack Execution Flow","Persistence|Privilege Escalation|Defense Evasion","no"
+"T1069.001","Local Groups","Discovery","Tonto Team|Chimera|Operation Wocao|Turla|OilRig|admin@338"
+"T1570","Lateral Tool Transfer","Lateral Movement","Sandworm Team|Chimera|GALLIUM|Operation Wocao|APT32|Wizard Spider|Turla|FIN10"
+"T1568.003","DNS Calculation","Command And Control","APT12"
+"T1204.002","Malicious File","Execution","Nomadic Octopus|Indrik Spider|APT38|Andariel|Ferocious Kitten|IndigoZebra|Transparent Tribe|Tonto Team|Magic Hound|Ajax Security Team|Mustang Panda|TA551|Higaisa|Sidewinder|Kimsuky|FIN6|PROMETHIUM|APT30|Windshift|APT33|Sandworm Team|Naikon|Whitefly|Tropic Trooper|Gamaredon Group|Sharpshooter|Molerats|Wizard Spider|Mofang|Frankenstein|RTM|Inception|BlackTech|APT-C-36|Machete|admin@338|APT12|TA505|Silence|The White Company|APT39|FIN4|Darkhotel|Gallmaker|Dragonfly 2.0|FIN7|BRONZE BUTLER|Gorgon Group|OilRig|Dark Caracal|Cobalt Group|DarkHydrus|Rancor|Patchwork|APT32|APT19|MuddyWater|Lazarus Group|menuPass|APT37|Leviathan|TA459|APT29|APT28|FIN8|PLATINUM|Elderwood"
+"T1204.001","Malicious Link","Execution","FIN7|Transparent Tribe|APT3|Magic Hound|APT28|APT29|Mustang Panda|Sidewinder|ZIRCONIUM|MuddyWater|Evilnum|Sandworm Team|Wizard Spider|Patchwork|Windshift|APT32|Molerats|Mofang|BlackTech|TA505|OilRig|Machete|Leviathan|FIN8|FIN4|Elderwood|Dragonfly 2.0|Cobalt Group|APT39|Night Dragon|Turla|APT33"
+"T1195.003","Compromise Hardware Supply Chain","Initial Access","no"
+"T1195.002","Compromise Software Supply Chain","Initial Access","APT29|UNC2452|Cobalt Group|GOLD SOUTHFIELD|Dragonfly|Sandworm Team|APT41"
+"T1195.001","Compromise Software Dependencies and Development Tools","Initial Access","no"
+"T1568.001","Fast Flux DNS","Command And Control","menuPass|TA505"
+"T1052.001","Exfiltration over USB","Exfiltration","Mustang Panda|Tropic Trooper"
+"T1569.002","Service Execution","Execution","APT38|Chimera|Operation Wocao|Wizard Spider|Blue Mockingbird|APT39|APT41|Silence|FIN6|APT32|Honeybee|Ke3chang"
+"T1569.001","Launchctl","Execution","no"
+"T1569","System Services","Execution","no"
+"T1568.002","Domain Generation Algorithms","Command And Control","TA551|APT41"
+"T1568","Dynamic Resolution","Command And Control","Transparent Tribe|APT29|UNC2452"
+"T1011.001","Exfiltration Over Bluetooth","Exfiltration","no"
+"T1567.002","Exfiltration to Cloud Storage","Exfiltration","FIN7|ZIRCONIUM|HAFNIUM|Chimera|Leviathan|Turla"
+"T1567.001","Exfiltration to Code Repository","Exfiltration","no"
+"T1059.006","Python","Execution","Tonto Team|APT37|ZIRCONIUM|MuddyWater|Turla|Operation Wocao|Kimsuky|APT29|Rocke|BRONZE BUTLER|APT39|Dragonfly 2.0|Machete"
+"T1059.005","Visual Basic","Execution","OilRig|APT38|Transparent Tribe|APT29|Mustang Panda|Windshift|Higaisa|Sidewinder|APT39|Machete|Operation Wocao|Kimsuky|APT33|Sandworm Team|Gamaredon Group|Sharpshooter|Molerats|Frankenstein|Inception|APT-C-36|Rancor|Patchwork|MuddyWater|Honeybee|FIN7|APT37|BRONZE BUTLER|APT32|Turla|TA505|Silence|WIRTE|FIN4|Cobalt Group|Gorgon Group|Leviathan|TA459|Magic Hound"
+"T1059.004","Unix Shell","Execution","TeamTNT|Rocke|APT41"
+"T1059.003","Windows Command Shell","Execution","Sandworm Team|Nomadic Octopus|TeamTNT|APT29|Mustang Panda|ZIRCONIUM|TA551|Higaisa|Indrik Spider|Chimera|UNC2452|Fox Kitten|Machete|Operation Wocao|Wizard Spider|FIN6|TA505|Blue Mockingbird|Tropic Trooper|Frankenstein|OilRig|Lazarus Group|Honeybee|Cobalt Group|FIN7|APT41|GALLIUM|Turla|Silence|APT32|Darkhotel|MuddyWater|APT18|APT38|Gorgon Group|Dark Caracal|Ke3chang|Dragonfly 2.0|Rancor|FIN8|APT28|APT37|Magic Hound|BRONZE BUTLER|Sowbug|menuPass|FIN10|Threat Group-3390|Gamaredon Group|Patchwork|Suckfly|Threat Group-1314|APT3|admin@338|APT1"
+"T1059.002","AppleScript","Execution","no"
+"T1059.001","PowerShell","Execution","Nomadic Octopus|TeamTNT|APT38|Tonto Team|Mustang Panda|Indrik Spider|HAFNIUM|Sidewinder|UNC2452|Fox Kitten|GOLD SOUTHFIELD|Sandworm Team|Operation Wocao|Chimera|Blue Mockingbird|APT39|DarkVishnya|Molerats|Wizard Spider|Frankenstein|Inception|Silence|APT41|Kimsuky|GALLIUM|TA505|WIRTE|TEMP.Veles|APT33|Gallmaker|Turla|Thrip|Cobalt Group|APT28|DarkHydrus|Dragonfly 2.0|APT19|Gorgon Group|TA459|Leviathan|MuddyWater|FIN8|CopyKittens|OilRig|Magic Hound|BRONZE BUTLER|FIN7|APT32|menuPass|FIN10|Threat Group-3390|Patchwork|Stealth Falcon|FIN6|Poseidon Group|APT3|APT29|Deep Panda"
+"T1567","Exfiltration Over Web Service","Exfiltration","APT28"
+"T1497.003","Time Based Evasion","Defense Evasion|Discovery","no"
+"T1497.002","User Activity Based Checks","Defense Evasion|Discovery","Darkhotel|FIN7"
+"T1497.001","System Checks","Defense Evasion|Discovery","OilRig|Darkhotel|Evilnum|Frankenstein"
+"T1498.002","Reflection Amplification","Impact","no"
+"T1498.001","Direct Network Flood","Impact","no"
+"T1566.003","Spearphishing via Service","Initial Access","APT29|Ajax Security Team|Magic Hound|Windshift|FIN6|OilRig|Dark Caracal"
+"T1566.002","Spearphishing Link","Initial Access","Transparent Tribe|FIN7|APT3|Mustang Panda|ZIRCONIUM|MuddyWater|Sidewinder|Evilnum|Sandworm Team|Wizard Spider|APT1|Windshift|Molerats|Mofang|BlackTech|Machete|Kimsuky|TA505|Stolen Pencil|APT39|FIN4|APT32|Night Dragon|APT28|Cobalt Group|Turla|Dragonfly 2.0|OilRig|Elderwood|APT33|APT29|Leviathan|FIN8|Patchwork|Magic Hound"
+"T1566.001","Spearphishing Attachment","Initial Access","APT38|Andariel|Ferocious Kitten|IndigoZebra|Transparent Tribe|Nomadic Octopus|Tonto Team|Ajax Security Team|Mustang Panda|TA551|Higaisa|Sidewinder|APT1|FIN6|APT30|Windshift|APT33|Sandworm Team|Naikon|Gamaredon Group|Sharpshooter|Molerats|Mofang|Wizard Spider|RTM|Frankenstein|Inception|BlackTech|APT-C-36|APT41|Machete|admin@338|Kimsuky|APT12|TA505|Silence|The White Company|APT39|FIN4|Darkhotel|Gallmaker|Tropic Trooper|DarkHydrus|Lazarus Group|Gorgon Group|OilRig|BRONZE BUTLER|APT19|APT32|Cobalt Group|Rancor|FIN7|Dragonfly 2.0|MuddyWater|APT28|TA459|APT29|APT37|Leviathan|FIN8|Patchwork|menuPass|Elderwood|PLATINUM"
+"T1566","Phishing","Initial Access","GOLD SOUTHFIELD|Dragonfly"
+"T1565.003","Runtime Data Manipulation","Impact","APT38"
+"T1565.002","Transmitted Data Manipulation","Impact","APT38"
+"T1565.001","Stored Data Manipulation","Impact","APT38"
+"T1565","Data Manipulation","Impact","no"
+"T1564.001","Hidden Files and Directories","Defense Evasion","Transparent Tribe|Mustang Panda|Rocke|APT32|Tropic Trooper|APT28|Lazarus Group"
+"T1564","Hide Artifacts","Defense Evasion","no"
+"T1563.002","RDP Hijacking","Lateral Movement","no"
+"T1563.001","SSH Hijacking","Lateral Movement","no"
+"T1563","Remote Service Session Hijacking","Lateral Movement","no"
+"T1518.001","Security Software Discovery","Discovery","TeamTNT|APT38|Windshift|Sidewinder|Operation Wocao|Wizard Spider|Turla|Rocke|Frankenstein|The White Company|Cobalt Group|Darkhotel|MuddyWater|Tropic Trooper|FIN8|Patchwork|Naikon"
+"T1069.003","Cloud Groups","Discovery","no"
+"T1069.002","Domain Groups","Discovery","Turla|Inception|OilRig|Dragonfly 2.0|Ke3chang"
+"T1087.004","Cloud Account","Discovery","no"
+"T1087.003","Email Account","Discovery","Sandworm Team|TA505"
+"T1087.002","Domain Account","Discovery","MuddyWater|Fox Kitten|Operation Wocao|Wizard Spider|Chimera|Turla|Sandworm Team|Dragonfly 2.0|OilRig|BRONZE BUTLER|menuPass|FIN6|Poseidon Group|Ke3chang"
+"T1087.001","Local Account","Discovery","Chimera|Fox Kitten|Turla|Poseidon Group|OilRig|Ke3chang|APT32|APT1|Threat Group-3390|APT3|admin@338"
+"T1553.004","Install Root Certificate","Defense Evasion","no"
+"T1562.004","Disable or Modify System Firewall","Defense Evasion","TeamTNT|APT38|APT29|UNC2452|Operation Wocao|Rocke|Lazarus Group|Kimsuky|Dragonfly 2.0|Carbanak"
+"T1562.003","Impair Command History Logging","Defense Evasion","APT38"
+"T1562.002","Disable Windows Event Logging","Defense Evasion","Sandworm Team|APT29|UNC2452|Threat Group-3390"
+"T1562.001","Disable or Modify Tools","Defense Evasion","TeamTNT|Indrik Spider|APT29|MuddyWater|UNC2452|Wizard Spider|FIN6|Gamaredon Group|BRONZE BUTLER|Rocke|Kimsuky|Turla|Night Dragon|Gorgon Group|Lazarus Group|Putter Panda"
+"T1562","Impair Defenses","Defense Evasion","no"
+"T1003.004","LSA Secrets","Credential Access","OilRig|MuddyWater|menuPass|Leafminer|Ke3chang|Dragonfly 2.0|APT33|Threat Group-3390"
+"T1003.005","Cached Domain Credentials","Credential Access","OilRig|MuddyWater|Leafminer|APT33"
+"T1561.002","Disk Structure Wipe","Impact","Sandworm Team|Lazarus Group|APT38|APT37"
+"T1561.001","Disk Content Wipe","Impact","Lazarus Group"
+"T1561","Disk Wipe","Impact","no"
+"T1560.003","Archive via Custom Method","Collection","Mustang Panda|Lazarus Group|Kimsuky|CopyKittens|FIN6"
+"T1560.002","Archive via Library","Collection","Lazarus Group|Threat Group-3390"
+"T1560.001","Archive via Utility","Collection","APT28|APT29|Mustang Panda|HAFNIUM|UNC2452|Fox Kitten|Operation Wocao|Chimera|APT41|GALLIUM|Turla|Gallmaker|APT33|APT39|MuddyWater|Magic Hound|FIN8|BRONZE BUTLER|CopyKittens|Sowbug|APT3|menuPass|APT1|Ke3chang"
+"T1560","Archive Collected Data","Collection","Leviathan|menuPass|APT32|Honeybee|Patchwork|APT28|Dragonfly 2.0|FIN6|Lazarus Group|Ke3chang"
+"T1499.004","Application or System Exploitation","Impact","no"
+"T1499.003","Application Exhaustion Flood","Impact","no"
+"T1499.002","Service Exhaustion Flood","Impact","no"
+"T1499.001","OS Exhaustion Flood","Impact","no"
+"T1491.002","External Defacement","Impact","Sandworm Team"
+"T1491.001","Internal Defacement","Impact","Lazarus Group"
+"T1114.003","Email Forwarding Rule","Collection","Silent Librarian|Kimsuky"
+"T1114.002","Remote Email Collection","Collection","APT29|HAFNIUM|Chimera|UNC2452|APT1|FIN4|Ke3chang|Leafminer|Dragonfly 2.0|APT28"
+"T1114.001","Local Email Collection","Collection","Chimera|Magic Hound|APT1"
+"T1134.005","SID-History Injection","Defense Evasion|Privilege Escalation","no"
+"T1134.004","Parent PID Spoofing","Defense Evasion|Privilege Escalation","no"
+"T1134.003","Make and Impersonate Token","Defense Evasion|Privilege Escalation","no"
+"T1134.002","Create Process with Token","Defense Evasion|Privilege Escalation","Turla|Lazarus Group"
+"T1134.001","Token Impersonation/Theft","Defense Evasion|Privilege Escalation","FIN8|APT28"
+"T1213.002","Sharepoint","Collection","Chimera|Ke3chang|APT28"
+"T1213.001","Confluence","Collection","no"
+"T1555.003","Credentials from Web Browsers","Credential Access","Ajax Security Team|ZIRCONIUM|FIN6|Sandworm Team|Inception|Stealth Falcon|OilRig|Leafminer|APT33|APT3|Kimsuky|TA505|Stolen Pencil|MuddyWater|APT37|Patchwork|Molerats"
+"T1555.002","Securityd Memory","Credential Access","no"
+"T1555.001","Keychain","Credential Access","no"
+"T1559.002","Dynamic Data Exchange","Execution","Leviathan|Sidewinder|Sharpshooter|TA505|MuddyWater|Gallmaker|Patchwork|Cobalt Group|APT37|FIN7|APT28"
+"T1559.001","Component Object Model","Execution","Gamaredon Group|MuddyWater"
+"T1559","Inter-Process Communication","Execution","no"
+"T1558.002","Silver Ticket","Credential Access","no"
+"T1558.001","Golden Ticket","Credential Access","Ke3chang"
+"T1558","Steal or Forge Kerberos Tickets","Credential Access","no"
+"T1557.001","LLMNR/NBT-NS Poisoning and SMB Relay","Credential Access|Collection","Wizard Spider"
+"T1557","Adversary-in-the-Middle","Credential Access|Collection","Kimsuky"
+"T1556.002","Password Filter DLL","Credential Access|Defense Evasion|Persistence","Strider"
+"T1556.001","Domain Controller Authentication","Credential Access|Defense Evasion|Persistence","Chimera"
+"T1556","Modify Authentication Process","Credential Access|Defense Evasion|Persistence","no"
+"T1056.004","Credential API Hooking","Collection|Credential Access","PLATINUM"
+"T1056.003","Web Portal Capture","Collection|Credential Access","no"
+"T1056.002","GUI Input Capture","Collection|Credential Access","FIN4"
+"T1056.001","Keylogging","Collection|Credential Access","Tonto Team|Ajax Security Team|Operation Wocao|APT32|Sandworm Team|APT39|APT41|Kimsuky|menuPass|Stolen Pencil|FIN4|APT38|OilRig|Ke3chang|PLATINUM|Sowbug|Magic Hound|Group5|Lazarus Group|Threat Group-3390|APT3|Darkhotel|APT28"
+"T1555","Credentials from Password Stores","Credential Access","APT29|Evilnum|UNC2452|FIN6|APT39|OilRig|MuddyWater|Leafminer|APT33|Stealth Falcon"
+"T1552.005","Cloud Instance Metadata API","Credential Access","TeamTNT"
+"T1003.008","/etc/passwd and /etc/shadow","Credential Access","no"
+"T1003.007","Proc Filesystem","Credential Access","no"
+"T1003.006","DCSync","Credential Access","APT29|UNC2452|Operation Wocao"
+"T1558.003","Kerberoasting","Credential Access","FIN7|APT29|UNC2452|Operation Wocao|Wizard Spider"
+"T1552.006","Group Policy Preferences","Credential Access","APT33"
+"T1003.003","NTDS","Credential Access","APT28|Mustang Panda|HAFNIUM|Fox Kitten|menuPass|Wizard Spider|Chimera|FIN6|Dragonfly 2.0"
+"T1003.002","Security Account Manager","Credential Access","Wizard Spider|Threat Group-3390|Ke3chang|GALLIUM|Night Dragon|Dragonfly 2.0|menuPass"
+"T1003.001","LSASS Memory","Credential Access","Indrik Spider|HAFNIUM|Fox Kitten|Operation Wocao|Kimsuky|Sandworm Team|Whitefly|Blue Mockingbird|Silence|Threat Group-3390|Leviathan|APT41|GALLIUM|TEMP.Veles|APT33|APT39|Stolen Pencil|APT32|Leafminer|Magic Hound|FIN8|PLATINUM|MuddyWater|OilRig|BRONZE BUTLER|FIN6|APT3|APT28|APT1|Ke3chang|Cleaver"
+"T1110.004","Credential Stuffing","Credential Access","Chimera"
+"T1110.003","Password Spraying","Credential Access","Sandworm Team|APT29|Silent Librarian|Chimera|APT28|APT33|Leafminer|Lazarus Group"
+"T1110.002","Password Cracking","Credential Access","FIN6|APT41|Dragonfly 2.0|APT3"
+"T1110.001","Password Guessing","Credential Access","APT28"
+"T1021.006","Windows Remote Management","Lateral Movement","APT29|UNC2452|Chimera|Wizard Spider|Threat Group-3390"
+"T1021.005","VNC","Lateral Movement","FIN7|Fox Kitten|GCMAN"
+"T1021.004","SSH","Lateral Movement","TeamTNT|FIN7|Fox Kitten|Rocke|TEMP.Veles|Leviathan|APT39|OilRig|menuPass|GCMAN"
+"T1021.003","Distributed Component Object Model","Lateral Movement","no"
+"T1021.002","SMB/Windows Admin Shares","Lateral Movement","Sandworm Team|APT28|Fox Kitten|APT41|Operation Wocao|Wizard Spider|Chimera|Blue Mockingbird|APT39|APT32|Orangeworm|FIN8|APT3|Lazarus Group|Threat Group-1314|Turla|Deep Panda|Ke3chang"
+"T1021.001","Remote Desktop Protocol","Lateral Movement","Kimsuky|FIN7|Fox Kitten|Chimera|Blue Mockingbird|Wizard Spider|Silence|APT41|TEMP.Veles|Leviathan|APT39|Stolen Pencil|Cobalt Group|Dragonfly 2.0|FIN8|APT3|OilRig|FIN10|menuPass|Patchwork|FIN6|Lazarus Group|APT1|Axiom"
+"T1554","Compromise Client Software Binary","Persistence","no"
+"T1036.006","Space after Filename","Defense Evasion","no"
+"T1036.005","Match Legitimate Name or Location","Defense Evasion","APT28|Ferocious Kitten|FIN7|BackdoorDiplomacy|Transparent Tribe|Naikon|APT29|Mustang Panda|Sidewinder|Darkhotel|Lazarus Group|Indrik Spider|UNC2452|Fox Kitten|Machete|Chimera|PROMETHIUM|Rocke|Sandworm Team|APT39|Blue Mockingbird|Whitefly|Tropic Trooper|Silence|APT41|menuPass|TEMP.Veles|MuddyWater|Sowbug|BRONZE BUTLER|APT32|Patchwork|Poseidon Group|admin@338|Carbanak|APT1"
+"T1036.004","Masquerade Task or Service","Defense Evasion","BackdoorDiplomacy|APT41|Naikon|ZIRCONIUM|APT29|Higaisa|UNC2452|Fox Kitten|Kimsuky|PROMETHIUM|Wizard Spider|APT-C-36|Carbanak|APT32|FIN6|FIN7"
+"T1036.003","Rename System Utilities","Defense Evasion","menuPass|APT32|GALLIUM"
+"T1036.002","Right-to-Left Override","Defense Evasion","Ferocious Kitten|BRONZE BUTLER|BlackTech|Ke3chang|Scarlet Mimic"
+"T1036.001","Invalid Code Signature","Defense Evasion","Windshift|APT37"
+"T1553.003","SIP and Trust Provider Hijacking","Defense Evasion","no"
+"T1553.002","Code Signing","Defense Evasion","menuPass|APT29|GALLIUM|UNC2452|Wizard Spider|Kimsuky|PROMETHIUM|Patchwork|Silence|APT41|FIN6|TA505|FIN7|Honeybee|Leviathan|CopyKittens|Winnti Group|Suckfly|Molerats|Darkhotel"
+"T1553.001","Gatekeeper Bypass","Defense Evasion","no"
+"T1553","Subvert Trust Controls","Defense Evasion","no"
+"T1027.003","Steganography","Defense Evasion","Andariel|Leviathan|TA551|BRONZE BUTLER|Tropic Trooper|MuddyWater|APT37"
+"T1027.002","Software Packing","Defense Evasion","Sandworm Team|Kimsuky|TeamTNT|ZIRCONIUM|TA505|Rocke|GALLIUM|The White Company|APT39|APT38|Dark Caracal|Elderwood|APT3|Patchwork|APT29|Night Dragon"
+"T1027.001","Binary Padding","Defense Evasion","APT29|Mustang Panda|Higaisa|Gamaredon Group|Patchwork|APT32|Leviathan|BRONZE BUTLER|Moafee"
+"T1222.002","Linux and Mac File and Directory Permissions Modification","Defense Evasion","TeamTNT|Rocke|APT32"
+"T1222.001","Windows File and Directory Permissions Modification","Defense Evasion","Wizard Spider"
+"T1552.004","Private Keys","Credential Access","TeamTNT|APT29|UNC2452|Operation Wocao|Rocke"
+"T1552.003","Bash History","Credential Access","no"
+"T1552.002","Credentials in Registry","Credential Access","APT32"
+"T1552.001","Credentials In Files","Credential Access","TeamTNT|Kimsuky|Fox Kitten|Leafminer|APT33|OilRig|TA505|Stolen Pencil|MuddyWater|APT3"
+"T1552","Unsecured Credentials","Credential Access","no"
+"T1216.001","PubPrn","Defense Evasion","APT32"
+"T1070.006","Timestomp","Defense Evasion","APT38|APT29|UNC2452|Chimera|Kimsuky|Rocke|TEMP.Veles|APT32|Lazarus Group|APT28"
+"T1070.005","Network Share Connection Removal","Defense Evasion","Threat Group-3390"
+"T1070.004","File Deletion","Defense Evasion","TeamTNT|APT39|Mustang Panda|Chimera|Evilnum|UNC2452|Operation Wocao|FIN6|Sandworm Team|Rocke|Tropic Trooper|Gamaredon Group|Wizard Spider|APT41|Kimsuky|Silence|The White Company|TEMP.Veles|APT32|APT38|Cobalt Group|Dragonfly 2.0|Honeybee|Patchwork|menuPass|FIN8|OilRig|FIN5|BRONZE BUTLER|APT3|Magic Hound|Threat Group-3390|APT28|FIN10|Group5|Lazarus Group|APT18|APT29"
+"T1070.003","Clear Command History","Defense Evasion","TeamTNT|menuPass|APT41"
+"T1550.004","Web Session Cookie","Defense Evasion|Lateral Movement","APT29|UNC2452"
+"T1550.001","Application Access Token","Defense Evasion|Lateral Movement","APT28"
+"T1550.003","Pass the Ticket","Defense Evasion|Lateral Movement","APT32|BRONZE BUTLER|APT29"
+"T1550.002","Pass the Hash","Defense Evasion|Lateral Movement","Chimera|Kimsuky|GALLIUM|APT32|Night Dragon|APT28|APT1"
+"T1550","Use Alternate Authentication Material","Defense Evasion|Lateral Movement","APT29|UNC2452"
+"T1548.004","Elevated Execution with Prompt","Privilege Escalation|Defense Evasion","no"
+"T1548.003","Sudo and Sudo Caching","Privilege Escalation|Defense Evasion","no"
+"T1548.002","Bypass User Account Control","Privilege Escalation|Defense Evasion","Evilnum|APT37|MuddyWater|Threat Group-3390|Honeybee|Cobalt Group|BRONZE BUTLER|Patchwork|APT29"
+"T1548.001","Setuid and Setgid","Privilege Escalation|Defense Evasion","no"
+"T1548","Abuse Elevation Control Mechanism","Privilege Escalation|Defense Evasion","no"
+"T1136.003","Cloud Account","Persistence","no"
+"T1070.002","Clear Linux or Mac System Logs","Defense Evasion","TeamTNT|Rocke"
+"T1070.001","Clear Windows Event Logs","Defense Evasion","Indrik Spider|Chimera|Operation Wocao|APT41|APT38|Dragonfly 2.0|APT32|FIN8|FIN5|APT28"
+"T1136.002","Domain Account","Persistence","Sandworm Team|HAFNIUM|GALLIUM"
+"T1136.001","Local Account","Persistence","TeamTNT|Fox Kitten|APT39|APT41|Leafminer|Dragonfly 2.0|APT3"
+"T1547.011","Plist Modification","Persistence|Privilege Escalation","no"
+"T1547.010","Port Monitors","Persistence|Privilege Escalation","no"
+"T1547.009","Shortcut Modification","Persistence|Privilege Escalation","APT39|Darkhotel|APT29|Gorgon Group|Dragonfly 2.0|Lazarus Group|Leviathan"
+"T1547.008","LSASS Driver","Persistence|Privilege Escalation","no"
+"T1547.007","Re-opened Applications","Persistence|Privilege Escalation","no"
+"T1547.006","Kernel Modules and Extensions","Persistence|Privilege Escalation","no"
+"T1547.005","Security Support Provider","Persistence|Privilege Escalation","no"
+"T1547.004","Winlogon Helper DLL","Persistence|Privilege Escalation","Wizard Spider|Tropic Trooper|Turla"
+"T1547.003","Time Providers","Persistence|Privilege Escalation","no"
+"T1546.014","Emond","Privilege Escalation|Persistence","no"
+"T1546.013","PowerShell Profile","Privilege Escalation|Persistence","Turla"
+"T1546.012","Image File Execution Options Injection","Privilege Escalation|Persistence","TEMP.Veles"
+"T1218.008","Odbcconf","Defense Evasion","Cobalt Group"
+"T1546.011","Application Shimming","Privilege Escalation|Persistence","FIN7"
+"T1547.002","Authentication Package","Persistence|Privilege Escalation","no"
+"T1546.010","AppInit DLLs","Privilege Escalation|Persistence","APT39"
+"T1546.009","AppCert DLLs","Privilege Escalation|Persistence","Honeybee"
+"T1218.007","Msiexec","Defense Evasion","ZIRCONIUM|Molerats|Machete|TA505|Rancor"
+"T1546.008","Accessibility Features","Privilege Escalation|Persistence","Fox Kitten|APT41|APT3|APT29|Deep Panda|Axiom"
+"T1546.007","Netsh Helper DLL","Privilege Escalation|Persistence","no"
+"T1546.006","LC_LOAD_DYLIB Addition","Privilege Escalation|Persistence","no"
+"T1546.005","Trap","Privilege Escalation|Persistence","no"
+"T1546.004","Unix Shell Configuration Modification","Privilege Escalation|Persistence","no"
+"T1546.003","Windows Management Instrumentation Event Subscription","Privilege Escalation|Persistence","FIN8|Mustang Panda|UNC2452|APT33|Blue Mockingbird|Turla|Leviathan|APT29"
+"T1546.002","Screensaver","Privilege Escalation|Persistence","no"
+"T1546.001","Change Default File Association","Privilege Escalation|Persistence","Kimsuky"
+"T1547.001","Registry Run Keys / Startup Folder","Persistence|Privilege Escalation","TeamTNT|Naikon|Windshift|Mustang Panda|ZIRCONIUM|Higaisa|Sidewinder|APT28|Wizard Spider|PROMETHIUM|Rocke|Tropic Trooper|Gamaredon Group|Sharpshooter|Molerats|Silence|RTM|Inception|APT41|Kimsuky|APT33|APT39|APT32|APT18|Dark Caracal|Threat Group-3390|Honeybee|Turla|Cobalt Group|Ke3chang|Dragonfly 2.0|APT19|Gorgon Group|MuddyWater|APT37|Leviathan|BRONZE BUTLER|APT3|Magic Hound|FIN10|FIN7|Patchwork|FIN6|Lazarus Group|Putter Panda|APT29|Darkhotel"
+"T1218.002","Control Panel","Defense Evasion","no"
+"T1218.010","Regsvr32","Defense Evasion","TA551|Blue Mockingbird|Inception|WIRTE|Cobalt Group|APT19|Leviathan|APT32|Deep Panda"
+"T1218.009","Regsvcs/Regasm","Defense Evasion","no"
+"T1218.005","Mshta","Defense Evasion","Mustang Panda|TA551|Sidewinder|Inception|Kimsuky|APT32|MuddyWater|FIN7"
+"T1218.004","InstallUtil","Defense Evasion","Mustang Panda|menuPass"
+"T1218.001","Compiled HTML File","Defense Evasion","APT41|Silence|Dark Caracal|OilRig|Lazarus Group"
+"T1218.003","CMSTP","Defense Evasion","Cobalt Group|MuddyWater"
+"T1218.011","Rundll32","Defense Evasion","APT38|HAFNIUM|TA551|UNC2452|APT41|Gamaredon Group|APT32|Sandworm Team|Blue Mockingbird|TA505|MuddyWater|APT29|APT19|CopyKittens|APT3|Carbanak|APT28"
+"T1547","Boot or Logon Autostart Execution","Persistence|Privilege Escalation","no"
+"T1546","Event Triggered Execution","Privilege Escalation|Persistence","no"
+"T1098.003","Add Office 365 Global Administrator Role","Persistence","no"
+"T1098.002","Exchange Email Delegate Permissions","Persistence","APT28|APT29|UNC2452|Magic Hound"
+"T1098.001","Additional Cloud Credentials","Persistence","APT29|UNC2452"
+"T1543.004","Launch Daemon","Persistence|Privilege Escalation","no"
+"T1543.003","Windows Service","Persistence|Privilege Escalation","TeamTNT|APT38|PROMETHIUM|Blue Mockingbird|DarkVishnya|Wizard Spider|APT32|APT41|Kimsuky|Tropic Trooper|Cobalt Group|Ke3chang|FIN7|APT19|Threat Group-3390|Honeybee|APT3|Lazarus Group|Carbanak"
+"T1543.002","Systemd Service","Persistence|Privilege Escalation","TeamTNT|Rocke"
+"T1543.001","Launch Agent","Persistence|Privilege Escalation","no"
+"T1037.005","Startup Items","Persistence|Privilege Escalation","no"
+"T1037.004","RC Scripts","Persistence|Privilege Escalation","no"
+"T1055.012","Process Hollowing","Defense Evasion|Privilege Escalation","Threat Group-3390|menuPass|Gorgon Group|Patchwork"
+"T1055.013","Process Doppelgänging","Defense Evasion|Privilege Escalation","Leafminer"
+"T1055.011","Extra Window Memory Injection","Defense Evasion|Privilege Escalation","no"
+"T1055.014","VDSO Hijacking","Defense Evasion|Privilege Escalation","no"
+"T1055.009","Proc Memory","Defense Evasion|Privilege Escalation","no"
+"T1055.008","Ptrace System Calls","Defense Evasion|Privilege Escalation","no"
+"T1055.005","Thread Local Storage","Defense Evasion|Privilege Escalation","no"
+"T1055.004","Asynchronous Procedure Call","Defense Evasion|Privilege Escalation","FIN8"
+"T1055.003","Thread Execution Hijacking","Defense Evasion|Privilege Escalation","no"
+"T1055.002","Portable Executable Injection","Defense Evasion|Privilege Escalation","Rocke|Gorgon Group"
+"T1055.001","Dynamic-link Library Injection","Defense Evasion|Privilege Escalation","BackdoorDiplomacy|Leviathan|Wizard Spider|TA505|Turla|Tropic Trooper|Lazarus Group|Putter Panda"
+"T1037.003","Network Logon Script","Persistence|Privilege Escalation","no"
+"T1543","Create or Modify System Process","Persistence|Privilege Escalation","no"
+"T1037.002","Logon Script (Mac)","Persistence|Privilege Escalation","no"
+"T1037.001","Logon Script (Windows)","Persistence|Privilege Escalation","Cobalt Group|APT28"
+"T1542.003","Bootkit","Persistence|Defense Evasion","APT41|Lazarus Group|APT28"
+"T1542.002","Component Firmware","Persistence|Defense Evasion","Equation"
+"T1542.001","System Firmware","Persistence|Defense Evasion","no"
+"T1505.003","Web Shell","Persistence","BackdoorDiplomacy|APT38|APT29|APT28|Tonto Team|Sandworm Team|HAFNIUM|Volatile Cedar|Fox Kitten|Operation Wocao|Kimsuky|Tropic Trooper|GALLIUM|Threat Group-3390|TEMP.Veles|Leviathan|APT39|Dragonfly 2.0|APT32|OilRig|Deep Panda"
+"T1505.002","Transport Agent","Persistence","no"
+"T1505.001","SQL Stored Procedures","Persistence","Sandworm Team"
+"T1053.003","Cron","Execution|Persistence|Privilege Escalation","APT38|Rocke"
+"T1053.004","Launchd","Execution|Persistence|Privilege Escalation","no"
+"T1053.001","At (Linux)","Execution|Persistence|Privilege Escalation","no"
+"T1053.005","Scheduled Task","Execution|Persistence|Privilege Escalation","APT37|APT38|Naikon|CostaRicto|Mustang Panda|Higaisa|UNC2452|Fox Kitten|Molerats|Machete|Operation Wocao|Chimera|Gamaredon Group|Blue Mockingbird|MuddyWater|Wizard Spider|Frankenstein|APT-C-36|BRONZE BUTLER|APT41|GALLIUM|Silence|TEMP.Veles|APT33|APT39|Rancor|OilRig|Patchwork|Dragonfly 2.0|Cobalt Group|FIN8|menuPass|FIN10|FIN7|APT32|Stealth Falcon|FIN6|APT3|APT29"
+"T1053.002","At (Windows)","Execution|Persistence|Privilege Escalation","BRONZE BUTLER|Threat Group-3390|APT18"
+"T1542","Pre-OS Boot","Defense Evasion|Persistence","no"
+"T1137.001","Office Template Macros","Persistence","MuddyWater"
+"T1137.004","Outlook Home Page","Persistence","OilRig"
+"T1137.003","Outlook Forms","Persistence","no"
+"T1137.005","Outlook Rules","Persistence","no"
+"T1137.006","Add-ins","Persistence","Naikon"
+"T1137.002","Office Test","Persistence","APT28"
+"T1531","Account Access Removal","Impact","no"
+"T1539","Steal Web Session Cookie","Credential Access","Evilnum"
+"T1529","System Shutdown/Reboot","Impact","Lazarus Group|APT38|APT37"
+"T1518","Software Discovery","Discovery","Mustang Panda|Windshift|MuddyWater|Windigo|Sidewinder|Operation Wocao|BRONZE BUTLER|Tropic Trooper|Inception"
+"T1547.013","XDG Autostart Entries","Persistence|Privilege Escalation","no"
+"T1534","Internal Spearphishing","Lateral Movement","Leviathan|Gamaredon Group"
+"T1528","Steal Application Access Token","Credential Access","APT28"
+"T1535","Unused/Unsupported Cloud Regions","Defense Evasion","no"
+"T1525","Implant Internal Image","Persistence","no"
+"T1538","Cloud Service Dashboard","Discovery","no"
+"T1530","Data from Cloud Storage Object","Collection","Fox Kitten"
+"T1578","Modify Cloud Compute Infrastructure","Defense Evasion","no"
+"T1537","Transfer Data to Cloud Account","Exfiltration","no"
+"T1526","Cloud Service Discovery","Discovery","no"
+"T1505","Server Software Component","Persistence","no"
+"T1499","Endpoint Denial of Service","Impact","Sandworm Team"
+"T1497","Virtualization/Sandbox Evasion","Defense Evasion|Discovery","Darkhotel"
+"T1498","Network Denial of Service","Impact","APT28"
+"T1496","Resource Hijacking","Impact","TeamTNT|Blue Mockingbird|Rocke|APT41"
+"T1495","Firmware Corruption","Impact","no"
+"T1491","Defacement","Impact","no"
+"T1490","Inhibit System Recovery","Impact","no"
+"T1489","Service Stop","Impact","Indrik Spider|Wizard Spider|Lazarus Group"
+"T1486","Data Encrypted for Impact","Impact","FIN7|Indrik Spider|APT41|TA505|APT38"
+"T1485","Data Destruction","Impact","Sandworm Team|Lazarus Group|APT38"
+"T1484","Domain Policy Modification","Defense Evasion|Privilege Escalation","no"
+"T1482","Domain Trust Discovery","Discovery","FIN8|APT29|Chimera|UNC2452"
+"T1480","Execution Guardrails","Defense Evasion","no"
+"T1221","Template Injection","Defense Evasion","Gamaredon Group|Frankenstein|Inception|APT28|Tropic Trooper|DarkHydrus|Dragonfly 2.0"
+"T1222","File and Directory Permissions Modification","Defense Evasion","no"
+"T1220","XSL Script Processing","Defense Evasion","Higaisa|Cobalt Group"
+"T1217","Browser Bookmark Discovery","Discovery","APT38|Chimera|Fox Kitten"
+"T1212","Exploitation for Credential Access","Credential Access","no"
+"T1189","Drive-by Compromise","Initial Access","Transparent Tribe|Andariel|Leviathan|Machete|Windigo|Dragonfly|PROMETHIUM|Turla|Windshift|RTM|Darkhotel|APT38|APT19|Lazarus Group|Threat Group-3390|BRONZE BUTLER|APT32|Dark Caracal|Dragonfly 2.0|Leafminer|Patchwork|APT37|Elderwood|PLATINUM"
+"T1211","Exploitation for Defense Evasion","Defense Evasion","APT28"
+"T1197","BITS Jobs","Defense Evasion|Persistence","APT39|Patchwork|APT41|Leviathan"
+"T1203","Exploitation for Client Execution","Execution","Andariel|Transparent Tribe|APT3|Tonto Team|Mustang Panda|Darkhotel|Higaisa|HAFNIUM|Sidewinder|Sandworm Team|MuddyWater|Frankenstein|Inception|BlackTech|APT41|admin@338|Threat Group-3390|APT12|The White Company|APT33|APT32|APT28|Tropic Trooper|BRONZE BUTLER|Cobalt Group|Lazarus Group|Patchwork|Elderwood|APT29|TA459|APT37|Leviathan"
+"T1201","Password Policy Discovery","Discovery","Chimera|Turla|OilRig"
+"T1195","Supply Chain Compromise","Initial Access","no"
+"T1199","Trusted Relationship","Initial Access","APT29|Sandworm Team|GOLD SOUTHFIELD|APT28|menuPass"
+"T1218","Signed Binary Proxy Execution","Defense Evasion","no"
+"T1204","User Execution","Execution","no"
+"T1213","Data from Information Repositories","Collection","APT28|Fox Kitten|FIN6|Turla"
+"T1190","Exploit Public-Facing Application","Initial Access","BackdoorDiplomacy|menuPass|Volatile Cedar|UNC2452|Fox Kitten|Operation Wocao|APT28|APT29|GOLD SOUTHFIELD|Blue Mockingbird|Rocke|APT39|BlackTech|APT41|GALLIUM|Night Dragon|Axiom"
+"T1210","Exploitation of Remote Services","Lateral Movement","Tonto Team|FIN7|Fox Kitten|menuPass|Wizard Spider|Threat Group-3390|APT28"
+"T1200","Hardware Additions","Initial Access","DarkVishnya"
+"T1202","Indirect Command Execution","Defense Evasion","no"
+"T1219","Remote Access Software","Command And Control","TeamTNT|Mustang Panda|MuddyWater|Evilnum|GOLD SOUTHFIELD|Sandworm Team|DarkVishnya|RTM|Kimsuky|Night Dragon|Cobalt Group|Thrip|Carbanak"
+"T1207","Rogue Domain Controller","Defense Evasion","no"
+"T1216","Signed Script Proxy Execution","Defense Evasion","no"
+"T1205","Traffic Signaling","Defense Evasion|Persistence|Command And Control","no"
+"T1176","Browser Extensions","Persistence","Kimsuky|Stolen Pencil"
+"T1187","Forced Authentication","Credential Access","DarkHydrus|Dragonfly 2.0"
+"T1175","Component Object Model and Distributed COM","Lateral Movement|Execution","no"
+"T1185","Browser Session Hijacking","Collection","no"
+"T1140","Deobfuscate/Decode Files or Information","Defense Evasion","APT39|APT29|ZIRCONIUM|Higaisa|UNC2452|Rocke|Sandworm Team|Gamaredon Group|Molerats|Frankenstein|Turla|WIRTE|Darkhotel|Tropic Trooper|Honeybee|Gorgon Group|Threat Group-3390|menuPass|APT19|Leviathan|MuddyWater|APT28|OilRig|BRONZE BUTLER"
+"T1134","Access Token Manipulation","Defense Evasion|Privilege Escalation","FIN6|Blue Mockingbird"
+"T1149","LC_MAIN Hijacking","Defense Evasion","no"
+"T1136","Create Account","Persistence","Sandworm Team|Indrik Spider"
+"T1135","Network Share Discovery","Discovery","Tonto Team|APT38|Chimera|Operation Wocao|Wizard Spider|APT32|APT39|DarkVishnya|APT41|Tropic Trooper|APT1|Dragonfly 2.0|Sowbug"
+"T1137","Office Application Startup","Persistence","Gamaredon Group|APT32"
+"T1153","Source","Execution","no"
+"T1133","External Remote Services","Persistence|Initial Access","TeamTNT|Leviathan|APT28|APT29|UNC2452|Operation Wocao|Wizard Spider|Kimsuky|GOLD SOUTHFIELD|Chimera|Sandworm Team|APT41|GALLIUM|TEMP.Veles|Night Dragon|Ke3chang|OilRig|Dragonfly 2.0|FIN5|Threat Group-3390|APT18"
+"T1132","Data Encoding","Command And Control","no"
+"T1129","Shared Modules","Execution","no"
+"T1127","Trusted Developer Utilities Proxy Execution","Defense Evasion","no"
+"T1125","Video Capture","Collection","Silence|FIN7"
+"T1124","System Time Discovery","Discovery","Darkhotel|ZIRCONIUM|Higaisa|Sidewinder|Chimera|Operation Wocao|The White Company|Lazarus Group|BRONZE BUTLER|Turla"
+"T1123","Audio Capture","Collection","APT37"
+"T1120","Peripheral Device Discovery","Discovery","OilRig|BackdoorDiplomacy|Operation Wocao|Turla|APT37|Gamaredon Group|Equation|APT28"
+"T1119","Automated Collection","Collection","Mustang Panda|Sidewinder|Chimera|menuPass|Operation Wocao|Gamaredon Group|Tropic Trooper|Frankenstein|APT1|APT28|Patchwork|OilRig|FIN5|Threat Group-3390|FIN6"
+"T1115","Clipboard Data","Collection","Operation Wocao|APT39|APT38"
+"T1114","Email Collection","Collection","Magic Hound|Silent Librarian"
+"T1113","Screen Capture","Collection","GOLD SOUTHFIELD|Gamaredon Group|APT39|Silence|MuddyWater|Dragonfly 2.0|OilRig|Dark Caracal|FIN7|BRONZE BUTLER|Magic Hound|Group5|APT28"
+"T1112","Modify Registry","Defense Evasion","Operation Wocao|Kimsuky|Gamaredon Group|Blue Mockingbird|Wizard Spider|Silence|APT41|Turla|APT32|APT38|Patchwork|Gorgon Group|Threat Group-3390|Dragonfly 2.0|APT19|Honeybee|FIN8"
+"T1111","Two-Factor Authentication Interception","Credential Access","Chimera|Operation Wocao"
+"T1110","Brute Force","Credential Access","APT38|APT28|Fox Kitten|DarkVishnya|APT39|OilRig|FIN5|Turla"
+"T1108","Redundant Access","Defense Evasion|Persistence","no"
+"T1106","Native API","Execution","APT38|Higaisa|menuPass|Operation Wocao|Chimera|Gamaredon Group|Tropic Trooper|Sharpshooter|Turla|Silence|APT37|Gorgon Group"
+"T1105","Ingress Tool Transfer","Command And Control","TeamTNT|Nomadic Octopus|IndigoZebra|Andariel|BackdoorDiplomacy|Tonto Team|HAFNIUM|APT29|Ajax Security Team|Mustang Panda|Windshift|Darkhotel|ZIRCONIUM|TA551|Volatile Cedar|Indrik Spider|Evilnum|Sidewinder|UNC2452|Fox Kitten|Kimsuky|Operation Wocao|Chimera|Sandworm Team|Whitefly|Rocke|APT39|Tropic Trooper|Sharpshooter|Molerats|Frankenstein|Silence|APT-C-36|APT41|GALLIUM|TA505|WIRTE|APT33|MuddyWater|APT18|APT38|Rancor|Gorgon Group|OilRig|Turla|Cobalt Group|Dragonfly 2.0|FIN8|PLATINUM|APT37|Elderwood|Leviathan|APT32|Magic Hound|BRONZE BUTLER|APT3|menuPass|FIN7|Gamaredon Group|Patchwork|Lazarus Group|Threat Group-3390|APT28"
+"T1104","Multi-Stage Channels","Command And Control","APT41|MuddyWater|APT3"
+"T1102","Web Service","Command And Control","TeamTNT|FIN8|Fox Kitten|Turla|APT32|Gamaredon Group|Rocke|Inception|FIN6"
+"T1098","Account Manipulation","Persistence","Sandworm Team|APT3|Dragonfly 2.0|Lazarus Group"
+"T1095","Non-Application Layer Protocol","Command And Control","BackdoorDiplomacy|HAFNIUM|Operation Wocao|FIN6|APT29|PLATINUM|APT3"
+"T1092","Communication Through Removable Media","Command And Control","APT28"
+"T1091","Replication Through Removable Media","Lateral Movement|Initial Access","Mustang Panda|Tropic Trooper|Darkhotel|APT28"
+"T1090","Proxy","Command And Control","Windigo|Fox Kitten|Operation Wocao|Sandworm Team|Blue Mockingbird|APT41|Turla"
+"T1087","Account Discovery","Discovery","APT29|UNC2452"
+"T1083","File and Directory Discovery","Discovery","APT38|APT29|Mustang Panda|Darkhotel|Windigo|Sidewinder|Chimera|UNC2452|Fox Kitten|menuPass|APT39|Sandworm Team|Operation Wocao|Gamaredon Group|Tropic Trooper|Inception|APT41|Kimsuky|APT32|MuddyWater|APT18|Leafminer|Honeybee|Dark Caracal|Dragonfly 2.0|APT3|Sowbug|Magic Hound|BRONZE BUTLER|APT28|Patchwork|Lazarus Group|Dust Storm|admin@338|Turla|Ke3chang"
+"T1082","System Information Discovery","Discovery","TeamTNT|APT38|APT29|Mustang Panda|Windshift|ZIRCONIUM|Higaisa|Windigo|Sidewinder|UNC2452|Chimera|Operation Wocao|Wizard Spider|Rocke|Sandworm Team|Blue Mockingbird|Tropic Trooper|Frankenstein|Inception|Kimsuky|Darkhotel|MuddyWater|APT18|APT32|APT37|Honeybee|APT19|Magic Hound|Sowbug|OilRig|APT3|Gamaredon Group|Patchwork|Stealth Falcon|Lazarus Group|admin@338|Turla|Ke3chang"
+"T1080","Taint Shared Content","Lateral Movement","Gamaredon Group|BRONZE BUTLER|Darkhotel"
+"T1078","Valid Accounts","Defense Evasion|Persistence|Privilege Escalation|Initial Access","FIN7|Leviathan|APT29|Silent Librarian|UNC2452|Fox Kitten|Operation Wocao|Chimera|Sandworm Team|Wizard Spider|Silence|APT41|GALLIUM|TEMP.Veles|APT39|FIN4|Night Dragon|Dragonfly 2.0|FIN8|APT33|FIN5|OilRig|APT28|menuPass|FIN10|Suckfly|FIN6|Threat Group-3390|APT18|PittyTiger|Carbanak"
+"T1074","Data Staged","Collection","Wizard Spider"
+"T1072","Software Deployment Tools","Execution|Lateral Movement","Silence|APT32|Threat Group-1314"
+"T1071","Application Layer Protocol","Command And Control","TeamTNT|Rocke|Magic Hound|Dragonfly 2.0"
+"T1070","Indicator Removal on Host","Defense Evasion","APT29|UNC2452"
+"T1069","Permission Groups Discovery","Discovery","APT29|UNC2452|TA505|APT3"
+"T1068","Exploitation for Privilege Escalation","Privilege Escalation","Tonto Team|ZIRCONIUM|Turla|Whitefly|APT33|Cobalt Group|PLATINUM|FIN8|APT32|Threat Group-3390|FIN6|APT28"
+"T1064","Scripting","Defense Evasion|Execution","no"
+"T1062","Hypervisor","Persistence","no"
+"T1061","Graphical User Interface","Execution","no"
+"T1059","Command and Scripting Interpreter","Execution","APT37|Windigo|Fox Kitten|APT32|Whitefly|APT39|Dragonfly 2.0|FIN7|APT19|OilRig|FIN5|Stealth Falcon|FIN6|Ke3chang"
+"T1057","Process Discovery","Discovery","TeamTNT|Andariel|APT29|Mustang Panda|Windshift|Higaisa|Sidewinder|Chimera|UNC2452|Operation Wocao|Rocke|Frankenstein|Inception|Darkhotel|MuddyWater|APT1|APT38|Tropic Trooper|APT37|Honeybee|OilRig|APT3|Magic Hound|APT28|Winnti Group|Stealth Falcon|Poseidon Group|Lazarus Group|Molerats|Turla|Deep Panda|Ke3chang"
+"T1056","Input Capture","Collection|Credential Access","APT39"
+"T1055","Process Injection","Defense Evasion|Privilege Escalation","Operation Wocao|APT32|Sharpshooter|Silence|APT41|Kimsuky|Cobalt Group|Turla|APT37|Honeybee|PLATINUM"
+"T1053","Scheduled Task/Job","Execution|Persistence|Privilege Escalation","no"
+"T1052","Exfiltration Over Physical Medium","Exfiltration","no"
+"T1051","Shared Webroot","Lateral Movement","no"
+"T1049","System Network Connections Discovery","Discovery","TeamTNT|Andariel|BackdoorDiplomacy|Mustang Panda|MuddyWater|Chimera|Sandworm Team|Operation Wocao|Tropic Trooper|APT41|APT38|GALLIUM|APT32|APT1|OilRig|APT3|menuPass|Threat Group-3390|Poseidon Group|admin@338|Turla|Ke3chang"
+"T1048","Exfiltration Over Alternative Protocol","Exfiltration","no"
+"T1047","Windows Management Instrumentation","Execution","Sandworm Team|FIN7|Indrik Spider|Naikon|Mustang Panda|Windshift|UNC2452|Operation Wocao|Chimera|Blue Mockingbird|Wizard Spider|Frankenstein|APT41|FIN6|GALLIUM|APT32|MuddyWater|Threat Group-3390|OilRig|FIN8|Leviathan|menuPass|Stealth Falcon|Lazarus Group|APT29|Deep Panda"
+"T1046","Network Service Scanning","Discovery","TeamTNT|BackdoorDiplomacy|Naikon|CostaRicto|Chimera|Fox Kitten|Operation Wocao|Rocke|DarkVishnya|APT41|Tropic Trooper|APT39|APT32|OilRig|Cobalt Group|Leafminer|menuPass|Suckfly|FIN6|Threat Group-3390"
+"T1043","Commonly Used Port","Command And Control","OilRig|APT28|TEMP.Veles|Night Dragon|APT29|APT18|FIN7|APT19|Dragonfly 2.0|FIN8|APT37|APT3|Magic Hound|Lazarus Group|Threat Group-3390"
+"T1041","Exfiltration Over C2 Channel","Exfiltration","Leviathan|ZIRCONIUM|Higaisa|Chimera|APT39|Operation Wocao|Sandworm Team|MuddyWater|Wizard Spider|Frankenstein|Kimsuky|GALLIUM|APT32|APT3|Gamaredon Group|Stealth Falcon|Lazarus Group|Ke3chang"
+"T1040","Network Sniffing","Credential Access|Discovery","Kimsuky|Sandworm Team|DarkVishnya|APT33|Stolen Pencil|APT28"
+"T1039","Data from Network Shared Drive","Collection","APT28|Chimera|Fox Kitten|Gamaredon Group|BRONZE BUTLER|Sowbug|menuPass"
+"T1037","Boot or Logon Initialization Scripts","Persistence|Privilege Escalation","Rocke"
+"T1036","Masquerading","Defense Evasion","APT28|Nomadic Octopus|OilRig|APT29|ZIRCONIUM|TA551|UNC2452|Windshift|APT32|BRONZE BUTLER|menuPass|PLATINUM|Dragonfly 2.0"
+"T1034","Path Interception","Persistence|Privilege Escalation","no"
+"T1033","System Owner/User Discovery","Discovery","APT38|Windshift|ZIRCONIUM|Sidewinder|Chimera|Sandworm Team|Operation Wocao|Wizard Spider|Frankenstein|APT41|GALLIUM|Tropic Trooper|APT39|MuddyWater|APT37|Dragonfly 2.0|APT19|APT32|Magic Hound|OilRig|FIN10|Gamaredon Group|Patchwork|Stealth Falcon|Lazarus Group|APT3"
+"T1030","Data Transfer Size Limits","Exfiltration","APT28|Threat Group-3390"
+"T1029","Scheduled Transfer","Exfiltration","Higaisa"
+"T1027","Obfuscated Files or Information","Defense Evasion","TeamTNT|BackdoorDiplomacy|Transparent Tribe|APT39|Mustang Panda|Windshift|TA551|Higaisa|Sidewinder|UNC2452|Fox Kitten|GOLD SOUTHFIELD|Operation Wocao|Kimsuky|FIN6|Chimera|Gamaredon Group|Rocke|Sandworm Team|Blue Mockingbird|Whitefly|Molerats|Wizard Spider|Mofang|Frankenstein|Inception|APT-C-36|APT41|GALLIUM|Turla|TA505|Silence|APT33|Night Dragon|Darkhotel|Gallmaker|APT29|APT18|Tropic Trooper|Patchwork|menuPass|APT37|Threat Group-3390|Cobalt Group|Dark Caracal|Leafminer|Honeybee|APT19|BlackOasis|Leviathan|FIN8|MuddyWater|FIN7|Elderwood|OilRig|Magic Hound|APT3|APT32|Group5|Dust Storm|Lazarus Group|Putter Panda|APT28"
+"T1026","Multiband Communication","Command And Control","Lazarus Group"
+"T1025","Data from Removable Media","Collection","Turla|Gamaredon Group|APT28"
+"T1021","Remote Services","Lateral Movement","no"
+"T1020","Automated Exfiltration","Exfiltration","Sidewinder|Gamaredon Group|Tropic Trooper|Frankenstein|Honeybee"
+"T1018","Remote System Discovery","Discovery","Indrik Spider|Naikon|APT29|UNC2452|Chimera|Fox Kitten|Operation Wocao|Sandworm Team|Rocke|Wizard Spider|Silence|GALLIUM|APT39|APT32|Deep Panda|Ke3chang|Threat Group-3390|Dragonfly 2.0|Leafminer|FIN8|FIN5|APT3|BRONZE BUTLER|menuPass|FIN6|Turla"
+"T1016","System Network Configuration Discovery","Discovery","TeamTNT|ZIRCONIUM|Mustang Panda|Higaisa|Sidewinder|Chimera|Operation Wocao|Wizard Spider|Sandworm Team|Tropic Trooper|Frankenstein|APT41|GALLIUM|APT32|Darkhotel|MuddyWater|APT1|APT19|Dragonfly 2.0|Magic Hound|OilRig|Threat Group-3390|menuPass|Stealth Falcon|Lazarus Group|APT3|Naikon|admin@338|Turla|Ke3chang"
+"T1014","Rootkit","Defense Evasion","TeamTNT|Rocke|APT41|APT28|Winnti Group"
+"T1012","Query Registry","Discovery","ZIRCONIUM|Chimera|Fox Kitten|APT39|Operation Wocao|APT32|Dragonfly 2.0|Threat Group-3390|OilRig|Stealth Falcon|Lazarus Group|Turla"
+"T1011","Exfiltration Over Other Network Medium","Exfiltration","no"
+"T1010","Application Window Discovery","Discovery","Lazarus Group"
+"T1008","Fallback Channels","Command And Control","FIN7|APT41|OilRig|Lazarus Group"
+"T1007","System Service Discovery","Discovery","Indrik Spider|Chimera|Operation Wocao|BRONZE BUTLER|APT1|OilRig|Poseidon Group|admin@338|Turla|Ke3chang"
+"T1006","Direct Volume Access","Defense Evasion","no"
+"T1005","Data from Local System","Collection","FIN7|APT41|APT38|Andariel|APT29|Windigo|UNC2452|Fox Kitten|Sandworm Team|Operation Wocao|FIN6|Gamaredon Group|APT39|Frankenstein|Inception|Kimsuky|GALLIUM|Turla|menuPass|Dark Caracal|Dragonfly 2.0|Honeybee|APT37|APT28|APT3|BRONZE BUTLER|Patchwork|Stealth Falcon|Lazarus Group|Dust Storm|Threat Group-3390|APT1|Ke3chang"
+"T1003","OS Credential Dumping","Credential Access","Tonto Team|APT39|Frankenstein|APT32|APT28|Leviathan|Sowbug|Suckfly|Poseidon Group|Axiom"
+"T1001","Data Obfuscation","Command And Control","Operation Wocao|Axiom"
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_data/lookup/previously_seen_aws_regions.yml b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_data/lookups/previously_seen_aws_regions.yml
similarity index 100%
rename from bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_data/lookup/previously_seen_aws_regions.yml
rename to bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_data/lookups/previously_seen_aws_regions.yml
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_data/macro/security_content_ctime.yml b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_data/macro/security_content_ctime.yml
new file mode 100644
index 0000000000..3c18a1d7af
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_data/macro/security_content_ctime.yml
@@ -0,0 +1,5 @@
+arguments:
+ - field
+definition: 'convert timeformat="%Y-%m-%dT%H:%M:%S" ctime($field$)'
+description: convert epoch time to string
+name: security_content_ctime
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_security_content_basic_builder.py b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_security_content_basic_builder.py
index b65b164a1b..25c9c30a58 100644
--- a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_security_content_basic_builder.py
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_security_content_basic_builder.py
@@ -22,7 +22,7 @@ def test_read_deployment():
def test_read_lookup():
security_content_builder = SecurityContentBasicBuilder()
security_content_builder.setObject(os.path.join(os.path.dirname(__file__),
- 'test_data/lookup/previously_seen_aws_regions.yml'), SecurityContentType.lookups)
+ 'test_data/lookups/previously_seen_aws_regions.yml'), SecurityContentType.lookups)
lookup = security_content_builder.getObject()
assert lookup.name == "previously_seen_aws_regions"
@@ -45,4 +45,4 @@ def test_read_playbook():
playbook = security_content_builder.getObject()
assert playbook.name == "Ransomware Investigate and Contain"
- assert playbook.tags.detections[0] == "Conti Common Exec parameter"
\ No newline at end of file
+ assert playbook.tags.detections[0] == "Conti Common Exec parameter"
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_security_content_detection_builder.py b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_security_content_detection_builder.py
index 8290c2880e..d7e7020455 100644
--- a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_security_content_detection_builder.py
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_security_content_detection_builder.py
@@ -6,6 +6,8 @@ from contentctl_infrastructure.contentctl_infrastructure.builder.security_conten
from contentctl_infrastructure.contentctl_infrastructure.builder.security_content_basic_builder import SecurityContentBasicBuilder
from contentctl.contentctl.domain.entities.enums.enums import SecurityContentType
from contentctl_infrastructure.contentctl_infrastructure.builder.yml_reader import YmlReader
+from contentctl_infrastructure.contentctl_infrastructure.builder.security_content_investigation_builder import SecurityContentInvestigationBuilder
+from contentctl_infrastructure.contentctl_infrastructure.builder.security_content_baseline_builder import SecurityContentBaselineBuilder
def test_read_detection():
@@ -27,7 +29,7 @@ def test_add_deployment_to_detection():
security_content_builder = SecurityContentDetectionBuilder()
security_content_builder.setObject(os.path.join(os.path.dirname(__file__),
'test_data/detection/valid.yml'), SecurityContentType.detections)
- security_content_builder.addDeployment([deployment], SecurityContentProduct.ESCU)
+ security_content_builder.addDeployment([deployment])
detection = security_content_builder.getObject()
assert detection.deployment.name == "ESCU Default Configuration TTP"
@@ -42,7 +44,7 @@ def test_detection_nes_field_enrichment():
security_content_builder = SecurityContentDetectionBuilder()
security_content_builder.setObject(os.path.join(os.path.dirname(__file__),
'test_data/detection/valid.yml'), SecurityContentType.detections)
- security_content_builder.addDeployment([deployment], SecurityContentProduct.ESCU)
+ security_content_builder.addDeployment([deployment])
security_content_builder.addNesFields()
detection = security_content_builder.getObject()
@@ -58,7 +60,7 @@ def test_detection_annotation_enrichment():
security_content_builder = SecurityContentDetectionBuilder()
security_content_builder.setObject(os.path.join(os.path.dirname(__file__),
'test_data/detection/valid.yml'), SecurityContentType.detections)
- security_content_builder.addDeployment([deployment], SecurityContentProduct.ESCU)
+ security_content_builder.addDeployment([deployment])
security_content_builder.addAnnotations()
detection = security_content_builder.getObject()
@@ -77,6 +79,21 @@ def test_detection_annotation_enrichment():
assert detection.annotations == valid_annotations
+def test_detection_add_mappings():
+ security_content_builder = SecurityContentDetectionBuilder()
+ security_content_builder.setObject(os.path.join(os.path.dirname(__file__),
+ 'test_data/detection/valid.yml'), SecurityContentType.detections)
+ security_content_builder.addMappings()
+ detection = security_content_builder.getObject()
+
+ valid_mappings = {'mitre_attack': ['T1003.002', 'T1003'],
+ 'kill_chain_phases': ['Actions on Objectives'],
+ 'cis20': ['CIS 3', 'CIS 5', 'CIS 16'],
+ 'nist': ['DE.CM']}
+
+ assert detection.mappings == valid_mappings
+
+
def test_detection_add_rba():
security_content_builder = SecurityContentDetectionBuilder()
security_content_builder.setObject(os.path.join(os.path.dirname(__file__),
@@ -109,11 +126,8 @@ def test_detection_add_playbooks():
def test_detection_enrich_baseline():
- # create own object for baseline with own Builder
-
- baseline_builder = SecurityContentDetectionBuilder()
- baseline_builder.setObject(os.path.join(os.path.dirname(__file__),
- 'test_data/detection/baseline.yml'), SecurityContentType.detections)
+ baseline_builder = SecurityContentBaselineBuilder()
+ baseline_builder.setObject(os.path.join(os.path.dirname(__file__), 'test_data/baseline/baseline.yml'), SecurityContentType.baselines)
baseline = baseline_builder.getObject()
security_content_builder = SecurityContentDetectionBuilder()
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_security_content_director.py b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_security_content_director.py
new file mode 100644
index 0000000000..b4520e3041
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_security_content_director.py
@@ -0,0 +1,187 @@
+import os
+
+from contentctl_infrastructure.contentctl_infrastructure.builder.security_content_director import SecurityContentDirector
+from contentctl_infrastructure.contentctl_infrastructure.builder.security_content_basic_builder import SecurityContentBasicBuilder
+from contentctl_infrastructure.contentctl_infrastructure.builder.security_content_detection_builder import SecurityContentDetectionBuilder
+from contentctl_infrastructure.contentctl_infrastructure.builder.security_content_story_builder import SecurityContentStoryBuilder
+from contentctl.contentctl.domain.entities.enums.enums import SecurityContentProduct
+from contentctl_infrastructure.contentctl_infrastructure.builder.security_content_investigation_builder import SecurityContentInvestigationBuilder
+from contentctl_infrastructure.contentctl_infrastructure.builder.security_content_baseline_builder import SecurityContentBaselineBuilder
+
+
+def test_construct_deployments():
+ director = SecurityContentDirector()
+ deployment_builder = SecurityContentBasicBuilder()
+ director.constructDeployment(deployment_builder, os.path.join(os.path.dirname(__file__),
+ 'test_data/deployment/ESCU/00_default_ttp.yml'))
+ deployment = deployment_builder.getObject()
+
+ assert deployment.name == "ESCU Default Configuration TTP"
+ assert deployment.author == "Patrick Bareiss"
+ assert deployment.scheduling.schedule_window == "auto"
+ assert deployment.notable.rule_description == "%description%"
+
+
+def test_construct_lookups():
+ director = SecurityContentDirector()
+ lookup_builder = SecurityContentBasicBuilder()
+ director.constructLookup(lookup_builder, os.path.join(os.path.dirname(__file__),
+ 'test_data/lookups/previously_seen_aws_regions.yml'))
+ lookup = lookup_builder.getObject()
+
+ assert lookup.name == "previously_seen_aws_regions"
+ assert lookup.filename == "previously_seen_aws_regions.csv"
+
+
+def test_construct_macros():
+ director = SecurityContentDirector()
+ macro_builder = SecurityContentBasicBuilder()
+ director.constructMacro(macro_builder, os.path.join(os.path.dirname(__file__),
+ 'test_data/macro/powershell.yml'))
+ macro = macro_builder.getObject()
+
+ assert macro.name == "powershell"
+
+
+def test_construct_playbooks():
+ director = SecurityContentDirector()
+ playbook_builder = SecurityContentBasicBuilder()
+ director.constructPlaybook(playbook_builder, os.path.join(os.path.dirname(__file__),
+ 'test_data/playbook/example_playbook.yml'))
+ playbook = playbook_builder.getObject()
+
+ assert playbook.name == "Ransomware Investigate and Contain"
+ assert playbook.tags.detections[0] == "Conti Common Exec parameter"
+
+
+def test_construct_baselines():
+ director = SecurityContentDirector()
+
+ deployment_builder = SecurityContentBasicBuilder()
+ director.constructDeployment(deployment_builder, os.path.join(os.path.dirname(__file__),
+ 'test_data/deployment/ESCU/00_default_baseline.yml'))
+ deployment = deployment_builder.getObject()
+
+ baseline_builder = SecurityContentBaselineBuilder()
+ director.constructBaseline(baseline_builder, os.path.join(os.path.dirname(__file__),
+ 'test_data/baseline/baseline.yml'), [deployment])
+ baseline = baseline_builder.getObject()
+
+ assert baseline.name == "Previously Seen Users In CloudTrail - Update"
+
+ director.constructBaseline(baseline_builder, os.path.join(os.path.dirname(__file__),
+ 'test_data/baseline/baseline2.yml'), [deployment])
+ baseline = baseline_builder.getObject()
+
+ assert baseline.name == "Baseline Of Cloud Instances Launched"
+
+
+def test_construct_investigations():
+ director = SecurityContentDirector()
+ investigation_builder = SecurityContentInvestigationBuilder()
+ director.constructInvestigation(investigation_builder, os.path.join(os.path.dirname(__file__),
+ 'test_data/investigation/investigation.yml'))
+ investigation = investigation_builder.getObject()
+
+ assert investigation.name == "Get Parent Process Info"
+
+
+def test_construct_detections():
+ director = SecurityContentDirector()
+
+ deployment_builder = SecurityContentBasicBuilder()
+ director.constructDeployment(deployment_builder, os.path.join(os.path.dirname(__file__),
+ 'test_data/deployment/ESCU/00_default_ttp.yml'))
+ deployment = deployment_builder.getObject()
+
+ director.constructDeployment(deployment_builder, os.path.join(os.path.dirname(__file__),
+ 'test_data/deployment/ESCU/00_default_baseline.yml'))
+ deployment_baseline = deployment_builder.getObject()
+
+ playbook_builder = SecurityContentBasicBuilder()
+ director.constructPlaybook(playbook_builder, os.path.join(os.path.dirname(__file__),
+ 'test_data/playbook/example_playbook.yml'))
+ playbook = playbook_builder.getObject()
+
+ baseline_builder = SecurityContentBaselineBuilder()
+ director.constructBaseline(baseline_builder, os.path.join(os.path.dirname(__file__),
+ 'test_data/baseline/baseline.yml'), [deployment_baseline])
+ baseline = baseline_builder.getObject()
+
+ detection_builder = SecurityContentDetectionBuilder()
+ director.constructDetection(detection_builder, os.path.join(os.path.dirname(__file__),
+ 'test_data/detection/valid.yml'), [deployment], [playbook], [baseline])
+ detection = detection_builder.getObject()
+
+ valid_annotations = {'mitre_attack': ['T1003.002', 'T1003'],
+ 'kill_chain_phases': ['Actions on Objectives'],
+ 'cis20': ['CIS 3', 'CIS 5', 'CIS 16'],
+ 'nist': ['DE.CM'],
+ 'analytic_story': ['Credential Dumping', 'DarkSide Ransomware'],
+ 'observable': [{'name': 'user', 'type': 'User', 'role': ['Victim']},
+ {'name': 'dest', 'type': 'Hostname', 'role': ['Victim']},
+ {'name': 'parent_process_name', 'type': 'Process', 'role': ['Parent Process']},
+ {'name': 'process_name', 'type': 'Process', 'role': ['Child Process']}],
+ 'context': ['Source:Endpoint', 'Stage:Credential Access'],
+ 'impact': 90, 'confidence': 100}
+
+ valid_risk = [{'risk_object_type': 'user', 'risk_object_field': 'user', 'risk_score': 90},
+ {'risk_object_type': 'system', 'risk_object_field': 'dest', 'risk_score': 90},
+ {'threat_object_field': 'parent_process_name', 'threat_object_type': 'process'},
+ {'threat_object_field': 'process_name', 'threat_object_type': 'process'}]
+
+ assert detection.name == "Attempted Credential Dump From Registry via Reg exe"
+ assert detection.author == "Patrick Bareiss, Splunk"
+ assert detection.deployment.name == "ESCU Default Configuration TTP"
+ assert detection.deployment.notable.nes_fields == ['user', 'dest']
+ assert detection.annotations == valid_annotations
+ assert detection.risk == valid_risk
+ assert detection.playbooks[0].name == "Ransomware Investigate and Contain"
+ assert detection.baselines[0].name == "Previously Seen Users In CloudTrail - Update"
+
+
+def test_construct_stories():
+ director = SecurityContentDirector()
+
+ deployment_builder = SecurityContentBasicBuilder()
+ director.constructDeployment(deployment_builder, os.path.join(os.path.dirname(__file__),
+ 'test_data/deployment/ESCU/00_default_ttp.yml'))
+ deployment = deployment_builder.getObject()
+
+ director.constructDeployment(deployment_builder, os.path.join(os.path.dirname(__file__),
+ 'test_data/deployment/ESCU/00_default_baseline.yml'))
+ deployment_baseline = deployment_builder.getObject()
+
+ playbook_builder = SecurityContentBasicBuilder()
+ director.constructPlaybook(playbook_builder, os.path.join(os.path.dirname(__file__),
+ 'test_data/playbook/example_playbook.yml'))
+ playbook = playbook_builder.getObject()
+
+ baseline_builder = SecurityContentBaselineBuilder()
+ director.constructBaseline(baseline_builder, os.path.join(os.path.dirname(__file__),
+ 'test_data/baseline/baseline2.yml'), [deployment_baseline])
+ baseline = baseline_builder.getObject()
+
+ detection_builder = SecurityContentDetectionBuilder()
+ director.constructDetection(detection_builder, os.path.join(os.path.dirname(__file__),
+ 'test_data/detection/valid.yml'), [deployment], [playbook], [baseline])
+ detection = detection_builder.getObject()
+
+ investigation_builder = SecurityContentInvestigationBuilder()
+ director.constructInvestigation(investigation_builder, os.path.join(os.path.dirname(__file__),
+ 'test_data/investigation/investigation.yml'))
+ investigation = investigation_builder.getObject()
+
+ story_builder = SecurityContentStoryBuilder()
+ director.constructStory(story_builder, os.path.join(os.path.dirname(__file__),
+ 'test_data/story/ransomware_darkside.yml'),
+ [detection], [baseline], [investigation])
+ story = story_builder.getObject()
+
+ assert story.name == "DarkSide Ransomware"
+ assert story.tags.usecase == "Advanced Threat Detection"
+ assert story.detection_names == ["ESCU - Attempted Credential Dump From Registry via Reg exe - Rule"]
+ assert story.baseline_names == ["ESCU - Baseline Of Cloud Instances Launched"]
+ assert story.investigation_names == ["ESCU - Get Parent Process Info - Response Task"]
+ assert story.author_company == "Splunk"
+ assert story.author_name == "Bhavin Patel"
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_security_content_investigation_builder.py b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_security_content_investigation_builder.py
new file mode 100644
index 0000000000..e90e408883
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_security_content_investigation_builder.py
@@ -0,0 +1,33 @@
+import os
+
+from contentctl_infrastructure.contentctl_infrastructure.builder.security_content_investigation_builder import SecurityContentInvestigationBuilder
+from contentctl.contentctl.domain.entities.enums.enums import SecurityContentType
+
+
+def test_read_investigation():
+ investigation_builder = SecurityContentInvestigationBuilder()
+ investigation_builder.setObject(os.path.join(os.path.dirname(__file__),
+ 'test_data/investigation/investigation.yml'), SecurityContentType.investigations)
+ investigation = investigation_builder.getObject()
+
+ assert investigation.name == "Get Parent Process Info"
+
+
+def test_add_inputs():
+ investigation_builder = SecurityContentInvestigationBuilder()
+ investigation_builder.setObject(os.path.join(os.path.dirname(__file__),
+ 'test_data/investigation/investigation.yml'), SecurityContentType.investigations)
+ investigation_builder.addInputs()
+ investigation = investigation_builder.getObject()
+
+ assert investigation.inputs == ["parent_process_name", "dest"]
+
+
+def test_add_lowercase_name():
+ investigation_builder = SecurityContentInvestigationBuilder()
+ investigation_builder.setObject(os.path.join(os.path.dirname(__file__),
+ 'test_data/investigation/investigation.yml'), SecurityContentType.investigations)
+ investigation_builder.addLowercaseName()
+ investigation = investigation_builder.getObject()
+
+ assert investigation.lowercase_name == "get_parent_process_info"
\ No newline at end of file
diff --git a/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_security_content_story_builder.py b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_security_content_story_builder.py
new file mode 100644
index 0000000000..29dcde92ea
--- /dev/null
+++ b/bin/contentctl/contentctl_infrastructure/contentctl_infrastructure/tests/builder/test_security_content_story_builder.py
@@ -0,0 +1,74 @@
+import os
+
+from contentctl_infrastructure.contentctl_infrastructure.builder.security_content_story_builder import SecurityContentStoryBuilder
+from contentctl_infrastructure.contentctl_infrastructure.builder.security_content_detection_builder import SecurityContentDetectionBuilder
+from contentctl_infrastructure.contentctl_infrastructure.builder.security_content_basic_builder import SecurityContentBasicBuilder
+from contentctl.contentctl.domain.entities.enums.enums import SecurityContentType
+from contentctl_infrastructure.contentctl_infrastructure.builder.security_content_investigation_builder import SecurityContentInvestigationBuilder
+from contentctl_infrastructure.contentctl_infrastructure.builder.security_content_baseline_builder import SecurityContentBaselineBuilder
+
+
+def test_read_story():
+ story_builder = SecurityContentStoryBuilder()
+ story_builder.setObject(os.path.join(os.path.dirname(__file__),
+ 'test_data/story/ransomware_darkside.yml'), SecurityContentType.stories)
+ story = story_builder.getObject()
+
+ assert story.name == "DarkSide Ransomware"
+ assert story.tags.usecase == "Advanced Threat Detection"
+
+
+def test_add_detections():
+ security_content_builder = SecurityContentDetectionBuilder()
+ security_content_builder.setObject(os.path.join(os.path.dirname(__file__),
+ 'test_data/detection/valid.yml'), SecurityContentType.detections)
+ detection = security_content_builder.getObject()
+
+ story_builder = SecurityContentStoryBuilder()
+ story_builder.setObject(os.path.join(os.path.dirname(__file__),
+ 'test_data/story/ransomware_darkside.yml'), SecurityContentType.stories)
+ story_builder.addDetections([detection])
+ story = story_builder.getObject()
+
+ assert story.detection_names == ["ESCU - Attempted Credential Dump From Registry via Reg exe - Rule"]
+
+
+def test_add_baselines():
+ baseline_builder = SecurityContentBaselineBuilder()
+ baseline_builder.setObject(os.path.join(os.path.dirname(__file__),
+ 'test_data/baseline/baseline2.yml'), SecurityContentType.baselines)
+ baseline = baseline_builder.getObject()
+
+ story_builder = SecurityContentStoryBuilder()
+ story_builder.setObject(os.path.join(os.path.dirname(__file__),
+ 'test_data/story/ransomware_darkside.yml'), SecurityContentType.stories)
+ story_builder.addBaselines([baseline])
+ story = story_builder.getObject()
+
+ assert story.baseline_names == ["ESCU - Baseline Of Cloud Instances Launched"]
+
+
+def test_add_investigations():
+ investigation_builder = SecurityContentInvestigationBuilder()
+ investigation_builder.setObject(os.path.join(os.path.dirname(__file__),
+ 'test_data/investigation/investigation.yml'), SecurityContentType.investigations)
+ investigation = investigation_builder.getObject()
+
+ story_builder = SecurityContentStoryBuilder()
+ story_builder.setObject(os.path.join(os.path.dirname(__file__),
+ 'test_data/story/ransomware_darkside.yml'), SecurityContentType.stories)
+ story_builder.addInvestigations([investigation])
+ story = story_builder.getObject()
+
+ assert story.investigation_names == ["ESCU - Get Parent Process Info - Response Task"]
+
+
+def test_parse_authorr():
+ story_builder = SecurityContentStoryBuilder()
+ story_builder.setObject(os.path.join(os.path.dirname(__file__),
+ 'test_data/story/ransomware_darkside.yml'), SecurityContentType.stories)
+ story_builder.addAuthorCompanyName()
+ story = story_builder.getObject()
+
+ assert story.author_company == "Splunk"
+ assert story.author_name == "Bhavin Patel"
\ No newline at end of file
diff --git a/bin/contentctl/contentctl_infrastructure/requirements-dev.txt b/bin/contentctl/contentctl_infrastructure/requirements-dev.txt
deleted file mode 100644
index 33438ef509..0000000000
--- a/bin/contentctl/contentctl_infrastructure/requirements-dev.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-pytest
-PyYAML
diff --git a/bin/contentctl/contentctl_infrastructure/requirements.txt b/bin/contentctl/contentctl_infrastructure/requirements.txt
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/bin/contentctl/contentctl/requirements.txt b/bin/contentctl/main/contentctl.py
similarity index 100%
rename from bin/contentctl/contentctl/requirements.txt
rename to bin/contentctl/main/contentctl.py
diff --git a/bin/contentctl/requirements-dev.txt b/bin/contentctl/requirements-dev.txt
deleted file mode 100644
index 07bc69d664..0000000000
--- a/bin/contentctl/requirements-dev.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-pydantic
-pytest
-PyYAML
\ No newline at end of file
diff --git a/bin/contentctl/requirements.txt b/bin/contentctl/requirements.txt
index e69de29bb2..1ed1129366 100644
--- a/bin/contentctl/requirements.txt
+++ b/bin/contentctl/requirements.txt
@@ -0,0 +1,6 @@
+jinja2
+mock
+pydantic
+pytest
+PyYAML
+requests
\ No newline at end of file