Merge branch 'develop' into gcpk8plussearches

This commit is contained in:
Bhavin Patel
2020-07-13 15:47:35 -07:00
committed by GitHub
218 changed files with 8750 additions and 3386 deletions
+237 -26
View File
@@ -2,10 +2,17 @@
#
# Check https://circleci.com/docs/2.0/language-python/ for more details
#
#############
# Automatically generated by ci-generator.py in splunk/security-content
# On Date: 2020-07-09T12:33:27 UTC
# Author: Splunk Security Research
# Contact: research@splunk.com
#############
version: 2.1
orbs:
aws-cli: circleci/aws-cli@0.1.19
slack: circleci/slack@3.4.2
dependencies:
cache_directories:
@@ -38,6 +45,176 @@ executors:
working_directory: ~/repo
jobs:
test-detections:
executor: content-executor
steps:
- run:
name: checkout repo
command: |
if [[ ! -z "${CIRCLE_PULL_REQUEST}" && ! -z "${CIRCLE_PR_NUMBER}" ]]; then
git clone https://${GITHUB_TOKEN}@github.com/splunk/security-content.git
cd security-content
git fetch origin pull/${CIRCLE_PR_NUMBER}/head:${CIRCLE_BRANCH}
git checkout ${CIRCLE_BRANCH}
elif [ "${CIRCLE_BRANCH}" == "" ]; then
git clone https://${GITHUB_TOKEN}@github.com/splunk/security-content.git
else
git clone --branch ${CIRCLE_BRANCH} https://${GITHUB_TOKEN}@github.com/splunk/security-content.git
fi
- run:
name: checkout attack_range repo
command: |
git clone https://${GITHUB_TOKEN}@github.com/splunk/attack_range.git
- restore_cache:
key: virtualenv
- run: *apt-install
- run:
name: install python dependencies
command: |
cd attack_range
rm -rf venv
virtualenv --python=/usr/bin/python3 --clear venv
source venv/bin/activate
pip install -q -r requirements.txt
- aws-cli/setup:
profile-name: default
- add_ssh_keys:
fingerprints:
- "39:68:78:2b:01:d6:35:eb:78:42:28:58:1d:9c:be:90"
- run:
name: install terraform
command: |
wget https://releases.hashicorp.com/terraform/0.12.24/terraform_0.12.24_linux_amd64.zip
sudo unzip terraform_0.12.24_linux_amd64.zip -d /usr/bin
rm terraform_0.12.24_linux_amd64.zip
terraform --version
- run:
name: detection tests > T1574_009.yml
command: |
cd attack_range
source venv/bin/activate
# change attack_range default ssh keys
sed -i "s/key_name = .*$/key_name = attack-range-ci-job-security-content/g" attack_range.conf
sed -i "s/automated_testing = .*$/automated_testing = 1/g" attack_range.conf
sed -i "s/github_token =.*$/github_token = ${GITHUB_TOKEN}/g" attack_range.conf
sed -i "s/region = us-west-2/region = us-west-2/g" attack_range.conf
sed -i "s/private_key_path =.*$/private_key_path = ~\/.ssh\/id_rsa_3968782b01d635eb784228581d9cbe90/g" attack_range.conf
sed -i "s/windows_domain_controller = .*$/windows_domain_controller = 1/g" attack_range.conf
sed -i "s/capture_attack_data = .*$/capture_attack_data = 1/g" attack_range.conf
cd terraform/
terraform init
cd ..
python attack_range.py --mode terraform --action test --test_file ../security-content/tests/T1574_009.yml
- run:
name: detection tests > T1021_001.yml
command: |
cd attack_range
source venv/bin/activate
# change attack_range default ssh keys
sed -i "s/key_name = .*$/key_name = attack-range-ci-job-security-content/g" attack_range.conf
sed -i "s/automated_testing = .*$/automated_testing = 1/g" attack_range.conf
sed -i "s/github_token =.*$/github_token = ${GITHUB_TOKEN}/g" attack_range.conf
sed -i "s/region = us-west-2/region = us-west-2/g" attack_range.conf
sed -i "s/private_key_path =.*$/private_key_path = ~\/.ssh\/id_rsa_3968782b01d635eb784228581d9cbe90/g" attack_range.conf
sed -i "s/windows_domain_controller = .*$/windows_domain_controller = 1/g" attack_range.conf
sed -i "s/capture_attack_data = .*$/capture_attack_data = 1/g" attack_range.conf
cd terraform/
terraform init
cd ..
python attack_range.py --mode terraform --action test --test_file ../security-content/tests/T1021_001.yml
- run:
name: detection tests > T1003_003.yml
command: |
cd attack_range
source venv/bin/activate
# change attack_range default ssh keys
sed -i "s/key_name = .*$/key_name = attack-range-ci-job-security-content/g" attack_range.conf
sed -i "s/automated_testing = .*$/automated_testing = 1/g" attack_range.conf
sed -i "s/github_token =.*$/github_token = ${GITHUB_TOKEN}/g" attack_range.conf
sed -i "s/region = us-west-2/region = us-west-2/g" attack_range.conf
sed -i "s/private_key_path =.*$/private_key_path = ~\/.ssh\/id_rsa_3968782b01d635eb784228581d9cbe90/g" attack_range.conf
sed -i "s/windows_domain_controller = .*$/windows_domain_controller = 1/g" attack_range.conf
sed -i "s/capture_attack_data = .*$/capture_attack_data = 1/g" attack_range.conf
cd terraform/
terraform init
cd ..
python attack_range.py --mode terraform --action test --test_file ../security-content/tests/T1003_003.yml
- run:
name: detection tests > T1003_002.yml
command: |
cd attack_range
source venv/bin/activate
# change attack_range default ssh keys
sed -i "s/key_name = .*$/key_name = attack-range-ci-job-security-content/g" attack_range.conf
sed -i "s/automated_testing = .*$/automated_testing = 1/g" attack_range.conf
sed -i "s/github_token =.*$/github_token = ${GITHUB_TOKEN}/g" attack_range.conf
sed -i "s/region = us-west-2/region = us-west-2/g" attack_range.conf
sed -i "s/private_key_path =.*$/private_key_path = ~\/.ssh\/id_rsa_3968782b01d635eb784228581d9cbe90/g" attack_range.conf
sed -i "s/windows_domain_controller = .*$/windows_domain_controller = 1/g" attack_range.conf
sed -i "s/capture_attack_data = .*$/capture_attack_data = 1/g" attack_range.conf
cd terraform/
terraform init
cd ..
python attack_range.py --mode terraform --action test --test_file ../security-content/tests/T1003_002.yml
- run:
name: detection tests > T1136_001.yml
command: |
cd attack_range
source venv/bin/activate
# change attack_range default ssh keys
sed -i "s/key_name = .*$/key_name = attack-range-ci-job-security-content/g" attack_range.conf
sed -i "s/automated_testing = .*$/automated_testing = 1/g" attack_range.conf
sed -i "s/github_token =.*$/github_token = ${GITHUB_TOKEN}/g" attack_range.conf
sed -i "s/region = us-west-2/region = us-west-2/g" attack_range.conf
sed -i "s/private_key_path =.*$/private_key_path = ~\/.ssh\/id_rsa_3968782b01d635eb784228581d9cbe90/g" attack_range.conf
sed -i "s/windows_domain_controller = .*$/windows_domain_controller = 1/g" attack_range.conf
sed -i "s/capture_attack_data = .*$/capture_attack_data = 1/g" attack_range.conf
cd terraform/
terraform init
cd ..
python attack_range.py --mode terraform --action test --test_file ../security-content/tests/T1136_001.yml
- run:
name: detection tests > T1003_001.yml
command: |
cd attack_range
source venv/bin/activate
# change attack_range default ssh keys
sed -i "s/key_name = .*$/key_name = attack-range-ci-job-security-content/g" attack_range.conf
sed -i "s/automated_testing = .*$/automated_testing = 1/g" attack_range.conf
sed -i "s/github_token =.*$/github_token = ${GITHUB_TOKEN}/g" attack_range.conf
sed -i "s/region = us-west-2/region = us-west-2/g" attack_range.conf
sed -i "s/private_key_path =.*$/private_key_path = ~\/.ssh\/id_rsa_3968782b01d635eb784228581d9cbe90/g" attack_range.conf
sed -i "s/windows_domain_controller = .*$/windows_domain_controller = 1/g" attack_range.conf
sed -i "s/capture_attack_data = .*$/capture_attack_data = 1/g" attack_range.conf
cd terraform/
terraform init
cd ..
python attack_range.py --mode terraform --action test --test_file ../security-content/tests/T1003_001.yml
- run:
name: detection tests > T1551_001.yml
command: |
cd attack_range
source venv/bin/activate
# change attack_range default ssh keys
sed -i "s/key_name = .*$/key_name = attack-range-ci-job-security-content/g" attack_range.conf
sed -i "s/automated_testing = .*$/automated_testing = 1/g" attack_range.conf
sed -i "s/github_token =.*$/github_token = ${GITHUB_TOKEN}/g" attack_range.conf
sed -i "s/region = us-west-2/region = us-west-2/g" attack_range.conf
sed -i "s/private_key_path =.*$/private_key_path = ~\/.ssh\/id_rsa_3968782b01d635eb784228581d9cbe90/g" attack_range.conf
sed -i "s/windows_domain_controller = .*$/windows_domain_controller = 1/g" attack_range.conf
sed -i "s/capture_attack_data = .*$/capture_attack_data = 1/g" attack_range.conf
cd terraform/
terraform init
cd ..
python attack_range.py --mode terraform --action test --test_file ../security-content/tests/T1551_001.yml
- run:
name: cleanup terraform on failures
command: |
cd attack_range
source venv/bin/activate
python attack_range.py --mode terraform --action destroy
when: on_fail
validate-content:
executor: content-executor
steps:
@@ -81,19 +258,11 @@ jobs:
cd security-content
source venv/bin/activate
python bin/doc-gen.py --path . --output docs -v
- run:
name: check for broken links using liche
command: |
echo 'export GOROOT=~/.go' >> $BASH_ENV
echo 'export PATH=$GOROOT/bin:$PATH' >> $BASH_ENV
echo 'export GOPATH=~/go' >> $BASH_ENV
echo 'export PATH=$GOPATH/bin:$PATH' >> $BASH_ENV
echo 'export GO111MODULE="on"' >> $BASH_ENV
source $BASH_ENV
go get -u github.com/raviqqe/liche
cd security-content
liche docs/stories_categories.md -v -t 45
liche README.md -v -t 45
- slack/status:
webhook: '${SLACK_WEBHOOK}'
fail_only: true
build-sources:
executor: content-executor
steps:
@@ -127,7 +296,7 @@ jobs:
python bin/generate.py --path . --output package -v
# make a copy of use_case_lib in order to have ES work :-(
cp package/default/use_case_library.conf package/default/analyticstories.conf
- run:
- run:
name: copy lookups .csv files
command: |
cd security-content
@@ -159,6 +328,10 @@ jobs:
root: security-content/
paths:
- content-pack-build.tar.gz
- slack/status:
fail_only: true
webhook: '${SLACK_WEBHOOK}'
build-package:
executor: content-executor
steps:
@@ -196,6 +369,10 @@ jobs:
root: ~/dist
paths:
- DA-ESS-ContentUpdate-latest.tar.gz
- slack/status:
fail_only: true
webhook: '${SLACK_WEBHOOK}'
run-appinspect:
executor: content-executor
steps:
@@ -228,6 +405,10 @@ jobs:
root: ~/
paths:
- DA-ESS-ContentUpdate-latest.tar.gz
- slack/status:
fail_only: true
webhook: '${SLACK_WEBHOOK}'
community-api-update:
executor: aws-cli/default
steps:
@@ -244,17 +425,19 @@ jobs:
- run: *apt-install
- aws-cli/setup:
profile-name: default
- run:
- run:
name: update community api sources
command: |
cd security-content
aws s3 cp stories s3://security-content-community/stories --recursive --exclude "*" --include "*.yml"
aws s3 cp baselines s3://security-content-community/baselines --recursive --exclude "*" --include "*.yml"
aws s3 cp detections s3://security-content-community/detections --recursive --exclude "*" --include "*.yml"
aws s3 cp investigations s3://security-content-community/investigations --recursive --exclude "*" --include "*.yml"
aws s3 cp responses s3://security-content-community/responses --recursive --exclude "*" --include "*.yml"
aws s3 cp lookups s3://security-content-community/lookups --recursive --exclude "*" --include "*.yml"
aws s3 cp macros s3://security-content-community/macros --recursive --exclude "*" --include "*.yml"
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 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"
aws s3 cp deployments s3://security-content/deployments --recursive --exclude "*" --include "*.yml"
- persist_to_workspace:
root: ~/
paths:
@@ -309,6 +492,10 @@ jobs:
root: ~/
paths:
- DA-ESS-ContentUpdate-latest.tar.gz
- slack/status:
fail_only: true
webhook: '${SLACK_WEBHOOK}'
publish-github-release:
docker:
- image: cibuilds/github:0.10
@@ -324,6 +511,10 @@ jobs:
root: ~/
paths:
- DA-ESS-ContentUpdate-latest.tar.gz
- slack/status:
fail_only: true
webhook: '${SLACK_WEBHOOK}'
attack-range-update:
executor: aws-cli/default
steps:
@@ -334,9 +525,13 @@ jobs:
- run:
name: sync latest ESCU to the Attack Range S3 bucket for apps
command: |
aws s3 cp ~/DA-ESS-ContentUpdate-latest.tar.gz s3://attack-range-appbinaries/
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
- slack/status:
fail_only: true
webhook: '${SLACK_WEBHOOK}'
master-api-update:
executor: aws-cli/default
steps:
@@ -351,19 +546,35 @@ jobs:
- run: *apt-install
- aws-cli/setup:
profile-name: default
- run:
- run:
name: update api sources
command: |
cd security-content
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 investigations s3://security-content/investigations --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 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"
aws s3 cp deployments s3://security-content/deployments --recursive --exclude "*" --include "*.yml"
- slack/status:
fail_only: true
webhook: '${SLACK_WEBHOOK}'
workflows:
version: 2.1
test-detections:
jobs:
- test-detections
triggers:
- schedule:
cron: "0 5 * * *"
filters:
branches:
only:
- develop
validate-and-build:
jobs:
- validate-content:
@@ -458,4 +669,4 @@ workflows:
tags:
only: /^v.*/
branches:
ignore: /.*/
ignore: /.*/
-3
View File
@@ -9,7 +9,4 @@ repos:
- id: check-yaml
- id: pretty-format-json
args: [--autofix]
- id: flake8
args: [--max-line-length=131]
exclude: 'package/bin/da_ess_contentupdate/|package/bin/splunklib/|venv/|package/bin/escu_contextualize.py|package/bin/escu_investigate.py|package/bin/runstory.py|package/bin/detect.py|package/bin/investigate.py'
- id: requirements-txt-fixer
+84 -1
View File
@@ -1 +1,84 @@
new version of the README needs to be done
# Splunk Security Content
![security-content](docs/static/logo.png)
=====
| branch | build status |
| --- | --- |
| develop| [![develop status](https://circleci.com/gh/splunk/security-content/tree/develop.svg?style=svg&circle-token=67ad1fa7779c57d7e5bcfc42bd617baf607ec269)](https://circleci.com/gh/splunk/security-content/tree/develop)|
| master | [![master status](https://circleci.com/gh/splunk/security-content/tree/master.svg?style=svg&circle-token=67ad1fa7779c57d7e5bcfc42bd617baf607ec269)](https://circleci.com/gh/splunk/security-content/tree/master)|
Welcome to the Splunk Security Content
This project gives you access to our repository of Analytic Stories that are security guides which provide background on TTPs, mapped to the MITRE framework, the Lockheed Martin Kill Chain, and CIS controls. They include Splunk searches, machine-learning algorithms, and Splunk Phantom playbooks (where available)—all designed to work together to detect, investigate, and respond to threats.
# Usage
The Splunk Security Content can be used via:
#### [Splunk App](https://github.com/splunk/security-content/releases)
Grab the latest release of DA-ESS-ContentUpdate and install it on a Splunk Enterprise instance.
#### [API](https://docs.splunkresearch.com/?version=latest)
```
curl -s https://content.splunkresearch.com | jq
{
"hello": "welcome to Splunks Research security content api"
}
```
#### [GitHub Workflow](https://github.com/splunk/security-content/wiki/Installation-and-Usage)
Create your customized version of Security Content by forking this project and following this guide.
# What's in an Analytic Story?
[Analytic Stories](https://github.com/splunk/security-content/blob/develop/docs/stories_categories.md) and their corresponding searches are composed of **.yml** files (manifests) and associated .conf files. The stories reside in [/stories](https://github.com/splunk/security-content/tree/develop/stories) and the searches live in [/detections](https://github.com/splunk/security-content/tree/develop/detections).
Manifests contain a number of mandatory and optional fields. You can see the full field list for each piece of content [here](https://github.com/splunk/security-content/tree/develop/docs#spec-documentation).
# Customize to your Environment
After release [1.0.46](https://github.com/splunk/security-content/releases) we introduced a concept of **input(pre-filter)** and **output(post-filter)** macros for each of our detection search. The intention behind introducing these macros is primarily to help our users to update the macro definition “once” and those changes will be applicable across all detections that leverage that macro and local to your Splunk Environment.
**input(pre-filter):** This macro is to specify your environment-specific configurations (index, source, sourcetype, etc.) to get the specific data sources that you would like to bring in. Replace the macro definition with configurations for your Splunk environment. For example the [sysmon](macros/sysmon.yml) **input macro** can be modified to the local splunk deployments index or sourcetype.
**output(post-filter):** This macro is to specify your environment-specific values (eg: dest, user), to filter out known false positives.. Replace the macro definition with values that youd like to exclude from detection results. Think of this as a whitelisting/blacklisting using macros. A good example
# Execute an Analytic Story
Download and install the latest version of [Splunk Analytic Story Execution]
(https://github.com/splunk/analytic_story_execution/releases). This Splunk application will help the user do the following:
1. Execute an analytic story in an adhoc mode and view the results.
2. Schedule all the detection searches in an analytic story.
3. Update security-content via an API
# Writing Content
Before you begin, follow the steps to install **dependencies and pre-commit hooks** under [Developing Content](https://github.com/splunk/security-content/wiki/Developing-Content).
# Security Content
#### Content Parts
* [stories/](stories/): All Analytic Stories
* [detections/](detections/): Splunk Enterprise, Splunk UBA, and Splunk Phantom detections that power Analytic Stories
* [response_tasks/](response_tasks/): Splunk Enterprise and Splunk Phantom investigative searches and playbooks employed by Analytic Stories
* [responses/](responses/): Automated Splunk Enterprise and Splunk Phantom responses triggered by Analytic Stories
* [baselines/](baselines/): Splunk Phantom and Splunk Enterprise baseline searches needed to support detection searches in Analytic Stories
#### Supporting Parts
* [package/](package/): Splunk content app-source files, including lookups, binaries, and default config files
* [bin/](bin/): All binaries required to produce and test content
# Contribution
We welcome feedback and contributions from the community! Please see our [contributing to the project](https://github.com/splunk/security-content/wiki/Contributing-to-the-Project) for more information on how to get involved.
## Support
Please use the [GitHub Issue Tracker](https://github.com/splunk/security-content/issues) to submit bugs or request features.
If you have questions or need support, you can:
* Post a question to [Splunk Answers](http://answers.splunk.com)
* Join the [#security-research](https://splunk-usergroups.slack.com/messages/C1RH09ERM/) room in the [Splunk Slack channel](http://splunk-usergroups.slack.com)
* If you are a Splunk Enterprise customer with a valid support entitlement contract and have a Splunk-related question, you can also open a support case on the https://www.splunk.com/ support portal
-1
View File
@@ -1 +0,0 @@
theme: jekyll-theme-hacker
@@ -31,5 +31,5 @@ tags:
- Suspicious MSHTA Activity
- Unusual Processes
detections:
- Unusually Long Command Line - MLTK
- Detect Prohibited Applications Spawning cmd.exe
- Unusually Long Command Line - MLTK
+1 -1
View File
@@ -36,5 +36,5 @@ tags:
- Netsh Abuse
- Ransomware
detections:
- SMB Traffic Spike - MLTK
- Processes launching netsh
- SMB Traffic Spike - MLTK
+1 -1
View File
@@ -17,5 +17,5 @@ tags:
- Suspicious Emails
detections:
- Monitor Email For Brand Abuse
- Monitor Web Traffic For Brand Abuse
- Monitor DNS For Brand Abuse
- Monitor Web Traffic For Brand Abuse
@@ -17,7 +17,7 @@ tags:
analytics_story:
- AWS Suspicious Provisioning Activities
detections:
- AWS Cloud Provisioning From Previously Unseen City
- AWS Cloud Provisioning From Previously Unseen IP Address
- AWS Cloud Provisioning From Previously Unseen Region
- AWS Cloud Provisioning From Previously Unseen City
- AWS Cloud Provisioning From Previously Unseen Country
- AWS Cloud Provisioning From Previously Unseen Region
@@ -25,6 +25,6 @@ tags:
- Suspicious Command-Line Executions
- Suspicious MSHTA Activity
detections:
- Detect Prohibited Applications Spawning cmd.exe
- Processes launching netsh
- First time seen command line argument
- Detect Prohibited Applications Spawning cmd.exe
@@ -1,20 +1,23 @@
name: Previously Seen Running Windows Services
name: Previously Seen Running Windows Services - Initial
id: 64ce0ade-cb01-4678-bddd-d31c0b175394
version: 2
date: '2020-01-13'
version: 3
date: '2020-06-23'
description: This collects the services that have been started across your entire
enterprise.
how_to_implement: While this search does not require you to adhere to Splunk CIM,
you must be ingesting your Windows security-event logs for it to execute successfully.
Please ensure that the Splunk Add-on for Microsoft Windows is version 5.0.0 or above.
Please ensure that the Splunk Add-on for Microsoft Windows is version 8.0.0 or above.
author: David Dorsey, Splunk
search: '`wineventlog_system` signature_id=7036 | rename param1 as service_name |
rename param2 as action | search action="running" | stats earliest(_time) as firstTime,
latest(_time) as lastTime by service_name | outputlookup previously_seen_running_windows_services
| stats count'
search: '`wineventlog_system` EventCode=7036 |
rex field=Message "The (?<service>[-\(\)\s\w]+) service entered the (?<state>\w+) state" |
where state="running" |
stats earliest(_time) as firstTimeSeen, latest(_time) as lastTimeSeen by service |
outputlookup previously_seen_running_windows_services'
tags:
analytics_story:
- Orangeworm Attack Group
- Windows Service Abuse
detections:
- First Time Seen Running Windows Service
deployments:
- 90 Day Baseline
@@ -0,0 +1,28 @@
name: Previously Seen Running Windows Services - Update
id: 2e3bdd68-1863-46ee-81f8-87273eee7f1c
version: 3
date: '2020-06-23'
description: This search returns the first and last time a Windows service was seen across your enterprise
within the last hour. It then updates this information with historical data and filters out
Windows services pairs that have not been seen within the specified time window.
This updated table is then cached.
how_to_implement: While this search does not require you to adhere to Splunk CIM,
you must be ingesting your Windows security-event logs for it to execute successfully.
Please ensure that the Splunk Add-on for Microsoft Windows is version 8.0.0 or above.
author: David Dorsey, Splunk
search: '`wineventlog_system` EventCode=7036 |
rex field=Message "The (?<service>[-\(\)\s\w]+) service entered the (?<state>\w+) state" |
where state="running" |
stats earliest(_time) as firstTimeSeen, latest(_time) as lastTimeSeen by service |
inputlookup previously_seen_running_windows_services append=t |
stats min(firstTimeSeen) as firstTimeSeen, max(lastTimeSeen) as lastTimeSeen by service |
where lastTimeSeen > relative_time(now(), "`previously_seen_windows_service_forget_window`") |
outputlookup previously_seen_running_windows_services'
tags:
analytics_story:
- Orangeworm Attack Group
- Windows Service Abuse
detections:
- First Time Seen Running Windows Service
deployments:
- Hourly Cache Updates
@@ -20,6 +20,6 @@ tags:
- Suspicious AWS Login Activities
detections:
- Detect AWS Console Login by User from New Country
- Detect AWS Console Login by User from New City
- Detect AWS Console Login by User from New Region
- Detect AWS Console Login by User from New City
- Detect new user AWS Console Login
@@ -0,0 +1,25 @@
name: Previously seen users in CloudTrail - DM
id: 0a87ecf9-dc6a-43af-861a-205e75a09bf5
version: 1
date: '2020-05-28'
description: This search looks for CloudTrail events where a user logs into the console,
then creates a baseline of the latest and earliest times, City, Region, and Country
we have encountered this user in our dataset, grouped by username, within the last 30
days.
how_to_implement: You must install and configure the Splunk Add-on for AWS (version 5.1.0 or later)
and Enterprise Security 6.2, which contains the required updates to the Authentication data model
for cloud use cases. Validate the user name entries in `previously_seen_users_console_logins.csv`,
which is a lookup file created by this support search.
author: Rico Valdez, Splunk
search: '| tstats earliest(_time) as firstTime latest(_time) as lastTime from datamodel=Authentication
where Authentication.signature=ConsoleLogin by Authentication.user Authentication.src
| iplocation Authentication.src | rename Authentication.user as user Authentication.src as src
| table user src City Region Country firstTime lastTime | outputlookup previously_seen_users_console_logins.csv | stats count'
tags:
analytics_story:
- Suspicious Cloud Authentication Activities
detections:
- Detect AWS Console Login by User from New Country
- Detect AWS Console Login by User from New Region
- Detect AWS Console Login by User from New City
- Detect new user AWS Console Login - DM
@@ -0,0 +1,22 @@
name: Previously Seen Zoom Child Processes - Initial
id: 60b9c00f-a9d6-4e51-803c-5d63ea21b95b
version: 1
date: '2020-05-20'
description: This search returns the first and last time a process was seen per endpoint with
a parent process of zoom.exe (Windows) or zoom.us (macOS). This table is then cached.
how_to_implement: You must be ingesting endpoint data that tracks process activity,
including parent-child relationships from your endpoints, to populate the Endpoint
data model in the Processes node.
author: David Dorsey, Splunk
search: '| tstats `security_content_summariesonly` min(_time) as firstTimeSeen max(_time) as lastTimeSeen
from datamodel=Endpoint.Processes where (Processes.parent_process_name=zoom.exe OR Processes.parent_process_name=zoom.us)
by Processes.process_name Processes.dest| `drop_dm_object_name(Processes)`
| table dest, process_name, firstTimeSeen, lastTimeSeen
| outputlookup zoom_first_time_child_process'
tags:
analytics_story:
- Suspicious Zoom Child Processes
detections:
- First Time Seen Child Process of Zoom
deployments:
- 90 Day Baseline
@@ -0,0 +1,27 @@
name: Previously Seen Zoom Child Processes - Update
id: 80aea7fd-5da2-4533-b3c2-560533bfbaee
version: 1
date: '2020-05-20'
description: This search returns the first and last time a process was seen per endpoint with
a parent process of zoom.exe (Windows) or zoom.us (macOS) within the last hour. It then updates
this information with historical data and filters out proces_name and endpoint pairs that have not
been seen within the specified time window. This updated table is outputed to disk.
how_to_implement: You must be ingesting endpoint data that tracks process activity,
including parent-child relationships from your endpoints, to populate the Endpoint
data model in the Processes node.
author: David Dorsey, Splunk
search: '| tstats `security_content_summariesonly` min(_time) as firstTimeSeen max(_time) as lastTimeSeen
from datamodel=Endpoint.Processes where (Processes.parent_process_name=zoom.exe OR Processes.parent_process_name=zoom.us)
by Processes.process_name Processes.dest| `drop_dm_object_name(Processes)`
| table firstTimeSeen, lastTimeSeen, process_name, dest
| inputlookup zoom_first_time_child_process append=t
| stats min(firstTimeSeen) as firstTimeSeen max(lastTimeSeen) as lastTimeSeen by process_name, dest
| where lastTimeSeen > relative_time(now(), "`previously_seen_zoom_child_processes_forget_window`")
| outputlookup zoom_first_time_child_process'
tags:
analytics_story:
- Suspicious Zoom Child Processes
detections:
- First Time Seen Child Process of Zoom
deployments:
- Hourly Cache Updates
@@ -21,6 +21,6 @@ tags:
- Suspicious AWS Login Activities
detections:
- Detect AWS Console Login by User from New Country
- Detect AWS Console Login by User from New City
- Detect AWS Console Login by User from New Region
- Detect AWS Console Login by User from New City
- Detect new user AWS Console Login
@@ -0,0 +1,27 @@
name: Update previously seen users in CloudTrail - DM
id: 66ff71c2-7e01-47dd-a041-906688c9d322
version: 1
date: '2020-05-28'
description: This search looks for CloudTrail events where a user logs into the console,
then updates the baseline of the latest and earliest times, City, Region, and Country
we have encountered this user in our dataset, grouped by user, within the last hour.
how_to_implement: You must install and configure the Splunk Add-on for AWS (version 5.1.0 or later)
and Enterprise Security 6.2, which contains the required updates to the Authentication data model
for cloud use cases. Validate the user name entries in `previously_seen_users_console_logins.csv`,
which is a lookup file created by this support search.
author: Rico Valdez, Splunk
search: '| tstats earliest(_time) as firstTime latest(_time) as lastTime from
datamodel=Authentication where Authentication.signature=ConsoleLogin by Authentication.user
Authenticaiton.src | iplocation Authentication.src | rename Authentication.user as user
Authentciation.src as src | table user src City Region Country firstTime lastTime
| inputlookup append=t previously_seen_users_console_logins.csv | stats min(firstTime) as
firstTime max(lastTime) as lastTime by user src City Region Country
| outputlookup previously_seen_users_console_logins.csv'
tags:
analytics_story:
- Suspicious Cloud Authentication Activities
detections:
- Detect AWS Console Login by User from New Country
- Detect AWS Console Login by User from New Region
- Detect AWS Console Login by User from New City
- Detect new user AWS Console Login - DM
+74
View File
@@ -0,0 +1,74 @@
#!/usr/bin/python
'''
Generates circleci jobs from the tests under /tests in the security-content repo.
'''
import glob
import yaml
import argparse
from os import path
import sys
import datetime
from jinja2 import Environment, FileSystemLoader
import re
import os
# global variables
REPO_PATH = ''
VERBOSE = False
OUTPUT_PATH = ''
# def load_objects(file_path, VERBOSE):
# files = []
# test_files = path.join(path.expanduser(REPO_PATH), file_path)
# for file in sorted(glob.glob(test_files)):
# if VERBOSE:
# print("processing test: {0}".format(file))
# files.append(load_file(file))
# return files
#
#
# def load_file(file_path):
# with open(file_path, 'r') as stream:
# try:
# file = list(yaml.safe_load_all(stream))[0]
# except yaml.YAMLError as exc:
# print(exc)
# sys.exit("ERROR: reading {0}".format(file_path))
# return file
def generate_circleci_conf(tests, OUTPUT_PATH, VERBOSE):
j2_env = Environment(loader=FileSystemLoader('bin/jinja2_templates'),
trim_blocks=True)
template = j2_env.get_template('circleci_config.j2')
output_path = OUTPUT_PATH + "config.yml"
utc_time = datetime.datetime.utcnow().replace(microsecond=0).isoformat()
output = template.render(detection_tests=tests, time=utc_time)
with open(output_path, 'w') as f:
f.write(output)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="generates circleci config file from tests", epilog="""
This generates circleci config files that includes all of our CI logic as well as a dynamically created set of detection tests.
The detection tests are defined under the /tests folder on the security-content repository.
The config file is saved under the .circleci/config.yml file.""")
parser.add_argument("-p", "--path", required=False, default=".", help="path to security-content repo, defaults to: .")
parser.add_argument("-o", "--output", required=False, default=".circleci/", help="path to the output directory of circleci config, defaults to: .circleci/")
parser.add_argument("-v", "--verbose", required=False, default=False, action='store_true', help="prints verbose output")
# parse them
args = parser.parse_args()
REPO_PATH = args.path
OUTPUT_PATH = args.output
VERBOSE = args.verbose
#tests = load_objects("tests/*.yml", VERBOSE)
tests = arr = os.listdir("tests/")
generate_circleci_conf(tests, OUTPUT_PATH, VERBOSE)
if VERBOSE:
print("{0} tests have been successfully written to {1}".format(len(tests), OUTPUT_PATH))
print("security content circleci config generation completed..")
+88 -12
View File
@@ -12,6 +12,8 @@ import sys
import datetime
from jinja2 import Environment, FileSystemLoader
import re
from attackcti import attack_client
import csv
# global variables
@@ -19,14 +21,13 @@ REPO_PATH = ''
VERBOSE = False
OUTPUT_PATH = ''
def load_objects(file_path):
def load_objects(file_path, VERBOSE):
files = []
manifest_files = path.join(path.expanduser(REPO_PATH), file_path)
for file in sorted(glob.glob(manifest_files)):
if VERBOSE:
print("processing manifest: {0}".format(file))
files.append(load_file(file))
return files
@@ -55,6 +56,22 @@ def generate_transforms_conf(lookups):
return output_path
def generate_collections_conf(lookups):
filtered_lookups = list(filter(lambda i: 'collection' in i, lookups))
sorted_lookups = sorted(filtered_lookups, key=lambda i: i['name'])
utc_time = datetime.datetime.utcnow().replace(microsecond=0).isoformat()
j2_env = Environment(loader=FileSystemLoader('bin/jinja2_templates'),
trim_blocks=True)
template = j2_env.get_template('collections.j2')
output_path = OUTPUT_PATH + "/default/collections.conf"
output = template.render(lookups=sorted_lookups, time=utc_time)
with open(output_path, 'w') as f:
f.write(output)
return output_path
def generate_savedsearches_conf(detections, response_tasks, baselines, deployments):
@@ -150,6 +167,7 @@ def generate_use_case_library_conf(stories, detections, response_tasks, baseline
sto_res = map_response_tasks_to_stories(response_tasks)
for story in stories:
story['author_name'], story['author_company'] = parse_author_company(story)
if story['name'] in sto_det:
story['detections'] = list(sto_det[story['name']])
if story['name'] in sto_res:
@@ -235,6 +253,12 @@ def generate_workbench_panels(response_tasks, stories):
trim_blocks=True)
template = j2_env.get_template('panel.j2')
output_path = OUTPUT_PATH + "/default/data/ui/panels/workbench_panel_" + response_file_name + ".xml"
if response_task['search'].find(">") is not -1:
response_task['search']= response_task['search'].replace(">","&gt;")
if response_task['search'].find("<") is not -1:
response_task['search']= response_task['search'].replace("<","&lt;")
output = template.render(search=response_task['search'])
with open(output_path, 'w') as f:
f.write(output)
@@ -263,6 +287,22 @@ def parse_data_models_from_search(search):
return False
def parse_author_company(story):
match_author = re.search(r'^([^,]+)', story['author'])
if match_author is None:
match_author = 'no'
else:
match_author = match_author.group(1)
match_company = re.search(r',\s?(.*)$', story['author'])
if match_company is None:
match_company = 'no'
else:
match_company = match_company.group(1)
return match_author, match_company
def get_deployments(object, deployments):
matched_deployments = []
@@ -436,6 +476,33 @@ def prepare_stories(stories, detections):
return stories
def generate_mitre_lookup():
csv_mitre_rows = [["mitre_id", "technique", "tactics", "groups"]]
lift = attack_client()
all_enterprise = lift.get_enterprise(stix_format=False)
enterprise_relationships = lift.get_enterprise_relationships()
enterprise_groups = lift.get_enterprise_groups()
for technique in all_enterprise['techniques']:
apt_groups = []
for relationship in enterprise_relationships:
if (relationship['target_ref'] == technique['id']) and relationship['source_ref'].startswith('intrusion-set'):
for group in enterprise_groups:
if relationship['source_ref'] == group['id']:
apt_groups.append(group['name'])
if len(apt_groups) == 0:
apt_groups.append('no')
csv_mitre_rows.append([technique['technique_id'], technique['technique'], '|'.join(technique['tactic']).replace('-',' ').title(), '|'.join(apt_groups)])
with open('lookups/mitre_enrichment.csv', 'w', newline='') as file:
writer = csv.writer(file)
writer.writerows(csv_mitre_rows)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="generates splunk conf files out of security-content manifests", epilog="""
@@ -450,16 +517,24 @@ if __name__ == "__main__":
REPO_PATH = args.path
OUTPUT_PATH = args.output
VERBOSE = args.verbose
stories = load_objects("stories/*.yml")
macros = load_objects("macros/*.yml")
lookups = load_objects("lookups/*.yml")
baselines = load_objects("baselines/*.yml")
detections = load_objects("detections/*.yml")
responses = load_objects("responses/*.yml")
response_tasks = load_objects("response_tasks/*.yml")
deployments = load_objects("deployments/*.yml")
stories = load_objects("stories/*.yml", VERBOSE)
macros = load_objects("macros/*.yml", VERBOSE)
lookups = load_objects("lookups/*.yml", VERBOSE)
baselines = load_objects("baselines/*.yml", VERBOSE)
detections = load_objects("detections/*.yml", VERBOSE)
responses = load_objects("responses/*.yml", VERBOSE)
response_tasks = load_objects("response_tasks/*.yml", VERBOSE)
deployments = load_objects("deployments/*.yml", VERBOSE)
try:
if VERBOSE:
print("generating Mitre lookups")
generate_mitre_lookup()
except:
print("WARNING: Generation of Mitre lookup failed.")
lookups_path = generate_transforms_conf(lookups)
lookups_path = generate_collections_conf(lookups)
detections = sorted(detections, key=lambda d: d['name'])
response_tasks = sorted(response_tasks, key=lambda i: i['name'])
@@ -476,6 +551,7 @@ if __name__ == "__main__":
generate_workbench_panels(response_tasks, stories)
if VERBOSE:
print("{0} stories have been successfully written to {1}".format(len(stories), story_path))
print("{0} detections have been successfully written to {1}".format(len(detections), detection_path))
+572
View File
@@ -0,0 +1,572 @@
# Python CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/language-python/ for more details
#
#############
# Automatically generated by ci-generator.py in splunk/security-content
# On Date: {{ time }} UTC
# Author: Splunk Security Research
# Contact: research@splunk.com
#############
version: 2.1
orbs:
aws-cli: circleci/aws-cli@0.1.19
slack: circleci/slack@3.4.2
dependencies:
cache_directories:
- "~/.apt-cache"
pre:
- sudo rm -rf /var/cache/apt/archives && sudo ln -s ~/.apt-cache /var/cache/apt/archives && mkdir -p ~/.apt-cache/partial
apt-run: &apt-install
name: install system packages
command: |
sudo apt update -qq
sudo apt install -y python-dev python3-dev -qq
# install go for other testing tools
# but first lets clean up the env
if [ -f goinstall.sh ]; then
rm goinstall.sh
fi
if [ -d ~/.go ]; then
rm -rf ~/.go
fi
wget https://raw.githubusercontent.com/canha/golang-tools-install-script/master/goinstall.sh
sudo chown circleci goinstall.sh
chmod +x goinstall.sh
./goinstall.sh
executors:
content-executor:
docker:
- image: circleci/python:latest
working_directory: ~/repo
jobs:
test-detections:
executor: content-executor
steps:
- run:
name: checkout repo
command: |
if [[ ! -z "${CIRCLE_PULL_REQUEST}" && ! -z "${CIRCLE_PR_NUMBER}" ]]; then
git clone https://${GITHUB_TOKEN}@github.com/splunk/security-content.git
cd security-content
git fetch origin pull/${CIRCLE_PR_NUMBER}/head:${CIRCLE_BRANCH}
git checkout ${CIRCLE_BRANCH}
elif [ "${CIRCLE_BRANCH}" == "" ]; then
git clone https://${GITHUB_TOKEN}@github.com/splunk/security-content.git
else
git clone --branch ${CIRCLE_BRANCH} https://${GITHUB_TOKEN}@github.com/splunk/security-content.git
fi
- run:
name: checkout attack_range repo
command: |
git clone https://${GITHUB_TOKEN}@github.com/splunk/attack_range.git
- restore_cache:
key: virtualenv
- run: *apt-install
- run:
name: install python dependencies
command: |
cd attack_range
rm -rf venv
virtualenv --python=/usr/bin/python3 --clear venv
source venv/bin/activate
pip install -q -r requirements.txt
- aws-cli/setup:
profile-name: default
- add_ssh_keys:
fingerprints:
- "39:68:78:2b:01:d6:35:eb:78:42:28:58:1d:9c:be:90"
- run:
name: install terraform
command: |
wget https://releases.hashicorp.com/terraform/0.12.24/terraform_0.12.24_linux_amd64.zip
sudo unzip terraform_0.12.24_linux_amd64.zip -d /usr/bin
rm terraform_0.12.24_linux_amd64.zip
terraform --version
{% for test in detection_tests %}
- run:
name: detection tests > {{ test }}
command: |
cd attack_range
source venv/bin/activate
# change attack_range default ssh keys
sed -i "s/key_name = .*$/key_name = attack-range-ci-job-security-content/g" attack_range.conf
sed -i "s/automated_testing = .*$/automated_testing = 1/g" attack_range.conf
sed -i "s/github_token =.*$/github_token = ${GITHUB_TOKEN}/g" attack_range.conf
sed -i "s/region = us-west-2/region = us-west-2/g" attack_range.conf
sed -i "s/private_key_path =.*$/private_key_path = ~\/.ssh\/id_rsa_3968782b01d635eb784228581d9cbe90/g" attack_range.conf
sed -i "s/windows_domain_controller = .*$/windows_domain_controller = 1/g" attack_range.conf
sed -i "s/capture_attack_data = .*$/capture_attack_data = 1/g" attack_range.conf
cd terraform/
terraform init
cd ..
python attack_range.py --mode terraform --action test --test_file ../security-content/tests/{{ test }}
{% endfor %}
- run:
name: cleanup terraform on failures
command: |
cd attack_range
source venv/bin/activate
python attack_range.py --mode terraform --action destroy
when: on_fail
validate-content:
executor: content-executor
steps:
- run:
name: checkout repo
command: |
if [[ ! -z "${CIRCLE_PULL_REQUEST}" && ! -z "${CIRCLE_PR_NUMBER}" ]]; then
git clone https://${GITHUB_TOKEN}@github.com/splunk/security-content.git
cd security-content
git fetch origin pull/${CIRCLE_PR_NUMBER}/head:${CIRCLE_BRANCH}
git checkout ${CIRCLE_BRANCH}
elif [ "${CIRCLE_BRANCH}" == "" ]; then
git clone https://${GITHUB_TOKEN}@github.com/splunk/security-content.git
else
git clone --branch ${CIRCLE_BRANCH} https://${GITHUB_TOKEN}@github.com/splunk/security-content.git
fi
- restore_cache:
key: virtualenv
- run: *apt-install
- run:
name: install python dependencies
command: |
cd security-content
rm -rf venv
virtualenv --python=/usr/bin/python3 --clear venv
source venv/bin/activate
pip install -q -r requirements.txt
- save_cache:
key: virtualenv
paths:
- "/security-content/venv"
- run:
name: run validate
command: |
cd security-content
source venv/bin/activate
python bin/validate.py --path . --verbose
- run:
name: run doc-gen
command: |
cd security-content
source venv/bin/activate
python bin/doc-gen.py --path . --output docs -v
- slack/status:
webhook: '${SLACK_WEBHOOK}'
fail_only: true
build-sources:
executor: content-executor
steps:
- run:
name: checkout repo
command: |
if [[ ! -z "${CIRCLE_PULL_REQUEST}" && ! -z "${CIRCLE_PR_NUMBER}" ]]; then
git clone https://${GITHUB_TOKEN}@github.com/splunk/security-content.git
cd security-content
git fetch origin pull/${CIRCLE_PR_NUMBER}/head:${CIRCLE_BRANCH}
git checkout ${CIRCLE_BRANCH}
elif [ "${CIRCLE_BRANCH}" == "" ]; then
git clone https://${GITHUB_TOKEN}@github.com/splunk/security-content.git
else
git clone --branch ${CIRCLE_BRANCH} https://${GITHUB_TOKEN}@github.com/splunk/security-content.git
fi
- run: *apt-install
- run:
name: install python dependencies
command: |
cd security-content
rm -rf venv
virtualenv --python=/usr/bin/python3 --clear venv
source venv/bin/activate
pip install -q -r requirements.txt
- run:
name: run generate
command: |
cd security-content
source venv/bin/activate
python bin/generate.py --path . --output package -v
# make a copy of use_case_lib in order to have ES work :-(
cp package/default/use_case_library.conf package/default/analyticstories.conf
- run:
name: copy lookups .csv files
command: |
cd security-content
# clean up current lookups
rm -rf package/lookups
mkdir package/lookups
# copy over lookups
cd lookups
cp -rv *.csv ../package/lookups
- run:
name: update version and build number
command: |
cd security-content
# check if tag is set, get build number from the tag if set
if [ -z "${CIRCLE_TAG}" ]; then
CONTENT_VERSION=$(grep -oP "(\d.\d.\d+$)" package/default/content-version.conf)
echo "detected content version: $CONTENT_VERSION"
else
CONTENT_VERSION=$(echo $CIRCLE_TAG | grep -oP "\d.\d.\d+")
echo "content version: $CONTENT_VERSION, set by tag: $CIRCLE_TAG"
fi
# update build number and version
sed -i "s/build = .*$/build = $CIRCLE_BUILD_NUM/g" package/default/app.conf
sed -i "s/^version = .*$/version = $CONTENT_VERSION/g" package/default/app.conf
sed -i "s/\"version\": .*$/\"version\": \"$CONTENT_VERSION\"/g" package/app.manifest
sed -i "s/version = .*$/version = $CONTENT_VERSION/g" package/default/content-version.conf
tar -czf content-pack-build.tar.gz package/*
- persist_to_workspace:
root: security-content/
paths:
- content-pack-build.tar.gz
- slack/status:
fail_only: true
webhook: '${SLACK_WEBHOOK}'
build-package:
executor: content-executor
steps:
- attach_workspace:
at: ~/dist
- run:
name: grab splunk packaging toolkit
command: |
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
- run:
name: install splunk packaging toolkit (slim)
command: |
cd ~/slim-latest
sudo pip install --upgrade pip setuptools
sudo pip install virtualenv
virtualenv --python=/usr/bin/python2.7 --clear venv
source venv/bin/activate
pip install semantic_version
pip install .
- run:
name: create a .spl for this build using slim
command: |
source ~/slim-latest/venv/bin/activate
cd ~/dist
tar -zxf content-pack-build.tar.gz
mv package DA-ESS-ContentUpdate
slim package -o upload DA-ESS-ContentUpdate
cp upload/*.tar.gz DA-ESS-ContentUpdate-latest.tar.gz
- store_artifacts:
path: ~/dist/upload
destination: package/
- persist_to_workspace:
root: ~/dist
paths:
- DA-ESS-ContentUpdate-latest.tar.gz
- slack/status:
fail_only: true
webhook: '${SLACK_WEBHOOK}'
run-appinspect:
executor: content-executor
steps:
- attach_workspace:
at: ~/
- run: *apt-install
- run:
name: grab appinspect
command: |
curl -Ls https://download.splunk.com/misc/appinspect/splunk-appinspect-2.0.0.tar.gz -o appinspect-lastest.tar.gz
mkdir appinspect-latest
tar -zxf appinspect-lastest.tar.gz -C appinspect-latest --strip-components=1
- run:
name: install app inspect
command: |
cd appinspect-latest
rm -rf venv
sudo pip install --upgrade pip setuptools
sudo pip install virtualenv
virtualenv --python=/usr/bin/python3 --clear venv
source venv/bin/activate
pip install .
- run:
name: run app inspect
command: |
cd appinspect-latest
source venv/bin/activate
splunk-appinspect inspect ~/DA-ESS-ContentUpdate-latest.tar.gz --included-tags=cloud --max-messages=all
- persist_to_workspace:
root: ~/
paths:
- DA-ESS-ContentUpdate-latest.tar.gz
- slack/status:
fail_only: true
webhook: '${SLACK_WEBHOOK}'
community-api-update:
executor: aws-cli/default
steps:
- attach_workspace:
at: ~/
- run:
name: checkout repo
command: |
if [ "${CIRCLE_BRANCH}" == "" ]; then
git clone community https://${GITHUB_TOKEN}@github.com/splunk/security-content.git
else
git clone --branch ${CIRCLE_BRANCH} https://${GITHUB_TOKEN}@github.com/splunk/security-content.git
fi
- run: *apt-install
- aws-cli/setup:
profile-name: default
- run:
name: update community api sources
command: |
cd security-content
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 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"
aws s3 cp deployments s3://security-content/deployments --recursive --exclude "*" --include "*.yml"
- persist_to_workspace:
root: ~/
paths:
- DA-ESS-ContentUpdate-latest.tar.gz
update-sources-github:
executor: content-executor
steps:
- attach_workspace:
at: ~/
- run: *apt-install
- run:
name: checkout repo
command: |
mkdir ~/latest
tar -zxf ~/DA-ESS-ContentUpdate-latest.tar.gz -C ~/latest --strip-components=1
if [ "${CIRCLE_BRANCH}" == "" ]; then
git clone https://${GITHUB_TOKEN}@github.com/splunk/security-content.git
else
git clone --branch ${CIRCLE_BRANCH} https://${GITHUB_TOKEN}@github.com/splunk/security-content.git
fi
- run:
name: install python dependencies
command: |
cd security-content
rm -rf venv
virtualenv --python=/usr/bin/python3 --clear venv
source venv/bin/activate
pip install -q -r requirements.txt
- run:
name: run doc-gen
command: |
cd security-content
source venv/bin/activate
python bin/doc-gen.py --path . --output docs -v
- run:
name: update github with new docs and package bits
command: |
cd security-content
rm -rf package
mv ~/latest package
# 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 package/*
git add docs/*
git commit --allow-empty -m "updating docs and package bits [ci skip]"
# Push quietly to prevent showing the token in log
git push https://${GITHUB_TOKEN}@github.com/splunk/security-content.git ${CIRCLE_BRANCH}
- persist_to_workspace:
root: ~/
paths:
- DA-ESS-ContentUpdate-latest.tar.gz
- slack/status:
fail_only: true
webhook: '${SLACK_WEBHOOK}'
publish-github-release:
docker:
- image: cibuilds/github:0.10
steps:
- attach_workspace:
at: ~/
- run:
name: publish release on github
command: |
cp ~/DA-ESS-ContentUpdate-latest.tar.gz ~/DA-ESS-ContentUpdate-${CIRCLE_TAG}.tar.gz
ghr -t ${GITHUB_TOKEN} -u ${CIRCLE_PROJECT_USERNAME} -r ${CIRCLE_PROJECT_REPONAME} -c ${CIRCLE_SHA1} -delete ${CIRCLE_TAG} ~/DA-ESS-ContentUpdate-${CIRCLE_TAG}.tar.gz
- persist_to_workspace:
root: ~/
paths:
- DA-ESS-ContentUpdate-latest.tar.gz
- slack/status:
fail_only: true
webhook: '${SLACK_WEBHOOK}'
attack-range-update:
executor: aws-cli/default
steps:
- attach_workspace:
at: ~/
- aws-cli/setup:
profile-name: default
- run:
name: sync latest ESCU to the Attack Range S3 bucket for apps
command: |
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
- slack/status:
fail_only: true
webhook: '${SLACK_WEBHOOK}'
master-api-update:
executor: aws-cli/default
steps:
- run:
name: checkout repo
command: |
if [ "${CIRCLE_BRANCH}" == "" ]; then
git clone https://${GITHUB_TOKEN}@github.com/splunk/security-content.git
else
git clone --branch ${CIRCLE_BRANCH} https://${GITHUB_TOKEN}@github.com/splunk/security-content.git
fi
- run: *apt-install
- aws-cli/setup:
profile-name: default
- run:
name: update api sources
command: |
cd security-content
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 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"
aws s3 cp deployments s3://security-content/deployments --recursive --exclude "*" --include "*.yml"
- slack/status:
fail_only: true
webhook: '${SLACK_WEBHOOK}'
workflows:
version: 2.1
test-detections:
jobs:
- test-detections
triggers:
- schedule:
cron: "0 5 * * *"
filters:
branches:
only:
- develop
validate-and-build:
jobs:
- validate-content:
# build always
filters:
tags:
only: /.*/
- build-sources:
# build always
requires:
- validate-content
filters:
tags:
only: /.*/
- build-package:
# build always
requires:
- validate-content
- build-sources
filters:
tags:
only: /.*/
- run-appinspect:
# build always
requires:
- validate-content
- build-sources
- build-package
filters:
tags:
only: /.*/
- community-api-update:
# build only on community changes
requires:
- validate-content
- build-sources
- build-package
- run-appinspect
filters:
branches:
only: community
- update-sources-github:
# update package and docs in github if is a tag
requires:
- validate-content
- build-sources
- build-package
- run-appinspect
filters:
tags:
only: /^v.*/
branches:
ignore: /.*/
- publish-github-release:
# publish release in github if is a tag
requires:
- validate-content
- build-sources
- build-package
- run-appinspect
- update-sources-github
filters:
tags:
only: /^v.*/
branches:
ignore: /.*/
- attack-range-update:
# update the attack range with the latest build
requires:
- validate-content
- build-sources
- build-package
- run-appinspect
- update-sources-github
- publish-github-release
filters:
tags:
only: /^v.*/
branches:
ignore: /.*/
- master-api-update:
# update master API from develop if is a tag
requires:
- validate-content
- build-sources
- build-package
- run-appinspect
- update-sources-github
- publish-github-release
- attack-range-update
filters:
tags:
only: /^v.*/
branches:
ignore: /.*/
@@ -0,0 +1,575 @@
# Python CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/language-python/ for more details
#
#############
# Automatically generated by ci-generator.py in splunk/security-content
# On Date: {{ time }} UTC
# Author: Splunk Security Research
# Contact: research@splunk.com
#############
version: 2.1
orbs:
aws-cli: circleci/aws-cli@0.1.19
slack: circleci/slack@3.4.2
dependencies:
cache_directories:
- "~/.apt-cache"
pre:
- sudo rm -rf /var/cache/apt/archives && sudo ln -s ~/.apt-cache /var/cache/apt/archives && mkdir -p ~/.apt-cache/partial
apt-run: &apt-install
name: install system packages
command: |
sudo apt update -qq
sudo apt install -y python-dev python3-dev -qq
# install go for other testing tools
# but first lets clean up the env
if [ -f goinstall.sh ]; then
rm goinstall.sh
fi
if [ -d ~/.go ]; then
rm -rf ~/.go
fi
wget https://raw.githubusercontent.com/canha/golang-tools-install-script/master/goinstall.sh
sudo chown circleci goinstall.sh
chmod +x goinstall.sh
./goinstall.sh
executors:
content-executor:
docker:
- image: circleci/python:latest
working_directory: ~/repo
jobs:
test-detections:
executor: content-executor
steps:
- run:
name: checkout repo
command: |
if [[ ! -z "${CIRCLE_PULL_REQUEST}" && ! -z "${CIRCLE_PR_NUMBER}" ]]; then
git clone https://${GITHUB_TOKEN}@github.com/splunk/security-content.git
cd security-content
git fetch origin pull/${CIRCLE_PR_NUMBER}/head:${CIRCLE_BRANCH}
git checkout ${CIRCLE_BRANCH}
elif [ "${CIRCLE_BRANCH}" == "" ]; then
git clone https://${GITHUB_TOKEN}@github.com/splunk/security-content.git
else
git clone --branch ${CIRCLE_BRANCH} https://${GITHUB_TOKEN}@github.com/splunk/security-content.git
fi
- run:
name: checkout attack_range repo
command: |
git clone --single-branch --branch automated_detection_testing https://${GITHUB_TOKEN}@github.com/splunk/attack_range.git
- restore_cache:
key: virtualenv
- run: *apt-install
- run:
name: install python dependencies
command: |
cd attack_range
rm -rf venv
virtualenv --python=/usr/bin/python3 --clear venv
source venv/bin/activate
pip install -q -r requirements.txt
- aws-cli/setup:
profile-name: default
- add_ssh_keys:
fingerprints:
- "39:68:78:2b:01:d6:35:eb:78:42:28:58:1d:9c:be:90"
- run:
name: install terraform
command: |
wget https://releases.hashicorp.com/terraform/0.12.24/terraform_0.12.24_linux_amd64.zip
sudo unzip terraform_0.12.24_linux_amd64.zip -d /usr/bin
rm terraform_0.12.24_linux_amd64.zip
terraform --version
{% for test in detection_tests %}
- run:
name: detection tests > {{ test.name }}
command: |
cd attack_range
source venv/bin/activate
# change attack_range default ssh keys
sed -i "s/key_name = .*$/key_name = attack-range-ci-job-security-content/g" attack_range.conf
sed -i "s/automated_testing = .*$/automated_testing = 1/g" attack_range.conf
sed -i "s/github_token = .*$/github_token = ${GITHUB_ACCESS_TOKEN}/g" attack_range.conf
sed -i "s/region = us-west-2/region = us-west-2/g" attack_range.conf
sed -i "s/private_key_path =.*$/private_key_path = ~\/.ssh\/id_rsa_3968782b01d635eb784228581d9cbe90/g" attack_range.conf
sed -i "s/windows_domain_controller = .*$/windows_domain_controller = 1/g" attack_range.conf
sed -i "s/capture_attack_data = .*$/capture_attack_data = 1/g" attack_range.conf
cat attack_range.conf
cd terraform/
terraform init
cd ..
python attack_range.py --mode terraform --action test --test_file ../security-content/tests/{{ test.name|replace(" ", "_")|lower() }}.yml
{% endfor %}
- run:
name: cleanup terraform on failures
command: |
cd attack_range
source venv/bin/activate
python attack_range.py --mode terraform --action destroy
when: on_fail
validate-content:
executor: content-executor
steps:
- run:
name: checkout repo
command: |
if [[ ! -z "${CIRCLE_PULL_REQUEST}" && ! -z "${CIRCLE_PR_NUMBER}" ]]; then
git clone https://${GITHUB_TOKEN}@github.com/splunk/security-content.git
cd security-content
git fetch origin pull/${CIRCLE_PR_NUMBER}/head:${CIRCLE_BRANCH}
git checkout ${CIRCLE_BRANCH}
elif [ "${CIRCLE_BRANCH}" == "" ]; then
git clone https://${GITHUB_TOKEN}@github.com/splunk/security-content.git
else
git clone --branch ${CIRCLE_BRANCH} https://${GITHUB_TOKEN}@github.com/splunk/security-content.git
fi
- restore_cache:
key: virtualenv
- run: *apt-install
- run:
name: install python dependencies
command: |
cd security-content
rm -rf venv
virtualenv --python=/usr/bin/python3 --clear venv
source venv/bin/activate
pip install -q -r requirements.txt
- save_cache:
key: virtualenv
paths:
- "/security-content/venv"
- run:
name: run validate
command: |
cd security-content
source venv/bin/activate
python bin/validate.py --path . --verbose
- run:
name: run doc-gen
command: |
cd security-content
source venv/bin/activate
python bin/doc-gen.py --path . --output docs -v
- slack/status:
webhook: '${SLACK_WEBHOOK}'
fail_only: true
build-sources:
executor: content-executor
steps:
- run:
name: checkout repo
command: |
if [[ ! -z "${CIRCLE_PULL_REQUEST}" && ! -z "${CIRCLE_PR_NUMBER}" ]]; then
git clone https://${GITHUB_TOKEN}@github.com/splunk/security-content.git
cd security-content
git fetch origin pull/${CIRCLE_PR_NUMBER}/head:${CIRCLE_BRANCH}
git checkout ${CIRCLE_BRANCH}
elif [ "${CIRCLE_BRANCH}" == "" ]; then
git clone https://${GITHUB_TOKEN}@github.com/splunk/security-content.git
else
git clone --branch ${CIRCLE_BRANCH} https://${GITHUB_TOKEN}@github.com/splunk/security-content.git
fi
- run: *apt-install
- run:
name: install python dependencies
command: |
cd security-content
rm -rf venv
virtualenv --python=/usr/bin/python3 --clear venv
source venv/bin/activate
pip install -q -r requirements.txt
- run:
name: run generate
command: |
cd security-content
source venv/bin/activate
python bin/generate.py --path . --output package -v
# make a copy of use_case_lib in order to have ES work :-(
cp package/default/use_case_library.conf package/default/analyticstories.conf
- run:
name: copy lookups .csv files
command: |
cd security-content
# clean up current lookups
rm -rf package/lookups
mkdir package/lookups
# copy over lookups
cd lookups
cp -rv *.csv ../package/lookups
- run:
name: update version and build number
command: |
cd security-content
# check if tag is set, get build number from the tag if set
if [ -z "${CIRCLE_TAG}" ]; then
CONTENT_VERSION=$(grep -oP "(\d.\d.\d+$)" package/default/content-version.conf)
echo "detected content version: $CONTENT_VERSION"
else
CONTENT_VERSION=$(echo $CIRCLE_TAG | grep -oP "\d.\d.\d+")
echo "content version: $CONTENT_VERSION, set by tag: $CIRCLE_TAG"
fi
# update build number and version
sed -i "s/build = .*$/build = $CIRCLE_BUILD_NUM/g" package/default/app.conf
sed -i "s/^version = .*$/version = $CONTENT_VERSION/g" package/default/app.conf
sed -i "s/\"version\": .*$/\"version\": \"$CONTENT_VERSION\"/g" package/app.manifest
sed -i "s/version = .*$/version = $CONTENT_VERSION/g" package/default/content-version.conf
tar -czf content-pack-build.tar.gz package/*
- persist_to_workspace:
root: security-content/
paths:
- content-pack-build.tar.gz
- slack/status:
fail_only: true
webhook: '${SLACK_WEBHOOK}'
build-package:
executor: content-executor
steps:
- attach_workspace:
at: ~/dist
- run:
name: grab splunk packaging toolkit
command: |
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
- run:
name: install splunk packaging toolkit (slim)
command: |
cd ~/slim-latest
sudo pip install --upgrade pip setuptools
sudo pip install virtualenv
virtualenv --python=/usr/bin/python2.7 --clear venv
source venv/bin/activate
pip install semantic_version
pip install .
- run:
name: create a .spl for this build using slim
command: |
source ~/slim-latest/venv/bin/activate
cd ~/dist
tar -zxf content-pack-build.tar.gz
mv package DA-ESS-ContentUpdate
slim package -o upload DA-ESS-ContentUpdate
cp upload/*.tar.gz DA-ESS-ContentUpdate-latest.tar.gz
- store_artifacts:
path: ~/dist/upload
destination: package/
- persist_to_workspace:
root: ~/dist
paths:
- DA-ESS-ContentUpdate-latest.tar.gz
- slack/status:
fail_only: true
webhook: '${SLACK_WEBHOOK}'
run-appinspect:
executor: content-executor
steps:
- attach_workspace:
at: ~/
- run: *apt-install
- run:
name: grab appinspect
command: |
curl -Ls https://download.splunk.com/misc/appinspect/splunk-appinspect-2.0.0.tar.gz -o appinspect-lastest.tar.gz
mkdir appinspect-latest
tar -zxf appinspect-lastest.tar.gz -C appinspect-latest --strip-components=1
- run:
name: install app inspect
command: |
cd appinspect-latest
rm -rf venv
sudo pip install --upgrade pip setuptools
sudo pip install virtualenv
virtualenv --python=/usr/bin/python3 --clear venv
source venv/bin/activate
pip install .
- run:
name: run app inspect
command: |
cd appinspect-latest
source venv/bin/activate
splunk-appinspect inspect ~/DA-ESS-ContentUpdate-latest.tar.gz --included-tags=cloud --max-messages=all
- persist_to_workspace:
root: ~/
paths:
- DA-ESS-ContentUpdate-latest.tar.gz
- slack/status:
fail_only: true
webhook: '${SLACK_WEBHOOK}'
community-api-update:
executor: aws-cli/default
steps:
- attach_workspace:
at: ~/
- run:
name: checkout repo
command: |
if [ "${CIRCLE_BRANCH}" == "" ]; then
git clone community https://${GITHUB_TOKEN}@github.com/splunk/security-content.git
else
git clone --branch ${CIRCLE_BRANCH} https://${GITHUB_TOKEN}@github.com/splunk/security-content.git
fi
- run: *apt-install
- aws-cli/setup:
profile-name: default
- run:
name: update community api sources
command: |
cd security-content
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 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"
aws s3 cp deployments s3://security-content/deployments --recursive --exclude "*" --include "*.yml"
- persist_to_workspace:
root: ~/
paths:
- DA-ESS-ContentUpdate-latest.tar.gz
update-sources-github:
executor: content-executor
steps:
- attach_workspace:
at: ~/
- run: *apt-install
- run:
name: checkout repo
command: |
mkdir ~/latest
tar -zxf ~/DA-ESS-ContentUpdate-latest.tar.gz -C ~/latest --strip-components=1
if [ "${CIRCLE_BRANCH}" == "" ]; then
git clone https://${GITHUB_TOKEN}@github.com/splunk/security-content.git
else
git clone --branch ${CIRCLE_BRANCH} https://${GITHUB_TOKEN}@github.com/splunk/security-content.git
fi
- run:
name: install python dependencies
command: |
cd security-content
rm -rf venv
virtualenv --python=/usr/bin/python3 --clear venv
source venv/bin/activate
pip install -q -r requirements.txt
- run:
name: run doc-gen
command: |
cd security-content
source venv/bin/activate
python bin/doc-gen.py --path . --output docs -v
- run:
name: update github with new docs and package bits
command: |
cd security-content
rm -rf package
mv ~/latest package
# 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 package/*
git add docs/*
git commit --allow-empty -m "updating docs and package bits [ci skip]"
# Push quietly to prevent showing the token in log
git push https://${GITHUB_TOKEN}@github.com/splunk/security-content.git ${CIRCLE_BRANCH}
- persist_to_workspace:
root: ~/
paths:
- DA-ESS-ContentUpdate-latest.tar.gz
- slack/status:
fail_only: true
webhook: '${SLACK_WEBHOOK}'
publish-github-release:
docker:
- image: cibuilds/github:0.10
steps:
- attach_workspace:
at: ~/
- run:
name: publish release on github
command: |
cp ~/DA-ESS-ContentUpdate-latest.tar.gz ~/DA-ESS-ContentUpdate-${CIRCLE_TAG}.tar.gz
ghr -t ${GITHUB_TOKEN} -u ${CIRCLE_PROJECT_USERNAME} -r ${CIRCLE_PROJECT_REPONAME} -c ${CIRCLE_SHA1} -delete ${CIRCLE_TAG} ~/DA-ESS-ContentUpdate-${CIRCLE_TAG}.tar.gz
- persist_to_workspace:
root: ~/
paths:
- DA-ESS-ContentUpdate-latest.tar.gz
- slack/status:
fail_only: true
webhook: '${SLACK_WEBHOOK}'
attack-range-update:
executor: aws-cli/default
steps:
- attach_workspace:
at: ~/
- aws-cli/setup:
profile-name: default
- run:
name: sync latest ESCU to the Attack Range S3 bucket for apps
command: |
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
- slack/status:
fail_only: true
webhook: '${SLACK_WEBHOOK}'
master-api-update:
executor: aws-cli/default
steps:
- run:
name: checkout repo
command: |
if [ "${CIRCLE_BRANCH}" == "" ]; then
git clone https://${GITHUB_TOKEN}@github.com/splunk/security-content.git
else
git clone --branch ${CIRCLE_BRANCH} https://${GITHUB_TOKEN}@github.com/splunk/security-content.git
fi
- run: *apt-install
- aws-cli/setup:
profile-name: default
- run:
name: update api sources
command: |
cd security-content
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 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"
aws s3 cp deployments s3://security-content/deployments --recursive --exclude "*" --include "*.yml"
- slack/status:
fail_only: true
webhook: '${SLACK_WEBHOOK}'
workflows:
version: 2.1
test-detections:
jobs:
- test-detections
triggers:
- schedule:
cron: "4 12 * * *"
filters:
branches:
only:
- master
- develop
- automated_detection_testing
validate-and-build:
jobs:
- validate-content:
# build always
filters:
tags:
only: /.*/
- build-sources:
# build always
requires:
- validate-content
filters:
tags:
only: /.*/
- build-package:
# build always
requires:
- validate-content
- build-sources
filters:
tags:
only: /.*/
- run-appinspect:
# build always
requires:
- validate-content
- build-sources
- build-package
filters:
tags:
only: /.*/
- community-api-update:
# build only on community changes
requires:
- validate-content
- build-sources
- build-package
- run-appinspect
filters:
branches:
only: community
- update-sources-github:
# update package and docs in github if is a tag
requires:
- validate-content
- build-sources
- build-package
- run-appinspect
filters:
tags:
only: /^v.*/
branches:
ignore: /.*/
- publish-github-release:
# publish release in github if is a tag
requires:
- validate-content
- build-sources
- build-package
- run-appinspect
- update-sources-github
filters:
tags:
only: /^v.*/
branches:
ignore: /.*/
- attack-range-update:
# update the attack range with the latest build
requires:
- validate-content
- build-sources
- build-package
- run-appinspect
- update-sources-github
- publish-github-release
filters:
tags:
only: /^v.*/
branches:
ignore: /.*/
- master-api-update:
# update master API from develop if is a tag
requires:
- validate-content
- build-sources
- build-package
- run-appinspect
- update-sources-github
- publish-github-release
- attack-range-update
filters:
tags:
only: /^v.*/
branches:
ignore: /.*/
+13
View File
@@ -0,0 +1,13 @@
#############
# Automatically generated by generator.py in splunk/security-content
# On Date: {{ time }} UTC
# Author: Splunk Security Research
# Contact: research@splunk.com
#############
{% for lookup in lookups %}
[{{ lookup.name }}]
enforceTypes = false
replicate = false
{% endfor %}
+2 -1
View File
@@ -94,7 +94,7 @@ search = {{ detection.search }}
### ESCU BASELINES ###
{% for baseline in baselines %}
[ESCU - {{ baseline.name }} - Baseline]
[ESCU - {{ baseline.name }}]
action.escu = 0
action.escu.enabled = 1
action.escu.search_type = support
@@ -112,6 +112,7 @@ action.escu.data_models = [{{ baseline.data_model | tojson }}]
{% else %}
action.escu.data_models = []
{% endif %}
cron_schedule = {{ baseline.deployment.scheduling.cron_schedule }}
dispatch.earliest_time = {{ baseline.deployment.scheduling.earliest_time }}
dispatch.latest_time = {{ baseline.deployment.scheduling.latest_time }}
{% if baseline.deployment.scheduling.schedule_window is defined %}
+8 -1
View File
@@ -11,6 +11,7 @@
filename = {{ lookup.filename }}
{% else %}
collection = {{ lookup.collection }}
external_type = kvstore
{% endif %}
{% if lookup.default_match is defined %}
default_match = {{ lookup.default_match }}
@@ -30,5 +31,11 @@ max_matches = {{ lookup.max_matches }}
{% if lookup.min_matches is defined %}
min_matches = {{ lookup.min_matches }}
{% endif %}
{% if lookup.fields_list is defined %}
fields_list = {{ lookup.fields_list }}
{% endif %}
{% if lookup.filter is defined %}
filter = {{ lookup.filter }}
{% endif %}
{% endfor %}
{% endfor %}
+3 -3
View File
@@ -13,7 +13,7 @@ category = {{ story.tags.category[0] }}
last_updated = {{ story.date }}
version = {{ story.version }}
references = {{ story.references | tojson }}
maintainers = {{ story.author | tojson }}
maintainers = [{"company": "{{ story.author_company }}", "email": "-", "name": "{{ story.author_name }}"}]
spec_version = 3
searches = {{ story.searches | tojson }}
description = {{ story.description }}
@@ -29,7 +29,7 @@ narrative = {{ story.narrative }}
{% for detection in detections %}
[savedsearch://ESCU - {{ detection.name }} - Rule]
type = detection
asset_type = {{ detection.asset_type }}
asset_type = {{ detection.tags.asset_type }}
confidence = medium
explanation = {{ detection.description }}
{% if detection.how_to_implement is defined %}
@@ -39,7 +39,7 @@ how_to_implement = none
{% endif %}
annotations = {{ detection.mappings | tojson }}
known_false_positives = {{ detection.known_false_positives }}
providing_technologies = none
providing_technologies = []
{% endfor %}
### END DETECTIONS ###
@@ -4,9 +4,9 @@ date: '2020-04-27'
description: This configuration file applies to all correlation searches that are used for detection
author: Bhavin Patel
scheduling:
cron_schedule: '*/30 * * * *'
earliest_time: -30m
latest_time: now
cron_schedule: '0 * * * *'
earliest_time: -70m@m
latest_time: -10m@m
schedule_window: auto
alert_action:
notable:
@@ -0,0 +1,13 @@
name: Baseline Cache Hourly Updates
id: 1030c701-2acf-4b1a-9970-46c7145caf2d
date: '2020-06-24'
description: This configuration file applies to all baselines with tag deployments Hourly Cache Updates
author: Bhavin Patel
scheduling:
cron_schedule: '55 * * * *'
earliest_time: -70m@m
latest_time: -10m@m
schedule_window: auto
tags:
deployments:
- Hourly Cache Updates
@@ -0,0 +1,13 @@
name: 90 Day Baseline Searches
id: 6eac9f8b-a35d-4b64-b57f-e5ecde43be6b
date: '2020-06-24'
description: This configuration file applies to all baselines with tag deployments Long Running Baseline
author: Bhavin Patel
scheduling:
cron_schedule: '0 4 * * *'
earliest_time: -90d@d
latest_time: -10m@m
schedule_window: auto
tags:
deployments:
- 90 Day Baseline
@@ -28,6 +28,8 @@ tags:
- Suspicious AWS EC2 Activities
kill_chain_phases:
- Actions on Objectives
mitre_attack_id:
- T1078
cis20:
- CIS 13
nist:
@@ -24,6 +24,8 @@ tags:
- Suspicious AWS EC2 Activities
kill_chain_phases:
- Actions on Objectives
mitre_attack_id:
- T1078
cis20:
- CIS 13
nist:
@@ -28,6 +28,8 @@ tags:
- Suspicious AWS EC2 Activities
kill_chain_phases:
- Actions on Objectives
mitre_attack_id:
- T1078
cis20:
- CIS 13
nist:
@@ -23,6 +23,8 @@ tags:
- Suspicious AWS EC2 Activities
kill_chain_phases:
- Actions on Objectives
mitre_attack_id:
- T1078
cis20:
- CIS 13
nist:
@@ -23,7 +23,7 @@ tags:
analytics_story:
- Credential Dumping
mitre_attack_id:
- T1003
- T1003.001
kill_chain_phases:
- Actions on Objectives
cis20:
@@ -14,7 +14,7 @@ author: Rico Valdez, Splunk
search: '| tstats `security_content_summariesonly` count min(_time) as firstTime values(Processes.process)
as process max(_time) as lastTime from datamodel=Endpoint.Processes where Processes.process_name=certutil.exe
(Processes.process=*-addstore* AND Processes.process=*disallowed* ) by Processes.parent_process
Processes.process_name Processes.user | `drop_dm_object_name("Processes")` | `security_content_ctime(firstTime)`|`security_content_ctime(lastTime)`
Processes.process_name Processes.user | `drop_dm_object_name("Processes")` | `security_content_ctime(firstTime)` |`security_content_ctime(lastTime)`
| `attempt_to_add_certificate_to_untrusted_store_filter`'
known_false_positives: There may be legitimate reasons for administrators to add a
certificate to the untrusted certificate store. In such cases, this will typically
@@ -17,7 +17,7 @@ search: "| tstats `security_content_summariesonly` count min(_time) as firstTime
\ (Registry.registry_value_name=Unrestricted OR Registry.registry_value_name=Bypass)\
\ by Registry.registry_path Registry.registry_key_name Registry.registry_value_name\
\ Registry.dest | `drop_dm_object_name(Registry)` | `security_content_ctime(firstTime)`|\
\ `security_content_ctime(lastTime)` | `attempt_to_set_default_powershell_execution_policy_to_unrestricted_or_bypass_filter` "
\ `security_content_ctime(lastTime)` | `attempt_to_set_default_powershell_execution_policy_to_unrestricted_or_bypass_filter`\_"
known_false_positives: Administrators may attempt to change the default execution
policy on a system for a variety of reasons. However, setting the policy to "unrestricted"
or "bypass" as this search is designed to identify, would be unusual. Hits should
@@ -23,7 +23,7 @@ tags:
analytics_story:
- Credential Dumping
mitre_attack_id:
- T1003
- T1003.002
kill_chain_phases:
- Actions on Objectives
cis20:
@@ -37,6 +37,8 @@ known_false_positives: "This is a strictly behavioral search, so we define \"fal
tags:
analytics_story:
- AWS Suspicious Provisioning Activities
mitre_attack_id:
- T1535
cis20:
- CIS 1
nist:
@@ -38,6 +38,8 @@ known_false_positives: "This is a strictly behavioral search, so we define \"fal
tags:
analytics_story:
- AWS Suspicious Provisioning Activities
mitre_attack_id:
- T1535
cis20:
- CIS 1
nist:
@@ -37,6 +37,8 @@ known_false_positives: "This is a strictly behavioral search, so we define \"fal
tags:
analytics_story:
- AWS Suspicious Provisioning Activities
mitre_attack_id:
- T1535
cis20:
- CIS 1
nist:
@@ -1,6 +1,6 @@
name: AWS Cross Account Activity From Previously Unseen Account
id: 64fbbddf-fabf-4edf-80b3-0cc36ef37727
version: 2
version: 3
date: '2018-11-02'
description: This search looks for AssumeRole events where an IAM role in a different
account is requested for the first time.
@@ -15,12 +15,10 @@ author: David Dorsey, Splunk
search: '`cloudtrail` eventName=AssumeRole | spath output=requestingAccountId path=userIdentity.accountId
| spath output=requestedAccountId path=resources{}.accountId | search requestingAccountId=*
| where requestingAccountId != requestedAccountId | inputlookup append=t previously_seen_aws_cross_account_activity
| multireport [| stats min(eval(coalesce(firstTime, strptime(_time,"%Y-%m-%d %H:%M:%S"))))
as firstTime max(eval(coalesce(strptime(_time,"%Y-%m-%d %H:%M:%S"), lastTime)))
| multireport [| stats min(eval(coalesce(firstTime, _time))) as firstTime max(eval(coalesce(lastTime, _time)))
as lastTime by requestingAccountId, requestedAccountId | outputlookup previously_seen_aws_cross_account_activity
| where fact=fiction] [| eventstats min(eval(coalesce(firstTime, strptime(_time,"%Y-%m-%d
%H:%M:%S")))) as firstTime, max(eval(coalesce(strptime(_time,"%Y-%m-%d %H:%M:%S"),
lastTime))) as lastTime by requestingAccountId, requestedAccountId | where firstTime
| where fact=fiction] [| eventstats min(eval(coalesce(firstTime, _time))) as firstTime,
max(eval(coalesce(lastTime, _time))) as lastTime by requestingAccountId, requestedAccountId | where firstTime
>= relative_time(now(), "-70m@m") AND isnotnull(_time) | spath output=accessKeyId
path=responseElements.credentials.accessKeyId | spath output=requestingARN path=resources{}.ARN
| stats values(awsRegion) as awsRegion values(firstTime) as firstTime values(lastTime)
@@ -36,6 +34,8 @@ tags:
- AWS Cross Account Activity
kill_chain_phases:
- Actions on Objectives
mitre_attack_id:
- T1078
cis20:
- CIS 16
nist:
@@ -27,10 +27,10 @@ known_false_positives: It's possible that an enterprise has more than five DNS s
that are configured in a round-robin rotation. Please customize the search, as appropriate.
tags:
analytics_story:
- Command and Control
- Host Redirection
- Suspicious DNS Traffic
- DNS Hijacking
- Command and Control
- Suspicious DNS Traffic
- Host Redirection
mitre_attack_id:
- T1048
kill_chain_phases:
@@ -28,6 +28,8 @@ tags:
- Cloud Cryptomining
cis20:
- CIS 1
mitre_attack_id:
- T1078
nist:
- ID.AM
security_domain: endpoint
@@ -29,6 +29,8 @@ tags:
- Cloud Cryptomining
kill_chain_phases:
- Actions on Objectives
mitre_attack_id:
- T1535
cis20:
- CIS 12
nist:
+1 -1
View File
@@ -15,7 +15,7 @@ author: David Dorsey, Splunk
search: '| tstats `security_content_summariesonly` count min(_time) as firstTime max(_time)
as lastTime values(Filesystem.user) as user values(Filesystem.dest) as dest values(Filesystem.file_path)
as file_path from datamodel=Endpoint.Filesystem by Filesystem.file_name | `drop_dm_object_name(Filesystem)`
| `security_content_ctime(lastTime)` | `security_content_ctime(firstTime)`|`ransomware_notes`|
| `security_content_ctime(lastTime)` | `security_content_ctime(firstTime)` | `ransomware_notes` |
`common_ransomware_notes_filter`'
known_false_positives: It's possible that a legitimate file could be created with
the same name used by ransomware note files.
@@ -14,11 +14,11 @@ references: []
author: Bhavin Patel, Splunk
search: '| tstats `security_content_summariesonly` count values(Processes.user) as
user values(Processes.parent_process) as parent_process min(_time) as firstTime
max(_time) as lastTime from datamodel=Endpoint.Processes where (Processs.process_name=net.exe
OR Processes.process_name=net1.exe) by Processes.process Processes.process_name
Processes.dest | `drop_dm_object_name(Processes)` | `security_content_ctime(firstTime)`|
`security_content_ctime(lastTime)` | search (process=*localgroup* OR process=*/add*
OR process=*user*) |`create_local_admin_accounts_using_net_exe_filter` '
max(_time) as lastTime from datamodel=Endpoint.Processes where (Processes.process_name=net.exe
OR Processes.process_name=net1.exe) AND (Processes.process=*localgroup* OR Processes.process=*/add*
OR Processes.process=*user*) by Processes.process Processes.process_name Processes.dest
| `drop_dm_object_name(Processes)` | `security_content_ctime(firstTime)`| `security_content_ctime(lastTime)`
|`create_local_admin_accounts_using_net_exe_filter` '
known_false_positives: Administrators often leverage net.exe to create admin accounts.
tags:
analytics_story:
@@ -19,8 +19,7 @@ search: '| tstats `security_content_summariesonly` count values(Processes.user)
max(_time) as lastTime from datamodel=Endpoint.Processes where (Processs.process_name=net.exe
OR Processes.process_name=net1.exe) by Processes.process Processes.process_name
Processes.dest | `drop_dm_object_name(Processes)` | `security_content_ctime(firstTime)`|
`security_content_ctime(lastTime)` | search (process=*share* AND process=*delete*)
| `create_or_delete_windows_shares_using_net_exe_filter` '
`security_content_ctime(lastTime)` | search process=*share* | `create_or_delete_windows_shares_using_net_exe_filter` '
known_false_positives: Administrators often leverage net.exe to create or delete network
shares. You should verify that the activity was intentional and is legitimate.
tags:
@@ -16,14 +16,14 @@ author: Patrick Bareiss, Splunk
search: '`sysmon` EventID=8 TargetImage=*lsass.exe | stats count min(_time) as firstTime
max(_time) as lastTime by Computer, EventCode, TargetImage, TargetProcessId | rename
Computer as dest | `security_content_ctime(firstTime)`| `security_content_ctime(lastTime)`
|`create_remote_thread_into_lsass_filter`'
| `create_remote_thread_into_lsass_filter`'
known_false_positives: Other tools can access LSASS for legitimate reasons and generate
an event. In these cases, tweaking the search may help eliminate noise.
tags:
analytics_story:
- Credential Dumping
mitre_attack_id:
- T1003
- T1003.001
kill_chain_phases:
- Actions on Objectives
cis20:
+1 -1
View File
@@ -26,7 +26,7 @@ tags:
analytics_story:
- Credential Dumping
mitre_attack_id:
- T1003
- T1003.003
kill_chain_phases:
- Actions on Objectives
cis20:
@@ -4,26 +4,21 @@ version: 1
date: '2019-12-10'
description: This search detects the use of wmic and Powershell to create a shadow
copy.
how_to_implement: You must enable Powershell scriptblock logging in order to detect
this attack.This search uses an input macro named `sysmon`. We strongly recommend
that you specify your environment-specific configurations (index, source, sourcetype,
etc.) for Windows Sysmon logs. Replace the macro definition with configurations
for your Splunk environment. The search also uses a post-filter macro designed to
filter out known false positives.
type: ESCU
references:
- https://2017.zeronights.org/wp-content/uploads/materials/ZN17_Kheirkhabarov_Hunting_for_Credentials_Dumping_in_Windows_Environment.pdf
author: Patrick Bareiss, Splunk
search: '`sysmon` Message=*win32_shadowcopy* Message=*Create* | stats count min(_time)
as firstTime max(_time) as lastTime by dvc User EventCode Message | rename User
as user, dvc as dest | `security_content_ctime(firstTime)`| `security_content_ctime(lastTime)`
| `creation_of_shadow_copy_with_wmic_and_powershell_filter` '
search: '| tstats `security_content_summariesonly` count min(_time) as firstTime max(_time) as lastTime from datamodel=Endpoint.Processes
where Processes.process_name=wmic* OR Processes.process_name=powershell* Processes.process=*shadowcopy* Processes.process=*create*
by Processes.user Processes.process_name Processes.process Processes.dest
| `drop_dm_object_name(Processes)` | `security_content_ctime(firstTime)`| `security_content_ctime(lastTime)`
| `creation_of_shadow_copy_with_wmic_and_powershell_filter`'
known_false_positives: Legtimate administrator usage of wmic to create a shadow copy.
tags:
analytics_story:
- Credential Dumping
mitre_attack_id:
- T1003
- T1003.003
kill_chain_phases:
- Actions on Objectives
cis20:
@@ -24,7 +24,7 @@ tags:
analytics_story:
- Credential Dumping
mitre_attack_id:
- T1003
- T1003.003
kill_chain_phases:
- Actions on Objectives
cis20:
@@ -22,7 +22,7 @@ tags:
analytics_story:
- Credential Dumping
mitre_attack_id:
- T1003
- T1003.003
kill_chain_phases:
- Actions on Objectives
cis20:
+1 -1
View File
@@ -24,8 +24,8 @@ known_false_positives: vssadmin.exe and wmic.exe are standard applications shipp
delete old backup copies, although this is typically rare.
tags:
analytics_story:
- SamSam Ransomware
- Windows Log Manipulation
- SamSam Ransomware
- Ransomware
kill_chain_phases:
- Actions on Objectives
@@ -19,8 +19,8 @@ known_false_positives: It's possible for legitimate HTTP requests to be made to
containing the suspicious paths.
tags:
analytics_story:
- SamSam Ransomware
- JBoss Vulnerability
- SamSam Ransomware
mitre_attack_id:
- T1082
kill_chain_phases:
@@ -51,6 +51,8 @@ tags:
- Actions on Objectives
cis20:
- CIS 16
mitre_attack_id:
- T1078
nist:
- DE.DP
- DE.CM
@@ -30,8 +30,11 @@ known_false_positives: When a legitimate new user logins for the first time, thi
tags:
analytics_story:
- Suspicious AWS Login Activities
- Suspicious Cloud Authentication Activities
kill_chain_phases:
- Actions on Objectives
mitre_attack_id:
- T1535
cis20:
- CIS 16
nist:
@@ -30,8 +30,11 @@ known_false_positives: When a legitimate new user logins for the first time, thi
tags:
analytics_story:
- Suspicious AWS Login Activities
- Suspicious Cloud Authentication Activities
kill_chain_phases:
- Actions on Objectives
mitre_attack_id:
- T1535
cis20:
- CIS 16
nist:
@@ -30,8 +30,11 @@ known_false_positives: When a legitimate new user logins for the first time, thi
tags:
analytics_story:
- Suspicious AWS Login Activities
- Suspicious Cloud Authentication Activities
kill_chain_phases:
- Actions on Objectives
mitre_attack_id:
- T1535
cis20:
- CIS 16
nist:
@@ -26,7 +26,7 @@ tags:
analytics_story:
- Credential Dumping
mitre_attack_id:
- T1003
- T1003.001
kill_chain_phases:
- Actions on Objectives
cis20:
@@ -44,12 +44,12 @@ known_false_positives: Some users and applications may leverage Dynamic DNS to r
however this activity must be verified.
tags:
analytics_story:
- Data Protection
- Prohibited Traffic Allowed or Protocol Mismatch
- Suspicious DNS Traffic
- DNS Hijacking
- Suspicious DNS Traffic
- Dynamic DNS
- Command and Control
- Data Protection
kill_chain_phases:
- Command and Control
- Actions on Objectives
@@ -28,8 +28,8 @@ known_false_positives: It's possible that legitimate TXT record responses can be
to help mitigate false positives.
tags:
analytics_story:
- Command and Control
- Suspicious DNS Traffic
- Command and Control
mitre_attack_id:
- T1043
kill_chain_phases:
@@ -20,8 +20,8 @@ search: '| tstats `security_content_summariesonly` count min(_time) as firstTime
known_false_positives: No known false positives for this detection.
tags:
analytics_story:
- SamSam Ransomware
- JBoss Vulnerability
- SamSam Ransomware
kill_chain_phases:
- Delivery
cis20:
@@ -28,6 +28,9 @@ known_false_positives: It is possible that there are legitimate user roles makin
tags:
analytics_story:
- AWS User Monitoring
mitre_attack_id:
- T1078
- T1098
cis20:
- CIS 1
nist:
+9 -32
View File
@@ -1,41 +1,18 @@
name: Detect New Local Admin account
id: b25f6f62-0712-43c1-b203-083231ffd97d
version: 1
date: '2019-02-28'
version: 2
date: '2020-07-08'
description: This search looks for newly created accounts that have been elevated
to local administrators.
how_to_implement: 'You must be ingesting Windows Security logs. You must also enable
the account change auditing here:http://docs.splunk.com/Documentation/Splunk/7.0.2/Data/MonitorWindowseventlogdata.
Additionally, this search requires you to enable your Group Management Audit Logs
in your Local Windows Security Policy and to be ingesting those logs. More information
on how to enable them can be found here: http://whatevernetworks.com/auditing-group-membership-changes-in-active-directory/.
Finally, please make sure that the local administrator group name is "Administrators"
to be able to look for the right group membership changes.\
This search produces fields (`Security_ID`,`Group_Name`,`Message`) that are not
yet supported by ES Incident Review and therefore cannot be viewed when a notable
event is raised. These fields contribute additional context to the notable. To see
the additional metadata, add the following fields, if not already present, to Incident
Review - Event Attributes (Configure > Incident Management > Incident Review Settings
> Add New Entry):\\n1. **Label:** Security ID, **Field:** Security_ID\
1. \
1. **Label:** Group Name, **Field:** Group_Name\
1. \
1. **Label:** Message, **Field:** Message\
Detailed documentation on how to create a new field within Incident Review may be
found here: `https://docs.splunk.com/Documentation/ES/5.3.0/Admin/Customizenotables#Add_a_field_to_the_notable_event_details`'
type: ESCU
references: []
author: David Dorsey, Splunk
search: '`wineventlog_security` signature_id=4720 OR (signature_id=4732 Group_Name=
Administrators) | transaction Security_ID connected=false maxspan=180m | search
signature_id=4720 signature_id=4732 | table _time user dest signature_id Security_ID
Group_Name src_user Message | `detect_new_local_admin_account_filter`'
search: '`wineventlog_security` EventID=4720 OR (EventID=4732 Group_Name=Administrators)
| transaction MemberSid connected=false maxspan=180m
| rename MemberSid as user
| stats count min(_time) as firstTime max(_time) as lastTime by user dest
| `security_content_ctime(firstTime)`| `security_content_ctime(lastTime)`
| `detect_new_local_admin_account_filter`'
known_false_positives: The activity may be legitimate. For this reason, it's best
to verify the account with an administrator and ask whether there was a valid service
request for the account creation. If your local administrator group name is not
@@ -44,7 +21,7 @@ tags:
analytics_story:
- DHS Report TA18-074A
mitre_attack_id:
- T1078
- T1136.001
kill_chain_phases:
- Actions on Objectives
- Command and Control
@@ -25,6 +25,8 @@ tags:
- Suspicious AWS S3 Activities
kill_chain_phases:
- Actions on Objectives
mitre_attack_id:
- T1530
cis20:
- CIS 13
nist:
@@ -29,6 +29,8 @@ tags:
- Suspicious AWS Login Activities
kill_chain_phases:
- Actions on Objectives
mitre_attack_id:
- T1078
cis20:
- CIS 16
nist:
@@ -0,0 +1,33 @@
name: Detect new user AWS Console Login - DM
id: bc91a8cd-35e7-4bb2-6140-e756cc46fd71
version: 1
date: '2020-05-28'
description: This search looks for CloudTrail events wherein a console login event
by a user was recorded within the last hour, then compares the event to a lookup
file of previously seen users (by ARN values) who have logged into the console.
The alert is fired if the user has logged into the console for the first time within
the last hour
how_to_implement: You must install and configure the Splunk Add-on for AWS (version 5.1.0 or later)
and Enterprise Security 6.2, which contains the required updates to the Authentication data model
for cloud use cases. Run the "Previously seen users in CloudTrail" support search only once to
create a baseline of previously seen IAM users within the last 30 days. Run "Update
previously seen users in CloudTrail" hourly (or more frequently depending on how
often you run the detection searches) to refresh the baselines.
type: ESCU
author: Rico Valdez, Splunk
search: "| tstats earliest(_time) as firstTime latest(_time) as lastTime from datamodel=Authentication where Authentication.signature=ConsoleLogin by Authentication.user | `drop_dm_object_name(Authentication)` | inputlookup append=t previously_seen_users_console_logins.csv | stats min(firstTime) as firstTime max(lastTime) as lastTime by user | eval userStatus=if(firstTime >=relative_time(now(), '-70m@m'), 'First Time Logging into AWS Console','Previously Seen User')| `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`| `detect_new_user_aws_console_login___dm_filter`"
known_false_positives: When a legitimate new user logins for the first time, this
activity will be detected. Check how old the account is and verify that the user
activity is legitimate.
tags:
analytics_story:
- Suspicious Cloud Authentication Activities
kill_chain_phases:
- Actions on Objectives
cis20:
- CIS 16
nist:
- DE.DP
- DE.AE
security_domain: network
asset_type: AWS Instance
@@ -1,28 +1,24 @@
name: Detect Path Interception By Creation Of program exe
id: c77162d3-f93c-45cc-80c8-22f6v5264g9f
version: 2
date: '2018-11-15'
description: 'The search is looking for the creation of program.exe in the C: drive. The
creation of this file in that location may be driven by a motive to perform path
interception.'
how_to_implement: You must be ingesting data that records the file-system activity
from your hosts to populate the Endpoint file-system data model node. This is typically
populated via endpoint detection-and-response products, such as Carbon Black, or
other endpoint data sources, such as Sysmon. The data used for this search is typically
generated via logs that report file system reads and writes.
version: 3
date: '2020-07-03'
description: 'The detection Detect Path Interception By Creation Of program exe is detecting the abuse of
unquoted service paths, which is a popular technique for privilege escalation. '
type: ESCU
references: []
author: Bhavin Patel, Splunk
search: '| tstats `security_content_summariesonly` count min(_time) as firstTime max(_time)
as lastTime values(Filesystem.user) as user values(Filesystem.dest) as dest values(Filesystem.file_hash)
as file_hash values(Filesystem.file_path) as file_path from datamodel=Endpoint.Filesystem
where Filesystem.file_path="C:\\program.exe" by Filesystem.file_name | `drop_dm_object_name(Filesystem)`
| `security_content_ctime(lastTime)` | `security_content_ctime(firstTime)` | `detect_path_interception_by_creation_of_program_exe_filter`'
known_false_positives: 'It is unlikely that a normal user may create and place this
file in the C: drive. Confirm with the user.'
references:
- https://medium.com/@SumitVerma101/windows-privilege-escalation-part-1-unquoted-service-path-c7a011a8d8ae
author: Patrick Bareiss, Splunk
search: '| tstats `security_content_summariesonly` count min(_time) as firstTime max(_time) as lastTime from
datamodel=Endpoint.Processes where Processes.parent_process_name=services.exe by Processes.user Processes.process_name
Processes.process Processes.dest | `drop_dm_object_name(Processes)` | rex field=process "^.*\\\\(?<service_process>.*\.(?:exe|bat|com|ps1))"
| eval process_name = lower(process_name) | eval service_process = lower(service_process)| where process_name != service_process
| `security_content_ctime(firstTime)`| `security_content_ctime(lastTime)` | `detect_path_interception_by_creation_of_program_exe_filter`'
known_false_positives: unknown
tags:
analytics_story:
- Windows Persistence Techniques
mitre_attack_id:
- T1054.009
kill_chain_phases:
- Actions on Objectives
cis20:
@@ -31,4 +27,4 @@ tags:
- PR.PT
- DE.CM
security_domain: endpoint
asset_type: ''
asset_type: Endpoint
@@ -24,6 +24,7 @@ tags:
analytics_story:
- Suspicious Command-Line Executions
- Suspicious MSHTA Activity
- Suspicious Zoom Child Processes
mitre_attack_id:
- T1059
kill_chain_phases:
@@ -28,6 +28,8 @@ tags:
- Suspicious AWS S3 Activities
kill_chain_phases:
- Actions on Objectives
mitre_attack_id:
- T1530
cis20:
- CIS 13
- CIS 14
@@ -54,6 +54,8 @@ tags:
- AWS User Monitoring
kill_chain_phases:
- Actions on Objectives
mitre_attack_id:
- T1078
cis20:
- CIS 16
nist:
@@ -41,9 +41,9 @@ known_false_positives: The false-positive rate may vary based on the values of`d
of blocked outbound connections.
tags:
analytics_story:
- Command and Control
- AWS Network ACL Activity
- Suspicious AWS Traffic
- Command and Control
kill_chain_phases:
- Actions on Objectives
- Command and Control
@@ -36,6 +36,8 @@ known_false_positives: Based on the values of`dataPointThreshold` and `deviation
tags:
analytics_story:
- Suspicious AWS S3 Activities
mitre_attack_id:
- T1530
kill_chain_phases:
- Actions on Objectives
cis20:
@@ -39,6 +39,8 @@ tags:
- AWS User Monitoring
kill_chain_phases:
- Actions on Objectives
mitre_attack_id:
- T1078
cis20:
- CIS 16
nist:
@@ -22,8 +22,8 @@ search: '| tstats `security_content_summariesonly` count values(Processes.proces
known_false_positives: Some legitimate applications may exhibit this behavior.
tags:
analytics_story:
- Suspicious Command-Line Executions
- 'Emotet Malware DHS Report TA18-201A '
- Suspicious Command-Line Executions
mitre_attack_id:
- T1059
kill_chain_phases:
+1 -1
View File
@@ -39,9 +39,9 @@ known_false_positives: It's possible that normal DNS traffic will exhibit this b
can also be modified to better suit your environment.
tags:
analytics_story:
- Command and Control
- Data Protection
- Suspicious DNS Traffic
- Command and Control
mitre_attack_id:
- T1043
kill_chain_phases:
@@ -21,8 +21,8 @@ known_false_positives: This registry key may be modified via administrators to i
a change in system policy. This type of change should be a very rare occurrence.
tags:
analytics_story:
- Suspicious Windows Registry Activities
- Windows Defense Evasion Tactics
- Suspicious Windows Registry Activities
mitre_attack_id:
- T1112
kill_chain_phases:
@@ -47,9 +47,9 @@ known_false_positives: If you are seeing more results than desired, you may cons
the support search to re-build the ML model on the latest data.
tags:
analytics_story:
- Command and Control
- Hidden Cobra Malware
- Suspicious DNS Traffic
- Command and Control
mitre_attack_id:
- T1043
kill_chain_phases:
@@ -18,9 +18,9 @@ search: '| tstats `security_content_summariesonly` count from datamodel=Network_
known_false_positives: It's possible there can be long domain names that are legitimate.
tags:
analytics_story:
- Command and Control
- Hidden Cobra Malware
- Suspicious DNS Traffic
- Command and Control
mitre_attack_id:
- T1043
kill_chain_phases:
@@ -18,10 +18,10 @@ known_false_positives: Legitimate DNS activity can be detected in this search. I
verify and update the list of authorized DNS servers as appropriate.
tags:
analytics_story:
- Command and Control
- Host Redirection
- Suspicious DNS Traffic
- DNS Hijacking
- Command and Control
- Suspicious DNS Traffic
- Host Redirection
kill_chain_phases:
- Command and Control
cis20:
+1 -1
View File
@@ -22,7 +22,7 @@ tags:
analytics_story:
- Credential Dumping
mitre_attack_id:
- T1003
- T1003.001
kill_chain_phases:
- Actions on Objectives
cis20:
@@ -26,6 +26,8 @@ known_false_positives: It's possible that a new user will start to modify EC2 in
tags:
analytics_story:
- Unusual AWS EC2 Modifications
mitre_attack_id:
- T1078
cis20:
- CIS 1
nist:
@@ -27,6 +27,9 @@ tags:
- Suspicious AWS EC2 Activities
kill_chain_phases:
- Actions on Objectives
mitre_attack_id:
- T1078
- T1535
cis20:
- CIS 12
nist:
@@ -27,6 +27,8 @@ tags:
analytics_story:
- AWS Cryptomining
- Suspicious AWS EC2 Activities
mitre_attack_id:
- T1078
cis20:
- CIS 1
nist:
@@ -29,8 +29,8 @@ search: '| tstats `security_content_summariesonly` count values(All_Email.recipi
known_false_positives: None at this time
tags:
analytics_story:
- Suspicious Emails
- 'Emotet Malware DHS Report TA18-201A '
- Suspicious Emails
kill_chain_phases:
- Delivery
cis20:
+1 -1
View File
@@ -21,8 +21,8 @@ known_false_positives: It is possible legitimate traffic can trigger this rule.
to better suit your environment.
tags:
analytics_story:
- Command and Control
- Suspicious DNS Traffic
- Command and Control
mitre_attack_id:
- T1048
- T1043
@@ -0,0 +1,38 @@
name: First Time Seen Child Process of Zoom
id: e91bd102-d630-4e76-ab73-7e3ba22c5961
version: 1
date: '2020-05-20'
description: This search looks for child processes spawned by zoom.exe or zoom.us that has not previously been seen.
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 should run the baseline search `Previously Seen Zoom Child Processes - Initial` to build the initial table of child processes and hostnames for this search to work. You should also schedule at the same interval as this search the second baseline search `Previously Seen Zoom Child Processes - Update` to keep this table up to date and to age out old child processes. Please update the `previously_seen_zoom_child_processes_window` macro to adjust the time window.
type: ESCU
references: []
author: David Dorsey, Splunk
search: '| tstats `security_content_summariesonly` min(_time) as firstTime
values(Processes.parent_process_name) as parent_process_name
values(Processes.parent_process_id) as parent_process_id
values(Processes.process_name) as process_name values(Processes.process) as process
from datamodel=Endpoint.Processes where (Processes.parent_process_name=zoom.exe OR Processes.parent_process_name=zoom.us)
by Processes.process_id Processes.dest
| `drop_dm_object_name(Processes)`
| lookup zoom_first_time_child_process dest as dest process_name as process_name OUTPUT firstTimeSeen
| where isnull(firstTimeSeen) OR firstTimeSeen > relative_time(now(), "`previously_seen_zoom_child_processes_window`")
| `security_content_ctime(firstTime)`
| table firstTime dest, process_id, process_name, parent_process_id, parent_process_name |`first_time_seen_child_process_of_zoom_filter`'
known_false_positives: A new child process of zoom isn't malicious by that fact alone. Further investigation of the actions of the child process is needed to verify any malicious behavior is taken.
tags:
analytics_story:
- Suspicious Zoom Child Processes
mitre_attack_id:
- T1068
kill_chain_phases:
- Actions on Objectives
cis20:
- CIS 3
- CIS 8
nist:
- PR.PT
- DE.CM
- PR.IP
security_domain: endpoint
asset_type: Endpoint
@@ -34,11 +34,11 @@ known_false_positives: Legitimate programs can also use command-line arguments t
macro to exclude legitimate parent_process_name
tags:
analytics_story:
- Suspicious Command-Line Executions
- Hidden Cobra Malware
- DHS Report TA18-074A
- Possible Backdoor Activity Associated With MUDCARP Espionage Campaigns
- Suspicious Command-Line Executions
- Orangeworm Attack Group
- Possible Backdoor Activity Associated With MUDCARP Espionage Campaigns
- Hidden Cobra Malware
mitre_attack_id:
- T1064
- T1059
@@ -1,28 +1,27 @@
name: First Time Seen Running Windows Service
id: 823136f2-d755-4b6d-ae04-372b486a5808
version: 2
date: '2020-01-13'
description: This search looks for the first time a Windows service is seen running
in your environment.
version: 3
date: '2020-06-15'
description: This search looks for the first and last time a Windows service is seen running
in your environment. This table is then cached.
how_to_implement: While this search does not require you to adhere to Splunk CIM,
you must be ingesting your Windows security-event logs in order for this search
to execute successfully. The support search, `Previously Seen Running Windows Services`,
should be run before this search to create the baseline of known Windows services.
Please ensure that the Splunk Add-on for Microsoft Windows is version 5.0.0 or above.
you must be ingesting your Windows system event logs in order for this search
to execute successfully. You should run the baseline search
`Previously Seen Running Windows Services - Initial` to build the initial table of child
processes and hostnames for this search to work. You should also schedule at the same interval
as this search the second baseline search `Previously Seen Running Windows Services - Update` to
keep this table up to date and to age out old Windows Services. Please update the
`previously_seen_windows_service_window` macro to adjust the time window.
Please ensure that the Splunk Add-on for Microsoft Windows is version 8.0.0 or above.
type: ESCU
references: []
author: David Dorsey, Splunk
search: '`wineventlog_system` signature_id=7036 | rename param1 as service_name |
rename param2 as action | search action="running" [ search `wineventlog_system`
signature_id=7036 | rename param1 as service_name | rename param2 as action | search
action="running" | stats earliest(_time) as firstTime, latest(_time) as lastTime
by service_name | inputlookup append=t previously_seen_running_windows_services
| stats min(firstTime) as firstTime max(lastTime) as lastTime by service_name |
outputlookup previously_seen_running_windows_services| eval serviceStatus=if(firstTime
>= relative_time(now(),"-60m@m"), "First time seen Windows service","Previously
seen Windows service") | where serviceStatus="First time seen Windows service"|
`security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | table
service_name]| table _time dest service_name | `first_time_seen_running_windows_service_filter`'
search: '`wineventlog_system` EventCode=7036 |
rex field=Message "The (?<service>[-\(\)\s\w]+) service entered the (?<state>\w+) state" |
where state="running" |
lookup previously_seen_running_windows_services service as service OUTPUT firstTimeSeen |
where isnull(firstTimeSeen) OR firstTimeSeen > relative_time(now(), "`previously_seen_windows_service_window`") |
table _time dest service | `first_time_seen_running_windows_service_filter`'
known_false_positives: A previously unseen service is not necessarily malicious. Verify
that the service is legitimate and that was installed by a legitimate process.
tags:
@@ -25,3 +25,5 @@ tags:
- Container Implantation Monitoring and Investigation
security_domain: threat
asset_type: GCP GCR Container
mitre_attack_id:
- T1525
@@ -17,14 +17,14 @@ author: Bhavin Patel, Splunk
search: '| tstats `security_content_summariesonly` count min(_time) values(Processes.process)
as process max(_time) as lastTime from datamodel=Endpoint.Processes where Processes.process_name=attrib.exe
(Processes.process=*+h*) by Processes.parent_process Processes.process_name Processes.user
| `drop_dm_object_name("Processes")` | `security_content_ctime(firstTime)`|`security_content_ctime(lastTime)`|
Processes.dest | `drop_dm_object_name("Processes")` | `security_content_ctime(firstTime)`|`security_content_ctime(lastTime)`|
`hiding_files_and_directories_with_attrib_exe_filter` '
known_false_positives: 'Some applications and users may legitimately use attrib.exe
to interact with the files. '
tags:
analytics_story:
- Windows Persistence Techniques
- Windows Defense Evasion Tactics
- Windows Persistence Techniques
kill_chain_phases:
- Actions on Objectives
cis20:
@@ -0,0 +1,31 @@
name: Kerberoasting spn request with RC4 encryption
id: 5cc67381-44fa-4111-8a37-7a230943f027
version: 1
date: '2020-06-11'
description: This search detects a potential kerberoasting attack via service principal name requests
how_to_implement: You must be ingesting endpoint data that tracks process activity, and include the windows security event logs that contain kerberos
type: ESCU
references:
- https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1208/T1208.md
- https://www.trimarcsecurity.com/post/trimarcresearch-detecting-kerberoasting-activity
author: Jose Hernandez, Splunk
search: '`wineventlog_security` EventID=4769 TicketOptions=0x40810000 TicketEncryptionType=0x17
| stats count min(_time) as firstTime max(_time) as lastTime values(ServiceName) values(TargetUserName) values(user) by TargetDomainName
| `security_content_ctime(lastTime)`
| `security_content_ctime(firstTime)`
| `kerberoasting_spn_request_with_rc4_encryption_filter`'
known_false_positives: Older systems that support kerberos RC4 by default NetApp may generate false positives
tags:
analytics_story:
- Lateral Movement
mitre_attack_id:
- T1208
kill_chain_phases:
- Actions on Objectives
cis20:
- CIS 8
- CIS 16
nist:
- DE.CM
security_domain: endpoint
asset_type: Endpoint
@@ -4,9 +4,9 @@ description: "This search provides information on Kubernetes service accounts,ac
how_to_implement: "You must install splunk AWS add on and Splunk App for AWS. This search works with cloudwatch logs"
id: 5b30b25d-7d32-42d8-95ca-64dfcd9076e6
known_false_positives: "Not all service accounts interactions are malicious. Analyst must consider IP, verb and decision context when trying to detect maliciousness."
name: "AWs EKS Kubernetes detect most active service accounts by pod."
name: "Kubernetes AWS detect most active service accounts by pod"
references: []
search: sourcetype=aws:cloudwatchlogs:eks user.groups{}=system:serviceaccounts objectRef.resource=pods | table sourceIPs{} user.username userAgent verb annotations.authorization.k8s.io/decision | top sourceIPs{} user.username verb annotations.authorization.k8s.io/decision |`kubernetes_aws_detect_most_active_service_accounts_by_pod`
search: "`aws_cloudwatchlogs_eks` user.groups{}=system:serviceaccounts objectRef.resource=pods | table sourceIPs{} user.username userAgent verb annotations.authorization.k8s.io/decision | top sourceIPs{} user.username verb annotations.authorization.k8s.io/decision |`kubernetes_aws_detect_most_active_service_accounts_by_pod_filter`"
tags:
analytics_story:
- "Kubernetes Sensitive Role Activity"
@@ -4,9 +4,9 @@ description: "This search provides information on Kubernetes RBAC authorizations
how_to_implement: "You must install splunk AWS add on and Splunk App for AWS. This search works with cloudwatch logs"
id: de7264ed-3ed9-4fef-bb01-6eefc87cefe8
known_false_positives: "Not all RBAC Authorications are malicious. RBAC authorizations can uncover malicious activity specially if sensitive Roles have been granted."
name: "AWS EKS Kubernetes RBAC authorizations by account"
name: "Kubernetes AWS detect RBAC authorization by account"
references: []
search: sourcetype="aws:cloudwatchlogs:eks" annotations.authorization.k8s.io/reason=* | table sourceIPs{} user.username userAgent annotations.authorization.k8s.io/reason | stats count by user.username annotations.authorization.k8s.io/reason | rare user.username annotations.authorization.k8s.io/reason |`kubernetes_aws_detect_RBAC_authorization_by_account`
search: "`aws_cloudwatchlogs_eks` annotations.authorization.k8s.io/reason=* | table sourceIPs{} user.username userAgent annotations.authorization.k8s.io/reason | stats count by user.username annotations.authorization.k8s.io/reason | rare user.username annotations.authorization.k8s.io/reason |`kubernetes_aws_detect_rbac_authorization_by_account_filter`"
tags:
analytics_story:
- "Kubernetes Sensitive Role Activity"
@@ -4,9 +4,9 @@ description: "This search provides information on Kubernetes accounts accessing
how_to_implement: "You must install splunk AWS add on and Splunk App for AWS. This search works with cloudwatch logs."
id: 7f227943-2196-4d4d-8d6a-ac8cb308e61c
known_false_positives: "Sensitive object access is not necessarily malicious but user and object context can provide guidance for detection."
name: "AWS EKS Kubernetes cluster sensitive object access detection"
name: "AWS EKS Kubernetes cluster sensitive object access"
references: []
search: sourcetype="aws:cloudwatchlogs:eks" objectRef.resource=secrets OR configmaps sourceIPs{}!=::1 sourceIPs{}!=127.0.0.1 |table sourceIPs{} user.username user.groups{} objectRef.resource objectRef.namespace objectRef.name annotations.authorization.k8s.io/reason |dedup user.username user.groups{} |`kubernetes_aws_detect_sensitive_object_access`"
search: "`aws_cloudwatchlogs_eks` objectRef.resource=secrets OR configmaps sourceIPs{}!=::1 sourceIPs{}!=127.0.0.1 |table sourceIPs{} user.username user.groups{} objectRef.resource objectRef.namespace objectRef.name annotations.authorization.k8s.io/reason |dedup user.username user.groups{} |`aws_eks_kubernetes_cluster_sensitive_object_access_filter`"
tags:
analytics_story:
- "Kubernetes Sensitive Object Access Activity"
@@ -4,9 +4,9 @@ description: "This search provides information on Kubernetes accounts accessing
how_to_implement: "You must install splunk AWS add on and Splunk App for AWS. This search works with cloudwatch logs."
id: b6013a7b-85e0-4a45-b051-10b252d69569
known_false_positives: "Sensitive role resource access is necessary for cluster operation, however source IP, namespace and user group may indicate possible malicious use. "
name: "AWS EKS Kubernetes cluster sensitive role access detection"
name: "Kubernetes AWS detect sensitive role access"
references: []
search: sourcetype="aws:cloudwatchlogs:eks" objectRef.resource=clusterroles OR clusterrolebindings sourceIPs{}!=::1 sourceIPs{}!=127.0.0.1 | table sourceIPs{} user.username user.groups{} objectRef.namespace requestURI annotations.authorization.k8s.io/reason | dedup user.username user.groups{} |`kubernetes_aws_detect_sensitive_role_access`
search: "`aws_cloudwatchlogs_eks` objectRef.resource=clusterroles OR clusterrolebindings sourceIPs{}!=::1 sourceIPs{}!=127.0.0.1 | table sourceIPs{} user.username user.groups{} objectRef.namespace requestURI annotations.authorization.k8s.io/reason | dedup user.username user.groups{} |`kubernetes_aws_detect_sensitive_role_access_filter`"
tags:
analytics_story:
- "Kubernetes Sensitive Role Activity"
@@ -4,9 +4,9 @@ description: "This search provides information on Kubernetes service accounts wi
how_to_implement: "You must install splunk AWS add on and Splunk App for AWS. This search works with cloudwatch logs."
id: a6959c57-fa8f-4277-bb86-7c32fba579d5
known_false_positives: "This search can give false positives as there might be inherent issues with authentications and permissions at cluster."
name: "AWS EKS Kubernetes cluster sensitive object access detection"
name: "Kubernetes AWS detect service accounts forbidden failure access"
references: []
search: sourcetype=aws:cloudwatchlogs:eks user.groups{}=system:serviceaccounts responseStatus.status = Failure | table sourceIPs{} src_user userAgent verb responseStatus.status requestURI | `kubernetes_aws_detect_service_accounts_forbidden_failure_access`
search: "`aws_cloudwatchlogs_eks` user.groups{}=system:serviceaccounts responseStatus.status = Failure | table sourceIPs{} src_user userAgent verb responseStatus.status requestURI | `kubernetes_aws_detect_service_accounts_forbidden_failure_access_filter`"
tags:
analytics_story:
- "Kubernetes Sensitive Object Access Activity"
@@ -4,9 +4,9 @@ description: "This search provides information on anonymous Kubectl calls with I
how_to_implement: "You must install splunk AWS add on and Splunk App for AWS. This search works with cloudwatch logs."
id: 042a3d32-8318-4763-9679-09db2644a8f2
known_false_positives: "Kubectl calls are not malicious by nature. However source IP, verb and Object can reveal potential malicious activity, specially anonymous suspicious IPs and sensitive objects such as configmaps or secrets"
name: "AWS EKS Kubernetes detect suspicious kubectl calls"
name: "Kubernetes AWS detect suspicious kubectl calls"
references: []
search: "sourcetype=aws:cloudwatchlogs:eks userAgent=kubectl* sourceIPs{}!=127.0.0.1 sourceIPs{}!=::1 src_user=system:anonymous | table src_ip src_user verb userAgent requestURI | stats count by src_ip src_user verb userAgent requestURI |`kubernetes_aws_detect_suspicious_kubectl_calls`"
search: "`aws_cloudwatchlogs_eks` userAgent=kubectl* sourceIPs{}!=127.0.0.1 sourceIPs{}!=::1 src_user=system:anonymous | table src_ip src_user verb userAgent requestURI | stats count by src_ip src_user verb userAgent requestURI |`kubernetes_aws_detect_suspicious_kubectl_calls_filter`"
tags:
analytics_story:
- "Kubernetes Sensitive Object Access Activity"
@@ -4,9 +4,9 @@ description: "This search provides information on Kubernetes service accounts,ac
how_to_implement: "You must install the Add-on for Microsoft Cloud Services and Configure Kube-Audit data diagnostics"
id: 55a2264a-b7f0-45e5-addd-1e5ab3415c72
known_false_positives: "Not all service accounts interactions are malicious. Analyst must consider IP and verb context when trying to detect maliciousness."
name: "Azure AKS Kubernetes detect most active service accounts by pod and namespaces"
name: "Kubernetes Azure detect most active service accounts by pod namespace"
references: []
search: "sourcetype:mscs:storage:blob:json category=kube-audit | spath input=properties.log | search user.groups{}=system:serviceaccounts* OR user.username=system.anonymous OR annotations.authorization.k8s.io/decision=allow | table sourceIPs{} user.username userAgent verb responseStatus.reason responseStatus.status properties.pod objectRef.namespace | top sourceIPs{} user.username verb responseStatus.status properties.pod objectRef.namespace |`kubernetes_azure_detect_most_active_service_accounts_by_pod_namespace`"
search: "`kubernetes_azure` category=kube-audit | spath input=properties.log | search user.groups{}=system:serviceaccounts* OR user.username=system.anonymous OR annotations.authorization.k8s.io/decision=allow | table sourceIPs{} user.username userAgent verb responseStatus.reason responseStatus.status properties.pod objectRef.namespace | top sourceIPs{} user.username verb responseStatus.status properties.pod objectRef.namespace |`kubernetes_azure_detect_most_active_service_accounts_by_pod_namespace_filter`"
tags:
analytics_story:
- "Kubernetes Sensitive Role Activity"
@@ -4,9 +4,9 @@ description: "This search provides information on Kubernetes RBAC authorizations
how_to_implement: "You must install the Add-on for Microsoft Cloud Services and Configure Kube-Audit data diagnostics"
id: 47af7d20-0607-4079-97d7-7a29af58b54e
known_false_positives: "Not all RBAC Authorications are malicious. RBAC authorizations can uncover malicious activity specially if sensitive Roles have been granted."
name: "Azure AKS Kubernetes RBAC authorizations by account"
name: "Kubernetes Azure detect RBAC authorization by account"
references: []
search: "sourcetype:mscs:storage:blob:json category=kube-audit | spath input=properties.log | search annotations.authorization.k8s.io/reason=* | table sourceIPs{} user.username userAgent annotations.authorization.k8s.io/reason |stats count by user.username annotations.authorization.k8s.io/reason | rare user.username annotations.authorization.k8s.io/reason |`kubernetes_azure_detect_RBAC_authorization_by_account`"
search: "sourcetype:mscs:storage:blob:json category=kube-audit | spath input=properties.log | search annotations.authorization.k8s.io/reason=* | table sourceIPs{} user.username userAgent annotations.authorization.k8s.io/reason |stats count by user.username annotations.authorization.k8s.io/reason | rare user.username annotations.authorization.k8s.io/reason |`kubernetes_azure_detect_rbac_authorization_by_account_filter`"
tags:
analytics_story:
- "Kubernetes Sensitive Role Activity"
@@ -4,9 +4,9 @@ description: "This search provides information on Kubernetes accounts accessing
how_to_implement: "You must install the Add-on for Microsoft Cloud Services and Configure Kube-Audit data diagnostics"
id: 1bba382b-07fd-4ffa-b390-8002739b76e8
known_false_positives: "Sensitive object access is not necessarily malicious but user and object context can provide guidance for detection."
name: "Azure AKS Kubernetes cluster sensitive object access detection"
name: "Kubernetes Azure detect sensitive object access"
references: []
search: "sourcetype=mscs:storage:blob:json category=kube-audit | spath input=properties.log| search objectRef.resource=secrets OR configmaps user.username=system.anonymous OR annotations.authorization.k8s.io/decision=allow |table user.username user.groups{} objectRef.resource objectRef.namespace objectRef.name annotations.authorization.k8s.io/reason |dedup user.username user.groups{} |`kubernetes_azure_detect_sensitive_object_access`"
search: "`kubernetes_azure` category=kube-audit | spath input=properties.log| search objectRef.resource=secrets OR configmaps user.username=system.anonymous OR annotations.authorization.k8s.io/decision=allow |table user.username user.groups{} objectRef.resource objectRef.namespace objectRef.name annotations.authorization.k8s.io/reason |dedup user.username user.groups{} |`kubernetes_azure_detect_sensitive_object_access_filter`"
tags:
analytics_story:
- "Kubernetes Sensitive Object Access Activity"

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