Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
85 commits
Select commit Hold shift + click to select a range
bbe3e20
story spec update
patel-bhavin Mar 25, 2019
a80a625
spec update
patel-bhavin Mar 25, 2019
8c3a6b2
skeleton of generic detection spec
josehelps Mar 25, 2019
59769ac
Merge branch 'spec_update' of github.com:splunk/security-content into…
josehelps Mar 25, 2019
c0b7672
updated project structure
josehelps Mar 26, 2019
7a92414
removing ds store osx files
josehelps Mar 26, 2019
f6bc356
updated dirs and README
josehelps Mar 26, 2019
821eee8
minor spelling mistakes
josehelps Mar 26, 2019
c400c66
support spec to support splunk/phantom
patel-bhavin Mar 26, 2019
94ab0a3
Merge branch 'spec_update' of https://github.com/splunk/security-cont…
patel-bhavin Mar 26, 2019
58d082d
baseline spec
patel-bhavin Mar 26, 2019
c615358
updating readme, adding logo
josehelps Mar 26, 2019
130e6fc
renames:
patel-bhavin Mar 27, 2019
adf26a7
Merge branch 'spec_update' of https://github.com/splunk/security-cont…
patel-bhavin Mar 27, 2019
f622335
spec and structure
patel-bhavin Mar 27, 2019
185ab94
example updates
patel-bhavin Mar 27, 2019
0063df9
id mappings
patel-bhavin Mar 27, 2019
31ff0c5
name conventions on file
patel-bhavin Mar 27, 2019
5d75e12
spec update
patel-bhavin Mar 27, 2019
722c2e2
renamed things a bit
josehelps Mar 27, 2019
bdddbe7
Merge branch 'spec_update' of github.com:splunk/security-content into…
josehelps Mar 27, 2019
aa67083
moved examples into their own folder
josehelps Mar 27, 2019
f334e81
updates
patel-bhavin Mar 27, 2019
a121e91
uba detection
patel-bhavin Mar 27, 2019
af66893
removed unecessary prefixes
josehelps Mar 27, 2019
3b8d1ac
Merge branch 'spec_update' of github.com:splunk/security-content into…
josehelps Mar 27, 2019
9833427
product_up
patel-bhavin Mar 27, 2019
c793eab
Merge branch 'spec_update' of https://github.com/splunk/security-cont…
patel-bhavin Mar 27, 2019
3717c4d
updated schema versions
josehelps Mar 27, 2019
7ee0f62
detection
patel-bhavin Mar 27, 2019
de1b66a
splunk example
patel-bhavin Mar 27, 2019
c17a169
baseline updates
patel-bhavin Mar 27, 2019
db8ce1a
emojis and stuff
patel-bhavin Mar 27, 2019
c7cb162
response
patel-bhavin Mar 27, 2019
af17d1e
fixes
patel-bhavin Mar 27, 2019
cbcd037
entitirees
patel-bhavin Mar 27, 2019
c57c7b5
more spec jdpate
patel-bhavin Mar 27, 2019
28239d6
added docs for specs
josehelps Mar 27, 2019
c473db1
merge conflicts
josehelps Mar 27, 2019
2c3ee03
updated readme with doc gen instructions
josehelps Mar 27, 2019
5b10971
naming changed
patel-bhavin Mar 27, 2019
a5d8d2c
updates to enum
patel-bhavin Mar 27, 2019
048784a
updating story spec and others name to prep for auto doc generationgi…
josehelps Mar 27, 2019
fb287b5
Merge branch 'spec_update' of github.com:splunk/security-content into…
josehelps Mar 27, 2019
ba9b46e
updating
patel-bhavin Mar 27, 2019
10238a1
fixing baseline
josehelps Mar 27, 2019
eab7cea
updated spec and docs for investigations
josehelps Mar 28, 2019
bd4849a
updated spec and docs for investigations
josehelps Mar 28, 2019
b6ee037
docs and updated response schema
josehelps Mar 28, 2019
a011965
added docs readme
josehelps Mar 28, 2019
bc405a6
updated readme
josehelps Mar 28, 2019
66f1c68
updated readme
josehelps Mar 28, 2019
6c44cc6
updated readme
josehelps Mar 28, 2019
57269d8
added example to story
josehelps Mar 28, 2019
a5d69e8
update veuve categories in story:
patel-bhavin Mar 28, 2019
fe3e471
validate story skeleton
josehelps Mar 28, 2019
33eff93
adding logic for checking story content
josehelps Mar 28, 2019
bdbe20f
detection spec update
patel-bhavin Mar 28, 2019
341ee8b
better printing for story
josehelps Mar 28, 2019
6ce4f80
updates
patel-bhavin Mar 28, 2019
568771a
Merge branch 'spec_update' of https://github.com/splunk/security-cont…
patel-bhavin Mar 29, 2019
a2f431b
baseline update
patel-bhavin Mar 29, 2019
6c24bb9
spec omne enums and v2 examples
patel-bhavin Mar 29, 2019
1e965b3
udpated validate script to check detections
josehelps Mar 29, 2019
a627f86
Merge branch 'spec_update' of github.com:splunk/security-content into…
josehelps Mar 29, 2019
fd6a55d
updated mitre mappings
josehelps Mar 29, 2019
f05f011
added investigative check functions
josehelps Mar 30, 2019
af192d4
fixed errors with investigative validations
josehelps Mar 30, 2019
e562cc1
updated with baseline searches
josehelps Apr 1, 2019
35f8c61
oneOF example
patel-bhavin Apr 2, 2019
9cd8ba0
skeleton of generate tool, removed old validation tool
josehelps Apr 2, 2019
a9bb9ba
updated spec and examples to correct some def errors
josehelps Apr 2, 2019
b923dc5
updated investigations
josehelps Apr 2, 2019
43093da
story spec with example and docs
patel-bhavin Apr 2, 2019
6b852b5
fixed error in validate
josehelps Apr 2, 2019
d76848c
correct mistakes with the sub schema validation
josehelps Apr 2, 2019
6112fcc
updating schedule field in specs, also corrected validation logic
josehelps Apr 2, 2019
87c1490
Merge branch 'spec_update' of github.com:splunk/security-content into…
josehelps Apr 2, 2019
cfeccbd
removed example spec
josehelps Apr 2, 2019
018cd82
examples in spec files and docs
patel-bhavin Apr 3, 2019
4e08aa6
docs
patel-bhavin Apr 3, 2019
00a13b4
update to the generator
josehelps Apr 9, 2019
8ee0606
first commit
josehelps Apr 9, 2019
aa20585
spec 2 manifests
patel-bhavin Apr 9, 2019
ad6a52f
adding phishing payloads story
josehelps Apr 9, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# usual mac files
.DS_Store

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
Expand Down
31 changes: 23 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,34 @@
security-content ![security-content](static/logo.png)
=====

