add content_organizer

This commit is contained in:
P4T12ICK
2022-01-17 10:49:57 +01:00
parent 9ed2766f6c
commit 15531b5cfc
7 changed files with 88 additions and 16 deletions
@@ -27,5 +27,9 @@ class Adapter(abc.ABC):
pass
@abc.abstractmethod
def writeObjects(self, objects: list) -> None:
def writeObjectsInPlace(self, objects: list) -> None:
pass
@abc.abstractmethod
def writeObjects(self, objects: list, security_content_folder: str) -> None:
pass
@@ -23,7 +23,7 @@ class ContentChanger:
converter_func = getattr(self, input_dto.converter_func_name)
converter_func(objects)
input_dto.adapter.writeObjects(objects)
input_dto.adapter.writeObjectsInPlace(objects)
# Define Converter Functions here
@@ -0,0 +1,22 @@
from dataclasses import dataclass
from contentctl_core.application.factory.object_factory import ObjectFactory, ObjectFactoryInputDto
from contentctl_core.application.adapter.adapter import Adapter
@dataclass(frozen=True)
class ContentOrganizerInputDto:
adapter : Adapter
factory_input_dto : ObjectFactoryInputDto
output_path : str
class ContentOrganizer:
def execute(self, input_dto: ContentOrganizerInputDto) -> None:
objects = list()
factory = ObjectFactory(objects)
factory.execute(input_dto.factory_input_dto)
input_dto.adapter.writeObjects(objects, input_dto.output_path)
@@ -93,5 +93,9 @@ class ObjToConfAdapter(Adapter):
macros)
def writeObjects(self, objects: list) -> None:
def writeObjectsInPlace(self, objects: list) -> None:
pass
def writeObjects(self, objects: list, security_content_folder: str) -> None:
pass
@@ -34,12 +34,30 @@ class ObjToYmlAdapter(Adapter):
object.pop('deprecated')
YmlWriter.writeYmlFile(file_path, object)
# def convertNameToFileName(self, obj: dict):
# file_name = obj['name'] \
# .replace(' ', '_') \
# .replace('-','_') \
# .replace('.','_') \
# .replace('/','_') \
# .lower()
# file_name = file_name + '.yml'
# return file_name
def writeObjects(self, objects: list, security_content_folder: str) -> None:
for object in objects:
if object['type'] == 'Investigation':
file_name = self.convertNameToFileName(object)
file_path = object['file_path']
object.pop('file_path')
object.pop('deprecated')
YmlWriter.writeYmlFile(os.path.join(security_content_folder, 'investigations', file_name))
os.remove(file_path)
elif object['type'] == 'Baseline':
file_name = self.convertNameToFileName(object)
file_path = object['file_path']
object.pop('file_path')
object.pop('deprecated')
YmlWriter.writeYmlFile(os.path.join(security_content_folder, 'baselines', file_name))
os.remove(file_path)
def convertNameToFileName(self, obj: dict):
file_name = obj['name'] \
.replace(' ', '_') \
.replace('-','_') \
.replace('.','_') \
.replace('/','_') \
.lower()
file_name = file_name + '.yml'
return file_name
@@ -10,7 +10,7 @@ def test_read_and_write_yml():
'obj_to_yml_data/attempted_credential_dump_from_registry_via_reg_exe.yml')
yml_obj = YmlReader.load_file(file_path)
adapter = ObjToYmlAdapter()
adapter.writeObjects([yml_obj])
adapter.writeObjectsInPlace([yml_obj])
ref_file_path = os.path.join(os.path.dirname(__file__),
'obj_to_yml_data_ref/attempted_credential_dump_from_registry_via_reg_exe.yml')
+27 -3
View File
@@ -3,6 +3,7 @@ import argparse
import os
from contentctl_core.application.use_cases.content_changer import ContentChanger, ContentChangerInputDto
from contentctl_core.application.use_cases.content_organizer import ContentOrganizer, ContentOrganizerInputDto
from contentctl_core.application.factory.object_factory import ObjectFactoryInputDto
from contentctl_infrastructure.builder.security_content_object_builder import SecurityContentObjectBuilder
from contentctl_infrastructure.builder.security_content_director import SecurityContentDirector
@@ -69,12 +70,27 @@ def content_changer(args) -> None:
content_changer.execute(input_dto)
def content_organizer(args) -> None:
factory_input_dto = ObjectFactoryInputDto(
os.path.abspath(args.path),
SecurityContentObjectBuilder(),
SecurityContentDirector()
)
input_dto = ContentOrganizerInputDto(
ObjToYmlAdapter(),
factory_input_dto,
os.path.abspath(args.security_content_path)
)
content_organizer = ContentOrganizer()
content_organizer.execute(input_dto)
def main(args):
# grab arguments
parser = argparse.ArgumentParser(
description="Use `contentctl.py action -h` to get help with any Splunk Security Content action")
parser.add_argument("-p", "--path", required=False, default=".",
help="path to the Splunk Security Content. Defaults to `.`")
parser.set_defaults(func=lambda _: parser.print_help())
actions_parser = parser.add_subparsers(title="Splunk Security Content actions", dest="action")
@@ -82,6 +98,7 @@ def main(args):
#validate_parser = actions_parser.add_parser("validate", help="Validates written content")
#generate_parser = actions_parser.add_parser("generate", help="Generates a deployment package for different platforms (splunk_app)")
content_changer_parser = actions_parser.add_parser("content_changer", help="Change Security Content based on defined rules")
content_organizer_parser = actions_parser.add_parser("content_organizer", help="Organize Security Content")
# # new arguments
# new_parser.add_argument("-t", "--type", required=False, type=str, default="detection",
@@ -102,11 +119,18 @@ def main(args):
# generate_parser.set_defaults(func=generate)
content_changer_parser.add_argument("-p", "--path", required=True,
help="path to the Splunk Security Content")
help="path to the Splunk Security Content folder")
content_changer_parser.add_argument("-cf", "--change_function", required=True, type=str,
help="Define a change funtion defined in bin/contentctl_core/contentctl/application/use_cases/content_changer.py")
content_changer_parser.set_defaults(func=content_changer)
content_organizer_parser.add_argument("-p", "--path", required=True,
help="path to the Splunk Security Content folder")
content_organizer_parser.add_argument("-scp", "--security_content_path", required=True,
help="path to the Splunk Security Content")
content_organizer_parser.set_defaults(func=content_organizer)
# # parse them
args = parser.parse_args()
return args.func(args)