diff --git a/.github/workflows/build-and-validate.yml b/.github/workflows/build-and-validate.yml index f6c2cb2019..475e1cd6e4 100644 --- a/.github/workflows/build-and-validate.yml +++ b/.github/workflows/build-and-validate.yml @@ -40,13 +40,29 @@ jobs: exit 0 fi - validate-content: + validate-and-build: #Note that the CircleCI job used a Container. The way to do this with Github Actions #is to first start up a Virtual Machine, then we can by following: # https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idcontainer runs-on: ubuntu-latest needs: [validate-tag-if-present] steps: + + - name: Configure Enrichment and Tag + id: vars + run: | + if [ $(echo ${GITHUB_REF} | grep "^refs/tags/*") ]; then + #failed to find the refs/tags/ beginning, grab and set the tag + echo "Release is TAGGED!" + echo "::set-output name=tag::${GITHUB_REF#refs/tags/}" + echo "::set-output name=skip_enrichment_var::" + else + #Not a tagged relese + echo "Release is NOT TAGGED!" + echo "::set-output name=tag::" + echo "::set-output name=skip_enrichment_var::--skip_enrichment" + fi + #Previous config chose which branch/tag to operate on. #I think Github is smart enough to choose based on whether it's a pull request or push + other info? - name: Check out the repository code @@ -62,38 +78,27 @@ jobs: architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified - #TODO: CircleCI restore_cache equivalent - - #don't need to install python3 or python3-dev since it was handled by the action above? - #Also, no support for YAML anchors/aliases in Github Actions... - name: Install System Packages run: | sudo apt update -qq sudo apt install jq -qq - #TODO: CircleCI save_cache equivalent + - name: Install Python Dependencies run: | #Get the virtualenv set up rm -rf venv - python3 -m venv --clear venv - source venv/bin/activate - python3 -m pip install --upgrade pip - python3 -m pip install wheel - python3 -m pip install -q -r requirements.txt + python -m venv --clear .venv + source .venv/bin/activate + python -m pip install --upgrade pip + python -m pip install wheel + python -m pip install -q -r requirements.txt - - name: run validate + - name: content_ctl validate run: | - source venv/bin/activate - python3 contentctl.py -p . validate -pr ESCU - python3 contentctl.py -p . validate -pr SSA - - - # - name: Get CTI Repo for Mitre context - # uses: actions/checkout@v2 - # with: - # repository: mitre/cti #check out https://github.com/mitre/cti.git, defaults to HEAD - # path: "cti/" + source .venv/bin/activate + python contentctl.py -p . ${{ steps.vars.outputs.skip_enrichment_var }} validate -pr ESCU > /dev/null + python contentctl.py -p . ${{ steps.vars.outputs.skip_enrichment_var }} validate -pr SSA > /dev/null #Now generate the documentation (uses Node) @@ -101,76 +106,32 @@ jobs: with: node-version: '14' #can easily be changed to a different version - - name: Generate documentation + - name: contentctl docgen run: | - ls -lah - #Enter the virtualenv and run the docgen - source venv/bin/activate - python3 contentctl.py -p . docgen -o docs + source .venv/bin/activate + python contentctl.py -p . --skip_enrichment docgen -o docs #Now generate the spec docs npm install -g @adobe/jsonschema2md jsonschema2md -d spec -o docs/spec -f yaml -e spec.json -x - #Clean up extra properties on docs rm -rf docs/spec/*-*.md - echo "****** BRANCH INFORMATION ******" - git branch - git branch --show-current - - build-sources: - runs-on: ubuntu-latest - needs: validate-content - steps: - - name: Checkout Repo - uses: actions/checkout@v2 - - - uses: actions/setup-python@v2 - with: - python-version: '3.9' #Available versions here - https://github.com/actions/python-versions/releases easy to change/make a matrix/use pypy - architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified - - - name: Install System Packages - run: | - sudo apt update -qq - sudo apt install jq -qq - - name: Install Python Dependencies + - name: contentctl generate run: | - #Get the virtualenv set up - rm -rf venv - python3 -m venv --clear venv - source venv/bin/activate - python3 -m pip install --upgrade pip - python3 -m pip install wheel - python3 -m pip install -q -r requirements.txt - - - name: Run Generate - run: | - source venv/bin/activate + source .venv/bin/activate rm -rf dist/escu/default/data/ui/panels/*.xml - python3 contentctl.py --path . generate --product ESCU --output dist/escu - python3 contentctl.py --path . generate --product SSA --output dist/ssa + python contentctl.py --path . ${{ steps.vars.outputs.skip_enrichment_var }} generate --product ESCU --output dist/escu > /dev/null + python contentctl.py --path . ${{ steps.vars.outputs.skip_enrichment_var }} generate --product SSA --output dist/ssa > /dev/null - name: Copy lookups .mlmodel files run: | cd lookups count=`ls -1 *.mlmodel 2>/dev/null | wc -l` if [ $count != 0 ] - then cp -rv *.mlmodel ../dist/escu/lookups - else echo "No mlmodel files to copy" - fi - - #Tag is '' for non-tagged push and the tag name for a tagged release - - name: Set tag - id: vars - run: | - if [ $(echo ${GITHUB_REF} | grep "^refs/tags/*") ]; then - #failed to find the refs/tags/ beginning, grab and set the tag - echo "Release is TAGGED!" - echo "::set-output name=tag::${GITHUB_REF#refs/tags/}" - else - #Not a tagged relese - echo "Release is NOT TAGGED!" - echo "::set-output name=tag::" + then + cp -rv *.mlmodel ../dist/escu/lookups + else + echo "No mlmodel files to copy" fi - name: Update Version and Build number @@ -188,57 +149,24 @@ jobs: sed -i "s/^version = .*$/version = $CONTENT_VERSION/g" dist/escu/default/app.conf sed -i "s/\"version\": .*$/\"version\": \"$CONTENT_VERSION\"/g" dist/escu/app.manifest sed -i "s/version = .*$/version = $CONTENT_VERSION/g" dist/escu/default/content-version.conf - tar -czf content-pack-build-escu.tar.gz dist/escu/* + mkdir build + tar -czf build/content-pack-build-escu.tar.gz dist/escu/* # update build number and version for ssa - tar -czf content-pack-build-ssa.tar.gz dist/ssa/* - - - name: Persist to Workspace - uses: actions/upload-artifact@v2 - with: - name: content-pack-build - path: | - content-pack-build-escu.tar.gz - content-pack-build-ssa.tar.gz - - build-package: - runs-on: ubuntu-latest - needs: [validate-content, build-sources] - - steps: - - uses: actions/download-artifact@v2 - with: - name: content-pack-build - path: build/ - - #This explicitly uses a different version of python (2.7) - - uses: actions/setup-python@v2 - with: - python-version: '2.7' #Available versions here - https://github.com/actions/python-versions/releases easy to change/make a matrix/use pypy - architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified - - - name: Get virtualenv for Python 2.7 - run: | - sudo apt install virtualenv + tar -czf build/content-pack-build-ssa.tar.gz dist/ssa/* - - name: Grab Splunk Packaging Toolkit + - name: Download and Install Splunk Packaging Toolkit run : | - curl -Ls https://download.splunk.com/misc/packaging-toolkit/splunk-packaging-toolkit-0.9.0.tar.gz -o splunk-packaging-toolkit-latest.tar.gz + source .venv/bin/activate + curl -Ls https://download.splunk.com/misc/packaging-toolkit/splunk-packaging-toolkit-1.0.1.tar.gz -o splunk-packaging-toolkit-latest.tar.gz mkdir slim-latest tar -zxf splunk-packaging-toolkit-latest.tar.gz -C slim-latest --strip-components=1 - - - name: Install Splunk Packaging Toolkit (slim) - run: | cd slim-latest - virtualenv --python=/usr/bin/python2.7 --clear venv - source venv/bin/activate - python2 -m pip install --upgrade pip - python2 -m pip install wheel - python2 -m pip install semantic_version - python2 -m pip install . + python -m pip install . + cd .. - - name: Create a .spl for this Build Using Slim + - name: Build ESCU run: | - source slim-latest/venv/bin/activate + source .venv/bin/activate cd build tar -zxf content-pack-build-escu.tar.gz tar -zxf content-pack-build-ssa.tar.gz @@ -253,7 +181,8 @@ jobs: tar -zcf upload/SSA_Content-NO_SLIM.tar.gz SSA_Content cp upload/SSA_Content-*.tar.gz SSA_Content-latest.tar.gz sha256sum SSA_Content-latest.tar.gz >> checksum.txt - + + - name: store_artifacts uses: actions/upload-artifact@v2 with: @@ -269,13 +198,13 @@ jobs: build/DA-ESS-ContentUpdate-latest.tar.gz build/SSA_Content-latest.tar.gz build/checksum.txt - + #Everything below this line should ONLY run on a tag and nothing else #We still want all of the above checks to run and pass before running these run-appinspect: runs-on: ubuntu-latest - needs: [validate-content, build-sources, build-package] + needs: [validate-and-build] #Only run when tagged if: startsWith(github.ref, 'refs/tags/') steps: @@ -331,7 +260,7 @@ jobs: create-report: runs-on: ubuntu-latest - needs: [validate-content, build-sources, build-package, run-appinspect] + needs: [validate-and-build, run-appinspect] #Only run when tagged if: startsWith(github.ref, 'refs/tags/') steps: @@ -379,7 +308,7 @@ jobs: update-sources-github: runs-on: ubuntu-latest - needs: [validate-content, build-sources, build-package, run-appinspect, create-report] + needs: [validate-and-build, run-appinspect, create-report] #Only run when tagged if: startsWith(github.ref, 'refs/tags/') steps: @@ -424,12 +353,12 @@ jobs: - name: Run doc-gen run: | source venv/bin/activate - python3 contentctl.py -p . docgen -o docs + python3 contentctl.py -p . docgen -o docs > /dev/null - name: Run reporting run: | source venv/bin/activate - python3 contentctl.py -p . reporting + python3 contentctl.py -p . reporting > /dev/null - name: Update github with new docs and package bits run: | @@ -453,7 +382,7 @@ jobs: #Github-maintained release action is in archived state: https://github.com/actions/create-release #They recommend several and we use the following with the most stars: https://github.com/softprops/action-gh-release runs-on: ubuntu-latest - needs: [validate-content, build-sources, build-package, run-appinspect, create-report, update-sources-github] + needs: [validate-and-build, run-appinspect, create-report] #Only run when tagged if: startsWith(github.ref, 'refs/tags/') steps: @@ -493,7 +422,7 @@ jobs: attack-range-update: runs-on: ubuntu-latest - needs: [validate-content, build-sources, build-package, run-appinspect, create-report, update-sources-github, publish-github-release] + needs: [validate-and-build, run-appinspect, create-report] #Only run when tagged if: startsWith(github.ref, 'refs/tags/') steps: @@ -519,7 +448,7 @@ jobs: master-api-update: runs-on: ubuntu-latest - needs: [validate-content, build-sources, build-package, run-appinspect, create-report, update-sources-github, publish-github-release, attack-range-update] + needs: [validate-and-build, run-appinspect, create-report] #Only run when tagged if: startsWith(github.ref, 'refs/tags/') steps: diff --git a/bin/contentctl_project/contentctl_core/application/factory/ba_factory.py b/bin/contentctl_project/contentctl_core/application/factory/ba_factory.py index e611a15304..d5050d854c 100644 --- a/bin/contentctl_project/contentctl_core/application/factory/ba_factory.py +++ b/bin/contentctl_project/contentctl_core/application/factory/ba_factory.py @@ -33,9 +33,10 @@ def __init__(self, output_dto: BAFactoryOutputDto) -> None: def execute(self, input_dto: BAFactoryInputDto) -> None: self.input_dto = input_dto - + print("Creating Security Content - SSA. This may take some time...") self.createSecurityContent(SecurityContentType.unit_tests) self.createSecurityContent(SecurityContentType.detections) + @@ -48,15 +49,24 @@ def createSecurityContent(self, type: SecurityContentType) -> list: validation_error_found = False - for file in files: + files_with_ssa = [f for f in files if 'ssa___' in f] + for index,file in enumerate(files_with_ssa): + + #Index + 1 because we are zero indexed, not 1 indexed. This ensures + # that printouts end at 100%, not some other number + progress_percent = ((index+1)/len(files_with_ssa)) * 100 + if 'ssa__' in file: + progress_percent = ((index+1)/len(files_with_ssa)) * 100 try: if type == SecurityContentType.detections: + print(f"\r{'Detections Progress'.rjust(23)}: [{progress_percent:3.0f}%]...", end="", flush=True) self.input_dto.director.constructDetection(self.input_dto.detection_builder, file, [], [], [], self.output_dto.tests, {}, [], []) detection = self.input_dto.detection_builder.getObject() if not detection.deprecated and not detection.experimental: self.output_dto.detections.append(detection) elif type == SecurityContentType.unit_tests: + print(f"\r{'Unit Tests Progress'.rjust(23)}: [{progress_percent:3.0f}%]...", end="", flush=True) self.input_dto.director.constructTest(self.input_dto.basic_builder, file) test = self.input_dto.basic_builder.getObject() self.output_dto.tests.append(test) @@ -65,6 +75,7 @@ def createSecurityContent(self, type: SecurityContentType) -> list: print('\nValidation Error for file ' + file) print(e) validation_error_found = True + print("Done!") if validation_error_found: sys.exit(1) \ No newline at end of file diff --git a/bin/contentctl_project/contentctl_core/application/factory/factory.py b/bin/contentctl_project/contentctl_core/application/factory/factory.py index 1b41524232..9fa6e81cbe 100644 --- a/bin/contentctl_project/contentctl_core/application/factory/factory.py +++ b/bin/contentctl_project/contentctl_core/application/factory/factory.py @@ -14,7 +14,7 @@ from bin.contentctl_project.contentctl_core.application.builder.playbook_builder import PlaybookBuilder from bin.contentctl_project.contentctl_core.application.builder.director import Director from bin.contentctl_project.contentctl_core.application.factory.utils.utils import Utils - +from bin.contentctl_project.contentctl_core.domain.entities.link_validator import LinkValidator @dataclass(frozen=True) class FactoryInputDto: @@ -27,6 +27,7 @@ class FactoryInputDto: playbook_builder: PlaybookBuilder director: Director attack_enrichment: dict + force_cached_or_offline: bool = True @dataclass() @@ -53,7 +54,7 @@ def __init__(self, output_dto: FactoryOutputDto) -> None: def execute(self, input_dto: FactoryInputDto) -> None: self.input_dto = input_dto - + print("Creating Security Content - ESCU. This may take some time...") # order matters to load and enrich security content types self.createSecurityContent(SecurityContentType.unit_tests) self.createSecurityContent(SecurityContentType.lookups) @@ -64,9 +65,11 @@ def execute(self, input_dto: FactoryInputDto) -> None: self.createSecurityContent(SecurityContentType.playbooks) self.createSecurityContent(SecurityContentType.detections) self.createSecurityContent(SecurityContentType.stories) - + LinkValidator.print_link_validation_errors() + 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), 'ESCU')) @@ -76,59 +79,151 @@ def createSecurityContent(self, type: SecurityContentType) -> list: files = Utils.get_all_yml_files_from_directory(os.path.join(self.input_dto.input_path, str(type.name))) validation_error_found = False - - for file in files: - if not 'ssa__' in file: + + #Code below us commented out, but allows threaded construction of detections + #No issues have been observed running construction in parallel + ''' + import copy + import threading + NUM_THREADS = 1 + + def make_detections_thread(index:int): + my_dto = copy.deepcopy(self.input_dto) + for i in range(index, len(files), NUM_THREADS): + file = files[i] + if 'ssa__' in file: + continue try: 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()) + my_dto.director.constructLookup(my_dto.basic_builder, file) + self.output_dto.lookups.append(my_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()) + my_dto.director.constructMacro(my_dto.basic_builder, file) + self.output_dto.macros.append(my_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()) + my_dto.director.constructDeployment(my_dto.basic_builder, file) + self.output_dto.deployments.append(my_dto.basic_builder.getObject()) elif type == SecurityContentType.playbooks: - self.input_dto.director.constructPlaybook(self.input_dto.playbook_builder, file) - self.output_dto.playbooks.append(self.input_dto.playbook_builder.getObject()) + my_dto.director.constructPlaybook(my_dto.playbook_builder, file) + self.output_dto.playbooks.append(my_dto.playbook_builder.getObject()) elif type == SecurityContentType.baselines: - self.input_dto.director.constructBaseline(self.input_dto.baseline_builder, file, self.output_dto.deployments) - baseline = self.input_dto.baseline_builder.getObject() + my_dto.director.constructBaseline(my_dto.baseline_builder, file, self.output_dto.deployments) + baseline = my_dto.baseline_builder.getObject() self.output_dto.baselines.append(baseline) elif type == SecurityContentType.investigations: - self.input_dto.director.constructInvestigation(self.input_dto.investigation_builder, file) - investigation = self.input_dto.investigation_builder.getObject() + my_dto.director.constructInvestigation(my_dto.investigation_builder, file) + investigation = my_dto.investigation_builder.getObject() self.output_dto.investigations.append(investigation) elif type == SecurityContentType.stories: - self.input_dto.director.constructStory(self.input_dto.story_builder, file, + my_dto.director.constructStory(my_dto.story_builder, file, self.output_dto.detections, self.output_dto.baselines, self.output_dto.investigations) - story = self.input_dto.story_builder.getObject() + story = my_dto.story_builder.getObject() self.output_dto.stories.append(story) elif type == SecurityContentType.detections: - self.input_dto.director.constructDetection(self.input_dto.detection_builder, file, + my_dto.director.constructDetection(my_dto.detection_builder, file, self.output_dto.deployments, self.output_dto.playbooks, self.output_dto.baselines, - self.output_dto.tests, self.input_dto.attack_enrichment, self.output_dto.macros, - self.output_dto.lookups) - detection = self.input_dto.detection_builder.getObject() + self.output_dto.tests, my_dto.attack_enrichment, self.output_dto.macros, + self.output_dto.lookups, my_dto.force_cached_or_offline) + detection = my_dto.detection_builder.getObject() self.output_dto.detections.append(detection) elif type == SecurityContentType.unit_tests: - self.input_dto.director.constructTest(self.input_dto.basic_builder, file) - test = self.input_dto.basic_builder.getObject() + my_dto.director.constructTest(my_dto.basic_builder, file) + test = my_dto.basic_builder.getObject() self.output_dto.tests.append(test) except ValidationError as e: print('\nValidation Error for file ' + file) print(e) validation_error_found = True + + + + builder_threads = [] + + for t in range(NUM_THREADS): + thread = threading.Thread(target=make_detections_thread,args=(t,)) + thread.start() + builder_threads.append(thread) + + for thread in builder_threads: + thread.join() + ''' + + #Non threaded, production version of the construction code + files_without_ssa = [f for f in files if 'ssa___' not in f] + for index,file in enumerate(files_without_ssa): + + #Index + 1 because we are zero indexed, not 1 indexed. This ensures + # that printouts end at 100%, not some other number + progress_percent = ((index+1)/len(files_without_ssa)) * 100 + try: + if type == SecurityContentType.lookups: + print(f"\r{'Lookups Progress'.rjust(23)}: [{progress_percent:3.0f}%]...", end="", flush=True) + 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: + print(f"\r{'Playbooks Progress'.rjust(23)}: [{progress_percent:3.0f}%]...", end="", flush=True) + 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: + print(f"\r{'Deployments Progress'.rjust(23)}: [{progress_percent:3.0f}%]...", end="", flush=True) + 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: + print(f"\r{'Playbooks Progress'.rjust(23)}: [{progress_percent:3.0f}%]...", end="", flush=True) + self.input_dto.director.constructPlaybook(self.input_dto.playbook_builder, file) + self.output_dto.playbooks.append(self.input_dto.playbook_builder.getObject()) + + elif type == SecurityContentType.baselines: + print(f"\r{'Baselines Progress'.rjust(23)}: [{progress_percent:3.0f}%]...", end="", flush=True) + self.input_dto.director.constructBaseline(self.input_dto.baseline_builder, file, self.output_dto.deployments) + baseline = self.input_dto.baseline_builder.getObject() + self.output_dto.baselines.append(baseline) + + elif type == SecurityContentType.investigations: + print(f"\r{'Investigations Progress'.rjust(23)}: [{progress_percent:3.0f}%]...", end="", flush=True) + self.input_dto.director.constructInvestigation(self.input_dto.investigation_builder, file) + investigation = self.input_dto.investigation_builder.getObject() + self.output_dto.investigations.append(investigation) + + elif type == SecurityContentType.stories: + print(f"\r{'Stories Progress'.rjust(23)}: [{progress_percent:3.0f}%]...", end="", flush=True) + self.input_dto.director.constructStory(self.input_dto.story_builder, file, + self.output_dto.detections, self.output_dto.baselines, self.output_dto.investigations) + story = self.input_dto.story_builder.getObject() + self.output_dto.stories.append(story) + + elif type == SecurityContentType.detections: + print(f"\r{'Detections Progress'.rjust(23)}: [{progress_percent:3.0f}%]...", end="", flush=True) + 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.tests, self.input_dto.attack_enrichment, self.output_dto.macros, + self.output_dto.lookups, self.input_dto.force_cached_or_offline) + detection = self.input_dto.detection_builder.getObject() + self.output_dto.detections.append(detection) + + elif type == SecurityContentType.unit_tests: + print(f"\r{'Unit Tests Progress'.rjust(23)}: [{progress_percent:3.0f}%]...", end="", flush=True) + self.input_dto.director.constructTest(self.input_dto.basic_builder, file) + test = self.input_dto.basic_builder.getObject() + self.output_dto.tests.append(test) + + except ValidationError as e: + print('\nValidation Error for file ' + file) + print(e) + validation_error_found = True + print("Done!") if validation_error_found: sys.exit(1) \ No newline at end of file diff --git a/bin/contentctl_project/contentctl_core/application/use_cases/content_changer.py b/bin/contentctl_project/contentctl_core/application/use_cases/content_changer.py index 0573ab422c..dadcb7a07c 100644 --- a/bin/contentctl_project/contentctl_core/application/use_cases/content_changer.py +++ b/bin/contentctl_project/contentctl_core/application/use_cases/content_changer.py @@ -1,6 +1,8 @@ +import argparse +from ast import arg import re import uuid - +import inspect from dataclasses import dataclass from bin.contentctl_project.contentctl_core.application.factory.object_factory import ObjectFactory, ObjectFactoryInputDto @@ -13,7 +15,6 @@ class ContentChangerInputDto: factory_input_dto : ObjectFactoryInputDto converter_func_name : str - class ContentChanger: def execute(self, input_dto: ContentChangerInputDto) -> None: @@ -26,21 +27,24 @@ def execute(self, input_dto: ContentChangerInputDto) -> None: input_dto.adapter.writeObjectsInPlace(objects) + @staticmethod + def enumerate_content_changer_functions(exclude_functions: list[str] = ["enumerate_content_changer_functions", "execute", "example_converter_func"]) -> list[str]: + members = inspect.getmembers(ContentChanger, predicate=inspect.isfunction) + function_names = [function_object[0] for function_object in members if function_object[0] not in exclude_functions] + return function_names - # Define Converter Functions here + def all(self, objects : list) -> None: + for func_name in ContentChanger.enumerate_content_changer_functions(): + if func_name not in ["all", "change_test_file_format"]: + print(f"calling {func_name}") + func_object = getattr(self, func_name) + func_object(objects) - def example_converter_func(self, objects : list) -> None: - for obj in objects: - obj['author'] = obj['author'].upper() - def add_default_risk_values(self, objects : list) -> None: + # Define Converter Functions here + def example_converter_func(self, objects : list) -> None: for obj in objects: - if not 'confidence' in obj['tags']: - obj['tags']['confidence'] = 50 - if not 'impact' in obj['tags']: - obj['tags']['impact'] = 50 - if not 'risk_score' in obj['tags']: - obj['tags']['risk_score'] = 25 + obj['author'] = obj['author'].upper() def add_unknown_context(self, objects : list) -> None: for obj in objects: @@ -104,8 +108,9 @@ def add_default_kill_chain_phases(self, objects : list) -> None: def fix_wrong_calculated_risk_score(self, objects : list) -> None: for obj in objects: - calculated_risk_score = (int(obj['tags']['impact']))*(int(obj['tags']['confidence']))/100 - if calculated_risk_score != int(obj['tags']['risk_score']): + #Risk score must be an integer, so we round it to the nearest integer + calculated_risk_score = round((obj['tags']['impact'] * obj['tags']['confidence'])/100) + if calculated_risk_score != round(obj['tags']['risk_score']): obj['tags']['risk_score'] = calculated_risk_score def add_asset_type_to_endpoint_detections(self, objects : list) -> None: @@ -174,13 +179,18 @@ def fix_kill_chain(self, objects : list) -> None: def add_default_confidence_impact_risk_score(self, objects : list) -> None: for obj in objects: - if 'confidence' not in obj['tags']: + updated = True + if not 'confidence' in obj['tags']: + updated = True obj['tags']['confidence'] = 50 - if 'impact' not in obj['tags']: + if not 'impact' in obj['tags']: + updated = True obj['tags']['impact'] = 50 - if 'risk_score' not in obj['tags']: - calculated_risk_score = (int(obj['tags']['impact']))*(int(obj['tags']['confidence']))/100 - obj['tags']['risk_score'] = calculated_risk_score + if not 'risk_score' in obj['tags'] or updated == True: + #Recalculate the risk score if we have added/updated + #the confidence or impact fields OR the risk_score + #was missing in the first place + self.fix_wrong_calculated_risk_score([obj]) def fix_cc(self, objects : list) -> None: for obj in objects: diff --git a/bin/contentctl_project/contentctl_core/application/use_cases/generate.py b/bin/contentctl_project/contentctl_core/application/use_cases/generate.py index 3f3f4f5ce2..e0732c5840 100644 --- a/bin/contentctl_project/contentctl_core/application/use_cases/generate.py +++ b/bin/contentctl_project/contentctl_core/application/use_cases/generate.py @@ -2,6 +2,7 @@ import shutil from dataclasses import dataclass +from typing import Union from bin.contentctl_project.contentctl_core.domain.entities.enums.enums import SecurityContentProduct, SecurityContentType from bin.contentctl_project.contentctl_core.application.adapter.adapter import Adapter @@ -13,8 +14,8 @@ @dataclass(frozen=True) class GenerateInputDto: output_path: str - factory_input_dto: FactoryInputDto - ba_factory_input_dto: BAFactoryInputDto + factory_input_dto: Union[FactoryInputDto,None] + ba_factory_input_dto: Union[BAFactoryInputDto,None] adapter : Adapter product: SecurityContentProduct diff --git a/bin/contentctl_project/contentctl_core/application/use_cases/validate.py b/bin/contentctl_project/contentctl_core/application/use_cases/validate.py index a83f831c6e..65637518d9 100644 --- a/bin/contentctl_project/contentctl_core/application/use_cases/validate.py +++ b/bin/contentctl_project/contentctl_core/application/use_cases/validate.py @@ -3,6 +3,7 @@ from dataclasses import dataclass from pydantic import ValidationError +from typing import Union from bin.contentctl_project.contentctl_core.domain.entities.enums.enums import SecurityContentProduct from bin.contentctl_project.contentctl_core.application.factory.factory import FactoryInputDto, Factory, FactoryOutputDto @@ -11,8 +12,8 @@ @dataclass(frozen=True) class ValidateInputDto: - factory_input_dto: FactoryInputDto - ba_factory_input_dto: BAFactoryInputDto + factory_input_dto: Union[FactoryInputDto,None] + ba_factory_input_dto: Union[BAFactoryInputDto,None] product: SecurityContentProduct diff --git a/bin/contentctl_project/contentctl_core/domain/entities/baseline.py b/bin/contentctl_project/contentctl_core/domain/entities/baseline.py index cd0b5ee32d..6f6026ed2e 100644 --- a/bin/contentctl_project/contentctl_core/domain/entities/baseline.py +++ b/bin/contentctl_project/contentctl_core/domain/entities/baseline.py @@ -10,6 +10,7 @@ from bin.contentctl_project.contentctl_core.domain.entities.enums.enums import DataModel from bin.contentctl_project.contentctl_core.domain.entities.baseline_tags import BaselineTags from bin.contentctl_project.contentctl_core.domain.entities.deployment import Deployment +from bin.contentctl_project.contentctl_core.domain.entities.link_validator import LinkValidator class Baseline(BaseModel, SecurityContentObject): @@ -25,6 +26,7 @@ class Baseline(BaseModel, SecurityContentObject): search: str how_to_implement: str known_false_positives: str + check_references: bool = False #Validation is done in order, this field must be defined first references: list tags: BaselineTags @@ -84,15 +86,17 @@ def encode_error(cls, v, values, field): @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"]) + + + if 'check_references' in values and values['check_references'] is False: + #Reference checking is NOT enabled + return v + elif 'check_references' not in values: + raise(Exception("Member 'check_references' missing from Baseline!")) + - return v + for reference in v: + LinkValidator.validate_reference(reference, values['name']) @validator('search') def search_validate(cls, v, values): diff --git a/bin/contentctl_project/contentctl_core/domain/entities/detection.py b/bin/contentctl_project/contentctl_core/domain/entities/detection.py index d2bb95035f..2db26c076c 100644 --- a/bin/contentctl_project/contentctl_core/domain/entities/detection.py +++ b/bin/contentctl_project/contentctl_core/domain/entities/detection.py @@ -1,13 +1,14 @@ -import enum import uuid import string -import re import requests - +import time from pydantic import BaseModel, validator, root_validator from dataclasses import dataclass from datetime import datetime + + + from bin.contentctl_project.contentctl_core.domain.entities.security_content_object import SecurityContentObject from bin.contentctl_project.contentctl_core.domain.entities.enums.enums import AnalyticsType from bin.contentctl_project.contentctl_core.domain.entities.enums.enums import DataModel @@ -18,6 +19,11 @@ from bin.contentctl_project.contentctl_core.domain.entities.lookup import Lookup from bin.contentctl_project.contentctl_core.domain.entities.baseline import Baseline from bin.contentctl_project.contentctl_core.domain.entities.playbook import Playbook +from bin.contentctl_project.contentctl_core.domain.entities.link_validator import LinkValidator +import sys + + + class Detection(BaseModel, SecurityContentObject): # detection spec @@ -32,8 +38,10 @@ class Detection(BaseModel, SecurityContentObject): search: str how_to_implement: str known_false_positives: str + check_references: bool = False #Validation is done in order, this field must be defined first references: list tags: DetectionTags + # enrichments deprecated: bool = None @@ -122,18 +130,21 @@ def name_max_length(cls, values): raise ValueError('name is longer then 67 chars: ' + values["name"]) return values - - # @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('references') + def references_check(cls, v, values): + + + if 'check_references' in values and values['check_references'] is False: + #Reference checking is NOT enabled + return v + elif 'check_references' not in values: + raise(Exception("Member 'check_references' missing from Detection!")) + + + for reference in v: + LinkValidator.validate_reference(reference, values['name']) + return v @validator('search') def search_validate(cls, v, values): diff --git a/bin/contentctl_project/contentctl_core/domain/entities/detection_tags.py b/bin/contentctl_project/contentctl_core/domain/entities/detection_tags.py index e506ad08d9..51081a8e89 100644 --- a/bin/contentctl_project/contentctl_core/domain/entities/detection_tags.py +++ b/bin/contentctl_project/contentctl_core/domain/entities/detection_tags.py @@ -29,7 +29,7 @@ class DetectionTags(BaseModel): supported_tas: list = None # enrichment - mitre_attack_enrichments: list[MitreAttackEnrichment] = None + mitre_attack_enrichments: list[MitreAttackEnrichment] = [] confidence_id: int = None impact_id: int = None context_ids: list = None diff --git a/bin/contentctl_project/contentctl_core/domain/entities/investigation.py b/bin/contentctl_project/contentctl_core/domain/entities/investigation.py index b177465927..340a544c2b 100644 --- a/bin/contentctl_project/contentctl_core/domain/entities/investigation.py +++ b/bin/contentctl_project/contentctl_core/domain/entities/investigation.py @@ -12,6 +12,7 @@ from bin.contentctl_project.contentctl_core.domain.entities.enums.enums import AnalyticsType from bin.contentctl_project.contentctl_core.domain.entities.enums.enums import DataModel from bin.contentctl_project.contentctl_core.domain.entities.investigation_tags import InvestigationTags +from bin.contentctl_project.contentctl_core.domain.entities.link_validator import LinkValidator class Investigation(BaseModel, SecurityContentObject): @@ -27,6 +28,7 @@ class Investigation(BaseModel, SecurityContentObject): search: str how_to_implement: str known_false_positives: str + check_references: bool = False #Validation is done in order, this field must be defined first references: list inputs: list = None tags: InvestigationTags @@ -81,15 +83,17 @@ def encode_error(cls, v, values, field): @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"]) + + + if 'check_references' in values and values['check_references'] is False: + #Reference checking is NOT enabled + return v + elif 'check_references' not in values: + raise(Exception("Member 'check_references' missing from Investigation!")) + - return v + for reference in v: + LinkValidator.validate_reference(reference, values['name']) @validator('search') def search_validate(cls, v, values): diff --git a/bin/contentctl_project/contentctl_core/domain/entities/link_validator.py b/bin/contentctl_project/contentctl_core/domain/entities/link_validator.py new file mode 100644 index 0000000000..a022f2a963 --- /dev/null +++ b/bin/contentctl_project/contentctl_core/domain/entities/link_validator.py @@ -0,0 +1,159 @@ +from lib2to3.pytree import Base +import re +from tracemalloc import start +from unittest.mock import DEFAULT +from pydantic import BaseModel, validator, root_validator,Field +from typing import Union, Callable +import requests +import urllib3, urllib3.exceptions +import time +import abc + +import os +import shelve + +DEFAULT_USER_AGENT_STRING = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.41 Safari/537.36" +ALLOWED_HTTP_CODES = [200] +class LinkStats(BaseModel): + #Static Values + method: Callable = requests.get + allowed_http_codes: list[int] = ALLOWED_HTTP_CODES + access_count: int = 1 #when constructor is called, it has been accessed once! + timeout_seconds: int = 15 + allow_redirects: bool = True + headers: dict = {"User-Agent": DEFAULT_USER_AGENT_STRING} + verify_ssl: bool = False + if verify_ssl is False: + urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) + + #Values generated at runtime. + #We need to assign these some default values to get the + #validation working since ComputedField has not yet been + #introduced to Pydantic + reference: str + referencing_files: set[str] + redirect: Union[str,None] = None + status_code: int = 0 + valid: bool = False + resolution_time: float = 0 + + + def is_link_valid(self, referencing_file:str)->bool: + self.access_count += 1 + self.referencing_files.add(referencing_file) + return self.valid + + @root_validator + def check_reference(cls, values): + start_time = time.time() + #Get out all the fields names to make them easier to reference + method = values['method'] + reference = values['reference'] + timeout_seconds = values['timeout_seconds'] + headers = values['headers'] + allow_redirects = values['allow_redirects'] + verify_ssl = values['verify_ssl'] + allowed_http_codes = values['allowed_http_codes'] + if not (reference.startswith("http://") or reference.startswith("https://")): + raise(ValueError(f"Reference {reference} does not begin with http(s). Only http(s) references are supported")) + + try: + get = method(reference, timeout=timeout_seconds, + headers = headers, + allow_redirects=allow_redirects, verify=verify_ssl) + resolution_time = time.time() - start_time + values['status_code'] = get.status_code + values['resolution_time'] = resolution_time + if reference != get.url: + values['redirect'] = get.url + else: + values['redirect'] = None #None is also already the default + + #Returns the updated values and sets them for the object + if get.status_code in allowed_http_codes: + values['valid'] = True + else: + #print(f"Unacceptable HTTP Status Code {get.status_code} received for {reference}") + values['valid'] = False + return values + + except Exception as e: + resolution_time = time.time() - start_time + #print(f"Reference {reference} was not reachable after {resolution_time:.2f} seconds") + values['status_code'] = 0 + values['valid'] = False + values['redirect'] = None + values['resolution_time'] = resolution_time + return values + + +class LinkValidator(abc.ABC): + cache: Union[dict[str,LinkStats], shelve.Shelf] = {} + uncached_checks: int = 0 + total_checks: int = 0 + #cache: dict[str,LinkStats] = {} + + use_file_cache: bool = False + reference_cache_file: str ="lookups/REFERENCE_CACHE.db" + + @staticmethod + def initialize_cache(use_file_cache: bool = False): + LinkValidator.use_file_cache = use_file_cache + if use_file_cache is False: + return + if not os.path.exists(LinkValidator.reference_cache_file): + print(f"Cache at {LinkValidator.reference_cache_file} not found - Creating it.") + + try: + LinkValidator.cache = shelve.open(LinkValidator.reference_cache_file, flag='c', writeback=True) + except: + print(f"Failed to create the cache file {LinkValidator.reference_cache_file}. Reference info will not be cached.") + LinkValidator.cache = {} + + #Remove all of the failures to force those resources to be resolved again + failed_refs = [] + for ref in LinkValidator.cache.keys(): + if LinkValidator.cache[ref].status_code not in ALLOWED_HTTP_CODES: + failed_refs.append(ref) + #can't remove it here because this will throw an error: + #cannot change size of dictionary while iterating over it + else: + #Set the reference count to 0 and referencing files to empty set + LinkValidator.cache[ref].access_count = 0 + LinkValidator.cache[ref].referencing_files = set() + + for ref in failed_refs: + del(LinkValidator.cache[ref]) + + + + + @staticmethod + def close_cache(): + if LinkValidator.use_file_cache: + LinkValidator.cache.close() + + @staticmethod + def validate_reference(reference: str, referencing_file:str, raise_exception_if_failure: bool = False) -> bool: + LinkValidator.total_checks += 1 + if reference not in LinkValidator.cache: + LinkValidator.uncached_checks += 1 + LinkValidator.cache[reference] = LinkStats(reference=reference, referencing_files = set([referencing_file])) + result = LinkValidator.cache[reference].is_link_valid(referencing_file) + + #print(f"Total Checks: {LinkValidator.total_checks}, Percent Cached: {100*(1 - LinkValidator.uncached_checks / LinkValidator.total_checks):.2f}") + + if result is True: + return True + elif raise_exception_if_failure is True: + raise(Exception(f"Reference Link Failed: {reference}")) + else: + return False + @staticmethod + def print_link_validation_errors(): + failures = [LinkValidator.cache[k] for k in LinkValidator.cache if LinkValidator.cache[k].valid is False] + failures.sort(key=lambda d: d.status_code) + for failure in failures: + print(f"Link {failure.reference} invalid with HTTP Status Code [{failure.status_code}] and referenced by the following files:") + for ref in failure.referencing_files: + print(f"\t* {ref}") diff --git a/bin/contentctl_project/contentctl_core/domain/entities/playbook.py b/bin/contentctl_project/contentctl_core/domain/entities/playbook.py index c1696ec72c..9fcafb78c1 100644 --- a/bin/contentctl_project/contentctl_core/domain/entities/playbook.py +++ b/bin/contentctl_project/contentctl_core/domain/entities/playbook.py @@ -6,6 +6,7 @@ from bin.contentctl_project.contentctl_core.domain.entities.security_content_object import SecurityContentObject from bin.contentctl_project.contentctl_core.domain.entities.playbook_tags import PlaybookTag +from bin.contentctl_project.contentctl_core.domain.entities.link_validator import LinkValidator @@ -19,7 +20,23 @@ class Playbook(BaseModel, SecurityContentObject): description: str how_to_implement: str playbook: str + check_references: bool = False #Validation is done in order, this field must be defined first references: list app_list: list tags: PlaybookTag + + @validator('references') + def references_check(cls, v, values): + + + if 'check_references' in values and values['check_references'] is False: + #Reference checking is NOT enabled + return v + elif 'check_references' not in values: + raise(Exception("Member 'check_references' missing from Playbook!")) + + + for reference in v: + LinkValidator.validate_reference(reference, values['name']) + diff --git a/bin/contentctl_project/contentctl_core/domain/entities/story.py b/bin/contentctl_project/contentctl_core/domain/entities/story.py index cae85af56f..107879cc0b 100644 --- a/bin/contentctl_project/contentctl_core/domain/entities/story.py +++ b/bin/contentctl_project/contentctl_core/domain/entities/story.py @@ -7,6 +7,7 @@ from bin.contentctl_project.contentctl_core.domain.entities.security_content_object import SecurityContentObject from bin.contentctl_project.contentctl_core.domain.entities.story_tags import StoryTags +from bin.contentctl_project.contentctl_core.domain.entities.link_validator import LinkValidator class Story(BaseModel, SecurityContentObject): # story spec @@ -17,6 +18,7 @@ class Story(BaseModel, SecurityContentObject): author: str description: str narrative: str + check_references: bool = False #Validation is done in order, this field must be defined first references: list tags: StoryTags @@ -61,14 +63,16 @@ def encode_error(cls, v, values, field): 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"]) + @validator('references') + def references_check(cls, v, values): + + + if 'check_references' in values and values['check_references'] is False: + #Reference checking is NOT enabled + return v + elif 'check_references' not in values: + raise(Exception("Member 'check_references' missing from Story!")) + - # return v \ No newline at end of file + for reference in v: + LinkValidator.validate_reference(reference, values['name']) \ No newline at end of file diff --git a/bin/contentctl_project/contentctl_core/domain/entities/story_tags.py b/bin/contentctl_project/contentctl_core/domain/entities/story_tags.py index 14f905f8b8..639bf033c5 100644 --- a/bin/contentctl_project/contentctl_core/domain/entities/story_tags.py +++ b/bin/contentctl_project/contentctl_core/domain/entities/story_tags.py @@ -13,10 +13,10 @@ class StoryTags(BaseModel): usecase: str # enrichment - mitre_attack_enrichments: list[MitreAttackEnrichment] = None - mitre_attack_tactics: list = None - datamodels: list = None - kill_chain_phases: list = None + mitre_attack_enrichments: list[MitreAttackEnrichment] = [] + mitre_attack_tactics: list = [] + datamodels: list = [] + kill_chain_phases: list = [] @validator('product') diff --git a/bin/contentctl_project/contentctl_core/tests/application/use_cases/test_data_input/stories/ransomware_darkside.yml b/bin/contentctl_project/contentctl_core/tests/application/use_cases/test_data_input/stories/ransomware_darkside.yml index f2e6d8bfd9..b9c2d45c48 100644 --- a/bin/contentctl_project/contentctl_core/tests/application/use_cases/test_data_input/stories/ransomware_darkside.yml +++ b/bin/contentctl_project/contentctl_core/tests/application/use_cases/test_data_input/stories/ransomware_darkside.yml @@ -8,7 +8,7 @@ description: Leverage searches that allow you to detect and investigate unusual 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.' 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 +- https://www.mandiant.com/resources/shining-a-light-on-darkside-ransomware-operations tags: analytic_story: DarkSide Ransomware category: diff --git a/bin/contentctl_project/contentctl_core/tests/application/use_cases/test_data_output/detections/cobalt_strike_named_pipes.yml b/bin/contentctl_project/contentctl_core/tests/application/use_cases/test_data_output/detections/cobalt_strike_named_pipes.yml index 4638e6c952..8cea32f024 100644 --- a/bin/contentctl_project/contentctl_core/tests/application/use_cases/test_data_output/detections/cobalt_strike_named_pipes.yml +++ b/bin/contentctl_project/contentctl_core/tests/application/use_cases/test_data_output/detections/cobalt_strike_named_pipes.yml @@ -34,7 +34,7 @@ references: - https://attack.mitre.org/techniques/T1218/009/ - https://docs.microsoft.com/en-us/windows/win32/ipc/named-pipes - https://gist.github.com/MHaggis/6c600e524045a6d49c35291a21e10752 -- https://www.fireeye.com/blog/threat-research/2021/05/shining-a-light-on-darkside-ransomware-operations.html +- https://www.mandiant.com/resources/shining-a-light-on-darkside-ransomware-operations tags: analytic_story: - Cobalt Strike diff --git a/bin/contentctl_project/contentctl_infrastructure/adapter/obj_to_md_adapter.py b/bin/contentctl_project/contentctl_infrastructure/adapter/obj_to_md_adapter.py index bbc3ccf846..e8cdfb5d03 100644 --- a/bin/contentctl_project/contentctl_infrastructure/adapter/obj_to_md_adapter.py +++ b/bin/contentctl_project/contentctl_infrastructure/adapter/obj_to_md_adapter.py @@ -1,5 +1,5 @@ import os - +import asyncio from bin.contentctl_project.contentctl_core.application.adapter.adapter import Adapter from bin.contentctl_project.contentctl_core.domain.entities.enums.enums import SecurityContentType @@ -7,8 +7,14 @@ class ObjToMdAdapter(Adapter): - + index = 0 + files_to_write = 0 + def writeObjects(self, objects: list, output_path: str, type: SecurityContentType = None) -> None: + self.files_to_write = sum([len(obj) for obj in objects]) + self.index = 0 + progress_percent = ((self.index+1)/self.files_to_write) * 100 + print(f"\r{'Docgen Progress'.rjust(23)}: [{progress_percent:3.0f}%]...", end="", flush=True) attack_tactics = set() datamodels = set() @@ -36,7 +42,7 @@ def writeObjects(self, objects: list, output_path: str, type: SecurityContentTyp self.writeNavigationPageObjects(sorted(list(datamodels)), output_path) self.writeNavigationPageObjects(sorted(list(attack_tactics)), output_path) self.writeNavigationPageObjects(sorted(list(categories)), output_path) - + JinjaWriter.writeObjectsList('doc_story_page.j2', os.path.join(output_path, '_pages/stories.md'), sorted(objects[0], key=lambda x: x.name)) self.writeObjectsMd(objects[0], os.path.join(output_path, '_stories'), 'doc_stories.j2') @@ -45,8 +51,8 @@ def writeObjects(self, objects: list, output_path: str, type: SecurityContentTyp JinjaWriter.writeObjectsList('doc_playbooks_page.j2', os.path.join(output_path, '_pages/paybooks.md'), sorted(objects[2], key=lambda x: x.name)) self.writeObjectsMd(objects[2], os.path.join(output_path, '_playbooks'), 'doc_playbooks.j2') - - + + print("Done!") def writeNavigationPageObjects(self, objects: list, output_path: str) -> None: for obj in objects: JinjaWriter.writeObject('doc_navigation_pages.j2', os.path.join(output_path, '_pages', obj.lower().replace(' ', '_') + '.md'), @@ -57,8 +63,16 @@ def writeNavigationPageObjects(self, objects: list, output_path: str) -> None: def writeObjectsMd(self, objects, output_path: str, template_name: str) -> None: for obj in objects: + progress_percent = ((self.index+1)/self.files_to_write) * 100 + self.index+=1 + print(f"\r{'Docgen Progress'.rjust(23)}: [{progress_percent:3.0f}%]...", end="", flush=True) + JinjaWriter.writeObject(template_name, os.path.join(output_path, obj.name.lower().replace(' ', '_') + '.md'), obj) def writeDetectionsMd(self, objects, output_path: str, template_name: str) -> None: for obj in objects: + progress_percent = ((self.index+1)/self.files_to_write) * 100 + self.index+=1 + print(f"\r{'Docgen Progress'.rjust(23)}: [{progress_percent:3.0f}%]...", end="", flush=True) + JinjaWriter.writeObject(template_name, os.path.join(output_path, obj.date + '-' + obj.name.lower().replace(' ', '_') + '.md'), obj) \ No newline at end of file diff --git a/bin/contentctl_project/contentctl_infrastructure/builder/attack_enrichment.py b/bin/contentctl_project/contentctl_infrastructure/builder/attack_enrichment.py index b74f9cbde1..5a648fca71 100644 --- a/bin/contentctl_project/contentctl_infrastructure/builder/attack_enrichment.py +++ b/bin/contentctl_project/contentctl_infrastructure/builder/attack_enrichment.py @@ -13,17 +13,37 @@ class AttackEnrichment(): @classmethod - def get_attack_lookup(self, store_csv = None) -> dict: + def get_attack_lookup(self, store_csv = None, force_cached_or_offline: bool = False, skip_enrichment:bool = False) -> dict: + print("Getting MITRE Attack Enrichment Data. This may take some time...") attack_lookup = dict() file_path = os.path.join(os.path.dirname(__file__), '../../../../lookups/mitre_enrichment.csv') + if skip_enrichment is True: + print("Skipping enrichment") + return attack_lookup try: + + if force_cached_or_offline is True: + raise(Exception("WARNING - Using cached MITRE Attack Enrichment. Attack Enrichment may be out of date. Only use this setting for offline environments and development purposes.")) + print(f"\r{'Client'.rjust(23)}: [{0:3.0f}%]...", end="", flush=True) lift = attack_client() + print(f"\r{'Client'.rjust(23)}: [{100:3.0f}%]...Done!", end="\n", flush=True) + + print(f"\r{'Enterprise'.rjust(23)}: [{0.0:3.0f}%]...", end="", flush=True) all_enterprise = lift.get_enterprise(stix_format=False) + print(f"\r{'Enterprise'.rjust(23)}: [{100:3.0f}%]...Done!", end="\n", flush=True) + + print(f"\r{'Relationships'.rjust(23)}: [{0.0:3.0f}%]...", end="", flush=True) enterprise_relationships = lift.get_enterprise_relationships() + print(f"\r{'Relationships'.rjust(23)}: [{100:3.0f}%]...Done!", end="\n", flush=True) + + print(f"\r{'Groups'.rjust(23)}: [{0:3.0f}%]...", end="", flush=True) enterprise_groups = lift.get_enterprise_groups() - - for technique in all_enterprise['techniques']: + print(f"\r{'Groups'.rjust(23)}: [{100:3.0f}%]...Done!", end="\n", flush=True) + + for index, technique in enumerate(all_enterprise['techniques']): + progress_percent = ((index+1)/len(all_enterprise['techniques'])) * 100 + print(f"\r\t{'MITRE Technique Progress'.rjust(23)}: [{progress_percent:3.0f}%]...", end="", flush=True) apt_groups = [] for relationship in enterprise_relationships: if (relationship['target_ref'] == technique['id']) and relationship['source_ref'].startswith('intrusion-set'): @@ -67,4 +87,5 @@ def get_attack_lookup(self, store_csv = None) -> dict: attack_lookup = {rows[0]:{'technique': rows[1], 'tactics': rows[2].split('|'), 'groups': rows[3].split('|')} for rows in reader} attack_lookup.pop('mitre_id') + print("Done!") return attack_lookup \ No newline at end of file diff --git a/bin/contentctl_project/contentctl_infrastructure/builder/cve_enrichment.py b/bin/contentctl_project/contentctl_infrastructure/builder/cve_enrichment.py index a6e2ae5cf7..0e509377a5 100644 --- a/bin/contentctl_project/contentctl_infrastructure/builder/cve_enrichment.py +++ b/bin/contentctl_project/contentctl_infrastructure/builder/cve_enrichment.py @@ -1,17 +1,57 @@ from pycvesearch import CVESearch +import functools +import os +import shelve CVESSEARCH_API_URL = 'https://cve.circl.lu' +CVE_CACHE_FILENAME = "lookups/CVE_CACHE.db" + +@functools.cache +def cvesearch_helper(url:str, cve_id:str): + if not os.path.exists(CVE_CACHE_FILENAME): + print(f"Cache at {CVE_CACHE_FILENAME} not found - Creating it.") + cache = shelve.open(CVE_CACHE_FILENAME, flag='c', writeback=True) + if cve_id in cache: + req = cache[cve_id] + cache.close() + return req + + + + try: + cve = cvesearch_id_helper(url) + result = cve.id(cve_id) + except Exception as e: + raise(Exception(f"The option 'force_cached_or_offline' was used, but {cve_id} not found in {CVE_CACHE_FILENAME} and unable to connect to {CVESSEARCH_API_URL}")) + if result is None: + raise(Exception(f'CveEnrichment for [ {cve_id} ] failed - CVE does not exist')) + cache[cve_id] = result + cache.close() + + return result + +@functools.cache +def cvesearch_id_helper(url:str): + #The initial CVESearch call takes some time. + #We cache it to avoid making this call each time we need to do a lookup + cve = CVESearch(CVESSEARCH_API_URL) + return cve + + class CveEnrichment(): @classmethod - def enrich_cve(self, cve_id: str) -> dict: + def enrich_cve(self, cve_id: str, force_cached_or_offline: bool = False) -> dict: cve_enriched = dict() try: - cve = CVESearch(CVESSEARCH_API_URL) - result = cve.id(cve_id) + if force_cached_or_offline is True: + result = cvesearch_helper(CVESSEARCH_API_URL, cve_id) + else: + cve = CVESearch(CVESSEARCH_API_URL) + result = cve.id(cve_id) cve_enriched['id'] = cve_id cve_enriched['cvss'] = result['cvss'] cve_enriched['summary'] = result['summary'] @@ -19,5 +59,8 @@ def enrich_cve(self, cve_id: str) -> dict: # there was a error calling the circl api lets just empty the object print("WARNING, issue enriching {0}, with error: {1}".format(cve_id, str(TypeErr))) cve_enriched = dict() + except Exception as e: + print("WARNING - {0}".format(str(e))) + cve_enriched = dict() return cve_enriched \ No newline at end of file diff --git a/bin/contentctl_project/contentctl_infrastructure/builder/security_content_baseline_builder.py b/bin/contentctl_project/contentctl_infrastructure/builder/security_content_baseline_builder.py index 8dc85d55fb..62a9e243c9 100644 --- a/bin/contentctl_project/contentctl_infrastructure/builder/security_content_baseline_builder.py +++ b/bin/contentctl_project/contentctl_infrastructure/builder/security_content_baseline_builder.py @@ -11,12 +11,19 @@ class SecurityContentBaselineBuilder(BaselineBuilder): baseline : Baseline + check_references: bool + + def __init__(self, check_references: bool = False): + self.check_references = check_references def setObject(self, path: str) -> None: yml_dict = YmlReader.load_file(path) yml_dict["tags"]["name"] = yml_dict["name"] + + yml_dict["check_references"] = self.check_references try: self.baseline = Baseline.parse_obj(yml_dict) + del(yml_dict["check_references"]) except ValidationError as e: print('Validation Error for file ' + path) print(e) diff --git a/bin/contentctl_project/contentctl_infrastructure/builder/security_content_detection_builder.py b/bin/contentctl_project/contentctl_infrastructure/builder/security_content_detection_builder.py index 072facd9c0..5924a6fc19 100644 --- a/bin/contentctl_project/contentctl_infrastructure/builder/security_content_detection_builder.py +++ b/bin/contentctl_project/contentctl_infrastructure/builder/security_content_detection_builder.py @@ -16,12 +16,23 @@ class SecurityContentDetectionBuilder(DetectionBuilder): security_content_obj : SecurityContentObject + #Only SecurityContentDetectionBuilder cares about force_cached_or_offline because it is + #used for CveEnrichment.enrich_cve and SplunkAppEnrichment.enrich_splunk_app + force_cached_or_offline: bool + check_references: bool + skip_enrichment: bool + def __init__(self, force_cached_or_offline: bool = False, check_references: bool = False, skip_enrichment:bool = False): + self.force_cached_or_offline = force_cached_or_offline + self.check_references = check_references + self.skip_enrichment = skip_enrichment def setObject(self, path: str) -> None: yml_dict = YmlReader.load_file(path) yml_dict["tags"]["name"] = yml_dict["name"] + yml_dict["check_references"] = self.check_references self.security_content_obj = Detection.parse_obj(yml_dict) + del(yml_dict["check_references"]) self.security_content_obj.source = os.path.split(os.path.dirname(self.security_content_obj.file_path))[-1] @@ -165,6 +176,10 @@ def addMitreAttackEnrichment(self, attack_enrichment: dict) -> None: if attack_enrichment: if self.security_content_obj.tags.mitre_attack_id: self.security_content_obj.tags.mitre_attack_enrichments = [] + if self.skip_enrichment: + # We just want to make the above, mitre_attack_enrichments, and + # empty list since we didn't actually fetch those enrichments + return for mitre_attack_id in self.security_content_obj.tags.mitre_attack_id: if mitre_attack_id in attack_enrichment: mitre_attack_enrichment = MitreAttackEnrichment( @@ -176,7 +191,7 @@ def addMitreAttackEnrichment(self, attack_enrichment: dict) -> None: self.security_content_obj.tags.mitre_attack_enrichments.append(mitre_attack_enrichment) else: #print("mitre_attack_id " + mitre_attack_id + " doesn't exist for detecction " + self.security_content_obj.name) - raise ValueError("mitre_attack_id " + mitre_attack_id + " doesn't exist for detecction " + self.security_content_obj.name) + raise ValueError("mitre_attack_id " + mitre_attack_id + " doesn't exist for detection " + self.security_content_obj.name) def addMacros(self, macros: list) -> None: @@ -215,18 +230,22 @@ def addLookups(self, lookups: list) -> None: def addCve(self) -> None: + if self.skip_enrichment: + return None if self.security_content_obj: self.security_content_obj.cve_enrichment = [] if self.security_content_obj.tags.cve: for cve in self.security_content_obj.tags.cve: - self.security_content_obj.cve_enrichment.append(CveEnrichment.enrich_cve(cve)) + self.security_content_obj.cve_enrichment.append(CveEnrichment.enrich_cve(cve, force_cached_or_offline = self.force_cached_or_offline)) def addSplunkApp(self) -> None: + if self.skip_enrichment: + return None if self.security_content_obj: self.security_content_obj.splunk_app_enrichment = [] if self.security_content_obj.tags.supported_tas: for splunk_app in self.security_content_obj.tags.supported_tas: - self.security_content_obj.splunk_app_enrichment.append(SplunkAppEnrichment.enrich_splunk_app(splunk_app)) + self.security_content_obj.splunk_app_enrichment.append(SplunkAppEnrichment.enrich_splunk_app(splunk_app, force_cached_or_offline=self.force_cached_or_offline)) def reset(self) -> None: self.security_content_obj = None diff --git a/bin/contentctl_project/contentctl_infrastructure/builder/security_content_director.py b/bin/contentctl_project/contentctl_infrastructure/builder/security_content_director.py index 5475ded773..414822839e 100644 --- a/bin/contentctl_project/contentctl_infrastructure/builder/security_content_director.py +++ b/bin/contentctl_project/contentctl_infrastructure/builder/security_content_director.py @@ -12,7 +12,7 @@ class SecurityContentDirector(Director): - def constructDetection(self, builder: DetectionBuilder, path: str, deployments: list, playbooks: list, baselines: list, tests: list, attack_enrichment: dict, macros: list, lookups: list) -> None: + def constructDetection(self, builder: DetectionBuilder, path: str, deployments: list, playbooks: list, baselines: list, tests: list, attack_enrichment: dict, macros: list, lookups: list, force_cached_or_offline: bool = False) -> None: builder.reset() builder.setObject(os.path.join(os.path.dirname(__file__), path)) builder.addDeployment(deployments) diff --git a/bin/contentctl_project/contentctl_infrastructure/builder/security_content_investigation_builder.py b/bin/contentctl_project/contentctl_infrastructure/builder/security_content_investigation_builder.py index a9d5869d6b..618bc454e1 100644 --- a/bin/contentctl_project/contentctl_infrastructure/builder/security_content_investigation_builder.py +++ b/bin/contentctl_project/contentctl_infrastructure/builder/security_content_investigation_builder.py @@ -11,12 +11,17 @@ class SecurityContentInvestigationBuilder(InvestigationBuilder): investigation: Investigation + check_references: bool + def __init__(self, check_references: bool = False): + self.check_references = check_references def setObject(self, path: str) -> None: yml_dict = YmlReader.load_file(path) try: + yml_dict["check_references"] = self.check_references self.investigation = Investigation.parse_obj(yml_dict) + del(yml_dict["check_references"]) except ValidationError as e: print('Validation Error for file ' + path) print(e) diff --git a/bin/contentctl_project/contentctl_infrastructure/builder/security_content_playbook_builder.py b/bin/contentctl_project/contentctl_infrastructure/builder/security_content_playbook_builder.py index 59edc3dd21..f76823322a 100644 --- a/bin/contentctl_project/contentctl_infrastructure/builder/security_content_playbook_builder.py +++ b/bin/contentctl_project/contentctl_infrastructure/builder/security_content_playbook_builder.py @@ -12,12 +12,17 @@ class SecurityContentPlaybookBuilder(PlaybookBuilder): playbook: Playbook - + check_references: bool + + def __init__(self, check_references: bool = False): + self.check_references = check_references def setObject(self, path: str) -> None: yml_dict = YmlReader.load_file(path) + yml_dict["check_references"] = self.check_references try: self.playbook = Playbook.parse_obj(yml_dict) + del(yml_dict["check_references"]) except ValidationError as e: print('Validation Error for file ' + path) print(e) diff --git a/bin/contentctl_project/contentctl_infrastructure/builder/security_content_story_builder.py b/bin/contentctl_project/contentctl_infrastructure/builder/security_content_story_builder.py index 6358830596..670bd3a9fa 100644 --- a/bin/contentctl_project/contentctl_infrastructure/builder/security_content_story_builder.py +++ b/bin/contentctl_project/contentctl_infrastructure/builder/security_content_story_builder.py @@ -11,12 +11,18 @@ class SecurityContentStoryBuilder(StoryBuilder): story: Story + check_references: bool + + def __init__(self, check_references: bool = False): + self.check_references = check_references def setObject(self, path: str) -> None: yml_dict = YmlReader.load_file(path) yml_dict["tags"]["name"] = yml_dict["name"] + yml_dict["check_references"] = self.check_references try: self.story = Story.parse_obj(yml_dict) + del(yml_dict["check_references"]) except ValidationError as e: print('Validation Error for file ' + path) print(e) diff --git a/bin/contentctl_project/contentctl_infrastructure/builder/splunk_app_enrichment.py b/bin/contentctl_project/contentctl_infrastructure/builder/splunk_app_enrichment.py index 0a3c520bdf..8dbcab908f 100644 --- a/bin/contentctl_project/contentctl_infrastructure/builder/splunk_app_enrichment.py +++ b/bin/contentctl_project/contentctl_infrastructure/builder/splunk_app_enrichment.py @@ -1,19 +1,47 @@ import requests import xmltodict import json +import functools +import pickle +import shelve +import os SPLUNKBASE_API_URL = "https://apps.splunk.com/api/apps/entriesbyid/" +APP_ENRICHMENT_CACHE_FILENAME = "lookups/APP_ENRICHMENT_CACHE.db" + +@functools.cache +def requests_get_helper(url:str)->bytes: + if not os.path.exists(APP_ENRICHMENT_CACHE_FILENAME): + print(f"Cache at {APP_ENRICHMENT_CACHE_FILENAME} not found - Creating it.") + cache = shelve.open(APP_ENRICHMENT_CACHE_FILENAME, flag='c', writeback=True) + if url in cache: + req_content = cache[url] + cache.close() + return req_content + try: + req = requests.get(url) + req_content = req.content + cache[url] = req_content + cache.close() + return req_content + except Exception as e: + raise(Exception(f"ERROR - Failed to get Splunk App Enrichment at {SPLUNKBASE_API_URL}")) + class SplunkAppEnrichment(): @classmethod - def enrich_splunk_app(self, splunk_ta: str) -> dict: + def enrich_splunk_app(self, splunk_ta: str, force_cached_or_offline: bool = False) -> dict: appurl = SPLUNKBASE_API_URL + splunk_ta splunk_app_enriched = dict() try: - response = requests.get(appurl) - response_dict = xmltodict.parse(response.content) + if force_cached_or_offline is True: + content = requests_get_helper(appurl) + response_dict = xmltodict.parse(content) + else: + response = requests.get(appurl) + response_dict = xmltodict.parse(response.content) # check if list since data changes depending on answer url, results = self._parse_splunkbase_response(response_dict) # grab the app name @@ -22,8 +50,12 @@ def enrich_splunk_app(self, splunk_ta: str) -> dict: splunk_app_enriched['name'] = i['#text'] # grab out the splunkbase url if 'entriesbyid' in url: - response = requests.get(url) - response_dict = xmltodict.parse(response.content) + if force_cached_or_offline is True: + content = requests_get_helper(url) + response_dict = xmltodict.parse(content) + else: + response = requests.get(url) + response_dict = xmltodict.parse(response.content) #print(json.dumps(response_dict, indent=2)) url, results = self._parse_splunkbase_response(response_dict) # chop the url so we grab the splunkbase portion but not direct download diff --git a/bin/contentctl_project/contentctl_infrastructure/tests/builder/test_data/story/ransomware_darkside.yml b/bin/contentctl_project/contentctl_infrastructure/tests/builder/test_data/story/ransomware_darkside.yml index f2e6d8bfd9..b9c2d45c48 100644 --- a/bin/contentctl_project/contentctl_infrastructure/tests/builder/test_data/story/ransomware_darkside.yml +++ b/bin/contentctl_project/contentctl_infrastructure/tests/builder/test_data/story/ransomware_darkside.yml @@ -8,7 +8,7 @@ description: Leverage searches that allow you to detect and investigate unusual 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.' 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 +- https://www.mandiant.com/resources/shining-a-light-on-darkside-ransomware-operations tags: analytic_story: DarkSide Ransomware category: diff --git a/bin/docker_detection_tester/detection_testing_execution.py b/bin/docker_detection_tester/detection_testing_execution.py index 2b58110445..01a457ae11 100644 --- a/bin/docker_detection_tester/detection_testing_execution.py +++ b/bin/docker_detection_tester/detection_testing_execution.py @@ -177,10 +177,10 @@ def generate_escu_app(persist_security_content: bool = False) -> str: ". ./.venv/bin/activate", "python -m pip install wheel", "python -m pip install -r requirements.txt", - "python3 contentctl.py --path . generate --product ESCU --output dist/escu"] + "python3 ../../../contentctl.py --path . --skip_enrichment generate --product ESCU --output dist/escu"] else: commands = [". ./.venv/bin/activate", - "python3 contentctl.py --path . generate --product ESCU --output dist/escu"] + "python3 ../../../contentctl.py --path . --skip_enrichment generate --product ESCU --output dist/escu"] ret = subprocess.run("; ".join(commands), shell=True, capture_output=True) if ret.returncode != 0: diff --git a/bin/docker_detection_tester/modules/github_service.py b/bin/docker_detection_tester/modules/github_service.py index c775c4be2f..da279c1e10 100644 --- a/bin/docker_detection_tester/modules/github_service.py +++ b/bin/docker_detection_tester/modules/github_service.py @@ -70,9 +70,13 @@ def __init__(self, security_content_branch: str, commit_hash: Union[str,None], P # No checking to see if the hash is to a commit inside of the branch - the user # has to do that by hand. + + # -- ensures that we check out the appropriate branch or commit hash. + # Without --, there can be ambiguity if a file/folder exists with the + # same name as the branch, causing the checkout to fail with error if commit_hash is not None: print("Checking out commit hash: [%s]" % (commit_hash)) - self.security_content_repo_obj.git.checkout(commit_hash) + self.security_content_repo_obj.git.checkout(commit_hash, '--') else: #Even if we have fetched a PR, we still MUST check out the branch to # be able to do anything with it. Otherwise we won't have the files @@ -80,7 +84,7 @@ def __init__(self, security_content_branch: str, commit_hash: Union[str,None], P (security_content_branch), end='') sys.stdout.flush() self.security_content_repo_obj.git.checkout( - security_content_branch) + security_content_branch, '--') commit_hash = self.security_content_repo_obj.head.object.hexsha print("commit_hash %s" % (commit_hash)) diff --git a/bin/docker_detection_tester/modules/utils.py b/bin/docker_detection_tester/modules/utils.py index 6671e16367..2d36239311 100644 --- a/bin/docker_detection_tester/modules/utils.py +++ b/bin/docker_detection_tester/modules/utils.py @@ -17,6 +17,8 @@ def download_file_from_http(url:str, destination_file:str, overwrite_file:bool=F with open(destination_file, "wb") as output: for piece in file_to_download.iter_content(chunk_size=chunk_size): output.write(piece) + if verbose_print: + print("Done") except Exception as e: if verbose_print: print("FAILED") diff --git a/contentctl.py b/contentctl.py index f0e4026e8f..5b79db40f8 100644 --- a/contentctl.py +++ b/contentctl.py @@ -2,6 +2,8 @@ import argparse import os +from bin.contentctl_project.contentctl_core.domain.entities.link_validator import LinkValidator + sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), 'bin/contentctl_project'))) from bin.contentctl_project.contentctl_core.application.use_cases.content_changer import ContentChanger, ContentChangerInputDto @@ -92,24 +94,33 @@ def generate(args) -> None: print("ERROR: invalid product. valid products are ESCU, SSA or API.") sys.exit(1) - factory_input_dto = FactoryInputDto( - os.path.abspath(args.path), - SecurityContentBasicBuilder(), - SecurityContentDetectionBuilder(), - SecurityContentStoryBuilder(), - SecurityContentBaselineBuilder(), - SecurityContentInvestigationBuilder(), - SecurityContentPlaybookBuilder(), - SecurityContentDirector(), - AttackEnrichment.get_attack_lookup(store_csv=True) - ) - ba_factory_input_dto = BAFactoryInputDto( - os.path.abspath(args.path), - SecurityContentBasicBuilder(), - SecurityContentDetectionBuilder(), - SecurityContentDirector() - ) + if args.cached_and_offline: + LinkValidator.initialize_cache(args.cached_and_offline) + + #Save runtime by only generating the required factory inputs + factory_input_dto = None + ba_factory_input_dto = None + if args.product in ["ESCU", "API"]: + factory_input_dto = FactoryInputDto( + os.path.abspath(args.path), + SecurityContentBasicBuilder(), + SecurityContentDetectionBuilder(force_cached_or_offline=args.cached_and_offline, skip_enrichment=args.skip_enrichment), + SecurityContentStoryBuilder(), + SecurityContentBaselineBuilder(), + SecurityContentInvestigationBuilder(), + SecurityContentPlaybookBuilder(), + SecurityContentDirector(), + AttackEnrichment.get_attack_lookup(force_cached_or_offline=args.cached_and_offline, skip_enrichment=args.skip_enrichment) + ) + if args.product in ["SSA", "API"]: + ba_factory_input_dto = BAFactoryInputDto( + os.path.abspath(args.path), + SecurityContentBasicBuilder(), + SecurityContentDetectionBuilder(force_cached_or_offline = args.cached_and_offline, skip_enrichment=args.skip_enrichment), + SecurityContentDirector() + ) + if args.product == "ESCU": generate_input_dto = GenerateInputDto( @@ -128,6 +139,7 @@ def generate(args) -> None: SecurityContentProduct.API ) else: + print("making dto") generate_input_dto = GenerateInputDto( os.path.abspath(args.output), factory_input_dto, @@ -135,10 +147,11 @@ def generate(args) -> None: ObjToYmlAdapter(), SecurityContentProduct.SSA ) - generate = Generate() generate.execute(generate_input_dto) + if args.cached_and_offline: + LinkValidator.close_cache() def validate(args) -> None: if not args.product: @@ -149,25 +162,32 @@ def validate(args) -> None: print("ERROR: invalid product. valid products are all, ESCU or SSA.") sys.exit(1) - factory_input_dto = FactoryInputDto( - os.path.abspath(args.path), - SecurityContentBasicBuilder(), - SecurityContentDetectionBuilder(), - SecurityContentStoryBuilder(), - SecurityContentBaselineBuilder(), - SecurityContentInvestigationBuilder(), - SecurityContentPlaybookBuilder(), - SecurityContentDirector(), - AttackEnrichment.get_attack_lookup() - ) - - ba_factory_input_dto = BAFactoryInputDto( - os.path.abspath(args.path), - SecurityContentBasicBuilder(), - SecurityContentDetectionBuilder(), - SecurityContentDirector() - ) - + if args.cached_and_offline: + LinkValidator.initialize_cache(args.cached_and_offline) + + #Save runtime by only generating the required factory inputs + factory_input_dto = None + ba_factory_input_dto = None + if args.product in ["ESCU", "all"]: + factory_input_dto = FactoryInputDto( + os.path.abspath(args.path), + SecurityContentBasicBuilder(), + SecurityContentDetectionBuilder(force_cached_or_offline=args.cached_and_offline, check_references=args.check_references, skip_enrichment=args.skip_enrichment), + SecurityContentStoryBuilder(check_references=args.check_references), + SecurityContentBaselineBuilder(check_references=args.check_references), + SecurityContentInvestigationBuilder(check_references=args.check_references), + SecurityContentPlaybookBuilder(check_references=args.check_references), + SecurityContentDirector(), + AttackEnrichment.get_attack_lookup(force_cached_or_offline=args.cached_and_offline, skip_enrichment=args.skip_enrichment) + ) + if args.product in ["SSA", "all"]: + ba_factory_input_dto = BAFactoryInputDto( + os.path.abspath(args.path), + SecurityContentBasicBuilder(), + SecurityContentDetectionBuilder(force_cached_or_offline = args.cached_and_offline, check_references=args.check_references, skip_enrichment=args.skip_enrichment), + SecurityContentDirector() + ) + if args.product == "ESCU" or args.product == "all": validate_input_dto = ValidateInputDto( factory_input_dto, @@ -186,19 +206,21 @@ def validate(args) -> None: validate = Validate() validate.execute(validate_input_dto) + if args.cached_and_offline: + LinkValidator.close_cache() def doc_gen(args) -> None: factory_input_dto = FactoryInputDto( os.path.abspath(args.path), SecurityContentBasicBuilder(), - SecurityContentDetectionBuilder(), + SecurityContentDetectionBuilder(force_cached_or_offline=args.cached_and_offline, skip_enrichment=args.skip_enrichment), SecurityContentStoryBuilder(), SecurityContentBaselineBuilder(), SecurityContentInvestigationBuilder(), SecurityContentPlaybookBuilder(), SecurityContentDirector(), - AttackEnrichment.get_attack_lookup() + AttackEnrichment.get_attack_lookup(force_cached_or_offline=args.cached_and_offline, skip_enrichment=args.skip_enrichment) ) doc_gen_input_dto = DocGenInputDto( @@ -213,14 +235,14 @@ def doc_gen(args) -> None: def new_content(args) -> None: if args.type == 'detection': - type = SecurityContentType.detections + contentType = SecurityContentType.detections elif args.type == 'story': - type = SecurityContentType.stories + contentType = SecurityContentType.stories else: print("ERROR: type " + args.type + " not supported") sys.exit(1) - new_content_factory_input_dto = NewContentFactoryInputDto(type) + new_content_factory_input_dto = NewContentFactoryInputDto(contentType) new_content_input_dto = NewContentInputDto(new_content_factory_input_dto, ObjToYmlAdapter()) new_content = NewContent() new_content.execute(new_content_input_dto) @@ -230,13 +252,13 @@ def reporting(args) -> None: factory_input_dto = FactoryInputDto( os.path.abspath(args.path), SecurityContentBasicBuilder(), - SecurityContentDetectionBuilder(), + SecurityContentDetectionBuilder(force_cached_or_offline=args.cached_and_offline, skip_enrichment=args.skip_enrichment), SecurityContentStoryBuilder(), SecurityContentBaselineBuilder(), SecurityContentInvestigationBuilder(), SecurityContentPlaybookBuilder(), SecurityContentDirector(), - AttackEnrichment.get_attack_lookup() + AttackEnrichment.get_attack_lookup(force_cached_or_offline=args.cached_and_offline, skip_enrichment=args.skip_enrichment) ) reporting_input_dto = ReportingInputDto( @@ -257,8 +279,13 @@ def main(args): parser = argparse.ArgumentParser( description="Use `contentctl.py action -h` to get help with any Splunk Security Content action") parser.add_argument("-p", "--path", required=True, - help="path to the Splunk Security Content folder") - parser.set_defaults(func=lambda _: parser.print_help()) + help="path to the Splunk Security Content folder",) + parser.add_argument("--cached_and_offline", action=argparse.BooleanOptionalAction, + help="Force cached/offline resources. While this makes execution much faster, it may result in enrichment which is out of date. This is suitable for use only in development or disconnected environments.") + parser.add_argument("--skip_enrichment", action=argparse.BooleanOptionalAction, + help="Skip enrichment of CVEs. This can significantly decrease the amount of time needed to run content_ctl.") + + parser.set_defaults(cached_and_offline=False, func=lambda _: parser.print_help()) actions_parser = parser.add_subparsers(title="Splunk Security Content actions", dest="action") #new_parser = actions_parser.add_parser("new", help="Create new content (detection, story, baseline)") @@ -269,6 +296,8 @@ def main(args): new_content_parser = actions_parser.add_parser("new_content", help="Create new security content object") reporting_parser = actions_parser.add_parser("reporting", help="Create security content reporting") + + # # new arguments # new_parser.add_argument("-t", "--type", required=False, type=str, default="detection", # help="Type of new content to create, please choose between `detection`, `baseline` or `story`. Defaults to `detection`") @@ -278,7 +307,12 @@ def main(args): validate_parser.add_argument("-pr", "--product", required=True, type=str, default='all', help="Type of package to create, choose between all, `ESCU` or `SSA`.") - validate_parser.set_defaults(func=validate, epilog=""" + validate_parser.add_argument('--check_references', action=argparse.BooleanOptionalAction, help="The number of threads to use to resolve references. " + "Larger numbers will result in faster resolution, but will be more likely to hit rate limits or use a large amount of " + "bandwidth. A larger number of threads is particularly useful on high-bandwidth connections, but does not improve " + "performance on slow connections.") + + validate_parser.set_defaults(func=validate, check_references=False, epilog=""" Validates security manifest for correctness, adhering to spec and other common items.""") generate_parser.add_argument("-o", "--output", required=True, type=str, @@ -287,8 +321,10 @@ def main(args): help="Type of package to create, choose between `ESCU`, `SSA` or `API`.") generate_parser.set_defaults(func=generate) - 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_choices = ContentChanger.enumerate_content_changer_functions() + content_changer_parser.add_argument("-cf", "--change_function", required=True, metavar='{ ' + ', '.join(content_changer_choices) +' }' , type=str, choices=content_changer_choices, + help= "Choose from the functions above defined in \nbin/contentctl_core/contentctl/application/use_cases/content_changer.py") + content_changer_parser.set_defaults(func=content_changer) docgen_parser.add_argument("-o", "--output", required=True, type=str, @@ -301,6 +337,10 @@ def main(args): reporting_parser.set_defaults(func=reporting) + + + + # # parse them args = parser.parse_args() return args.func(args) diff --git a/detections/cloud/aws_create_policy_version_to_allow_all_resources.yml b/detections/cloud/aws_create_policy_version_to_allow_all_resources.yml index 65df63e746..e51efde414 100644 --- a/detections/cloud/aws_create_policy_version_to_allow_all_resources.yml +++ b/detections/cloud/aws_create_policy_version_to_allow_all_resources.yml @@ -21,7 +21,7 @@ known_false_positives: While this search has no known false positives, it is pos resources. That said, AWS strongly advises against granting full control to all AWS resources and you must verify this activity. references: -- https://labs.bishopfox.com/tech-blog/privilege-escalation-in-aws +- https://bishopfox.com/blog/privilege-escalation-in-aws - https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation-part-2/ tags: analytic_story: diff --git a/detections/cloud/aws_createaccesskey.yml b/detections/cloud/aws_createaccesskey.yml index ff06ff2563..02642b1e49 100644 --- a/detections/cloud/aws_createaccesskey.yml +++ b/detections/cloud/aws_createaccesskey.yml @@ -24,7 +24,7 @@ how_to_implement: You must install splunk AWS add on and Splunk App for AWS. Thi known_false_positives: While this search has no known false positives, it is possible that an AWS admin has legitimately created keys for another user. references: -- https://labs.bishopfox.com/tech-blog/privilege-escalation-in-aws +- https://bishopfox.com/blog/privilege-escalation-in-aws - https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation-part-2/ tags: analytic_story: diff --git a/detections/cloud/aws_createloginprofile.yml b/detections/cloud/aws_createloginprofile.yml index 050e1d6a5c..bebf5ac260 100644 --- a/detections/cloud/aws_createloginprofile.yml +++ b/detections/cloud/aws_createloginprofile.yml @@ -22,7 +22,7 @@ how_to_implement: You must install splunk AWS add on and Splunk App for AWS. Thi known_false_positives: While this search has no known false positives, it is possible that an AWS admin has legitimately created a login profile for another user. references: -- https://labs.bishopfox.com/tech-blog/privilege-escalation-in-aws +- https://bishopfox.com/blog/privilege-escalation-in-aws - https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation-part-2/ tags: analytic_story: diff --git a/detections/cloud/aws_iam_assume_role_policy_brute_force.yml b/detections/cloud/aws_iam_assume_role_policy_brute_force.yml index 3848d3b9bb..2630f63548 100644 --- a/detections/cloud/aws_iam_assume_role_policy_brute_force.yml +++ b/detections/cloud/aws_iam_assume_role_policy_brute_force.yml @@ -24,7 +24,7 @@ known_false_positives: This detection will require tuning to provide high fideli detection capabilties. Tune based on src addresses (corporate offices, VPN terminations) or by groups of users. references: -- https://www.praetorian.com/blog/aws-iam-assume-role-vulnerabilities +- https://www.praetorian.com/blog/aws-iam-assume-role-vulnerabilities/ - https://rhinosecuritylabs.com/aws/assume-worst-aws-assume-role-enumeration/ - https://www.elastic.co/guide/en/security/current/aws-iam-brute-force-of-assume-role-policy.html tags: diff --git a/detections/cloud/aws_saml_access_by_provider_user_and_principal.yml b/detections/cloud/aws_saml_access_by_provider_user_and_principal.yml index 003d880703..022dafe665 100644 --- a/detections/cloud/aws_saml_access_by_provider_user_and_principal.yml +++ b/detections/cloud/aws_saml_access_by_provider_user_and_principal.yml @@ -23,7 +23,7 @@ known_false_positives: Attacks using a Golden SAML or SAML assertion hijacks or access and abuse detection searches can provide the necessary context to detect these attacks. references: -- https://us-cert.cisa.gov/ncas/alerts/aa21-008a +- https://www.cisa.gov/uscert/ncas/alerts/aa21-008a - https://www.splunk.com/en_us/blog/security/a-golden-saml-journey-solarwinds-continued.html - https://www.fireeye.com/content/dam/fireeye-www/blog/pdfs/wp-m-unc2452-2021-000343-01.pdf - https://www.cyberark.com/resources/threat-research-blog/golden-saml-newly-discovered-attack-technique-forges-authentication-to-cloud-apps diff --git a/detections/cloud/aws_saml_update_identity_provider.yml b/detections/cloud/aws_saml_update_identity_provider.yml index 34aef7434e..dac7c0d864 100644 --- a/detections/cloud/aws_saml_update_identity_provider.yml +++ b/detections/cloud/aws_saml_update_identity_provider.yml @@ -19,7 +19,7 @@ how_to_implement: You must install splunk AWS add on and Splunk App for AWS. Thi known_false_positives: Updating a SAML provider or creating a new one may not necessarily be malicious however it needs to be closely monitored. references: -- https://us-cert.cisa.gov/ncas/alerts/aa21-008a +- https://www.cisa.gov/uscert/ncas/alerts/aa21-008a - https://www.splunk.com/en_us/blog/security/a-golden-saml-journey-solarwinds-continued.html - https://www.fireeye.com/content/dam/fireeye-www/blog/pdfs/wp-m-unc2452-2021-000343-01.pdf - https://www.cyberark.com/resources/threat-research-blog/golden-saml-newly-discovered-attack-technique-forges-authentication-to-cloud-apps diff --git a/detections/cloud/aws_setdefaultpolicyversion.yml b/detections/cloud/aws_setdefaultpolicyversion.yml index 6e9d444e48..83f36e3050 100644 --- a/detections/cloud/aws_setdefaultpolicyversion.yml +++ b/detections/cloud/aws_setdefaultpolicyversion.yml @@ -21,7 +21,7 @@ known_false_positives: While this search has no known false positives, it is pos all resources. That said, AWS strongly advises against granting full control to all AWS resources references: -- https://labs.bishopfox.com/tech-blog/privilege-escalation-in-aws +- https://bishopfox.com/blog/privilege-escalation-in-aws - https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation-part-2/ tags: analytic_story: diff --git a/detections/cloud/aws_updateloginprofile.yml b/detections/cloud/aws_updateloginprofile.yml index 20a56ccfc2..aabeb5a952 100644 --- a/detections/cloud/aws_updateloginprofile.yml +++ b/detections/cloud/aws_updateloginprofile.yml @@ -24,7 +24,7 @@ how_to_implement: You must install splunk AWS add on and Splunk App for AWS. Thi known_false_positives: While this search has no known false positives, it is possible that an AWS admin has legitimately created keys for another user. references: -- https://labs.bishopfox.com/tech-blog/privilege-escalation-in-aws +- https://bishopfox.com/blog/privilege-escalation-in-aws - https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation-part-2/ tags: analytic_story: diff --git a/detections/cloud/gsuite_email_suspicious_subject_with_attachment.yml b/detections/cloud/gsuite_email_suspicious_subject_with_attachment.yml index 25722961dd..b544c0a87b 100644 --- a/detections/cloud/gsuite_email_suspicious_subject_with_attachment.yml +++ b/detections/cloud/gsuite_email_suspicious_subject_with_attachment.yml @@ -32,7 +32,7 @@ known_false_positives: normal user or normal transaction may contain the subject file type attachment that this detection try to search. references: - https://www.redhat.com/en/topics/devops/what-is-devsecops -- https://www.fireeye.com/content/dam/fireeye-www/global/en/current-threats/pdfs/rpt-top-spear-phishing-words.pdf +- https://www.mandiant.com/resources/top-words-used-in-spear-phishing-attacks tags: analytic_story: - Dev Sec Ops diff --git a/detections/cloud/gsuite_suspicious_shared_file_name.yml b/detections/cloud/gsuite_suspicious_shared_file_name.yml index 90cc35bc48..33fcc963af 100644 --- a/detections/cloud/gsuite_suspicious_shared_file_name.yml +++ b/detections/cloud/gsuite_suspicious_shared_file_name.yml @@ -31,7 +31,7 @@ known_false_positives: normal user or normal transaction may contain the subject file type attachment that this detection try to search references: - https://www.redhat.com/en/topics/devops/what-is-devsecops -- https://www.fireeye.com/content/dam/fireeye-www/global/en/current-threats/pdfs/rpt-top-spear-phishing-words.pdf +- https://www.mandiant.com/resources/top-words-used-in-spear-phishing-attacks tags: analytic_story: - Dev Sec Ops diff --git a/detections/cloud/kubernetes_nginx_ingress_rfi.yml b/detections/cloud/kubernetes_nginx_ingress_rfi.yml index a647e3df2d..7ff7ad1c68 100644 --- a/detections/cloud/kubernetes_nginx_ingress_rfi.yml +++ b/detections/cloud/kubernetes_nginx_ingress_rfi.yml @@ -18,7 +18,7 @@ how_to_implement: You must ingest Kubernetes logs through Splunk Connect for Kub known_false_positives: unknown references: - https://github.com/splunk/splunk-connect-for-kubernetes -- https://www.netsparker.com/blog/web-security/remote-file-inclusion-vulnerability/ +- https://www.invicti.com/blog/web-security/remote-file-inclusion-vulnerability/ tags: analytic_story: - Dev Sec Ops diff --git a/detections/cloud/o365_add_app_role_assignment_grant_user.yml b/detections/cloud/o365_add_app_role_assignment_grant_user.yml index 764103e793..4ee794bd2d 100644 --- a/detections/cloud/o365_add_app_role_assignment_grant_user.yml +++ b/detections/cloud/o365_add_app_role_assignment_grant_user.yml @@ -19,7 +19,7 @@ known_false_positives: The creation of a new Federation is not necessarily malic abuse or backdoor via federated identities at a different cloud provider. references: - https://www.fireeye.com/content/dam/fireeye-www/blog/pdfs/wp-m-unc2452-2021-000343-01.pdf -- https://us-cert.cisa.gov/ncas/alerts/aa21-008a +- https://www.cisa.gov/uscert/ncas/alerts/aa21-008a tags: analytic_story: - Office 365 Detections diff --git a/detections/cloud/o365_added_service_principal.yml b/detections/cloud/o365_added_service_principal.yml index 4eb8e927bf..2b47480363 100644 --- a/detections/cloud/o365_added_service_principal.yml +++ b/detections/cloud/o365_added_service_principal.yml @@ -20,9 +20,9 @@ known_false_positives: The creation of a new Federation is not necessarily malic abuse or backdoor via federated identities at a different cloud provider. references: - https://www.fireeye.com/content/dam/fireeye-www/blog/pdfs/wp-m-unc2452-2021-000343-01.pdf -- https://us-cert.cisa.gov/ncas/alerts/aa21-008a +- https://www.cisa.gov/uscert/ncas/alerts/aa21-008a - https://www.splunk.com/en_us/blog/security/a-golden-saml-journey-solarwinds-continued.html -- https://www.sygnia.co/golden-saml-advisory +- https://blog.sygnia.co/detection-and-hunting-of-golden-saml-attack?hsLang=en tags: analytic_story: - Office 365 Detections diff --git a/detections/cloud/o365_new_federated_domain_added.yml b/detections/cloud/o365_new_federated_domain_added.yml index beeb34270c..f9662fce58 100644 --- a/detections/cloud/o365_new_federated_domain_added.yml +++ b/detections/cloud/o365_new_federated_domain_added.yml @@ -18,9 +18,9 @@ known_false_positives: The creation of a new Federated domain is not necessarily abuse or backdoor via federated identities at a similar or different cloud provider. references: - https://www.fireeye.com/content/dam/fireeye-www/blog/pdfs/wp-m-unc2452-2021-000343-01.pdf -- https://us-cert.cisa.gov/ncas/alerts/aa21-008a +- https://www.cisa.gov/uscert/ncas/alerts/aa21-008a - https://www.splunk.com/en_us/blog/security/a-golden-saml-journey-solarwinds-continued.html -- https://www.sygnia.co/golden-saml-advisory +- https://blog.sygnia.co/detection-and-hunting-of-golden-saml-attack?hsLang=en - https://o365blog.com/post/aadbackdoor/ tags: analytic_story: diff --git a/detections/deprecated/suspicious_rundll32_rename.yml b/detections/deprecated/suspicious_rundll32_rename.yml index f772449975..ec83425324 100644 --- a/detections/deprecated/suspicious_rundll32_rename.yml +++ b/detections/deprecated/suspicious_rundll32_rename.yml @@ -28,7 +28,7 @@ known_false_positives: Although unlikely, some legitimate applications may use a references: - https://attack.mitre.org/techniques/T1218/011/ - https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1218.011/T1218.011.md -- https://lolbas-project.github.io/lolbas/Binaries/Rundll32 +- https://lolbas-project.github.io/lolbas/Binaries/Rundll32/ tags: analytic_story: - Suspicious Rundll32 Activity diff --git a/detections/endpoint/account_discovery_with_net_app.yml b/detections/endpoint/account_discovery_with_net_app.yml index 50656c9f33..d22b22d34f 100644 --- a/detections/endpoint/account_discovery_with_net_app.yml +++ b/detections/endpoint/account_discovery_with_net_app.yml @@ -28,7 +28,7 @@ how_to_implement: To successfully implement this search you need to be ingesting known_false_positives: admin or power user may used this series of command. references: - https://labs.vipre.com/trickbot-and-its-modules/ -- https://blog.whitehat.eu/2019/05/incident-trickbot-ryuk-2.html +- https://whitehat.eu/incident-response-case-study-featuring-ryuk-and-trickbot-part-2/ - https://app.any.run/tasks/48414a33-3d66-4a46-afe5-c2003bb55ccf/ tags: analytic_story: diff --git a/detections/endpoint/active_setup_registry_autostart.yml b/detections/endpoint/active_setup_registry_autostart.yml index aba210b24e..824682c8f9 100644 --- a/detections/endpoint/active_setup_registry_autostart.yml +++ b/detections/endpoint/active_setup_registry_autostart.yml @@ -34,7 +34,7 @@ how_to_implement: To successfully implement this search, you must be ingesting d to the registry. known_false_positives: Active setup installer may add or modify this registry. references: -- https://www.microsoft.com/en-us/wdsi/threats/malware-encyclopedia-description?Name=Backdoor%3aWin32%2fPoisonivy.E +- https://www.microsoft.com/en-us/wdsi/threats/malware-encyclopedia-description?Name=Backdoor%3AWin32%2FPoisonivy.E - https://attack.mitre.org/techniques/T1547/014/ tags: analytic_story: diff --git a/detections/endpoint/allow_file_and_printing_sharing_in_firewall.yml b/detections/endpoint/allow_file_and_printing_sharing_in_firewall.yml index 1ccf2ebe82..85441224e3 100644 --- a/detections/endpoint/allow_file_and_printing_sharing_in_firewall.yml +++ b/detections/endpoint/allow_file_and_printing_sharing_in_firewall.yml @@ -24,7 +24,7 @@ how_to_implement: To successfully implement this search you need to be ingesting known_false_positives: network admin may modify this firewall feature that may cause this rule to be triggered. references: -- https://kb.fortinet.com/kb/documentLink.do?externalID=FD52469 +- https://community.fortinet.com:443/t5/FortiEDR/How-FortiEDR-detects-and-blocks-Revil-Ransomware-aka-sodinokibi/ta-p/189638?externalID=FD52469 - https://app.any.run/tasks/c0f98850-af65-4352-9746-fbebadee4f05/ tags: analytic_story: diff --git a/detections/endpoint/allow_network_discovery_in_firewall.yml b/detections/endpoint/allow_network_discovery_in_firewall.yml index fd7b605d0d..22d738824e 100644 --- a/detections/endpoint/allow_network_discovery_in_firewall.yml +++ b/detections/endpoint/allow_network_discovery_in_firewall.yml @@ -25,7 +25,7 @@ how_to_implement: To successfully implement this search you need to be ingesting known_false_positives: network admin may modify this firewall feature that may cause this rule to be triggered. references: -- https://kb.fortinet.com/kb/documentLink.do?externalID=FD52469 +- https://community.fortinet.com:443/t5/FortiEDR/How-FortiEDR-detects-and-blocks-Revil-Ransomware-aka-sodinokibi/ta-p/189638?externalID=FD52469 - https://app.any.run/tasks/c0f98850-af65-4352-9746-fbebadee4f05/ tags: analytic_story: diff --git a/detections/endpoint/certutil_download_with_urlcache_and_split_arguments.yml b/detections/endpoint/certutil_download_with_urlcache_and_split_arguments.yml index 8c970d2088..6bbe7450e2 100644 --- a/detections/endpoint/certutil_download_with_urlcache_and_split_arguments.yml +++ b/detections/endpoint/certutil_download_with_urlcache_and_split_arguments.yml @@ -29,7 +29,7 @@ known_false_positives: Limited false positives in most environments, however tun references: - https://attack.mitre.org/techniques/T1105/ - https://www.avira.com/en/blog/certutil-abused-by-attackers-to-spread-threats -- https://www.fireeye.com/blog/threat-research/2019/10/certutil-qualms-they-came-to-drop-fombs.html +- https://web.archive.org/web/20210921110637/https://www.fireeye.com/blog/threat-research/2019/10/certutil-qualms-they-came-to-drop-fombs.html tags: analytic_story: - Ingress Tool Transfer diff --git a/detections/endpoint/clop_common_exec_parameter.yml b/detections/endpoint/clop_common_exec_parameter.yml index f3deda0e64..ba8b92a48e 100644 --- a/detections/endpoint/clop_common_exec_parameter.yml +++ b/detections/endpoint/clop_common_exec_parameter.yml @@ -25,7 +25,7 @@ how_to_implement: To successfully implement this search you need to be ingesting your endpoints into the `Endpoint` datamodel in the `Processes` node. known_false_positives: Operators can execute third party tools using these parameters. references: -- https://www.fireeye.com/blog/threat-research/2020/10/fin11-email-campaigns-precursor-for-ransomware-data-theft.html +- https://www.mandiant.com/resources/fin11-email-campaigns-precursor-for-ransomware-data-theft - https://blog.virustotal.com/2020/11/keep-your-friends-close-keep-ransomware.html tags: analytic_story: diff --git a/detections/endpoint/clop_ransomware_known_service_name.yml b/detections/endpoint/clop_ransomware_known_service_name.yml index 9df5fb9fd3..6fd13099f6 100644 --- a/detections/endpoint/clop_ransomware_known_service_name.yml +++ b/detections/endpoint/clop_ransomware_known_service_name.yml @@ -19,7 +19,7 @@ how_to_implement: To successfully implement this search, you need to be ingestin from your endpoints. known_false_positives: unknown references: -- https://www.fireeye.com/blog/threat-research/2020/10/fin11-email-campaigns-precursor-for-ransomware-data-theft.html +- https://www.mandiant.com/resources/fin11-email-campaigns-precursor-for-ransomware-data-theft - https://blog.virustotal.com/2020/11/keep-your-friends-close-keep-ransomware.html tags: analytic_story: diff --git a/detections/endpoint/cmdline_tool_not_executed_in_cmd_shell.yml b/detections/endpoint/cmdline_tool_not_executed_in_cmd_shell.yml index f69af6ee9f..c8f69706d3 100644 --- a/detections/endpoint/cmdline_tool_not_executed_in_cmd_shell.yml +++ b/detections/endpoint/cmdline_tool_not_executed_in_cmd_shell.yml @@ -31,7 +31,7 @@ known_false_positives: A network operator or systems administrator may utilize a automated host discovery application that may generate false positives. Filter as needed. references: -- https://www.fireeye.com/blog/threat-research/2018/08/fin7-pursuing-an-enigmatic-and-evasive-global-criminal-operation.html +- https://www.mandiant.com/resources/fin7-pursuing-an-enigmatic-and-evasive-global-criminal-operation - https://attack.mitre.org/groups/G0046/ tags: analytic_story: diff --git a/detections/endpoint/cobalt_strike_named_pipes.yml b/detections/endpoint/cobalt_strike_named_pipes.yml index 35150685ae..25bbb4a2bd 100644 --- a/detections/endpoint/cobalt_strike_named_pipes.yml +++ b/detections/endpoint/cobalt_strike_named_pipes.yml @@ -33,10 +33,10 @@ known_false_positives: The idea of using named pipes with Cobalt Strike is to bl references: - https://attack.mitre.org/techniques/T1218/009/ - https://docs.microsoft.com/en-us/windows/win32/ipc/named-pipes -- https://www.cobaltstrike.com/help-smb-beacon -- https://blog.cobaltstrike.com/2021/02/09/learn-pipe-fitting-for-all-of-your-offense-projects/ +- https://hstechdocs.helpsystems.com/manuals/cobaltstrike/current/userguide/index.htm#cshid=1040 +- https://www.cobaltstrike.com/blog/learn-pipe-fitting-for-all-of-your-offense-projects/ - https://gist.github.com/MHaggis/6c600e524045a6d49c35291a21e10752 -- https://www.fireeye.com/blog/threat-research/2021/05/shining-a-light-on-darkside-ransomware-operations.html +- https://www.mandiant.com/resources/shining-a-light-on-darkside-ransomware-operations tags: analytic_story: - Cobalt Strike diff --git a/detections/endpoint/create_or_delete_windows_shares_using_net_exe.yml b/detections/endpoint/create_or_delete_windows_shares_using_net_exe.yml index 049158682e..3826c9058d 100644 --- a/detections/endpoint/create_or_delete_windows_shares_using_net_exe.yml +++ b/detections/endpoint/create_or_delete_windows_shares_using_net_exe.yml @@ -22,7 +22,7 @@ how_to_implement: To successfully implement this search you need to be ingesting known_false_positives: Administrators often leverage net.exe to create or delete network shares. You should verify that the activity was intentional and is legitimate. references: -- https://attack.mitre.org/techniques/T1070/005 +- https://attack.mitre.org/techniques/T1070/005/ tags: analytic_story: - Hidden Cobra Malware diff --git a/detections/endpoint/delete_shadowcopy_with_powershell.yml b/detections/endpoint/delete_shadowcopy_with_powershell.yml index 7688461d92..2d6a8474dd 100644 --- a/detections/endpoint/delete_shadowcopy_with_powershell.yml +++ b/detections/endpoint/delete_shadowcopy_with_powershell.yml @@ -20,8 +20,8 @@ how_to_implement: To successfully implement this search, you need to be ingestin registry to monitor this event. known_false_positives: unknown references: -- https://www.fireeye.com/blog/threat-research/2021/05/shining-a-light-on-darkside-ransomware-operations.html -- https://searchwindowsserver.techtarget.com/tutorial/Set-up-PowerShell-script-block-logging-for-added-security +- https://www.mandiant.com/resources/shining-a-light-on-darkside-ransomware-operations +- https://www.techtarget.com/searchwindowsserver/tutorial/Set-up-PowerShell-script-block-logging-for-added-security tags: analytic_story: - DarkSide Ransomware diff --git a/detections/endpoint/detect_html_help_spawn_child_process.yml b/detections/endpoint/detect_html_help_spawn_child_process.yml index 7803c03508..ce9659c565 100644 --- a/detections/endpoint/detect_html_help_spawn_child_process.yml +++ b/detections/endpoint/detect_html_help_spawn_child_process.yml @@ -32,7 +32,7 @@ references: - https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1218.001/T1218.001.md - https://lolbas-project.github.io/lolbas/Binaries/Hh/ - https://gist.github.com/mgeeky/cce31c8602a144d8f2172a73d510e0e7 -- https://cyberforensicator.com/2019/01/20/silence-dissecting-malicious-chm-files-and-performing-forensic-analysis/ +- https://web.archive.org/web/20220119133748/https://cyberforensicator.com/2019/01/20/silence-dissecting-malicious-chm-files-and-performing-forensic-analysis/ tags: analytic_story: - Suspicious Compiled HTML Activity diff --git a/detections/endpoint/detect_html_help_url_in_command_line.yml b/detections/endpoint/detect_html_help_url_in_command_line.yml index 71053ab030..1772887629 100644 --- a/detections/endpoint/detect_html_help_url_in_command_line.yml +++ b/detections/endpoint/detect_html_help_url_in_command_line.yml @@ -36,7 +36,7 @@ references: - https://lolbas-project.github.io/lolbas/Binaries/Hh/ - https://blog.sevagas.com/?Hacking-around-HTA-files - https://gist.github.com/mgeeky/cce31c8602a144d8f2172a73d510e0e7 -- https://cyberforensicator.com/2019/01/20/silence-dissecting-malicious-chm-files-and-performing-forensic-analysis/ +- https://web.archive.org/web/20220119133748/https://cyberforensicator.com/2019/01/20/silence-dissecting-malicious-chm-files-and-performing-forensic-analysis/ tags: analytic_story: - Suspicious Compiled HTML Activity diff --git a/detections/endpoint/detect_html_help_using_infotech_storage_handlers.yml b/detections/endpoint/detect_html_help_using_infotech_storage_handlers.yml index 1c1298b8fe..7c1a5b5be0 100644 --- a/detections/endpoint/detect_html_help_using_infotech_storage_handlers.yml +++ b/detections/endpoint/detect_html_help_using_infotech_storage_handlers.yml @@ -38,7 +38,7 @@ references: - https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1218.001/T1218.001.md - https://lolbas-project.github.io/lolbas/Binaries/Hh/ - https://gist.github.com/mgeeky/cce31c8602a144d8f2172a73d510e0e7 -- https://cyberforensicator.com/2019/01/20/silence-dissecting-malicious-chm-files-and-performing-forensic-analysis/ +- https://web.archive.org/web/20220119133748/https://cyberforensicator.com/2019/01/20/silence-dissecting-malicious-chm-files-and-performing-forensic-analysis/ tags: analytic_story: - Suspicious Compiled HTML Activity diff --git a/detections/endpoint/detect_rclone_command_line_usage.yml b/detections/endpoint/detect_rclone_command_line_usage.yml index 5d1051b1d3..37048de5ad 100644 --- a/detections/endpoint/detect_rclone_command_line_usage.yml +++ b/detections/endpoint/detect_rclone_command_line_usage.yml @@ -29,7 +29,7 @@ known_false_positives: False positives should be limited as this is restricted t the Rclone process name. Filter or tune the analytic as needed. references: - https://redcanary.com/blog/rclone-mega-extortion/ -- https://www.fireeye.com/blog/threat-research/2021/05/shining-a-light-on-darkside-ransomware-operations.html +- https://www.mandiant.com/resources/shining-a-light-on-darkside-ransomware-operations - https://thedfirreport.com/2021/03/29/sodinokibi-aka-revil-ransomware/ - https://thedfirreport.com/2021/11/29/continuing-the-bazar-ransomware-story/ tags: diff --git a/detections/endpoint/detect_renamed_rclone.yml b/detections/endpoint/detect_renamed_rclone.yml index a147b17a02..58dccda89b 100644 --- a/detections/endpoint/detect_renamed_rclone.yml +++ b/detections/endpoint/detect_renamed_rclone.yml @@ -28,7 +28,7 @@ known_false_positives: False positives should be limited as this analytic identi use case. references: - https://redcanary.com/blog/rclone-mega-extortion/ -- https://www.fireeye.com/blog/threat-research/2021/05/shining-a-light-on-darkside-ransomware-operations.html +- https://www.mandiant.com/resources/shining-a-light-on-darkside-ransomware-operations - https://thedfirreport.com/2021/03/29/sodinokibi-aka-revil-ransomware/ tags: analytic_story: diff --git a/detections/endpoint/detect_rundll32_application_control_bypass___advpack.yml b/detections/endpoint/detect_rundll32_application_control_bypass___advpack.yml index a3e262f36e..916d615608 100644 --- a/detections/endpoint/detect_rundll32_application_control_bypass___advpack.yml +++ b/detections/endpoint/detect_rundll32_application_control_bypass___advpack.yml @@ -31,7 +31,7 @@ known_false_positives: Although unlikely, some legitimate applications may use a references: - https://attack.mitre.org/techniques/T1218/011/ - https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1218.011/T1218.011.md -- https://lolbas-project.github.io/lolbas/Binaries/Rundll32 +- https://lolbas-project.github.io/lolbas/Binaries/Rundll32/ - https://lolbas-project.github.io/lolbas/Libraries/Advpack/ - https://bohops.com/2018/02/26/leveraging-inf-sct-fetch-execute-techniques-for-bypass-evasion-persistence/ tags: diff --git a/detections/endpoint/detect_rundll32_application_control_bypass___setupapi.yml b/detections/endpoint/detect_rundll32_application_control_bypass___setupapi.yml index 1a4e2bb1cd..5baa5324b6 100644 --- a/detections/endpoint/detect_rundll32_application_control_bypass___setupapi.yml +++ b/detections/endpoint/detect_rundll32_application_control_bypass___setupapi.yml @@ -29,7 +29,7 @@ known_false_positives: Although unlikely, some legitimate applications may use s references: - https://attack.mitre.org/techniques/T1218/011/ - https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1218.011/T1218.011.md -- https://lolbas-project.github.io/lolbas/Binaries/Rundll32 +- https://lolbas-project.github.io/lolbas/Binaries/Rundll32/ - https://lolbas-project.github.io/lolbas/Libraries/Setupapi/ - https://bohops.com/2018/02/26/leveraging-inf-sct-fetch-execute-techniques-for-bypass-evasion-persistence/ tags: diff --git a/detections/endpoint/detect_rundll32_application_control_bypass___syssetup.yml b/detections/endpoint/detect_rundll32_application_control_bypass___syssetup.yml index 78f7368a0e..4e207fb56c 100644 --- a/detections/endpoint/detect_rundll32_application_control_bypass___syssetup.yml +++ b/detections/endpoint/detect_rundll32_application_control_bypass___syssetup.yml @@ -31,7 +31,7 @@ known_false_positives: Although unlikely, some legitimate applications may use s references: - https://attack.mitre.org/techniques/T1218/011/ - https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1218.011/T1218.011.md -- https://lolbas-project.github.io/lolbas/Binaries/Rundll32 +- https://lolbas-project.github.io/lolbas/Binaries/Rundll32/ - https://lolbas-project.github.io/lolbas/Libraries/Syssetup/ - https://bohops.com/2018/02/26/leveraging-inf-sct-fetch-execute-techniques-for-bypass-evasion-persistence/ tags: diff --git a/detections/endpoint/detect_wmi_event_subscription_persistence.yml b/detections/endpoint/detect_wmi_event_subscription_persistence.yml index aaf397cc5b..1cb56a143a 100644 --- a/detections/endpoint/detect_wmi_event_subscription_persistence.yml +++ b/detections/endpoint/detect_wmi_event_subscription_persistence.yml @@ -38,8 +38,8 @@ known_false_positives: It is possible some applications will create a consumer a references: - https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1546.003/T1546.003.md - https://www.eideon.com/2018-03-02-THL03-WMIBackdoors/ -- https://github.com/trustedsec/SysmonCommunityGuide/blob/master/WMI-events.md -- https://in.security/an-intro-into-abusing-and-identifying-wmi-event-subscriptions-for-persistence/ +- https://github.com/trustedsec/SysmonCommunityGuide/blob/master/chapters/WMI-events.md +- https://in.security/2019/04/03/an-intro-into-abusing-and-identifying-wmi-event-subscriptions-for-persistence/ tags: analytic_story: - Suspicious WMI Use diff --git a/detections/endpoint/disable_show_hidden_files.yml b/detections/endpoint/disable_show_hidden_files.yml index 4b38910f2a..a11229d9b5 100644 --- a/detections/endpoint/disable_show_hidden_files.yml +++ b/detections/endpoint/disable_show_hidden_files.yml @@ -31,7 +31,7 @@ how_to_implement: To successfully implement this search you need to be ingesting that this registry was included in your config files ex. sysmon config to be monitored. known_false_positives: unknown references: -- https://www.sophos.com/en-us/threat-center/threat-analyses/viruses-and-spyware/W32~Tiotua-P/detailed-analysis.aspx +- https://www.sophos.com/en-us/threat-center/threat-analyses/viruses-and-spyware/W32~Tiotua-P/detailed-analysis tags: analytic_story: - Windows Defense Evasion Tactics diff --git a/detections/endpoint/disabling_firewall_with_netsh.yml b/detections/endpoint/disabling_firewall_with_netsh.yml index 0354fb1152..64d2057372 100644 --- a/detections/endpoint/disabling_firewall_with_netsh.yml +++ b/detections/endpoint/disabling_firewall_with_netsh.yml @@ -23,7 +23,7 @@ how_to_implement: To successfully implement this search you need to be ingesting known_false_positives: admin may disable firewall during testing or fixing network problem. references: -- https://tccontre.blogspot.com/2020/01/remcos-rat-evading-windows-defender-av.htm +- https://tccontre.blogspot.com/2020/01/remcos-rat-evading-windows-defender-av.html tags: analytic_story: - Windows Defense Evasion Tactics diff --git a/detections/endpoint/dllhost_with_no_command_line_arguments_with_network.yml b/detections/endpoint/dllhost_with_no_command_line_arguments_with_network.yml index 614061636c..f6e063ff1c 100644 --- a/detections/endpoint/dllhost_with_no_command_line_arguments_with_network.yml +++ b/detections/endpoint/dllhost_with_no_command_line_arguments_with_network.yml @@ -28,7 +28,7 @@ known_false_positives: Although unlikely, some legitimate third party applicatio may use a moved copy of dllhost, triggering a false positive. references: - https://raw.githubusercontent.com/threatexpress/malleable-c2/c3385e481159a759f79b8acfe11acf240893b830/jquery-c2.4.2.profile -- https://blog.cobaltstrike.com/2021/02/09/learn-pipe-fitting-for-all-of-your-offense-projects/ +- https://www.cobaltstrike.com/blog/learn-pipe-fitting-for-all-of-your-offense-projects/ tags: analytic_story: - Cobalt Strike diff --git a/detections/endpoint/dns_exfiltration_using_nslookup_app.yml b/detections/endpoint/dns_exfiltration_using_nslookup_app.yml index ea24ac1917..48d6aa3ef3 100644 --- a/detections/endpoint/dns_exfiltration_using_nslookup_app.yml +++ b/detections/endpoint/dns_exfiltration_using_nslookup_app.yml @@ -26,8 +26,8 @@ how_to_implement: To successfully implement this search, you need to be ingestin Sysmon TA. Tune and filter known instances of nslookup.exe may be used. known_false_positives: admin nslookup usage references: -- https://www.fireeye.com/blog/threat-research/2017/03/fin7_spear_phishing.html -- https://www.varonis.com/blog/dns-tunneling/ +- https://www.mandiant.com/resources/fin7-spear-phishing-campaign-targets-personnel-involved-sec-filings +- https://www.varonis.com/blog/dns-tunneling - https://www.microsoft.com/security/blog/2021/01/20/deep-dive-into-the-solorigate-second-stage-activation-from-sunburst-to-teardrop-and-raindrop/ tags: analytic_story: diff --git a/detections/endpoint/drop_icedid_license_dat.yml b/detections/endpoint/drop_icedid_license_dat.yml index f37b89a86d..5f354529b2 100644 --- a/detections/endpoint/drop_icedid_license_dat.yml +++ b/detections/endpoint/drop_icedid_license_dat.yml @@ -19,7 +19,7 @@ how_to_implement: To successfully implement this search, you need to be ingestin Sysmon TA. known_false_positives: unknown references: -- https://www.cisecurity.org/white-papers/security-primer-icedid/ +- https://www.cisecurity.org/insights/white-papers/security-primer-icedid tags: analytic_story: - IcedID diff --git a/detections/endpoint/dsquery_domain_discovery.yml b/detections/endpoint/dsquery_domain_discovery.yml index c88919c256..6d3d833e1a 100644 --- a/detections/endpoint/dsquery_domain_discovery.yml +++ b/detections/endpoint/dsquery_domain_discovery.yml @@ -40,7 +40,7 @@ known_false_positives: Limited false positives. If there is a true false positiv filter based on command-line or parent process. references: - https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1482/T1482.md -- http://www.harmj0y.net/blog/redteaming/a-guide-to-attacking-domain-trusts/ +- https://blog.harmj0y.net/redteaming/a-guide-to-attacking-domain-trusts/ - https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-R2-and-2012/cc732952(v=ws.11) - https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-R2-and-2012/cc754232(v=ws.11) tags: diff --git a/detections/endpoint/eventvwr_uac_bypass.yml b/detections/endpoint/eventvwr_uac_bypass.yml index e4c6563593..691b33b0c9 100644 --- a/detections/endpoint/eventvwr_uac_bypass.yml +++ b/detections/endpoint/eventvwr_uac_bypass.yml @@ -34,7 +34,7 @@ known_false_positives: Some false positives may be present and will need to be f references: - https://blog.malwarebytes.com/malwarebytes-news/2021/02/lazyscripter-from-empire-to-double-rat/ - https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1548.002/T1548.002.md -- https://attack.mitre.org/techniques/T1548/002 +- https://attack.mitre.org/techniques/T1548/002/ - https://enigma0x3.net/2016/08/15/fileless-uac-bypass-using-eventvwr-exe-and-registry-hijacking/ tags: analytic_story: diff --git a/detections/endpoint/excessive_usage_of_nslookup_app.yml b/detections/endpoint/excessive_usage_of_nslookup_app.yml index 892c8587e5..3365a1cd69 100644 --- a/detections/endpoint/excessive_usage_of_nslookup_app.yml +++ b/detections/endpoint/excessive_usage_of_nslookup_app.yml @@ -28,8 +28,8 @@ how_to_implement: To successfully implement this search, you need to be ingestin Sysmon TA. Tune and filter known instances of nslookup.exe may be used. known_false_positives: unknown references: -- https://www.fireeye.com/blog/threat-research/2017/03/fin7_spear_phishing.html -- https://www.varonis.com/blog/dns-tunneling/ +- https://www.mandiant.com/resources/fin7-spear-phishing-campaign-targets-personnel-involved-sec-filings +- https://www.varonis.com/blog/dns-tunneling - https://www.microsoft.com/security/blog/2021/01/20/deep-dive-into-the-solorigate-second-stage-activation-from-sunburst-to-teardrop-and-raindrop/ tags: analytic_story: diff --git a/detections/endpoint/executable_file_written_in_administrative_smb_share.yml b/detections/endpoint/executable_file_written_in_administrative_smb_share.yml index e8c96f3fb8..288d0e71c6 100644 --- a/detections/endpoint/executable_file_written_in_administrative_smb_share.yml +++ b/detections/endpoint/executable_file_written_in_administrative_smb_share.yml @@ -27,7 +27,7 @@ references: - https://attack.mitre.org/techniques/T1021/002/ - https://www.rapid7.com/blog/post/2013/03/09/psexec-demystified/ - https://labs.vipre.com/trickbot-and-its-modules/ -- https://blog.whitehat.eu/2019/05/incident-trickbot-ryuk-2.html +- https://whitehat.eu/incident-response-case-study-featuring-ryuk-and-trickbot-part-2/ tags: analytic_story: - Data Destruction diff --git a/detections/endpoint/extraction_of_registry_hives.yml b/detections/endpoint/extraction_of_registry_hives.yml index 0da0a0fd51..9c32749838 100644 --- a/detections/endpoint/extraction_of_registry_hives.yml +++ b/detections/endpoint/extraction_of_registry_hives.yml @@ -23,7 +23,7 @@ how_to_implement: To successfully implement this search you need to be ingesting known_false_positives: It is possible some agent based products will generate false positives. Filter as needed. references: -- https://www.fireeye.com/blog/threat-research/2021/05/shining-a-light-on-darkside-ransomware-operations.html +- https://www.mandiant.com/resources/shining-a-light-on-darkside-ransomware-operations - https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1003.002/T1003.002.md tags: analytic_story: diff --git a/detections/endpoint/firewall_allowed_program_enable.yml b/detections/endpoint/firewall_allowed_program_enable.yml index 1e90cd0a8d..0d664b3f46 100644 --- a/detections/endpoint/firewall_allowed_program_enable.yml +++ b/detections/endpoint/firewall_allowed_program_enable.yml @@ -27,7 +27,7 @@ known_false_positives: A network operator or systems administrator may utilize a automated or manual execution of this firewall rule that may generate false positives. Filter as needed. references: -- https://app.any.run/tasks/ad4c3cda-41f2-4401-8dba-56cc2d245488/# +- https://app.any.run/tasks/ad4c3cda-41f2-4401-8dba-56cc2d245488/ tags: analytic_story: - Windows Defense Evasion Tactics diff --git a/detections/endpoint/fodhelper_uac_bypass.yml b/detections/endpoint/fodhelper_uac_bypass.yml index a90168a952..10fad03051 100644 --- a/detections/endpoint/fodhelper_uac_bypass.yml +++ b/detections/endpoint/fodhelper_uac_bypass.yml @@ -33,7 +33,7 @@ references: - https://blog.malwarebytes.com/malwarebytes-news/2021/02/lazyscripter-from-empire-to-double-rat/ - https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1548.002/T1548.002.md - https://github.com/gushmazuko/WinBypass/blob/master/FodhelperBypass.ps1 -- https://attack.mitre.org/techniques/T1548/002 +- https://attack.mitre.org/techniques/T1548/002/ tags: analytic_story: - Windows Defense Evasion Tactics diff --git a/detections/endpoint/get_domaintrust_with_powershell.yml b/detections/endpoint/get_domaintrust_with_powershell.yml index 6a8ad0c082..f129d1717d 100644 --- a/detections/endpoint/get_domaintrust_with_powershell.yml +++ b/detections/endpoint/get_domaintrust_with_powershell.yml @@ -25,7 +25,7 @@ how_to_implement: To successfully implement this search you need to be ingesting known_false_positives: Limited false positives as this requires an active Administrator or adversary to bring in, import, and execute. references: -- http://www.harmj0y.net/blog/redteaming/a-guide-to-attacking-domain-trusts/ +- https://blog.harmj0y.net/redteaming/a-guide-to-attacking-domain-trusts/ tags: analytic_story: - Active Directory Discovery diff --git a/detections/endpoint/get_domaintrust_with_powershell_script_block.yml b/detections/endpoint/get_domaintrust_with_powershell_script_block.yml index 910ee5d880..f90d423fed 100644 --- a/detections/endpoint/get_domaintrust_with_powershell_script_block.yml +++ b/detections/endpoint/get_domaintrust_with_powershell_script_block.yml @@ -26,7 +26,7 @@ how_to_implement: To successfully implement this analytic, you will need to enab known_false_positives: It is possible certain system management frameworks utilize this command to gather trust information. references: -- http://www.harmj0y.net/blog/redteaming/a-guide-to-attacking-domain-trusts/ +- https://blog.harmj0y.net/redteaming/a-guide-to-attacking-domain-trusts/ - https://docs.splunk.com/Documentation/UBA/5.0.4.1/GetDataIn/AddPowerShell#Configure_module_logging_for_PowerShell. - https://blog.palantir.com/tampering-with-windows-event-tracing-background-offense-and-defense-4be7ac62ac63 - https://static1.squarespace.com/static/552092d5e4b0661088167e5c/t/59c1814829f18782e24f1fe2/1505853768977/Windows+PowerShell+Logging+Cheat+Sheet+ver+Sept+2017+v2.1.pdf diff --git a/detections/endpoint/getcurrent_user_with_powershell_script_block.yml b/detections/endpoint/getcurrent_user_with_powershell_script_block.yml index 331d62cc82..89d39eead8 100644 --- a/detections/endpoint/getcurrent_user_with_powershell_script_block.yml +++ b/detections/endpoint/getcurrent_user_with_powershell_script_block.yml @@ -22,7 +22,7 @@ known_false_positives: Administrators or power users may use this PowerShell com for troubleshooting. references: - https://attack.mitre.org/techniques/T1033/ -- https://docs.microsoft.com/en-us/dotnet/api/system.security.principal.windowsidentity.getcurrent?view=net-5.0 +- https://docs.microsoft.com/en-us/dotnet/api/system.security.principal.windowsidentity.getcurrent?view=net-6.0&viewFallbackFrom=net-5.0 tags: analytic_story: - Active Directory Discovery diff --git a/detections/endpoint/gpupdate_with_no_command_line_arguments_with_network.yml b/detections/endpoint/gpupdate_with_no_command_line_arguments_with_network.yml index b19ba37540..6e144d84d4 100644 --- a/detections/endpoint/gpupdate_with_no_command_line_arguments_with_network.yml +++ b/detections/endpoint/gpupdate_with_no_command_line_arguments_with_network.yml @@ -29,7 +29,7 @@ known_false_positives: Limited false positives may be present in small environme Tuning may be required based on parent process. references: - https://raw.githubusercontent.com/xx0hcd/Malleable-C2-Profiles/0ef8cf4556e26f6d4190c56ba697c2159faa5822/crimeware/trick_ryuk.profile -- https://blog.cobaltstrike.com/2021/02/09/learn-pipe-fitting-for-all-of-your-offense-projects/ +- https://www.cobaltstrike.com/blog/learn-pipe-fitting-for-all-of-your-offense-projects/ tags: analytic_story: - Cobalt Strike diff --git a/detections/endpoint/high_process_termination_frequency.yml b/detections/endpoint/high_process_termination_frequency.yml index 2ab9945819..b204013bde 100644 --- a/detections/endpoint/high_process_termination_frequency.yml +++ b/detections/endpoint/high_process_termination_frequency.yml @@ -19,7 +19,7 @@ how_to_implement: To successfully implement this search, you need to be ingestin If you are using Sysmon, you must have at least version 6.0.4 of the Sysmon TA. known_false_positives: admin or user tool that can terminate multiple process. references: -- https://www.fireeye.com/blog/threat-research/2020/10/fin11-email-campaigns-precursor-for-ransomware-data-theft.html +- https://www.mandiant.com/resources/fin11-email-campaigns-precursor-for-ransomware-data-theft - https://blog.virustotal.com/2020/11/keep-your-friends-close-keep-ransomware.html tags: analytic_story: diff --git a/detections/endpoint/icedid_exfiltrated_archived_file_creation.yml b/detections/endpoint/icedid_exfiltrated_archived_file_creation.yml index fe1ef7e880..a183c225cd 100644 --- a/detections/endpoint/icedid_exfiltrated_archived_file_creation.yml +++ b/detections/endpoint/icedid_exfiltrated_archived_file_creation.yml @@ -19,7 +19,7 @@ how_to_implement: To successfully implement this search, you need to be ingestin Sysmon TA. known_false_positives: unknown references: -- https://www.cisecurity.org/white-papers/security-primer-icedid/ +- https://www.cisecurity.org/insights/white-papers/security-primer-icedid tags: analytic_story: - IcedID diff --git a/detections/endpoint/impacket_lateral_movement_commandline_parameters.yml b/detections/endpoint/impacket_lateral_movement_commandline_parameters.yml index 051e857767..0ef2da8938 100644 --- a/detections/endpoint/impacket_lateral_movement_commandline_parameters.yml +++ b/detections/endpoint/impacket_lateral_movement_commandline_parameters.yml @@ -31,7 +31,7 @@ references: - https://attack.mitre.org/techniques/T1021/003/ - https://attack.mitre.org/techniques/T1047/ - https://attack.mitre.org/techniques/T1053/ -- https://attack.mitre.org/techniques/T1053/005 +- https://attack.mitre.org/techniques/T1053/005/ - https://github.com/SecureAuthCorp/impacket - https://vk9-sec.com/impacket-remote-code-execution-rce-on-windows-from-linux/ - https://www.microsoft.com/security/blog/2022/01/15/destructive-malware-targeting-ukrainian-organizations/ diff --git a/detections/endpoint/jscript_execution_using_cscript_app.yml b/detections/endpoint/jscript_execution_using_cscript_app.yml index 964c8a046b..7a0a6585a2 100644 --- a/detections/endpoint/jscript_execution_using_cscript_app.yml +++ b/detections/endpoint/jscript_execution_using_cscript_app.yml @@ -24,7 +24,7 @@ how_to_implement: To successfully implement this search, you need to be ingestin Sysmon TA. known_false_positives: unknown references: -- https://www.fireeye.com/blog/threat-research/2018/08/fin7-pursuing-an-enigmatic-and-evasive-global-criminal-operation.html +- https://www.mandiant.com/resources/fin7-pursuing-an-enigmatic-and-evasive-global-criminal-operation - https://attack.mitre.org/groups/G0046/ tags: analytic_story: diff --git a/detections/endpoint/kerberoasting_spn_request_with_rc4_encryption.yml b/detections/endpoint/kerberoasting_spn_request_with_rc4_encryption.yml index e066626974..a8f708c1d4 100644 --- a/detections/endpoint/kerberoasting_spn_request_with_rc4_encryption.yml +++ b/detections/endpoint/kerberoasting_spn_request_with_rc4_encryption.yml @@ -24,8 +24,8 @@ how_to_implement: To successfully implement this search, you need to be ingestin known_false_positives: Older systems that support kerberos RC4 by default like NetApp may generate false positives. Filter as needed references: -- https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1208/T1208.md -- https://www.trimarcsecurity.com/post/trimarcresearch-detecting-kerberoasting-activity +- https://github.com/redcanaryco/atomic-red-team/blob/4e3e9c8096dde00639a6b98845ec349135554ed5/atomics/T1208/T1208.md +- https://www.hub.trimarcsecurity.com/post/trimarc-research-detecting-kerberoasting-activity tags: analytic_story: - Windows Privilege Escalation diff --git a/detections/endpoint/kerberos_user_enumeration.yml b/detections/endpoint/kerberos_user_enumeration.yml index 7b0b57fe32..fcf31e87b0 100644 --- a/detections/endpoint/kerberos_user_enumeration.yml +++ b/detections/endpoint/kerberos_user_enumeration.yml @@ -28,7 +28,7 @@ known_false_positives: Possible false positive scenarios include but are not lim references: - https://github.com/ropnop/kerbrute - https://attack.mitre.org/techniques/T1589/002/ -- https://www.redsiege.com/blog/2020/04/user-enumeration-part-3-windows/ +- https://redsiege.com/tools-techniques/2020/04/user-enumeration-part-3-windows/ tags: analytic_story: - Active Directory Kerberos Attacks diff --git a/detections/endpoint/logon_script_event_trigger_execution.yml b/detections/endpoint/logon_script_event_trigger_execution.yml index 46e8bea28d..c2789af5d0 100644 --- a/detections/endpoint/logon_script_event_trigger_execution.yml +++ b/detections/endpoint/logon_script_event_trigger_execution.yml @@ -23,7 +23,7 @@ how_to_implement: To successfully implement this search, you must be ingesting d to the registry. known_false_positives: unknown references: -- https://attack.mitre.org/techniques/T1037/001 +- https://attack.mitre.org/techniques/T1037/001/ tags: analytic_story: - Windows Persistence Techniques diff --git a/detections/endpoint/ms_scripting_process_loading_ldap_module.yml b/detections/endpoint/ms_scripting_process_loading_ldap_module.yml index aef0f2abc1..f2dcbe9f8e 100644 --- a/detections/endpoint/ms_scripting_process_loading_ldap_module.yml +++ b/detections/endpoint/ms_scripting_process_loading_ldap_module.yml @@ -25,7 +25,7 @@ how_to_implement: To successfully implement this search, you need to be ingestin known_false_positives: automation scripting language may used by network operator to do ldap query. references: -- https://www.fireeye.com/blog/threat-research/2018/08/fin7-pursuing-an-enigmatic-and-evasive-global-criminal-operation.html +- https://www.mandiant.com/resources/fin7-pursuing-an-enigmatic-and-evasive-global-criminal-operation - https://attack.mitre.org/groups/G0046/ tags: analytic_story: diff --git a/detections/endpoint/ms_scripting_process_loading_wmi_module.yml b/detections/endpoint/ms_scripting_process_loading_wmi_module.yml index 9d2c2c28f0..9454179e9b 100644 --- a/detections/endpoint/ms_scripting_process_loading_wmi_module.yml +++ b/detections/endpoint/ms_scripting_process_loading_wmi_module.yml @@ -26,7 +26,7 @@ how_to_implement: To successfully implement this search, you need to be ingestin known_false_positives: automation scripting language may used by network operator to do ldap query. references: -- https://www.fireeye.com/blog/threat-research/2018/08/fin7-pursuing-an-enigmatic-and-evasive-global-criminal-operation.html +- https://www.mandiant.com/resources/fin7-pursuing-an-enigmatic-and-evasive-global-criminal-operation - https://attack.mitre.org/groups/G0046/ tags: analytic_story: diff --git a/detections/endpoint/msbuild_suspicious_spawned_by_script_process.yml b/detections/endpoint/msbuild_suspicious_spawned_by_script_process.yml index 3b9815d26f..5472eb5965 100644 --- a/detections/endpoint/msbuild_suspicious_spawned_by_script_process.yml +++ b/detections/endpoint/msbuild_suspicious_spawned_by_script_process.yml @@ -27,7 +27,7 @@ how_to_implement: To successfully implement this search you need to be ingesting known_false_positives: False positives should be limited as developers do not spawn MSBuild via a WSH. references: -- https://app.any.run/tasks/dc93ee63-050c-4ff8-b07e-8277af9ab939/# +- https://app.any.run/tasks/dc93ee63-050c-4ff8-b07e-8277af9ab939/ tags: analytic_story: - Trusted Developer Utilities Proxy Execution MSBuild diff --git a/detections/endpoint/network_discovery_using_route_windows_app.yml b/detections/endpoint/network_discovery_using_route_windows_app.yml index 6815de87b5..ebf5e23634 100644 --- a/detections/endpoint/network_discovery_using_route_windows_app.yml +++ b/detections/endpoint/network_discovery_using_route_windows_app.yml @@ -24,7 +24,7 @@ known_false_positives: A network operator or systems administrator may utilize a automated host discovery application that may generate false positives or an amazon ec2 script that uses this application. Filter as needed. references: -- https://app.any.run/tasks/ad4c3cda-41f2-4401-8dba-56cc2d245488/# +- https://app.any.run/tasks/ad4c3cda-41f2-4401-8dba-56cc2d245488/ tags: analytic_story: - Active Directory Discovery diff --git a/detections/endpoint/nishang_powershelltcponeline.yml b/detections/endpoint/nishang_powershelltcponeline.yml index 81d98127c6..ec9059bce4 100644 --- a/detections/endpoint/nishang_powershelltcponeline.yml +++ b/detections/endpoint/nishang_powershelltcponeline.yml @@ -29,7 +29,7 @@ references: - https://github.com/samratashok/nishang/blob/master/Shells/Invoke-PowerShellTcpOneLine.ps1 - https://www.volexity.com/blog/2021/03/02/active-exploitation-of-microsoft-exchange-zero-day-vulnerabilities/ - https://www.microsoft.com/security/blog/2021/03/02/hafnium-targeting-exchange-servers/ -- https://blog.rapid7.com/2021/03/03/rapid7s-insightidr-enables-detection-and-response-to-microsoft-exchange-0-day/ +- https://www.rapid7.com/blog/post/2021/03/03/rapid7s-insightidr-enables-detection-and-response-to-microsoft-exchange-0-day/ tags: analytic_story: - HAFNIUM Group diff --git a/detections/endpoint/nltest_domain_trust_discovery.yml b/detections/endpoint/nltest_domain_trust_discovery.yml index 26070b6bfe..45919d38b8 100644 --- a/detections/endpoint/nltest_domain_trust_discovery.yml +++ b/detections/endpoint/nltest_domain_trust_discovery.yml @@ -25,7 +25,7 @@ references: - https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1482/T1482.md - https://malware.news/t/lets-learn-trickbot-implements-network-collector-module-leveraging-cmd-wmi-ldap/19104 - https://attack.mitre.org/techniques/T1482/ -- https://www.owasp.org/images/4/4b/Red_Team_Operating_in_a_Modern_Environment.pdf +- https://owasp.org/www-pdf-archive/Red_Team_Operating_in_a_Modern_Environment.pdf - https://ss64.com/nt/nltest.html - https://redcanary.com/threat-detection-report/techniques/domain-trust-discovery/ - https://thedfirreport.com/2020/10/08/ryuks-return/ diff --git a/detections/endpoint/office_application_drop_executable.yml b/detections/endpoint/office_application_drop_executable.yml index ea59025eb4..8fa06d009e 100644 --- a/detections/endpoint/office_application_drop_executable.yml +++ b/detections/endpoint/office_application_drop_executable.yml @@ -31,7 +31,7 @@ how_to_implement: To successfully implement this search, you need to be ingestin Sysmon TA. Tune and filter known instances where renamed rundll32.exe may be used. known_false_positives: office macro for automation may do this behavior references: -- https://www.fireeye.com/blog/threat-research/2018/08/fin7-pursuing-an-enigmatic-and-evasive-global-criminal-operation.html +- https://www.mandiant.com/resources/fin7-pursuing-an-enigmatic-and-evasive-global-criminal-operation - https://attack.mitre.org/groups/G0046/ tags: analytic_story: diff --git a/detections/endpoint/office_document_spawned_child_process_to_download.yml b/detections/endpoint/office_document_spawned_child_process_to_download.yml index 3dde6f4156..d26b64a7d2 100644 --- a/detections/endpoint/office_document_spawned_child_process_to_download.yml +++ b/detections/endpoint/office_document_spawned_child_process_to_download.yml @@ -25,7 +25,7 @@ how_to_implement: To successfully implement this search, you need to be ingestin used. known_false_positives: Default browser not in the filter list. references: -- https://app.any.run/tasks/92d7ef61-bfd7-4c92-bc15-322172b4ebec/# +- https://app.any.run/tasks/92d7ef61-bfd7-4c92-bc15-322172b4ebec/ tags: analytic_story: - Spearphishing Attachments diff --git a/detections/endpoint/office_spawning_control.yml b/detections/endpoint/office_spawning_control.yml index d566a598d1..8d514f5f02 100644 --- a/detections/endpoint/office_spawning_control.yml +++ b/detections/endpoint/office_spawning_control.yml @@ -30,7 +30,7 @@ references: - https://strontic.github.io/xcyclopedia/library/control.exe-1F13E714A0FEA8887707DFF49287996F.html - https://app.any.run/tasks/36c14029-9df8-439c-bba0-45f2643b0c70/ - https://attack.mitre.org/techniques/T1218/011/ -- https://www.echotrail.io/insights/search/control.exe +- https://www.echotrail.io/insights/search/control.exe/ - https://msrc.microsoft.com/update-guide/vulnerability/CVE-2021-40444 - https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1218.002/T1218.002.yaml tags: diff --git a/detections/endpoint/possible_lateral_movement_powershell_spawn.yml b/detections/endpoint/possible_lateral_movement_powershell_spawn.yml index 0f02d539bc..94fd63e776 100644 --- a/detections/endpoint/possible_lateral_movement_powershell_spawn.yml +++ b/detections/endpoint/possible_lateral_movement_powershell_spawn.yml @@ -30,10 +30,10 @@ how_to_implement: To successfully implement this search, you need to be ingestin known_false_positives: Legitimate applications may spawn PowerShell as a child process of the the identified processes. Filter as needed. references: -- https://attack.mitre.org/techniques/T1021/003 +- https://attack.mitre.org/techniques/T1021/003/ - https://attack.mitre.org/techniques/T1021/006/ - https://attack.mitre.org/techniques/T1047/ -- https://attack.mitre.org/techniques/T1053.005/ +- https://attack.mitre.org/techniques/T1053/005/ - https://attack.mitre.org/techniques/T1543/003/ tags: analytic_story: diff --git a/detections/endpoint/powershell_4104_hunting.yml b/detections/endpoint/powershell_4104_hunting.yml index 65732d0319..07aab110ed 100644 --- a/detections/endpoint/powershell_4104_hunting.yml +++ b/detections/endpoint/powershell_4104_hunting.yml @@ -45,7 +45,7 @@ references: - https://github.com/marcurdy/dfir-toolset/blob/master/Powershell%20Blueteam.txt - https://devblogs.microsoft.com/powershell/powershell-the-blue-team/ - https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_logging?view=powershell-5.1 -- https://www.fireeye.com/blog/threat-research/2016/02/greater_visibilityt.html +- https://www.mandiant.com/resources/greater-visibilityt - https://hurricanelabs.com/splunk-tutorials/how-to-use-powershell-transcription-logs-in-splunk/ tags: analytic_story: diff --git a/detections/endpoint/powershell_using_memory_as_backing_store.yml b/detections/endpoint/powershell_using_memory_as_backing_store.yml index 4541744860..bbc498ef64 100644 --- a/detections/endpoint/powershell_using_memory_as_backing_store.yml +++ b/detections/endpoint/powershell_using_memory_as_backing_store.yml @@ -21,7 +21,7 @@ how_to_implement: To successfully implement this analytic, you will need to enab known_false_positives: powershell may used this function to store out object into memory. references: -- https://www.carbonblack.com/blog/decoding-malicious-powershell-streams/ +- https://web.archive.org/web/20201112031711/https://www.carbonblack.com/blog/decoding-malicious-powershell-streams/ - https://docs.splunk.com/Documentation/UBA/5.0.4.1/GetDataIn/AddPowerShell#Configure_module_logging_for_PowerShell. - https://blog.palantir.com/tampering-with-windows-event-tracing-background-offense-and-defense-4be7ac62ac63 - https://static1.squarespace.com/static/552092d5e4b0661088167e5c/t/59c1814829f18782e24f1fe2/1505853768977/Windows+PowerShell+Logging+Cheat+Sheet+ver+Sept+2017+v2.1.pdf diff --git a/detections/endpoint/print_spooler_adding_a_printer_driver.yml b/detections/endpoint/print_spooler_adding_a_printer_driver.yml index fba2cdcbc3..824349bf6f 100644 --- a/detections/endpoint/print_spooler_adding_a_printer_driver.yml +++ b/detections/endpoint/print_spooler_adding_a_printer_driver.yml @@ -28,8 +28,8 @@ how_to_implement: You will need to ensure PrintService Admin and Operational log known_false_positives: Unknown. This may require filtering. references: - https://twitter.com/MalwareJake/status/1410421445608476679?s=20 -- https://blog.truesec.com/2021/06/30/fix-for-printnightmare-cve-2021-1675-exploit-to-keep-your-print-servers-running-while-a-patch-is-not-available/ -- https://blog.truesec.com/2021/06/30/exploitable-critical-rce-vulnerability-allows-regular-users-to-fully-compromise-active-directory-printnightmare-cve-2021-1675/ +- https://www.truesec.com/hub/blog/fix-for-printnightmare-cve-2021-1675-exploit-to-keep-your-print-servers-running-while-a-patch-is-not-available +- https://www.truesec.com/hub/blog/exploitable-critical-rce-vulnerability-allows-regular-users-to-fully-compromise-active-directory-printnightmare-cve-2021-1675 - https://www.reddit.com/r/msp/comments/ob6y02/critical_vulnerability_printnightmare_exposes tags: analytic_story: diff --git a/detections/endpoint/print_spooler_failed_to_load_a_plug_in.yml b/detections/endpoint/print_spooler_failed_to_load_a_plug_in.yml index 6d4944b43d..03692c30ac 100644 --- a/detections/endpoint/print_spooler_failed_to_load_a_plug_in.yml +++ b/detections/endpoint/print_spooler_failed_to_load_a_plug_in.yml @@ -27,8 +27,8 @@ how_to_implement: You will need to ensure PrintService Admin and Operational log are being logged to Splunk from critical or all systems. known_false_positives: False positives are unknown and filtering may be required. references: -- https://blog.truesec.com/2021/06/30/fix-for-printnightmare-cve-2021-1675-exploit-to-keep-your-print-servers-running-while-a-patch-is-not-available/ -- https://blog.truesec.com/2021/06/30/exploitable-critical-rce-vulnerability-allows-regular-users-to-fully-compromise-active-directory-printnightmare-cve-2021-1675/ +- https://www.truesec.com/hub/blog/fix-for-printnightmare-cve-2021-1675-exploit-to-keep-your-print-servers-running-while-a-patch-is-not-available +- https://www.truesec.com/hub/blog/exploitable-critical-rce-vulnerability-allows-regular-users-to-fully-compromise-active-directory-printnightmare-cve-2021-1675 - https://www.reddit.com/r/msp/comments/ob6y02/critical_vulnerability_printnightmare_exposes tags: analytic_story: diff --git a/detections/endpoint/process_deleting_its_process_file_path.yml b/detections/endpoint/process_deleting_its_process_file_path.yml index 91963eddde..ee649e7d5b 100644 --- a/detections/endpoint/process_deleting_its_process_file_path.yml +++ b/detections/endpoint/process_deleting_its_process_file_path.yml @@ -24,7 +24,7 @@ how_to_implement: You must be ingesting data that records process activity from model. known_false_positives: unknown references: -- https://www.fireeye.com/blog/threat-research/2020/10/fin11-email-campaigns-precursor-for-ransomware-data-theft.html +- https://www.mandiant.com/resources/fin11-email-campaigns-precursor-for-ransomware-data-theft - https://blog.virustotal.com/2020/11/keep-your-friends-close-keep-ransomware.html - https://www.microsoft.com/security/blog/2022/01/15/destructive-malware-targeting-ukrainian-organizations/ tags: diff --git a/detections/endpoint/ransomware_notes_bulk_creation.yml b/detections/endpoint/ransomware_notes_bulk_creation.yml index 4beb9bbadd..7f18f31534 100644 --- a/detections/endpoint/ransomware_notes_bulk_creation.yml +++ b/detections/endpoint/ransomware_notes_bulk_creation.yml @@ -22,7 +22,7 @@ how_to_implement: You must be ingesting data that records the filesystem activit you want to collect data. known_false_positives: unknown references: -- https://www.fireeye.com/blog/threat-research/2020/10/fin11-email-campaigns-precursor-for-ransomware-data-theft.html +- https://www.mandiant.com/resources/fin11-email-campaigns-precursor-for-ransomware-data-theft - https://blog.virustotal.com/2020/11/keep-your-friends-close-keep-ransomware.html tags: analytic_story: diff --git a/detections/endpoint/regsvr32_silent_and_install_param_dll_loading.yml b/detections/endpoint/regsvr32_silent_and_install_param_dll_loading.yml index 25a35dcb5b..1aab04eb9a 100644 --- a/detections/endpoint/regsvr32_silent_and_install_param_dll_loading.yml +++ b/detections/endpoint/regsvr32_silent_and_install_param_dll_loading.yml @@ -26,7 +26,7 @@ how_to_implement: To successfully implement this search you need to be ingesting known_false_positives: Other third part application may used this parameter but not so common in base windows environment. references: -- https://app.any.run/tasks/dc93ee63-050c-4ff8-b07e-8277af9ab939/# +- https://app.any.run/tasks/dc93ee63-050c-4ff8-b07e-8277af9ab939/ - https://attack.mitre.org/techniques/T1218/010/ tags: analytic_story: diff --git a/detections/endpoint/remcos_rat_file_creation_in_remcos_folder.yml b/detections/endpoint/remcos_rat_file_creation_in_remcos_folder.yml index 5a7db5ddf9..99f25fd29a 100644 --- a/detections/endpoint/remcos_rat_file_creation_in_remcos_folder.yml +++ b/detections/endpoint/remcos_rat_file_creation_in_remcos_folder.yml @@ -21,7 +21,7 @@ how_to_implement: To successfully implement this search, you need to be ingestin Sysmon TA. known_false_positives: unknown references: -- https://success.trendmicro.com/solution/1123281-remcos-malware-information +- https://success.trendmicro.com/dcx/s/solution/1123281-remcos-malware-information?language=en_US - https://blog.malwarebytes.com/threat-intelligence/2021/07/remcos-rat-delivered-via-visual-basic/ tags: analytic_story: diff --git a/detections/endpoint/resize_shadowstorage_volume.yml b/detections/endpoint/resize_shadowstorage_volume.yml index e26140cd64..5b8102197c 100644 --- a/detections/endpoint/resize_shadowstorage_volume.yml +++ b/detections/endpoint/resize_shadowstorage_volume.yml @@ -28,7 +28,7 @@ how_to_implement: To successfully implement this search, you need to be ingestin Sysmon TA. known_false_positives: network admin can resize the shadowstorage for valid purposes. references: -- https://www.fireeye.com/blog/threat-research/2020/10/fin11-email-campaigns-precursor-for-ransomware-data-theft.html +- https://www.mandiant.com/resources/fin11-email-campaigns-precursor-for-ransomware-data-theft - https://blog.virustotal.com/2020/11/keep-your-friends-close-keep-ransomware.html - https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1490/T1490.md - https://redcanary.com/blog/blackbyte-ransomware/ diff --git a/detections/endpoint/rubeus_command_line_parameters.yml b/detections/endpoint/rubeus_command_line_parameters.yml index fc1f7a21f5..6e99edde4c 100644 --- a/detections/endpoint/rubeus_command_line_parameters.yml +++ b/detections/endpoint/rubeus_command_line_parameters.yml @@ -34,7 +34,7 @@ known_false_positives: Although unlikely, legitimate applications may use the sa command line parameters as Rubeus. Filter as needed. references: - https://github.com/GhostPack/Rubeus -- http://www.harmj0y.net/blog/redteaming/from-kekeo-to-rubeus/ +- https://web.archive.org/web/20210725005734/http://www.harmj0y.net/blog/redteaming/from-kekeo-to-rubeus/ - https://attack.mitre.org/techniques/T1550/003/ - https://en.hackndo.com/kerberos-silver-golden-tickets/ tags: diff --git a/detections/endpoint/rubeus_kerberos_ticket_exports_through_winlogon_access.yml b/detections/endpoint/rubeus_kerberos_ticket_exports_through_winlogon_access.yml index ce3cf7ae65..5e8df260a9 100644 --- a/detections/endpoint/rubeus_kerberos_ticket_exports_through_winlogon_access.yml +++ b/detections/endpoint/rubeus_kerberos_ticket_exports_through_winlogon_access.yml @@ -31,7 +31,7 @@ known_false_positives: Legitimate applications may obtain a handle for winlogon. Filter as needed references: - https://github.com/GhostPack/Rubeus -- http://www.harmj0y.net/blog/redteaming/from-kekeo-to-rubeus/ +- https://web.archive.org/web/20210725005734/http://www.harmj0y.net/blog/redteaming/from-kekeo-to-rubeus/ - https://attack.mitre.org/techniques/T1550/003/ tags: analytic_story: diff --git a/detections/endpoint/runas_execution_in_commandline.yml b/detections/endpoint/runas_execution_in_commandline.yml index 3fd74c50d6..74202d6ecc 100644 --- a/detections/endpoint/runas_execution_in_commandline.yml +++ b/detections/endpoint/runas_execution_in_commandline.yml @@ -27,7 +27,7 @@ known_false_positives: A network operator or systems administrator may utilize a automated or manual execute this command that may generate false positives. filter is needed. references: -- https://app.any.run/tasks/ad4c3cda-41f2-4401-8dba-56cc2d245488/# +- https://app.any.run/tasks/ad4c3cda-41f2-4401-8dba-56cc2d245488/ tags: analytic_story: - Windows Privilege Escalation diff --git a/detections/endpoint/rundll32_with_no_command_line_arguments_with_network.yml b/detections/endpoint/rundll32_with_no_command_line_arguments_with_network.yml index bc4cd4c43b..4ece57a8bc 100644 --- a/detections/endpoint/rundll32_with_no_command_line_arguments_with_network.yml +++ b/detections/endpoint/rundll32_with_no_command_line_arguments_with_network.yml @@ -35,7 +35,7 @@ known_false_positives: Although unlikely, some legitimate applications may use a references: - https://attack.mitre.org/techniques/T1218/011/ - https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1218.011/T1218.011.md -- https://lolbas-project.github.io/lolbas/Binaries/Rundll32 +- https://lolbas-project.github.io/lolbas/Binaries/Rundll32/ - https://bohops.com/2018/02/26/leveraging-inf-sct-fetch-execute-techniques-for-bypass-evasion-persistence/ tags: analytic_story: diff --git a/detections/endpoint/schedule_task_with_rundll32_command_trigger.yml b/detections/endpoint/schedule_task_with_rundll32_command_trigger.yml index 85cfe1293e..342bdbb973 100644 --- a/detections/endpoint/schedule_task_with_rundll32_command_trigger.yml +++ b/detections/endpoint/schedule_task_with_rundll32_command_trigger.yml @@ -30,7 +30,7 @@ how_to_implement: To successfully implement this search, you need to be ingestin known_false_positives: unknown references: - https://labs.vipre.com/trickbot-and-its-modules/ -- https://blog.whitehat.eu/2019/05/incident-trickbot-ryuk-2.html +- https://whitehat.eu/incident-response-case-study-featuring-ryuk-and-trickbot-part-2/ tags: analytic_story: - Windows Persistence Techniques diff --git a/detections/endpoint/sdclt_uac_bypass.yml b/detections/endpoint/sdclt_uac_bypass.yml index a217ae1d8d..6e0bfbad04 100644 --- a/detections/endpoint/sdclt_uac_bypass.yml +++ b/detections/endpoint/sdclt_uac_bypass.yml @@ -33,7 +33,7 @@ known_false_positives: Limited to no false positives are expected. references: - https://enigma0x3.net/2017/03/17/fileless-uac-bypass-using-sdclt-exe/ - https://github.com/hfiref0x/UACME -- https://www.cyborgsecurity.com/cyborg_labs/threat-hunt-deep-dives-user-account-control-bypass-via-registry-modification/ +- https://www.cyborgsecurity.com/cyborg-labs/threat-hunt-deep-dives-user-account-control-bypass-via-registry-modification/ tags: analytic_story: - Windows Defense Evasion Tactics diff --git a/detections/endpoint/searchprotocolhost_with_no_command_line_with_network.yml b/detections/endpoint/searchprotocolhost_with_no_command_line_with_network.yml index 72bb777f36..344ea9a9db 100644 --- a/detections/endpoint/searchprotocolhost_with_no_command_line_with_network.yml +++ b/detections/endpoint/searchprotocolhost_with_no_command_line_with_network.yml @@ -28,7 +28,7 @@ how_to_implement: To successfully implement this search you need to be ingesting known_false_positives: Limited false positives may be present in small environments. Tuning may be required based on parent process. references: -- https://github.com/fireeye/red_team_tool_countermeasures/blob/master/rules/PGF/supplemental/hxioc/SUSPICIOUS%20EXECUTION%20OF%20SEARCHPROTOCOLHOST%20(METHODOLOGY).ioc +- https://github.com/mandiant/red_team_tool_countermeasures/blob/master/rules/PGF/supplemental/hxioc/SUSPICIOUS%20EXECUTION%20OF%20SEARCHPROTOCOLHOST%20(METHODOLOGY).ioc tags: analytic_story: - Cobalt Strike diff --git a/detections/endpoint/serviceprincipalnames_discovery_with_powershell.yml b/detections/endpoint/serviceprincipalnames_discovery_with_powershell.yml index e928600d1e..78ed3308a1 100644 --- a/detections/endpoint/serviceprincipalnames_discovery_with_powershell.yml +++ b/detections/endpoint/serviceprincipalnames_discovery_with_powershell.yml @@ -37,7 +37,7 @@ references: - https://strontic.github.io/xcyclopedia/library/setspn.exe-5C184D581524245DAD7A0A02B51FD2C2.html - https://attack.mitre.org/techniques/T1558/003/ - https://social.technet.microsoft.com/wiki/contents/articles/717.service-principal-names-spn-setspn-syntax.aspx -- https://www.harmj0y.net/blog/powershell/kerberoasting-without-mimikatz/ +- https://web.archive.org/web/20220212163642/https://www.harmj0y.net/blog/powershell/kerberoasting-without-mimikatz/ - https://blog.zsec.uk/paving-2-da-wholeset/ - https://msitpros.com/?p=3113 - https://adsecurity.org/?p=3466 diff --git a/detections/endpoint/serviceprincipalnames_discovery_with_setspn.yml b/detections/endpoint/serviceprincipalnames_discovery_with_setspn.yml index 895d40e049..05e43bedb0 100644 --- a/detections/endpoint/serviceprincipalnames_discovery_with_setspn.yml +++ b/detections/endpoint/serviceprincipalnames_discovery_with_setspn.yml @@ -49,7 +49,7 @@ references: - https://strontic.github.io/xcyclopedia/library/setspn.exe-5C184D581524245DAD7A0A02B51FD2C2.html - https://attack.mitre.org/techniques/T1558/003/ - https://social.technet.microsoft.com/wiki/contents/articles/717.service-principal-names-spn-setspn-syntax.aspx -- https://www.harmj0y.net/blog/powershell/kerberoasting-without-mimikatz/ +- https://web.archive.org/web/20220212163642/https://www.harmj0y.net/blog/powershell/kerberoasting-without-mimikatz/ - https://blog.zsec.uk/paving-2-da-wholeset/ - https://msitpros.com/?p=3113 - https://adsecurity.org/?p=3466 diff --git a/detections/endpoint/services_escalate_exe.yml b/detections/endpoint/services_escalate_exe.yml index c92a1c97ba..1acb3164ea 100644 --- a/detections/endpoint/services_escalate_exe.yml +++ b/detections/endpoint/services_escalate_exe.yml @@ -31,7 +31,7 @@ known_false_positives: False positives should be limited as `services.exe` shoul references: - https://thedfirreport.com/2021/03/29/sodinokibi-aka-revil-ransomware/ - https://attack.mitre.org/techniques/T1548/ -- https://www.cobaltstrike.com/help-beacon +- https://hstechdocs.helpsystems.com/manuals/cobaltstrike/current/userguide/index.htm#cshid=1085 tags: analytic_story: - Cobalt Strike diff --git a/detections/endpoint/slui_runas_elevated.yml b/detections/endpoint/slui_runas_elevated.yml index 4dbc34bea1..2a13cda060 100644 --- a/detections/endpoint/slui_runas_elevated.yml +++ b/detections/endpoint/slui_runas_elevated.yml @@ -25,10 +25,10 @@ known_false_positives: Limited false positives should be present as this is not used by legitimate applications. references: - https://www.exploit-db.com/exploits/46998 -- https://medium.com/@mattharr0ey/privilege-escalation-uac-bypass-in-changepk-c40b92818d1b +- https://mattharr0ey.medium.com/privilege-escalation-uac-bypass-in-changepk-c40b92818d1b - https://gist.github.com/r00t-3xp10it/0c92cd554d3156fd74f6c25660ccc466 - https://www.rapid7.com/db/modules/exploit/windows/local/bypassuac_sluihijack/ -- https://www.fireeye.com/blog/threat-research/2021/05/shining-a-light-on-darkside-ransomware-operations.html +- https://www.mandiant.com/resources/shining-a-light-on-darkside-ransomware-operations tags: analytic_story: - DarkSide Ransomware diff --git a/detections/endpoint/slui_spawning_a_process.yml b/detections/endpoint/slui_spawning_a_process.yml index 3215584ac4..cd58e631f7 100644 --- a/detections/endpoint/slui_spawning_a_process.yml +++ b/detections/endpoint/slui_spawning_a_process.yml @@ -26,7 +26,7 @@ known_false_positives: Certain applications may spawn from `slui.exe` that are l references: - https://www.exploit-db.com/exploits/46998 - https://www.rapid7.com/db/modules/exploit/windows/local/bypassuac_sluihijack/ -- https://www.fireeye.com/blog/threat-research/2021/05/shining-a-light-on-darkside-ransomware-operations.html +- https://www.mandiant.com/resources/shining-a-light-on-darkside-ransomware-operations tags: analytic_story: - DarkSide Ransomware diff --git a/detections/endpoint/spoolsv_spawning_rundll32.yml b/detections/endpoint/spoolsv_spawning_rundll32.yml index 5b326fbfa3..f899e7cb85 100644 --- a/detections/endpoint/spoolsv_spawning_rundll32.yml +++ b/detections/endpoint/spoolsv_spawning_rundll32.yml @@ -26,8 +26,8 @@ how_to_implement: To successfully implement this search you need to be ingesting known_false_positives: Limited false positives have been identified. There are limited instances where `rundll32.exe` may be spawned by a legitimate print driver. references: -- https://blog.truesec.com/2021/06/30/fix-for-printnightmare-cve-2021-1675-exploit-to-keep-your-print-servers-running-while-a-patch-is-not-available/ -- https://blog.truesec.com/2021/06/30/exploitable-critical-rce-vulnerability-allows-regular-users-to-fully-compromise-active-directory-printnightmare-cve-2021-1675/ +- https://www.truesec.com/hub/blog/fix-for-printnightmare-cve-2021-1675-exploit-to-keep-your-print-servers-running-while-a-patch-is-not-available +- https://www.truesec.com/hub/blog/exploitable-critical-rce-vulnerability-allows-regular-users-to-fully-compromise-active-directory-printnightmare-cve-2021-1675 - https://www.reddit.com/r/msp/comments/ob6y02/critical_vulnerability_printnightmare_exposes tags: analytic_story: diff --git a/detections/endpoint/spoolsv_suspicious_process_access.yml b/detections/endpoint/spoolsv_suspicious_process_access.yml index 121e22215b..5e8615a259 100644 --- a/detections/endpoint/spoolsv_suspicious_process_access.yml +++ b/detections/endpoint/spoolsv_suspicious_process_access.yml @@ -23,8 +23,8 @@ how_to_implement: To successfully implement this search, you need to be ingestin known_false_positives: Unknown. Filter as needed. references: - https://github.com/cube0x0/impacket/commit/73b9466c17761384ece11e1028ec6689abad6818 -- https://blog.truesec.com/2021/06/30/fix-for-printnightmare-cve-2021-1675-exploit-to-keep-your-print-servers-running-while-a-patch-is-not-available/ -- https://blog.truesec.com/2021/06/30/exploitable-critical-rce-vulnerability-allows-regular-users-to-fully-compromise-active-directory-printnightmare-cve-2021-1675/ +- https://www.truesec.com/hub/blog/fix-for-printnightmare-cve-2021-1675-exploit-to-keep-your-print-servers-running-while-a-patch-is-not-available +- https://www.truesec.com/hub/blog/exploitable-critical-rce-vulnerability-allows-regular-users-to-fully-compromise-active-directory-printnightmare-cve-2021-1675 - https://www.reddit.com/r/msp/comments/ob6y02/critical_vulnerability_printnightmare_exposes tags: analytic_story: diff --git a/detections/endpoint/spoolsv_writing_a_dll.yml b/detections/endpoint/spoolsv_writing_a_dll.yml index 8c5aebff2d..537821a9cf 100644 --- a/detections/endpoint/spoolsv_writing_a_dll.yml +++ b/detections/endpoint/spoolsv_writing_a_dll.yml @@ -28,8 +28,8 @@ how_to_implement: To successfully implement this search you need to be ingesting node. known_false_positives: Unknown. references: -- https://blog.truesec.com/2021/06/30/fix-for-printnightmare-cve-2021-1675-exploit-to-keep-your-print-servers-running-while-a-patch-is-not-available/ -- https://blog.truesec.com/2021/06/30/exploitable-critical-rce-vulnerability-allows-regular-users-to-fully-compromise-active-directory-printnightmare-cve-2021-1675/ +- https://www.truesec.com/hub/blog/fix-for-printnightmare-cve-2021-1675-exploit-to-keep-your-print-servers-running-while-a-patch-is-not-available +- https://www.truesec.com/hub/blog/exploitable-critical-rce-vulnerability-allows-regular-users-to-fully-compromise-active-directory-printnightmare-cve-2021-1675 - https://www.reddit.com/r/msp/comments/ob6y02/critical_vulnerability_printnightmare_exposes tags: analytic_story: diff --git a/detections/endpoint/spoolsv_writing_a_dll___sysmon.yml b/detections/endpoint/spoolsv_writing_a_dll___sysmon.yml index c725e2030e..a1a2b581fe 100644 --- a/detections/endpoint/spoolsv_writing_a_dll___sysmon.yml +++ b/detections/endpoint/spoolsv_writing_a_dll___sysmon.yml @@ -23,8 +23,8 @@ how_to_implement: To successfully implement this search, you need to be ingestin known_false_positives: Limited false positives. Filter as needed. references: - https://github.com/cube0x0/impacket/commit/73b9466c17761384ece11e1028ec6689abad6818 -- https://blog.truesec.com/2021/06/30/fix-for-printnightmare-cve-2021-1675-exploit-to-keep-your-print-servers-running-while-a-patch-is-not-available/ -- https://blog.truesec.com/2021/06/30/exploitable-critical-rce-vulnerability-allows-regular-users-to-fully-compromise-active-directory-printnightmare-cve-2021-1675/ +- https://www.truesec.com/hub/blog/fix-for-printnightmare-cve-2021-1675-exploit-to-keep-your-print-servers-running-while-a-patch-is-not-available +- https://www.truesec.com/hub/blog/exploitable-critical-rce-vulnerability-allows-regular-users-to-fully-compromise-active-directory-printnightmare-cve-2021-1675 - https://www.reddit.com/r/msp/comments/ob6y02/critical_vulnerability_printnightmare_exposes tags: analytic_story: diff --git a/detections/endpoint/sqlite_module_in_temp_folder.yml b/detections/endpoint/sqlite_module_in_temp_folder.yml index 7611e81ac0..35f4d81ff1 100644 --- a/detections/endpoint/sqlite_module_in_temp_folder.yml +++ b/detections/endpoint/sqlite_module_in_temp_folder.yml @@ -21,7 +21,7 @@ how_to_implement: To successfully implement this search, you need to be ingestin Sysmon TA. known_false_positives: unknown references: -- https://www.cisecurity.org/white-papers/security-primer-icedid/ +- https://www.cisecurity.org/insights/white-papers/security-primer-icedid tags: analytic_story: - IcedID diff --git a/detections/endpoint/ssa___detect_rclone_command_line_usage.yml b/detections/endpoint/ssa___detect_rclone_command_line_usage.yml index fb2d973337..a1ba6e1c39 100644 --- a/detections/endpoint/ssa___detect_rclone_command_line_usage.yml +++ b/detections/endpoint/ssa___detect_rclone_command_line_usage.yml @@ -37,7 +37,7 @@ known_false_positives: False positives should be limited as this is restricted t the Rclone process name. Filter or tune the analytic as needed. references: - https://redcanary.com/blog/rclone-mega-extortion/ -- https://www.fireeye.com/blog/threat-research/2021/05/shining-a-light-on-darkside-ransomware-operations.html +- https://www.mandiant.com/resources/shining-a-light-on-darkside-ransomware-operations - https://thedfirreport.com/2021/03/29/sodinokibi-aka-revil-ransomware/ - https://thedfirreport.com/2021/11/29/continuing-the-bazar-ransomware-story/ tags: diff --git a/detections/endpoint/ssa___dns_exfiltration_using_nslookup_app.yml b/detections/endpoint/ssa___dns_exfiltration_using_nslookup_app.yml index 6463d7e1a0..6948bda87f 100644 --- a/detections/endpoint/ssa___dns_exfiltration_using_nslookup_app.yml +++ b/detections/endpoint/ssa___dns_exfiltration_using_nslookup_app.yml @@ -32,8 +32,8 @@ how_to_implement: To successfully implement this search you need to be ingesting known_false_positives: It is possible for some legitimate administrative utilities to use similar cmd_line parameters. Filter as needed. references: -- https://www.fireeye.com/blog/threat-research/2017/03/fin7_spear_phishing.html -- https://www.varonis.com/blog/dns-tunneling/ +- https://www.mandiant.com/resources/fin7-spear-phishing-campaign-targets-personnel-involved-sec-filings +- https://www.varonis.com/blog/dns-tunneling - https://www.microsoft.com/security/blog/2021/01/20/deep-dive-into-the-solorigate-second-stage-activation-from-sunburst-to-teardrop-and-raindrop/ tags: analytic_story: diff --git a/detections/endpoint/ssa___resize_shadowstorage_volume.yml b/detections/endpoint/ssa___resize_shadowstorage_volume.yml index 8051f68180..2e976b397c 100644 --- a/detections/endpoint/ssa___resize_shadowstorage_volume.yml +++ b/detections/endpoint/ssa___resize_shadowstorage_volume.yml @@ -30,7 +30,7 @@ how_to_implement: To successfully implement this search, you need to be ingestin known_false_positives: System administrators may resize the shadowstorage for valid purposes. Filter as needed. references: -- https://www.fireeye.com/blog/threat-research/2020/10/fin11-email-campaigns-precursor-for-ransomware-data-theft.html +- https://www.mandiant.com/resources/fin11-email-campaigns-precursor-for-ransomware-data-theft - https://blog.virustotal.com/2020/11/keep-your-friends-close-keep-ransomware.html tags: analytic_story: diff --git a/detections/endpoint/ssa___windows_certutil_urlcache_download.yml b/detections/endpoint/ssa___windows_certutil_urlcache_download.yml index 1cc747b227..9559de6e58 100644 --- a/detections/endpoint/ssa___windows_certutil_urlcache_download.yml +++ b/detections/endpoint/ssa___windows_certutil_urlcache_download.yml @@ -34,7 +34,7 @@ known_false_positives: Limited false positives in most environments, however tun references: - https://attack.mitre.org/techniques/T1105/ - https://www.avira.com/en/blog/certutil-abused-by-attackers-to-spread-threats -- https://www.fireeye.com/blog/threat-research/2019/10/certutil-qualms-they-came-to-drop-fombs.html +- https://web.archive.org/web/20210921110637/https://www.fireeye.com/blog/threat-research/2019/10/certutil-qualms-they-came-to-drop-fombs.html tags: analytic_story: - Ingress Tool Transfer diff --git a/detections/endpoint/ssa___windows_eventvwr_uac_bypass.yml b/detections/endpoint/ssa___windows_eventvwr_uac_bypass.yml index 0fbedc0c94..236ae03d09 100644 --- a/detections/endpoint/ssa___windows_eventvwr_uac_bypass.yml +++ b/detections/endpoint/ssa___windows_eventvwr_uac_bypass.yml @@ -35,7 +35,7 @@ known_false_positives: None known at this time. references: - https://blog.malwarebytes.com/malwarebytes-news/2021/02/lazyscripter-from-empire-to-double-rat/ - https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1548.002/T1548.002.md -- https://attack.mitre.org/techniques/T1548/002 +- https://attack.mitre.org/techniques/T1548/002/ - https://enigma0x3.net/2016/08/15/fileless-uac-bypass-using-eventvwr-exe-and-registry-hijacking/ tags: analytic_story: diff --git a/detections/endpoint/ssa___windows_rasautou_dll_execution.yml b/detections/endpoint/ssa___windows_rasautou_dll_execution.yml index ff0ec076d5..1e567f0bcc 100644 --- a/detections/endpoint/ssa___windows_rasautou_dll_execution.yml +++ b/detections/endpoint/ssa___windows_rasautou_dll_execution.yml @@ -34,7 +34,7 @@ references: - https://github.com/mandiant/DueDLLigence - https://github.com/MHaggis/notes/blob/master/utilities/Invoke-SPLDLLigence.ps1 - https://gist.github.com/NickTyrer/c6043e4b302d5424f701f15baf136513 -- https://www.fireeye.com/blog/threat-research/2019/10/staying-hidden-on-the-endpoint-evading-detection-with-shellcode.html +- https://www.mandiant.com/resources/staying-hidden-on-the-endpoint-evading-detection-with-shellcode tags: analytic_story: - Windows Defense Evasion Tactics diff --git a/detections/endpoint/suspicious_dllhost_no_command_line_arguments.yml b/detections/endpoint/suspicious_dllhost_no_command_line_arguments.yml index 1312e658f1..eb9e665c8f 100644 --- a/detections/endpoint/suspicious_dllhost_no_command_line_arguments.yml +++ b/detections/endpoint/suspicious_dllhost_no_command_line_arguments.yml @@ -26,7 +26,7 @@ known_false_positives: Limited false positives may be present in small environme Tuning may be required based on parent process. references: - https://raw.githubusercontent.com/threatexpress/malleable-c2/c3385e481159a759f79b8acfe11acf240893b830/jquery-c2.4.2.profile -- https://blog.cobaltstrike.com/2021/02/09/learn-pipe-fitting-for-all-of-your-offense-projects/ +- https://www.cobaltstrike.com/blog/learn-pipe-fitting-for-all-of-your-offense-projects/ tags: analytic_story: - Cobalt Strike diff --git a/detections/endpoint/suspicious_gpupdate_no_command_line_arguments.yml b/detections/endpoint/suspicious_gpupdate_no_command_line_arguments.yml index 63799d764f..9b4e2687db 100644 --- a/detections/endpoint/suspicious_gpupdate_no_command_line_arguments.yml +++ b/detections/endpoint/suspicious_gpupdate_no_command_line_arguments.yml @@ -25,7 +25,7 @@ known_false_positives: Limited false positives may be present in small environme Tuning may be required based on parent process. references: - https://raw.githubusercontent.com/xx0hcd/Malleable-C2-Profiles/0ef8cf4556e26f6d4190c56ba697c2159faa5822/crimeware/trick_ryuk.profile -- https://blog.cobaltstrike.com/2021/02/09/learn-pipe-fitting-for-all-of-your-offense-projects/ +- https://www.cobaltstrike.com/blog/learn-pipe-fitting-for-all-of-your-offense-projects/ tags: analytic_story: - Cobalt Strike diff --git a/detections/endpoint/suspicious_image_creation_in_appdata_folder.yml b/detections/endpoint/suspicious_image_creation_in_appdata_folder.yml index 3c7ddb8699..76b8e82de4 100644 --- a/detections/endpoint/suspicious_image_creation_in_appdata_folder.yml +++ b/detections/endpoint/suspicious_image_creation_in_appdata_folder.yml @@ -28,7 +28,7 @@ how_to_implement: To successfully implement this search, you need to be ingestin Sysmon TA. known_false_positives: unknown references: -- https://success.trendmicro.com/solution/1123281-remcos-malware-information +- https://success.trendmicro.com/dcx/s/solution/1123281-remcos-malware-information?language=en_US - https://blog.malwarebytes.com/threat-intelligence/2021/07/remcos-rat-delivered-via-visual-basic/ tags: analytic_story: diff --git a/detections/endpoint/suspicious_reg_exe_process.yml b/detections/endpoint/suspicious_reg_exe_process.yml index a0c4ac1abd..8eb801fb52 100644 --- a/detections/endpoint/suspicious_reg_exe_process.yml +++ b/detections/endpoint/suspicious_reg_exe_process.yml @@ -28,7 +28,7 @@ known_false_positives: It's possible for system administrators to write scripts exhibit this behavior. If this is the case, the search will need to be modified to filter them out. references: -- https://car.mitre.org/wiki/CAR-2013-03-001 +- https://car.mitre.org/wiki/CAR-2013-03-001/ tags: analytic_story: - Windows Defense Evasion Tactics diff --git a/detections/endpoint/suspicious_rundll32_dllregisterserver.yml b/detections/endpoint/suspicious_rundll32_dllregisterserver.yml index 01c948bca9..c8be5358d0 100644 --- a/detections/endpoint/suspicious_rundll32_dllregisterserver.yml +++ b/detections/endpoint/suspicious_rundll32_dllregisterserver.yml @@ -30,11 +30,11 @@ known_false_positives: This is likely to produce false positives and will requir references: - https://attack.mitre.org/techniques/T1218/011/ - https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1218.011/T1218.011.md -- https://lolbas-project.github.io/lolbas/Binaries/Rundll32 +- https://lolbas-project.github.io/lolbas/Binaries/Rundll32/ - https://symantec-enterprise-blogs.security.com/blogs/threat-intelligence/seedworm-apt-iran-middle-east - https://github.com/pan-unit42/tweets/blob/master/2020-12-10-IOCs-from-Ursnif-infection-with-Delf-variant.txt - https://www.crowdstrike.com/blog/duck-hunting-with-falcon-complete-qakbot-zip-based-campaign/ -- https://msdn.microsoft.com/en-us/library/windows/desktop/ms682162(v=vs.85).aspx +- https://docs.microsoft.com/en-us/windows/win32/api/olectl/nf-olectl-dllregisterserver?redirectedfrom=MSDN tags: analytic_story: - Suspicious Rundll32 Activity diff --git a/detections/endpoint/suspicious_rundll32_startw.yml b/detections/endpoint/suspicious_rundll32_startw.yml index f490971e25..9917f0f74b 100644 --- a/detections/endpoint/suspicious_rundll32_startw.yml +++ b/detections/endpoint/suspicious_rundll32_startw.yml @@ -31,8 +31,8 @@ known_false_positives: Although unlikely, some legitimate applications may use S references: - https://attack.mitre.org/techniques/T1218/011/ - https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1218.011/T1218.011.md -- https://www.cobaltstrike.com/help-windows-executable -- https://lolbas-project.github.io/lolbas/Binaries/Rundll32 +- https://hstechdocs.helpsystems.com/manuals/cobaltstrike/current/userguide/index.htm#cshid=1036 +- https://lolbas-project.github.io/lolbas/Binaries/Rundll32/ - https://bohops.com/2018/02/26/leveraging-inf-sct-fetch-execute-techniques-for-bypass-evasion-persistence/ tags: analytic_story: diff --git a/detections/endpoint/suspicious_rundll32_with_no_command_line_arguments.yml b/detections/endpoint/suspicious_rundll32_with_no_command_line_arguments.yml index 9923bf96eb..69bf3619f8 100644 --- a/detections/endpoint/suspicious_rundll32_with_no_command_line_arguments.yml +++ b/detections/endpoint/suspicious_rundll32_with_no_command_line_arguments.yml @@ -27,7 +27,7 @@ known_false_positives: Although unlikely, some legitimate applications may use a references: - https://attack.mitre.org/techniques/T1218/011/ - https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1218.011/T1218.011.md -- https://lolbas-project.github.io/lolbas/Binaries/Rundll32 +- https://lolbas-project.github.io/lolbas/Binaries/Rundll32/ - https://bohops.com/2018/02/26/leveraging-inf-sct-fetch-execute-techniques-for-bypass-evasion-persistence/ tags: analytic_story: diff --git a/detections/endpoint/suspicious_searchprotocolhost_no_command_line_arguments.yml b/detections/endpoint/suspicious_searchprotocolhost_no_command_line_arguments.yml index 0a667c2244..91d7f49a76 100644 --- a/detections/endpoint/suspicious_searchprotocolhost_no_command_line_arguments.yml +++ b/detections/endpoint/suspicious_searchprotocolhost_no_command_line_arguments.yml @@ -26,7 +26,7 @@ how_to_implement: To successfully implement this search you need to be ingesting known_false_positives: Limited false positives may be present in small environments. Tuning may be required based on parent process. references: -- https://github.com/fireeye/red_team_tool_countermeasures/blob/master/rules/PGF/supplemental/hxioc/SUSPICIOUS%20EXECUTION%20OF%20SEARCHPROTOCOLHOST%20(METHODOLOGY).ioc +- https://github.com/mandiant/red_team_tool_countermeasures/blob/master/rules/PGF/supplemental/hxioc/SUSPICIOUS%20EXECUTION%20OF%20SEARCHPROTOCOLHOST%20(METHODOLOGY).ioc tags: analytic_story: - Cobalt Strike diff --git a/detections/endpoint/suspicious_wav_file_in_appdata_folder.yml b/detections/endpoint/suspicious_wav_file_in_appdata_folder.yml index 111d718101..ff532958aa 100644 --- a/detections/endpoint/suspicious_wav_file_in_appdata_folder.yml +++ b/detections/endpoint/suspicious_wav_file_in_appdata_folder.yml @@ -27,7 +27,7 @@ how_to_implement: To successfully implement this search, you need to be ingestin version 6.0.4 of the Sysmon TA. known_false_positives: unknown references: -- https://success.trendmicro.com/solution/1123281-remcos-malware-information +- https://success.trendmicro.com/dcx/s/solution/1123281-remcos-malware-information?language=en_US - https://blog.malwarebytes.com/threat-intelligence/2021/07/remcos-rat-delivered-via-visual-basic/ tags: analytic_story: diff --git a/detections/endpoint/system_information_discovery_detection.yml b/detections/endpoint/system_information_discovery_detection.yml index fb110f5366..fe8728e82d 100644 --- a/detections/endpoint/system_information_discovery_detection.yml +++ b/detections/endpoint/system_information_discovery_detection.yml @@ -21,7 +21,7 @@ how_to_implement: To successfully implement this search you need to be ingesting your endpoints into the `Endpoint` datamodel in the `Processes` node. known_false_positives: Administrators debugging servers references: -- https://oscp.infosecsanyam.in/priv-escalation/windows-priv-escalation +- https://web.archive.org/web/20210119205146/https://oscp.infosecsanyam.in/priv-escalation/windows-priv-escalation tags: analytic_story: - Discovery Techniques diff --git a/detections/endpoint/trickbot_named_pipe.yml b/detections/endpoint/trickbot_named_pipe.yml index 547a6d02b8..292aa13b47 100644 --- a/detections/endpoint/trickbot_named_pipe.yml +++ b/detections/endpoint/trickbot_named_pipe.yml @@ -19,7 +19,7 @@ how_to_implement: To successfully implement this search, you need to be ingestin known_false_positives: unknown references: - https://labs.vipre.com/trickbot-and-its-modules/ -- https://blog.whitehat.eu/2019/05/incident-trickbot-ryuk-2.html +- https://whitehat.eu/incident-response-case-study-featuring-ryuk-and-trickbot-part-2/ tags: analytic_story: - Trickbot diff --git a/detections/endpoint/unified_messaging_service_spawning_a_process.yml b/detections/endpoint/unified_messaging_service_spawning_a_process.yml index 9089986a8c..6848554959 100644 --- a/detections/endpoint/unified_messaging_service_spawning_a_process.yml +++ b/detections/endpoint/unified_messaging_service_spawning_a_process.yml @@ -31,7 +31,7 @@ known_false_positives: Unknown. Tune out child processes as needed to limit volu references: - https://www.volexity.com/blog/2021/03/02/active-exploitation-of-microsoft-exchange-zero-day-vulnerabilities/ - https://www.microsoft.com/security/blog/2021/03/02/hafnium-targeting-exchange-servers/ -- https://blog.rapid7.com/2021/03/03/rapid7s-insightidr-enables-detection-and-response-to-microsoft-exchange-0-day/ +- https://www.rapid7.com/blog/post/2021/03/03/rapid7s-insightidr-enables-detection-and-response-to-microsoft-exchange-0-day/ tags: analytic_story: - HAFNIUM Group diff --git a/detections/endpoint/wermgr_process_connecting_to_ip_check_web_services.yml b/detections/endpoint/wermgr_process_connecting_to_ip_check_web_services.yml index e6b0890526..ac61d89c7d 100644 --- a/detections/endpoint/wermgr_process_connecting_to_ip_check_web_services.yml +++ b/detections/endpoint/wermgr_process_connecting_to_ip_check_web_services.yml @@ -27,7 +27,7 @@ how_to_implement: To successfully implement this search, you need to be ingestin known_false_positives: unknown references: - https://labs.vipre.com/trickbot-and-its-modules/ -- https://blog.whitehat.eu/2019/05/incident-trickbot-ryuk-2.html +- https://whitehat.eu/incident-response-case-study-featuring-ryuk-and-trickbot-part-2/ tags: analytic_story: - Trickbot diff --git a/detections/endpoint/wermgr_process_create_executable_file.yml b/detections/endpoint/wermgr_process_create_executable_file.yml index 0a4ae33869..1f6e626961 100644 --- a/detections/endpoint/wermgr_process_create_executable_file.yml +++ b/detections/endpoint/wermgr_process_create_executable_file.yml @@ -23,7 +23,7 @@ how_to_implement: To successfully implement this search, you need to be ingestin known_false_positives: unknown references: - https://labs.vipre.com/trickbot-and-its-modules/ -- https://blog.whitehat.eu/2019/05/incident-trickbot-ryuk-2.html +- https://whitehat.eu/incident-response-case-study-featuring-ryuk-and-trickbot-part-2/ tags: analytic_story: - Trickbot diff --git a/detections/endpoint/wermgr_process_spawned_cmd_or_powershell_process.yml b/detections/endpoint/wermgr_process_spawned_cmd_or_powershell_process.yml index 27e26fb8c8..19baae8d94 100644 --- a/detections/endpoint/wermgr_process_spawned_cmd_or_powershell_process.yml +++ b/detections/endpoint/wermgr_process_spawned_cmd_or_powershell_process.yml @@ -25,7 +25,7 @@ how_to_implement: To successfully implement this search you need to be ingesting known_false_positives: unknown references: - https://labs.vipre.com/trickbot-and-its-modules/ -- https://blog.whitehat.eu/2019/05/incident-trickbot-ryuk-2.html +- https://whitehat.eu/incident-response-case-study-featuring-ryuk-and-trickbot-part-2/ tags: analytic_story: - Trickbot diff --git a/detections/endpoint/windows_adfind_exe.yml b/detections/endpoint/windows_adfind_exe.yml index 1a48f71173..f0faeb2522 100644 --- a/detections/endpoint/windows_adfind_exe.yml +++ b/detections/endpoint/windows_adfind_exe.yml @@ -26,7 +26,7 @@ known_false_positives: administrators rarely use adfind, usually not used for le reasons references: - https://www.volexity.com/blog/2020/12/14/dark-halo-leverages-solarwinds-compromise-to-breach-organizations/ -- https://www.fireeye.com/blog/threat-research/2019/01/a-nasty-trick-from-credential-theft-malware-to-business-disruption.html +- https://www.mandiant.com/resources/a-nasty-trick-from-credential-theft-malware-to-business-disruption tags: analytic_story: - NOBELIUM Group diff --git a/detections/endpoint/windows_disable_windows_group_policy_features_through_registry.yml b/detections/endpoint/windows_disable_windows_group_policy_features_through_registry.yml index 1dcf8918c4..ac3844dbc3 100644 --- a/detections/endpoint/windows_disable_windows_group_policy_features_through_registry.yml +++ b/detections/endpoint/windows_disable_windows_group_policy_features_through_registry.yml @@ -32,7 +32,7 @@ how_to_implement: To successfully implement this search you need to be ingesting known_false_positives: unknown references: - https://hybrid-analysis.com/sample/ef1c427394c205580576d18ba68d5911089c7da0386f19d1ca126929d3e671ab?environmentId=120&lang=en -- https://www.sophos.com/de-de/threat-center/threat-analyses/viruses-and-spyware/Troj~Krotten-N/detailed-analysis +- https://www.sophos.com/en-us/threat-center/threat-analyses/viruses-and-spyware/Troj~Krotten-N/detailed-analysis - https://www.virustotal.com/gui/file/2d7855bf6470aa323edf2949b54ce2a04d9e38770f1322c3d0420c2303178d91/details tags: analytic_story: diff --git a/detections/endpoint/windows_high_file_deletion_frequency.yml b/detections/endpoint/windows_high_file_deletion_frequency.yml index e36112b07b..9aaf0c761e 100644 --- a/detections/endpoint/windows_high_file_deletion_frequency.yml +++ b/detections/endpoint/windows_high_file_deletion_frequency.yml @@ -22,7 +22,7 @@ how_to_implement: To successfully implement this search, you need to be ingestin If you are using Sysmon, you must have at least version 6.0.4 of the Sysmon TA. known_false_positives: user may delete bunch of pictures or files in a folder. references: -- https://www.fireeye.com/blog/threat-research/2020/10/fin11-email-campaigns-precursor-for-ransomware-data-theft.html +- https://www.mandiant.com/resources/fin11-email-campaigns-precursor-for-ransomware-data-theft - https://blog.virustotal.com/2020/11/keep-your-friends-close-keep-ransomware.html - https://www.microsoft.com/security/blog/2022/01/15/destructive-malware-targeting-ukrainian-organizations/ tags: diff --git a/detections/endpoint/windows_powerview_constrained_delegation_discovery.yml b/detections/endpoint/windows_powerview_constrained_delegation_discovery.yml index d32ac79dcd..6e52ede05b 100644 --- a/detections/endpoint/windows_powerview_constrained_delegation_discovery.yml +++ b/detections/endpoint/windows_powerview_constrained_delegation_discovery.yml @@ -21,7 +21,7 @@ references: - https://adsecurity.org/?p=1667 - https://docs.microsoft.com/en-us/defender-for-identity/cas-isp-unconstrained-kerberos - https://www.guidepointsecurity.com/blog/delegating-like-a-boss-abusing-kerberos-delegation-in-active-directory/ -- https://book.hacktricks.xyz/windows/active-directory-methodology/constrained-delegation +- https://book.hacktricks.xyz/windows-hardening/active-directory-methodology/constrained-delegation - https://www.cyberark.com/resources/threat-research-blog/weakness-within-kerberos-delegation tags: analytic_story: diff --git a/detections/endpoint/windows_rasautou_dll_execution.yml b/detections/endpoint/windows_rasautou_dll_execution.yml index a0dde062a7..55f9249c45 100644 --- a/detections/endpoint/windows_rasautou_dll_execution.yml +++ b/detections/endpoint/windows_rasautou_dll_execution.yml @@ -27,7 +27,7 @@ references: - https://github.com/mandiant/DueDLLigence - https://github.com/MHaggis/notes/blob/master/utilities/Invoke-SPLDLLigence.ps1 - https://gist.github.com/NickTyrer/c6043e4b302d5424f701f15baf136513 -- https://www.fireeye.com/blog/threat-research/2019/10/staying-hidden-on-the-endpoint-evading-detection-with-shellcode.html +- https://www.mandiant.com/resources/staying-hidden-on-the-endpoint-evading-detection-with-shellcode tags: analytic_story: - Windows Defense Evasion Tactics diff --git a/detections/endpoint/windows_service_created_with_suspicious_service_path.yml b/detections/endpoint/windows_service_created_with_suspicious_service_path.yml index 6303ab57ba..5be65564e7 100644 --- a/detections/endpoint/windows_service_created_with_suspicious_service_path.yml +++ b/detections/endpoint/windows_service_created_with_suspicious_service_path.yml @@ -22,7 +22,7 @@ how_to_implement: To successfully implement this search, you need to be ingestin known_false_positives: Legitimate applications may install services with uncommon services paths. references: -- https://www.fireeye.com/blog/threat-research/2020/10/fin11-email-campaigns-precursor-for-ransomware-data-theft.html +- https://www.mandiant.com/resources/fin11-email-campaigns-precursor-for-ransomware-data-theft - https://blog.virustotal.com/2020/11/keep-your-friends-close-keep-ransomware.html tags: analytic_story: diff --git a/detections/endpoint/wmi_permanent_event_subscription___sysmon.yml b/detections/endpoint/wmi_permanent_event_subscription___sysmon.yml index ce9c28550f..a218df1b1b 100644 --- a/detections/endpoint/wmi_permanent_event_subscription___sysmon.yml +++ b/detections/endpoint/wmi_permanent_event_subscription___sysmon.yml @@ -37,8 +37,8 @@ known_false_positives: Although unlikely, administrators may use event subscript references: - https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1546.003/T1546.003.md - https://www.eideon.com/2018-03-02-THL03-WMIBackdoors/ -- https://github.com/trustedsec/SysmonCommunityGuide/blob/master/WMI-events.md -- https://in.security/an-intro-into-abusing-and-identifying-wmi-event-subscriptions-for-persistence/ +- https://github.com/trustedsec/SysmonCommunityGuide/blob/master/chapters/WMI-events.md +- https://in.security/2019/04/03/an-intro-into-abusing-and-identifying-wmi-event-subscriptions-for-persistence/ tags: analytic_story: - Suspicious WMI Use diff --git a/detections/endpoint/wmi_recon_running_process_or_services.yml b/detections/endpoint/wmi_recon_running_process_or_services.yml index bd73f3bf21..269b959417 100644 --- a/detections/endpoint/wmi_recon_running_process_or_services.yml +++ b/detections/endpoint/wmi_recon_running_process_or_services.yml @@ -22,8 +22,8 @@ known_false_positives: network administrator may used this command for checking references: - https://news.sophos.com/en-us/2020/05/12/maze-ransomware-1-year-counting/ - https://www.eideon.com/2018-03-02-THL03-WMIBackdoors/ -- https://github.com/trustedsec/SysmonCommunityGuide/blob/master/WMI-events.md -- https://in.security/an-intro-into-abusing-and-identifying-wmi-event-subscriptions-for-persistence/ +- https://github.com/trustedsec/SysmonCommunityGuide/blob/master/chapters/WMI-events.md +- https://in.security/2019/04/03/an-intro-into-abusing-and-identifying-wmi-event-subscriptions-for-persistence/ tags: analytic_story: - Hermetic Wiper diff --git a/detections/endpoint/xsl_script_execution_with_wmic.yml b/detections/endpoint/xsl_script_execution_with_wmic.yml index 2d6353c745..b1e1d43adf 100644 --- a/detections/endpoint/xsl_script_execution_with_wmic.yml +++ b/detections/endpoint/xsl_script_execution_with_wmic.yml @@ -23,7 +23,7 @@ how_to_implement: To successfully implement this search, you need to be ingestin Sysmon TA. known_false_positives: unknown references: -- https://www.fireeye.com/blog/threat-research/2018/08/fin7-pursuing-an-enigmatic-and-evasive-global-criminal-operation.html +- https://www.mandiant.com/resources/fin7-pursuing-an-enigmatic-and-evasive-global-criminal-operation - https://attack.mitre.org/groups/G0046/ - https://web.archive.org/web/20190814201250/https://subt0x11.blogspot.com/2018/04/wmicexe-whitelisting-bypass-hacking.html - https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1220/T1220.md#atomic-test-3---wmic-bypass-using-local-xsl-file diff --git a/detections/experimental/cloud/gsuite_suspicious_calendar_invite.yml b/detections/experimental/cloud/gsuite_suspicious_calendar_invite.yml index e7d37480b9..5ed8af2f8c 100644 --- a/detections/experimental/cloud/gsuite_suspicious_calendar_invite.yml +++ b/detections/experimental/cloud/gsuite_suspicious_calendar_invite.yml @@ -24,7 +24,7 @@ known_false_positives: This search will also produce normal activity statistics. use email parameter. references: - https://www.techrepublic.com/article/how-to-avoid-the-dreaded-google-calendar-malicious-invite-issue/ -- https://gcn.com/articles/2012/09/26/20-most-common-words-phishing-attacks.aspx +- https://gcn.com/cybersecurity/2012/09/the-20-most-common-words-in-phishing-attacks/280956/ tags: analytic_story: - Spearphishing Attachments diff --git a/detections/experimental/endpoint/ssa___high_file_deletion_frequency.yml b/detections/experimental/endpoint/ssa___high_file_deletion_frequency.yml index b34dd03ff3..4e432359a4 100644 --- a/detections/experimental/endpoint/ssa___high_file_deletion_frequency.yml +++ b/detections/experimental/endpoint/ssa___high_file_deletion_frequency.yml @@ -29,7 +29,7 @@ how_to_implement: To successfully implement this search you need to be ingesting your endpoints into the `Endpoint` datamodel in the `Filesytem` node. known_false_positives: user may delete bunch of pictures or files in a folder. references: -- https://www.fireeye.com/blog/threat-research/2020/10/fin11-email-campaigns-precursor-for-ransomware-data-theft.html +- https://www.mandiant.com/resources/fin11-email-campaigns-precursor-for-ransomware-data-theft - https://blog.virustotal.com/2020/11/keep-your-friends-close-keep-ransomware.html tags: analytic_story: diff --git a/detections/experimental/endpoint/sunburst_correlation_dll_and_network_event.yml b/detections/experimental/endpoint/sunburst_correlation_dll_and_network_event.yml index f040044a13..2fd0388a69 100644 --- a/detections/experimental/endpoint/sunburst_correlation_dll_and_network_event.yml +++ b/detections/experimental/endpoint/sunburst_correlation_dll_and_network_event.yml @@ -20,7 +20,7 @@ how_to_implement: This detection relies on sysmon logs with the Event ID 7, Driv We suggest to run this detection at least once a day over the last 14 days. known_false_positives: unknown references: -- https://www.fireeye.com/blog/threat-research/2020/12/evasive-attacker-leverages-solarwinds-supply-chain-compromises-with-sunburst-backdoor.html +- https://www.mandiant.com/resources/evasive-attacker-leverages-solarwinds-supply-chain-compromises-with-sunburst-backdoor tags: analytic_story: - NOBELIUM Group diff --git a/detections/experimental/endpoint/suspicious_curl_network_connection.yml b/detections/experimental/endpoint/suspicious_curl_network_connection.yml index e6c08c0328..7c203d23b2 100644 --- a/detections/experimental/endpoint/suspicious_curl_network_connection.yml +++ b/detections/experimental/endpoint/suspicious_curl_network_connection.yml @@ -22,7 +22,7 @@ how_to_implement: To successfully implement this search you need to be ingesting known_false_positives: Unknown. Filter as needed. references: - https://redcanary.com/blog/clipping-silver-sparrows-wings/ -- https://marcosantadev.com/manage-plist-files-plistbuddy/ +- https://www.marcosantadev.com/manage-plist-files-plistbuddy/ tags: analytic_story: - Silver Sparrow diff --git a/detections/experimental/endpoint/suspicious_plistbuddy_usage.yml b/detections/experimental/endpoint/suspicious_plistbuddy_usage.yml index 561a1ffe12..24b026e856 100644 --- a/detections/experimental/endpoint/suspicious_plistbuddy_usage.yml +++ b/detections/experimental/endpoint/suspicious_plistbuddy_usage.yml @@ -43,7 +43,7 @@ known_false_positives: Some legitimate applications may use PlistBuddy to create modify property lists and possibly generate false positives. Review the property list being modified or created to confirm. references: -- https://marcosantadev.com/manage-plist-files-plistbuddy/ +- https://www.marcosantadev.com/manage-plist-files-plistbuddy/ tags: analytic_story: - Silver Sparrow diff --git a/detections/experimental/endpoint/suspicious_plistbuddy_usage_via_osquery.yml b/detections/experimental/endpoint/suspicious_plistbuddy_usage_via_osquery.yml index 4a0f6a3dee..df66383b81 100644 --- a/detections/experimental/endpoint/suspicious_plistbuddy_usage_via_osquery.yml +++ b/detections/experimental/endpoint/suspicious_plistbuddy_usage_via_osquery.yml @@ -38,7 +38,7 @@ known_false_positives: Some legitimate applications may use PlistBuddy to create modify property lists and possibly generate false positives. Review the property list being modified or created to confirm. references: -- https://marcosantadev.com/manage-plist-files-plistbuddy/ +- https://www.marcosantadev.com/manage-plist-files-plistbuddy/ tags: analytic_story: - Silver Sparrow diff --git a/detections/experimental/endpoint/suspicious_sqlite3_lsquarantine_behavior.yml b/detections/experimental/endpoint/suspicious_sqlite3_lsquarantine_behavior.yml index 36e24b86b2..95230c6f41 100644 --- a/detections/experimental/endpoint/suspicious_sqlite3_lsquarantine_behavior.yml +++ b/detections/experimental/endpoint/suspicious_sqlite3_lsquarantine_behavior.yml @@ -22,7 +22,7 @@ how_to_implement: To successfully implement this search you need to be ingesting known_false_positives: Unknown. references: - https://redcanary.com/blog/clipping-silver-sparrows-wings/ -- https://marcosantadev.com/manage-plist-files-plistbuddy/ +- https://www.marcosantadev.com/manage-plist-files-plistbuddy/ tags: analytic_story: - Silver Sparrow diff --git a/detections/experimental/endpoint/winrm_spawning_a_process.yml b/detections/experimental/endpoint/winrm_spawning_a_process.yml index 69f91b9d8a..520c21f52d 100644 --- a/detections/experimental/endpoint/winrm_spawning_a_process.yml +++ b/detections/experimental/endpoint/winrm_spawning_a_process.yml @@ -24,7 +24,7 @@ how_to_implement: To successfully implement this search you need to be ingesting known_false_positives: Unknown. Add new processes or filter as needed. It is possible system management software may spawn processes from `wsmprovhost.exe`. references: -- https://github.com/SigmaHQ/sigma/blob/master/rules/windows/process_access/win_susp_shell_spawn_from_winrm.yml +- https://github.com/SigmaHQ/sigma/blob/9b7fb0c0f3af2e53ed483e29e0d0f88ccf1c08ca/rules/windows/process_access/win_susp_shell_spawn_from_winrm.yml - https://www.zerodayinitiative.com/blog/2021/5/17/cve-2021-31166-a-wormable-code-execution-bug-in-httpsys - https://github.com/0vercl0k/CVE-2021-31166/blob/main/cve-2021-31166.py tags: diff --git a/detections/experimental/network/detect_snicat_sni_exfiltration.yml b/detections/experimental/network/detect_snicat_sni_exfiltration.yml index dad4a82700..6843d4d652 100644 --- a/detections/experimental/network/detect_snicat_sni_exfiltration.yml +++ b/detections/experimental/network/detect_snicat_sni_exfiltration.yml @@ -18,7 +18,7 @@ how_to_implement: You must be ingesting Zeek SSL data into Splunk. Zeek data sho or disprove if any data exfiltration has taken place. known_false_positives: Unknown references: -- https://www.mnemonic.no/blog/introducing-snicat/ +- https://www.mnemonic.io/resources/blog/introducing-snicat/ - https://github.com/mnemonic-no/SNIcat - https://attack.mitre.org/techniques/T1041/ tags: diff --git a/detections/experimental/network/detect_zerologon_via_zeek.yml b/detections/experimental/network/detect_zerologon_via_zeek.yml index 8523d2505f..add1fbb7aa 100644 --- a/detections/experimental/network/detect_zerologon_via_zeek.yml +++ b/detections/experimental/network/detect_zerologon_via_zeek.yml @@ -20,7 +20,7 @@ known_false_positives: unknown references: - https://www.secura.com/blog/zero-logon - https://github.com/SecuraBV/CVE-2020-1472 -- https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2020-1472 +- https://msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2020-1472 tags: analytic_story: - Detect Zerologon Attack diff --git a/detections/experimental/web/supernova_webshell.yml b/detections/experimental/web/supernova_webshell.yml index 0c59ce3170..272047d798 100644 --- a/detections/experimental/web/supernova_webshell.yml +++ b/detections/experimental/web/supernova_webshell.yml @@ -20,7 +20,7 @@ known_false_positives: There might be false positives associted with this detect since items like args as a web argument is pretty generic. references: - https://www.splunk.com/en_us/blog/security/detecting-supernova-malware-solarwinds-continued.html -- https://www.guidepointsecurity.com/supernova-solarwinds-net-webshell-analysis/ +- https://www.guidepointsecurity.com/blog/supernova-solarwinds-net-webshell-analysis/ tags: analytic_story: - NOBELIUM Group diff --git a/detections/network/multiple_archive_files_http_post_traffic.yml b/detections/network/multiple_archive_files_http_post_traffic.yml index 3c52e5ca0b..2406e5f37e 100644 --- a/detections/network/multiple_archive_files_http_post_traffic.yml +++ b/detections/network/multiple_archive_files_http_post_traffic.yml @@ -29,7 +29,7 @@ how_to_implement: To successfully implement this search, you need to be ingestin known_false_positives: Normal archive transfer via HTTP protocol may trip this detection. references: - https://attack.mitre.org/techniques/T1560/001/ -- https://www.fireeye.com/blog/threat-research/2019/01/apt39-iranian-cyber-espionage-group-focused-on-personal-information.html +- https://www.mandiant.com/resources/apt39-iranian-cyber-espionage-group-focused-on-personal-information - https://www.microsoft.com/security/blog/2021/01/20/deep-dive-into-the-solorigate-second-stage-activation-from-sunburst-to-teardrop-and-raindrop/ tags: analytic_story: diff --git a/detections/web/vmware_server_side_template_injection_hunt.yml b/detections/web/vmware_server_side_template_injection_hunt.yml index 535d254d2c..62edaaec13 100644 --- a/detections/web/vmware_server_side_template_injection_hunt.yml +++ b/detections/web/vmware_server_side_template_injection_hunt.yml @@ -20,7 +20,7 @@ how_to_implement: To successfully implement this search, you need to be ingestin by known good. known_false_positives: False positives may be present if the activity is blocked or was not successful. Filter known vulnerablity scanners. Filter as needed. references: - - https://www.cisa.gov/uscert/sites/default/files/publications/CISA_CSA_Threat_Actors_Chaining_VMware_Unpatched_Vulnerabilities_for_Full_System_Control.pdf + - https://www.cisa.gov/uscert/ncas/alerts/aa22-138b - https://github.com/wvu/metasploit-framework/blob/master/modules/exploits/linux/http/vmware_workspace_one_access_cve_2022_22954.rb - https://github.com/sherlocksecurity/VMware-CVE-2022-22954 - https://www.vmware.com/security/advisories/VMSA-2022-0011.html diff --git a/detections/web/vmware_workspace_one_freemarker_server_side_template_injection.yml b/detections/web/vmware_workspace_one_freemarker_server_side_template_injection.yml index 3162fafb0d..b13bdb98c7 100644 --- a/detections/web/vmware_workspace_one_freemarker_server_side_template_injection.yml +++ b/detections/web/vmware_workspace_one_freemarker_server_side_template_injection.yml @@ -21,7 +21,7 @@ how_to_implement: To successfully implement this search, you need to be ingestin by known good. known_false_positives: False positives may be present if the activity is blocked or was not successful. Filter known vulnerablity scanners. Filter as needed. references: - - https://www.cisa.gov/uscert/sites/default/files/publications/CISA_CSA_Threat_Actors_Chaining_VMware_Unpatched_Vulnerabilities_for_Full_System_Control.pdf + - https://www.cisa.gov/uscert/ncas/alerts/aa22-138b - https://github.com/wvu/metasploit-framework/blob/master/modules/exploits/linux/http/vmware_workspace_one_access_cve_2022_22954.rb - https://github.com/sherlocksecurity/VMware-CVE-2022-22954 - https://www.vmware.com/security/advisories/VMSA-2022-0011.html diff --git a/stories/hidden_cobra_malware.yml b/stories/hidden_cobra_malware.yml index 0c62805bc0..ee5087e413 100644 --- a/stories/hidden_cobra_malware.yml +++ b/stories/hidden_cobra_malware.yml @@ -35,7 +35,7 @@ narrative: 'North Korea''s government-sponsored "cyber army" has been slowly bui files associated with the malware. You can also use a search in this story to investigate activity that indicates that malware is sending email back to the attackers.' references: -- https://www.us-cert.gov/HIDDEN-COBRA-North-Korean-Malicious-Cyber-Activity +- https://web.archive.org/web/20191220004307/https://www.us-cert.gov/HIDDEN-COBRA-North-Korean-Malicious-Cyber-Activity - https://www.operationblockbuster.com/wp-content/uploads/2016/02/Operation-Blockbuster-Destructive-Malware-Report.pdf tags: analytic_story: Hidden Cobra Malware diff --git a/stories/netsh_abuse.yml b/stories/netsh_abuse.yml index 83a715d79a..f6bea10719 100644 --- a/stories/netsh_abuse.yml +++ b/stories/netsh_abuse.yml @@ -18,7 +18,7 @@ narrative: 'It is a common practice for attackers of all types to leverage nativ references: - https://docs.microsoft.com/en-us/previous-versions/tn-archive/bb490939(v=technet.10) - https://htmlpreview.github.io/?https://github.com/MatthewDemaske/blogbackup/blob/master/netshell.html -- http://blog.jpcert.or.jp/2016/01/windows-commands-abused-by-attackers.html +- https://blogs.jpcert.or.jp/en/2016/01/windows-commands-abused-by-attackers.html tags: analytic_story: Netsh Abuse category: diff --git a/stories/ransomware.yml b/stories/ransomware.yml index 1835219ce4..f7e4597f27 100644 --- a/stories/ransomware.yml +++ b/stories/ransomware.yml @@ -17,7 +17,7 @@ narrative: Ransomware is an ever-present risk to the enterprise, wherein an infe apply several techniques--such as those in this Analytic Story--to detect and or mitigate the effects of ransomware. references: -- https://www.carbonblack.com/2017/06/28/carbon-black-threat-research-technical-analysis-petya-notpetya-ransomware/ +- https://web.archive.org/web/20190826231258/https://www.carbonblack.com/2017/06/28/carbon-black-threat-research-technical-analysis-petya-notpetya-ransomware/ - https://www.splunk.com/blog/2017/06/27/closing-the-detection-to-mitigation-gap-or-to-petya-or-notpetya-whocares-.html tags: analytic_story: Ransomware diff --git a/stories/router_and_infrastructure_security.yml b/stories/router_and_infrastructure_security.yml index 1d6f3a161c..9c8a14a05f 100644 --- a/stories/router_and_infrastructure_security.yml +++ b/stories/router_and_infrastructure_security.yml @@ -17,7 +17,7 @@ narrative: 'Networking devices, such as routers and switches, are often overlook can obtain direct access to the company''s internal infrastructure— effectively increasing the attack surface and accessing private services/data.' references: -- https://www.fireeye.com/blog/executive-perspective/2015/09/the_new_route_toper.html +- https://web.archive.org/web/20210420020040/https://www.fireeye.com/blog/executive-perspective/2015/09/the_new_route_toper.html - https://www.cisco.com/c/en/us/about/security-center/event-response/synful-knock.html tags: analytic_story: Router and Infrastructure Security diff --git a/stories/suspicious_gcp_storage_activities.yml b/stories/suspicious_gcp_storage_activities.yml index 3964d460bb..125b4d2f7a 100644 --- a/stories/suspicious_gcp_storage_activities.yml +++ b/stories/suspicious_gcp_storage_activities.yml @@ -13,7 +13,7 @@ narrative: Similar to other cloud providers, GCP operates on a shared responsibi on detecting things like open storage buckets (both read and write) along with storage bucket access from unfamiliar users and IP addresses. references: -- https://cloud.google.com/blog/product/gcp/4-steps-for-hardening-your-cloud-storage-buckets-taking-charge-of-your-security +- https://cloud.google.com/blog/products/gcp/4-steps-for-hardening-your-cloud-storage-buckets-taking-charge-of-your-security - https://rhinosecuritylabs.com/gcp/google-cloud-platform-gcp-bucket-enumeration/ tags: analytic_story: Suspicious GCP Storage Activities diff --git a/stories/suspicious_wmi_use.yml b/stories/suspicious_wmi_use.yml index a54992248c..c8c5c7b3a5 100644 --- a/stories/suspicious_wmi_use.yml +++ b/stories/suspicious_wmi_use.yml @@ -21,7 +21,7 @@ narrative: WMI is a Microsoft infrastructure for management data and operations These details may provide insights related to how WMI was used and to what end. references: - https://www.blackhat.com/docs/us-15/materials/us-15-Graeber-Abusing-Windows-Management-Instrumentation-WMI-To-Build-A-Persistent%20Asynchronous-And-Fileless-Backdoor-wp.pdf -- https://www.fireeye.com/blog/threat-research/2017/03/wmimplant_a_wmi_ba.html +- https://web.archive.org/web/20210921091529/https://www.fireeye.com/blog/threat-research/2017/03/wmimplant_a_wmi_ba.html tags: analytic_story: Suspicious WMI Use category: diff --git a/stories/unusual_processes.yml b/stories/unusual_processes.yml index d25056b6d0..063a71c912 100644 --- a/stories/unusual_processes.yml +++ b/stories/unusual_processes.yml @@ -21,7 +21,7 @@ narrative: 'Being able to profile a host''s processes within your environment ca other hosts are affected. This extra information may provide clues that can help the analyst further investigate any suspicious activity.' references: -- https://www.fireeye.com/blog/threat-research/2017/08/monitoring-windows-console-activity-part-two.html +- https://web.archive.org/web/20210921093439/https://www.fireeye.com/blog/threat-research/2017/08/monitoring-windows-console-activity-part-two.html - https://www.splunk.com/pdfs/technical-briefs/advanced-threat-detection-and-response-tech-brief.pdf - https://www.sans.org/reading-room/whitepapers/logging/detecting-security-incidents-windows-workstation-event-logs-34262 tags: diff --git a/stories/vmware_server_side_injection_and_privilege_escalation.yml b/stories/vmware_server_side_injection_and_privilege_escalation.yml index b3b23f8355..da5ea81156 100644 --- a/stories/vmware_server_side_injection_and_privilege_escalation.yml +++ b/stories/vmware_server_side_injection_and_privilege_escalation.yml @@ -9,7 +9,7 @@ narrative: 'On April 6, 2022, VMware published VMSA-2022-0011, which discloses m To further exacerbate this issue, VMware also disclosed a local privilege escalation issue, CVE-2022-22960, which permits the attacker to gain root after exploiting CVE-2022-22954. Products affected include - VMware Workspace ONE Access (Access) 20.10.0.0 - 20.10.0.1, 21.08.0.0 - 21.08.0.1 and VMware Identity Manager (vIDM) 3.3.3 - 3.3.6.' references: - https://attackerkb.com/topics/BDXyTqY1ld/cve-2022-22954/rapid7-analysis - - https://www.cisa.gov/uscert/sites/default/files/publications/CISA_CSA_Threat_Actors_Chaining_VMware_Unpatched_Vulnerabilities_for_Full_System_Control.pdf + - https://www.cisa.gov/uscert/ncas/alerts/aa22-138b tags: analytic_story: VMware Server Side Injection and Privilege Escalation category: