Merge branch 'develop' of github.com:splunk/security-content into tf23

This commit is contained in:
Xiao Lin
2021-11-09 20:22:12 -08:00
1090 changed files with 883651 additions and 662235 deletions
+96 -92
View File
@@ -23,7 +23,7 @@ jobs:
steps:
- name: TAGGED, Validate that the tag is in the correct format
run: |
echo "The GITHUB_REF: $GITHUB_REF"
#First check to see if the release is a tag
@@ -32,7 +32,7 @@ jobs:
#is in the correct format (like v1.10.20)
if [[ $GITHUB_REF =~ refs/tags/v[0-9]+.[0-9]+.[0-9]+ ]]; then
echo "PASS: Tagged release with good format"
exit 0
exit 0
else
echo "FAIL: Tagged release with bad format"
exit 1
@@ -49,14 +49,14 @@ jobs:
runs-on: ubuntu-latest
needs: [validate-tag-if-present]
steps:
#Previous config chose which branch/tag to operate on.
#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
- name: Check out the repository code
uses: actions/checkout@v2
#with:
# repository: splunk/security-content #check out https://github.com/mitre/cti.git, defaults to HEAD
# path: "security-content"
- uses: actions/setup-python@v2
with:
@@ -66,14 +66,14 @@ jobs:
#TODO: CircleCI restore_cache equivalent
#don't need to install python3 or python3-dev since it was handled by the action above?
#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: |
run: |
sudo apt update -qq
sudo apt install jq -qq
#TODO: CircleCI save_cache equivalent
sudo apt install jq -qq
#TODO: CircleCI save_cache equivalent
- name: Install Python Dependencies
run: |
#Get the virtualenv set up
@@ -83,19 +83,19 @@ jobs:
python3 -m pip install --upgrade pip
python3 -m pip install wheel
python3 -m pip install -q -r requirements.txt
- name: run validate
run: |
- name: run validate
run: |
source venv/bin/activate
python3 contentctl.py --path . --verbose validate
- name: Get CTI Repo for Mitre context
uses: actions/checkout@v2
- 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/"
#Now generate the documentation (uses Node)
- uses: actions/setup-node@v2
@@ -108,18 +108,18 @@ jobs:
#Enter the virtualenv and run the docgen
source venv/bin/activate
python3 bin/doc_gen.py --path . --output docs -v
#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
@@ -128,10 +128,10 @@ jobs:
uses: actions/checkout@v2
- name: Install System Packages
run: |
run: |
sudo apt update -qq
sudo apt install jq -qq
sudo apt install jq -qq
- name: Install Python Dependencies
run: |
#Get the virtualenv set up
@@ -143,18 +143,15 @@ jobs:
python3 -m pip install -q -r requirements.txt
- name: Run Generate
run: |
run: |
source venv/bin/activate
python3 contentctl.py --path . --verbose generate --product ESCU --output dist/escu
python3 contentctl.py --path . --verbose generate --product SAAWS --output dist/saaws
python3 contentctl.py --path . --verbose generate --product DevSecOps --output dist/devsecops
# make a copy of use_case_lib in order to have ES work :-(
# cp dist/escu/default/use_case_library.conf dist/escu/default/analyticstories.conf
# cp dist/saaws/default/use_case_library.conf dist/saaws/default/analyticstories.conf
# cp dist/devsecops/default/use_case_library.conf dist/devsecops/default/analyticstories.conf
python3 contentctl.py --path . --verbose generate --product SSA --output dist/ssa
- name: Copy lookups .csv files
run: |
run: |
# clean up current lookups
rm -rf dist/escu/lookups
rm -rf dist/saaws/lookups
@@ -167,7 +164,7 @@ jobs:
cp -rv *.csv ../dist/escu/lookups
cp -rv *.csv ../dist/saaws/lookups
cp -rv *.csv ../dist/devsecops/lookups
#Tag is '' for non-tagged push and the tag name for a tagged release
- name: Set tag
id: vars
@@ -198,7 +195,7 @@ jobs:
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/*
# update build number and version for saaws
sed -i "s/build = .*$/build = ${{ github.run_number }}/g" dist/saaws/default/app.conf
sed -i "s/^version = .*$/version = $CONTENT_VERSION/g" dist/saaws/default/app.conf
@@ -209,6 +206,9 @@ jobs:
# update build number and version for devsecops
tar -czf content-pack-build-devsecops.tar.gz dist/devsecops/*
# 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:
@@ -217,12 +217,13 @@ jobs:
content-pack-build-escu.tar.gz
content-pack-build-saaws.tar.gz
content-pack-build-devsecops.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:
@@ -234,12 +235,12 @@ jobs:
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
sudo apt install virtualenv
- name: Grab Splunk Packaging Toolkit
- name: Grab 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
mkdir slim-latest
@@ -264,6 +265,7 @@ jobs:
mv dist/escu DA-ESS-ContentUpdate
mv dist/saaws DA-ESS_AmazonWebServices_Content
mv dist/devsecops dev_sec_ops_analytics
slim package -o upload DA-ESS-ContentUpdate
slim package -o upload DA-ESS_AmazonWebServices_Content
slim package -o upload dev_sec_ops_analytics
@@ -276,6 +278,9 @@ jobs:
cp upload/dev_sec_ops_analytics-*tar.gz dev_sec_ops_analytics-latest.tar.gz
cp content-pack-build-ssa.tar.gz upload/SSA_Content-latest.tar.gz
sha256sum upload/SSA_Content-latest.tar.gz >> checksum.txt
touch tag-canary.txt
- name: store_artifacts
@@ -292,8 +297,9 @@ jobs:
build/DA-ESS-ContentUpdate-latest.tar.gz
build/DA-ESS_AmazonWebServices_Content-latest.tar.gz
build/dev_sec_ops_analytics-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
@@ -301,7 +307,7 @@ jobs:
runs-on: ubuntu-latest
needs: [validate-content, build-sources, build-package]
#Only run when tagged
if: startsWith(github.ref, 'refs/tags/')
if: startsWith(github.ref, 'refs/tags/')
steps:
- name: Checkout Repo
@@ -319,10 +325,10 @@ jobs:
- name: Install System Packages
run: |
run: |
sudo apt update -qq
sudo apt install jq -qq
- name: Submit ESCU Package to AppInspect API
@@ -333,8 +339,8 @@ jobs:
cd bin
#Enclose in quotes in case there are any special characters in the username/password
#Better not to pass these arguments on the command line, if possible
./appinspect.sh ../ DA-ESS-ContentUpdate-latest.tar.gz "$APPINSPECT_USERNAME" "$APPINSPECT_PASSWORD"
./appinspect.sh ../ DA-ESS-ContentUpdate-latest.tar.gz "$APPINSPECT_USERNAME" "$APPINSPECT_PASSWORD"
- name: Submit SAAWS Package to AppInspect API
env:
APPINSPECT_USERNAME: ${{ secrets.AppInspectUsername }}
@@ -342,20 +348,20 @@ jobs:
run: |
cd bin
./appinspect.sh ../ DA-ESS_AmazonWebServices_Content-latest.tar.gz "$APPINSPECT_USERNAME" "$APPINSPECT_PASSWORD"
- name: Create report artifact
if: always()
run: |
#Always create this, regardless of whether success or failure above
tar -cvzf report.tar.gz report/
- name: store_artifacts
- name: store_artifacts
uses: actions/upload-artifact@v2
with:
name: appinspect_reports
path: |
report.tar.gz
#Still store the report, even if we have failed (otherwise we don't know why/how we failed)
- name: store_artifacts_on_failure
uses: actions/upload-artifact@v2
@@ -364,7 +370,7 @@ jobs:
name: appinspect_reports_failure
path: |
report.tar.gz
create-report:
runs-on: ubuntu-latest
needs: [validate-content, build-sources, build-package, run-appinspect]
@@ -375,13 +381,13 @@ jobs:
uses: actions/checkout@v2
with:
ref: 'develop'
- name: Install System Packages
run: |
run: |
sudo apt update -qq
sudo apt install jq -qq
- 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
@@ -396,12 +402,12 @@ jobs:
python3 -m pip install --upgrade pip
python3 -m pip install wheel
python3 -m pip install -q -r requirements.txt
- name: run reporting
run: |
run: |
source venv/bin/activate
python3 bin/reporting.py
#Official, Verified Amazon-AWS Github Account Provided Action
- uses: aws-actions/configure-aws-credentials@v1
with:
@@ -410,23 +416,23 @@ jobs:
# aws-session-token: ${{ secrets.AWS_SESSION_TOKEN }} # if you have/need it
aws-region: us-west-1 #assume we will always use this, could make this an environment variable...
- name: Upload Reporting
- name: Upload Reporting
run: |
aws s3 cp bin/reporting s3://security-content/reporting --recursive --exclude "*" --include "*.svg"
update-sources-github:
runs-on: ubuntu-latest
needs: [validate-content, build-sources, build-package, run-appinspect, create-report]
#Only run when tagged
if: startsWith(github.ref, 'refs/tags/')
steps:
steps:
- name: Checkout Repo
uses: actions/checkout@v2
with:
token: ${{ secrets.PROTECTED_BRANCH_PUSH_TOKEN }}
ref: 'develop'
- 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
@@ -443,6 +449,8 @@ jobs:
tar -zxf DA-ESS-ContentUpdate-latest.tar.gz -C latest-escu --strip-components=1
mkdir latest-saaws
tar -zxf DA-ESS_AmazonWebServices_Content-latest.tar.gz -C latest-saaws --strip-components=1
mkdir latest-ssa
tar -zxf SSA_Content-latest.tar.gz -C latest-ssa --strip-components=1
- name: Install Python Dependencies
run: |
#Get the virtualenv set up
@@ -452,9 +460,9 @@ jobs:
python3 -m pip install --upgrade pip
python3 -m pip install wheel
python3 -m pip install -q -r requirements.txt
- name: Get CTI Repo for Mitre context
uses: actions/checkout@v2
- 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/"
@@ -463,33 +471,30 @@ jobs:
id: vars
run: |
echo "::set-output name=branch::${GITHUB_REF#refs/heads/}"
- name: Run doc-gen
run: |
source venv/bin/activate
python3 bin/doc_gen.py --path . --output docs -v
- name: Make YAMLs Pretty
- name: Run doc-gen
run: |
source venv/bin/activate
python3 bin/pretty_yaml.py --path . -v
python3 bin/doc_gen.py --path . --output docs -v
- name: Make YAMLs Pretty
run: |
source venv/bin/activate
python3 bin/pretty_yaml.py --path . -v
- name: Run generate-coverage-map
run: |
source venv/bin/activate
python3 bin/generate-coverage-map.py --projects_path . --output docs/mitre-map
- name: Update github with new docs and package bits
run: |
rm -rf dist
mkdir dist
echo "Directory layout 3"
pwd
ls -lah
mv latest-escu dist/escu
mv latest-saaws dist/saaws
mv latest-ssa dist/ssa
# configure git to prep for commit
#git config credential.helper 'cache --timeout=120'
git config user.email "research@splunk.com"
git config user.name "research bot"
git config --global push.default simple
@@ -500,7 +505,7 @@ jobs:
# Push quietly to prevent showing the token in log
#No need to provide any credentials
git push
publish-github-release:
#Github-maintained release action is in archived state: https://github.com/actions/create-release
@@ -510,7 +515,7 @@ jobs:
#Only run when tagged
if: startsWith(github.ref, 'refs/tags/')
steps:
#Get the artifacts that we need
- uses: actions/download-artifact@v2
with:
@@ -520,23 +525,24 @@ jobs:
with:
name: appinspect_reports
#Rename those artifacts appropriately
- name: Set tag
id: vars
run: echo "::set-output name=tag::${GITHUB_REF#refs/*/}"
- name: Rename the content-update appropriately
- name: Rename the content-update appropriately
run: |
cp DA-ESS-ContentUpdate-latest.tar.gz DA-ESS-ContentUpdate-${{ steps.vars.outputs.tag }}.tar.gz
cp DA-ESS_AmazonWebServices_Content-latest.tar.gz DA-ESS_AmazonWebServices_Content-${{ steps.vars.outputs.tag }}.tar.gz
cp SSA_Content-latest.tar.gz SSA_Content-${{ steps.vars.outputs.tag }}.tar.gz
#No checksum on the reports
cp report.tar.gz report-${{ steps.vars.outputs.tag }}.tar.gz
cp checksum.txt checksum-${{ steps.vars.outputs.tag }}.txt
#Upload all of the artifacts that we have created using the third party
#action recommended bu Github
- name: Upload Release Artifacts
@@ -545,18 +551,19 @@ jobs:
files: |
DA-ESS-ContentUpdate-${{ steps.vars.outputs.tag }}.tar.gz
DA-ESS_AmazonWebServices_Content-${{ steps.vars.outputs.tag }}.tar.gz
SSA_Content-${{ steps.vars.outputs.tag }}.tar.gz
report-${{ steps.vars.outputs.tag }}.tar.gz
checksum-${{ steps.vars.outputs.tag }}.txt
attack-range-update:
runs-on: ubuntu-latest
needs: [validate-content, build-sources, build-package, run-appinspect, create-report, update-sources-github, publish-github-release]
#Only run when tagged
if: startsWith(github.ref, 'refs/tags/')
steps:
steps:
#Get the artifacts that we need
- uses: actions/download-artifact@v2
with:
@@ -569,20 +576,20 @@ jobs:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
# aws-session-token: ${{ secrets.AWS_SESSION_TOKEN }} # if you have/need it
aws-region: us-west-1 #assume we will always use this, could make this an environment variable...
aws-region: us-west-1 #assume we will always use this, could make this an environment variable...
- name: Sync latest ESCU to the Attack Range S3 bucket for apps
run: |
aws s3 cp DA-ESS-ContentUpdate-latest.tar.gz s3://attack-range-appbinaries/
# make the file public since it is not by default
aws s3api put-object-acl --bucket attack-range-appbinaries --key DA-ESS-ContentUpdate-latest.tar.gz --acl public-read
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]
#Only run when tagged
if: startsWith(github.ref, 'refs/tags/')
steps:
steps:
- name: Checkout Repo
uses: actions/checkout@v2
with:
@@ -607,7 +614,7 @@ jobs:
- name: Create Baseline Folder
run: |
source venv/bin/activate
python3 bin/create_baseline_folder.py
python3 bin/create_baseline_folder.py
#Official, Verified Amazon-AWS Github Account Provided Action
- uses: aws-actions/configure-aws-credentials@v1
@@ -615,7 +622,7 @@ jobs:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
# aws-session-token: ${{ secrets.AWS_SESSION_TOKEN }} # if you have/need it
aws-region: us-west-1 #assume we will always use this, could make this an environment variable...
aws-region: us-west-1 #assume we will always use this, could make this an environment variable...
- name: Update API sources
run: |
@@ -623,8 +630,7 @@ jobs:
aws s3 cp stories s3://security-content/stories --recursive --exclude "*" --include "*.yml"
aws s3 cp baselines s3://security-content/baselines --recursive --exclude "*" --include "*.yml"
aws s3 cp detections s3://security-content/detections --recursive --exclude "*" --include "*.yml"
aws s3 cp response_tasks s3://security-content/response_tasks --recursive --exclude "*" --include "*.yml"
aws s3 cp responses s3://security-content/responses --recursive --exclude "*" --include "*.yml"
aws s3 cp playbooks s3://security-content/playbooks --recursive --exclude "*" --include "*.yml"
aws s3 cp lookups s3://security-content/lookups --recursive --exclude "*" --include "*.yml"
aws s3 cp lookups s3://security-content/lookups --recursive --exclude "*" --include "*.csv"
aws s3 cp macros s3://security-content/macros --recursive --exclude "*" --include "*.yml"
@@ -638,5 +644,3 @@ jobs:
echo "Error [Security Content API status: $API_STATUS]"
exit 1
fi
+2 -2
View File
@@ -69,7 +69,7 @@ jobs:
- name: Install Python Dependencies
run: |
#Get the virtualenv set up
cd automated_detection_testing/ci/python_ci_code
cd bin/automated_detection_testing/ci/python_ci_code
rm -rf venv
python3 -m venv --clear venv
source venv/bin/activate
@@ -90,7 +90,7 @@ jobs:
- name: Run Detection testing
timeout-minutes: 120
run: |
cd automated_detection_testing/ci/python_ci_code
cd bin/automated_detection_testing/ci/python_ci_code
source venv/bin/activate
echo "github.event.issue.pull_request : [${{ github.event.issue.pull_request }}]"