Contains a collection of security stories with their corresponding detection, investigative, contexual and support splunk searches

| 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)|

# security-content
Contains a collection of security stories with their corresponding detection, investigative, contexual and support splunk searches

# Consumption
# Usage
Can be consumed using:
* API (https://api.splunksecuritycontent.com)
* CLI

#### [API](https://github.com/splunk/security-content-api)
`curl https://g7jbilqdth.execute-api.us-west-2.amazonaws.com/api/`

#### [CLI](https://github.com/splunk/security-content-api/blob/master/content-update.py)
`python content-update.py -o $SPLUNK_HOME/etc/apps/DA-ESS-ContentUpdate --splunk_user admin --splunk_password xxxx`

# Structure
`src/` - splunk content app source files, includes lookups, binaries, and defaul config files
* [stories/](stories/) - contains all analytics stories/use cases for ESCU
* [detections/](detections/) - splunk, uba and phantom detections that power stories
* [investigations/](investigations/) - splunk, and phantom investigation content that are used in stories
* [responses/](responses/) - automated splunk and phantom responses that are used in stories
* [baselines/](baselines/) - phantom and Splunk baseline needed to support detections in stories
* [src/](src/) - splunk content app source files, includes lookups, binaries, and defaul config files
* [bin/](bin/) - where all binaries to produce, and test content lives
* [spec/](spec/) - location of all spec files that describe ESCU content
* [docs/](docs/) - documentation for all of the spec files

# Developing

For getting pre-commit checks, install the hooks see below for steps:
1. Install circleci [CLI Tool](https://circleci.com/docs/2.0/local-cli/#installation)
2. create virtualenv and install requirements: `virtualenv venv && source venv/bin/activate && pip install -r requirements.txt`
Expand All @@ -25,3 +37,6 @@ For getting pre-commit checks, install the hooks see below for steps:
To test a local change to CI or build make sure you are running docker and then
`circleci local execute -e GITHUB_TOKEN=$GITHUB_TOKEN --branch <your branch>`

To generate docs from schema automatically
1. install https://github.com/adobe/jsonschema2md
2. `jsonschema2md -d spec/v2/detections.json.spec -o docs`
2 changes: 0 additions & 2 deletions bin/config.ini

This file was deleted.

204 changes: 204 additions & 0 deletions bin/generate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
#!/usr/bin/python

'''
Generates splunk configurations from manifest files under the security-content repo.
'''

import glob
import json
import argparse
from os import path

ALL_UUIDS = []


def markdown(x):
markdown = str(x)
markdown = markdown.replace("<code>", "`")
markdown = markdown.replace("</code>", "`")
markdown = markdown.replace("<b>", "**")
markdown = markdown.replace("</b>", "**")
# list tag replacements
markdown = markdown.replace("<ol><li>", "\\\n\\\n1. ")
markdown = markdown.replace("</li><li>", "\\\n\\\n1. ")
markdown = markdown.replace("</li></ol>", "")
markdown = markdown.replace("</li></ul>", "")
markdown = markdown.replace("<ul><li>", "\\\n\\\n1. ")
# break tags replacements
markdown = markdown.replace("<br></br>", "\\\n\\\n")
markdown = markdown.replace("<br/><br/>", "\\\n\\\n")
markdown = markdown.replace("<br/>", "\\\n\\\n")
return markdown


def generate_savedsearches(REPO_PATH, stories):
# first we process detections

# detections_files = []
# detections_manifest_files = path.join(path.expanduser(REPO_PATH), "detections/*.json")

for story_name, story in stories.iteritems():
if 'detections' in story:

search_manifests = {}
for search_manifest_file in glob.glob(path.join(REPO_PATH, '*/detections/*.json')):
try:
search_manifest = json.loads(open(search_manifest_file, 'r').read())
except Exception as e:
print "Error reading %s" % search_manifest_file
print e
continue

search_manifests[search_manifest['search_name']] = search_manifest

# story['mappings'] =
# complete_stories[story['name']]['mappings'] = {}
# complete_stories[story['name']]['data_models'] = set()
# complete_stories[story['name']]['providing_technologies'] = set()


def generate_analytics_story(REPO_PATH, verbose):
story_files = []
story_manifest_files = path.join(path.expanduser(REPO_PATH), "stories/*.json")

for story_manifest_file in glob.glob(story_manifest_files):
# read in each story
try:
story = json.loads(
open(story_manifest_file, 'r').read())
except IOError:
print "ERROR: reading {0}".format(story_manifest_file)
continue
story_files.append(story)

# store an object with all stories and their data

complete_stories = dict()
for story in story_files:
if verbose:
print "processing story: {0}".format(story['name'])
# Start building the story for the use case
complete_stories[story['name']] = {}
complete_stories[story['name']]['story_name'] = story['name']
complete_stories[story['name']]['id'] = story['id']

# grab modification date if it has one, otherwise write as creation date
if 'modification_date' in story:
complete_stories[story['name']]['modification_date'] = story['modification_date']
complete_stories[story['name']]['creation_date'] = story['creation_date']
else:
complete_stories[story['name']]['modification_date'] = story['creation_date']
complete_stories[story['name']]['creation_date'] = story['creation_date']

complete_stories[story['name']]['description'] = story['description']
if 'references' not in story:
story['references'] = []
complete_stories[story['name']]['references'] = story['references']
complete_stories[story['name']]['category'] = story['category']
complete_stories[story['name']]['version'] = story['version']
complete_stories[story['name']]['narrative'] = story['narrative']

# grab searches
if story['spec_version'] == 1:
if 'detection_searches' in story['searches']:
detections = []
for d in story['searches']['detection_searches']:
detections.append({"type": "splunk", "name": "ESCU - " + d + " - Rule"})
complete_stories[story['name']]['detections'] = detections

if 'support_searches' in story['searches']:
baselines = []
for b in story['searches']['support_searches']:
detections.append({"type": "splunk", "name": "ESCU - " + b})
complete_stories[story['name']]['baselines'] = baselines

investigations = []
if 'contexual_searches' in story['searches']:
for i in story['searches']['contexual_searches']:
investigations.append({"type": "splunk", "name": "ESCU - " + i})
if 'investigative_searches' in story['searches']:
for i in story['searches']['investigative_searches']:
investigations.append({"type": "splunk", "name": "ESCU - " + i})
complete_stories[story['name']]['investigations'] = investigations

if story['spec_version'] == 2:
if 'detections' in story:
detections = []
for d in story['detections']:
detections.append({"type": d['type'], "name": "ESCU - " + d['name'] + " - Rule"})
complete_stories[story['name']]['detections'] = detections

if 'baselines' in story:
baselines = []
for b in story['baselines']:
detections.append({"type": d['type'], "name": "ESCU - " + b['name']})
complete_stories[story['name']]['baselines'] = baselines

if 'investigations' in story:
investigations = []
for i in story['investigations']:
investigations.append({"type": i['type'], "name": "ESCU - " + i['name']})
complete_stories[story['name']]['investigations'] = investigations

return complete_stories


def write_story_output(complete_stories, OUTPUT_DIR):

# Create conf files from analytics stories files
story_output_path = OUTPUT_DIR + "/default/analytics_stories.conf"
output_file = open(story_output_path, 'w')

# Finish the story
for story_name, story in sorted(complete_stories.iteritems()):
output_file.write("[%s]\n" % story_name)
output_file.write("category = %s\n" % story['category'])
output_file.write("creation_date = %s\n" % story['creation_date'])
output_file.write("modification_date = %s\n" % story['modification_date'])
output_file.write("id = %s\n" % story['id'])
output_file.write("version = %s\n" % story['version'])
output_file.write("reference = %s\n" % json.dumps(story['references']))

if 'detections' in story:
output_file.write("detections = %s\n" % json.dumps(story['detections']))
if 'investigations' in story:
output_file.write("investigations = %s\n" % json.dumps(story['investigations']))
if 'baselines' in story:
output_file.write("baselines = %s\n" % json.dumps(story['baselines']))

# REMOVE THIS FUNCTION MAKE SURE ALL DESCRIPTIONs ARE NATIVELY IN MARKDOWN
description = markdown(story['description'])
output_file.write("description = %s\n" % description)

# REMOVE THIS FUNCTION MAKE SURE ALL NARRATIVE ARE NATIVELY IN MARKDOWN
if story['narrative']:
narrative = markdown(story['narrative'])
output_file.write("narrative = %s\n" % narrative)
output_file.write("\n")

# close file, count stories we found and return
output_file.close()
story_count = len(complete_stories.keys())
return story_count, story_output_path


if __name__ == "__main__":

# grab arguments
parser = argparse.ArgumentParser(description="generates splunk conf files out of security-content manifests", epilog="""
This tool converts manifests to the source files to be used by products like Splunk Enterprise.
It generates the savesearches.conf, analytics_stories.conf files for ES.""")
parser.add_argument("-p", "--path", required=True, help="path to security-security content repo")
parser.add_argument("-o", "--output", required=True, help="path to the output directory")
parser.add_argument("-v", "--verbose", required=False, action='store_true', help="prints verbose output")

# parse them
args = parser.parse_args()
REPO_PATH = args.path
OUTPUT_DIR = args.output
verbose = args.verbose

complete_stories = generate_analytics_story(REPO_PATH, verbose)
# generate_detections(REPO_PATH, complete_stories)
story_count, story_path = write_story_output(complete_stories, OUTPUT_DIR)
print "{0} stories have been successfully to {1}".format(story_count, story_path)
Loading