mirror of
https://github.com/splunk/security_content
synced 2026-06-08 17:32:49 +00:00
Merge branch 'develop' into dev_sec_ops_package
This commit is contained in:
@@ -0,0 +1,275 @@
|
||||
#This file makes use of a number of useful, external Github Actions.
|
||||
#Check the links below for additional documentation on each of these:
|
||||
#https://github.com/actions/setup-python
|
||||
#https://github.com/actions/setup-node
|
||||
#https://github.com/actions/checkout
|
||||
#https://github.com/actions/upload-artifact
|
||||
|
||||
#The mechanism for persisting data between jobs in a workflow is the same as for persisting it
|
||||
#permanently:
|
||||
#https://docs.github.com/en/actions/guides/storing-workflow-data-as-artifacts
|
||||
#In CircleCI, this was different (store_artifacts vs persist_to_workspace)
|
||||
|
||||
|
||||
|
||||
name: build-and-validate
|
||||
on: [push, pull_request]
|
||||
jobs:
|
||||
validate-tag-if-present:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
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
|
||||
if [[ $GITHUB_REF =~ refs/tags/* ]]; then
|
||||
#Yes, this is a tag, so we need to test to make sure that the tag
|
||||
#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
|
||||
else
|
||||
echo "FAIL: Tagged release with bad format"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "PASS: Not a tagged release"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
validate-content:
|
||||
#Note that the CircleCI job used a Container. The way to do this with Github Actions
|
||||
#is to first start up a Virtual Machine, then we can by following:
|
||||
# https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idcontainer
|
||||
runs-on: ubuntu-latest
|
||||
needs: [validate-tag-if-present]
|
||||
steps:
|
||||
#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
|
||||
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:
|
||||
python-version: '3.9' #Available versions here - https://github.com/actions/python-versions/releases easy to change/make a matrix/use pypy
|
||||
architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified
|
||||
|
||||
|
||||
#TODO: CircleCI restore_cache equivalent
|
||||
|
||||
#don't need to install python3 or python3-dev since it was handled by the action above?
|
||||
#Also, no support for YAML anchors/aliases in Github Actions...
|
||||
- name: Install System Packages
|
||||
run: |
|
||||
sudo apt update -qq
|
||||
sudo apt install jq -qq
|
||||
#TODO: CircleCI save_cache equivalent
|
||||
|
||||
- name: Install Python Dependencies
|
||||
run: |
|
||||
#Get the virtualenv set up
|
||||
rm -rf venv
|
||||
python3 -m venv --clear venv
|
||||
source venv/bin/activate
|
||||
python3 -m pip install -q -r requirements.txt
|
||||
|
||||
|
||||
- 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
|
||||
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
|
||||
with:
|
||||
node-version: '14' #can easily be changed to a different version
|
||||
- name: Generate documentation
|
||||
run: |
|
||||
ls -lah
|
||||
|
||||
#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
|
||||
steps:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install System Packages
|
||||
run: |
|
||||
sudo apt update -qq
|
||||
sudo apt install jq -qq
|
||||
|
||||
- name: Install Python Dependencies
|
||||
run: |
|
||||
#Get the virtualenv set up
|
||||
rm -rf venv
|
||||
python3 -m venv --clear venv
|
||||
source venv/bin/activate
|
||||
python3 -m pip install -q -r requirements.txt
|
||||
|
||||
- name: Run Generate
|
||||
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
|
||||
#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
|
||||
|
||||
- name: Copy lookups .csv files
|
||||
run: |
|
||||
# clean up current lookups
|
||||
rm -rf dist/escu/lookups
|
||||
rm -rf dist/saaws/lookups
|
||||
mkdir dist/escu/lookups
|
||||
mkdir dist/saaws/lookups
|
||||
#copy over lookups
|
||||
cd lookups
|
||||
cp -rv *.csv ../dist/escu/lookups
|
||||
cp -rv *.csv ../dist/saaws/lookups
|
||||
|
||||
#Tag is '' for non-tagged push and the tag name for a tagged release
|
||||
- name: Set tag
|
||||
id: vars
|
||||
run: |
|
||||
if [ echo ${GITHUB_REF} | grep "^refs/tags/*" ]; then
|
||||
#failed to find the refs/tags/ beginning, grab and set the tag
|
||||
echo "::set-output name=tag::${GITHUB_REF#refs/tags/}"
|
||||
else
|
||||
#Not a tagged relese
|
||||
echo "::set-output name=tag::"
|
||||
fi
|
||||
|
||||
- name: Update Version and Build number
|
||||
run : |
|
||||
# check if tag is set, get build number from the tag if set
|
||||
if [ -z "${{ steps.vars.outputs.tag }}" ]; then
|
||||
CONTENT_VERSION=$(grep -oP "(\d+.\d+.\d+$)" dist/escu/default/content-version.conf)
|
||||
echo "detected content version: $CONTENT_VERSION"
|
||||
else
|
||||
CONTENT_VERSION=$(echo ${{ steps.vars.outputs.tag }} | grep -oP "\d+.\d+.\d+")
|
||||
echo "content version: $CONTENT_VERSION, set by tag: ${{ steps.vars.outputs.tag }}"
|
||||
fi
|
||||
# update build number and version for ESCU
|
||||
sed -i "s/build = .*$/build = ${{ github.run_number }}/g" dist/escu/default/app.conf
|
||||
sed -i "s/^version = .*$/version = $CONTENT_VERSION/g" dist/escu/default/app.conf
|
||||
sed -i "s/\"version\": .*$/\"version\": \"$CONTENT_VERSION\"/g" dist/escu/app.manifest
|
||||
sed -i "s/version = .*$/version = $CONTENT_VERSION/g" dist/escu/default/content-version.conf
|
||||
tar -czf content-pack-build-escu.tar.gz dist/escu/*
|
||||
# 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
|
||||
sed -i "s/\"version\": .*$/\"version\": \"$CONTENT_VERSION\"/g" dist/saaws/app.manifest
|
||||
sed -i "s/version = .*$/version = $CONTENT_VERSION/g" dist/saaws/default/content-version.conf
|
||||
tar -czf content-pack-build-saaws.tar.gz dist/saaws/*
|
||||
|
||||
- name: Persist to Workspace
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: content-pack-build
|
||||
path: |
|
||||
content-pack-build-escu.tar.gz
|
||||
content-pack-build-saaws.tar.gz
|
||||
|
||||
|
||||
build-package:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [validate-content, build-sources]
|
||||
|
||||
steps:
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: content-pack-build
|
||||
path: build/
|
||||
|
||||
#This explicitly uses a different version of python (2.7)
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '2.7' #Available versions here - https://github.com/actions/python-versions/releases easy to change/make a matrix/use pypy
|
||||
architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified
|
||||
|
||||
- name: Get virtualenv for Python 2.7
|
||||
run: |
|
||||
sudo apt install virtualenv
|
||||
|
||||
- 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
|
||||
tar -zxf splunk-packaging-toolkit-latest.tar.gz -C slim-latest --strip-components=1
|
||||
|
||||
- name: Install Splunk Packaging Toolkit (slim)
|
||||
run: |
|
||||
cd slim-latest
|
||||
virtualenv --python=/usr/bin/python2.7 --clear venv
|
||||
source venv/bin/activate
|
||||
python -m pip install semantic_version
|
||||
python -m pip install .
|
||||
- name: Create a .spl for this Build Using Slim
|
||||
run: |
|
||||
source slim-latest/venv/bin/activate
|
||||
cd build
|
||||
tar -zxf content-pack-build-escu.tar.gz
|
||||
tar -zxf content-pack-build-saaws.tar.gz
|
||||
mv dist/escu DA-ESS-ContentUpdate
|
||||
mv dist/saaws DA-ESS_AmazonWebServices_Content
|
||||
slim package -o upload DA-ESS-ContentUpdate
|
||||
slim package -o upload DA-ESS_AmazonWebServices_Content
|
||||
|
||||
cp upload/DA-ESS-ContentUpdate-*.tar.gz DA-ESS-ContentUpdate-latest.tar.gz
|
||||
sha256sum DA-ESS-ContentUpdate-latest.tar.gz > checksum.txt
|
||||
|
||||
cp upload/DA-ESS_AmazonWebServices_Content-*tar.gz DA-ESS_AmazonWebServices_Content-latest.tar.gz
|
||||
sha256sum DA-ESS_AmazonWebServices_Content-latest.tar.gz >> checksum.txt
|
||||
|
||||
touch tag-canary.txt
|
||||
- name: store_artifacts
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: package
|
||||
path: |
|
||||
build/upload
|
||||
- name: store_artifacts_two
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: content-latest
|
||||
path: |
|
||||
build/DA-ESS-ContentUpdate-latest.tar.gz
|
||||
build/DA-ESS_AmazonWebServices_Content-latest.tar.gz
|
||||
build/checksum.txt
|
||||
|
||||
#Store the tag to indicate that this was a tagged build
|
||||
- name: store_artifacts_three
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: tag-canary
|
||||
path: |
|
||||
build/tag-canary.txt
|
||||
@@ -31,7 +31,7 @@ jobs:
|
||||
environment: Detection-Testing-Approval
|
||||
needs: [validate-tag-if-present]
|
||||
#Only run when tagged
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
if: startsWith(github.ref, 'refs/heads/')
|
||||
steps:
|
||||
|
||||
- name: Checkout Repo
|
||||
|
||||
@@ -0,0 +1,398 @@
|
||||
name: release-checks
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: ["validate-and-build"]
|
||||
types:
|
||||
- completed
|
||||
|
||||
|
||||
|
||||
jobs:
|
||||
|
||||
#Check that the validate-and-build workflow succeeded
|
||||
check-validate-and-build-success:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- if: github.event.workflow_run.conclusion != 'success'
|
||||
name: Abort if failed
|
||||
run: |
|
||||
echo "FAIL: validate-and-build.yml DID NOT run successfully. Terminating..."
|
||||
exit 1
|
||||
- name: Print Success
|
||||
run: |
|
||||
echo "SUCCESS: validate-and-build.yml ran successfully. Continue"
|
||||
exit 0
|
||||
|
||||
|
||||
#Enusre that we are running on a tag. There is no good way to see if this was
|
||||
#triggered from a tag/release, so we use the creation of an aritifact in the
|
||||
#validate-and-build workflow to represent it
|
||||
verify-tag:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [check-validate-and-build-success]
|
||||
steps:
|
||||
- name: Try to get the canary
|
||||
uses: dawidd6/action-download-artifact@v2
|
||||
with:
|
||||
github_token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
workflow: ${{ github.event.workflow_run.workflow_id }}
|
||||
#workflow: validate-and-build.yml
|
||||
#run_id: ${{ github.event.workflow_run.id }}
|
||||
name: tag-canary
|
||||
path: canary
|
||||
- name: Check for existence of canary
|
||||
run: |
|
||||
#If this file does not exist, then cat will return a nonzero status (failure)
|
||||
#and the entire workflow will fail
|
||||
cat canary/tag-canary.txt
|
||||
|
||||
run-appinspect:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [check-validate-and-build-success, verify-tag]
|
||||
#Only run when tagged
|
||||
steps:
|
||||
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
ref: 'develop'
|
||||
|
||||
#Download the artifacts we want to check
|
||||
- name: Restore Content-Pack Artifacts for AppInspect testing
|
||||
uses: dawidd6/action-download-artifact@v2
|
||||
with:
|
||||
workflow: validate-and-build.yml
|
||||
workflow_conclusion: success
|
||||
run_id: ${{ github.event.workflow_run.id }}
|
||||
name: content-latest
|
||||
path: build/
|
||||
|
||||
|
||||
|
||||
- name: Install System Packages
|
||||
run: |
|
||||
sudo apt update -qq
|
||||
sudo apt install jq -qq
|
||||
|
||||
|
||||
|
||||
- name: Submit ESCU Package to AppInspect API
|
||||
env:
|
||||
APPINSPECT_USERNAME: ${{ secrets.AppInspectUsername }}
|
||||
APPINSPECT_PASSWORD: ${{ secrets.AppInspectPassword }}
|
||||
run: |
|
||||
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"
|
||||
|
||||
- name: Submit SAAWS Package to AppInspect API
|
||||
env:
|
||||
APPINSPECT_USERNAME: ${{ secrets.AppInspectUsername }}
|
||||
APPINSPECT_PASSWORD: ${{ secrets.AppInspectPassword }}
|
||||
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
|
||||
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
|
||||
if: failure()
|
||||
with:
|
||||
name: appinspect_reports_failure
|
||||
path: |
|
||||
report.tar.gz
|
||||
|
||||
create-report:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [check-validate-and-build-success, verify-tag, run-appinspect]
|
||||
#Only run when tagged
|
||||
steps:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
ref: 'develop'
|
||||
|
||||
|
||||
- name: Install System Packages
|
||||
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
|
||||
architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified
|
||||
|
||||
- name: Install Python Dependencies
|
||||
run: |
|
||||
#Get the virtualenv set up
|
||||
rm -rf venv
|
||||
python3 -m venv --clear venv
|
||||
source venv/bin/activate
|
||||
python3 -m pip install -q -r requirements.txt
|
||||
|
||||
- name: run reporting
|
||||
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:
|
||||
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...
|
||||
|
||||
- name: Upload Reporting
|
||||
run: |
|
||||
aws s3 cp bin/reporting s3://security-content-testing/reporting --recursive --exclude "*" --include "*.svg"
|
||||
|
||||
update-sources-github:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [check-validate-and-build-success, verify-tag, run-appinspect, create-report]
|
||||
#Only run when tagged
|
||||
steps:
|
||||
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
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
|
||||
architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified
|
||||
|
||||
|
||||
- uses: dawidd6/action-download-artifact@v2
|
||||
with:
|
||||
workflow: validate-and-build.yml
|
||||
workflow_conclusion: success
|
||||
run_id: ${{ github.event.workflow_run.id }}
|
||||
path: .
|
||||
name: content-latest
|
||||
|
||||
- name: Stage artifacts in proper directories
|
||||
run: |
|
||||
mkdir latest-escu
|
||||
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
|
||||
- name: Install Python Dependencies
|
||||
run: |
|
||||
#Get the virtualenv set up
|
||||
rm -rf venv
|
||||
python3 -m venv --clear venv
|
||||
source venv/bin/activate
|
||||
python3 -m pip install -q -r requirements.txt
|
||||
|
||||
- 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/"
|
||||
|
||||
- name: Get branch and PR required for detection testing main.py
|
||||
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
|
||||
run: |
|
||||
source venv/bin/activate
|
||||
python3 bin/pretty_yaml.py --path . -v
|
||||
|
||||
- name: Run generate-actors-map
|
||||
run: |
|
||||
source venv/bin/activate
|
||||
python3 bin/generate-actors-map.py --projects_path . --output docs/mitre-map/
|
||||
|
||||
- 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
|
||||
# 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
|
||||
git add dist/*
|
||||
git add docs/*
|
||||
git add detections/*
|
||||
git commit --allow-empty -m "updating docs and package bits [ci skip]"
|
||||
# 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
|
||||
#They recommend several and we use the following with the most stars: https://github.com/softprops/action-gh-release
|
||||
runs-on: ubuntu-latest
|
||||
needs: [check-validate-and-build-success, verify-tag, run-appinspect, create-report, update-sources-github]
|
||||
#Only run when tagged
|
||||
|
||||
steps:
|
||||
|
||||
#Get the artifacts that we need
|
||||
- uses: dawidd6/action-download-artifact@v2
|
||||
with:
|
||||
workflow: validate-and-build.yml
|
||||
workflow_conclusion: success
|
||||
run_id: ${{ github.event.workflow_run.id }}
|
||||
path: .
|
||||
name: content-latest
|
||||
- uses: dawidd6/action-download-artifact@v2
|
||||
with:
|
||||
workflow: validate-and-build.yml
|
||||
workflow_conclusion: success
|
||||
run_id: ${{ github.event.workflow_run.id }}
|
||||
path: .
|
||||
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
|
||||
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
|
||||
|
||||
#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
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
files: |
|
||||
DA-ESS-ContentUpdate-${{ steps.vars.outputs.tag }}.tar.gz
|
||||
DA-ESS_AmazonWebServices_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: [check-validate-and-build-success, verify-tag, run-appinspect, create-report, update-sources-github, publish-github-release]
|
||||
#Only run when tagged
|
||||
steps:
|
||||
|
||||
- uses: dawidd6/action-download-artifact@v2
|
||||
with:
|
||||
workflow: validate-and-build.yml
|
||||
workflow_conclusion: success
|
||||
run_id: ${{ github.event.workflow_run.id }}
|
||||
path: .
|
||||
name: content-latest
|
||||
|
||||
#Official, Verified Amazon-AWS Github Account Provided Action
|
||||
- uses: aws-actions/configure-aws-credentials@v1
|
||||
with:
|
||||
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...
|
||||
|
||||
- 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-testing/
|
||||
# make the file public since it is not by default
|
||||
aws s3api put-object-acl --bucket attack-range-appbinaries-testing --key DA-ESS-ContentUpdate-latest.tar.gz --acl public-read
|
||||
|
||||
master-api-update:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [check-validate-and-build-success, verify-tag, run-appinspect, create-report, update-sources-github, publish-github-release, attack-range-update]
|
||||
#Only run when tagged
|
||||
steps:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
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
|
||||
architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified
|
||||
|
||||
- name: Install Python Dependencies
|
||||
run: |
|
||||
#Get the virtualenv set up
|
||||
rm -rf venv
|
||||
python3 -m venv --clear venv
|
||||
source venv/bin/activate
|
||||
python3 -m pip install -q -r requirements.txt
|
||||
|
||||
- name: Create Baseline Folder
|
||||
run: |
|
||||
source venv/bin/activate
|
||||
python3 bin/create_baseline_folder.py
|
||||
|
||||
#Official, Verified Amazon-AWS Github Account Provided Action
|
||||
- uses: aws-actions/configure-aws-credentials@v1
|
||||
with:
|
||||
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...
|
||||
|
||||
- name: Update API sources
|
||||
run: |
|
||||
aws s3 rm s3://security-content-testing --recursive --exclude "*" --include "*.yml"
|
||||
aws s3 cp stories s3://security-content-testing/stories --recursive --exclude "*" --include "*.yml"
|
||||
aws s3 cp baselines s3://security-content-testing/baselines --recursive --exclude "*" --include "*.yml"
|
||||
aws s3 cp detections s3://security-content-testing/detections --recursive --exclude "*" --include "*.yml"
|
||||
aws s3 cp response_tasks s3://security-content-testing/response_tasks --recursive --exclude "*" --include "*.yml"
|
||||
aws s3 cp responses s3://security-content-testing/responses --recursive --exclude "*" --include "*.yml"
|
||||
aws s3 cp lookups s3://security-content-testing/lookups --recursive --exclude "*" --include "*.yml"
|
||||
aws s3 cp lookups s3://security-content-testing/lookups --recursive --exclude "*" --include "*.csv"
|
||||
aws s3 cp macros s3://security-content-testing/macros --recursive --exclude "*" --include "*.yml"
|
||||
aws s3 cp deployments s3://security-content-testing/deployments --recursive --exclude "*" --include "*.yml"
|
||||
- name: Security Content API Smoke Test
|
||||
run: |
|
||||
API_URL='https://content.splunkresearch.com/detections'
|
||||
API_STATUS=$(curl -s -o /dev/null -w "%{http_code}" $API_URL)
|
||||
echo "Security Content API Status: $API_STATUS"
|
||||
if [ "$API_STATUS" != "200" ]; then
|
||||
echo "Error [Security Content API status: $API_STATUS]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
@@ -41,16 +41,15 @@ jobs:
|
||||
# Scan code using project's configuration on https://semgrep.dev/manage
|
||||
- uses: returntocorp/semgrep-action@v1
|
||||
with:
|
||||
#The following line is commented out for now pending a fix to the semgrep repo
|
||||
#generateSarif: "1"
|
||||
generateSarif: "1"
|
||||
config: >- # more at semgrep.dev/explore
|
||||
p/security-audit
|
||||
p/secrets
|
||||
|
||||
# Upload SARIF file generated in previous step
|
||||
#The following lines are commented out right now pending a fix to the semgrep repo
|
||||
# - name: Upload SARIF file
|
||||
# uses: github/codeql-action/upload-sarif@v1
|
||||
# with:
|
||||
# sarif_file: semgrep.sarif
|
||||
# if: always()
|
||||
- name: Upload SARIF file
|
||||
uses: github/codeql-action/upload-sarif@v1
|
||||
with:
|
||||
sarif_file: semgrep.sarif
|
||||
if: always()
|
||||
|
||||
@@ -148,7 +148,7 @@ def main(args):
|
||||
detection_obj['tags']['dataset'] = datasets
|
||||
|
||||
with open(file_path, 'w') as f:
|
||||
yaml.dump(detection_obj, f, sort_keys=False)
|
||||
yaml.dump(detection_obj, f, sort_keys=False, allow_unicode=True)
|
||||
|
||||
changed_file_path = 'detections/' + test['detection_result']['detection_file']
|
||||
security_content_repo_obj.index.add([changed_file_path])
|
||||
@@ -177,7 +177,7 @@ def main(args):
|
||||
|
||||
|
||||
def load_file(file_path):
|
||||
with open(file_path, 'r') as stream:
|
||||
with open(file_path, 'r', encoding="utf-8") as stream:
|
||||
try:
|
||||
file = list(yaml.safe_load_all(stream))[0]
|
||||
except yaml.YAMLError as exc:
|
||||
|
||||
@@ -19,6 +19,7 @@ certifi==2021.5.30
|
||||
cffi==1.14.5
|
||||
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
|
||||
@@ -55,6 +56,7 @@ PyInquirer==1.0.3
|
||||
PyJWT==2.1.0
|
||||
PyNaCl==1.4.0
|
||||
pyparsing==2.4.7
|
||||
pyperclip==1.8.2
|
||||
pytest==6.2.4
|
||||
python-daemon==2.3.0
|
||||
python-dateutil==2.8.1
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
name: Github Commit Changes In Master
|
||||
id: c9d2bfe2-019f-11ec-a8eb-acde48001122
|
||||
version: 1
|
||||
date: '2021-08-20'
|
||||
author: Teoderick Contreras, Splunk
|
||||
type: Anomaly
|
||||
datamodel: []
|
||||
description: This search is to detect a pushed or commit to master or main branch.
|
||||
This is to avoid unwanted modification to master without a review to the changes. Ideally in terms of devsecops the changes made in a branch and do a
|
||||
PR for review. of course in some cases admin of the project may did a changes directly to master branch
|
||||
search: '`github` branches{}.name = main OR branches{}.name = master
|
||||
| stats count min(_time) as firstTime max(_time) as lastTime by commit.author.html_url commit.commit.author.email commit.author.login commit.commit.message repository.pushed_at commit.commit.committer.date
|
||||
| `security_content_ctime(firstTime)`
|
||||
| `security_content_ctime(lastTime)`
|
||||
| `github_commit_changes_in_master_filter`'
|
||||
how_to_implement: To successfully implement this search, you need to be ingesting
|
||||
logs related to github logs having the fork, commit, push metadata that can be use
|
||||
to monitor the changes in a github project.
|
||||
known_false_positives: admin can do changes directly to master branch
|
||||
references:
|
||||
- https://www.redhat.com/en/topics/devops/what-is-devsecops
|
||||
tags:
|
||||
analytic_story:
|
||||
- DevSecOps
|
||||
dataset:
|
||||
- https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1199/github_push_master/github_push_master.log
|
||||
kill_chain_phases:
|
||||
- Exploitation
|
||||
mitre_attack_id:
|
||||
- T1199
|
||||
product:
|
||||
- Splunk Enterprise
|
||||
- Splunk Enterprise Security
|
||||
- Splunk Cloud
|
||||
required_fields:
|
||||
- _time
|
||||
security_domain: endpoint
|
||||
impact: 30
|
||||
confidence: 30
|
||||
risk_score: 9
|
||||
context:
|
||||
- Source:Endpoint
|
||||
- Stage:Reconnaissance
|
||||
message: suspicious commit by $commit.commit.author.email$ to main branch
|
||||
observable:
|
||||
- name: commit.commit.author.email
|
||||
type: User
|
||||
role:
|
||||
- attacker
|
||||
automated_detection_testing: passed
|
||||
@@ -0,0 +1,68 @@
|
||||
name: Gsuite Email Suspicious Subject With Attachment
|
||||
id: 8ef3971e-00f2-11ec-b54f-acde48001122
|
||||
version: 1
|
||||
date: '2021-08-19'
|
||||
author: Teoderick Contreras, Splunk
|
||||
type: Anomaly
|
||||
datamodel: []
|
||||
description: This search is to detect a gsuite email contains suspicious subject having
|
||||
known file type used in spear phishing. This technique is a common and effective
|
||||
entry vector of attacker to compromise a network by luring the user to click or
|
||||
execute the suspicious attachment send from external email account because of the
|
||||
effective social engineering of subject related to delivery, bank and so on. On
|
||||
the other hand this detection may catch a normal email traffic related to legitimate
|
||||
transaction so better to check the email sender, spelling and etc. avoid click link
|
||||
or opening the attachment if you are not expecting this type of e-mail.
|
||||
search: '`gsuite_gmail` num_message_attachments > 0 subject IN ("*dhl*", "* ups *",
|
||||
"*delivery*", "*parcel*", "*label*", "*invoice*", "*postal*", "* fedex *", "* usps
|
||||
*", "* express *", "*shipment*", "*Banking/Tax*","*shipment*", "*new order*") attachment{}.file_extension_type
|
||||
IN ("doc", "docx", "xls", "xlsx", "ppt", "pptx", "pdf", "zip", "rar", "html","htm","hta")
|
||||
| rex field=source.from_header_address "[^@]+@(?<source_domain>[^@]+)" | rex field=destination{}.address
|
||||
"[^@]+@(?<dest_domain>[^@]+)" | where not source_domain="internal_test_email.com"
|
||||
and dest_domain="internal_test_email.com" | stats count min(_time) as firstTime
|
||||
max(_time) as lastTime values(attachment{}.file_extension_type) as email_attachments,
|
||||
values(attachment{}.sha256) as attachment_sha256, values(payload_size) as payload_size
|
||||
by destination{}.service num_message_attachments subject destination{}.address
|
||||
source.address | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`
|
||||
| `gsuite_email_suspicious_subject_with_attachment_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.
|
||||
known_false_positives: normal user or normal transaction may contain the subject and
|
||||
file type attachment that this detection try to search.
|
||||
references:
|
||||
- https://www.redhat.com/en/topics/devops/what-is-devsecops
|
||||
- https://www.fireeye.com/content/dam/fireeye-www/global/en/current-threats/pdfs/rpt-top-spear-phishing-words.pdf
|
||||
tags:
|
||||
analytic_story:
|
||||
- DevSecOps
|
||||
dataset:
|
||||
- https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1566.001/gsuite_susp_subj/gsuite_susp_subj_attach.log
|
||||
kill_chain_phases:
|
||||
- Exploitation
|
||||
mitre_attack_id:
|
||||
- T1566.001
|
||||
product:
|
||||
- Splunk Enterprise
|
||||
- Splunk Enterprise Security
|
||||
- Splunk Cloud
|
||||
required_fields:
|
||||
- _time
|
||||
security_domain: endpoint
|
||||
impact: 50
|
||||
confidence: 50
|
||||
risk_score: 25
|
||||
context:
|
||||
- Source:Endpoint
|
||||
- Stage:Reconnaissance
|
||||
message: suspicious email from $source.address$ to $destination{}.address$
|
||||
observable:
|
||||
- name: source.address
|
||||
type: User
|
||||
role:
|
||||
- attacker
|
||||
- name: destination{}.address
|
||||
type: User
|
||||
role:
|
||||
- Victim
|
||||
automated_detection_testing: passed
|
||||
@@ -0,0 +1,58 @@
|
||||
name: Gsuite Email With Known Abuse Web Service Link
|
||||
id: 8630aa22-042b-11ec-af39-acde48001122
|
||||
version: 1
|
||||
date: '2021-08-23'
|
||||
author: Teoderick Contreras, Splunk
|
||||
type: Anomaly
|
||||
datamodel: []
|
||||
description: This analytics is to detect a gmail containing a link that are known
|
||||
to be abused by malware or attacker like pastebin, telegram and discord to deliver
|
||||
malicious payload. This event can encounter some normal email traffic within organization
|
||||
and external email that normally using this application and services.
|
||||
search: '`gsuite_gmail` "link_domain{}" IN ("*pastebin.com*", "*discord*", "*telegram*","t.me")
|
||||
| rex field=source.from_header_address "[^@]+@(?<source_domain>[^@]+)" | rex field=destination{}.address
|
||||
"[^@]+@(?<dest_domain>[^@]+)" | where not source_domain="internal_test_email.com"
|
||||
and dest_domain="internal_test_email.com" |stats values(link_domain{}) as link_domains
|
||||
min(_time) as firstTime max(_time) as lastTime count by is_spam source.address source.from_header_address
|
||||
subject destination{}.address | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`
|
||||
| `gsuite_email_with_known_abuse_web_service_link_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.
|
||||
known_false_positives: normal email contains this link that are known application
|
||||
within the organization or network can be catched by this detection.
|
||||
references:
|
||||
- https://news.sophos.com/en-us/2021/07/22/malware-increasingly-targets-discord-for-abuse/
|
||||
tags:
|
||||
analytic_story:
|
||||
- DevSecOps
|
||||
dataset:
|
||||
- https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1566.001/gsuite_susp_url/gsuite_susp_url.log
|
||||
kill_chain_phases:
|
||||
- Exploitation
|
||||
mitre_attack_id:
|
||||
- T1566.001
|
||||
product:
|
||||
- Splunk Enterprise
|
||||
- Splunk Enterprise Security
|
||||
- Splunk Cloud
|
||||
required_fields:
|
||||
- _time
|
||||
security_domain: endpoint
|
||||
impact: 50
|
||||
confidence: 50
|
||||
risk_score: 25
|
||||
context:
|
||||
- Source:Endpoint
|
||||
- Stage:Reconnaissance
|
||||
message: suspicious email from $source.address$ to $destination{}.address$
|
||||
observable:
|
||||
- name: source.address
|
||||
type: User
|
||||
role:
|
||||
- attacker
|
||||
- name: destination{}.address
|
||||
type: User
|
||||
role:
|
||||
- Victim
|
||||
automated_detection_testing: passed
|
||||
@@ -0,0 +1,71 @@
|
||||
name: Gsuite Suspicious Shared File Name
|
||||
id: 07eed200-03f5-11ec-98fb-acde48001122
|
||||
version: 1
|
||||
date: '2021-08-23'
|
||||
author: Teoderick Contreras, Splunk
|
||||
type: Anomaly
|
||||
datamodel: []
|
||||
description: This search is to detect a shared file in google drive with suspicious
|
||||
file name that are commonly used by spear phishing campaign. This technique is very
|
||||
popular to lure the user by running a malicious document or click a malicious link
|
||||
within the shared file that will redirected to malicious website. This detection
|
||||
can also catch some normal email communication between organization and its external
|
||||
customer.
|
||||
search: '`gsuite_drive` parameters.owner_is_team_drive=false "parameters.doc_title"
|
||||
IN ("*dhl*", "* ups *", "*delivery*", "*parcel*", "*label*", "*invoice*", "*postal*",
|
||||
"*fedex*", "* usps *", "* express *", "*shipment*", "*Banking/Tax*","*shipment*",
|
||||
"*new order*") parameters.doc_type IN ("document","pdf", "msexcel", "msword", "spreadsheet",
|
||||
"presentation") | rex field=parameters.owner "[^@]+@(?<source_domain>[^@]+)" | rex
|
||||
field=parameters.target_user "[^@]+@(?<dest_domain>[^@]+)" | where not source_domain="internal_test_email.com"
|
||||
and dest_domain="internal_test_email.com" | stats count min(_time) as firstTime
|
||||
max(_time) as lastTime by email parameters.owner parameters.target_user parameters.doc_title
|
||||
parameters.doc_type | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`
|
||||
| `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.
|
||||
known_false_positives: normal user or normal transaction may contain the subject and
|
||||
file type attachment that this detection try to search
|
||||
references:
|
||||
- https://www.redhat.com/en/topics/devops/what-is-devsecops
|
||||
- https://www.fireeye.com/content/dam/fireeye-www/global/en/current-threats/pdfs/rpt-top-spear-phishing-words.pdf
|
||||
tags:
|
||||
analytic_story:
|
||||
- DevSecOps
|
||||
dataset:
|
||||
- https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1566.001/gdrive_susp_file_share/gdrive_susp_attach.log
|
||||
kill_chain_phases:
|
||||
- Exploitation
|
||||
mitre_attack_id:
|
||||
- T1566.001
|
||||
product:
|
||||
- Splunk Enterprise
|
||||
- Splunk Enterprise Security
|
||||
- Splunk Cloud
|
||||
required_fields:
|
||||
- _time
|
||||
- parameters.doc_title
|
||||
- src_domain
|
||||
- dest_domain
|
||||
- email
|
||||
- parameters.visibility
|
||||
- parameters.owner
|
||||
- parameters.doc_type
|
||||
security_domain: endpoint
|
||||
impact: 30
|
||||
confidence: 30
|
||||
risk_score: 9
|
||||
context:
|
||||
- Source:Endpoint
|
||||
- Stage:Reconnaissance
|
||||
message: suspicious share gdrive from $parameters.owner$ to $email$ namely as $parameters.doc_title$
|
||||
observable:
|
||||
- name: parameters.owner
|
||||
type: User
|
||||
role:
|
||||
- attacker
|
||||
- name: email
|
||||
type: User
|
||||
role:
|
||||
- Victim
|
||||
automated_detection_testing: passed
|
||||
@@ -0,0 +1,55 @@
|
||||
name: Kubernetes Nginx Ingress LFI
|
||||
id: 0f83244b-425b-4528-83db-7a88c5f66e48
|
||||
version: 1
|
||||
date: '2021-08-20'
|
||||
author: Patrick Bareiss, Splunk
|
||||
type: TTP
|
||||
datamodel: []
|
||||
description: This search uses the Kubernetes logs from a nginx ingress controller
|
||||
to detect local file inclusion attacks.
|
||||
search: '`kubernetes_container_controller` | rex field=_raw "^(?<remote_addr>\S+)\s+-\s+-\s+\[(?<time_local>[^\]]*)\]\s\"(?<request>[^\"]*)\"\s(?<status>\S*)\s(?<body_bytes_sent>\S*)\s\"(?<http_referer>[^\"]*)\"\s\"(?<http_user_agent>[^\"]*)\"\s(?<request_length>\S*)\s(?<request_time>\S*)\s\[(?<proxy_upstream_name>[^\]]*)\]\s\[(?<proxy_alternative_upstream_name>[^\]]*)\]\s(?<upstream_addr>\S*)\s(?<upstream_response_length>\S*)\s(?<upstream_response_time>\S*)\s(?<upstream_status>\S*)\s(?<req_id>\S*)"
|
||||
| lookup local_file_inclusion_paths local_file_inclusion_paths AS request OUTPUT
|
||||
lfi_path | search lfi_path=yes | rename remote_addr AS src_ip, upstream_status as
|
||||
status, proxy_upstream_name as proxy | rex field=request "^(?<http_method>\S+)\s(?<url>\S+)\s"
|
||||
| stats count min(_time) as firstTime max(_time) as lastTime by src_ip, status,
|
||||
url, http_method, host, http_user_agent, proxy | `security_content_ctime(firstTime)`
|
||||
| `security_content_ctime(lastTime)` | `kubernetes_nginx_ingress_lfi_filter`'
|
||||
how_to_implement: You must ingest Kubernetes logs through Splunk Connect for Kubernetes.
|
||||
known_false_positives: unknown
|
||||
references:
|
||||
- https://github.com/splunk/splunk-connect-for-kubernetes
|
||||
- https://www.offensive-security.com/metasploit-unleashed/file-inclusion-vulnerabilities/
|
||||
tags:
|
||||
analytic_story:
|
||||
- Dev Sec Ops
|
||||
asset_type: Kubernetes
|
||||
cis20:
|
||||
- CIS 13
|
||||
confidence: 70
|
||||
impact: 70
|
||||
kill_chain_phases:
|
||||
- Actions on Objectives
|
||||
message: Local File Inclusion Attack detected on $host$
|
||||
mitre_attack_id:
|
||||
- T1212
|
||||
nist:
|
||||
- PR.DS
|
||||
- PR.AC
|
||||
- DE.CM
|
||||
observable:
|
||||
- name: src_ip
|
||||
type: IP Address
|
||||
role:
|
||||
- Attacker
|
||||
product:
|
||||
- Splunk Enterprise
|
||||
- Splunk Enterprise Security
|
||||
- Splunk Cloud
|
||||
required_fields:
|
||||
- raw
|
||||
risk_score: 49
|
||||
security_domain: network
|
||||
automated_detection_testing: passed
|
||||
dataset:
|
||||
- https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1212/kubernetes_nginx_lfi_attack/kubernetes_nginx_lfi_attack.log
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
name: Kubernetes Nginx Ingress RFI
|
||||
id: fc5531ae-62fd-4de6-9c36-b4afdae8ca95
|
||||
version: 1
|
||||
date: '2021-08-23'
|
||||
author: Patrick Bareiss, Splunk
|
||||
type: TTP
|
||||
datamodel: []
|
||||
description: This search uses the Kubernetes logs from a nginx ingress controller
|
||||
to detect remote file inclusion attacks.
|
||||
search: '`kubernetes_container_controller` | rex field=_raw "^(?<remote_addr>\S+)\s+-\s+-\s+\[(?<time_local>[^\]]*)\]\s\"(?<request>[^\"]*)\"\s(?<status>\S*)\s(?<body_bytes_sent>\S*)\s\"(?<http_referer>[^\"]*)\"\s\"(?<http_user_agent>[^\"]*)\"\s(?<request_length>\S*)\s(?<request_time>\S*)\s\[(?<proxy_upstream_name>[^\]]*)\]\s\[(?<proxy_alternative_upstream_name>[^\]]*)\]\s(?<upstream_addr>\S*)\s(?<upstream_response_length>\S*)\s(?<upstream_response_time>\S*)\s(?<upstream_status>\S*)\s(?<req_id>\S*)"
|
||||
| rex field=request "^(?<http_method>\S+)?\s(?<url>\S+)\s" | rex field=url "(?<dest_ip>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})"
|
||||
| search dest_ip=* | rename remote_addr AS src_ip, upstream_status as status, proxy_upstream_name
|
||||
as proxy | stats count min(_time) as firstTime max(_time) as lastTime by src_ip,
|
||||
dest_ip status, url, http_method, host, http_user_agent, proxy | `security_content_ctime(firstTime)`
|
||||
| `security_content_ctime(lastTime)` | `kubernetes_nginx_ingress_rfi_filter`'
|
||||
how_to_implement: You must ingest Kubernetes logs through Splunk Connect for Kubernetes.
|
||||
known_false_positives: unknown
|
||||
references:
|
||||
- https://github.com/splunk/splunk-connect-for-kubernetes
|
||||
- https://www.netsparker.com/blog/web-security/remote-file-inclusion-vulnerability/
|
||||
tags:
|
||||
analytic_story:
|
||||
- Dev Sec Ops
|
||||
asset_type: Kubernetes
|
||||
cis20:
|
||||
- CIS 13
|
||||
confidence: 70
|
||||
impact: 70
|
||||
kill_chain_phases:
|
||||
- Actions on Objectives
|
||||
message: Remote File Inclusion Attack detected on $host$
|
||||
mitre_attack_id:
|
||||
- T1212
|
||||
nist:
|
||||
- PR.DS
|
||||
- PR.AC
|
||||
- DE.CM
|
||||
observable:
|
||||
- name: src_ip
|
||||
type: IP Address
|
||||
role:
|
||||
- Attacker
|
||||
product:
|
||||
- Splunk Enterprise
|
||||
- Splunk Enterprise Security
|
||||
- Splunk Cloud
|
||||
required_fields:
|
||||
- raw
|
||||
risk_score: 49
|
||||
security_domain: network
|
||||
automated_detection_testing: passed
|
||||
dataset:
|
||||
- https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1212/kuberntest_nginx_rfi_attack/kubernetes_nginx_rfi_attack.log
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
name: Kubernetes Scanner Image Pulling
|
||||
id: 4890cd6b-0112-4974-a272-c5c153aee551
|
||||
version: 1
|
||||
date: '2021-08-24'
|
||||
author: Patrick Bareiss, Splunk
|
||||
type: TTP
|
||||
datamodel: []
|
||||
description: This search uses the Kubernetes logs from Splunk Connect from Kubernetes
|
||||
to detect Kubernetes Security Scanner.
|
||||
search: '`kube_objects_events` object.message IN ("Pulling image *kube-hunter*", "Pulling
|
||||
image *kube-bench*", "Pulling image *kube-recon*", "Pulling image *kube-recon*")
|
||||
| rename object.* AS * | rename involvedObject.* AS * | rename source.host AS host
|
||||
| stats min(_time) as firstTime max(_time) as lastTime count by host, name, namespace,
|
||||
kind, reason, message | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`
|
||||
| `kubernetes_scanner_image_pulling_filter`'
|
||||
how_to_implement: You must ingest Kubernetes logs through Splunk Connect for Kubernetes.
|
||||
known_false_positives: unknown
|
||||
references:
|
||||
- https://github.com/splunk/splunk-connect-for-kubernetes
|
||||
tags:
|
||||
analytic_story:
|
||||
- Dev Sec Ops
|
||||
asset_type: Kubernetes
|
||||
cis20:
|
||||
- CIS 13
|
||||
confidence: 70
|
||||
impact: 70
|
||||
kill_chain_phases:
|
||||
- Actions on Objectives
|
||||
message: Kubernetes Scanner image pulled on host $host$
|
||||
mitre_attack_id:
|
||||
- T1526
|
||||
nist:
|
||||
- PR.DS
|
||||
- PR.AC
|
||||
- DE.CM
|
||||
observable:
|
||||
- name: host
|
||||
type: Entity
|
||||
product:
|
||||
- Splunk Enterprise
|
||||
- Splunk Enterprise Security
|
||||
- Splunk Cloud
|
||||
required_fields:
|
||||
- object.message
|
||||
- source.host
|
||||
- object.involvedObject.name
|
||||
- object.involvedObject.namespace
|
||||
- object.involvedObject.kind
|
||||
- object.message
|
||||
- object.reason
|
||||
risk_score: 49
|
||||
security_domain: network
|
||||
automated_detection_testing: passed
|
||||
dataset:
|
||||
- https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1526/kubernetes_kube_hunter/kubernetes_kube_hunter.json
|
||||
|
||||
@@ -80,3 +80,4 @@ tags:
|
||||
- Processes.parent_process_id
|
||||
risk_score: 90
|
||||
security_domain: endpoint
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,7 @@
|
||||
description: A list of interesting files in a local file inclusion attack
|
||||
filename: local_file_inclusion_paths.csv
|
||||
name: local_file_inclusion_paths
|
||||
default_match: 'false'
|
||||
match_type: WILDCARD(local_file_inclusion_paths)
|
||||
min_matches: 1
|
||||
case_sensitive_match: 'false'
|
||||
@@ -0,0 +1,4 @@
|
||||
definition: sourcetype=aws:firehose:json
|
||||
description: customer specific splunk configurations(eg- index, source, sourcetype).
|
||||
Replace the macro definition with configurations for your Splunk Environmnent.
|
||||
name: github
|
||||
@@ -0,0 +1,4 @@
|
||||
definition: sourcetype=kube:objects:events
|
||||
description: customer specific splunk configurations(eg- index, source, sourcetype).
|
||||
Replace the macro definition with configurations for your Splunk Environmnent.
|
||||
name: kube_objects_events
|
||||
@@ -0,0 +1,3 @@
|
||||
definition: sourcetype=kube:container:controller
|
||||
description: customer specific splunk configurations(eg- index, source, sourcetype) for Kubernetes data. Replace the macro definition with configurations for your Splunk Environmnent.
|
||||
name: kubernetes_container_controller
|
||||
@@ -0,0 +1,12 @@
|
||||
name: Github Commit Changes In Master Unit Test
|
||||
tests:
|
||||
- name: Github Commit Changes In Master
|
||||
file: cloud/github_commit_changes_in_master.yml
|
||||
pass_condition: '| stats count | where count > 0'
|
||||
earliest_time: '-30d'
|
||||
latest_time: 'now'
|
||||
attack_data:
|
||||
- file_name: github_push_master.log
|
||||
data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1199/github_push_master/github_push_master.log
|
||||
source: github
|
||||
sourcetype: aws:firehose:json
|
||||
@@ -0,0 +1,12 @@
|
||||
name: Gsuite Email Suspicious Subject With Attachment Unit Test
|
||||
tests:
|
||||
- name: Gsuite Email Suspicious Subject With Attachment
|
||||
file: cloud/gsuite_email_suspicious_subject_with_attachment.yml
|
||||
pass_condition: '| stats count | where count > 0'
|
||||
earliest_time: '-24h'
|
||||
latest_time: 'now'
|
||||
attack_data:
|
||||
- file_name: gsuite_susp_subj_attach.log
|
||||
data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1566.001/gsuite_susp_subj/gsuite_susp_subj_attach.log
|
||||
source: http:gsuite
|
||||
sourcetype: gsuite:gmail:bigquery
|
||||
@@ -0,0 +1,12 @@
|
||||
name: Gsuite Email With Known Abuse Web Service Link Unit Test
|
||||
tests:
|
||||
- name: Gsuite Email With Known Abuse Web Service Link
|
||||
file: cloud/gsuite_email_with_known_abuse_web_service_link.yml
|
||||
pass_condition: '| stats count | where count > 0'
|
||||
earliest_time: '-24h'
|
||||
latest_time: 'now'
|
||||
attack_data:
|
||||
- file_name: gsuite_susp_url.log
|
||||
data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1566.001/gsuite_susp_url/gsuite_susp_url.log
|
||||
source: http:gsuite
|
||||
sourcetype: gsuite:gmail:bigquery
|
||||
@@ -0,0 +1,12 @@
|
||||
name: Gsuite Suspicious Shared File Name Unit Test
|
||||
tests:
|
||||
- name: Gsuite Suspicious Shared File Name
|
||||
file: cloud/gsuite_suspicious_shared_file_name.yml
|
||||
pass_condition: '| stats count | where count > 0'
|
||||
earliest_time: '-24h'
|
||||
latest_time: 'now'
|
||||
attack_data:
|
||||
- file_name: gdrive_susp_attach.log
|
||||
data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1566.001/gdrive_susp_file_share/gdrive_susp_attach.log
|
||||
source: http:gsuite
|
||||
sourcetype: gsuite:drive:json
|
||||
@@ -0,0 +1,12 @@
|
||||
name: Kubernetes Nginx Ingress LFI Unit Test
|
||||
tests:
|
||||
- name: Kubernetes Nginx Ingress LFI
|
||||
file: cloud/kubernetes_nginx_ingress_lfi.yml
|
||||
pass_condition: '| stats count | where count > 0'
|
||||
earliest_time: '-365d'
|
||||
latest_time: 'now'
|
||||
attack_data:
|
||||
- file_name: kubernetes_nginx_lfi_attack.log
|
||||
data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1212/kubernetes_nginx_lfi_attack/kubernetes_nginx_lfi_attack.log
|
||||
sourcetype: kube:container:controller
|
||||
source: kubernetes
|
||||
@@ -0,0 +1,12 @@
|
||||
name: Kubernetes Nginx Ingress RFI Unit Test
|
||||
tests:
|
||||
- name: Kubernetes Nginx Ingress RFI
|
||||
file: cloud/kubernetes_nginx_ingress_rfi.yml
|
||||
pass_condition: '| stats count | where count > 0'
|
||||
earliest_time: '-365d'
|
||||
latest_time: 'now'
|
||||
attack_data:
|
||||
- file_name: kubernetes_nginx_rfi_attack.log
|
||||
data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1212/kuberntest_nginx_rfi_attack/kubernetes_nginx_rfi_attack.log
|
||||
sourcetype: kube:container:controller
|
||||
source: kubernetes
|
||||
@@ -0,0 +1,12 @@
|
||||
name: Kubernetes Scanner Image Pulling Unit Test
|
||||
tests:
|
||||
- name: Kubernetes Scanner Image Pulling
|
||||
file: cloud/kubernetes_scanner_image_pulling.yml
|
||||
pass_condition: '| stats count | where count > 0'
|
||||
earliest_time: '-7d'
|
||||
latest_time: 'now'
|
||||
attack_data:
|
||||
- file_name: kubernetes_kube_hunter.json
|
||||
data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1526/kubernetes_kube_hunter/kubernetes_kube_hunter.json
|
||||
sourcetype: kube:objects:events
|
||||
source: kubernetes
|
||||
Reference in New Issue
Block a user