Before

Width:  |  Height:  |  Size: 78 KiB

After

Width:  |  Height:  |  Size: 78 KiB

@@ -1,4 +1,4 @@
ansible==3.4.0
ansible==4.7.0
ansible-runner==2.0.2
apipkg==1.5
aspy.yaml==1.3.0
@@ -7,31 +7,31 @@ attackcti==0.3.4.3
attrs==21.2.0
azure-common==1.1.27
azure-core==1.18.0
azure-mgmt-compute==23.0.0
azure-identity==1.6.1
azure-mgmt-compute==20.0.0
azure-mgmt-core==1.2.1
azure-mgmt-network==19.0.0
azure-mgmt-resource==17.0.0
bcrypt==3.2.0
boto3==1.18.38
botocore==1.20.105
botocore==1.22.5
certifi==2021.5.30
cffi==1.14.5
cffi==1.15.0
cfgv==3.3.0
chardet==4.0.0
colorama==0.4.4
configparser==5.0.2
contextlib2==0.6.0.post1
Deprecated==1.2.12
Deprecated==1.2.13
dnspython==2.1.0
docutils==0.17.1
docutils==0.18
execnet==1.9.0
gitdb==4.0.5
GitPython==3.1.18
GitPython==3.1.24
identify==2.2.10
idna==2.8
idna==3.3
importlib-metadata==4.0.1
Jinja2==3.0.0
Jinja2==3.0.2
jmespath==0.10.0
lockfile==0.12.2
MarkupSafe==2.0.1
@@ -57,15 +57,15 @@ PyJWT==2.1.0
PyNaCl==1.4.0
pyparsing==2.4.7
pyperclip==1.8.2
pytest==6.2.4
pytest==6.2.5
python-daemon==2.3.0
python-dateutil==2.8.1
python-terraform==0.10.1
pywinrm==0.4.2
PyYAML==5.4.1
PyYAML==6.0
requests==2.25.1
requests-ntlm==1.1.0
s3transfer==0.4.2
s3transfer==0.5.0
six==1.16.0
smmap==3.0.5
splunk-sdk==1.6.16
@@ -73,10 +73,10 @@ tabulate==0.8.9
termcolor==1.1.0
toml==0.10.2
urllib3<1.26.8
virtualenv==20.4.6
virtualenv==20.9.0
wcwidth==0.2.5
wget==3.2
wrapt==1.12.1
wrapt==1.13.1
xmltodict==0.12.0
zipp==3.4.1
+24 -46
View File
@@ -3,7 +3,7 @@ import yaml
import argparse
import sys
import re
from os import path, walk
from os import path, walk, remove
import json
from jinja2 import Environment, FileSystemLoader
import datetime
@@ -172,7 +172,7 @@ def generate_doc_stories(REPO_PATH, OUTPUT_DIR, TEMPLATE_PATH, attack, sorted_de
if t not in tactics:
tactics.append(t)
template = j2_env.get_template('doc_navigation_markdown.j2')
template = j2_env.get_template('doc_navigation.j2')
output_path = path.join(OUTPUT_DIR + '/_data/navigation.yml')
output = template.render(tactics=sorted(tactics), datamodels=sorted(datamodels), categories=sorted(category_names))
with open(output_path, 'w', encoding="utf-8") as f:
@@ -181,7 +181,7 @@ def generate_doc_stories(REPO_PATH, OUTPUT_DIR, TEMPLATE_PATH, attack, sorted_de
# write navigation _pages
# for datamodels
template = j2_env.get_template('doc_navigation_pages_markdown.j2')
template = j2_env.get_template('doc_navigation_pages.j2')
for datamodel in sorted(datamodels):
output_path = path.join(OUTPUT_DIR + '/_pages/' + datamodel.lower().replace(" ", "_") + ".md")
output = template.render(tag=datamodel)
@@ -197,7 +197,7 @@ def generate_doc_stories(REPO_PATH, OUTPUT_DIR, TEMPLATE_PATH, attack, sorted_de
messages.append("doc_gen.py wrote _page for: {1} structure to: {0}".format(output_path, tactic))
# for story categories
template = j2_env.get_template('doc_navigation_story_pages_markdown.j2')
template = j2_env.get_template('doc_navigation_story_pages.j2')
for category in categories:
output_path = path.join(OUTPUT_DIR + '/_pages/' + category['name'].lower().replace(" ", "_") + ".md")
output = template.render(category=category)
@@ -206,7 +206,7 @@ def generate_doc_stories(REPO_PATH, OUTPUT_DIR, TEMPLATE_PATH, attack, sorted_de
messages.append("doc_gen.py wrote _page for: {0} structure to: {1}".format(category['name'], output_path))
# write stories listing markdown
template = j2_env.get_template('doc_story_page_markdown.j2')
template = j2_env.get_template('doc_story_page.j2')
output_path = path.join(OUTPUT_DIR + '/_pages/stories.md')
output = template.render(stories=sorted_stories)
with open(output_path, 'w', encoding="utf-8") as f:
@@ -214,7 +214,7 @@ def generate_doc_stories(REPO_PATH, OUTPUT_DIR, TEMPLATE_PATH, attack, sorted_de
messages.append("doc_gen.py wrote _pages for story to: {0}".format(output_path))
# write stories markdown
template = j2_env.get_template('doc_stories_markdown.j2')
template = j2_env.get_template('doc_stories.j2')
for story in sorted_stories:
file_name = story['name'].lower().replace(" ","_") + '.md'
output_path = path.join(OUTPUT_DIR + '/_stories/' + file_name)
@@ -223,14 +223,6 @@ def generate_doc_stories(REPO_PATH, OUTPUT_DIR, TEMPLATE_PATH, attack, sorted_de
f.write(output)
messages.append("doc_gen.py wrote {0} story documentation in markdown to: {1}".format(len(sorted_stories),OUTPUT_DIR + '/_stories/'))
# write wikimarkup
template = j2_env.get_template('doc_stories_wiki.j2')
output_path = path.join(OUTPUT_DIR + '/stories.wiki')
output = template.render(categories=categories, time=datetime.datetime.now())
with open(output_path, 'w', encoding="utf-8") as f:
f.write(output)
messages.append("doc_gen.py wrote {0} stories documentation in mediawiki to: {1}".format(len(stories),output_path))
return sorted_stories, messages
@@ -293,7 +285,7 @@ def generate_doc_detections(REPO_PATH, OUTPUT_DIR, TEMPLATE_PATH, attack, messag
trim_blocks=False, autoescape=True)
# write markdown
template = j2_env.get_template('doc_detections_markdown.j2')
template = j2_env.get_template('doc_detections.j2')
for detection in sorted_detections:
file_name = detection['date'] + "-" + detection['name'].lower().replace(" ","_") + '.md'
output_path = path.join(OUTPUT_DIR + '/_posts/' + file_name)
@@ -303,38 +295,13 @@ def generate_doc_detections(REPO_PATH, OUTPUT_DIR, TEMPLATE_PATH, attack, messag
messages.append("doc_gen.py wrote {0} detections documentation in markdown to: {1}".format(len(sorted_detections),OUTPUT_DIR + '/_posts/'))
# write markdown detection page
template = j2_env.get_template('doc_detection_page_markdown.j2')
template = j2_env.get_template('doc_detection_page.j2')
output_path = path.join(OUTPUT_DIR + '/_pages/detections.md')
output = template.render(detections=sorted_detections, time=datetime.datetime.now())
with open(output_path, 'w', encoding="utf-8") as f:
f.write(output)
messages.append("doc_gen.py wrote detections.md page to: {0}".format(output_path))
#sort detections by kind into categories
kinds = []
kind_names = set()
for detection in sorted_detections:
kind_names.add(detection['kind'])
for kind_name in sorted(kind_names):
new_kind = {}
new_kind['name'] = kind_name
new_kind['detections'] = []
kinds.append(new_kind)
for detection in sorted_detections:
for kind in kinds:
if kind['name'] == detection['kind']:
kind['detections'].append(detection)
# write wikimarkup
template = j2_env.get_template('doc_detections_wiki.j2')
output_path = path.join(OUTPUT_DIR + '/detections.wiki')
output = template.render(kinds=kinds, time=datetime.datetime.now())
with open(output_path, 'w', encoding="utf-8") as f:
f.write(output)
messages.append("doc_gen.py wrote {0} detections documentation in mediawiki to: {1}".format(len(detections),output_path))
return sorted_detections, messages
def generate_doc_playbooks(REPO_PATH, OUTPUT_DIR, TEMPLATE_PATH, sorted_detections, messages, VERBOSE):
@@ -366,7 +333,7 @@ def generate_doc_playbooks(REPO_PATH, OUTPUT_DIR, TEMPLATE_PATH, sorted_detectio
trim_blocks=False, autoescape=True)
# write markdown
template = j2_env.get_template('doc_playbooks_markdown.j2')
template = j2_env.get_template('doc_playbooks.j2')
for playbook in sorted_playbooks:
file_name = playbook['name'].lower().replace(" ","_") + '.md'
output_path = path.join(OUTPUT_DIR + '/_playbooks/' + file_name)
@@ -376,7 +343,7 @@ def generate_doc_playbooks(REPO_PATH, OUTPUT_DIR, TEMPLATE_PATH, sorted_detectio
messages.append("doc_gen.py wrote {0} playbook documentation in markdown to: {1}".format(len(sorted_playbooks),OUTPUT_DIR + '/_playbooks/'))
# write markdown detection page
template = j2_env.get_template('doc_playbooks_page_markdown.j2')
template = j2_env.get_template('doc_playbooks_page.j2')
output_path = path.join(OUTPUT_DIR + '/_pages/playbooks.md')
output = template.render(playbooks=sorted_playbooks, detections=sorted_detections, time=datetime.datetime.now())
with open(output_path, 'w', encoding="utf-8") as f:
@@ -392,7 +359,7 @@ def generate_doc_index(OUTPUT_DIR, TEMPLATE_PATH, sorted_detections, sorted_stor
trim_blocks=False, autoescape=True)
# write index updated metrics
template = j2_env.get_template('doc_index_markdown.j2')
template = j2_env.get_template('doc_index.j2')
output_path = path.join(OUTPUT_DIR + '/index.markdown')
output = template.render(detection_count=len(sorted_detections), story_count=len(sorted_stories), playbook_count=len(sorted_playbooks))
with open(output_path, 'w', encoding="utf-8") as f:
@@ -405,7 +372,7 @@ if __name__ == "__main__":
# grab arguments
parser = argparse.ArgumentParser(description="Generates documentation from Splunk Security Content", epilog="""
This tool converts all Splunk Security Content detections, stories, workbooks and spec files into documentation. It builds both wiki markup (Splunk Docs) an markdown documentation.""")
This generates documention in the form of jekyll site research.splunk.com from Splunk Security Content yamls. """)
parser.add_argument("-p", "--path", required=True, help="path to security_content repo")
parser.add_argument("-o", "--output", required=True, help="path to the output directory for the docs")
parser.add_argument("-v", "--verbose", required=False, default=False, action='store_true', help="prints verbose output")
@@ -417,13 +384,24 @@ if __name__ == "__main__":
OUTPUT_DIR = args.output
VERBOSE = args.verbose
TEMPLATE_PATH = path.join(REPO_PATH, 'bin/jinja2_templates')
if VERBOSE:
print("getting mitre enrichment data from cti")
techniques = get_all_techniques(REPO_PATH)
if VERBOSE:
print("wiping the {0}/_posts/* folder".format(OUTPUT_DIR))
try:
for root, dirs, files in walk(OUTPUT_DIR + '/_posts/'):
for file in files:
if file.endswith(".md"):
remove(OUTPUT_DIR + '/_posts/' + file)
except OSError as e:
print("error: %s : %s" % (file, e.strerror))
sys.exit(1)
messages = []
sorted_detections, messages = generate_doc_detections(REPO_PATH, OUTPUT_DIR, TEMPLATE_PATH, techniques, messages, VERBOSE)
sorted_stories, messages = generate_doc_stories(REPO_PATH, OUTPUT_DIR, TEMPLATE_PATH, techniques, sorted_detections, messages, VERBOSE)
+60 -46
View File
@@ -92,6 +92,29 @@ def generate_collections_conf(lookups, TEMPLATE_PATH, OUTPUT_PATH):
return output_path
def generate_ssa_yaml(detections, TEMPLATE_PATH, OUTPUT_PATH):
'''
@param detections: input list of individual YAML detections in detections/ directory
@return: the enhanced yaml file located in /detections directory
'''
# disable yaml pointers https://stackoverflow.com/questions/51272814/python-yaml-dumping-pointer-references
yaml.Dumper.ignore_aliases = lambda *args : True
for d in detections:
manifest_file = OUTPUT_PATH + '/detections/' + d['name'].lower().replace(" ", "_") + '.yml'
# remove unused fields
del d['risk']
del d['deployment']
del d['mappings']
del d['savedsearch_annotations']
with open(manifest_file, 'w') as file:
documents = yaml.dump(d, file, sort_keys=True)
return OUTPUT_PATH + '/detections/'
def generate_savedsearches_conf(detections, deployments, TEMPLATE_PATH, OUTPUT_PATH):
'''
@param detections: input list of individual YAML detections in detections/ directory
@@ -113,19 +136,6 @@ def generate_savedsearches_conf(detections, deployments, TEMPLATE_PATH, OUTPUT_P
return output_path
# def generate_analytic_story_conf(stories, detections, TEMPLATE_PATH, OUTPUT_PATH):
# utc_time = datetime.datetime.utcnow().replace(microsecond=0).isoformat()
# j2_env = Environment(loader=FileSystemLoader(TEMPLATE_PATH), # nosemgrep
# trim_blocks=True)
# template = j2_env.get_template('analytic_stories.j2')
# output_path = path.join(OUTPUT_PATH, 'default/analytic_stories.conf')
# output = template.render(stories=stories, time=utc_time)
# with open(output_path, 'w', encoding="utf-8") as f:
# f.write(output)
# return output_path
def generate_use_case_library_conf(stories, detections, TEMPLATE_PATH, OUTPUT_PATH):
utc_time = datetime.datetime.utcnow().replace(microsecond=0).isoformat()
@@ -245,7 +255,6 @@ def get_deployments(object, deployments):
for tag_value_deployment in tag_array_deployment:
if tag_value == tag_value_deployment:
# print("tag value: {}, matched deployment tag: {} on deployment: {}".format(tag_value,tag_value_deployment, deployment))
matched_deployments.append(deployment)
continue
@@ -257,9 +266,7 @@ def get_deployments(object, deployments):
last_deployment = deployment
else:
last_deployment = matched_deployments[-1]
# last_deployment = replace_vars_in_deployment(last_deployment, object) # Not needed because of custom_jinja2_enrichment_filter
# print(last_deployment)
return last_deployment
def get_nes_fields(search, deployment):
@@ -336,18 +343,18 @@ def add_annotations(detection):
savedsearch_annotations[key] = detection['tags'][key]
detection['savedsearch_annotations'] = savedsearch_annotations
# add SSA risk_severity
if 'risk_score' in detection['tags']:
if detection['tags']['risk_score'] >= 80:
detection['tags']['risk_severity'] = 'high'
elif(50>= detection['tags']['risk_score'] <=79):
detection['tags']['risk_severity'] = 'medium'
else:
detection['tags']['risk_severity'] = 'low'
return detection
def add_rba(detection):
# removed since this is causing a duplicate bug in ES 6.4+
# if 'risk_object' in detection['tags']:
# detection['risk_object'] = detection['tags']['risk_object']
# if 'risk_object_type' in detection['tags']:
# detection['risk_object_type'] = detection['tags']['risk_object_type']
# if 'risk_score' in detection['tags']:
# detection['risk_score'] = detection['tags']['risk_score']
# grab risk message
if 'message' in detection['tags']:
detection['risk_message'] = detection['tags']['message']
@@ -433,7 +440,6 @@ def prepare_detections(detections, deployments, playbooks, OUTPUT_PATH):
elif detection['type'] == 'Correlation':
detection['search'] = detection['search'] + ' | collect index=alerts'
# parse out data_models
data_model = parse_data_models_from_search(detection['search'])
if data_model:
@@ -465,7 +471,7 @@ def prepare_detections(detections, deployments, playbooks, OUTPUT_PATH):
if 'product' in detection['tags']:
detection['product'] = detection['tags']['product']
# turn all SAAWS detections
# enable all SAAWS detections
if (OUTPUT_PATH) == 'dist/saaws':
detection['disabled'] = 'false'
@@ -626,14 +632,17 @@ def compute_objects(objects, PRODUCT, OUTPUT_PATH):
objects["detections"] = [object for object in objects["detections"] if 'Dev Sec Ops Analytics' in object['tags']['product']]
objects["stories"] = [object for object in objects["stories"] if 'Dev Sec Ops Analytics' in object['tags']['product']]
if PRODUCT == "ESCU":
# only use ESCU detections to the configurations
objects["detections"] = sorted(filter(lambda d: not 'Splunk Behavioral Analytics' in d['tags']['product'], objects["detections"]), key=lambda d: d['name'])
objects["stories"] = sorted(filter(lambda s: not 'Splunk Behavioral Analytics' in s['tags']['product'], objects["stories"]), key=lambda s: s['name'])
# only use ESCU detections to the configurations
objects["detections"] = sorted(filter(lambda d: not 'Splunk Behavioral Analytics' in d['tags']['product'], objects["detections"]), key=lambda d: d['name'])
# only use ESCU stories to the configuration
objects["stories"] = sorted(filter(lambda s: not 'Splunk Behavioral Analytics' in s['tags']['product'], objects["stories"]), key=lambda s: s['name'])
if PRODUCT == "SSA":
# only SSA detections, also no need to calculate stories
objects["detections"] = sorted(filter(lambda d: 'Splunk Behavioral Analytics' in d['tags']['product'], objects["detections"]), key=lambda d: d['name'])
objects["stories"] = sorted(filter(lambda s: 'Splunk Behavioral Analytics' in s['tags']['product'], objects["stories"]), key=lambda s: s['name'])
objects["macros"] = sorted(objects["macros"], key=lambda m: m['name'])
objects["detections"] = prepare_detections(objects["detections"], objects["deployments"], objects["playbooks"], OUTPUT_PATH)
objects["stories"] = prepare_stories(objects["stories"], objects["detections"], objects["playbooks"])
@@ -654,31 +663,36 @@ def main(REPO_PATH, OUTPUT_PATH, PRODUCT, VERBOSE):
try:
if VERBOSE:
print("generating Mitre lookups")
generate_mitre_lookup(OUTPUT_PATH)
# generate_mitre_lookup(OUTPUT_PATH)
except Exception as e:
print('Error: ' + str(e))
print("WARNING: Generation of Mitre lookup failed.")
lookups_path = generate_transforms_conf(objects["lookups"], TEMPLATE_PATH, OUTPUT_PATH)
lookups_path = generate_collections_conf(objects["lookups"], TEMPLATE_PATH, OUTPUT_PATH)
lookups_files = generate_lookup_files(objects["lookups"], TEMPLATE_PATH, OUTPUT_PATH,REPO_PATH)
detection_path = generate_savedsearches_conf(objects["detections"], objects["deployments"], TEMPLATE_PATH, OUTPUT_PATH)
# story_path = generate_analytic_story_conf(objects["stories"], objects["detections"], TEMPLATE_PATH, OUTPUT_PATH)
use_case_lib_path = generate_use_case_library_conf(objects["stories"], objects["detections"], TEMPLATE_PATH, OUTPUT_PATH)
macros_path = generate_macros_conf(objects["macros"], objects["detections"], TEMPLATE_PATH, OUTPUT_PATH)
workbench_panels_objects = generate_workbench_panels(objects["detections"], objects["stories"], TEMPLATE_PATH, OUTPUT_PATH)
# calculate deprecation totals
deprecated = []
for d in objects['detections']:
if 'deprecated' in d:
deprecated.append(d)
detection_path = ''
lookups_path = ''
lookups_files= ''
use_case_lib_path = ''
macros_path = ''
workbench_panels_objects = ''
if global_product == 'SSA':
detection_path = generate_ssa_yaml(objects["detections"], TEMPLATE_PATH, OUTPUT_PATH)
objects["macros"] = []
else:
detection_path = generate_savedsearches_conf(objects["detections"], objects["deployments"], TEMPLATE_PATH, OUTPUT_PATH)
lookups_path = generate_transforms_conf(objects["lookups"], TEMPLATE_PATH, OUTPUT_PATH)
lookups_path = generate_collections_conf(objects["lookups"], TEMPLATE_PATH, OUTPUT_PATH)
lookups_files = generate_lookup_files(objects["lookups"], TEMPLATE_PATH, OUTPUT_PATH,REPO_PATH)
use_case_lib_path = generate_use_case_library_conf(objects["stories"], objects["detections"], TEMPLATE_PATH, OUTPUT_PATH)
macros_path = generate_macros_conf(objects["macros"], objects["detections"], TEMPLATE_PATH, OUTPUT_PATH)
workbench_panels_objects = generate_workbench_panels(objects["detections"], objects["stories"], TEMPLATE_PATH, OUTPUT_PATH)
if VERBOSE:
print("{0} stories have been successfully written to {1}".format(len(objects["stories"]), use_case_lib_path))
print("{0} detections have been successfully written to {1}".format(len(objects["detections"]), detection_path))
@@ -12,9 +12,7 @@ last_modified_at: {{detection.date}}
toc: true
toc_label: ""
tags:
- {{ detection.type }}
{%- for attack in detection.mitre_attacks %}
- {{ attack.technique_id }}
- {{ attack.technique }}
{%- for attack_tactic in attack.tactic %}
- {{ attack_tactic }}
@@ -28,9 +26,6 @@ tags:
{%- endfor -%}
{%- for datamodel in detection.datamodel %}
- {{ datamodel }}
{%- endfor -%}
{%- for phase in detection.tags.kill_chain_phases %}
- {{ phase }}
{%- endfor %}
---
@@ -55,12 +50,11 @@ We have not been able to test, simulate or build datasets for it, use at your ow
{% if detection.mitre_attacks %}
#### [ATT&CK](https://attack.mitre.org/)
| ID | Technique | Tactic |
| ----------- | ----------- | ----------- |
{% for attack in detection.mitre_attacks -%}
| ID | Technique | Tactic |
| ----------- | ----------- |--------------- |
{%- for attack in detection.mitre_attacks %}
{% if attack.technique_id -%}
{% set sub_technique = attack.technique_id.split('.') -%}
{% if sub_technique | length > 1 -%}
{% set sub_technique = attack.technique_id.split('.') %}{% if sub_technique | length > 1 -%}
| [{{ attack.technique_id }}](https://attack.mitre.org/techniques/{{sub_technique[0]}}/{{sub_technique[1]}}/) | {{ attack.technique }} | {{ attack.tactic|join(', ') }} |
{% else -%}
| [{{ attack.technique_id }}](https://attack.mitre.org/techniques/{{attack.technique_id}}/) | {{ attack.technique }} | {{ attack.tactic|join(', ') }} |
@@ -1,98 +0,0 @@
=Splunk Security Content Detections =
----
All the detections shipped to different Splunk products. Below is a breakdown by kind.
{% for kind in kinds %}
=={{ kind.name|capitalize }}==
{% for detection in kind.detections %}
==={{ detection.name|capitalize}}===
{{ detection.description }}
* '''Product''': {{ detection.tags.product|join(', ') }}
* '''Datamodel''': {{ detection.datamodel|join(', ') }}
* '''ATT&CK''': {% for attack in detection.mitre_attacks -%}
{%- if attack.technique_id -%}
{% set sub_technique = attack.technique_id.split('.') %}
{%- if sub_technique | length > 1 -%}
[https://attack.mitre.org/techniques/{{sub_technique[0] }}/{{sub_technique[1]}}/ {{ attack.technique_id }}]
{%- else -%}
[https://attack.mitre.org/techniques/{{attack.technique_id}}/ {{ attack.technique_id }}]
{%- endif -%}
{%- endif -%}
{% if not loop.last -%}, {% endif -%}
{% endfor %}
* '''Last Updated''': {{ detection.date }}
<div class="toccolours mw-collapsible mw-collapsed">
<div class="mw-collapsible-content">
====Search====
<search>{{ detection.search|replace("|", "\n|") }}</search>
====Associated Analytic Story====
{% for story in detection.tags.analytic_story %}
* [[Documentation:ESSOC:stories:UseCase#{{ story|replace(" ", "_") }}|{{ story }}]]
{% endfor %}
====How To Implement====
{{ detection.how_to_implement}}
====Required field====
{% for field in detection.tags.required_fields %}
* {{ field }}
{% endfor %}
{% if detection.mitre_attacks|length > 0 %}
====ATT&CK====
{|
! style="text-align:left;"| ID
! Technique
! Tactic
{%-for attack in detection.mitre_attacks %}
|-
| {{ attack.technique_id }}
| {{ attack.technique }}
| {{ attack.tactic|join(', ') }}
{%- endfor %}
|}
{% endif %}
====Kill Chain Phase====
{% for phase in detection.tags.kill_chain_phases %}
* {{ phase }}
{% endfor %}
====Known False Positives====
{{ detection.known_false_positives}}
====Reference====
{% if detection.references %}
{% for reference in detection.references %}
* {{ reference }}
{% endfor %}
{% endif %}
====Test Dataset====
{% for dataset in detection.tags.dataset %}
* {{ dataset }}
{% endfor %}
''version'': {{detection.version}}
</div>
</div>
----
{% endfor %}
{% endfor %}
<pre>
#############
# Automatically generated by doc_gen.py in https://github.com/splunk/security_content''
# On Date: {{ time }} UTC''
# Author: Splunk Security Research''
# Contact: research@splunk.com''
#############
</pre>
-75
View File
@@ -1,75 +0,0 @@
=Splunk Security Content Analytic Story =
----
All the Analytic Stories shipped to different Splunk products. Below is a breakdown by Category.
{% for category in categories %}
=={{ category.name }}==
{% for story in category.stories %}
==={{ story.name|capitalize }}===
{{ story.description }}
* '''Product''': {{ story.tags.product|join(', ') }}
* '''Datamodel''': {%-for datamodel in story.data_models %}[https://docs.splunk.com/Documentation/CIM/latest/User/{{ datamodel|replace("_", "")}} {{ datamodel }}]{% if not loop.last %}, {% endif %}{%-endfor %}
* '''Last Updated''': {{ story.date }}
* '''Use Case''': {{ story.tags.usecase }}
<div class="toccolours mw-collapsible">
<div class="mw-collapsible-content">
====Detection Profile====
{|
! style="text-align:left;"| name
! ID
! Technique
! Tactic
! Type
{%- for detection in story.detections %}
|-
| [[Documentation:ESSOC:detections:Detections#{{ detection.name|replace(" ", "_")|capitalize }}|{{ detection.name }}]]
{% if story.mitre_attacks|length > 0 %}
| {%-for attack in detection.mitre_attacks %}
[https://attack.mitre.org/techniques/{{ attack.technique_id }}/ {{ attack.technique_id }}]{% if not loop.last %}, {% endif %}
{%-endfor %}
| {%-for attack in detection.mitre_attacks %}
{{ attack.technique}}{{ ", " if not loop.last else "" }}
{%- endfor %}
| {%-for attack in detection.mitre_attacks %}
{{ attack.tactic|join(', ') }}{{ ", " if not loop.last else "" }}
{%- endfor %}
{% else %}
|
|
|
{% endif %}
| {{ detection.type }}
{%- endfor %}
|}
====Kill Chain Phase====
{% for phase in story.kill_chain_phases %}
* {{ phase }}
{% endfor %}
====Reference====
{% for reference in story.references %}
* {{ reference }}
{% endfor %}
''version'': {{story.version}}
</div>
</div>
----
{% endfor %}
{% endfor %}
<pre>
#############
# Automatically generated by doc_gen.py in https://github.com/splunk/security_content
# On Date: {{ time }} UTC
# Author: Splunk Security Research
# Contact: research@splunk.com
#############
</pre>
+3 -6
View File
@@ -103,16 +103,13 @@ def main(args):
# validate arguments
validate_parser.set_defaults(func=validate, epilog="""
Validates security manifest for correctness, adhering to spec and other common items.
VALIDATE DOES NOT PROCESS RESPONSES SPEC for the moment.""")
Validates security manifest for correctness, adhering to spec and other common items.""")
# generate arguments
generate_parser.add_argument("-f", "--format", required=False, type=str, default="splunk_app",
help="Format of our deployment package, defaults to `splunk_app`.\n The deployment `splunk_app` runs on product Splunk Enterprise Security and Splunk Enterprise.")
generate_parser.add_argument("-o", "--output", required=False, type=str, default="dist/escu",
help="Path where to store the deployment package, defaults to `dist/escu`")
generate_parser.add_argument("--product", required=False, type=str, default="ESCU",
help="Type of package to create, choose between `ESCU`, or `SAAWS`. Defaults to `ESCU`")
generate_parser.add_argument("-p", "--product", required=False, type=str, default="ESCU",
help="Type of package to create, choose between `ESCU`, `DevSecOps`, `SAAWS`, or `SSA`. Defaults to `ESCU`")
generate_parser.set_defaults(func=generate)
# # parse them
@@ -19,7 +19,9 @@ search: '`gsuite_drive` NOT (email IN("", "null")) | rex field=parameters.owner
| `gsuite_drive_share_in_external_email_filter`'
how_to_implement: To successfully implement this search, you need to be ingesting
logs related to gsuite having the file attachment metadata like file type, file
extension, source email, destination email, num of attachment and etc. In order for the search to work for your environment, please edit the query to use your company specific email domain instead of `internal_test_email.com`.
extension, source email, destination email, num of attachment and etc. In order
for the search to work for your environment, please edit the query to use your company
specific email domain instead of `internal_test_email.com`.
known_false_positives: network admin or normal user may share files to customer and
external team.
references:
@@ -67,4 +69,3 @@ tags:
- parameters.doc_type
risk_score: 72
security_domain: endpoint
@@ -24,7 +24,9 @@ search: '`gsuite_drive` parameters.owner_is_team_drive=false "parameters.doc_tit
| `gsuite_suspicious_shared_file_name_filter`'
how_to_implement: To successfully implement this search, you need to be ingesting
logs related to gsuite having the file attachment metadata like file type, file
extension, source email, destination email, num of attachment and etc. In order for the search to work for your environment, please edit the query to use your company specific email domain instead of `internal_test_email.com`.
extension, source email, destination email, num of attachment and etc. In order
for the search to work for your environment, please edit the query to use your company
specific email domain instead of `internal_test_email.com`.
known_false_positives: normal user or normal transaction may contain the subject and
file type attachment that this detection try to search
references:
@@ -19,6 +19,8 @@ tags:
- CIS 3
- CIS 4
- CIS 18
cve:
- CVE-2016-4859
kill_chain_phases:
- Delivery
nist:
@@ -35,5 +37,3 @@ tags:
required_fields:
- _time
security_domain: network
cve:
- CVE-2016-4859
@@ -24,6 +24,8 @@ tags:
asset_type: Endpoint
cis20:
- CIS 4
cve:
- CVE-2017-5753
nist:
- ID.RA
- RS.MI
@@ -36,5 +38,3 @@ tags:
required_fields:
- _time
security_domain: endpoint
cve:
- CVE-2017-5753
@@ -26,6 +26,8 @@ tags:
- CIS 3
- CIS 4
- CIS 18
cve:
- CVE-2018-11409
kill_chain_phases:
- Delivery
nist:
@@ -42,6 +44,3 @@ tags:
required_fields:
- _time
security_domain: network
cve:
- CVE-2018-11409
@@ -33,13 +33,29 @@ tags:
analytic_story:
- Windows Persistence Techniques
- Windows Privilege Escalation
automated_detection_testing: passed
confidence: 80
context:
- source:endpoint
- stage:Privilege Escalation Persistence
dataset:
- https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/t1547.014/active_setup_stubpath/sysmon.log
impact: 80
kill_chain_phases:
- Exploitation
message: modified/added/deleted registry entry $Registry.registry_path$ in $dest$
mitre_attack_id:
- T1547.014
- T1547
observable:
- name: dest
type: Hostname
role:
- Victim
- name: user
type: user
role:
- Victim
product:
- Splunk Enterprise
- Splunk Enterprise Security
@@ -51,21 +67,5 @@ tags:
- Registry.registry_path
- Registry.registry_key_name
- Registry.registry_value_name
security_domain: endpoint
impact: 80
confidence: 80
risk_score: 64
context:
- source:endpoint
- stage:Privilege Escalation Persistence
message: modified/added/deleted registry entry $Registry.registry_path$ in $dest$
observable:
- name: dest
type: Hostname
role:
- Victim
- name: user
type: user
role:
- Victim
automated_detection_testing: passed
security_domain: endpoint
@@ -1,7 +1,7 @@
name: Attacker Tools On Endpoint
id: a51bfe1a-94f0-48cc-b4e4-16a110145893
version: 1
date: '2021-06-21'
version: 2
date: '2021-11-04'
author: Bhavin Patel, Splunk
type: TTP
datamodel:
@@ -14,7 +14,7 @@ search: '| tstats `security_content_summariesonly` count min(_time) as firstTime
Processes.user!=unknown by Processes.dest Processes.user Processes.process_name
Processes.process | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`
| `drop_dm_object_name(Processes)` | lookup attacker_tools attacker_tool_names AS
process_name OUTPUT description | search description=* | `attacker_tools_on_endpoint_filter`'
process_name OUTPUT description | search description !=false| `attacker_tools_on_endpoint_filter`'
how_to_implement: To successfully implement this search, you must be ingesting data
that records process activity from your hosts to populate the endpoint data model
in the processes node. This is typically populated via endpoint detection-and-response
@@ -30,13 +30,29 @@ tags:
analytic_story:
- Windows Persistence Techniques
- Windows Privilege Escalation
automated_detection_testing: passed
confidence: 100
context:
- source:endpoint
- stage:Privilege Escalation Persistence
dataset:
- https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1546.001/txtfile_reg/sysmon.log
impact: 80
kill_chain_phases:
- Exploitation
message: modified/added/deleted registry entry $Registry.registry_path$ in $dest$
mitre_attack_id:
- T1546.001
- T1546
observable:
- name: dest
type: Hostname
role:
- Victim
- name: user
type: user
role:
- Victim
product:
- Splunk Enterprise
- Splunk Enterprise Security
@@ -48,21 +64,5 @@ tags:
- Registry.registry_path
- Registry.registry_key_name
- Registry.registry_value_name
security_domain: endpoint
impact: 80
confidence: 100
risk_score: 80
context:
- source:endpoint
- stage:Privilege Escalation Persistence
message: modified/added/deleted registry entry $Registry.registry_path$ in $dest$
observable:
- name: dest
type: Hostname
role:
- Victim
- name: user
type: user
role:
- Victim
automated_detection_testing: passed
security_domain: endpoint
@@ -0,0 +1,69 @@
name: CMD Carry Out String Command Parameter
id: 54a6ed00-3256-11ec-b031-acde48001122
version: 1
date: '2021-10-21'
author: Teoderick Contreras, Splunk, Bhavin Patel, Splunk
type: Hunting
datamodel:
- Endpoint
description: This search looks for command-line arguments where `cmd.exe /c` is used
to execute a program. This technique is commonly seen in adversaries and malware
to execute batch command using different shell like powershell or different process
other than cmd.exe. This is a good hunting query for suspicious commandline made
by a script or relative process execute it.
search: '| tstats `security_content_summariesonly` min(_time) as firstTime max(_time)
as lastTime from datamodel=Endpoint.Processes where `process_cmd` AND Processes.process="*
/c *" by Processes.dest Processes.user Processes.parent_process Processes.process_name
Processes.original_file_name Processes.process Processes.process_id Processes.parent_process_id
| `drop_dm_object_name(Processes)` | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`
| `cmd_carry_out_string_command_parameter_filter`'
how_to_implement: To successfully implement this search, you need to be ingesting
logs with the process name, parent process, and command-line executions from your
endpoints. If you are using Sysmon, you must have at least version 6.0.4 of the
Sysmon TA.
known_false_positives: unknown
references:
- https://thedfirreport.com/2021/10/18/icedid-to-xinglocker-ransomware-in-24-hours/
tags:
analytic_story:
- IcedID
dataset:
- https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/malware/icedid/cmd_carry_str_param/sysmon.log
kill_chain_phases:
- Exploitation
mitre_attack_id:
- T1059.003
- T1059
product:
- Splunk Enterprise
- Splunk Enterprise Security
- Splunk Cloud
required_fields:
- _time
- Processes.parent_process_name
- Processes.parent_process
- Processes.process_name
- Processes.process_id
- Processes.process
- Processes.dest
- Processes.user
- Processes.process_id
- Processes.parent_process_id
security_domain: endpoint
impact: 60
confidence: 50
risk_score: 30
context:
- Source:Endpoint
- Stage:Execution
message: $process_name$ with commandline $process$ in $dest$
observable:
- name: dest
type: Endpoint
role:
- Victim
- name: user
type: User
role:
- Victim
automated_detection_testing: passed
@@ -6,25 +6,30 @@ author: Teoderick Contreras, Splunk
type: TTP
datamodel:
- Endpoint
description: This search is to detect a suspicious parent process execution of commandline
tool not in shell commandline. This technique was seen in FIN7 JSSLoader .net compile
payload where it run ipconfig.exe and systeminfo.exe using .net application. This
event cause some good TTP since those tool are commonly run in commandline not by
another application. This TTP is a good indicator for application gather host information
either an attacker or an automated tool made by admin.
description: The following analytic identifies a non-standard parent process (not
matching CMD, PowerShell, or Explorer) spawning `ipconfig.exe` or `systeminfo.exe`.
This particular behavior was seen in FIN7's JSSLoader .NET payload. This is also
typically seen when an adversary is injected into another process performing different
discovery techniques. This event stands out as a TTP since these tools are commonly
executed with a shell application or Explorer parent, and not by another application.
This TTP is a good indicator for an adversary gathering host information, but one
possible false positive might be an automated tool used by a system administator.
search: '| tstats `security_content_summariesonly` count min(_time) as firstTime max(_time)
as lastTime from datamodel=Endpoint.Processes where (Processes.process_name = "ipconfig.exe"
OR Processes.process_name = "systeminfo.exe") AND NOT (Processes.parent_process_name
= "cmd.exe" OR Processes.parent_process_name = "powershell*" OR Processes.parent_process_name
= "explorer.exe") by Processes.parent_process_name Processes.parent_process Processes.process_name
Processes.process_id Processes.process Processes.dest Processes.user | `drop_dm_object_name(Processes)`
= "cmd.exe" OR Processes.parent_process_name = "powershell*" OR Processes.parent_process_name="pwsh.exe"
OR Processes.parent_process_name = "explorer.exe") by Processes.parent_process_name
Processes.parent_process Processes.process_name Processes.original_file_name Processes.process_id
Processes.process Processes.dest Processes.user | `drop_dm_object_name(Processes)`
| `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `cmdline_tool_not_executed_in_cmd_shell_filter`'
how_to_implement: To successfully implement this search, you need to be ingesting
logs with the process name, parent process, and command-line executions from your
endpoints. If you are using Sysmon, you must have at least version 6.0.4 of the
Sysmon TA.
known_false_positives: network operator or admin may create this type of tool to gather
host information
how_to_implement: To successfully implement this search you need to be ingesting information
on process that include the name of the process responsible for the changes from
your endpoints into the `Endpoint` datamodel in the `Processes` node. In addition,
confirm the latest CIM App 4.20 or higher is installed and the latest TA for the
endpoint product.
known_false_positives: A network operator or systems administrator may utilize an
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://attack.mitre.org/groups/G0046/
@@ -41,8 +46,8 @@ tags:
impact: 70
kill_chain_phases:
- Exploitation
message: parent process name $parent_process_name$ with child process $process_name$
to execute commandline tool in $dest$
message: A non-standard parent process $parent_process_name$ spawned child process
$process_name$ to execute command-line tool on $dest$.
mitre_attack_id:
- T1059
- T1059.007
@@ -55,18 +60,30 @@ tags:
type: User
role:
- Victim
- name: parent_process_name
type: Parent Process
role:
- Parent Process
- name: process_name
type: Process
role:
- Child Process
product:
- Splunk Enterprise
- Splunk Enterprise Security
- Splunk Cloud
required_fields:
- _time
- Processes.parent_process_name
- Processes.parent_process
- Processes.process_name
- Processes.process_id
- Processes.process
- Processes.dest
- Processes.user
- Processes.parent_process_name
- Processes.parent_process
- Processes.original_file_name
- Processes.process_name
- Processes.process
- Processes.process_id
- Processes.parent_process_path
- Processes.process_path
- Processes.parent_process_id
risk_score: 56
security_domain: endpoint
@@ -39,6 +39,8 @@ tags:
context:
- Source:Endpoint
- Stage:Defense Evasion
cve:
- CVE-2021-40444
dataset:
- https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1218.002/atomic_red_team/windows-sysmon.log
impact: 80
@@ -84,5 +86,3 @@ tags:
- Processes.parent_process_id
risk_score: 80
security_domain: endpoint
cve:
- CVE-2021-40444
@@ -30,6 +30,8 @@ tags:
context:
- Source:Endpoint
- Stage:Lateral Movement
cve:
- CVE-2020-1472
impact: 70
kill_chain_phases:
- Actions on Objectives
@@ -67,5 +69,3 @@ tags:
- user
risk_score: 49
security_domain: endpoint
cve:
- CVE-2020-1472
@@ -40,6 +40,8 @@ tags:
context:
- Source:Endpoint
- Stage:Defense Evasion
cve:
- CVE-2021-36934
dataset:
- https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1003.002/serioussam/windows-powershell.log
impact: 80
@@ -72,5 +74,3 @@ tags:
- EventCode
risk_score: 80
security_domain: endpoint
cve:
- CVE-2021-36934
@@ -10,8 +10,8 @@ description: The following analytic identifies regasm.exe with no command line a
This particular behavior occurs when another process injects into regasm.exe, no
command line arguments will be present. During investigation, identify any network
connections and parallel processes. Identify any suspicious module loads related
to credential dumping or file writes. Regasm.exe are natively found in C:\Windows\Microsoft.NET\Framework\v*\regasm|regsvcs.exe
and C:\Windows\Microsoft.NET\Framework64\v*\regasm|regsvcs.exe.
to credential dumping or file writes. Regasm.exe are natively found in `C:\Windows\Microsoft.NET\Framework\v*\regasm|regsvcs.exe`
and `C:\Windows\Microsoft.NET\Framework64\v*\regasm|regsvcs.exe`.
search: '| tstats `security_content_summariesonly` count FROM datamodel=Endpoint.Processes
where `process_regasm` by _time span=1h Processes.process_id Processes.process_name
Processes.dest Processes.process_path Processes.process Processes.parent_process_name
@@ -0,0 +1,66 @@
name: Disable Defender AntiVirus Registry
id: aa4f695a-3024-11ec-9987-acde48001122
version: 1
date: '2021-10-18'
author: Teoderick Contreras, Splunk
type: TTP
datamodel:
- Endpoint
description: This particular behavior is typically executed when an adversaries or
malware gains access to an endpoint and beings to perform execution and to evade
detections. Usually, a batch (.bat) will be executed and multiple registry and scheduled
task modifications will occur. During triage, review parallel processes and identify
any further file modifications. Endpoint should be isolated.
search: '| tstats `security_content_summariesonly` count min(_time) as firstTime max(_time)
as lastTime from datamodel=Endpoint.Registry where Registry.registry_path = "*\\Policies\\Microsoft\\Windows
Defender*" Registry.registry_value_name = DisableAntiVirus Registry.registry_value_data
= 0x00000001 by Registry.dest Registry.user Registry.registry_path Registry.registry_value_name
Registry.registry_value_data | `drop_dm_object_name(Registry)` | `security_content_ctime(lastTime)`
| `security_content_ctime(firstTime)` | `disable_defender_antivirus_registry_filter`'
how_to_implement: To successfully implement this search, you need to be ingesting
logs with the registry value name, registry path, and registry value data from your
endpoints. If you are using Sysmon, you must have at least version 6.0.4 of the
Sysmon TA.
known_false_positives: admin or user may choose to disable windows defender product
references:
- https://thedfirreport.com/2021/10/18/icedid-to-xinglocker-ransomware-in-24-hours/
tags:
analytic_story:
- IceID
dataset:
- https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/malware/icedid/disable_av/sysmon.log
kill_chain_phases:
- Exploitation
mitre_attack_id:
- T1562.001
- T1562
product:
- Splunk Enterprise
- Splunk Enterprise Security
- Splunk Cloud
required_fields:
- _time
- Registry.dest
- Registry.user
- Registry.registry_value_name
- Registry.registry_key_name
- Registry.registry_path
- Registry.registry_value_data
security_domain: endpoint
impact: 70
confidence: 70
risk_score: 49
context:
- Source:Endpoint
- Stage:Defense Evasion
message: modified/added/deleted registry entry $registry_path$ in $dest$
observable:
- name: dest
type: Hostname
role:
- Victim
- name: user
type: user
role:
- Victim
automated_detection_testing: passed
@@ -0,0 +1,65 @@
name: Disable Defender BlockAtFirstSeen Feature
id: 2dd719ac-3021-11ec-97b4-acde48001122
version: 1
date: '2021-10-18'
author: Teoderick Contreras
type: TTP
datamodel:
- Endpoint
description: This analytic is to detect a suspicious modification of registry to disable
windows defender feature. This technique is to bypassed or evade detection from
Windows Defender AV product specially the BlockAtFirstSeen feature where it block
suspicious file first seen in the host.
search: '| tstats `security_content_summariesonly` count min(_time) as firstTime max(_time)
as lastTime from datamodel=Endpoint.Registry where Registry.registry_path = "*\\Microsoft\\Windows
Defender\\SpyNet*" Registry.registry_value_name = DisableBlockAtFirstSeen Registry.registry_value_data
= 0x00000001 by Registry.dest Registry.user Registry.registry_path Registry.registry_value_name
Registry.registry_value_data | `drop_dm_object_name(Registry)` | `security_content_ctime(lastTime)`
| `security_content_ctime(firstTime)` | `disable_defender_blockatfirstseen_feature_filter`'
how_to_implement: To successfully implement this search, you need to be ingesting
logs with the registry value name, registry path, and registry value data from your
endpoints. If you are using Sysmon, you must have at least version 6.0.4 of the
Sysmon TA.
known_false_positives: admin or user may choose to disable windows defender product
references:
- https://thedfirreport.com/2021/10/18/icedid-to-xinglocker-ransomware-in-24-hours/
tags:
analytic_story:
- IceID
dataset:
- https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/malware/icedid/disable_av/sysmon.log
kill_chain_phases:
- Exploitation
mitre_attack_id:
- T1562.001
- T1562
product:
- Splunk Enterprise
- Splunk Enterprise Security
- Splunk Cloud
required_fields:
- _time
- Registry.dest
- Registry.user
- Registry.registry_value_name
- Registry.registry_key_name
- Registry.registry_path
- Registry.registry_value_data
security_domain: endpoint
impact: 70
confidence: 70
risk_score: 49
context:
- Source:Endpoint
- Stage:Defense Evasion
message: modified/added/deleted registry entry $registry_path$ in $dest$
observable:
- name: dest
type: Hostname
role:
- Victim
- name: user
type: user
role:
- Victim
automated_detection_testing: passed
@@ -0,0 +1,65 @@
name: Disable Defender Enhanced Notification
id: dc65678c-301f-11ec-8e30-acde48001122
version: 1
date: '2021-10-18'
author: Teoderick Contreras, Splunk
type: TTP
datamodel:
- Endpoint
description: This analytic is to detect a suspicious modification of registry to disable
windows defender feature. This technique is to bypassed or evade detection from
Windows Defender AV product specially the Enhanced Notification feature wher user
or admin set to show or display alerts.
search: '| tstats `security_content_summariesonly` count min(_time) as firstTime max(_time)
as lastTime from datamodel=Endpoint.Registry where Registry.registry_path = "*Microsoft\\Windows
Defender\\Reporting*" Registry.registry_value_name = DisableEnhancedNotifications
Registry.registry_value_data = 0x00000001 by Registry.dest Registry.user Registry.registry_path
Registry.registry_value_name Registry.registry_value_data | `drop_dm_object_name(Registry)`
| `security_content_ctime(lastTime)` | `security_content_ctime(firstTime)` | `disable_defender_enhanced_notification_filter`'
how_to_implement: To successfully implement this search, you need to be ingesting
logs with the registry value name, registry path, and registry value data executions from your
endpoints. If you are using Sysmon, you must have at least version 6.0.4 of the
Sysmon TA.
known_false_positives: user may choose to disable windows defender AV
references:
- https://thedfirreport.com/2021/10/18/icedid-to-xinglocker-ransomware-in-24-hours/
tags:
analytic_story:
- IceID
dataset:
- https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/malware/icedid/disable_av/sysmon.log
kill_chain_phases:
- Exploitation
mitre_attack_id:
- T1562.001
- T1562
product:
- Splunk Enterprise
- Splunk Enterprise Security
- Splunk Cloud
required_fields:
- _time
- Registry.dest
- Registry.user
- Registry.registry_value_name
- Registry.registry_key_name
- Registry.registry_path
- Registry.registry_value_data
security_domain: endpoint
impact: 70
confidence: 70
risk_score: 49
context:
- Source:Endpoint
- Stage:Defense Evasion
message: modified/added/deleted registry entry $registry_path$ in $dest$
observable:
- name: dest
type: Hostname
role:
- Victim
- name: user
type: user
role:
- Victim
automated_detection_testing: passed
@@ -0,0 +1,66 @@
name: Disable Defender MpEngine Registry
id: cc391750-3024-11ec-955a-acde48001122
version: 1
date: '2021-10-18'
author: Teoderick Contreras, Splunk
type: TTP
datamodel:
- Endpoint
description: This particular behavior is typically executed when an adversaries or
malware gains access to an endpoint and beings to perform execution and to evade
detections. Usually, a batch (.bat) will be executed and multiple registry and scheduled
task modifications will occur. During triage, review parallel processes and identify
any further file modifications. Endpoint should be isolated.
search: '| tstats `security_content_summariesonly` count min(_time) as firstTime max(_time)
as lastTime from datamodel=Endpoint.Registry where Registry.registry_path = "*\\Policies\\Microsoft\\Windows
Defender\\MpEngine*" Registry.registry_value_name = MpEnablePus Registry.registry_value_data
= 0x00000000 by Registry.dest Registry.user Registry.registry_path Registry.registry_value_name
Registry.registry_value_data | `drop_dm_object_name(Registry)` | `security_content_ctime(lastTime)`
| `security_content_ctime(firstTime)` | `disable_defender_mpengine_registry_filter`'
how_to_implement: To successfully implement this search, you need to be ingesting
logs with the registry value name, registry path, and registry value data from your
endpoints. If you are using Sysmon, you must have at least version 6.0.4 of the
Sysmon TA.
known_false_positives: admin or user may choose to disable windows defender product
references:
- https://thedfirreport.com/2021/10/18/icedid-to-xinglocker-ransomware-in-24-hours/
tags:
analytic_story:
- IceID
dataset:
- https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/malware/icedid/disable_av/sysmon.log
kill_chain_phases:
- Exploitation
mitre_attack_id:
- T1562.001
- T1562
product:
- Splunk Enterprise
- Splunk Enterprise Security
- Splunk Cloud
required_fields:
- _time
- Registry.dest
- Registry.user
- Registry.registry_value_name
- Registry.registry_key_name
- Registry.registry_path
- Registry.registry_value_data
security_domain: endpoint
impact: 70
confidence: 70
risk_score: 49
context:
- Source:Endpoint
- Stage:Defense Evasion
message: modified/added/deleted registry entry $registry_path$ in $dest$
observable:
- name: dest
type: Hostname
role:
- Victim
- name: user
type: user
role:
- Victim
automated_detection_testing: passed
@@ -0,0 +1,64 @@
name: Disable Defender Spynet Reporting
id: 898debf4-3021-11ec-ba7c-acde48001122
version: 1
date: '2021-10-18'
author: Teoderick Contreras, Splunk
type: TTP
datamodel:
- Endpoint
description: This analytic is to detect a suspicious modification of registry to disable
windows defender feature. This technique is to bypassed or evade detection from
Windows Defender AV product specially the spynet reporting for its telemetry.
search: '| tstats `security_content_summariesonly` count min(_time) as firstTime max(_time)
as lastTime from datamodel=Endpoint.Registry where Registry.registry_path = "*\\Microsoft\\Windows
Defender\\SpyNet*" Registry.registry_value_name = SpynetReporting Registry.registry_value_data
= 0x00000000 by Registry.dest Registry.user Registry.registry_path Registry.registry_value_name
Registry.registry_value_data | `drop_dm_object_name(Registry)` | `security_content_ctime(lastTime)`
| `security_content_ctime(firstTime)` | `disable_defender_spynet_reporting_filter`'
how_to_implement: To successfully implement this search, you need to be ingesting
logs with the registry value name, registry path, and registry value data from your
endpoints. If you are using Sysmon, you must have at least version 6.0.4 of the
Sysmon TA.
known_false_positives: admin or user may choose to disable windows defender product
references:
- https://thedfirreport.com/2021/10/18/icedid-to-xinglocker-ransomware-in-24-hours/
tags:
analytic_story:
- IceID
dataset:
- https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/malware/icedid/disable_av/sysmon.log
kill_chain_phases:
- Exploitation
mitre_attack_id:
- T1562.001
- T1562
product:
- Splunk Enterprise
- Splunk Enterprise Security
- Splunk Cloud
required_fields:
- _time
- Registry.dest
- Registry.user
- Registry.registry_value_name
- Registry.registry_key_name
- Registry.registry_path
- Registry.registry_value_data
security_domain: endpoint
impact: 70
confidence: 70
risk_score: 49
context:
- Source:Endpoint
- Stage:Defense Evasion
message: modified/added/deleted registry entry $registry_path$ in $dest$
observable:
- name: dest
type: Hostname
role:
- Victim
- name: user
type: user
role:
- Victim
automated_detection_testing: passed
@@ -0,0 +1,64 @@
name: Disable Defender Submit Samples Consent Feature
id: 73922ff8-3022-11ec-bf5e-acde48001122
version: 1
date: '2021-10-18'
author: Teoderick Contreras, Splunk
type: TTP
datamodel:
- Endpoint
description: his analytic is to detect a suspicious modification of registry to disable
windows defender feature. This technique is to bypassed or evade detection from
Windows Defender AV product specially the submit samples feature for further analysis..
search: '| tstats `security_content_summariesonly` count min(_time) as firstTime max(_time)
as lastTime from datamodel=Endpoint.Registry where Registry.registry_path = "*\\Microsoft\\Windows
Defender\\SpyNet*" Registry.registry_value_name = SubmitSamplesConsent Registry.registry_value_data
= 0x00000000 by Registry.dest Registry.user Registry.registry_path Registry.registry_value_name
Registry.registry_value_data | `drop_dm_object_name(Registry)` | `security_content_ctime(lastTime)`
| `security_content_ctime(firstTime)` | `disable_defender_submit_samples_consent_feature_filter`'
how_to_implement: To successfully implement this search, you need to be ingesting
logs with the registry value name, registry path, and registry value data from your
endpoints. If you are using Sysmon, you must have at least version 6.0.4 of the
Sysmon TA.
known_false_positives: admin or user may choose to disable windows defender product
references:
- https://thedfirreport.com/2021/10/18/icedid-to-xinglocker-ransomware-in-24-hours/
tags:
analytic_story:
- IceID
dataset:
- https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/malware/icedid/disable_av/sysmon.log
kill_chain_phases:
- Exploitation
mitre_attack_id:
- T1562.001
- T1562
product:
- Splunk Enterprise
- Splunk Enterprise Security
- Splunk Cloud
required_fields:
- _time
- Registry.dest
- Registry.user
- Registry.registry_value_name
- Registry.registry_key_name
- Registry.registry_path
- Registry.registry_value_data
security_domain: endpoint
impact: 70
confidence: 70
risk_score: 49
context:
- Source:Endpoint
- Stage:Defense Evasion
message: modified/added/deleted registry entry $Registry.registry_path$ in $dest$
observable:
- name: dest
type: Hostname
role:
- Victim
- name: user
type: user
role:
- Victim
automated_detection_testing: passed
@@ -0,0 +1,62 @@
name: Disable Schedule Task
id: db596056-3019-11ec-a9ff-acde48001122
version: 1
date: '2021-10-18'
author: Teoderick Contreras, Splunk
type: TTP
datamodel:
- Endpoint
description: This analytic is to detect a suspicious commandline to disable existing
schedule task. This technique is used by adversaries or commodity malware like IceID
to disable security application (AV products) in the targetted host to evade detections.
This TTP is a good pivot to check further why and what other process run before
and after this detection. check which process execute the commandline and what task
is disabled. parent child process is quite valuable in this scenario too.
search: '| tstats `security_content_summariesonly` count min(_time) as firstTime
max(_time) as lastTime from datamodel=Endpoint.Processes where Processes.process_name=schtasks.exe
Processes.process=*/change* Processes.process=*/disable* by Processes.user Processes.process_name
Processes.process Processes.parent_process_name Processes.parent_process Processes.dest
| `drop_dm_object_name(Processes)` | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`
| `disable_schedule_task_filter`'
how_to_implement: To successfully implement this search, you need to be ingesting
logs with the process name, parent process, and command-line executions from your
endpoints. If you are using Sysmon, you must have at least version 6.0.4 of the
Sysmon TA.
known_false_positives: admin may disable problematic schedule task
references:
- https://thedfirreport.com/2021/10/18/icedid-to-xinglocker-ransomware-in-24-hours/
tags:
analytic_story:
- IcedID
dataset:
- https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/malware/icedid/disable_schtask/sysmon.log
kill_chain_phases:
- Exploitation
mitre_attack_id:
- T1562.001
- T1562
product:
- Splunk Enterprise
- Splunk Enterprise Security
- Splunk Cloud
required_fields:
- _time
- Processes.user
- Processes.process_name
- Processes.parent_process_name
- Processes.dest
security_domain: endpoint
impact: 70
confidence: 80
risk_score: 56
context:
- Source:Endpoint
- Stage:Defense Evasion
message: schtask process with commandline $process$ to disable schedule task in
$dest$
observable:
- name: dest
type: Endpoint
role:
- Victim
automated_detection_testing: passed
@@ -15,9 +15,9 @@ search: '| tstats `security_content_summariesonly` count min(_time) as firstTim
by Registry.dest Registry.user Registry.registry_value_name Registry.registry_key_name
Registry.registry_path Registry.registry_value_data | `security_content_ctime(lastTime)`
| `security_content_ctime(firstTime)` | `disable_security_logs_using_minint_registry_filter`'
how_to_implement: To successfully implement this search, you must be ingesting
data that records registry activity from your hosts to populate the endpoint data
model in the registry node. This is typically populated via endpoint detection-and-response
how_to_implement: To successfully implement this search, you must be ingesting data
that records registry activity from your hosts to populate the endpoint data model
in the registry node. This is typically populated via endpoint detection-and-response
product, such as Carbon Black or endpoint data sources, such as Sysmon. The data
used for this search is typically generated via logs that report reads and writes
to the registry.
@@ -27,12 +27,28 @@ references:
tags:
analytic_story:
- Windows Defense Evasion Tactics
automated_detection_testing: passed
confidence: 100
context:
- Source:Endpoint
- Stage:Defense Evasion
dataset:
- https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1112/minint_reg/sysmon.log
impact: 80
kill_chain_phases:
- Exploitation
message: modified/added/deleted registry entry $Registry.registry_path$ in $dest$
mitre_attack_id:
- T1112
observable:
- name: dest
type: Hostname
role:
- Victim
- name: user
type: user
role:
- Victim
product:
- Splunk Enterprise
- Splunk Enterprise Security
@@ -45,21 +61,5 @@ tags:
- Registry.registry_key_name
- Registry.registry_path
- Registry.registry_value_data
security_domain: endpoint
impact: 80
confidence: 100
risk_score: 80
context:
- Source:Endpoint
- Stage:Defense Evasion
message: modified/added/deleted registry entry $Registry.registry_path$ in $dest$
observable:
- name: dest
type: Hostname
role:
- Victim
- name: user
type: user
role:
- Victim
automated_detection_testing: passed
security_domain: endpoint
@@ -31,13 +31,29 @@ tags:
analytic_story:
- Windows Defense Evasion Tactics
- Suspicious Windows Registry Activities
automated_detection_testing: passed
confidence: 100
context:
- source:endpoint
- stage:Privilege Escalation Persistence
dataset:
- https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1548.002/LocalAccountTokenFilterPolicy/sysmon.log
impact: 80
kill_chain_phases:
- Exploitation
message: modified/added/deleted registry entry $Registry.registry_path$ in $dest$
mitre_attack_id:
- T1548.002
- T1548
observable:
- name: dest
type: Hostname
role:
- Victim
- name: user
type: user
role:
- Victim
product:
- Splunk Enterprise
- Splunk Enterprise Security
@@ -50,21 +66,5 @@ tags:
- Registry.registry_key_name
- Registry.registry_value_name
- Registry.registry_value_data
security_domain: endpoint
impact: 80
confidence: 100
risk_score: 80
context:
- source:endpoint
- stage:Privilege Escalation Persistence
message: modified/added/deleted registry entry $Registry.registry_path$ in $dest$
observable:
- name: dest
type: Hostname
role:
- Victim
- name: user
type: user
role:
- Victim
automated_detection_testing: passed
security_domain: endpoint
@@ -0,0 +1,67 @@
name: Disabling Defender Services
id: 911eacdc-317f-11ec-ad30-acde48001122
version: 1
date: '2021-10-20'
author: Teoderick Contreras, Splunk
type: TTP
datamodel:
- Endpoint
description: This particular behavior is typically executed when an adversaries or
malware gains access to an endpoint and beings to perform execution and to evade
detections. Usually, a batch (.bat) will be executed and multiple registry and scheduled
task modifications will occur. During triage, review parallel processes and identify
any further file modifications. Endpoint should be isolated.
search: '| tstats `security_content_summariesonly` count min(_time) as firstTime max(_time)
as lastTime from datamodel=Endpoint.Registry where Registry.registry_path = "*\\System\\CurrentControlSet\\Services\\*"
AND (Registry.registry_path IN("*WdBoot*", "*WdFilter*", "*WdNisDrv*", "*WdNisSvc*",
"*WinDefend*", "*SecurityHealthService*")) AND Registry.registry_value_name = Start
Registry.registry_value_data = 0x00000004 by Registry.dest Registry.user Registry.registry_path
Registry.registry_value_name Registry.registry_value_data | `drop_dm_object_name(Registry)`
| `security_content_ctime(lastTime)` | `security_content_ctime(firstTime)` | `disabling_defender_services_filter`'
how_to_implement: To successfully implement this search, you need to be ingesting
logs with the process name, parent process, and command-line executions from your
endpoints. If you are using Sysmon, you must have at least version 6.0.4 of the
Sysmon TA.
known_false_positives: admin or user may choose to disable windows defender product
references:
- https://thedfirreport.com/2021/10/18/icedid-to-xinglocker-ransomware-in-24-hours/
tags:
analytic_story:
- IceID
dataset:
- https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/malware/icedid/disable_av/sysmon2.log
kill_chain_phases:
- Exploitation
mitre_attack_id:
- T1562.001
- T1562
product:
- Splunk Enterprise
- Splunk Enterprise Security
- Splunk Cloud
required_fields:
- _time
- Registry.dest
- Registry.user
- Registry.registry_value_name
- Registry.registry_key_name
- Registry.registry_path
- Registry.registry_value_data
security_domain: endpoint
impact: 70
confidence: 70
risk_score: 49
context:
- Source:Endpoint
- Stage:Defense Evasion
message: modified/added/deleted registry entry $registry_path$ in $dest$
observable:
- name: dest
type: Hostname
role:
- Victim
- name: user
type: user
role:
- Victim
automated_detection_testing: passed
@@ -17,9 +17,9 @@ search: '| tstats `security_content_summariesonly` count min(_time) as firstTim
= 0x00000001 by Registry.dest Registry.user Registry.registry_value_name Registry.registry_key_name
Registry.registry_path Registry.registry_value_data | `security_content_ctime(lastTime)`
| `security_content_ctime(firstTime)` | `enable_wdigest_uselogoncredential_registry_filter`'
how_to_implement: To successfully implement this search, you must be ingesting
data that records registry activity from your hosts to populate the endpoint data
model in the registry node. This is typically populated via endpoint detection-and-response
how_to_implement: To successfully implement this search, you must be ingesting data
that records registry activity from your hosts to populate the endpoint data model
in the registry node. This is typically populated via endpoint detection-and-response
product, such as Carbon Black or endpoint data sources, such as Sysmon. The data
used for this search is typically generated via logs that report reads and writes
to the registry.
@@ -29,13 +29,29 @@ references:
tags:
analytic_story:
- Credential Dumping
automated_detection_testing: passed
confidence: 100
context:
- Source:Endpoint
- Stage:Credential Access
dataset:
- https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1003/wdigest_enable/sysmon.log
impact: 80
kill_chain_phases:
- Exploitation
message: wdigest registry $registry_path$ was modified in $dest$
mitre_attack_id:
- T1112
- T1003
observable:
- name: user
type: User
role:
- Victim
- name: dest
type: Hostname
role:
- Victim
product:
- Splunk Enterprise
- Splunk Enterprise Security
@@ -48,21 +64,5 @@ tags:
- Registry.registry_key_name
- Registry.registry_path
- Registry.registry_value_data
security_domain: endpoint
impact: 80
confidence: 100
risk_score: 80
context:
- Source:Endpoint
- Stage:Credential Access
message: wdigest registry $registry_path$ was modified in $dest$
observable:
- name: user
type: User
role:
- Victim
- name: dest
type: Hostname
role:
- Victim
automated_detection_testing: passed
security_domain: endpoint
+17 -17
View File
@@ -28,14 +28,30 @@ tags:
analytic_story:
- Windows Persistence Techniques
- Windows Privilege Escalation
automated_detection_testing: passed
confidence: 100
context:
- source:endpoint
- stage:Privilege Escalation Persistence
dataset:
- https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1127/etw_disable/sysmon.log
impact: 90
kill_chain_phases:
- Exploitation
message: modified/added/deleted registry entry $Registry.registry_path$ in $dest$
mitre_attack_id:
- T1562.006
- T1127
- T1562
observable:
- name: dest
type: Hostname
role:
- Victim
- name: user
type: user
role:
- Victim
product:
- Splunk Enterprise
- Splunk Enterprise Security
@@ -48,21 +64,5 @@ tags:
- Registry.registry_key_name
- Registry.registry_value_name
- Registry.registry_value_data
security_domain: endpoint
impact: 90
confidence: 100
risk_score: 90
context:
- source:endpoint
- stage:Privilege Escalation Persistence
message: modified/added/deleted registry entry $Registry.registry_path$ in $dest$
observable:
- name: dest
type: Hostname
role:
- Victim
- name: user
type: user
role:
- Victim
automated_detection_testing: passed
security_domain: endpoint
@@ -28,13 +28,29 @@ tags:
analytic_story:
- Windows Persistence Techniques
- Windows Privilege Escalation
automated_detection_testing: passed
confidence: 100
context:
- source:endpoint
- stage:Privilege Escalation Persistence
dataset:
- https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1037.001/logonscript_reg/sysmon.log
impact: 80
kill_chain_phases:
- Exploitation
message: modified/added/deleted registry entry $Registry.registry_path$ in $dest$
mitre_attack_id:
- T1037
- T1037.001
observable:
- name: dest
type: Hostname
role:
- Victim
- name: user
type: user
role:
- Victim
product:
- Splunk Enterprise
- Splunk Enterprise Security
@@ -46,21 +62,5 @@ tags:
- Registry.registry_path
- Registry.registry_key_name
- Registry.registry_value_name
security_domain: endpoint
impact: 80
confidence: 100
risk_score: 80
context:
- source:endpoint
- stage:Privilege Escalation Persistence
message: modified/added/deleted registry entry $Registry.registry_path$ in $dest$
observable:
- name: dest
type: Hostname
role:
- Victim
- name: user
type: user
role:
- Victim
automated_detection_testing: passed
security_domain: endpoint
@@ -46,13 +46,30 @@ tags:
analytic_story:
- Suspicious Regsvr32 Activity
- Remcos
automated_detection_testing: passed
confidence: 100
context:
- Source:Endpoint
- Stage:Defense Evasion
dataset:
- https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/malware/remcos/remcos/windows-sysmon.log
impact: 80
kill_chain_phases:
- Exploitation
message: The $process_name$ was identified on endpoint $dest$ modifying the registry
with a known malicious clsid under InProcServer32.
mitre_attack_id:
- T1218.010
- T1112
observable:
- name: dest
type: Hostname
role:
- Victim
- name: process_name
type: Process
role:
- Child Process
product:
- Splunk Enterprise
- Splunk Enterprise Security
@@ -65,22 +82,5 @@ tags:
- registry_key_name
- registry_value_name
- user
security_domain: endpoint
impact: 80
confidence: 100
risk_score: 80
context:
- Source:Endpoint
- Stage:Defense Evasion
message: The $process_name$ was identified on endpoint $dest$ modifying the registry
with a known malicious clsid under InProcServer32.
observable:
- name: dest
type: Hostname
role:
- Victim
- name: process_name
type: Process
role:
- Child Process
automated_detection_testing: passed
security_domain: endpoint
@@ -5,18 +5,22 @@ date: '2021-10-05'
author: David Dorsey, Michael Haag Splunk
type: Hunting
datamodel:
- Endpoint
description: 'The following hunting analytic identifies PowerShell commands utilizing the WindowStyle parameter to hide the window on the compromised endpoint. This combination of command-line options is suspicious because it is overriding the default PowerShell execution policy, attempts to hide its activity from the user, and connects to the Internet.
Removed in this version of the query is New-Object.
The analytic identifies all variations of WindowStyle, as PowerShell allows the ability to shorten the parameter. For example w, win, windowsty and so forth. In addition, through our research it was identified that PowerShell will interpret different command switch types beyond the hyphen. We have added endash, emdash, horizontal bar, and forward slash.'
search: '| tstats `security_content_summariesonly` count min(_time) as firstTime max(_time)
as lastTime from datamodel=Endpoint.Processes where `process_powershell` by Processes.user
Processes.process_name Processes.process Processes.parent_process_name Processes.original_file_name Processes.dest Processes.process_id
| `drop_dm_object_name(Processes)`
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| where match(process,"(?i)[\-|\/||—|―]w(in*d*o*w*s*t*y*l*e*)*\s+[^-]")
| `malicious_powershell_process___connect_to_internet_with_hidden_window_filter`'
- Endpoint
description: The following hunting analytic identifies PowerShell commands utilizing
the WindowStyle parameter to hide the window on the compromised endpoint. This combination
of command-line options is suspicious because it is overriding the default PowerShell
execution policy, attempts to hide its activity from the user, and connects to the
Internet. Removed in this version of the query is New-Object. The analytic identifies
all variations of WindowStyle, as PowerShell allows the ability to shorten the parameter.
For example w, win, windowsty and so forth. In addition, through our research it
was identified that PowerShell will interpret different command switch types beyond
the hyphen. We have added endash, emdash, horizontal bar, and forward slash.
search: "| tstats `security_content_summariesonly` count min(_time) as firstTime max(_time)\
\ as lastTime from datamodel=Endpoint.Processes where `process_powershell` by Processes.user\
\ Processes.process_name Processes.process Processes.parent_process_name Processes.original_file_name\
\ Processes.dest Processes.process_id | `drop_dm_object_name(Processes)` | `security_content_ctime(firstTime)`\
\ | `security_content_ctime(lastTime)` | where match(process,\"(?i)[\\-|\\/|\u2013\
|\u2014|\u2015]w(in*d*o*w*s*t*y*l*e*)*\\s+[^-]\") | `malicious_powershell_process___connect_to_internet_with_hidden_window_filter`"
how_to_implement: You must be ingesting data that records process activity from your
hosts to populate the Endpoint data model in the Processes node. You must also be
ingesting logs with both the process name and command line from your endpoints.
@@ -24,11 +28,11 @@ how_to_implement: You must be ingesting data that records process activity from
model.
known_false_positives: Legitimate process can have this combination of command-line
options, but it's not common.
references:
- https://regexr.com/663rr
- https://github.com/redcanaryco/AtomicTestHarnesses/blob/master/TestHarnesses/T1059.001_PowerShell/OutPowerShellCommandLineParameter.ps1
- https://ss64.com/ps/powershell.html
- https://twitter.com/M_haggis/status/1440758396534214658?s=20
references:
- https://regexr.com/663rr
- https://github.com/redcanaryco/AtomicTestHarnesses/blob/master/TestHarnesses/T1059.001_PowerShell/OutPowerShellCommandLineParameter.ps1
- https://ss64.com/ps/powershell.html
- https://twitter.com/M_haggis/status/1440758396534214658?s=20
tags:
analytic_story:
- Malicious PowerShell
@@ -86,4 +90,4 @@ tags:
- Processes.parent_process_name
- Processes.dest
risk_score: 81
security_domain: endpoint
security_domain: endpoint
@@ -5,29 +5,38 @@ date: '2021-10-05'
author: David Dorsey, Michael Haag, Splunk
type: Hunting
datamodel:
- Endpoint
description: 'The following analytic identifies the use of the EncodedCommand PowerShell parameter. This is typically used by Administrators to run complex scripts, but commonly used by adversaries to hide their code. \
The analytic identifies all variations of EncodedCommand, as PowerShell allows the ability to shorten the parameter. For example enc, enco, encod and so forth. In addition, through our research it was identified that PowerShell will interpret different command switch types beyond the hyphen. We have added endash, emdash, horizontal bar, and forward slash. \
During triage, review parallel events to determine legitimacy. Tune as needed based on admin scripts in use. \
- Endpoint
description: 'The following analytic identifies the use of the EncodedCommand PowerShell
parameter. This is typically used by Administrators to run complex scripts, but
commonly used by adversaries to hide their code. \
The analytic identifies all variations of EncodedCommand, as PowerShell allows the
ability to shorten the parameter. For example enc, enco, encod and so forth. In
addition, through our research it was identified that PowerShell will interpret
different command switch types beyond the hyphen. We have added endash, emdash,
horizontal bar, and forward slash. \
During triage, review parallel events to determine legitimacy. Tune as needed based
on admin scripts in use. \
Alternatively, may use regex per matching here https://regexr.com/662ov.'
search: '| tstats `security_content_summariesonly` count min(_time) as firstTime max(_time)
as lastTime from datamodel=Endpoint.Processes where `process_powershell` by Processes.user
Processes.process_name Processes.process Processes.parent_process_name Processes.original_file_name Processes.dest Processes.process_id
| `drop_dm_object_name(Processes)`
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| where match(process,"(?i)[\-|\/||—|―]e(nc*o*d*e*d*c*o*m*m*a*n*d*)*\s+[^-]")
| `malicious_powershell_process___encoded_command_filter`'
how_to_implement: To successfully implement this search you need to be ingesting information on process that include the name of the process responsible for the changes from your endpoints into the `Endpoint` datamodel in the `Processes` node. In addition, confirm the latest CIM App 4.20 or higher is installed and the latest TA for the endpoint product.
search: "| tstats `security_content_summariesonly` count min(_time) as firstTime max(_time)\
\ as lastTime from datamodel=Endpoint.Processes where `process_powershell` by Processes.user\
\ Processes.process_name Processes.process Processes.parent_process_name Processes.original_file_name\
\ Processes.dest Processes.process_id | `drop_dm_object_name(Processes)` | `security_content_ctime(firstTime)`\
\ | `security_content_ctime(lastTime)` | where match(process,\"(?i)[\\-|\\/|\u2013\
|\u2014|\u2015]e(nc*o*d*e*d*c*o*m*m*a*n*d*)*\\s+[^-]\") | `malicious_powershell_process___encoded_command_filter`"
how_to_implement: To successfully implement this search you need to be ingesting information
on process that include the name of the process responsible for the changes from
your endpoints into the `Endpoint` datamodel in the `Processes` node. In addition,
confirm the latest CIM App 4.20 or higher is installed and the latest TA for the
endpoint product.
known_false_positives: System administrators may use this option, but it's not common.
references:
- https://regexr.com/662ov
- https://github.com/redcanaryco/AtomicTestHarnesses/blob/master/TestHarnesses/T1059.001_PowerShell/OutPowerShellCommandLineParameter.ps1
- https://ss64.com/ps/powershell.html
- https://twitter.com/M_haggis/status/1440758396534214658?s=20
- https://regexr.com/662ov
- https://github.com/redcanaryco/AtomicTestHarnesses/blob/master/TestHarnesses/T1059.001_PowerShell/OutPowerShellCommandLineParameter.ps1
- https://ss64.com/ps/powershell.html
- https://twitter.com/M_haggis/status/1440758396534214658?s=20
tags:
analytic_story:
- Malicious PowerShell
@@ -75,4 +84,4 @@ tags:
- Processes.dest
- Processes.process_id
risk_score: 35
security_domain: endpoint
security_domain: endpoint
@@ -6,12 +6,12 @@ author: Teoderick Contreras, Splunk
type: TTP
datamodel:
- Endpoint
description: This analytic is to detect a suspicious child process of MSBuild
spawned by Windows Script Host - cscript or wscript.
This behavior or event are commonly seen and used by malware or adversaries
to execute malicious msbuild process using malicious script in the compromised host.
During triage, review parallel processes and identify any file modifications. MSBuild
may load a script from the same path without having command-line arguments.
description: This analytic is to detect a suspicious child process of MSBuild spawned
by Windows Script Host - cscript or wscript. This behavior or event are commonly
seen and used by malware or adversaries to execute malicious msbuild process using
malicious script in the compromised host. During triage, review parallel processes
and identify any file modifications. MSBuild may load a script from the same path
without having command-line arguments.
search: '| tstats `security_content_summariesonly` count values(Processes.process_name)
as process_name values(Processes.process) as process min(_time) as firstTime max(_time)
as lastTime from datamodel=Endpoint.Processes where Processes.parent_process_name
@@ -19,20 +19,42 @@ search: '| tstats `security_content_summariesonly` count values(Processes.proces
Processes.parent_process_name Processes.process_name Processes.original_file_name
Processes.user | `drop_dm_object_name(Processes)` | `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)` | `msbuild_suspicious_spawned_by_script_process_filter`'
how_to_implement: To successfully implement this search you need to be ingesting information on process that include the name of the process responsible for the changes from your endpoints into the `Endpoint` datamodel in the `Processes` node. In addition, confirm the latest CIM App 4.20 or higher is installed and the latest TA for the endpoint product.
known_false_positives: False positives should be limited as developers do not spawn MSBuild via a WSH.
how_to_implement: To successfully implement this search you need to be ingesting information
on process that include the name of the process responsible for the changes from
your endpoints into the `Endpoint` datamodel in the `Processes` node. In addition,
confirm the latest CIM App 4.20 or higher is installed and the latest TA for the
endpoint product.
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/#
tags:
analytic_story:
- Trusted Developer Utilities Proxy Execution MSBuild
automated_detection_testing: passed
confidence: 70
context:
- Stage:Execution
- Stage:Defense Evasion
dataset:
- https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1127.001/regsvr32_silent/sysmon.log
impact: 70
kill_chain_phases:
- Exploitation
message: Msbuild.exe process spawned by $parent_process_name$ on $dest$ executed
by $user$
mitre_attack_id:
- T1127.001
- T1127
observable:
- name: dest
type: Endpoint
role:
- Victim
- name: User
type: User
role:
- Victim
product:
- Splunk Enterprise
- Splunk Enterprise Security
@@ -45,22 +67,5 @@ tags:
- Processes.process_name
- Processes.original_file_name
- Processes.user
security_domain: endpoint
impact: 70
confidence: 70
risk_score: 49
context:
- Stage:Execution
- Stage:Defense Evasion
message: Msbuild.exe process spawned by $parent_process_name$ on $dest$ executed
by $user$
observable:
- name: dest
type: Endpoint
role:
- Victim
- name: User
type: User
role:
- Victim
automated_detection_testing: passed
security_domain: endpoint
@@ -33,6 +33,8 @@ tags:
context:
- Source:Endpoint
- Stage:Defense Evasion
cve:
- CVE-2021-40444
dataset:
- https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1566.001/macro/windows-sysmon_mshtml.log
impact: 80
@@ -69,5 +71,3 @@ tags:
- dest
risk_score: 80
security_domain: endpoint
cve:
- CVE-2021-40444
@@ -41,6 +41,8 @@ tags:
context:
- Source:Endpoint
- Stage:Defense Evasion
cve:
- CVE-2021-40444
dataset:
- https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1566.001/macro/windows-sysmon_cabinf.log
impact: 80
@@ -74,5 +76,3 @@ tags:
- file_path
risk_score: 80
security_domain: endpoint
cve:
- CVE-2021-40444
@@ -42,6 +42,8 @@ tags:
context:
- Source:Endpoint
- Stage:Defense Evasion
cve:
- CVE-2021-40444
dataset:
- https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1566.001/macro/windows-sysmon_control.log
impact: 80
@@ -83,5 +85,3 @@ tags:
- Processes.parent_process_id
risk_score: 80
security_domain: endpoint
cve:
- CVE-2021-40444
@@ -39,6 +39,8 @@ tags:
context:
- Source:Endpoint
- Stage:Credential Access
cve:
- CVE-2021-36942
dataset:
- https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1187/petitpotam/windows-security.log
impact: 80
@@ -68,5 +70,3 @@ tags:
- Message
risk_score: 56
security_domain: endpoint
cve:
- CVE-2021-36942
@@ -33,6 +33,8 @@ tags:
context:
- Source:Endpoint
- Stage:Credential Access
cve:
- CVE-2021-36942
dataset:
- https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1187/petitpotam/windows-security.log
impact: 80
@@ -61,5 +63,3 @@ tags:
- Message
risk_score: 56
security_domain: endpoint
cve:
- CVE-2021-36942
@@ -42,6 +42,9 @@ tags:
- Stage:Privilege Escalation
- Stage:Defense Evasion
- Scope:Incoming
cve:
- CVE-2021-34527
- CVE-2021-1675
dataset:
- https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1547.012/printnightmare/windows-printservice_operational.log
impact: 80
@@ -68,6 +71,3 @@ tags:
- Message
risk_score: 72
security_domain: endpoint
cve:
- CVE-2021-34527
- CVE-2021-1675
@@ -40,6 +40,9 @@ tags:
- Stage:Privilege Escalation
- Stage:Defense Evasion
- Scope:Incoming
cve:
- CVE-2021-34527
- CVE-2021-1675
dataset: []
impact: 80
kill_chain_phases:
@@ -66,6 +69,3 @@ tags:
- Message
risk_score: 72
security_domain: endpoint
cve:
- CVE-2021-34527
- CVE-2021-1675
@@ -32,7 +32,8 @@ how_to_implement: To successfully implement this search you need to be ingesting
latest TA for the endpoint product.
known_false_positives: False positives should be limited, however it is possible to
filter by Processes.process_name and specific processes (ex. wscript.exe). Filter
as needed. This may need modification based on EDR telemetry and how it brings in registry data. For example, removal of (Default).
as needed. This may need modification based on EDR telemetry and how it brings in
registry data. For example, removal of (Default).
references:
- https://blog.f-secure.com/hunting-for-koadic-a-com-based-rootkit/
- https://www.script-coding.com/dynwrapx_eng.html
@@ -42,34 +43,21 @@ references:
tags:
analytic_story:
- Remcos
dataset:
- https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/malware/remcos/remcos/windows-sysmon.log
kill_chain_phases:
- Exploitation
mitre_attack_id:
- T1059
- T1559.001
product:
- Splunk Enterprise
- Splunk Enterprise Security
- Splunk Cloud
required_fields:
- _time
- dest
- process_name
- process_guid
- file_name
- file_path
- file_create_time user
security_domain: endpoint
impact: 80
automated_detection_testing: passed
confidence: 100
risk_score: 80
context:
- Source:Endpoint
- Stage:Defense Evasion
dataset:
- https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/malware/remcos/remcos/windows-sysmon.log
impact: 80
kill_chain_phases:
- Exploitation
message: An instance of $process_name$ was identified on endpoint $dest$ downloading
the DynamicWrapperX dll.
mitre_attack_id:
- T1059
- T1559.001
observable:
- name: user
type: User
@@ -83,4 +71,17 @@ tags:
type: Process
role:
- Child Process
automated_detection_testing: passed
product:
- Splunk Enterprise
- Splunk Enterprise Security
- Splunk Cloud
required_fields:
- _time
- dest
- process_name
- process_guid
- file_name
- file_path
- file_create_time user
risk_score: 80
security_domain: endpoint
@@ -11,14 +11,13 @@ description: The search looks for modifications to registry keys that can be use
search: '| tstats `security_content_summariesonly` count values(Registry.registry_key_name)
as registry_key_name values(Registry.registry_path) as registry_path min(_time)
as firstTime max(_time) as lastTime FROM datamodel=Endpoint.Registry where (Registry.registry_path=*\\currentversion\\run*
OR Registry.registry_path=*\\currentVersion\\Windows\\Appinit_Dlls* OR Registry.registry_path=*\\CurrentVersion\\Winlogon\\Shell*
OR Registry.registry_path=*\\CurrentVersion\\Winlogon\\Notify*
OR Registry.registry_path=*\\CurrentVersion\\Winlogon\\Userinit* OR Registry.registry_path=*\\CurrentVersion\\Winlogon\\VmApplet*
OR Registry.registry_path=*\\currentversion\\policies\\explorer\\run* OR Registry.registry_path=*\\currentversion\\runservices*
OR Registry.registry_path=HKLM\\SOFTWARE\\Microsoft\\Netsh\\* OR (Registry.registry_path="*Microsoft\\Windows
NT\\CurrentVersion\\Image File Execution Options*" AND Registry.registry_key_name=Debugger)
OR (Registry.registry_path="*\\CurrentControlSet\\Control\\Lsa" AND Registry.registry_key_name="Security
Packages") OR (Registry.registry_path="*\\CurrentControlSet\\Control\\Lsa\\OSConfig"
OR Registry.registry_path=*\\currentVersion\\Windows\\Appinit_Dlls* OR Registry.registry_path=*\\CurrentVersion\\Winlogon\\Shell*
OR Registry.registry_path=*\\CurrentVersion\\Winlogon\\Notify* OR Registry.registry_path=*\\CurrentVersion\\Winlogon\\Userinit*
OR Registry.registry_path=*\\CurrentVersion\\Winlogon\\VmApplet* OR Registry.registry_path=*\\currentversion\\policies\\explorer\\run*
OR Registry.registry_path=*\\currentversion\\runservices* OR Registry.registry_path=HKLM\\SOFTWARE\\Microsoft\\Netsh\\*
OR (Registry.registry_path="*Microsoft\\Windows NT\\CurrentVersion\\Image File Execution
Options*" AND Registry.registry_key_name=Debugger) OR (Registry.registry_path="*\\CurrentControlSet\\Control\\Lsa"
AND Registry.registry_key_name="Security Packages") OR (Registry.registry_path="*\\CurrentControlSet\\Control\\Lsa\\OSConfig"
AND Registry.registry_key_name="Security Packages") OR (Registry.registry_path="*\\Microsoft\\Windows
NT\\CurrentVersion\\SilentProcessExit\\*") OR (Registry.registry_path="*currentVersion\\Windows"
AND Registry.registry_key_name="Load") OR (Registry.registry_path="*\\CurrentVersion"

Some files were not shown because too many files have changed in this diff Show More