mirror of
https://github.com/splunk/security_content
synced 2026-06-08 17:32:49 +00:00
Merge branch 'release_v4.32.0' into 'develop'
Release Branch - ESCU v4.32.0 See merge request threat-research/security_content!1505
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
# Ignore example files from contentctl tool
|
||||
apps/
|
||||
dist/
|
||||
test_results/
|
||||
detections/*/.yml.example
|
||||
stories/*.yml.example
|
||||
|
||||
@@ -13,7 +13,7 @@ search: '`wineventlog_system` EventCode=7036 | rex field=Message "The (?<service
|
||||
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`")
|
||||
by service | where lastTimeSeen > relative_time(now(), `previously_seen_windows_services_forget_window`)
|
||||
| outputlookup previously_seen_running_windows_services'
|
||||
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.
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
# Batch Detection Testing
|
||||
|
||||
The Splunk Threat Research Team produces the [Enterprise Security Content Update Splunk App](https://splunkbase.splunk.com/app/3449/), a power app that includes hundreds of curated, tested detections that you can run on your own Splunk Enterprise Server today. The splunk/security_content repo gives users an insight into our work and allows them to replicate our workflow and even author their own detections!
|
||||
|
||||
A core component of ESCU is that all of detections must be tested and validated against datasets to ensure they work correctly. In order to achieve that, the Security Content Detection Testing System was built with a few goals in mind:
|
||||
- How can we quickly test a small number of detections, and how can I easily debug those detections?
|
||||
- How can we reliably test new or modified detections every time they are committed to our repo (or every time that a PR is created) inside of GitHub Actions?
|
||||
- At the time of this writing, ESCU contains over 550 detections! How can we quickly test a large number of detections?
|
||||
- How can we run these tests on a wide variety of architectures, from develops' own machines to GitHub Actions to other Cloud Instances?
|
||||
|
||||
This architecture diagram gives insight into the workflow:
|
||||
In summary, the tool:
|
||||
|
||||
1. Downloads the latest version of the security_content Repo
|
||||
2. Lints/Sanity Checks all the Detections
|
||||
3. Builds an ESCU Splunk App
|
||||
4. Starts Docker containers (available from Docker Hub as splunk/splunk:latest), installing required Splunkbase Apps and ESCU
|
||||
5. Distributes Detection Tests Across those Containers
|
||||
6. Summarizes the Results of those Detections
|
||||
|
||||
|
||||
# Running a Basic Test
|
||||
|
||||
## Running the Tool
|
||||
The easiest way to run a tests with default, which is suitable for most use cases, is to run:
|
||||
|
||||
python detection_testing_exectuion.py run --branch BRANCH_TO_TEST [--splunkbase_username YOUR_USERNAME --splunkbase_password YOUR_PASSWORD]
|
||||
|
||||
While the test is running, you'll see helpful information printed, letting you know what step of the process is taking place and what detection is being tested.
|
||||
When you start your Splunk Server, the credentials will be printed out on the command line. You may want to use these credentials to log into the Splunk server, hosted locally, during testing for debugging or other exploration:
|
||||
|
||||
***********************
|
||||
Log into your [1] Splunk Container(s) after they boot at http://127.0.0.1:[8000-8000]
|
||||
Splunk App Username: [admin]
|
||||
Splunk App Password: [PBlZEeGvQrOF57zmUXFPOP]
|
||||
***********************
|
||||
|
||||
While you're running, you'll receive helpful progress updates each minute. They give you information about how long your test has been running, your approximate time remaining, and your approximate system load. Please note that this is total system load, not JUST load used by the detection testing:
|
||||
|
||||
***********PROGRESS UPDATE***********
|
||||
Elapsed Time : 0:27:53.358628
|
||||
Estimated Remaining Time : 0:49:18.896474
|
||||
Tests to run : 36
|
||||
Tests currently running : 1
|
||||
Tests completed : 20
|
||||
Success : 15
|
||||
Failure : 5
|
||||
Error : 0
|
||||
System Information:
|
||||
Total CPU Usage : 44% (2 CPUs)
|
||||
Total Memory Usage: 2.1GB USED / 6.8GB TOTAL
|
||||
Total Disk Usage : 21.4GB USED / 83.2GB TOTAL
|
||||
|
||||
Since you're probably running locally to test and debug your searches, there is a feature (enabled by default) called interactive_failure. If one of your detections fails, the test will pause and the offending detection will print out a message like this:
|
||||
|
||||
|
||||
|
||||
This allows you to login to your Splunk server and debug the search. All of the uploaded data for this search remains on the server. To continue, delete the data for this search, and move on to the next search, simply hit "Enter" in the command prompt.
|
||||
|
||||
When the test run is completed, you'll see some cleanup and summarization information. Finally, asimple output summarizes the test run, such as:
|
||||
|
||||
All containers completed testing!
|
||||
Removing all attack data that was downloaded during this test at: [/home/runner/work/security_content/security_content/bin/automated_detection_testing/ci/detection_testing_batch/attack_data_ogcm5da9]
|
||||
Successfully removed all attack data
|
||||
Generating test_results/success.csv...Done with [48] detections
|
||||
Generating test_results/failure.csv...Done with [9] detections
|
||||
Generating test_results/error.csv...Done with [0] detections
|
||||
Generating test_results/combined.csv...Done with [57] detections
|
||||
Settings updated. Writing results to: test_results/detection_failure_manifest.json
|
||||
Summary:
|
||||
Total Tests: 57
|
||||
Total Pass : 48
|
||||
Total Fail : 9 (0 of these were ERRORS)
|
||||
Test Execution Successful
|
||||
|
||||
Note that execution of this test will be successful if all tests complete, **even if 1 or more of the tests fail or contain errors!**
|
||||
|
||||
## Viewing Detailed Results
|
||||
A number of helpful files are generated when the tool runs and written to the `test_results/` directory. The most important files are:
|
||||
|
||||
- summary.json - A file which contains a summary of the test :
|
||||
- Successes, failures, and errors
|
||||
- The Splunk Apps (and their versions) that were installed
|
||||
- Specific Information about the Branch and Commit Hash the test was run against
|
||||
- Detailed Information about each individual test, including success/failure/error information.
|
||||
|
||||
- detection_failure_manifest.json - A file which allows you to replicate your test, testing ONLY the detections that have failed. This gives the user the chance to interactively debug these failures. This is especially useful because it is also generated by the GitHub Actions CI Pipeline - allowing you to pull a single file and debug failed tests locally in minutes! Because it contains specific application versions and the commit hash, this also lets you reproduce this test, exactly, at any point in the future.
|
||||
|
||||
|
||||
## Advanced Usage
|
||||
|
||||
### Command Line Arguments
|
||||
There are a large number of configurable parameters for advanced users. To view the most common parameters, simply run
|
||||
|
||||
python detection_testing_batch.py --help
|
||||
|
||||
These commands will be described in more detail at a later time.
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
|
||||
- hosts: all
|
||||
gather_facts: False
|
||||
roles:
|
||||
- attack_replay
|
||||
@@ -1,23 +0,0 @@
|
||||
|
||||
---
|
||||
|
||||
- name: Upload replay
|
||||
copy:
|
||||
src: ../../../{{ folder_name }}/{{ out }}
|
||||
dest: /tmp/{{ out }}
|
||||
|
||||
- name: Call oneshot import
|
||||
uri:
|
||||
url: https://localhost:8089/services/data/inputs/oneshot
|
||||
validate_certs: no
|
||||
method: POST
|
||||
user: admin
|
||||
password: "{{ splunk_password }}"
|
||||
force_basic_auth: yes
|
||||
body_format: form-urlencoded
|
||||
body:
|
||||
name: /tmp/{{ out }}
|
||||
sourcetype: "{{ sourcetype }}"
|
||||
rename-source: "{{ source }}"
|
||||
index: "{{ index }}"
|
||||
status_code: 201
|
||||
@@ -1,32 +0,0 @@
|
||||
---
|
||||
|
||||
- name: Delete ESCU APP
|
||||
file:
|
||||
state: absent
|
||||
path: "/opt/splunk/etc/apps/DA-ESS-ContentUpdate"
|
||||
become: yes
|
||||
|
||||
- name: Upload ESCU APP
|
||||
copy:
|
||||
src: ../../../{{ security_content_path }}/dist/escu/
|
||||
dest: "/opt/splunk/etc/apps/DA-ESS-ContentUpdate"
|
||||
owner: splunk
|
||||
group: splunk
|
||||
become: yes
|
||||
|
||||
|
||||
- name: restart containerized splunk
|
||||
ansible.builtin.shell: /opt/splunk/bin/splunk restart
|
||||
become: yes
|
||||
- name: restart splunk
|
||||
service:
|
||||
name: splunkd
|
||||
state: restarted
|
||||
become: yes
|
||||
|
||||
- name: restart splunk
|
||||
service:
|
||||
name: splunkd
|
||||
state: restarted
|
||||
become: yes
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
- hosts: all
|
||||
gather_facts: False
|
||||
roles:
|
||||
- update_escu
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,564 +0,0 @@
|
||||
import argparse
|
||||
import copy
|
||||
import csv
|
||||
# from ctypes.wintypes import tagRECT
|
||||
import json
|
||||
import os
|
||||
import queue
|
||||
import random
|
||||
import secrets
|
||||
import shutil
|
||||
import string
|
||||
import subprocess
|
||||
import sys
|
||||
import threading
|
||||
import time
|
||||
from collections import OrderedDict
|
||||
from datetime import datetime, timedelta
|
||||
from posixpath import basename
|
||||
from tempfile import mkdtemp
|
||||
from timeit import default_timer as timer
|
||||
from typing import Union
|
||||
from urllib.parse import urlparse
|
||||
import signal
|
||||
|
||||
|
||||
import docker
|
||||
import requests
|
||||
import requests.packages.urllib3
|
||||
from docker.client import DockerClient
|
||||
from requests import get
|
||||
|
||||
|
||||
|
||||
from modules import (container_manager, new_arguments2,
|
||||
testing_service, validate_args, utils)
|
||||
from modules.github_service import GithubService
|
||||
from modules.validate_args import validate, validate_and_write, ES_APP_NAME
|
||||
|
||||
SPLUNK_CONTAINER_APPS_DIR = "/opt/splunk/etc/apps"
|
||||
index_file_local_path = "indexes.conf.tar"
|
||||
index_file_container_path = os.path.join(SPLUNK_CONTAINER_APPS_DIR, "search")
|
||||
|
||||
# Should be the last one we copy.
|
||||
datamodel_file_local_path = "datamodels.conf.tar"
|
||||
datamodel_file_container_path = os.path.join(
|
||||
SPLUNK_CONTAINER_APPS_DIR, "Splunk_SA_CIM")
|
||||
|
||||
|
||||
authorizations_file_local_path = "authorize.conf.tar"
|
||||
authorizations_file_container_path = "/opt/splunk/etc/system/local"
|
||||
|
||||
CONTAINER_APP_DIRECTORY = "apps"
|
||||
|
||||
MAX_RECOMMENDED_CONTAINERS_BEFORE_WARNING = 2
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def copy_local_apps_to_directory(apps: dict[str, dict], splunkbase_username:tuple[str,None] = None, splunkbase_password:tuple[str,None] = None, mock:bool = False, target_directory:str = "apps") -> str:
|
||||
if mock is True:
|
||||
target_directory = os.path.join("prior_config", target_directory)
|
||||
|
||||
# Remove the apps directory or the prior config directory. If it's just an apps directory, then we don't want
|
||||
#to remove that.
|
||||
shutil.rmtree(target_directory, ignore_errors=True)
|
||||
try:
|
||||
# Make sure the directory exists. If it already did, that's okay. Don't delete anything from it
|
||||
# We want to re-use previously downloaded apps
|
||||
os.makedirs(target_directory, exist_ok = True)
|
||||
|
||||
except Exception as e:
|
||||
raise(Exception(f"Some error occured when trying to make the {target_directory}: [{str(e)}]"))
|
||||
|
||||
|
||||
for key, item in apps.items():
|
||||
|
||||
# These apps are URLs that will be passed. The apps will be downloaded and installed by the container
|
||||
# # Get the file from an http source
|
||||
splunkbase_info = True if ('app_number' in item and item['app_number'] is not None and
|
||||
'app_version' in item and item['app_version'] is not None) else False
|
||||
splunkbase_creds = True if (splunkbase_username is not None and
|
||||
splunkbase_password is not None) else False
|
||||
can_download_from_splunkbase = splunkbase_info and splunkbase_creds
|
||||
|
||||
|
||||
|
||||
#local apps can either have a local_path or an http_path
|
||||
if 'local_path' in item:
|
||||
source_path = os.path.abspath(os.path.expanduser(item['local_path']))
|
||||
base_name = os.path.basename(source_path)
|
||||
dest_path = os.path.join(target_directory, base_name)
|
||||
try:
|
||||
print(f"copying {os.path.relpath(source_path)} to {os.path.relpath(dest_path)}")
|
||||
shutil.copy(source_path, dest_path)
|
||||
item['local_path'] = dest_path
|
||||
except shutil.SameFileError as e:
|
||||
# Same file, not a real error. The copy just doesn't happen
|
||||
print("err:%s" % (str(e)))
|
||||
pass
|
||||
except Exception as e:
|
||||
print("Error copying ESCU Package [%s] to [%s]: [%s].\n\tQuitting..." % (
|
||||
source_path, dest_path, str(e)), file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
elif can_download_from_splunkbase is True:
|
||||
#Don't do anything, this will be downloaded from splunkbase
|
||||
pass
|
||||
elif splunkbase_info is True and splunkbase_creds is False and mock is True:
|
||||
#Don't need to do anything, when this actually runs the apps will be downloaded from Splunkbase
|
||||
#There is another opportunity to provide the creds then
|
||||
pass
|
||||
elif 'http_path' in item and can_download_from_splunkbase is False:
|
||||
http_path = item['http_path']
|
||||
try:
|
||||
url_parse_obj = urlparse(http_path)
|
||||
path_after_host = url_parse_obj[2].rstrip('/') #removes / at the end, if applicable
|
||||
base_name = path_after_host.rpartition('/')[-1] #just get the file name
|
||||
dest_path = os.path.join(target_directory, base_name) #write the whole path
|
||||
utils.download_file_from_http(http_path, dest_path, verbose_print=True)
|
||||
#we need to update the local path because this is used to copy it into the container later
|
||||
item['local_path'] = dest_path
|
||||
#Remove the HTTP Path, we will use the local_path instead
|
||||
except Exception as e:
|
||||
print("Error trying to download %s @ %s: [%s]. This app is required.\n\tQuitting..."%(key, http_path, str(e)),file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
elif splunkbase_info is False:
|
||||
print(f"Error - trying to install an app [{key}] that does not have 'local_path', 'http_path', "
|
||||
"or 'app_version' and 'app_number' for installing from Splunkbase.\n\tQuitting...")
|
||||
sys.exit(1)
|
||||
return target_directory
|
||||
|
||||
|
||||
def ensure_security_content(branch: str, commit_hash: Union[str,None], pr_number: Union[int, None], persist_security_content: bool) -> tuple[GithubService, bool]:
|
||||
if persist_security_content is True and os.path.exists("security_content"):
|
||||
print("****** You chose --persist_security_content and the security_content directory exists. "
|
||||
"We will not check out the repo again. Please be aware, this could cause issues if your "
|
||||
"repo is out of date or if a previous build failed to download all required tools and "\
|
||||
"libraries. If this occurs, it is suggested to change the "\
|
||||
"persist_security_content setting to false. ******")
|
||||
|
||||
github_service = GithubService(
|
||||
branch, commit_hash, persist_security_content=persist_security_content)
|
||||
|
||||
else:
|
||||
if persist_security_content is True and not os.path.exists("security_content"):
|
||||
print("Error - you chose --persist_security_content but the security_content directory does not exist!"
|
||||
" We will check it out for you.")
|
||||
persist_security_content = False
|
||||
|
||||
elif os.path.exists("security_content/"):
|
||||
print("Deleting the security_content directory")
|
||||
try:
|
||||
shutil.rmtree("security_content/", ignore_errors=True)
|
||||
print("Successfully removed security_content directory")
|
||||
except Exception as e:
|
||||
print(
|
||||
"Error - could not remove the security_content directory: [%s].\n\tQuitting..." % (str(e)))
|
||||
sys.exit(1)
|
||||
|
||||
if pr_number:
|
||||
github_service = GithubService(branch, commit_hash, pr_number)
|
||||
else:
|
||||
github_service = GithubService(branch, commit_hash)
|
||||
|
||||
return github_service, persist_security_content
|
||||
|
||||
|
||||
def generate_escu_app(persist_security_content: bool = False) -> str:
|
||||
# Go into the security content directory
|
||||
print("****GENERATING ESCU APP****")
|
||||
os.chdir("security_content")
|
||||
if persist_security_content is False:
|
||||
commands = ["python ../../../contentctl.py --path . --skip_enrichment generate --product ESCU --output dist/escu"]
|
||||
else:
|
||||
commands = ["python ../../../contentctl.py --path . --skip_enrichment generate --product ESCU --output dist/escu"]
|
||||
ret = subprocess.run("; ".join(commands),
|
||||
shell=True, capture_output=True)
|
||||
if ret.returncode != 0:
|
||||
print(f"Error generating new content0.\n\tQuitting and dumping error...\n{str(ret.stderr)}\n{str(ret.stdout)}")
|
||||
sys.exit(1)
|
||||
|
||||
ret = subprocess.run("tar -czf DA-ESS-ContentUpdate.spl -C dist/escu .",
|
||||
shell=True, capture_output=True)
|
||||
if ret.returncode != 0:
|
||||
print("Error generating new content1.\n\tQuitting and dumping error...\n[%s]" % (
|
||||
ret.stderr))
|
||||
sys.exit(1)
|
||||
|
||||
output_file_name = "DA-ESS-ContentUpdate-latest.tar.gz"
|
||||
output_file_path_from_slim_latest = os.path.join(
|
||||
"upload", output_file_name)
|
||||
output_file_path_from_security_content = os.path.join(
|
||||
"slim_packaging", output_file_path_from_slim_latest)
|
||||
output_file_path_from_root = os.path.join(
|
||||
"security_content", output_file_path_from_security_content)
|
||||
|
||||
if persist_security_content is True:
|
||||
try:
|
||||
os.remove(output_file_path_from_security_content)
|
||||
except FileNotFoundError:
|
||||
# No problem if we fail to remove it, that just means it wasn't there and we didn't need to
|
||||
pass
|
||||
except Exception as e:
|
||||
print("Error deleting the (possibly) existing old ESCU File: [%s]" % (
|
||||
str(e)), file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
# There remove the latest file if it exists
|
||||
commands = ["cd slim_packaging",
|
||||
"cp -R ../dist/escu DA-ESS-ContentUpdate",
|
||||
"mkdir upload",
|
||||
"tar -czf upload/DA-ESS-ContentUpdate*.tar.gz DA-ESS-ContentUpdate",
|
||||
"cp upload/DA-ESS-ContentUpdate*.tar.gz %s" % (output_file_path_from_slim_latest)]
|
||||
|
||||
else:
|
||||
os.mkdir("slim_packaging")
|
||||
commands = ["rm -rf slim_packaging/slim_latest",
|
||||
"mkdir slim_packaging",
|
||||
"cd slim_packaging",
|
||||
"cp -R ../dist/escu DA-ESS-ContentUpdate",
|
||||
"mkdir upload",
|
||||
"tar -czf upload/DA-ESS-ContentUpdate*.tar.gz DA-ESS-ContentUpdate",
|
||||
"cp upload/DA-ESS-ContentUpdate*.tar.gz %s" % (output_file_path_from_slim_latest)]
|
||||
|
||||
ret = subprocess.run("; ".join(commands),
|
||||
shell=True, capture_output=True)
|
||||
if ret.returncode != 0:
|
||||
print("Command List:\n%s" % (commands))
|
||||
print("Error generating new ESCU Package.\n\tQuitting and dumping error...\n[%s]" % (
|
||||
ret.stderr.decode('utf-8')), file=sys.stderr)
|
||||
sys.exit(1)
|
||||
os.chdir("../")
|
||||
|
||||
return output_file_path_from_root
|
||||
|
||||
|
||||
|
||||
def finish_mock(settings: dict, detections: list[str], output_file_template: str = "prior_config/config_tests_%d.json")->bool:
|
||||
num_containers = settings['num_containers']
|
||||
|
||||
for output_file_index in range(0, num_containers):
|
||||
fname = output_file_template % (output_file_index)
|
||||
|
||||
# Get the n'th detection for this file
|
||||
detection_tests = detections[output_file_index::num_containers]
|
||||
normalized_detection_names = []
|
||||
# Normalize the test filename to the name of the detection instead.
|
||||
# These are what we should write to the file
|
||||
for d in detection_tests:
|
||||
filename = os.path.basename(d)
|
||||
filename = filename.replace(".test.yml", ".yml")
|
||||
leading = os.path.split(d)[0]
|
||||
leading = leading.replace("tests/", "detections/")
|
||||
new_name = os.path.join(
|
||||
"security_content", leading, filename)
|
||||
normalized_detection_names.append(new_name)
|
||||
|
||||
# Generate an appropriate config file for this test
|
||||
mock_settings = copy.deepcopy(settings)
|
||||
# This may be able to support as many as 2 for GitHub Actions...
|
||||
# we will have to determine in testing.
|
||||
mock_settings['num_containers'] = 1
|
||||
|
||||
# Must be selected since we are passing in a list of detections
|
||||
mock_settings['mode'] = 'selected'
|
||||
|
||||
# Pass in the list of detections to run
|
||||
mock_settings['detections_list'] = normalized_detection_names
|
||||
|
||||
# We want to persist security content and run with the escu package that we created.
|
||||
#Note that if we haven't checked this out yet, we will check it out for you.
|
||||
mock_settings['persist_security_content'] = True
|
||||
|
||||
mock_settings['mock'] = False
|
||||
|
||||
# Make sure that it still validates after all of the changes
|
||||
|
||||
try:
|
||||
with open(fname, 'w') as outfile:
|
||||
validated_settings, b = validate_and_write(configuration=mock_settings, output_file = outfile, strip_credentials=True)
|
||||
if validated_settings is None:
|
||||
print(
|
||||
"There was an error validating the updated mock settings.\n\tQuitting...", file=sys.stderr)
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
print("Error writing config file %s: [%s]\n\tQuitting..." % (
|
||||
fname, str(e)), file=sys.stderr)
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def main(args: list[str]):
|
||||
#Disable insecure warnings. We make a number of HTTPS requests to Splunk
|
||||
#docker containers that we've set up. Without this line, we get an
|
||||
#insecure warning every time due to invalid cert.
|
||||
requests.packages.urllib3.disable_warnings()
|
||||
|
||||
start_datetime = datetime.now()
|
||||
|
||||
action, settings = new_arguments2.parse(args)
|
||||
if action == "configure":
|
||||
# Done, nothing else to do
|
||||
print("Configuration complete!")
|
||||
sys.exit(0)
|
||||
elif action != "run":
|
||||
print("Unsupported action: [%s]" % (action), file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
if settings['mock'] is False:
|
||||
# If this is a real run, then make sure Docker is installed and running and usable
|
||||
# If this is a mock, then that is not required. By only checking on a non-mock
|
||||
# run, we save ourselves the need to install docker in the CI for the manifest
|
||||
# generation step.
|
||||
try:
|
||||
docker.client.from_env()
|
||||
except Exception as e:
|
||||
print("Error, failed to get docker client. Is Docker Installed and Running?\n\t%s" % (str(e)))
|
||||
sys.exit(1)
|
||||
|
||||
credentials_needed = False
|
||||
credential_error = False
|
||||
|
||||
|
||||
|
||||
if settings['splunkbase_username'] == None or settings['splunkbase_password'] == None:
|
||||
|
||||
missing_credentials = []
|
||||
if settings['splunkbase_username'] == None:
|
||||
missing_credentials.append("--splunkbase_username")
|
||||
if settings['splunkbase_password'] == None:
|
||||
missing_credentials.append("--splunkbase_password")
|
||||
|
||||
missing_credentials_string = '\n\t'.join(missing_credentials)
|
||||
|
||||
splunkbase_only_apps = []
|
||||
for app,content in settings['apps'].items():
|
||||
if 'local_path' not in content and 'http_path' not in content:
|
||||
splunkbase_only_apps.append(app)
|
||||
if len(splunkbase_only_apps) != 0:
|
||||
print(f"Error - you have attempted to install the following apps: {splunkbase_only_apps}, "
|
||||
"but you have not provided a local_path or an http_path in the config file. Normally, "
|
||||
"we would download these from Splunkbase, but the following credentials are "
|
||||
f"missing:\n\t{missing_credentials_string}\n Please provide them on the command line "
|
||||
"or in the config file.\n\tQuitting...")
|
||||
sys.exit(1)
|
||||
|
||||
print(f"You have listed apps to install but have "\
|
||||
f"not provided\n\t{missing_credentials_string} \nvia the command line or config file. "
|
||||
f"We will download these files from S3 rather than Splunkbase.")
|
||||
else:
|
||||
|
||||
print(f"You have listed apps to install and provided Splunkbase credentials. "\
|
||||
f"These apps will be downloaded and installed from Splunkbase!")
|
||||
|
||||
|
||||
|
||||
|
||||
FULL_DOCKER_HUB_CONTAINER_NAME = "splunk/splunk:%s" % settings['container_tag']
|
||||
|
||||
if settings['num_containers'] > MAX_RECOMMENDED_CONTAINERS_BEFORE_WARNING:
|
||||
print("You requested to run with [%d] containers which may use a very large amount of resources "
|
||||
"as they all run in parallel. The maximum suggested number of parallel containers is "
|
||||
"[%d]. We will do what you asked, but be warned!" % (settings['num_containers'], MAX_RECOMMENDED_CONTAINERS_BEFORE_WARNING))
|
||||
|
||||
# Check out security content if required
|
||||
try:
|
||||
#Make sure we fix up the persist_securiy_content argument if it is passed in error (we say it exists but it doesn't)
|
||||
github_service, settings['persist_security_content'] = ensure_security_content(
|
||||
settings['branch'], settings['commit_hash'], settings['pr_number'], settings['persist_security_content'])
|
||||
settings['commit_hash'] = github_service.commit_hash
|
||||
except Exception as e:
|
||||
print("\nFailure checking out git repository: [%s]"\
|
||||
"\n\tCommit Hash: [%s]"\
|
||||
"\n\tBranch : [%s]"\
|
||||
"\n\tPR : [%s]\n\tQuitting..."%
|
||||
(str(e),settings['commit_hash'],settings['branch'],settings['pr_number']),file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
#passes = [{'search_string': '| tstats `security_content_summariesonly` count min(_time) as firstTime max(_time) as lastTime from datamodel=Endpoint.Processes where (Processes.process_name ="7z.exe" OR Processes.process_name = "7za.exe" OR Processes.original_file_name = "7z.exe" OR Processes.original_file_name = "7za.exe") AND (Processes.process="*\\\\C$\\\\*" OR Processes.process="*\\\\Admin$\\\\*" OR Processes.process="*\\\\IPC$\\\\*") by Processes.original_file_name Processes.parent_process_name Processes.parent_process Processes.process_name Processes.process Processes.parent_process_id Processes.process_id Processes.dest Processes.user | `drop_dm_object_name(Processes)` | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `7zip_commandline_to_smb_share_path_filter` | stats count | where count > 0', 'detection_name': '7zip CommandLine To SMB Share Path', 'detection_file': 'endpoint/7zip_commandline_to_smb_share_path.yml', 'success': True, 'error': False, 'diskUsage': '286720', 'runDuration': '0.922', 'scanCount': '4897'}]
|
||||
#github_service.update_and_commit_passed_tests(passes)
|
||||
#sys.exit(0)
|
||||
# Make a backup of this config containing the hash and stripped credentials.
|
||||
# This makes the test perfectly reproducible.
|
||||
reproduce_test_config, _ = validate_args.validate_and_write(settings, output_file=None, strip_credentials=True)
|
||||
if reproduce_test_config == None:
|
||||
print("Error - there was an error writing out the file to reproduce the test. This should not happen, as all "\
|
||||
"settings should have been validated by this point.\n\tQuitting...",file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
all_detection_files = github_service.get_detection_files(settings['mode'],
|
||||
settings['folders'],
|
||||
settings['types'],
|
||||
settings['detections_list'])
|
||||
|
||||
#We randomly shuffle this because there are likely patterns in searches. For example,
|
||||
#cloud/endpoint/network likely have different impacts on the system. By shuffling,
|
||||
#we spread out this load on a single computer, but also spread it in case
|
||||
#we are running on GitHub Actions against multiple machines. Hopefully, this
|
||||
#will reduce that chnaces the some machines run and complete quickly while
|
||||
#others take a long time.
|
||||
random.shuffle(all_detection_files)
|
||||
|
||||
except Exception as e:
|
||||
print("Error getting test files:\n%s"%(str(e)), file=sys.stderr)
|
||||
print("\tQuitting...", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
print("***This run will test [%d] detections!***"%(len(all_detection_files)))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Check to see if we want to install ESCU and whether it was preeviously generated and we should use that file
|
||||
if ES_APP_NAME in settings['apps'] and settings['apps'][ES_APP_NAME]['local_path'] is not None:
|
||||
# Using a pregenerated ESCU, no need to build it
|
||||
pass
|
||||
|
||||
elif ES_APP_NAME not in settings['apps']:
|
||||
print(f"{ES_APP_NAME} was not found in {settings['apps'].keys()}. We assume this is an error and shut down.\n\t"
|
||||
"Quitting...", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
else:
|
||||
# Generate the ESCU package from this branch.
|
||||
source_path = generate_escu_app(settings['persist_security_content'])
|
||||
settings['apps']['SPLUNK_ES_CONTENT_UPDATE']['local_path'] = source_path
|
||||
|
||||
|
||||
# Copy all the apps, to include ESCU (whether pregenerated or just generated)
|
||||
try:
|
||||
relative_app_path = copy_local_apps_to_directory(settings['apps'],
|
||||
splunkbase_username = settings['splunkbase_username'],
|
||||
splunkbase_password = settings['splunkbase_password'],
|
||||
mock=settings['mock'], target_directory = CONTAINER_APP_DIRECTORY)
|
||||
|
||||
mounts = [{"local_path": os.path.abspath(relative_app_path),
|
||||
"container_path": "/tmp/apps", "type": "bind", "read_only": True}]
|
||||
except Exception as e:
|
||||
print(f"Error occurred when copying apps to app folder: [{str(e)}]\n\tQuitting...", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
# If this is a mock run, finish it now
|
||||
if settings['mock']:
|
||||
#The function below
|
||||
if finish_mock(settings, all_detection_files):
|
||||
# mock was successful!
|
||||
print("Mock successful! Manifests generated!")
|
||||
sys.exit(0)
|
||||
else:
|
||||
print("There was an unrecoverage error during the mock.\n\tQuitting...",file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
|
||||
#Add some files that always need to be copied to to container to set up indexes and datamodels.
|
||||
files_to_copy_to_container = OrderedDict()
|
||||
files_to_copy_to_container["INDEXES"] = {
|
||||
"local_file_path": index_file_local_path, "container_file_path": index_file_container_path}
|
||||
files_to_copy_to_container["DATAMODELS"] = {
|
||||
"local_file_path": datamodel_file_local_path, "container_file_path": datamodel_file_container_path}
|
||||
files_to_copy_to_container["AUTHORIZATIONS"] = {
|
||||
"local_file_path": authorizations_file_local_path, "container_file_path": authorizations_file_container_path}
|
||||
|
||||
|
||||
|
||||
def shutdown_signal_handler_setup(sig, frame):
|
||||
|
||||
print(f"Signal {sig} received... stopping all [{settings['num_containers']}] containers and shutting down...")
|
||||
shutdown_client = docker.client.from_env()
|
||||
errorCount = 0
|
||||
for container_number in range(settings['num_containers']):
|
||||
container_name = settings['local_base_container_name']%container_number
|
||||
print(f"Shutting down {container_name}...", file=sys.stderr, end='')
|
||||
sys.stdout.flush()
|
||||
try:
|
||||
container = shutdown_client.containers.get(container_name)
|
||||
#Note that stopping does not remove any of the volumes or logs,
|
||||
#so stopping can be useful if we want to debug any container failure
|
||||
container.stop(timeout=10)
|
||||
print("done", file=sys.stderr)
|
||||
except Exception as e:
|
||||
print(f"Error trying to shut down {container_name}. It may have already shut down. Stop it youself with 'docker containter stop {container_name}", sys.stderr)
|
||||
errorCount += 1
|
||||
if errorCount == 0:
|
||||
print("All containers shut down successfully", file=sys.stderr)
|
||||
else:
|
||||
print(f"{errorCount} containers may still be running. Find out what is running with:\n\t'docker container ls'\nand shut them down with\n\t'docker container stop CONTAINER_NAME' ", file=sys.stderr)
|
||||
|
||||
print("Quitting...",file=sys.stderr)
|
||||
#We must use os._exit(1) because sys.exit(1) actually generates an exception which can be caught! And then we don't Quit!
|
||||
os._exit(1)
|
||||
|
||||
|
||||
|
||||
|
||||
#Setup requires a different teardown handler than during execution
|
||||
signal.signal(signal.SIGINT, shutdown_signal_handler_setup)
|
||||
|
||||
|
||||
try:
|
||||
cm = container_manager.ContainerManager(all_detection_files,
|
||||
FULL_DOCKER_HUB_CONTAINER_NAME,
|
||||
settings['local_base_container_name'],
|
||||
settings['num_containers'],
|
||||
settings['apps'],
|
||||
settings['branch'],
|
||||
settings['commit_hash'],
|
||||
reproduce_test_config,
|
||||
files_to_copy_to_container=files_to_copy_to_container,
|
||||
web_port_start=8000,
|
||||
management_port_start=8089,
|
||||
mounts=mounts,
|
||||
show_container_password=settings['show_splunk_app_password'],
|
||||
container_password=settings['splunk_app_password'],
|
||||
splunkbase_username=settings['splunkbase_username'],
|
||||
splunkbase_password=settings['splunkbase_password'],
|
||||
reuse_image=settings['reuse_image'],
|
||||
interactive_failure=not settings['no_interactive_failure'],
|
||||
interactive=settings['interactive'])
|
||||
except Exception as e:
|
||||
print("Error - unrecoverable error trying to set up the containers: [%s].\n\tQuitting..."%(str(e)),file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
def shutdown_signal_handler_execution(sig, frame):
|
||||
#Set that a container has failed which will gracefully stop the other containers.
|
||||
#This way we get our full cleanup routine, too!
|
||||
print("Got a signal to shut down. Shutting down all containers, please wait...", file=sys.stderr)
|
||||
cm.synchronization_object.containerFailure()
|
||||
|
||||
#Update the signal handler
|
||||
|
||||
signal.signal(signal.SIGINT, shutdown_signal_handler_execution)
|
||||
try:
|
||||
result = cm.run_test()
|
||||
except Exception as e:
|
||||
print("Error - there was an error running the tests: [%s]\n\tQuitting..."%(str(e)),file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
#github_service.update_and_commit_passed_tests(cm.synchronization_object.successes)
|
||||
|
||||
|
||||
#Return code indicates whether testing succeeded and all tests were run.
|
||||
#It does NOT indicate that all tests passed!
|
||||
if result is True:
|
||||
print("Test Execution Successful")
|
||||
sys.exit(0)
|
||||
else:
|
||||
print("Test Execution Failed - review the logs for more details")
|
||||
#Because one or more of the threads could be stuck in a certain setup loop, like
|
||||
#trying to copy files to a containers (which igonores errors), we must os._exit
|
||||
#instead of sys.exit
|
||||
os._exit(1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(sys.argv[1:])
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
import argparse
|
||||
import json
|
||||
import sys
|
||||
|
||||
RAW_BADGE_SVG = '''<?xml version="1.0"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="20">
|
||||
<linearGradient id="a" x2="0" y2="100%">
|
||||
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
|
||||
<stop offset="2" stop-opacity=".1"/>
|
||||
</linearGradient>
|
||||
|
||||
<rect rx="3" width="60" height="20" fill="#555"/> <!-- Comment -->
|
||||
<rect rx="3" x="60" width="40" height="20" fill="#4c1"/>
|
||||
|
||||
<path fill="#4c1" d="M58 0h4v20h-4z"/>
|
||||
|
||||
<rect rx="3" width="100" height="20" fill="url(#a)"/>
|
||||
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
|
||||
<text x="30" y="14">{}</text>
|
||||
<text x="80" y="14">{}</text>
|
||||
</g>
|
||||
</svg>'''
|
||||
|
||||
|
||||
parser = argparse.ArgumentParser(description='Use a summary.json file to generate a test coverage badge')
|
||||
parser.add_argument('-i', "--input_summary_file", type=argparse.FileType('r'), required = True,
|
||||
help='Summary file to use to generate the pass percentage badge')
|
||||
parser.add_argument('-o', "--output_badge_file", type=argparse.FileType('w'), required = True,
|
||||
help='Name of the badge to output')
|
||||
parser.add_argument('-s', "--badge_string", type=str, required = True,
|
||||
help='Name of the badge to output')
|
||||
|
||||
|
||||
|
||||
try:
|
||||
results = parser.parse_args()
|
||||
except Exception as e:
|
||||
print(f"Error parsing arguments: {str(e)}")
|
||||
exit(1)
|
||||
|
||||
try:
|
||||
summary_info = json.loads(results.input_summary_file.read())
|
||||
except Exception as e:
|
||||
print(f"Error loading {results.input_summary_file.name} JSON file: {str(e)}")
|
||||
sys.exit(1)
|
||||
|
||||
if 'summary' not in summary_info:
|
||||
print("Missing 'summary' key in {results.input_summary_file.name}")
|
||||
sys.exit(1)
|
||||
elif 'PASS_RATE' not in summary_info['summary'] or 'TESTS_PASSED' not in summary_info['summary']:
|
||||
print(f"Missing PASS_RATE in 'summary' section of {results.input_summary_file.name}")
|
||||
sys.exit(1)
|
||||
pass_percent = 100 * summary_info['summary']['PASS_RATE']
|
||||
|
||||
|
||||
try:
|
||||
results.output_badge_file.write(RAW_BADGE_SVG.format(results.badge_string, "{:2.1f}%".format(pass_percent)))
|
||||
except Exception as e:
|
||||
print(f"Error generating badge: {str(e)}")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
print(f"Badge {results.output_badge_file.name} successfully generated!")
|
||||
sys.exit(0)
|
||||
|
||||
Binary file not shown.
@@ -1,156 +0,0 @@
|
||||
import json
|
||||
from datetime import datetime
|
||||
from datetime import timedelta
|
||||
#import fileinput
|
||||
import os
|
||||
import re
|
||||
import io
|
||||
|
||||
class DataManipulation:
|
||||
|
||||
def manipulate_timestamp(self, file_path, sourcetype, source):
|
||||
|
||||
|
||||
#print('Updating timestamps in attack_data before replaying')
|
||||
|
||||
if sourcetype == 'aws:cloudtrail':
|
||||
self.manipulate_timestamp_cloudtrail(file_path)
|
||||
|
||||
if source == 'WinEventLog:System' or source == 'WinEventLog:Security':
|
||||
self.manipulate_timestamp_windows_event_log_raw(file_path)
|
||||
|
||||
if source == 'exchange':
|
||||
self.manipulate_timestamp_exchange_logs(file_path)
|
||||
|
||||
|
||||
def manipulate_timestamp_exchange_logs(self, path):
|
||||
#path = os.path.join(os.path.dirname(__file__), '../' + file_path)
|
||||
#path = path.replace('modules/../','')
|
||||
|
||||
f = io.open(path, "r", encoding="utf-8")
|
||||
|
||||
first_line = f.readline()
|
||||
d = json.loads(first_line)
|
||||
latest_event = datetime.strptime(d["CreationTime"],"%Y-%m-%dT%H:%M:%S")
|
||||
|
||||
now = datetime.now()
|
||||
now = now.strftime("%Y-%m-%dT%H:%M:%S")
|
||||
now = datetime.strptime(now,"%Y-%m-%dT%H:%M:%S")
|
||||
|
||||
difference = now - latest_event
|
||||
f.close()
|
||||
|
||||
#Mimic the behavior of fileinput but in a threadsafe way
|
||||
#Rename the file, which fileinput does for inplace.
|
||||
#Note that path will now be the new file
|
||||
original_backup_file = f"{path}.bak"
|
||||
os.rename(path, original_backup_file)
|
||||
|
||||
with open(original_backup_file, "r") as original_file:
|
||||
with open(path, "w") as new_file:
|
||||
for line in original_file:
|
||||
d = json.loads(line)
|
||||
original_time = datetime.strptime(d["CreationTime"],"%Y-%m-%dT%H:%M:%S")
|
||||
new_time = (difference + original_time)
|
||||
|
||||
original_time = original_time.strftime("%Y-%m-%dT%H:%M:%S")
|
||||
new_time = new_time.strftime("%Y-%m-%dT%H:%M:%S")
|
||||
#There is no end character appended, no need for end=''
|
||||
new_file.write(line.replace(original_time, new_time))
|
||||
|
||||
|
||||
os.remove(original_backup_file)
|
||||
|
||||
def manipulate_timestamp_windows_event_log_raw(self, path):
|
||||
#path = os.path.join(os.path.dirname(__file__), '../' + file_path)
|
||||
#path = path.replace('modules/../','')
|
||||
|
||||
f = io.open(path, "r", encoding="utf-8")
|
||||
self.now = datetime.now()
|
||||
self.now = self.now.strftime("%Y-%m-%dT%H:%M:%S.%fZ")
|
||||
self.now = datetime.strptime(self.now,"%Y-%m-%dT%H:%M:%S.%fZ")
|
||||
|
||||
# read raw logs
|
||||
regex = r'\d{2}/\d{2}/\d{4} \d{2}:\d{2}:\d{2} [AP]M'
|
||||
data = f.read()
|
||||
lst_matches = re.findall(regex, data)
|
||||
if len(lst_matches) > 0:
|
||||
latest_event = datetime.strptime(lst_matches[-1],"%m/%d/%Y %I:%M:%S %p")
|
||||
self.difference = self.now - latest_event
|
||||
f.close()
|
||||
|
||||
result = re.sub(regex, self.replacement_function, data)
|
||||
|
||||
with io.open(path, "w+", encoding='utf8') as f:
|
||||
f.write(result)
|
||||
else:
|
||||
f.close()
|
||||
return
|
||||
|
||||
|
||||
def replacement_function(self, match):
|
||||
try:
|
||||
event_time = datetime.strptime(match.group(),"%m/%d/%Y %I:%M:%S %p")
|
||||
new_time = self.difference + event_time
|
||||
return new_time.strftime("%m/%d/%Y %I:%M:%S %p")
|
||||
except Exception as e:
|
||||
self.logger.error("Error in timestamp replacement occured: " + str(e))
|
||||
return match.group()
|
||||
|
||||
|
||||
def manipulate_timestamp_cloudtrail(self, path):
|
||||
#path = os.path.join(os.path.dirname(__file__), '../' + file_path)
|
||||
#path = path.replace('modules/../','')
|
||||
|
||||
f = io.open(path, "r", encoding="utf-8")
|
||||
|
||||
try:
|
||||
first_line = f.readline()
|
||||
d = json.loads(first_line)
|
||||
latest_event = datetime.strptime(d["eventTime"],"%Y-%m-%dT%H:%M:%S.%fZ")
|
||||
|
||||
now = datetime.now()
|
||||
now = now.strftime("%Y-%m-%dT%H:%M:%S.%fZ")
|
||||
now = datetime.strptime(now,"%Y-%m-%dT%H:%M:%S.%fZ")
|
||||
except ValueError:
|
||||
first_line = f.readline()
|
||||
d = json.loads(first_line)
|
||||
latest_event = datetime.strptime(d["eventTime"],"%Y-%m-%dT%H:%M:%SZ")
|
||||
|
||||
now = datetime.now()
|
||||
now = now.strftime("%Y-%m-%dT%H:%M:%SZ")
|
||||
now = datetime.strptime(now,"%Y-%m-%dT%H:%M:%SZ")
|
||||
|
||||
difference = now - latest_event
|
||||
f.close()
|
||||
|
||||
|
||||
|
||||
#Mimic the behavior of fileinput but in a threadsafe way
|
||||
#Rename the file, which fileinput does for inplace.
|
||||
#Note that path will now be the new file
|
||||
original_backup_file = f"{path}.bak"
|
||||
os.rename(path, original_backup_file)
|
||||
|
||||
with open(original_backup_file, "r") as original_file:
|
||||
with open(path, "w") as new_file:
|
||||
for line in original_file:
|
||||
try:
|
||||
d = json.loads(line)
|
||||
original_time = datetime.strptime(d["eventTime"],"%Y-%m-%dT%H:%M:%S.%fZ")
|
||||
new_time = (difference + original_time)
|
||||
|
||||
original_time = original_time.strftime("%Y-%m-%dT%H:%M:%S.%fZ")
|
||||
new_time = new_time.strftime("%Y-%m-%dT%H:%M:%S.%fZ")
|
||||
new_file.write(line.replace(original_time, new_time))
|
||||
except ValueError:
|
||||
d = json.loads(line)
|
||||
original_time = datetime.strptime(d["eventTime"],"%Y-%m-%dT%H:%M:%SZ")
|
||||
new_time = (difference + original_time)
|
||||
|
||||
original_time = original_time.strftime("%Y-%m-%dT%H:%M:%SZ")
|
||||
new_time = new_time.strftime("%Y-%m-%dT%H:%M:%SZ")
|
||||
new_file.write(line.replace(original_time, new_time))
|
||||
|
||||
|
||||
os.remove(original_backup_file)
|
||||
@@ -1,305 +0,0 @@
|
||||
from collections import OrderedDict
|
||||
from tabnanny import check
|
||||
import docker
|
||||
import datetime
|
||||
import docker.types
|
||||
import os
|
||||
import random
|
||||
|
||||
from modules import splunk_container
|
||||
import string
|
||||
from modules import test_driver
|
||||
import threading
|
||||
import time
|
||||
import timeit
|
||||
|
||||
from typing import Union
|
||||
|
||||
WEB_PORT_STRING = "8000/tcp"
|
||||
MANAGEMENT_PORT_STRING = "8089/tcp"
|
||||
|
||||
|
||||
class ContainerManager:
|
||||
def __init__(
|
||||
self,
|
||||
test_list: list[str],
|
||||
full_docker_hub_name: str,
|
||||
container_name_template: str,
|
||||
num_containers: int,
|
||||
apps: OrderedDict,
|
||||
branch:str,
|
||||
commit_hash:str,
|
||||
summarization_reproduce_failure_config:dict,
|
||||
files_to_copy_to_container: OrderedDict = OrderedDict(),
|
||||
web_port_start: int = 8000,
|
||||
management_port_start: int = 8089,
|
||||
mounts: list[dict[str, str]] = [],
|
||||
show_container_password:bool=True,
|
||||
container_password: Union[str, None] = None,
|
||||
splunkbase_username: Union[str, None] = None,
|
||||
splunkbase_password: Union[str, None] = None,
|
||||
reuse_image:bool = True,
|
||||
interactive_failure:bool=False,
|
||||
interactive:bool=False
|
||||
|
||||
):
|
||||
#Used to determine whether or not we should wait for container threads to finish when summarizing
|
||||
self.all_tests_completed = False
|
||||
|
||||
self.synchronization_object = test_driver.TestDriver(
|
||||
test_list, num_containers, summarization_reproduce_failure_config)
|
||||
|
||||
self.mounts = self.create_mounts(mounts)
|
||||
self.apps = apps
|
||||
|
||||
|
||||
if container_password is None:
|
||||
self.container_password = self.get_random_password()
|
||||
else:
|
||||
self.container_password = container_password
|
||||
|
||||
print("\n\n***********************")
|
||||
print("Log into your [%d] Splunk Container(s) after they boot at http://127.0.0.1:[%d-%d]"%(num_containers, web_port_start, web_port_start + num_containers - 1))
|
||||
print("\tSplunk App Username: [%s]"%("admin"))
|
||||
print("\tSplunk App Password: ", end='')
|
||||
if show_container_password:
|
||||
print("[%s]"%(self.container_password))
|
||||
else:
|
||||
print(" --show_splunk_app_password set to False - password not printed")
|
||||
print("***********************\n\n")
|
||||
|
||||
|
||||
self.containers = self.create_containers(
|
||||
full_docker_hub_name,
|
||||
container_name_template,
|
||||
num_containers,
|
||||
web_port_start,
|
||||
management_port_start,
|
||||
splunkbase_username,
|
||||
splunkbase_password,
|
||||
files_to_copy_to_container,
|
||||
reuse_image,
|
||||
interactive_failure,
|
||||
interactive
|
||||
)
|
||||
self.summary_thread = threading.Thread(target=self.queue_status_thread,args=())
|
||||
|
||||
#Construct the baseline from the splunk version and the apps to be installed
|
||||
self.baseline = OrderedDict()
|
||||
#Get a datetime and add it as the first entry in the baseline
|
||||
self.start_time = datetime.datetime.now()
|
||||
self.baseline['SPLUNK_VERSION'] = full_docker_hub_name
|
||||
self.baseline["branch"] = branch
|
||||
self.baseline["commit_hash"] = commit_hash
|
||||
#Added here first to preserve ordering for OrderedDict
|
||||
self.baseline['TEST_START_TIME'] = "TO BE UPDATED"
|
||||
self.baseline['TEST_FINISH_TIME'] = "TO BE UPDATED"
|
||||
self.baseline['TEST_DURATION'] = "TO BE UPDATED"
|
||||
|
||||
for key in self.apps:
|
||||
self.baseline[key] = self.apps[key]
|
||||
|
||||
|
||||
|
||||
|
||||
def run_test(self)->bool:
|
||||
self.run_status_thread()
|
||||
self.run_containers()
|
||||
self.summary_thread.join()
|
||||
|
||||
|
||||
|
||||
|
||||
for container in self.containers:
|
||||
if self.all_tests_completed == True:
|
||||
container.thread.join()
|
||||
elif self.all_tests_completed == False:
|
||||
#For some reason, we stopped early. So don't wait on the child threads to finish. Don't join,
|
||||
#these threads may be stuck in their setup loops. Continue on.
|
||||
pass
|
||||
|
||||
print(container.get_container_summary())
|
||||
print("All containers completed testing!")
|
||||
|
||||
|
||||
stop_time = datetime.datetime.now()
|
||||
x = stop_time - self.start_time
|
||||
|
||||
self.baseline['TEST_START_TIME'] = str(self.start_time)
|
||||
self.baseline['TEST_FINISH_TIME'] = str(stop_time)
|
||||
|
||||
duration = stop_time - self.start_time
|
||||
self.baseline['TEST_DURATION'] = str(duration - datetime.timedelta(microseconds=duration.microseconds))
|
||||
|
||||
return self.synchronization_object.finish(self.baseline)
|
||||
|
||||
|
||||
|
||||
|
||||
def run_containers(self) -> None:
|
||||
for container_number, container in enumerate(self.containers):
|
||||
#give a little time between container startup if there is more than one container.
|
||||
#Never wait on the first container. This gets us to testing as fast as possible
|
||||
#for the most common case (one container) and gives us some extra time and
|
||||
#reduces load when we are launching more than one container
|
||||
if (container_number != 0):
|
||||
time.sleep(10)
|
||||
container.thread.start()
|
||||
|
||||
|
||||
def run_status_thread(self) -> None:
|
||||
self.summary_thread.start()
|
||||
|
||||
|
||||
|
||||
def create_containers(
|
||||
self,
|
||||
full_docker_hub_name: str,
|
||||
container_name_template: str,
|
||||
num_containers: int,
|
||||
web_port_start: int,
|
||||
management_port_start: int,
|
||||
splunkbase_username: Union[str, None] = None,
|
||||
splunkbase_password: Union[str, None] = None,
|
||||
files_to_copy_to_container: OrderedDict = OrderedDict(),
|
||||
reuse_image:bool = True,
|
||||
interactive_failure:bool = False,
|
||||
interactive:bool = False
|
||||
) -> list[splunk_container.SplunkContainer]:
|
||||
#First make sure that the image exists and has been downloaded.
|
||||
#Note that this is intentionally not part of the time to start
|
||||
#since it can take a long time on a slow connection!
|
||||
self.setup_image(reuse_image, full_docker_hub_name)
|
||||
|
||||
new_containers = []
|
||||
for index in range(num_containers):
|
||||
container_name = container_name_template % index
|
||||
web_port_tuple = (WEB_PORT_STRING, web_port_start + index)
|
||||
management_port_tuple = (
|
||||
MANAGEMENT_PORT_STRING,
|
||||
management_port_start + index,
|
||||
)
|
||||
|
||||
new_containers.append(
|
||||
splunk_container.SplunkContainer(
|
||||
self.synchronization_object,
|
||||
full_docker_hub_name,
|
||||
container_name,
|
||||
self.apps,
|
||||
web_port_tuple,
|
||||
management_port_tuple,
|
||||
self.container_password,
|
||||
files_to_copy_to_container,
|
||||
self.mounts,
|
||||
splunkbase_username,
|
||||
splunkbase_password,
|
||||
interactive_failure=interactive_failure,
|
||||
interactive=interactive
|
||||
)
|
||||
)
|
||||
|
||||
return new_containers
|
||||
|
||||
def create_mounts(
|
||||
self, mounts: list[dict[str, str]]
|
||||
) -> list[docker.types.Mount]:
|
||||
new_mounts = []
|
||||
for mount in mounts:
|
||||
new_mounts.append(self.create_mount(mount))
|
||||
return new_mounts
|
||||
|
||||
def create_mount(self, mount: dict[str, str]) -> docker.types.Mount:
|
||||
return docker.types.Mount(
|
||||
source=os.path.abspath(mount["local_path"]),
|
||||
target=mount["container_path"],
|
||||
type=mount["type"],
|
||||
read_only=mount["read_only"],
|
||||
)
|
||||
|
||||
# taken from attack_range
|
||||
def get_random_password(
|
||||
self, password_min_length: int = 16, password_max_length: int = 26
|
||||
) -> str:
|
||||
random_source = string.ascii_letters + string.digits
|
||||
password = random.choice(string.ascii_lowercase)
|
||||
password += random.choice(string.ascii_uppercase)
|
||||
password += random.choice(string.digits)
|
||||
|
||||
for i in range(random.randrange(password_min_length, password_max_length)):
|
||||
password += random.choice(random_source)
|
||||
|
||||
password_list = list(password)
|
||||
random.SystemRandom().shuffle(password_list)
|
||||
password = "".join(password_list)
|
||||
return password
|
||||
|
||||
def queue_status_thread(self, status_interval:int=60, num_steps:int=10)->None:
|
||||
|
||||
while True:
|
||||
#This for loop lets us run the summarize print less often, but check for failure more often
|
||||
for chunk in range(0, status_interval, int(status_interval/num_steps)):
|
||||
if self.synchronization_object.checkContainerFailure():
|
||||
print("One of the containers has shut down prematurely or the test was halted. Ensuring all containers are stopped.")
|
||||
for container in self.containers:
|
||||
container.stopContainer()
|
||||
print("All containers stopped")
|
||||
self.all_tests_completed = False
|
||||
return None
|
||||
time.sleep(status_interval/num_steps)
|
||||
|
||||
at_least_one_container_has_started_running_tests = False
|
||||
for container in self.containers:
|
||||
if container.test_start_time != -1:
|
||||
at_least_one_container_has_started_running_tests = True
|
||||
break
|
||||
if self.synchronization_object.summarize(testing_currently_active = at_least_one_container_has_started_running_tests) == False:
|
||||
#There are no more tests to run, so we can return from this thread
|
||||
self.all_tests_completed = True
|
||||
return None
|
||||
|
||||
|
||||
def setup_image(self, reuse_images: bool, container_name: str) -> None:
|
||||
client = docker.client.from_env()
|
||||
if not reuse_images:
|
||||
#Check to see if the image exists. If it does, then remove it. If it does not, then do nothing
|
||||
docker_image = None
|
||||
try:
|
||||
docker_image = client.images.get(container_name)
|
||||
except Exception as e:
|
||||
#We don't need to do anything, the image did not exist on our system
|
||||
#print("Image named [%s] did not exist, so we don't need to try and remove it."%(container_name))
|
||||
pass
|
||||
if docker_image != None:
|
||||
#We found the image. Let's try to delete it
|
||||
print("Found docker image named [%s] and you have requested that we forcefully remove it"%(container_name))
|
||||
try:
|
||||
client.images.remove(image=container_name, force=True, noprune=False)
|
||||
print("Docker image named [%s] forcefully removed"%(container_name))
|
||||
except Exception as e:
|
||||
print("Error forcefully removing [%s]"%(container_name))
|
||||
raise(e)
|
||||
|
||||
#See if the image exists. If it doesn't, then pull it from Docker Hub
|
||||
try:
|
||||
docker_image = client.images.get(container_name)
|
||||
print("Docker image [%s] found, no need to download it."%(container_name))
|
||||
except Exception as e:
|
||||
#Image did not exist on the system
|
||||
docker_image = None
|
||||
|
||||
if docker_image is None:
|
||||
#We did not find the image, so pull it
|
||||
try:
|
||||
print("Downloading image [%s]. Please note "
|
||||
"that this could take a long time depending on your "
|
||||
"connection. It's around 2GB."%(container_name))
|
||||
pull_start_time = timeit.default_timer()
|
||||
client.images.pull(container_name,platform="linux/amd64")
|
||||
pull_finish_time = timeit.default_timer()
|
||||
print("Successfully pulled the docker image [%s] in %ss"%
|
||||
(container_name,
|
||||
datetime.timedelta(seconds=pull_finish_time - pull_start_time, microseconds=0) ))
|
||||
|
||||
except Exception as e:
|
||||
print("There was an error trying to pull the image [%s]: [%s]"%(container_name,str(e)))
|
||||
raise(e)
|
||||
@@ -1,572 +0,0 @@
|
||||
import csv
|
||||
import glob
|
||||
import logging
|
||||
import os
|
||||
import pathlib
|
||||
import subprocess
|
||||
import sys
|
||||
from typing import Union
|
||||
from docker import types
|
||||
import datetime
|
||||
import git
|
||||
import yaml
|
||||
from git.objects import base
|
||||
from modules import testing_service
|
||||
import pathlib
|
||||
|
||||
# Logger
|
||||
logging.basicConfig(level=os.environ.get("LOGLEVEL", "INFO"))
|
||||
LOGGER = logging.getLogger(__name__)
|
||||
|
||||
SECURITY_CONTENT_URL = "https://github.com/splunk/security_content"
|
||||
|
||||
|
||||
DETECTION_ROOT_PATH = "security_content/detections"
|
||||
TEST_ROOT_PATH = "security_content/tests"
|
||||
DETECTION_FILE_EXTENSION = ".yml"
|
||||
TEST_FILE_EXTENSION = ".test.yml"
|
||||
SSA_PREFIX = "ssa___"
|
||||
|
||||
|
||||
class GithubService:
|
||||
def __init__(
|
||||
self,
|
||||
security_content_branch: str,
|
||||
commit_hash: Union[str, None],
|
||||
PR_number: Union[int, None] = None,
|
||||
persist_security_content: bool = False,
|
||||
):
|
||||
self.security_content_branch = security_content_branch
|
||||
if persist_security_content:
|
||||
print("Getting handle on existing security_content repo!")
|
||||
self.security_content_repo_obj = git.Repo("security_content")
|
||||
else:
|
||||
print("Checking out security_content repo!")
|
||||
self.security_content_repo_obj = self.clone_project(
|
||||
SECURITY_CONTENT_URL, f"security_content", f"develop"
|
||||
)
|
||||
|
||||
# Ensure that the branch name is valid
|
||||
# Get all the branch names, prefixed with "origin/"
|
||||
branch_names = [
|
||||
branch.name for branch in self.security_content_repo_obj.remote().refs
|
||||
]
|
||||
|
||||
if "origin/%s" % (security_content_branch) not in branch_names:
|
||||
raise (
|
||||
Exception(
|
||||
"Branch name [%s] not found in valid branches. Try running \n"
|
||||
"'git branch -a' to examine [%d] branches"
|
||||
% (security_content_branch, len(branch_names))
|
||||
)
|
||||
)
|
||||
|
||||
if commit_hash is not None and PR_number is not None:
|
||||
print(
|
||||
f"\n************\nWARNING - both the PR_number {PR_number} and the commit_hash {commit_hash} were provided. "
|
||||
f"You should only pass neither or one of these. We will ASSUME you want to use the PR_number, not the commit_hash. "
|
||||
f"Removing the commit_hash...\n************\n"
|
||||
)
|
||||
commit_hash = None
|
||||
|
||||
if PR_number:
|
||||
ret = subprocess.run(
|
||||
[
|
||||
"git",
|
||||
"-C",
|
||||
"security_content/",
|
||||
"fetch",
|
||||
"origin",
|
||||
"refs/pull/%d/head:%s" % (PR_number, security_content_branch),
|
||||
],
|
||||
capture_output=True,
|
||||
)
|
||||
# ret = subprocess.call(["git", "-C", "security_content/", "fetch", "origin",
|
||||
# "refs/pull/%d/head:%s" % (PR_number, security_content_branch)])
|
||||
|
||||
if ret.returncode != 0:
|
||||
raise (
|
||||
Exception(
|
||||
"Error checking out repository: [%s]"
|
||||
% (
|
||||
ret.stdout.decode("utf-8")
|
||||
+ "\n"
|
||||
+ ret.stderr.decode("utf-8")
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
# No checking to see if the hash is to a commit inside of the branch - the user
|
||||
# has to do that by hand.
|
||||
|
||||
# -- ensures that we check out the appropriate branch or commit hash.
|
||||
# Without --, there can be ambiguity if a file/folder exists with the
|
||||
# same name as the branch, causing the checkout to fail with error
|
||||
if commit_hash is not None:
|
||||
print("Checking out commit hash: [%s]" % (commit_hash))
|
||||
self.security_content_repo_obj.git.checkout(commit_hash, "--")
|
||||
else:
|
||||
# Even if we have fetched a PR, we still MUST check out the branch to
|
||||
# be able to do anything with it. Otherwise we won't have the files
|
||||
print("Checking out branch: [%s]..." % (security_content_branch), end="")
|
||||
sys.stdout.flush()
|
||||
self.security_content_repo_obj.git.checkout(security_content_branch, "--")
|
||||
commit_hash = self.security_content_repo_obj.head.object.hexsha
|
||||
print("commit_hash %s" % (commit_hash))
|
||||
|
||||
self.commit_hash = commit_hash
|
||||
|
||||
def update_and_commit_passed_tests(self, results: list[dict]) -> bool:
|
||||
changed_file_paths = []
|
||||
for result in results:
|
||||
detection_obj_path = os.path.join(
|
||||
"security_content", "detections", result["detection_file"]
|
||||
)
|
||||
|
||||
test_obj_path = detection_obj_path.replace("detections", "tests", 1)
|
||||
test_obj_path = test_obj_path.replace(".yml", ".test.yml")
|
||||
|
||||
detection_obj = testing_service.load_file(detection_obj_path)
|
||||
test_obj = testing_service.load_file(test_obj_path)
|
||||
detection_obj["tags"]["automated_detection_testing"] = "passed"
|
||||
# detection_obj['tags']['automated_detection_testing_date'] = datetime.datetime.today().strftime('%Y-%m-%d-%H:%M:%S')
|
||||
|
||||
for o in test_obj["tests"]:
|
||||
if "attack_data" in o:
|
||||
datasets = []
|
||||
for dataset in o["attack_data"]:
|
||||
datasets.append(dataset["data"])
|
||||
detection_obj["tags"]["dataset"] = datasets
|
||||
with open(detection_obj_path, "w") as f:
|
||||
yaml.dump(detection_obj, f, sort_keys=False, allow_unicode=True)
|
||||
|
||||
changed_file_paths.append(detection_obj_path)
|
||||
|
||||
relpaths = [
|
||||
pathlib.Path(*pathlib.Path(p).parts[1:]).as_posix()
|
||||
for p in changed_file_paths
|
||||
]
|
||||
newpath = relpaths[0] + ".wow"
|
||||
relpaths.append(newpath)
|
||||
with open("security_content/" + newpath, "w") as d:
|
||||
d.write("fake file")
|
||||
print("status results:")
|
||||
print(
|
||||
self.security_content_repo_obj.index.diff(
|
||||
self.security_content_repo_obj.head.commit
|
||||
)
|
||||
)
|
||||
|
||||
if len(relpaths) > 0:
|
||||
print("there is at least one changed file")
|
||||
print(relpaths)
|
||||
self.security_content_repo_obj.index.add(relpaths)
|
||||
print("status results after add:")
|
||||
print(
|
||||
self.security_content_repo_obj.index.diff(
|
||||
self.security_content_repo_obj.head.commit
|
||||
)
|
||||
)
|
||||
|
||||
commit_message = (
|
||||
"The following detections passed detection testing. Their YAMLs have been updated and their datasets linked:\n - %s"
|
||||
% ("\n - ".join(relpaths))
|
||||
)
|
||||
self.security_content_repo_obj.index.commit(commit_message)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def clone_project(self, url, project, branch):
|
||||
LOGGER.info(f"Clone Security Content Project")
|
||||
repo_obj = git.Repo.clone_from(url, project, branch=branch)
|
||||
return repo_obj
|
||||
|
||||
def prune_detections(
|
||||
self,
|
||||
detection_files: list[str],
|
||||
types_to_test: list[str],
|
||||
exclude_ssa: bool = True,
|
||||
) -> list[str]:
|
||||
pruned_tests = []
|
||||
|
||||
for detection in detection_files:
|
||||
if os.path.basename(detection).startswith(SSA_PREFIX) and exclude_ssa:
|
||||
continue
|
||||
with open(detection, "r") as d:
|
||||
description: dict = yaml.safe_load(d)
|
||||
|
||||
detection_filepath_without_security_content = str(
|
||||
pathlib.Path(*pathlib.Path(detection).parts[1:])
|
||||
)
|
||||
# If no types are provided, then we will get everything
|
||||
if (
|
||||
description.get("type", None) in types_to_test
|
||||
and "production" in description.get("status", "")
|
||||
and not (
|
||||
description.get("tags", False)
|
||||
and description["tags"].get("manual_test", False)
|
||||
)
|
||||
):
|
||||
if len(description.get("tests", [])) == 0:
|
||||
print(
|
||||
Exception(
|
||||
f"Detection {detection_filepath_without_security_content} has no tests/test section defined. Detection must include at least one test."
|
||||
)
|
||||
)
|
||||
continue
|
||||
raise (
|
||||
Exception(
|
||||
f"Detection {detection_filepath_without_security_content} has no tests/test section defined. Detection must include at least one test."
|
||||
)
|
||||
)
|
||||
|
||||
pruned_tests.append(detection_filepath_without_security_content)
|
||||
|
||||
else:
|
||||
if description.get("tags", False):
|
||||
manual_test = description["tags"].get("manual_test", False)
|
||||
else:
|
||||
manual_test = False
|
||||
|
||||
print(
|
||||
f"Ignore {detection}:\n - [status:'{description.get('status', None)}'] [type:'{description.get('type', None)}'] [manual_test:'{manual_test}']"
|
||||
)
|
||||
# Don't do anything with these files
|
||||
pass
|
||||
|
||||
# if not self.ensure_paired_detection_and_test_files([], [os.path.join("security_content", p) for p in pruned_tests], exclude_ssa):
|
||||
# raise(Exception("Missing one or more test/detection files. Please see the output above."))
|
||||
|
||||
return pruned_tests
|
||||
|
||||
def ensure_paired_detection_and_test_files(
|
||||
self,
|
||||
detection_files: list[str],
|
||||
test_files: list[str],
|
||||
exclude_ssa: bool = True,
|
||||
) -> bool:
|
||||
"""
|
||||
The security_content repo contains two folders: detections and test.
|
||||
For EVERY detection in the detections folder, there must be a test.
|
||||
for EVERY test in the tests folder, there MUST be a detection.
|
||||
|
||||
If this requirement is not met, then throw an error
|
||||
"""
|
||||
|
||||
MISSING_TEMPLATE = (
|
||||
"Missing {type} file:" "\n\tEXISTS - {exists}" "\n\tMISSING - {missing}"
|
||||
)
|
||||
|
||||
no_missing_files = True
|
||||
# Check that all detection files have a test file
|
||||
for detection_file in detection_files:
|
||||
test_file = self.convert_detection_filename_into_test_filename(
|
||||
detection_file
|
||||
)
|
||||
if not os.path.exists(test_file):
|
||||
if (
|
||||
os.path.basename(detection_file).startswith(SSA_PREFIX)
|
||||
and exclude_ssa is True
|
||||
):
|
||||
print(
|
||||
MISSING_TEMPLATE.format(
|
||||
type="test", exists=detection_file, missing=test_file
|
||||
)
|
||||
)
|
||||
print(
|
||||
"\tSince exclude_ssa is TRUE, this is not an error, just a warning"
|
||||
)
|
||||
else:
|
||||
print(
|
||||
MISSING_TEMPLATE.format(
|
||||
type="test", exists=detection_file, missing=test_file
|
||||
)
|
||||
)
|
||||
no_missing_files = False
|
||||
|
||||
# Check that all test files have a detection file
|
||||
for test_file in test_files:
|
||||
detection_file = self.convert_test_filename_into_detection_filename(
|
||||
test_file
|
||||
)
|
||||
if not os.path.exists(detection_file):
|
||||
if (
|
||||
os.path.basename(test_file).startswith(SSA_PREFIX)
|
||||
and exclude_ssa is True
|
||||
):
|
||||
print(
|
||||
MISSING_TEMPLATE.format(
|
||||
type="detection", exists=test_file, missing=detection_file
|
||||
)
|
||||
)
|
||||
print(
|
||||
"\tSince exclude_ssa is TRUE, this is not an error, just a warning"
|
||||
)
|
||||
else:
|
||||
print(
|
||||
MISSING_TEMPLATE.format(
|
||||
type="detection", exists=test_file, missing=detection_file
|
||||
)
|
||||
)
|
||||
no_missing_files = False
|
||||
|
||||
return no_missing_files
|
||||
|
||||
def convert_detection_filename_into_test_filename(
|
||||
self, detection_filename: str
|
||||
) -> str:
|
||||
head, tail = os.path.split(detection_filename)
|
||||
|
||||
assert head.startswith(
|
||||
DETECTION_ROOT_PATH
|
||||
), f"Error - Expected detection filename to start with [{DETECTION_ROOT_PATH}] but instead got {detection_filename}"
|
||||
|
||||
updated_head = head.replace(DETECTION_ROOT_PATH, TEST_ROOT_PATH, 1)
|
||||
|
||||
assert tail.endswith(
|
||||
DETECTION_FILE_EXTENSION
|
||||
), f"Error - Expected detection filename to end with [{DETECTION_FILE_EXTENSION}] but instead got [{detection_filename}]"
|
||||
updated_tail = TEST_FILE_EXTENSION.join(tail.rsplit(DETECTION_FILE_EXTENSION))
|
||||
|
||||
return os.path.join(updated_head, updated_tail)
|
||||
|
||||
def convert_test_filename_into_detection_filename(self, test_filename: str) -> str:
|
||||
head, tail = os.path.split(test_filename)
|
||||
|
||||
assert head.startswith(
|
||||
TEST_ROOT_PATH
|
||||
), f"Error - Expected test filename to start with [{TEST_ROOT_PATH}] but instead got {test_filename}"
|
||||
|
||||
updated_head = head.replace(TEST_ROOT_PATH, DETECTION_ROOT_PATH, 1)
|
||||
|
||||
assert tail.endswith(
|
||||
TEST_FILE_EXTENSION
|
||||
), f"Error - Expected test filename to end with [{TEST_FILE_EXTENSION}] but instead got [{test_filename}]"
|
||||
updated_tail = DETECTION_FILE_EXTENSION.join(tail.rsplit(TEST_FILE_EXTENSION))
|
||||
|
||||
return os.path.join(updated_head, updated_tail)
|
||||
|
||||
def get_detection_files(
|
||||
self,
|
||||
mode: str,
|
||||
folders: list[str],
|
||||
types: list[str],
|
||||
detections_list: Union[list[str], None],
|
||||
) -> list[str]:
|
||||
if mode == "changes":
|
||||
tests = self.get_changed_detection_files(folders, types)
|
||||
elif mode == "selected":
|
||||
if detections_list is None:
|
||||
# It's actually valid to supply an EMPTY list of files and the test should pass.
|
||||
# This can occur when we try to test, for example, 1 detection but start 2 containers.
|
||||
# We still want this to pass testing, so we shouldn't fail there!
|
||||
print(
|
||||
"Trying to test a list of files, but None were provided",
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
elif detections_list is not None:
|
||||
tests = self.get_selected_test_files(detections_list, types)
|
||||
else:
|
||||
# impossible to get here
|
||||
print(
|
||||
"Impossible to get here. Just kept to make the if/elif more self describing",
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
elif mode == "all":
|
||||
tests = self.get_all_tests_and_detections(folders, types)
|
||||
elif mode == "smoketest":
|
||||
tests = self.get_everything_including_experimental_and_deprecated(types)
|
||||
else:
|
||||
print(
|
||||
"Error, unsupported mode [%s]. Mode must be one of %s", file=sys.stderr
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
return tests
|
||||
|
||||
def get_selected_test_files(
|
||||
self,
|
||||
detection_file_list: list[str],
|
||||
types_to_test: list[str] = ["Anomaly", "Hunting", "TTP"],
|
||||
) -> list[str]:
|
||||
return self.prune_detections(detection_file_list, types_to_test)
|
||||
|
||||
def get_everything_including_experimental_and_deprecated(
|
||||
self,
|
||||
types_to_test: list[str] = ["Anomaly", "Hunting", "TTP"],
|
||||
exclude_ssa: bool = True,
|
||||
) -> list[str]:
|
||||
all_detections = glob.glob(
|
||||
os.path.join(DETECTION_ROOT_PATH, "**", f"*{DETECTION_FILE_EXTENSION}"),
|
||||
recursive=True,
|
||||
)
|
||||
only_selected_detection_types: list[str] = []
|
||||
for detection in all_detections:
|
||||
if os.path.basename(detection).startswith(SSA_PREFIX) and exclude_ssa:
|
||||
continue
|
||||
with open(detection, "r") as d:
|
||||
description: dict = yaml.safe_load(d)
|
||||
|
||||
detection_filepath_without_security_content = str(
|
||||
pathlib.Path(*pathlib.Path(detection).parts[1:])
|
||||
)
|
||||
|
||||
if description.get("type", None) not in types_to_test:
|
||||
continue
|
||||
only_selected_detection_types.append(
|
||||
detection_filepath_without_security_content
|
||||
)
|
||||
|
||||
print(
|
||||
f"Number of non-ssa tests including experimental and deprecated: {len(only_selected_detection_types)}"
|
||||
)
|
||||
|
||||
return only_selected_detection_types
|
||||
|
||||
def get_all_tests_and_detections(
|
||||
self,
|
||||
folders: list[str] = ["endpoint", "cloud", "network"],
|
||||
types_to_test: list[str] = ["Anomaly", "Hunting", "TTP"],
|
||||
) -> list[str]:
|
||||
detections = []
|
||||
for folder in folders:
|
||||
detections.extend(
|
||||
self.get_all_files_in_folder(
|
||||
os.path.join(DETECTION_ROOT_PATH, folder), "*"
|
||||
)
|
||||
)
|
||||
|
||||
# Prune this down to only the subset of detections we can test
|
||||
return self.prune_detections(detections, types_to_test)
|
||||
|
||||
def get_all_files_in_folder(self, foldername: str, extension: str) -> list[str]:
|
||||
filenames = glob.glob(os.path.join(foldername, extension))
|
||||
return filenames
|
||||
|
||||
def get_changed_detection_files(
|
||||
self,
|
||||
folders=["endpoint", "cloud", "network"],
|
||||
types_to_test=["Anomaly", "Hunting", "TTP"],
|
||||
) -> list[str]:
|
||||
branch1 = self.security_content_branch
|
||||
branch2 = "develop"
|
||||
g = git.Git("security_content")
|
||||
all_changed_test_files = []
|
||||
|
||||
all_changed_detection_files = []
|
||||
if branch1 != "develop":
|
||||
if self.commit_hash is None:
|
||||
differ = g.diff("--name-status", branch2 + "..." + branch1)
|
||||
else:
|
||||
differ = g.diff("--name-status", branch2 + "..." + self.commit_hash)
|
||||
|
||||
changed_files = differ.splitlines()
|
||||
|
||||
for file_path in changed_files:
|
||||
# added or changed test files
|
||||
if file_path.startswith("A") or file_path.startswith("M"):
|
||||
# changed detections
|
||||
if "detections" in file_path and os.path.basename(
|
||||
file_path
|
||||
).endswith(".yml"):
|
||||
all_changed_detection_files.append(file_path)
|
||||
else:
|
||||
print(
|
||||
"Looking for changed detections by diffing [%s] against [%s]. They are the same branch, so none were returned."
|
||||
% (branch1, branch2),
|
||||
file=sys.stderr,
|
||||
)
|
||||
return []
|
||||
|
||||
all_changed_detection_files = [
|
||||
os.path.join("security_content", name.split("\t")[1])
|
||||
for name in all_changed_detection_files
|
||||
if len(name.split("\t")) == 2
|
||||
]
|
||||
|
||||
# Trim out any of the tests/detection that are not in the selected folders, but at least print a notice
|
||||
# to the user.
|
||||
|
||||
changed_detection_files = [
|
||||
x
|
||||
for x in all_changed_detection_files
|
||||
if (len(pathlib.Path(x).parts) > 3 and pathlib.Path(x).parts[2] in folders)
|
||||
]
|
||||
|
||||
for missing in set(changed_detection_files).symmetric_difference(
|
||||
all_changed_detection_files
|
||||
):
|
||||
print(
|
||||
"Ignoring modified detecton [%s] not in set of selected folders: %s"
|
||||
% (missing, folders)
|
||||
)
|
||||
|
||||
# Convert the test files to the detection file equivalent.
|
||||
# Note that some of these tests may be baselines and their associated
|
||||
# detection could be in experimental or not in the experimental folder
|
||||
converted_test_files = []
|
||||
# for test_filepath in changed_test_files:
|
||||
# detection_filename = str(pathlib.Path(
|
||||
# *pathlib.Path(test_filepath).parts[-2:])).replace("tests", "detections", 1)
|
||||
# converted_test_files.append(detection_filename)
|
||||
|
||||
return self.prune_detections(changed_detection_files, types_to_test)
|
||||
|
||||
# detections_to_test,_,_ = self.filter_test_types(changed_detection_files)
|
||||
# for f in detections_to_test:
|
||||
# file_path_base = os.path.splitext(f)[0].replace('detections', 'tests') + '.test'
|
||||
# file_path_new = file_path_base + '.yml'
|
||||
# if file_path_new not in changed_test_files:
|
||||
# changed_test_files.append(file_path_new)
|
||||
|
||||
# print("Total things to test (test files and detection files changed): [%d]"%(len(changed_test_files)))
|
||||
# for l in changed_test_files:
|
||||
# print(l)
|
||||
# print(len(changed_test_files))
|
||||
# import time
|
||||
# time.sleep(5)
|
||||
|
||||
def filter_test_types(self, test_files, test_types=["Anomaly", "Hunting", "TTP"]):
|
||||
files_to_test = []
|
||||
files_not_to_test = []
|
||||
error_files = []
|
||||
for filename in test_files:
|
||||
try:
|
||||
with open(os.path.join("security_content", filename), "r") as fileData:
|
||||
yaml_dict = list(yaml.safe_load_all(fileData))[0]
|
||||
if "type" not in yaml_dict.keys():
|
||||
print(
|
||||
"Failed to find 'type' in the yaml for: [%s]" % (filename)
|
||||
)
|
||||
error_files.append(filename)
|
||||
if yaml_dict["type"] in test_types:
|
||||
files_to_test.append(filename)
|
||||
else:
|
||||
files_not_to_test.append(filename)
|
||||
except Exception as e:
|
||||
print("Error on trying to scan [%s]: [%s]" % (filename, str(e)))
|
||||
error_files.append(filename)
|
||||
print(
|
||||
"***Detection Information***\n"
|
||||
"\tTotal Files : %d"
|
||||
"\tFiles to test : %d"
|
||||
"\tFiles not to test : %d"
|
||||
"\tError files : %d"
|
||||
% (
|
||||
len(test_files),
|
||||
len(files_to_test),
|
||||
len(files_not_to_test),
|
||||
len(error_files),
|
||||
)
|
||||
)
|
||||
import time
|
||||
|
||||
time.sleep(5)
|
||||
return files_to_test, files_not_to_test, error_files
|
||||
@@ -1,173 +0,0 @@
|
||||
"""
|
||||
Courtesy https://github.com/ccpgames/jsonschema-errorprinter with minor
|
||||
updates to support Python 3 (changed cStringIO to io), to print out
|
||||
multiple errors, the ability to place default values, and a few
|
||||
other small changes.
|
||||
|
||||
Licensed under the MIT License, reproduced below:
|
||||
Copyright © 2015 CCP hf.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
THERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
||||
OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
"""
|
||||
|
||||
"""
|
||||
Json Schema Validation Error Pretty-printer.
|
||||
---------------------------------------------------
|
||||
|
||||
Makes a user friendly error message from a ValidationError.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
|
||||
import io
|
||||
import json
|
||||
import jsonschema
|
||||
import jsonschema.validators
|
||||
|
||||
# The 'default' field is really just for documentation in the
|
||||
# json schema. We would like to use it to actually fill in
|
||||
# values when they aren't supplied. This code is provided
|
||||
# by the jsonschema project itself because this behavior
|
||||
# is not part of the default jsonschema definition
|
||||
# https://python-jsonschema.readthedocs.io/en/latest/faq/
|
||||
def extend_with_default(validator_class):
|
||||
validate_properties = validator_class.VALIDATORS["properties"]
|
||||
|
||||
def set_defaults(validator, properties, instance, schema):
|
||||
for property, subschema in properties.items():
|
||||
if "default" in subschema:
|
||||
instance.setdefault(property, subschema["default"])
|
||||
|
||||
for error in validate_properties(
|
||||
validator, properties, instance, schema,
|
||||
):
|
||||
yield error
|
||||
|
||||
return jsonschema.validators.extend(
|
||||
validator_class, {"properties": set_defaults},
|
||||
)
|
||||
|
||||
|
||||
def check_json(json_object, schema, context=None) -> tuple[list[str], dict]:
|
||||
try:
|
||||
DefaultValidatingDraft7Validator = extend_with_default(
|
||||
jsonschema.Draft7Validator)
|
||||
|
||||
|
||||
validator = DefaultValidatingDraft7Validator(schema, jsonschema.FormatChecker())
|
||||
#validator = jsonschema.Draft7Validator(schema, jsonschema.FormatChecker())
|
||||
errors_formatted = []
|
||||
|
||||
for error in sorted(validator.iter_errors(json_object), key=str):
|
||||
|
||||
#validate(json_object, schema, format_checker=FormatChecker())
|
||||
# except jsonschema.ValidationError as e:
|
||||
report = generate_validation_error_report(error, json_object)
|
||||
|
||||
#note = "\n*** Note - If there is more than one error, only the first error is shown ***\n\n"
|
||||
if context:
|
||||
errors_formatted.append(
|
||||
"Schema check failed for '{}'\n{}".format(context, report))
|
||||
# return note + "Schema check failed for '{}'\n{}".format(context, report)
|
||||
else:
|
||||
errors_formatted.append(
|
||||
"Schema check failed.\n{}".format(report))
|
||||
# return note + "Schema check failed.\n{}".format(report)
|
||||
if len(errors_formatted) == 0:
|
||||
#DefaultValidatingDraft7Validator = extend_with_default(
|
||||
# jsonschema.Draft7Validator)
|
||||
#DefaultValidatingDraft7Validator(schema).validate(json_object)
|
||||
return (errors_formatted, json_object)
|
||||
else:
|
||||
return (errors_formatted, {})
|
||||
except Exception as e:
|
||||
# Some error occurred, probably related to the schema itself
|
||||
raise(Exception("Error validating the JSON Schema: %s" % (str(e))))
|
||||
|
||||
|
||||
def generate_validation_error_report(
|
||||
e,
|
||||
json_object,
|
||||
lines_before=7,
|
||||
lines_after=7
|
||||
):
|
||||
"""
|
||||
Generate a detailed report of a schema validation error.
|
||||
|
||||
'e' is a jsonschema.ValidationError exception that errored on
|
||||
'json_object'.
|
||||
|
||||
Steps to discover the location of the validation error:
|
||||
1. Traverse the json object using the 'path' in the validation exception
|
||||
and replace the offending value with a special marker.
|
||||
2. Pretty-print the json object indendented json text.
|
||||
3. Search for the special marker in the json text to find the actual
|
||||
line number of the error.
|
||||
4. Make a report by showing the error line with a context of
|
||||
'lines_before' and 'lines_after' number of lines on each side.
|
||||
"""
|
||||
|
||||
if json_object is None:
|
||||
return "'json_object' cannot be None."
|
||||
if not e.path:
|
||||
return str(e)
|
||||
marker = "3fb539deef7c4e2991f265c0a982f5ea"
|
||||
|
||||
# Find the object that is erroring, and replace it with the marker.
|
||||
ob_tmp = json_object
|
||||
for entry in list(e.path)[:-1]:
|
||||
ob_tmp = ob_tmp[entry]
|
||||
|
||||
orig, ob_tmp[e.path[-1]] = ob_tmp[e.path[-1]], marker
|
||||
|
||||
# Pretty print the object and search for the marker.
|
||||
json_error = json.dumps(json_object, indent=4)
|
||||
string_io_instance = io.StringIO(json_error)
|
||||
errline = None
|
||||
|
||||
for lineno, text in enumerate(string_io_instance):
|
||||
if marker in text:
|
||||
errline = lineno
|
||||
break
|
||||
|
||||
if errline is not None:
|
||||
# Re-create report.
|
||||
report = []
|
||||
ob_tmp[e.path[-1]] = orig
|
||||
json_error = json.dumps(json_object, indent=4)
|
||||
string_io_instance = io.StringIO(json_error)
|
||||
|
||||
for lineno, text in enumerate(string_io_instance):
|
||||
if lineno == errline:
|
||||
line_text = "{:4}: >>>".format(lineno+1)
|
||||
else:
|
||||
line_text = "{:4}: ".format(lineno+1)
|
||||
report.append(line_text + text.rstrip("\n"))
|
||||
|
||||
report = report[max(0, errline-lines_before):errline+1+lines_after]
|
||||
|
||||
s = "Error in line {}:\n".format(errline+1)
|
||||
s += "\n".join(report)
|
||||
s += '\n\tREASON:' + str(e).split('\n')[0]
|
||||
#s += "\n\n" + str(e).replace("u'", "'")
|
||||
else:
|
||||
s = str(e)
|
||||
return s
|
||||
@@ -1,234 +0,0 @@
|
||||
import argparse
|
||||
import json
|
||||
from typing import OrderedDict, Union
|
||||
from modules import validate_args
|
||||
import sys
|
||||
|
||||
DEFAULT_CONFIG_FILE = "test_config.json"
|
||||
|
||||
|
||||
def configure_action(args) -> tuple[str, dict]:
|
||||
settings = OrderedDict()
|
||||
if args.input_config_file is None:
|
||||
settings, schema = validate_args.validate({})
|
||||
else:
|
||||
settings, schema = validate_args.validate_file(args.input_config_file)
|
||||
|
||||
if settings is None:
|
||||
print("Failure while processing settings\n\tQuitting...", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
new_config = {}
|
||||
for arg in settings:
|
||||
default = settings[arg]
|
||||
default_string = str(default).replace("'", '"')
|
||||
|
||||
if 'enum' in schema['properties'][arg]:
|
||||
choice = input("%s [default: %s | choices: {%s}]: " % (
|
||||
arg, default_string, ','.join(schema['properties'][arg]['enum'])))
|
||||
else:
|
||||
choice = input("%s [default: %s]: " % (arg, default_string))
|
||||
choice = choice.strip()
|
||||
if len(choice) == 0:
|
||||
print("\tNothing entered, using default:")
|
||||
new_config[arg] = default
|
||||
formatted_print = default
|
||||
else:
|
||||
if choice.lower() in ["true", "false"] and schema['properties'][arg]['type'] == "boolean":
|
||||
new_config[arg] = json.loads(choice.lower())
|
||||
formatted_print = choice.lower()
|
||||
else:
|
||||
|
||||
if choice in ['true', 'false'] or (choice.isdigit() and schema['properties'][arg]['type'] != "integer"):
|
||||
choice = '"' + choice + '"'
|
||||
# replace all single quotes with doubles quotes to make valid json
|
||||
elif "'" in choice:
|
||||
print('''Found %d single quotes (') in input... we will convert these to double quotes (") to ensure valida json.''' % (
|
||||
choice.count("'")))
|
||||
choice = choice.replace("'", '"')
|
||||
elif '"' in choice:
|
||||
# Do nothing
|
||||
pass
|
||||
elif choice.isdigit():
|
||||
pass
|
||||
else:
|
||||
choice = '"' + choice + '"'
|
||||
|
||||
new_config[arg] = json.loads(choice)
|
||||
formatted_print = choice
|
||||
# We print out choice instead of new_config[arg] because the json.loads() messes up the quotation marks again
|
||||
print("\t{0}\n".format(formatted_print))
|
||||
|
||||
# Now parse the new config and make sure it's good
|
||||
validated_new_settings, schema = validate_args.validate_and_write(
|
||||
new_config, args.output_config_file, skip_password_accessibility_check=False)
|
||||
if validated_new_settings == None:
|
||||
print("Could not update settings.\n\tQuitting...", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
return ("configure", validated_new_settings)
|
||||
|
||||
|
||||
def update_config_with_cli_arguments(args_dict: dict) -> tuple[str, dict]:
|
||||
# First load the config file
|
||||
|
||||
settings, _ = validate_args.validate_file(args_dict['config_file'])
|
||||
if settings is None:
|
||||
print("Failure while processing settings in [%s].\n\tQuitting..." % (
|
||||
args_dict['config_file'].name), file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
# Then update it with the values that were passed as command line arguments
|
||||
for key, value in args_dict.items():
|
||||
if key in settings:
|
||||
settings[key] = value
|
||||
|
||||
# Validate again to make sure we didn't break anything
|
||||
settings, _ = validate_args.validate(settings,skip_password_accessibility_check=False)
|
||||
if settings is None:
|
||||
print("Failure while processing updated settings from command line.\n\tQuitting...", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
return ("run", settings)
|
||||
|
||||
|
||||
def run_action(args) -> tuple[str, dict]:
|
||||
|
||||
config = update_config_with_cli_arguments(args.__dict__)
|
||||
|
||||
return config
|
||||
|
||||
|
||||
def parse(args) -> tuple[str, dict]:
|
||||
'''
|
||||
try:
|
||||
with open(DEFAULT_CONFIG_FILE, 'r') as settings_file:
|
||||
default_settings = json.load(settings_file)
|
||||
except Exception as e:
|
||||
print("Error loading settings file %s: %s"%(DEFAULT_CONFIG_FILE, str(e)), file=sys.stderr)
|
||||
sys.exit(1)
|
||||
'''
|
||||
|
||||
import os
|
||||
# if there is no default config file, then generate one
|
||||
if not os.path.exists(DEFAULT_CONFIG_FILE):
|
||||
print("No default configuration file [%s] found. Creating one..." % (
|
||||
DEFAULT_CONFIG_FILE))
|
||||
with open(DEFAULT_CONFIG_FILE, 'w') as cfg:
|
||||
validate_args.validate_and_write({}, cfg, skip_password_accessibility_check=True)
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Use 'SOME_PROGRAM_NAME_STRING --help' to get help with the arguments")
|
||||
parser.set_defaults(func=lambda _: parser.print_help())
|
||||
|
||||
actions_parser = parser.add_subparsers(title="Action")
|
||||
|
||||
# Configure parser
|
||||
configure_parser = actions_parser.add_parser(
|
||||
"configure", help="Configure a test run")
|
||||
configure_parser.set_defaults(func=configure_action)
|
||||
configure_parser.add_argument('-i', '--input_config_file', required=False,
|
||||
type=argparse.FileType('r'), help="The config file to base the configuration off of.")
|
||||
configure_parser.add_argument('-o', '--output_config_file', required=False, default=DEFAULT_CONFIG_FILE,
|
||||
type=argparse.FileType('w'), help="The config file to write the configuration off of.")
|
||||
|
||||
# Run parser
|
||||
run_parser = actions_parser.add_parser(
|
||||
"run", help="Run a test")
|
||||
run_parser.set_defaults(func=run_action)
|
||||
run_parser.add_argument('-c', '--config_file', required=False,
|
||||
type=argparse.FileType('r'),
|
||||
default=DEFAULT_CONFIG_FILE,
|
||||
help="The config file for the test. Note that this file "
|
||||
"cannot be changed (except for credentials that can be "
|
||||
"entered on the command line).")
|
||||
|
||||
run_parser.add_argument('-user', '--splunkbase_username', required=False, type=str,
|
||||
help="Username for login to splunkbase. This is required "
|
||||
"if downloading packages from Splunkbase. While this can "
|
||||
"be stored in the config file, it is strongly recommended "
|
||||
"to enter it at runtime.")
|
||||
|
||||
run_parser.add_argument('-b', '--branch', required=False, type=str,
|
||||
help="The branch to run the tests on.")
|
||||
|
||||
run_parser.add_argument('-hash', '--commit_hash', required=False, type=str,
|
||||
help="The hash to run the tests on.")
|
||||
|
||||
run_parser.add_argument('-pr', '--pr_number', required=False, type=int,
|
||||
help="The Pull request to run the tests on.")
|
||||
|
||||
run_parser.add_argument('-m', '--mode', required=False, type=str,
|
||||
help="The mode all, changes, or selected for the testing.")
|
||||
|
||||
run_parser.add_argument('-pass', '--splunkbase_password', required=False, type=str,
|
||||
help="Password for login to splunkbase. This is required if "
|
||||
"downloading packages from Splunkbase. While this can be "
|
||||
"stored in the config file, it is strongly recommended "
|
||||
"to enter it at runtime.")
|
||||
|
||||
run_parser.add_argument('-splunkpass', '--splunk_app_password', required=False, type=str,
|
||||
help="Password for login to the splunk app. If you don't "
|
||||
"provide one here or in the config, it will be generated "
|
||||
"automatically for you.")
|
||||
|
||||
run_parser.add_argument("-show_pass", "--show_splunk_app_password", required=False,
|
||||
action="store_true",
|
||||
help="The password to login to the Splunk Server. If the config "
|
||||
"file is set to true, it will override the default False for this. True "
|
||||
"will override the default value in the config file.")
|
||||
|
||||
run_parser.add_argument("-mock", "--mock", required=False,
|
||||
action="store_true",
|
||||
help="Split into multiple configs, don't actually run the tests. If the config "
|
||||
"file is set to true, it will override the default False for this. True "
|
||||
"will override the default value in the config file.")
|
||||
|
||||
run_parser.add_argument("-n", "--num_containers", required=False, type=int,
|
||||
help="The number of Splunk containers to run or mock")
|
||||
|
||||
run_parser.add_argument("-nif", "--no_interactive_failure", required=False,
|
||||
action="store_true",
|
||||
help="After a detection fails, pause and allow the user to log into "\
|
||||
"the Splunk server to interactively debug the failure. Wait for the user "\
|
||||
"to hit enter before removing the test data and moving on to the next test.")
|
||||
|
||||
run_parser.add_argument("-i", "--interactive", required=False,
|
||||
action="store_true",
|
||||
help="After a detection runs, pause and allow the user to log into "\
|
||||
"the Splunk server to debug the detection. Wait for the user "\
|
||||
"to hit enter before removing the test data and moving on to the next test.")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
|
||||
# Run the appropriate parser
|
||||
try:
|
||||
# If one of these arguments is not passed on the command line, don't overwrite its config
|
||||
# file value with None - keep the config file value
|
||||
keys = list(args.__dict__.keys())
|
||||
for key in keys:
|
||||
|
||||
# We have to do the check separately because booleans using the --store_true
|
||||
# action have an implict default=False value, even if we don't set it. We cannot
|
||||
# set their value to something else, like None
|
||||
|
||||
# Don't overwite booleans
|
||||
if args.__dict__[key] is False and key in ["show_splunk_app_password", "mock", "no_interactive_failure", "interactive"]:
|
||||
del args.__dict__[key]
|
||||
# Don't overwrite other values
|
||||
elif args.__dict__[key] is None and key in ["splunkbase_username", "branch", "commit_hash",
|
||||
"pr_number", "mode", "splunkbase_password",
|
||||
"num_containers"]:
|
||||
del args.__dict__[key]
|
||||
|
||||
action, settings = args.func(args)
|
||||
|
||||
|
||||
return action, settings
|
||||
except Exception as e:
|
||||
print("Unknown Error Validating Json Configuration - [%s]" % (str(e)))
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
parse(sys.argv[1:])
|
||||
@@ -1,507 +0,0 @@
|
||||
from collections import OrderedDict
|
||||
import datetime
|
||||
import docker
|
||||
import docker.types
|
||||
import docker.models
|
||||
import docker.models.resource
|
||||
import docker.models.containers
|
||||
import os.path
|
||||
import random
|
||||
import requests
|
||||
import shutil
|
||||
from modules import splunk_sdk
|
||||
from modules import testing_service
|
||||
from modules import test_driver
|
||||
import time
|
||||
import timeit
|
||||
from typing import Union
|
||||
import threading
|
||||
import wrapt_timeout_decorator
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
SPLUNKBASE_URL = "https://splunkbase.splunk.com/app/%d/release/%s/download"
|
||||
SPLUNK_START_ARGS = "--accept-license"
|
||||
|
||||
# Give ten minutes to start - this is probably enough time
|
||||
MAX_CONTAINER_START_TIME_SECONDS = 60 * 20
|
||||
|
||||
|
||||
class SplunkContainer:
|
||||
def __init__(
|
||||
self,
|
||||
synchronization_object: test_driver.TestDriver,
|
||||
full_docker_hub_path,
|
||||
container_name: str,
|
||||
apps: OrderedDict,
|
||||
web_port_tuple: tuple[str, int],
|
||||
management_port_tuple: tuple[str, int],
|
||||
container_password: str,
|
||||
files_to_copy_to_container: OrderedDict = OrderedDict(),
|
||||
mounts: list[docker.types.Mount] = [],
|
||||
splunkbase_username: Union[str, None] = None,
|
||||
splunkbase_password: Union[str, None] = None,
|
||||
splunk_ip: str = "127.0.0.1",
|
||||
interactive_failure: bool = False,
|
||||
interactive: bool = False,
|
||||
):
|
||||
self.interactive_failure = interactive_failure
|
||||
self.interactive = interactive
|
||||
self.synchronization_object = synchronization_object
|
||||
self.client = docker.client.from_env()
|
||||
self.full_docker_hub_path = full_docker_hub_path
|
||||
self.container_password = container_password
|
||||
|
||||
self.apps = apps
|
||||
|
||||
self.files_to_copy_to_container = files_to_copy_to_container
|
||||
self.splunk_ip = splunk_ip
|
||||
self.container_name = container_name
|
||||
self.mounts = mounts
|
||||
self.environment = self.make_environment(
|
||||
apps, container_password, splunkbase_username, splunkbase_password
|
||||
)
|
||||
self.ports = self.make_ports(web_port_tuple, management_port_tuple)
|
||||
self.web_port = web_port_tuple[1]
|
||||
self.management_port = management_port_tuple[1]
|
||||
self.container = self.make_container()
|
||||
|
||||
self.thread = threading.Thread(
|
||||
target=self.run_container,
|
||||
)
|
||||
|
||||
self.container_start_time = -1
|
||||
self.test_start_time = -1
|
||||
self.num_tests_completed = 0
|
||||
|
||||
def prepare_apps_path(
|
||||
self,
|
||||
apps: OrderedDict,
|
||||
splunkbase_username: Union[str, None] = None,
|
||||
splunkbase_password: Union[str, None] = None,
|
||||
) -> tuple[str, bool]:
|
||||
apps_to_install = []
|
||||
|
||||
# We don't require credentials unless we install at least one splunkbase app
|
||||
require_credentials = False
|
||||
|
||||
# If the username and password are supplied, then we will use splunkbase...
|
||||
# assuming that the app_name and app_number are supplied. Note that if a
|
||||
# local_path is supplied, then it should override this option!
|
||||
if splunkbase_username is not None and splunkbase_password is not None:
|
||||
use_splunkbase = True
|
||||
else:
|
||||
use_splunkbase = False
|
||||
|
||||
for app_name, app_info in self.apps.items():
|
||||
if use_splunkbase is True and "local_path" not in app_info:
|
||||
target = SPLUNKBASE_URL % (
|
||||
app_info["app_number"],
|
||||
app_info["app_version"],
|
||||
)
|
||||
apps_to_install.append(target)
|
||||
# We will require credentials since we are installing at least one splunkbase app
|
||||
require_credentials = True
|
||||
# Some paths may have a local_path and an HTTP path defined. Default to the local_path first,
|
||||
# mostly because we may have copied it before into the cache to speed up start time.
|
||||
elif "local_path" in app_info:
|
||||
app_file_name = os.path.basename(app_info["local_path"])
|
||||
app_file_container_path = os.path.join("/tmp/apps", app_file_name)
|
||||
apps_to_install.append(app_file_container_path)
|
||||
elif "http_path" in app_info:
|
||||
apps_to_install.append(app_info["http_path"])
|
||||
|
||||
else:
|
||||
if use_splunkbase is True:
|
||||
print(
|
||||
"Error, the app %s: %s could not be installed from Splunkbase because "
|
||||
"--splunkbase_username and.or --splunkbase_password were not provided."
|
||||
"\n\tQuitting..." % (app_name, app_info),
|
||||
file=sys.stderr,
|
||||
)
|
||||
else:
|
||||
print(
|
||||
"Error, the app %s: %s has no http_path or local_path.\n\tQuitting..."
|
||||
% (app_name, app_info),
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
return ",".join(apps_to_install), require_credentials
|
||||
|
||||
def make_environment(
|
||||
self,
|
||||
apps: OrderedDict,
|
||||
container_password: str,
|
||||
splunkbase_username: Union[str, None] = None,
|
||||
splunkbase_password: Union[str, None] = None,
|
||||
) -> dict:
|
||||
env = {}
|
||||
env["SPLUNK_START_ARGS"] = SPLUNK_START_ARGS
|
||||
env["SPLUNK_PASSWORD"] = container_password
|
||||
splunk_apps_url, require_credentials = self.prepare_apps_path(
|
||||
apps, splunkbase_username, splunkbase_password
|
||||
)
|
||||
|
||||
if require_credentials:
|
||||
env["SPLUNKBASE_USERNAME"] = splunkbase_username
|
||||
env["SPLUNKBASE_PASSWORD"] = splunkbase_password
|
||||
env["SPLUNK_APPS_URL"] = splunk_apps_url
|
||||
|
||||
return env
|
||||
|
||||
def make_ports(self, *ports: tuple[str, int]) -> dict[str, int]:
|
||||
port_dict = {}
|
||||
for port in ports:
|
||||
port_dict[port[0]] = port[1]
|
||||
return port_dict
|
||||
|
||||
def __str__(self) -> str:
|
||||
container_string = (
|
||||
"Container Name: %s\n\t"
|
||||
"Docker Hub Path: %s\n\t"
|
||||
"Apps: %s\n\t"
|
||||
"Ports: %s\n\t"
|
||||
"Mounts: %s\n\t"
|
||||
% (
|
||||
self.container_name,
|
||||
self.full_docker_hub_path,
|
||||
self.environment["SPLUNK_APPS_URL"],
|
||||
self.ports,
|
||||
)
|
||||
)
|
||||
|
||||
return container_string
|
||||
|
||||
def make_container(self) -> docker.models.resource.Model:
|
||||
# First, make sure that the container has been removed if it already existed
|
||||
self.removeContainer()
|
||||
|
||||
container = self.client.containers.create(
|
||||
self.full_docker_hub_path,
|
||||
ports=self.ports,
|
||||
environment=self.environment,
|
||||
name=self.container_name,
|
||||
mounts=self.mounts,
|
||||
detach=True,
|
||||
platform="linux/amd64"
|
||||
)
|
||||
|
||||
return container
|
||||
|
||||
def extract_tar_file_to_container(
|
||||
self, local_file_path: str, container_file_path: str, sleepTimeSeconds: int = 5
|
||||
) -> bool:
|
||||
# Check to make sure that the file ends in .tar. If it doesn't raise an exception
|
||||
if os.path.splitext(local_file_path)[1] != ".tar":
|
||||
raise Exception(
|
||||
"Error - Failed copy of file [%s] to container [%s]. Only "
|
||||
"files ending in .tar can be copied to the container using this function."
|
||||
% (local_file_path, self.container_name)
|
||||
)
|
||||
successful_copy = False
|
||||
api_client = docker.APIClient()
|
||||
# need to use the low level client to put a file onto a container
|
||||
while not successful_copy:
|
||||
try:
|
||||
with open(local_file_path, "rb") as fileData:
|
||||
# splunk will restart a few times will installation of apps takes place so it will reload its indexes...
|
||||
|
||||
api_client.put_archive(
|
||||
container=self.container_name,
|
||||
path=container_file_path,
|
||||
data=fileData,
|
||||
)
|
||||
successful_copy = True
|
||||
except Exception as e:
|
||||
# print("Failed copy of [%s] file to [%s] on CONTAINER [%s]: [%s]\n...we will try again"%(local_file_path, container_file_path, self.container_name, str(e)))
|
||||
time.sleep(10)
|
||||
successful_copy = False
|
||||
# print("Successfully copied [%s] to [%s] on [%s]"% (local_file_path, container_file_path, self.container_name))
|
||||
return successful_copy
|
||||
|
||||
def stopContainer(self, timeout=10) -> bool:
|
||||
try:
|
||||
container = self.client.containers.get(self.container_name)
|
||||
# Note that stopping does not remove any of the volumes or logs,
|
||||
# so stopping can be useful if we want to debug any container failure
|
||||
container.stop(timeout=10)
|
||||
self.synchronization_object.containerFailure()
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
# Container does not exist, or we could not get it. Throw and error
|
||||
print("Error stopping docker container [%s]" % (self.container_name))
|
||||
return False
|
||||
|
||||
def removeContainer(
|
||||
self, removeVolumes: bool = True, forceRemove: bool = True
|
||||
) -> bool:
|
||||
try:
|
||||
container = self.client.containers.get(self.container_name)
|
||||
except Exception as e:
|
||||
# Container does not exist, no need to try and remove it
|
||||
return True
|
||||
try:
|
||||
# container was found, so now we try to remove it
|
||||
# v also removes volumes linked to the container
|
||||
container.remove(
|
||||
v=removeVolumes, force=forceRemove
|
||||
) # remove it even if it is running. remove volumes as well
|
||||
# No need to print that the container has been removed, it is expected behavior
|
||||
return True
|
||||
except Exception as e:
|
||||
print("Could not remove Docker Container [%s]" % (self.container_name))
|
||||
raise (Exception(f"CONTAINER REMOVE ERROR: {str(e)}"))
|
||||
|
||||
def get_container_summary(self) -> str:
|
||||
current_time = timeit.default_timer()
|
||||
|
||||
# Total time the container has been running
|
||||
if self.container_start_time == -1:
|
||||
total_time_string = "NOT STARTED"
|
||||
else:
|
||||
total_time_rounded = datetime.timedelta(
|
||||
seconds=round(current_time - self.container_start_time)
|
||||
)
|
||||
total_time_string = str(total_time_rounded)
|
||||
|
||||
# Time that the container setup took
|
||||
if self.test_start_time == -1 or self.container_start_time == -1:
|
||||
setup_time_string = "NOT SET UP"
|
||||
else:
|
||||
setup_secounds_rounded = datetime.timedelta(
|
||||
seconds=round(self.test_start_time - self.container_start_time)
|
||||
)
|
||||
setup_time_string = str(setup_secounds_rounded)
|
||||
|
||||
# Time that the tests have been running
|
||||
if self.test_start_time == -1 or self.num_tests_completed == 0:
|
||||
testing_time_string = "NO TESTS COMPLETED"
|
||||
else:
|
||||
testing_seconds_rounded = datetime.timedelta(
|
||||
seconds=round(current_time - self.test_start_time)
|
||||
)
|
||||
|
||||
# Get the approximate time per test. This is a clunky way to get rid of decimal
|
||||
# seconds.... but it works
|
||||
timedelta_per_test = testing_seconds_rounded / self.num_tests_completed
|
||||
timedelta_per_test_rounded = timedelta_per_test - datetime.timedelta(
|
||||
microseconds=timedelta_per_test.microseconds
|
||||
)
|
||||
|
||||
testing_time_string = "%s (%d tests @ %s per test)" % (
|
||||
testing_seconds_rounded,
|
||||
self.num_tests_completed,
|
||||
timedelta_per_test_rounded,
|
||||
)
|
||||
|
||||
summary_str = (
|
||||
"Summary for %s\n\t"
|
||||
"Total Time : [%s]\n\t"
|
||||
"Container Start Time: [%s]\n\t"
|
||||
"Test Execution Time : [%s]\n"
|
||||
% (
|
||||
self.container_name,
|
||||
total_time_string,
|
||||
setup_time_string,
|
||||
testing_time_string,
|
||||
)
|
||||
)
|
||||
|
||||
return summary_str
|
||||
|
||||
def wait_for_splunk_ready(
|
||||
self,
|
||||
seconds_between_attempts: int = 10,
|
||||
) -> bool:
|
||||
# The smarter version of this will try to hit one of the pages,
|
||||
# probably the login page, and when that is available it means that
|
||||
# splunk is fully started and ready to go. Until then, we just
|
||||
# use a simple sleep
|
||||
|
||||
while True:
|
||||
try:
|
||||
service = splunk_sdk.client.connect(
|
||||
host=self.splunk_ip,
|
||||
port=self.management_port,
|
||||
username="admin",
|
||||
password=self.container_password,
|
||||
)
|
||||
if service.restart_required:
|
||||
# The sleep below will wait
|
||||
pass
|
||||
else:
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
# There is a good chance the server is restarting, so the SDK connection failed.
|
||||
# Or, we tried to check restart_required while the server was restarting. In the
|
||||
# calling function, we have a timeout, so it's okay if this function could get
|
||||
# stuck in an infinite loop (the caller will generate a timeout error)
|
||||
pass
|
||||
|
||||
time.sleep(seconds_between_attempts)
|
||||
|
||||
# @wrapt_timeout_decorator.timeout(MAX_CONTAINER_START_TIME_SECONDS, timeout_exception=RuntimeError)
|
||||
def setup_container(self):
|
||||
self.container.start()
|
||||
|
||||
# def shutdown_signal_handler(sig, frame):
|
||||
# shutdown_client = docker.client.from_env()
|
||||
# errorCount = 0
|
||||
|
||||
# print(f"Shutting down {self.container_name}...", file=sys.stderr)
|
||||
# try:
|
||||
# container = shutdown_client.containers.get(self.container_name)
|
||||
# #Note that stopping does not remove any of the volumes or logs,
|
||||
# #so stopping can be useful if we want to debug any container failure
|
||||
# container.stop(timeout=10)
|
||||
# print(f"{self.container_name} shut down successfully", file=sys.stderr)
|
||||
# except Exception as e:
|
||||
# print(f"Error trying to shut down {self.container_name}. It may have already shut down. Stop it youself with 'docker containter stop {self.container_name}", sys.stderr)
|
||||
|
||||
# #We must use os._exit(1) because sys.exit(1) actually generates an exception which can be caught! And then we don't Quit!
|
||||
# import os
|
||||
# os._exit(1)
|
||||
|
||||
# import signal
|
||||
# signal.signal(signal.SIGINT, shutdown_signal_handler)
|
||||
|
||||
# By default, first copy the index file then the datamodel file
|
||||
for file_description, file_dict in self.files_to_copy_to_container.items():
|
||||
self.extract_tar_file_to_container(
|
||||
file_dict["local_file_path"], file_dict["container_file_path"]
|
||||
)
|
||||
|
||||
print("Finished copying files to [%s]" % (self.container_name))
|
||||
self.wait_for_splunk_ready()
|
||||
|
||||
def successfully_finish_tests(self) -> None:
|
||||
try:
|
||||
if self.num_tests_completed == 0:
|
||||
print(
|
||||
"Container [%s] did not find any tests and will not start.\n"
|
||||
"This does not mean there was an error!" % (self.container_name)
|
||||
)
|
||||
else:
|
||||
print(
|
||||
"Container [%s] has finished running [%d] detections, time to stop the container."
|
||||
% (self.container_name, self.num_tests_completed)
|
||||
)
|
||||
|
||||
# remove the container
|
||||
self.removeContainer()
|
||||
except Exception as e:
|
||||
print("Error stopping or removing the container: [%s]" % (str(e)))
|
||||
|
||||
return None
|
||||
|
||||
def run_container(self) -> None:
|
||||
print("Starting the container [%s]" % (self.container_name))
|
||||
|
||||
# Try to get something from the queue. Check this early on
|
||||
# before launching the container because it can save us a lot of time!
|
||||
detection_to_test = self.synchronization_object.getTest()
|
||||
if detection_to_test is None:
|
||||
return self.successfully_finish_tests()
|
||||
|
||||
self.container_start_time = timeit.default_timer()
|
||||
|
||||
container_start_time = timeit.default_timer()
|
||||
|
||||
try:
|
||||
self.setup_container()
|
||||
except Exception as e:
|
||||
print(
|
||||
"There was an exception starting the container [%s]: [%s]. Shutting down container"
|
||||
% (self.container_name, str(e)),
|
||||
file=sys.stdout,
|
||||
)
|
||||
self.stopContainer()
|
||||
elapsed_rounded = round(timeit.default_timer() - container_start_time)
|
||||
time_string = datetime.timedelta(seconds=elapsed_rounded)
|
||||
print("Container [%s] FAILED in [%s]" % (self.container_name, time_string))
|
||||
return None
|
||||
|
||||
# GTive some info about how long the container took to start up
|
||||
elapsed_rounded = round(timeit.default_timer() - container_start_time)
|
||||
time_string = datetime.timedelta(seconds=elapsed_rounded)
|
||||
print("Container [%s] took [%s] to start" % (self.container_name, time_string))
|
||||
self.synchronization_object.start_barrier.wait()
|
||||
|
||||
# Sleep for a small random time so that containers drift apart and don't synchronize their testing
|
||||
time.sleep(random.randint(1, 30))
|
||||
self.test_start_time = timeit.default_timer()
|
||||
while detection_to_test is not None:
|
||||
if self.synchronization_object.checkContainerFailure():
|
||||
self.container.stop()
|
||||
print(
|
||||
"Container [%s] successfully stopped early due to failure"
|
||||
% (self.container_name)
|
||||
)
|
||||
return None
|
||||
|
||||
current_test_start_time = timeit.default_timer()
|
||||
# Sleep for a small random time so that containers drift apart and don't synchronize their testing
|
||||
# time.sleep(random.randint(1, 30))
|
||||
|
||||
# There is a detection to test
|
||||
|
||||
print("Container [%s]--->[%s]" % (self.container_name, detection_to_test))
|
||||
try:
|
||||
result = testing_service.test_detection_wrapper(
|
||||
self.container_name,
|
||||
self.splunk_ip,
|
||||
self.container_password,
|
||||
self.management_port,
|
||||
detection_to_test,
|
||||
self.synchronization_object.attack_data_root_folder,
|
||||
wait_on_failure=self.interactive_failure,
|
||||
wait_on_completion=self.interactive,
|
||||
smoketest=self.synchronization_object.summarization_reproduce_failure_config[
|
||||
"mode"
|
||||
]
|
||||
== "smoketest",
|
||||
)
|
||||
|
||||
self.synchronization_object.addResult(
|
||||
result,
|
||||
duration_string=str(
|
||||
datetime.timedelta(
|
||||
seconds=round(
|
||||
timeit.default_timer() - current_test_start_time
|
||||
)
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
# Remove the data from the test that we just ran. We MUST do this when running on CI because otherwise, we will download
|
||||
# a massive amount of data over the course of a long path and will run out of space on the relatively small CI runner drive
|
||||
shutil.rmtree(result["attack_data_directory"], ignore_errors=True)
|
||||
except Exception as e:
|
||||
import traceback
|
||||
|
||||
print(
|
||||
"Warning - uncaught error in detection test for [%s] - this should not happen: [%s]"
|
||||
% (detection_to_test, str(e))
|
||||
)
|
||||
print(traceback.print_exc())
|
||||
|
||||
self.synchronization_object.addError(
|
||||
{"detection_file": detection_to_test, "detection_error": str(e)},
|
||||
duration_string=str(
|
||||
datetime.timedelta(
|
||||
seconds=round(
|
||||
timeit.default_timer() - current_test_start_time
|
||||
)
|
||||
)
|
||||
),
|
||||
)
|
||||
self.num_tests_completed += 1
|
||||
|
||||
# Try to get something from the queue
|
||||
detection_to_test = self.synchronization_object.getTest()
|
||||
|
||||
# We failed to get a test from the queue, so we must be done gracefully! Quit
|
||||
return self.successfully_finish_tests()
|
||||
@@ -1,310 +0,0 @@
|
||||
from os import error
|
||||
import sys
|
||||
from time import sleep
|
||||
import splunklib.client as client
|
||||
import splunklib.results as results
|
||||
import requests
|
||||
import time
|
||||
import timeit
|
||||
import datetime
|
||||
from typing import Union
|
||||
|
||||
DEFAULT_EVENT_HOST = "ATTACK_DATA_HOST"
|
||||
DEFAULT_DATA_INDEX = "main"
|
||||
FAILURE_SLEEP_INTERVAL_SECONDS = 60
|
||||
|
||||
def enable_delete_for_admin(splunk_host:str, splunk_port:int, splunk_password:str)->bool:
|
||||
try:
|
||||
service = client.connect(
|
||||
host=splunk_host,
|
||||
port=splunk_port,
|
||||
username='admin',
|
||||
password=splunk_password
|
||||
)
|
||||
except Exception as e:
|
||||
raise(Exception("Unable to connect to Splunk instance: " + str(e)))
|
||||
|
||||
|
||||
#write the following contents to /opt/splunk/etc/system/local/authorize.conf
|
||||
"[role_admin]"\
|
||||
"delete_by_keyword = enabled"\
|
||||
"grantableRoles = admin"\
|
||||
"importRoles = can_delete;user;power_user"\
|
||||
"srchIndexesAllowed = *;_*;main"\
|
||||
"srchIndexesDefault = main"\
|
||||
"srchMaxTime = 8640000"
|
||||
|
||||
#Run the following search, equivalent to running ./splunk reload auth, to get the settings to take effect
|
||||
|
||||
update_changed_auth_search = "| rest splunk_server=* /services/authentication/providers/services/_reload"
|
||||
|
||||
|
||||
try:
|
||||
job = service.jobs.create(update_changed_auth_search)
|
||||
except Exception as e:
|
||||
error_message = "Unable to enable delete: %s"%(str(e))
|
||||
return False
|
||||
|
||||
input("Waiting for you to check that delete has been enabled with: %s"%(update_changed_auth_search))
|
||||
return True
|
||||
'''
|
||||
# search and replace \\ with \\\
|
||||
# search = search.replace('\\','\\\\')
|
||||
role = service.roles['admin']
|
||||
try:
|
||||
role.grant('delete_by_keyword')
|
||||
except Exception as e:
|
||||
print("Error - failed trying to grant 'can_delete' privs to admin: [%s]"%(str(e)))
|
||||
return False
|
||||
'''
|
||||
return True
|
||||
|
||||
|
||||
|
||||
|
||||
def get_number_of_indexed_events(splunk_host, splunk_port, splunk_password, index:str, event_host:str=DEFAULT_EVENT_HOST, sourcetype:Union[str,None]=None )->int:
|
||||
|
||||
try:
|
||||
service = client.connect(
|
||||
host=splunk_host,
|
||||
port=splunk_port,
|
||||
username='admin',
|
||||
password=splunk_password
|
||||
)
|
||||
except Exception as e:
|
||||
raise(Exception("Unable to connect to Splunk instance: " + str(e)))
|
||||
|
||||
if sourcetype is not None:
|
||||
search = f'''search index="{index}" sourcetype="{sourcetype}" host="{event_host}" | stats count'''
|
||||
else:
|
||||
search = f'''search index="{index}" host="{event_host}" | stats count'''
|
||||
kwargs = {"exec_mode":"blocking"}
|
||||
try:
|
||||
job = service.jobs.create(search, **kwargs)
|
||||
|
||||
#This returns the count in string form, not as an int. For example:
|
||||
#OrderedDict([('count', '59630')])
|
||||
results_stream = job.results(output_mode='json')
|
||||
count = None
|
||||
for res in results.JSONResultsReader(results_stream):
|
||||
if 'count' in res:
|
||||
count = int(res['count'],10)
|
||||
if count is None:
|
||||
raise Exception(f"Expected the get_number_of_indexed_events search to only return 1 count, but got {len(search_results)} instead.")
|
||||
|
||||
return count
|
||||
|
||||
except Exception as e:
|
||||
raise Exception("Error trying to get the count while waiting for indexing to complete: %s"%(str(e)))
|
||||
|
||||
|
||||
|
||||
|
||||
def wait_for_indexing_to_complete(splunk_host, splunk_port, splunk_password, sourcetype:str, index:str, check_interval_seconds:int=10)->bool:
|
||||
startTime = timeit.default_timer()
|
||||
previous_count = -1
|
||||
time.sleep(check_interval_seconds)
|
||||
while True:
|
||||
new_count = get_number_of_indexed_events(splunk_host, splunk_port, splunk_password, index=index, sourcetype=sourcetype)
|
||||
#print(f"Previous Count [{previous_count}] New Count [{new_count}]")
|
||||
if previous_count == -1:
|
||||
previous_count = new_count
|
||||
else:
|
||||
if new_count == previous_count:
|
||||
stopTime = timeit.default_timer()
|
||||
return True
|
||||
else:
|
||||
previous_count = new_count
|
||||
|
||||
#If new_count is really low, then the server is taking some extra time to index the data.
|
||||
# So sleep for longer to make sure that we give time to complete (or at least process more
|
||||
# events so we don't return from this function prematurely)
|
||||
if new_count < 2:
|
||||
time.sleep(check_interval_seconds*3)
|
||||
else:
|
||||
time.sleep(check_interval_seconds)
|
||||
|
||||
|
||||
def test_baseline_search(splunk_host, splunk_port, splunk_password, search, pass_condition, baseline_name, baseline_file, earliest_time, latest_time)->dict:
|
||||
try:
|
||||
service = client.connect(
|
||||
host=splunk_host,
|
||||
port=splunk_port,
|
||||
username='admin',
|
||||
password=splunk_password
|
||||
)
|
||||
except Exception as e:
|
||||
raise(Exception("Unable to connect to Splunk instance: " + str(e)))
|
||||
|
||||
|
||||
|
||||
# search and replace \\ with \\\
|
||||
# search = search.replace('\\','\\\\')
|
||||
|
||||
if search.startswith('|'):
|
||||
updated_search = search
|
||||
else:
|
||||
updated_search = 'search ' + search
|
||||
|
||||
kwargs = {"exec_mode": "blocking",
|
||||
"dispatch.earliest_time": earliest_time,
|
||||
"dispatch.latest_time": latest_time}
|
||||
|
||||
splunk_search = updated_search + ' ' + pass_condition
|
||||
|
||||
try:
|
||||
job = service.jobs.create(splunk_search, **kwargs)
|
||||
except Exception as e:
|
||||
raise(Exception("Unable to execute baseline: " + str(e)))
|
||||
|
||||
|
||||
test_results = dict()
|
||||
test_results['diskUsage'] = job['diskUsage']
|
||||
test_results['runDuration'] = job['runDuration']
|
||||
test_results['baseline_name'] = baseline_name
|
||||
test_results['baseline_file'] = baseline_file
|
||||
test_results['scanCount'] = job['scanCount']
|
||||
|
||||
if int(job['resultCount']) != 1:
|
||||
print("Test failed for baseline: " + baseline_name)
|
||||
test_results['error'] = True
|
||||
return test_results
|
||||
else:
|
||||
print("Test successful for baseline: " + baseline_name)
|
||||
test_results['error'] = False
|
||||
return test_results
|
||||
|
||||
|
||||
|
||||
def test_detection_search(splunk_host:str, splunk_port:int, splunk_password:str, search:str, pass_condition:str,
|
||||
detection_name:str, detection_file:str, earliest_time:str, latest_time:str, attempts_remaining:int=4,
|
||||
failure_sleep_interval_seconds:int=FAILURE_SLEEP_INTERVAL_SECONDS)->dict:
|
||||
#Since this is an attempt, decrement the number of remaining attempts
|
||||
attempts_remaining -= 1
|
||||
|
||||
if search.startswith('|'):
|
||||
updated_search = search
|
||||
else:
|
||||
updated_search = 'search ' + search
|
||||
|
||||
kwargs = {"exec_mode": "blocking",
|
||||
"dispatch.earliest_time": "-1d",
|
||||
"dispatch.latest_time": "now"}
|
||||
|
||||
splunk_search = updated_search + ' ' + pass_condition
|
||||
test_results = dict()
|
||||
|
||||
#These will always be present. By default, we will say that the
|
||||
#test has failed AND there was an error (until they are set otherwise)
|
||||
test_results['search_string'] = splunk_search
|
||||
test_results['detection_name'] = detection_name
|
||||
test_results['detection_file'] = detection_file
|
||||
|
||||
test_results['success'] = False
|
||||
test_results['error'] = True
|
||||
|
||||
|
||||
try:
|
||||
service = client.connect(
|
||||
host=splunk_host,
|
||||
port=splunk_port,
|
||||
|
||||
username='admin',
|
||||
password=splunk_password
|
||||
)
|
||||
except Exception as e:
|
||||
error_message = "Unable to connect to Splunk instance: %s"%(str(e))
|
||||
print(error_message,file=sys.stderr)
|
||||
test_results['error'] = True
|
||||
test_results['detection_error'] = error_message
|
||||
return test_results
|
||||
|
||||
|
||||
# search and replace \\ with \\\
|
||||
# search = search.replace('\\','\\\\')
|
||||
|
||||
|
||||
|
||||
#print("SEARCH: %s"%(splunk_search))
|
||||
|
||||
|
||||
try:
|
||||
job = service.jobs.create(splunk_search, **kwargs)
|
||||
results_stream = job.results(output_mode='json')
|
||||
|
||||
except Exception as e:
|
||||
|
||||
error_message = "Unable to execute detection: %s"%(str(e))
|
||||
print(error_message,file=sys.stderr)
|
||||
test_results['error'] = True
|
||||
test_results['detection_error'] = error_message
|
||||
return test_results
|
||||
|
||||
test_results['diskUsage'] = job['diskUsage']
|
||||
test_results['runDuration'] = job['runDuration']
|
||||
test_results['scanCount'] = job['scanCount']
|
||||
|
||||
#If we get this far, then there was not an error
|
||||
#The search may have FAILED, but there was no error in the search
|
||||
test_results['error'] = False
|
||||
|
||||
|
||||
#Should this be 1 for a pass, or should it be greater than 0?
|
||||
if int(job['resultCount']) != 1:
|
||||
#print("Test failed for detection: " + detection_name)
|
||||
if attempts_remaining > 0:
|
||||
print(f"Execution of test failed for [{detection_name}]. Sleeping for [{failure_sleep_interval_seconds} seconds] and trying up to {attempts_remaining} more times...")
|
||||
time.sleep(failure_sleep_interval_seconds)
|
||||
return test_detection_search(splunk_host, splunk_port, splunk_password, search, pass_condition, detection_name, detection_file,
|
||||
earliest_time, latest_time, attempts_remaining=attempts_remaining,
|
||||
failure_sleep_interval_seconds=failure_sleep_interval_seconds)
|
||||
else:
|
||||
test_results['success'] = False
|
||||
return test_results
|
||||
else:
|
||||
#print("Test successful for detection: " + detection_name)
|
||||
test_results['success'] = True
|
||||
return test_results
|
||||
|
||||
|
||||
def delete_attack_data(splunk_host:str, splunk_password:str, splunk_port:int, wait_on_delete:Union[dict,None], search_string:str, detection_filename:str, indices:list[str]=[DEFAULT_DATA_INDEX], host:str=DEFAULT_EVENT_HOST)->bool:
|
||||
|
||||
if wait_on_delete:
|
||||
print(wait_on_delete['message'])
|
||||
print("FILENAME : [%s]"%(detection_filename))
|
||||
print("SEARCH :\n%s"%(search_string))
|
||||
_ = input("****************Press ENTER to Complete Test and DELETE data****************\n\n\n")
|
||||
|
||||
try:
|
||||
service = client.connect(
|
||||
host=splunk_host,
|
||||
port=splunk_port,
|
||||
|
||||
username='admin',
|
||||
password=splunk_password
|
||||
)
|
||||
except Exception as e:
|
||||
|
||||
raise(Exception("Unable to connect to Splunk instance: " + str(e)))
|
||||
|
||||
|
||||
#print(f"Deleting data for {detection_filename}: {indices}")
|
||||
for index in indices:
|
||||
while (get_number_of_indexed_events(splunk_host, splunk_port, splunk_password, index=index, event_host=host) != 0) :
|
||||
splunk_search = f'search index="{index}" host="{host}" | delete'
|
||||
kwargs = {
|
||||
"exec_mode": "blocking",
|
||||
"dispatch.earliest_time": "-1d",
|
||||
"dispatch.latest_time": "now"}
|
||||
try:
|
||||
|
||||
job = service.jobs.create(splunk_search, **kwargs)
|
||||
results_stream = job.results(output_mode='json')
|
||||
reader = results.JSONResultsReader(results_stream)
|
||||
|
||||
|
||||
except Exception as e:
|
||||
raise(Exception(f"Trouble deleting data using the search {splunk_search}: {str(e)}"))
|
||||
|
||||
|
||||
return True
|
||||
@@ -1,357 +0,0 @@
|
||||
import copy
|
||||
import csv
|
||||
import datetime
|
||||
import json
|
||||
import os
|
||||
import queue
|
||||
import shutil
|
||||
import sys
|
||||
import tempfile
|
||||
import threading
|
||||
import time
|
||||
import timeit
|
||||
from collections import OrderedDict
|
||||
from typing import Union
|
||||
|
||||
import psutil
|
||||
import summarize_json
|
||||
|
||||
|
||||
class TestDriver:
|
||||
def __init__(self, tests:list[str], num_containers:int, summarization_reproduce_failure_config:dict):
|
||||
#Create the queue and enque all of the tests
|
||||
self.testing_queue = queue.Queue()
|
||||
for test in tests:
|
||||
self.testing_queue.put(test)
|
||||
|
||||
self.total_number_of_tests = self.testing_queue.qsize()
|
||||
#Creates a lock that will be used to synchronize access to this object
|
||||
self.lock = threading.Lock()
|
||||
self.start_time = timeit.default_timer()
|
||||
self.failures = []
|
||||
self.successes = []
|
||||
self.errors = []
|
||||
self.container_ready_time = None
|
||||
|
||||
#No containers have failed
|
||||
self.container_failure = False
|
||||
|
||||
#Just make a random folder to store attack data that we donwload
|
||||
self.attack_data_root_folder = tempfile.mkdtemp(prefix="attack_data_", dir=os.getcwd())
|
||||
print("Attack data for this run will be stored at: [%s]"%(self.attack_data_root_folder))
|
||||
|
||||
#Not used right now, but we will keep it around for a bit in case we want to use it again
|
||||
self.start_barrier = threading.Barrier(num_containers)
|
||||
|
||||
#The config that will be used for writing out the error config reproduction fiel
|
||||
self.summarization_reproduce_failure_config = copy.deepcopy(summarization_reproduce_failure_config)
|
||||
|
||||
|
||||
#According to the docs:
|
||||
# Warning the first time this function is called with interval = 0.0 or None it will return a meaningless 0.0 value which you are supposed to ignore.
|
||||
# We call this exactly once here to prime for future calls and throw away the result
|
||||
cpu_info = psutil.cpu_times_percent(percpu=False)
|
||||
|
||||
|
||||
def checkContainerFailure(self)->bool:
|
||||
|
||||
self.lock.acquire()
|
||||
|
||||
try:
|
||||
result = self.container_failure
|
||||
finally:
|
||||
self.lock.release()
|
||||
|
||||
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def containerFailure(self)->None:
|
||||
self.lock.acquire()
|
||||
try:
|
||||
self.container_failure = True
|
||||
finally:
|
||||
self.lock.release()
|
||||
|
||||
def checkIfTestsRemain(self):
|
||||
failure = self.checkContainerFailure()
|
||||
if failure:
|
||||
#Just return None, don't continue testing if a container crashed
|
||||
#Indicate there are no tests remaining
|
||||
return False
|
||||
|
||||
try:
|
||||
#This call isn't reliable according to documentation, but can save us some time.
|
||||
#Err on the side of caution
|
||||
return not self.testing_queue.empty()
|
||||
except Exception as e:
|
||||
print("Error determinging if testing queue was empty. Return False and try to get something.",file=sys.stderr)
|
||||
return True
|
||||
|
||||
|
||||
def getTest(self)-> Union[str,None]:
|
||||
|
||||
failure = self.checkContainerFailure()
|
||||
|
||||
|
||||
|
||||
if failure:
|
||||
#Just return None, don't continue testing if a container crashed
|
||||
return None
|
||||
|
||||
try:
|
||||
return self.testing_queue.get(block=False)
|
||||
except Exception as e:
|
||||
return None
|
||||
|
||||
def addSuccess(self, result:dict, duration_string:str)->None:
|
||||
print("Test PASSED: [%s --> %s] in %s"%(result['detection_name'], result['detection_file'], duration_string))
|
||||
self.lock.acquire()
|
||||
try:
|
||||
self.successes.append(result)
|
||||
finally:
|
||||
self.lock.release()
|
||||
|
||||
|
||||
def addFailure(self, result:dict, duration_string:str)->None:
|
||||
print("Test FAILED: [%s --> %s] in %s"%(result['detection_name'], result['detection_file'], duration_string))
|
||||
self.lock.acquire()
|
||||
try:
|
||||
self.failures.append(result)
|
||||
finally:
|
||||
self.lock.release()
|
||||
|
||||
def addError(self, result:dict, duration_string:str)->None:
|
||||
#Make sure that even errors have all of the required fields.
|
||||
for required_field in ['search_string', 'diskUsage','runDuration', 'detection_name', 'scanCount', 'detection_error', 'detection_file']:
|
||||
if required_field not in result:
|
||||
result[required_field] = ""
|
||||
if 'error' not in result:
|
||||
result['error'] = True
|
||||
if 'success' not in result:
|
||||
result['success'] = False
|
||||
print("Test ERROR: [%s --> %s] in %s"%(result['detection_name'], result['detection_file'], duration_string))
|
||||
self.lock.acquire()
|
||||
try:
|
||||
self.errors.append(result)
|
||||
finally:
|
||||
self.lock.release()
|
||||
|
||||
|
||||
def outputResultsCSV(self, field_names:list[str], output_filename:str, data:list[dict], baseline:OrderedDict)->bool:
|
||||
success = True
|
||||
|
||||
print("Generating %s..."%(output_filename), end='')
|
||||
self.lock.acquire()
|
||||
|
||||
try:
|
||||
with open(output_filename, 'w') as csvfile:
|
||||
header_writer = csv.writer(csvfile, quoting=csv.QUOTE_ALL)
|
||||
for key in baseline:
|
||||
#Very basic support for pretty pritning dicts. Doesn't handle more than 1 nested dict
|
||||
if type(baseline[key]) is OrderedDict:
|
||||
header_writer.writerow([key, "-"])
|
||||
for nestedkey in baseline[key]:
|
||||
header_writer.writerow([nestedkey, baseline[key][nestedkey]])
|
||||
#Basic support for 1 layer nested list. Doesn't handle more than 1.
|
||||
elif type(baseline[key]) is list and len(baseline[key])>0:
|
||||
header_writer.writerow([key, baseline[key][0]])
|
||||
for i in range(1,len(baseline[key])):
|
||||
header_writer.writerow(['-', baseline[key][i]])
|
||||
|
||||
else:
|
||||
header_writer.writerow([key, baseline[key]])
|
||||
header_writer.writerow(['',''])
|
||||
csv_writer = csv.DictWriter(csvfile, fieldnames=field_names)
|
||||
csv_writer.writeheader()
|
||||
for row in data:
|
||||
csv_writer.writerow(row)
|
||||
print("Done with [%d] detections"%(len(data)))
|
||||
|
||||
except Exception as e:
|
||||
print("Failure writing to CSV file for [%s]:"%(output_filename, str(e)))
|
||||
success = False
|
||||
|
||||
finally:
|
||||
self.lock.release()
|
||||
|
||||
return success
|
||||
|
||||
def outputResultsJSON(self, field_names:list[str], output_filename:str, data:list[dict], baseline:OrderedDict)->bool:
|
||||
success = True
|
||||
try:
|
||||
with open(output_filename, "w") as jsonFile:
|
||||
json.dump({'baseline': baseline, 'results':data}, jsonFile, indent=" ")
|
||||
except Exception as e:
|
||||
print("There was an error generating [%s]: [%s]"%(output_filename, str(e)))
|
||||
success = False
|
||||
return success
|
||||
|
||||
def outputResultsFile(self, field_names:list[str], output_filename:str, data:list[dict], baseline:OrderedDict, output_json:bool=True, output_csv:bool=True)->bool:
|
||||
success = True
|
||||
if output_csv:
|
||||
success |= self.outputResultsCSV(field_names, output_filename + ".csv", data, baseline)
|
||||
if output_json:
|
||||
success |= self.outputResultsJSON(field_names, output_filename + ".json", data, baseline)
|
||||
return success
|
||||
|
||||
|
||||
def outputResultsFiles(self, baseline:OrderedDict, fields:list[str]=['detection_name', 'detection_file','runDuration','diskUsage', 'search_string', 'error', 'success', 'scanCount', 'detection_error'])->bool:
|
||||
results_directory = "test_results"
|
||||
try:
|
||||
shutil.rmtree(results_directory,ignore_errors=True)
|
||||
os.mkdir(results_directory)
|
||||
except Exception as e:
|
||||
print("There was an error removing the results directory [%s]: [%s].\n\t We will try to continue output anyway."%(results_directory, str(e)))
|
||||
|
||||
|
||||
res = self.outputResultsFile(fields,os.path.join(results_directory, "success"), self.successes, baseline)
|
||||
res |= self.outputResultsFile(fields, os.path.join(results_directory, "failure"), self.failures, baseline)
|
||||
res |= self.outputResultsFile(fields, os.path.join(results_directory, "error"), self.errors, baseline)
|
||||
combined_data = self.successes + self.failures + self.errors
|
||||
res |= self.outputResultsFile(fields, os.path.join(results_directory, "combined"), combined_data, baseline)
|
||||
|
||||
try:
|
||||
success, test_count,pass_count,fail_count,error_count = \
|
||||
summarize_json.outputResultsJSON("summary.json", combined_data,
|
||||
baseline, output_folder=results_directory,
|
||||
summarization_reproduce_failure_config=self.summarization_reproduce_failure_config)
|
||||
summarize_json.print_summary(test_count, pass_count, fail_count, error_count)
|
||||
res |= success
|
||||
except Exception as e:
|
||||
print("Failure writing the summary file: [%s]"%str(e),file=sys.stderr)
|
||||
res = False
|
||||
|
||||
return res
|
||||
|
||||
def finish(self, baseline:OrderedDict):
|
||||
self.cleanup()
|
||||
success = True
|
||||
if self.outputResultsFiles(baseline) == False:
|
||||
print("There was an error generating one or more of the output files. "\
|
||||
"Check the logs for details.",file=sys.stderr)
|
||||
success = False
|
||||
|
||||
|
||||
if self.checkContainerFailure():
|
||||
print("One or more containers crashed or the test was HALTED early, so testing did not complete successfully. We wrote out all the results that we could")
|
||||
return False
|
||||
else:
|
||||
return success
|
||||
|
||||
|
||||
|
||||
def cleanup(self):
|
||||
self.lock.acquire()
|
||||
try:
|
||||
print("Removing all attack data that was downloaded during this test at: [%s]"%(self.attack_data_root_folder))
|
||||
shutil.rmtree(self.attack_data_root_folder)
|
||||
print("Successfully removed all attack data")
|
||||
finally:
|
||||
self.lock.release()
|
||||
|
||||
def get_system_stats(self)->str:
|
||||
|
||||
bytes_per_GB = 1024 * 1024 * 1024
|
||||
cpu_info = psutil.cpu_times_percent(percpu=False)
|
||||
memory_info = psutil.virtual_memory()
|
||||
disk_usage_info = psutil.disk_usage('/')
|
||||
|
||||
#macOS is really weird about disk usage.... so to get free space we use TOTAL-FREE = USED instead of just USED
|
||||
corrected_used_space = disk_usage_info.total - disk_usage_info.free
|
||||
|
||||
cpu_info_string = "Total CPU Usage : %d%% (%d CPUs)"%(100 - cpu_info.idle, psutil.cpu_count(logical=False))
|
||||
memory_info_string = "Total Memory Usage: %0.1fGB USED / %0.1fGB TOTAL"%((memory_info.total - memory_info.available) / bytes_per_GB, memory_info.total / bytes_per_GB)
|
||||
disk_usage_info_string = "Total Disk Usage : %0.1fGB USED / %0.1fGB TOTAL"%(corrected_used_space / bytes_per_GB, disk_usage_info.total / bytes_per_GB)
|
||||
|
||||
return "System Information:\n\t%s\n\t%s\n\t%s"%(cpu_info_string, memory_info_string, disk_usage_info_string)
|
||||
|
||||
|
||||
def summarize(self,testing_currently_active:bool=False)->bool:
|
||||
self.lock.acquire()
|
||||
try:
|
||||
|
||||
#Get a summary of some system stats
|
||||
system_stats=self.get_system_stats()
|
||||
|
||||
current_time = timeit.default_timer()
|
||||
|
||||
|
||||
|
||||
if not testing_currently_active:
|
||||
#Testing has not started yet. We are setting up containers
|
||||
print("***********PROGRESS UPDATE***********\n"\
|
||||
"\tWaiting for container setup: %s\n\t%s\n"%(datetime.timedelta(seconds=current_time - self.start_time),system_stats))
|
||||
else:
|
||||
|
||||
if self.container_ready_time is None:
|
||||
#This is the first status update since container setup has completed. Get the current time.
|
||||
#This makes our remaining time estimates better since that estimate should not involve
|
||||
#the container setup time
|
||||
print("SETTING THE CONTAINER READY TIME!")
|
||||
|
||||
self.container_ready_time = current_time
|
||||
|
||||
numberOfCompletedTests = len(self.successes) + len(self.failures) + len(self.errors)
|
||||
remaining_tests = self.testing_queue.qsize()
|
||||
testsCurrentlyRunning = self.total_number_of_tests - remaining_tests - numberOfCompletedTests
|
||||
total_execution_time_seconds = round(current_time - self.start_time)
|
||||
|
||||
test_execution_time_seconds = current_time - self.container_ready_time
|
||||
|
||||
|
||||
if numberOfCompletedTests == 0 or test_execution_time_seconds == 0:
|
||||
estimated_seconds_to_finish_all_tests = "UNKNOWN"
|
||||
estimated_completion_time_string = "UNKNOWN"
|
||||
average_time_per_test_string = "UNKNOWN"
|
||||
else:
|
||||
average_time_per_test = test_execution_time_seconds / numberOfCompletedTests
|
||||
average_time_per_test_string = datetime.timedelta(seconds=round(test_execution_time_seconds/numberOfCompletedTests))
|
||||
#divide testsCurrentlyRunning by 2.0 because, on average, each running test will be 50% completed
|
||||
estimated_seconds_to_finish_all_tests = round(average_time_per_test * (remaining_tests + testsCurrentlyRunning/2.0))
|
||||
estimated_completion_time_string = datetime.timedelta(seconds=estimated_seconds_to_finish_all_tests)
|
||||
|
||||
|
||||
|
||||
|
||||
print(f"***********PROGRESS UPDATE***********\n"\
|
||||
f"\tElapsed Time : {datetime.timedelta(seconds=total_execution_time_seconds)}\n"\
|
||||
f"\tTest Execution Time : {datetime.timedelta(seconds=round(test_execution_time_seconds))}\n"\
|
||||
f"\tEstimated Remaining Time : {estimated_completion_time_string}\n"\
|
||||
f"\tTests to run : {remaining_tests}\n"\
|
||||
f"\tAverage Time Per Test : {average_time_per_test_string}\n",
|
||||
f"\tTests currently running : {testsCurrentlyRunning}\n"\
|
||||
f"\tTests completed : {numberOfCompletedTests}\n"\
|
||||
f"\t\tSuccess : {len(self.successes)}\n"\
|
||||
f"\t\tFailure : {len(self.failures)}\n"\
|
||||
f"\t\tError : {len(self.errors)}\n"\
|
||||
f"\t{system_stats}\n")
|
||||
|
||||
except Exception as e:
|
||||
print("Error in printing execution summary: [%s]"%(str(e)))
|
||||
finally:
|
||||
self.lock.release()
|
||||
|
||||
|
||||
#Return true while there are tests remaining
|
||||
completed_tests = len(self.successes) + len(self.failures) + len(self.errors)
|
||||
remaining_tests = self.total_number_of_tests - completed_tests
|
||||
return remaining_tests > 0
|
||||
|
||||
|
||||
|
||||
def addResult(self, result:dict, duration_string:str)->None:
|
||||
try:
|
||||
if result['detection_result']['error'] is True:
|
||||
self.addError(result['detection_result'], duration_string = duration_string)
|
||||
elif result['detection_result']['success'] is False:
|
||||
#This is actually a failure of the detection, not an error. Naming is confusiong
|
||||
self.addFailure(result['detection_result'], duration_string = duration_string)
|
||||
elif result['detection_result']['success'] is True:
|
||||
self.addSuccess(result['detection_result'], duration_string = duration_string)
|
||||
except Exception as e:
|
||||
#Neither a success or a failure, so add the object to the failures queue
|
||||
print('"There was an error adding the result: [%s]'%(str(e)))
|
||||
self.addError({'detection_file':"Unknown File", "detection_error":str(result)})
|
||||
|
||||
@@ -1,294 +0,0 @@
|
||||
import re
|
||||
|
||||
# import ansible_runner
|
||||
import yaml
|
||||
import uuid
|
||||
import sys
|
||||
import os
|
||||
import time
|
||||
import requests
|
||||
from modules.DataManipulation import DataManipulation
|
||||
from modules import utils
|
||||
from modules import splunk_sdk
|
||||
import timeit
|
||||
from typing import Union, Tuple
|
||||
from os.path import relpath
|
||||
from tempfile import mkdtemp, mkstemp
|
||||
import datetime
|
||||
import http.client
|
||||
|
||||
|
||||
def test_detection_wrapper(
|
||||
container_name: str,
|
||||
splunk_ip: str,
|
||||
splunk_password: str,
|
||||
splunk_port: int,
|
||||
detection_file: str,
|
||||
attack_data_root_folder,
|
||||
wait_on_failure: bool = False,
|
||||
wait_on_completion: bool = False,
|
||||
smoketest: bool = False,
|
||||
) -> dict:
|
||||
one_test_start = timeit.default_timer()
|
||||
uuid_var = str(uuid.uuid4())
|
||||
result_test, indices_to_delete = test_detection(
|
||||
splunk_ip,
|
||||
splunk_port,
|
||||
container_name,
|
||||
splunk_password,
|
||||
detection_file,
|
||||
uuid_var,
|
||||
attack_data_root_folder,
|
||||
smoketest,
|
||||
)
|
||||
one_test_stop = timeit.default_timer()
|
||||
|
||||
if result_test is None:
|
||||
# We failed so early in the process that we could not produce any meaningful result
|
||||
raise (Exception("Test execution Error"))
|
||||
|
||||
# enter = input("Run some tests from [%s] on [%s] - we don't delete until you hit enter :)"%(container_name, test_file))
|
||||
# delete test data
|
||||
search_string = result_test["detection_result"]["search_string"]
|
||||
|
||||
# get pretty time info
|
||||
elapsed_search_time_string = str(
|
||||
datetime.timedelta(seconds=round(one_test_stop - one_test_start))
|
||||
)
|
||||
|
||||
# search failed if there was an error or the detection failed to produce the expected result
|
||||
# print("Elapsed search time: %s"%(elapsed_search_time_string))
|
||||
if (wait_on_failure or wait_on_completion) and (
|
||||
result_test["detection_result"]["error"]
|
||||
or not result_test["detection_result"]["success"]
|
||||
):
|
||||
wait_on_delete = {
|
||||
"message": "\n\n\n****SEARCH FAILURE : Allowing time to debug search/data****"
|
||||
}
|
||||
elif wait_on_completion:
|
||||
wait_on_delete = {
|
||||
"message": "\n\n\n****SEARCH SUCCESS : Allowing time to examine search/data****"
|
||||
}
|
||||
else:
|
||||
wait_on_delete = None
|
||||
|
||||
splunk_sdk.delete_attack_data(
|
||||
splunk_ip,
|
||||
splunk_password,
|
||||
splunk_port,
|
||||
wait_on_delete,
|
||||
search_string,
|
||||
detection_file,
|
||||
indices=indices_to_delete,
|
||||
)
|
||||
|
||||
return result_test
|
||||
|
||||
|
||||
import splunklib.client as client
|
||||
|
||||
|
||||
def get_service(splunk_ip: str, splunk_port: int, splunk_password: str):
|
||||
try:
|
||||
service = client.connect(
|
||||
host=splunk_ip, port=splunk_port, username="admin", password=splunk_password
|
||||
)
|
||||
except Exception as e:
|
||||
raise (Exception("Unable to connect to Splunk instance: " + str(e)))
|
||||
return service
|
||||
|
||||
|
||||
def test_detection(
|
||||
splunk_ip: str,
|
||||
splunk_port: int,
|
||||
container_name: str,
|
||||
splunk_password: str,
|
||||
detection_file: str,
|
||||
uuid_var,
|
||||
attack_data_root_folder,
|
||||
smoketest: bool,
|
||||
) -> Tuple[Union[dict, None], set[str]]:
|
||||
detection_file_obj = load_file(os.path.join("security_content/", detection_file))
|
||||
|
||||
if not detection_file_obj:
|
||||
print("Not detection_file_obj!")
|
||||
raise (Exception("No test file object found for [%s]" % detection_file))
|
||||
|
||||
indices_to_delete = set()
|
||||
abs_folder_path = mkdtemp(prefix="DATA_", dir=attack_data_root_folder)
|
||||
if smoketest:
|
||||
result_detection = splunk_sdk.test_detection_search(
|
||||
splunk_ip,
|
||||
splunk_port,
|
||||
splunk_password,
|
||||
detection_file_obj["search"],
|
||||
"",
|
||||
detection_file_obj["name"],
|
||||
detection_file,
|
||||
"-24h",
|
||||
"now",
|
||||
attempts_remaining=1,
|
||||
)
|
||||
|
||||
result_test = {}
|
||||
test = {"name": detection_file_obj["name"] + " Smoketest"}
|
||||
result_test["baselines_result"] = []
|
||||
else:
|
||||
# print(test_file_obj)
|
||||
|
||||
# write entry dynamodb
|
||||
# aws_service.add_detection_results_in_dynamo_db('eu-central-1', uuid_var , uuid_test, test_file_obj['tests'][0]['name'], test_file_obj['tests'][0]['file'], str(int(time.time())))
|
||||
|
||||
# epoch_time = str(int(time.time()))
|
||||
|
||||
# We want the relative path, so we convert it as required
|
||||
|
||||
tests: dict = detection_file_obj.get("tests", {})
|
||||
if len(tests) > 1:
|
||||
print(
|
||||
f"****WARNING - THIS DETECTION CONTAINS {len(tests)} TESTS BUT WE WILL ONLY RUN 1"
|
||||
)
|
||||
test = tests[0]
|
||||
|
||||
for attack_data in test["attack_data"]:
|
||||
url = attack_data["data"]
|
||||
|
||||
if "custom_index" in attack_data:
|
||||
print(
|
||||
f"Found a custom index for {detection_file}: {attack_data['custom_index']}"
|
||||
)
|
||||
data_upload_index = attack_data["custom_index"]
|
||||
else:
|
||||
data_upload_index = splunk_sdk.DEFAULT_DATA_INDEX
|
||||
|
||||
indices_to_delete.add(data_upload_index)
|
||||
|
||||
_, target_file = mkstemp(prefix="attack_data_", dir=abs_folder_path)
|
||||
|
||||
utils.download_file_from_http(url, target_file, overwrite_file=True)
|
||||
|
||||
# Update timestamps before replay
|
||||
if "update_timestamp" in attack_data:
|
||||
if attack_data["update_timestamp"] == True:
|
||||
data_manipulation = DataManipulation()
|
||||
data_manipulation.manipulate_timestamp(
|
||||
target_file, attack_data["sourcetype"], attack_data["source"]
|
||||
)
|
||||
# replay_attack_dataset(container_name, splunk_password, folder_name, "test0", attack_data['sourcetype'], attack_data['source'], attack_data['file_name'])
|
||||
|
||||
try:
|
||||
service = get_service(splunk_ip, splunk_port, splunk_password)
|
||||
test_index = service.indexes[data_upload_index]
|
||||
|
||||
with open(target_file, "rb") as target:
|
||||
test_index.submit(
|
||||
target.read(),
|
||||
sourcetype=attack_data["sourcetype"],
|
||||
source=attack_data["source"],
|
||||
host=splunk_sdk.DEFAULT_EVENT_HOST,
|
||||
)
|
||||
|
||||
except http.client.HTTPException as e:
|
||||
raise (
|
||||
Exception(
|
||||
f"Failed to submit detection file {target_file} to Splunk Server: {str(e)}"
|
||||
)
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
raise (
|
||||
Exception(
|
||||
f"Failed to submit detection file {target_file} to Splunk Server: {str(e)}"
|
||||
)
|
||||
)
|
||||
|
||||
if not splunk_sdk.wait_for_indexing_to_complete(
|
||||
splunk_ip,
|
||||
splunk_port,
|
||||
splunk_password,
|
||||
attack_data["sourcetype"],
|
||||
data_upload_index,
|
||||
):
|
||||
raise Exception("There was an error waiting for indexing to complete.")
|
||||
|
||||
# Allow some time for the data to be ingested and processed
|
||||
# print("begin sleep 30")
|
||||
# time.sleep(60)
|
||||
|
||||
# print("end sleep 30")
|
||||
|
||||
result_test = {}
|
||||
|
||||
if "baselines" in test:
|
||||
results_baselines = []
|
||||
for baseline_obj in test["baselines"]:
|
||||
baseline_file_name = baseline_obj["file"]
|
||||
baseline = load_file(
|
||||
os.path.join(
|
||||
os.path.dirname(__file__),
|
||||
"../security_content",
|
||||
baseline_file_name,
|
||||
)
|
||||
)
|
||||
result_obj = dict()
|
||||
result_obj["baseline"] = baseline_obj["name"]
|
||||
result_obj["baseline_file"] = baseline_file_name
|
||||
print(
|
||||
"Making test_baseline_search request to: [%s:%d]"
|
||||
% (splunk_ip, splunk_port)
|
||||
)
|
||||
result = splunk_sdk.test_baseline_search(
|
||||
splunk_ip,
|
||||
splunk_port,
|
||||
splunk_password,
|
||||
baseline["search"],
|
||||
baseline_obj["pass_condition"],
|
||||
baseline["name"],
|
||||
baseline_file_name,
|
||||
baseline_obj["earliest_time"],
|
||||
baseline_obj["latest_time"],
|
||||
)
|
||||
# we don't seem to be doing anything with this loop... are we supposed to have the following line belwo?
|
||||
results_baselines.append(result)
|
||||
|
||||
result_test["baselines_result"] = results_baselines
|
||||
|
||||
result_detection = splunk_sdk.test_detection_search(
|
||||
splunk_ip,
|
||||
splunk_port,
|
||||
splunk_password,
|
||||
detection_file_obj["search"],
|
||||
test.get("pass_condition", "| stats count | where count > 0"),
|
||||
detection_file_obj["name"],
|
||||
detection_file,
|
||||
test.get("earliest_time", "-24h"),
|
||||
test.get("latest_time", "now"),
|
||||
)
|
||||
if result_detection["error"]:
|
||||
print(
|
||||
"There was an error running the search: %s"
|
||||
% (result_detection["search_string"])
|
||||
)
|
||||
|
||||
result_detection["detection_name"] = test["name"]
|
||||
result_detection["detection_file"] = detection_file
|
||||
result_test["detection_result"] = result_detection
|
||||
result_test["attack_data_directory"] = abs_folder_path
|
||||
|
||||
return result_test, indices_to_delete
|
||||
|
||||
|
||||
def load_file(file_path):
|
||||
try:
|
||||
with open(file_path, "r", encoding="utf-8") as stream:
|
||||
try:
|
||||
file = list(yaml.safe_load_all(stream))[0]
|
||||
except yaml.YAMLError as exc:
|
||||
raise (
|
||||
Exception(
|
||||
"ERROR: parsing YAML for {0}:[{1}]".format(file_path, str(exc))
|
||||
)
|
||||
)
|
||||
except Exception as e:
|
||||
raise (Exception("ERROR: opening {0}:[{1}]".format(file_path, str(e))))
|
||||
return file
|
||||
@@ -1,71 +0,0 @@
|
||||
Malicious events
|
||||
|
||||
| tstats count as count values(Processes.action) as action,
|
||||
values(Processes.cpu_load_percent) as cpu_load_percent,
|
||||
values(Processes.dest) as dest,
|
||||
values(Processes.mem_used) as mem_used,
|
||||
values(Processes.os) as os,
|
||||
values(Processes.parent_process) as parent_process,
|
||||
values(Processes.parent_process_exec) as parent_process_exec,
|
||||
values(Processes.parent_process_id) as parent_process_id,
|
||||
values(Processes.parent_process_guid) as parent_process_guid,
|
||||
values(Processes.parent_process_name) as parent_process_name,
|
||||
values(Processes.parent_process_path) as parent_process_path,
|
||||
values(Processes.process) as process,
|
||||
values(Processes.process_current_directory) as process_current_directory,
|
||||
values(Processes.process_exec) as process_exec,
|
||||
values(Processes.process_hash) as process_hash,
|
||||
values(Processes.process_guid) as process_guid,
|
||||
values(Processes.process_id) as process_id,
|
||||
values(Processes.process_integrity_level) as process_integrity_level,
|
||||
values(Processes.process_name) as process_name,
|
||||
values(Processes.process_path) as process_path,
|
||||
values(Processes.tag) as tag,
|
||||
values(Processes.user) as user,
|
||||
values(Processes.user_id) as user_id,
|
||||
values(Processes.vendor_product) as vendor_product,
|
||||
values(host) as host,
|
||||
values(source) as source,
|
||||
values(sourcetype) as sourcetype
|
||||
from datamodel=Endpoint.Processes
|
||||
where (Processes.process_name=reg.exe
|
||||
OR Processes.process_name=cmd.exe) Processes.process=*save* (Processes.process=*HKEY_LOCAL_MACHINE\\Security*
|
||||
OR Processes.process=*HKEY_LOCAL_MACHINE\\SAM* OR Processes.process=*HKEY_LOCAL_MACHINE\\System*
|
||||
OR Processes.process=*HKLM\\Security* OR Processes.process=*HKLM\\System* OR Processes.process=*HKLM\\SAM*)
|
||||
by Processes.user Processes.process_name Processes.process Processes.dest Processes.process_id
|
||||
|
||||
|
||||
Not mailicous events
|
||||
| tstats count as count values(Processes.action) as action,
|
||||
values(Processes.cpu_load_percent) as cpu_load_percent,
|
||||
values(Processes.dest) as dest,
|
||||
values(Processes.mem_used) as mem_used,
|
||||
values(Processes.os) as os,
|
||||
values(Processes.parent_process) as parent_process,
|
||||
values(Processes.parent_process_exec) as parent_process_exec,
|
||||
values(Processes.parent_process_id) as parent_process_id,
|
||||
values(Processes.parent_process_guid) as parent_process_guid,
|
||||
values(Processes.parent_process_name) as parent_process_name,
|
||||
values(Processes.parent_process_path) as parent_process_path,
|
||||
values(Processes.process) as process,
|
||||
values(Processes.process_current_directory) as process_current_directory,
|
||||
values(Processes.process_exec) as process_exec,
|
||||
values(Processes.process_hash) as process_hash,
|
||||
values(Processes.process_guid) as process_guid,
|
||||
values(Processes.process_id) as process_id,
|
||||
values(Processes.process_integrity_level) as process_integrity_level,
|
||||
values(Processes.process_name) as process_name,
|
||||
values(Processes.process_path) as process_path,
|
||||
values(Processes.tag) as tag,
|
||||
values(Processes.user) as user,
|
||||
values(Processes.user_id) as user_id,
|
||||
values(Processes.vendor_product) as vendor_product,
|
||||
values(host) as host,
|
||||
values(source) as source,
|
||||
values(sourcetype) as sourcetype
|
||||
from datamodel=Endpoint.Processes
|
||||
where NOT((Processes.process_name=reg.exe
|
||||
OR Processes.process_name=cmd.exe) Processes.process=*save* (Processes.process=*HKEY_LOCAL_MACHINE\\Security*
|
||||
OR Processes.process=*HKEY_LOCAL_MACHINE\\SAM* OR Processes.process=*HKEY_LOCAL_MACHINE\\System*
|
||||
OR Processes.process=*HKLM\\Security* OR Processes.process=*HKLM\\System* OR Processes.process=*HKLM\\SAM*))
|
||||
by Processes.user Processes.process_name Processes.process Processes.dest Processes.process_id
|
||||
@@ -1,25 +0,0 @@
|
||||
import os
|
||||
import requests
|
||||
|
||||
|
||||
def download_file_from_http(url:str, destination_file:str, overwrite_file:bool=False, chunk_size:int=1024*1024, verbose_print:bool=False)->None:
|
||||
if os.path.exists(destination_file) and overwrite_file is False:
|
||||
print(f"[{destination_file}] already exists...using cached version")
|
||||
return
|
||||
if verbose_print:
|
||||
print(f"downloading to [{destination_file}]...",end="")
|
||||
try:
|
||||
file_to_download = requests.get(url, stream=True)
|
||||
if file_to_download.status_code != 200:
|
||||
if verbose_print:
|
||||
print("FAILED")
|
||||
raise Exception(f"Error downloading the file {url}: Status Code {file_to_download.status_code}")
|
||||
with open(destination_file, "wb") as output:
|
||||
for piece in file_to_download.iter_content(chunk_size=chunk_size):
|
||||
output.write(piece)
|
||||
if verbose_print:
|
||||
print("Done")
|
||||
except Exception as e:
|
||||
if verbose_print:
|
||||
print("FAILED")
|
||||
raise e
|
||||
@@ -1,352 +0,0 @@
|
||||
import argparse
|
||||
import copy
|
||||
import io
|
||||
import json
|
||||
import modules.jsonschema_errorprinter as jsonschema_errorprinter
|
||||
import sys
|
||||
from typing import Union
|
||||
|
||||
|
||||
# If we want, we can easily add a description field to any of the objects here!
|
||||
ES_APP_NAME = "SPLUNK_ES_CONTENT_UPDATE"
|
||||
setup_schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"branch": {"type": "string", "default": "develop"},
|
||||
"commit_hash": {"type": ["string", "null"], "default": None},
|
||||
"container_tag": {"type": "string", "default": "latest"},
|
||||
"no_interactive_failure": {"type": "boolean", "default": False},
|
||||
"interactive": {"type": "boolean", "default": False},
|
||||
"detections_list": {
|
||||
"type": ["array", "null"],
|
||||
"items": {"type": "string"},
|
||||
"default": None,
|
||||
},
|
||||
"apps": {
|
||||
"type": "object",
|
||||
"additionalProperties": False,
|
||||
"patternProperties": {
|
||||
"^.*$": {
|
||||
"type": "object",
|
||||
"additionalProperties": False,
|
||||
"properties": {
|
||||
"app_number": {"type": ["integer", "null"]},
|
||||
"app_version": {"type": ["string", "null"]},
|
||||
"local_path": {"type": ["string", "null"]},
|
||||
"http_path": {"type": ["string", "null"]},
|
||||
},
|
||||
"anyOf": [
|
||||
{"required": ["local_path"]},
|
||||
{"required": ["http_path"]},
|
||||
{"required": ["app_number", "app_version"]},
|
||||
],
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
# The default apps below were taken from the attack_range loadout: https://github.com/splunk/attack_range/blob/develop/attack_range.conf.template
|
||||
"Splunk Add-on for CrowdStrike FDR": {
|
||||
"app_number": 5579,
|
||||
"app_version": "1.3.0",
|
||||
"http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/splunk-add-on-for-crowdstrike-fdr_140.tgz",
|
||||
},
|
||||
"ADD_ON_FOR_LINUX_SYSMON": {
|
||||
"app_number": 6176,
|
||||
"app_version": "1.0.4",
|
||||
"http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/add-on-for-linux-sysmon_104.tgz",
|
||||
},
|
||||
"SPLUNK_TA_FOR_IIS": {
|
||||
"app_number": 3185,
|
||||
"app_version": "1.2.0",
|
||||
"http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/splunk-add-on-for-microsoft-iis_120.tgz",
|
||||
},
|
||||
ES_APP_NAME: {
|
||||
"app_number": 3449,
|
||||
"app_version": None,
|
||||
"local_path": None,
|
||||
},
|
||||
"PALO_ALTO_NETWORKS_ADD_ON_FOR_SPLUNK": {
|
||||
"app_number": 2757,
|
||||
"app_version": "8.0.1",
|
||||
"http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/palo-alto-networks-add-on-for-splunk_802.tgz",
|
||||
},
|
||||
"PYTHON_FOR_SCIENTIFIC_COMPUTING_FOR_LINUX_64_BIT": {
|
||||
"app_number": 2882,
|
||||
"app_version": "4.1.0",
|
||||
"http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/python-for-scientific-computing-for-linux-64-bit_410.tgz",
|
||||
},
|
||||
"SPLUNK_ADD_ON_FOR_AMAZON_KINESIS_FIREHOSE": {
|
||||
"app_number": 3719,
|
||||
"app_version": "1.3.2",
|
||||
"http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/splunk-add-on-for-amazon-kinesis-firehose_132.tgz",
|
||||
},
|
||||
"SPLUNK_ADD_ON_FOR_MICROSOFT_OFFICE_365": {
|
||||
"app_number": 4055,
|
||||
"app_version": "4.2.1",
|
||||
"http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/splunk-add-on-for-microsoft-office-365_430.tgz",
|
||||
},
|
||||
"SPLUNK_ADD_ON_FOR_MICROSOFT_WINDOWS": {
|
||||
"app_number": 742,
|
||||
"app_version": "8.5.0",
|
||||
"http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/splunk-add-on-for-microsoft-windows_870.tgz",
|
||||
},
|
||||
"SPLUNK_ADD_ON_FOR_NGINX": {
|
||||
"app_number": 3258,
|
||||
"app_version": "3.2.1",
|
||||
"http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/splunk-add-on-for-nginx_321.tgz",
|
||||
},
|
||||
"SPLUNK_ADD_ON_FOR_STREAM_FORWARDERS": {
|
||||
"app_number": 5238,
|
||||
"app_version": "8.1.0",
|
||||
"http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/splunk-add-on-for-stream-forwarders_810.tgz",
|
||||
},
|
||||
"SPLUNK_ADD_ON_FOR_STREAM_WIRE_DATA": {
|
||||
"app_number": 5234,
|
||||
"app_version": "8.1.0",
|
||||
"http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/splunk-add-on-for-stream-wire-data_810.tgz",
|
||||
},
|
||||
"SPLUNK_ADD_ON_FOR_SYSMON": {
|
||||
"app_number": 5709,
|
||||
"app_version": "3.1.0",
|
||||
"http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/splunk-add-on-for-sysmon_310.tgz",
|
||||
},
|
||||
"SPLUNK_ADD_ON_FOR_UNIX_AND_LINUX": {
|
||||
"app_number": 833,
|
||||
"app_version": "8.8.0",
|
||||
"http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/splunk-add-on-for-unix-and-linux_890.tgz",
|
||||
},
|
||||
"SPLUNK_APP_FOR_STREAM": {
|
||||
"app_number": 1809,
|
||||
"app_version": "8.1.0",
|
||||
"http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/splunk-app-for-stream_810.tgz",
|
||||
},
|
||||
"SPLUNK_MACHINE_LEARNING_TOOLKIT": {
|
||||
"app_number": 2890,
|
||||
"app_version": "5.4.0",
|
||||
"http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/splunk-machine-learning-toolkit_540.tgz",
|
||||
},
|
||||
"SPLUNK_TA_FOR_ZEEK": {
|
||||
"app_number": 5466,
|
||||
"app_version": "1.0.5",
|
||||
"http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/ta-for-zeek_105.tgz",
|
||||
},
|
||||
"URL_TOOLBOX": {
|
||||
"app_number": 2734,
|
||||
"app_version": "1.9.2",
|
||||
"http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/url-toolbox_192.tgz",
|
||||
},
|
||||
"SPLUNK_TA_FIX_WINDOWS": {
|
||||
"app_number": 9999,
|
||||
"app_version": "1.0.0",
|
||||
"http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/Splunk_TA_fix_windows.tgz",
|
||||
},
|
||||
"SPLUNK_TA_MICROSOFT_CLOUD_SERVICES": {
|
||||
"app_number": 3110,
|
||||
"app_version": "4.5.2",
|
||||
"http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/splunk-add-on-for-microsoft-cloud-services_510.tgz",
|
||||
},
|
||||
"SPLUNK_ADD_ON_FOR_GOOGLE_CLOUD_PLATFORM": {
|
||||
"app_number": 3088,
|
||||
"app_version": "4.1.0",
|
||||
"http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/splunk-add-on-for-google-cloud-platform_410.tgz",
|
||||
},
|
||||
"SPLUNK_ADD_ON_FOR_GOOGLE_WORKSPACE": {
|
||||
"app_number": 3110,
|
||||
"app_version": "2.4.1",
|
||||
"http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/splunk-add-on-for-google-workspace_251.tgz",
|
||||
},
|
||||
"SPLUNK_TA_FOR_SURICATA": {
|
||||
"app_number": 2760,
|
||||
"app_version": "2.3.3",
|
||||
"http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/ta-for-suricata_234.tgz",
|
||||
},
|
||||
"SPLUNK_COMMON_INFORMATION_MODEL": {
|
||||
"app_number": 1621,
|
||||
"app_version": "5.1.0",
|
||||
"http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/splunk-common-information-model-cim_511.tgz",
|
||||
}
|
||||
},
|
||||
},
|
||||
"mode": {
|
||||
"type": "string",
|
||||
"enum": ["changes", "selected", "all", "smoketest"],
|
||||
"default": "changes",
|
||||
},
|
||||
"num_containers": {"type": "integer", "minimum": 1, "default": 1},
|
||||
"persist_security_content": {"type": "boolean", "default": False},
|
||||
"pr_number": {"type": ["integer", "null"], "default": None},
|
||||
"reuse_image": {"type": "boolean", "default": True},
|
||||
"show_splunk_app_password": {"type": "boolean", "default": False},
|
||||
"splunkbase_username": {"type": ["string", "null"], "default": None},
|
||||
"splunkbase_password": {"type": ["string", "null"], "default": None},
|
||||
"splunk_app_password": {"type": ["string", "null"], "default": None},
|
||||
"splunk_container_apps_directory": {
|
||||
"type": "string",
|
||||
"default": "/opt/splunk/etc/apps",
|
||||
},
|
||||
"local_base_container_name": {"type": "string", "default": "splunk_test_%d"},
|
||||
"mock": {"type": "boolean", "default": False},
|
||||
"folders": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"endpoint",
|
||||
"cloud",
|
||||
"network",
|
||||
"web",
|
||||
"application",
|
||||
"experimental",
|
||||
],
|
||||
},
|
||||
"default": ["endpoint", "cloud", "network", "web", "application"],
|
||||
},
|
||||
"types": {
|
||||
"type": "array",
|
||||
"items": {"type": "string", "enum": ["Anomaly", "Hunting", "TTP"]},
|
||||
"default": ["Anomaly", "Hunting", "TTP"],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def validate_file(file: io.TextIOWrapper) -> tuple[Union[dict, None], dict]:
|
||||
try:
|
||||
settings = json.loads(file.read())
|
||||
return validate(settings)
|
||||
except Exception as e:
|
||||
raise (e)
|
||||
|
||||
|
||||
def check_dependencies(
|
||||
settings: dict, skip_password_accessibility_check: bool = True
|
||||
) -> bool:
|
||||
# Check complex mode dependencies
|
||||
error_free = True
|
||||
|
||||
# Make sure that all the mode arguments are sane
|
||||
if settings["mode"] == "selected":
|
||||
# Make sure that exactly one of the following fields is populated
|
||||
|
||||
if settings["detections_list"] == None:
|
||||
print(
|
||||
"Error - mode was 'selected' but no detections_list was supplied.",
|
||||
file=sys.stderr,
|
||||
)
|
||||
error_free = False
|
||||
|
||||
if settings["mode"] != "selected" and settings["detections_list"] != None:
|
||||
print(
|
||||
"Error - mode was not 'selected' but detections_list was supplied.",
|
||||
file=sys.stderr,
|
||||
)
|
||||
error_free = False
|
||||
|
||||
# Make sure that if we will be in an interactive mode, that either the user has provided the password or the password will be printed
|
||||
if skip_password_accessibility_check:
|
||||
pass
|
||||
elif (
|
||||
settings["interactive"] or not settings["no_interactive_failure"]
|
||||
) and settings["show_splunk_app_password"] is False:
|
||||
print("\n\n******************************************************\n\n")
|
||||
if settings["splunk_app_password"] is not None:
|
||||
print(
|
||||
"Warning: You have chosen an interactive mode, set show_splunk_app_password False,\n"
|
||||
"and provided a password in the config file. We will NOT print this password to\n"
|
||||
"stdout. Look in the config file for this password.",
|
||||
file=sys.stderr,
|
||||
)
|
||||
else:
|
||||
print(
|
||||
"Warning: You have chosen an interactive mode, set show_splunk_app_password False,\n"
|
||||
"and DID NOT provide a password in the config file. We have updated show_splunk_app_password\n"
|
||||
"to True for you. Otherwise, interactive mode login would be impossible.",
|
||||
file=sys.stderr,
|
||||
)
|
||||
settings["show_splunk_app_password"] = True
|
||||
print("\n\n******************************************************\n\n")
|
||||
|
||||
# Returns true if there are not errors
|
||||
return error_free
|
||||
|
||||
|
||||
def validate_and_write(
|
||||
configuration: dict,
|
||||
output_file: Union[io.TextIOWrapper, None] = None,
|
||||
strip_credentials: bool = False,
|
||||
skip_password_accessibility_check: bool = True,
|
||||
) -> tuple[Union[dict, None], dict]:
|
||||
closeFile = False
|
||||
if output_file is None:
|
||||
import datetime
|
||||
|
||||
now = datetime.datetime.now()
|
||||
configname = now.strftime("%Y-%m-%dT%H:%M:%S%z") + "-test-run.json"
|
||||
output_file = open(configname, "w")
|
||||
closeFile = True
|
||||
|
||||
if strip_credentials:
|
||||
configuration = copy.deepcopy(configuration)
|
||||
configuration["splunkbase_password"] = None
|
||||
configuration["splunkbase_username"] = None
|
||||
configuration["container_password"] = None
|
||||
configuration["show_splunk_app_password"] = True
|
||||
|
||||
validated_json, setup_schema = validate(
|
||||
configuration, skip_password_accessibility_check
|
||||
)
|
||||
if validated_json == None:
|
||||
print("Error in the new settings! No output file written")
|
||||
else:
|
||||
print("Settings updated. Writing results to: %s" % (output_file.name))
|
||||
try:
|
||||
output_file.write(json.dumps(validated_json, sort_keys=True, indent=4))
|
||||
except Exception as e:
|
||||
print(
|
||||
"Error writing settings to %s: [%s]" % (output_file.name, str(e)),
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(1)
|
||||
if closeFile is True:
|
||||
output_file.close()
|
||||
|
||||
return validated_json, setup_schema
|
||||
|
||||
|
||||
def validate(
|
||||
configuration: dict, skip_password_accessibility_check: bool = True
|
||||
) -> tuple[Union[dict, None], dict]:
|
||||
# v = jsonschema.Draft201909Validator(argument_schema)
|
||||
|
||||
try:
|
||||
validation_errors, validated_json = jsonschema_errorprinter.check_json(
|
||||
configuration, setup_schema
|
||||
)
|
||||
|
||||
if len(validation_errors) == 0:
|
||||
# check to make sure there were no complex errors
|
||||
no_complex_errors = check_dependencies(
|
||||
validated_json, skip_password_accessibility_check
|
||||
)
|
||||
if no_complex_errors:
|
||||
return validated_json, setup_schema
|
||||
else:
|
||||
print(
|
||||
"Validation failed due to error(s) listed above.", file=sys.stderr
|
||||
)
|
||||
return None, setup_schema
|
||||
else:
|
||||
print(
|
||||
"[%d] failures detected during validation of the configuration!"
|
||||
% (len(validation_errors)),
|
||||
file=sys.stderr,
|
||||
)
|
||||
for error in validation_errors:
|
||||
print(error, end="\n\n", file=sys.stderr)
|
||||
return None, setup_schema
|
||||
|
||||
except Exception as e:
|
||||
print(
|
||||
"There was an error validation the configuration: [%s]" % (str(e)),
|
||||
file=sys.stderr,
|
||||
)
|
||||
return None, setup_schema
|
||||
@@ -1,247 +0,0 @@
|
||||
import json
|
||||
from collections import OrderedDict
|
||||
import argparse
|
||||
import sys
|
||||
import json
|
||||
from modules import validate_args
|
||||
import os.path
|
||||
from operator import itemgetter
|
||||
import copy
|
||||
|
||||
|
||||
def outputResultsJSON(
|
||||
output_filename: str,
|
||||
data: list[dict],
|
||||
baseline: OrderedDict,
|
||||
failure_manifest_filename="detection_failure_manifest.json",
|
||||
output_folder: str = "",
|
||||
summarization_reproduce_failure_config: dict = {},
|
||||
) -> tuple[bool, int, int, int, int]:
|
||||
success = True
|
||||
|
||||
try:
|
||||
test_count = len(data)
|
||||
# Passed
|
||||
pass_count = len([x for x in data if x["success"] == True])
|
||||
|
||||
# A failure or an error
|
||||
fail_count = len([x for x in data if x["success"] == False])
|
||||
|
||||
# An error (every error is also a failure)
|
||||
fail_and_error_count = len([x for x in data if x["error"] == True])
|
||||
|
||||
# A failure without an error
|
||||
fail_without_error_count = len(
|
||||
[x for x in data if x["success"] == False and x["error"] == False]
|
||||
)
|
||||
|
||||
# This number should always be zero...
|
||||
error_and_success_count = len(
|
||||
[x for x in data if x["success"] == True and x["error"] == True]
|
||||
)
|
||||
if error_and_success_count > 0:
|
||||
print(
|
||||
"Error - a test was successful, but also included an error. This should be impossible.",
|
||||
file=sys.stderr,
|
||||
)
|
||||
success = False
|
||||
|
||||
if test_count != (pass_count + fail_count):
|
||||
print(
|
||||
"Error - the total tests [%d] does not equal the pass[%d]/fails[%d]"
|
||||
% (test_count, pass_count, fail_count)
|
||||
)
|
||||
success = False
|
||||
|
||||
if fail_count > 0:
|
||||
result = "FAIL for %d detections" % (fail_count)
|
||||
success = False
|
||||
else:
|
||||
result = "PASS for all %d detections" % (pass_count)
|
||||
|
||||
summary = {
|
||||
"TOTAL_TESTS": test_count,
|
||||
"TESTS_PASSED": pass_count,
|
||||
"TOTAL_FAILURES": fail_count,
|
||||
"FAIL_ONLY": fail_without_error_count,
|
||||
"PASS_RATE": calculate_pass_rate(pass_count, test_count),
|
||||
"FAIL_AND_ERROR": fail_and_error_count,
|
||||
}
|
||||
|
||||
data_sorted = sorted(
|
||||
data, key=lambda k: (-k["error"], k["success"], k["detection_file"])
|
||||
)
|
||||
with open(os.path.join(output_folder, output_filename), "w") as jsonFile:
|
||||
json.dump(
|
||||
{"summary": summary, "baseline": baseline, "results": data_sorted},
|
||||
jsonFile,
|
||||
indent=" ",
|
||||
)
|
||||
|
||||
# Generate a failure that the user can download to reproduce and test ONLY the failures locally.
|
||||
# This makes it easy to test and debug ONLY those that failed. No need to test the ones
|
||||
# that succeeded!
|
||||
|
||||
fail_list = [
|
||||
os.path.join("security_content/detections", x["detection_file"])
|
||||
for x in data_sorted
|
||||
if x["success"] == False
|
||||
]
|
||||
|
||||
if len(fail_list) > 0:
|
||||
print("FAILURES:")
|
||||
for failed_test in fail_list:
|
||||
print(f"\t{failed_test}")
|
||||
failures_test_override = copy.deepcopy(
|
||||
summarization_reproduce_failure_config
|
||||
)
|
||||
# Force all tests to be interactive, even if they don't fail (because they failed on this test)
|
||||
failures_test_override.update(
|
||||
{
|
||||
"detections_list": fail_list,
|
||||
"no_interactive_failure": False,
|
||||
"interactive": True,
|
||||
"num_containers": 1,
|
||||
"branch": baseline["branch"],
|
||||
"commit_hash": baseline["commit_hash"],
|
||||
"mode": "selected",
|
||||
"show_splunk_app_password": True,
|
||||
}
|
||||
)
|
||||
with open(
|
||||
os.path.join(output_folder, failure_manifest_filename), "w"
|
||||
) as failures:
|
||||
validate_args.validate_and_write(failures_test_override, failures)
|
||||
except Exception as e:
|
||||
print(
|
||||
"There was an error generating [%s]: [%s]" % (output_filename, str(e)),
|
||||
file=sys.stderr,
|
||||
)
|
||||
print(data)
|
||||
raise (e)
|
||||
# success = False
|
||||
# return success, False
|
||||
|
||||
# note that total failures is fail_count, fail_and_error count is JUST errors (and every error is also a failure)
|
||||
return success, test_count, pass_count, fail_count, fail_and_error_count
|
||||
|
||||
|
||||
def calculate_pass_rate(pass_count: int, test_count: int) -> float:
|
||||
if test_count == 0:
|
||||
# Assume this means 100% pass rate to avoid divide by zero
|
||||
pass_rate = 1
|
||||
else:
|
||||
pass_rate = pass_count / test_count
|
||||
return pass_rate
|
||||
|
||||
|
||||
def print_summary(
|
||||
test_count: int, pass_count: int, fail_count: int, error_count: int
|
||||
) -> None:
|
||||
print(
|
||||
"Summary:"
|
||||
f"\n\tTotal Tests: {test_count}"
|
||||
f"\n\tTotal Pass : {pass_count}"
|
||||
f"\n\tTotal Fail : {fail_count} ({error_count} of these were ERRORS))"
|
||||
f"\n\tPass Rate : {calculate_pass_rate(pass_count, test_count):.3f}"
|
||||
)
|
||||
|
||||
|
||||
def exit_with_status(
|
||||
test_pass: bool, test_count: int, pass_count: int, fail_count: int, error_count: int
|
||||
) -> None:
|
||||
if not test_pass:
|
||||
print("Result: FAIL")
|
||||
# print("DURING TESTING, THIS WILL STILL EXIT WITH AN EXIT CODE OF 0 (SUCCESS) TO ALLOW THE WORKFLOW "
|
||||
# "TO PASS AND CI/CD TO CONTINUE. THIS WILL BE CHANGED IN A FUTURE VERSION.")
|
||||
# sys.exit(0)
|
||||
sys.exit(1)
|
||||
else:
|
||||
print("Result: PASS!")
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
def finish(
|
||||
test_pass: bool, test_count: int, pass_count: int, fail_count: int, error_count: int
|
||||
) -> None:
|
||||
print_summary(test_count, pass_count, fail_count, error_count)
|
||||
exit_with_status(test_pass, test_count, pass_count, fail_count, error_count)
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Results Merger")
|
||||
parser.add_argument(
|
||||
"-f",
|
||||
"--files",
|
||||
type=argparse.FileType("r"),
|
||||
required=True,
|
||||
nargs="+",
|
||||
help="The json files you would like to combine into a single file",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-o",
|
||||
"--output_filename",
|
||||
type=str,
|
||||
required=True,
|
||||
help="The name of the output file",
|
||||
)
|
||||
parser.add_argument("--smoketest", action=argparse.BooleanOptionalAction)
|
||||
args = parser.parse_args()
|
||||
|
||||
all_data = OrderedDict()
|
||||
try:
|
||||
print("We will summarize the files: %s" % (str([f.name for f in args.files])))
|
||||
for f in args.files:
|
||||
if not f.name.endswith(".json"):
|
||||
print(
|
||||
"Error: passed in file must end in .json - you passed in [%s].\n\tQuitting..."
|
||||
% (f.name)
|
||||
)
|
||||
sys.exit(1)
|
||||
data = json.loads(f.read())
|
||||
if "baseline" in all_data:
|
||||
# everything has the same baseline, only need to do it once
|
||||
pass
|
||||
else:
|
||||
all_data["baseline"] = data["baseline"]
|
||||
if "results" in all_data:
|
||||
# this is a list of dictionaries, so add to it
|
||||
all_data["results"].extend(data["results"])
|
||||
else:
|
||||
all_data["results"] = data["results"]
|
||||
|
||||
IGNORE_MESSAGES = [
|
||||
"Model does not exist", # model not generated by baseline
|
||||
"Data model 'Identity_Management' was not found", # missing datamodel included with es
|
||||
"get_asset", # missing macro included with es
|
||||
"Failed to load model", # when running a model that has not been downloaded separately
|
||||
"UEBA", # Another missing ES asset
|
||||
]
|
||||
if args.smoketest:
|
||||
new_results = []
|
||||
for result in all_data["results"]:
|
||||
if result.get("detection_error", None):
|
||||
message = result.get("detection_error", None)
|
||||
ignore = False
|
||||
for ignore_message in IGNORE_MESSAGES:
|
||||
if ignore_message in message:
|
||||
ignore = True
|
||||
break
|
||||
if not ignore:
|
||||
new_results.append(result)
|
||||
pass
|
||||
|
||||
all_data["results"] = new_results
|
||||
|
||||
test_pass, test_count, pass_count, fail_count, error_count = outputResultsJSON(
|
||||
args.output_filename, all_data["results"], all_data["baseline"]
|
||||
)
|
||||
finish(test_pass, test_count, pass_count, fail_count, error_count)
|
||||
|
||||
except Exception as e:
|
||||
print("Error generating the summary file: [%s].\n\tQuitting..." % (str(e)))
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,149 +0,0 @@
|
||||
{
|
||||
"apps": {
|
||||
"ADD_ON_FOR_LINUX_SYSMON": {
|
||||
"app_number": 6176,
|
||||
"app_version": "1.0.4",
|
||||
"http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/add-on-for-linux-sysmon_104.tgz"
|
||||
},
|
||||
"PALO_ALTO_NETWORKS_ADD_ON_FOR_SPLUNK": {
|
||||
"app_number": 2757,
|
||||
"app_version": "8.1.0",
|
||||
"http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/palo-alto-networks-add-on-for-splunk_810.tgz"
|
||||
},
|
||||
"SPLUNK_ADD_ON_FOR_AMAZON_KINESIS_FIREHOSE": {
|
||||
"app_number": 3719,
|
||||
"app_version": "1.3.2",
|
||||
"http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/splunk-add-on-for-amazon-kinesis-firehose_132.tgz"
|
||||
},
|
||||
"SPLUNK_ADD_ON_FOR_GOOGLE_CLOUD_PLATFORM": {
|
||||
"app_number": 3088,
|
||||
"app_version": "4.3.0",
|
||||
"http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/splunk-add-on-for-google-cloud-platform_430.tgz"
|
||||
},
|
||||
"SPLUNK_ADD_ON_FOR_GOOGLE_WORKSPACE": {
|
||||
"app_number": 3110,
|
||||
"app_version": "2.6.0",
|
||||
"http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/splunk-add-on-for-google-workspace_260.tgz"
|
||||
},
|
||||
"SPLUNK_ADD_ON_FOR_MICROSOFT_OFFICE_365": {
|
||||
"app_number": 4055,
|
||||
"app_version": "4.3.0",
|
||||
"http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/splunk-add-on-for-microsoft-office-365_430.tgz"
|
||||
},
|
||||
"SPLUNK_ADD_ON_FOR_MICROSOFT_WINDOWS": {
|
||||
"app_number": 742,
|
||||
"app_version": "8.8.0",
|
||||
"http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/splunk-add-on-for-microsoft-windows_880.tgz"
|
||||
},
|
||||
"SPLUNK_ADD_ON_FOR_NGINX": {
|
||||
"app_number": 3258,
|
||||
"app_version": "3.2.1",
|
||||
"http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/splunk-add-on-for-nginx_321.tgz"
|
||||
},
|
||||
"SPLUNK_ADD_ON_FOR_STREAM_FORWARDERS": {
|
||||
"app_number": 5238,
|
||||
"app_version": "8.1.1",
|
||||
"http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/splunk-add-on-for-stream-forwarders_811.tgz"
|
||||
},
|
||||
"SPLUNK_ADD_ON_FOR_STREAM_WIRE_DATA": {
|
||||
"app_number": 5234,
|
||||
"app_version": "8.1.1",
|
||||
"http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/splunk-add-on-for-stream-wire-data_811.tgz"
|
||||
},
|
||||
"SPLUNK_ADD_ON_FOR_SYSMON": {
|
||||
"app_number": 5709,
|
||||
"app_version": "3.1.0",
|
||||
"http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/splunk-add-on-for-sysmon_310.tgz"
|
||||
},
|
||||
"SPLUNK_ADD_ON_FOR_UNIX_AND_LINUX": {
|
||||
"app_number": 833,
|
||||
"app_version": "9.0.0",
|
||||
"http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/splunk-add-on-for-unix-and-linux_900.tgz"
|
||||
},
|
||||
"SPLUNK_COMMON_INFORMATION_MODEL": {
|
||||
"app_number": 1621,
|
||||
"app_version": "5.2.0",
|
||||
"http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/splunk-common-information-model-cim_520.tgz"
|
||||
},
|
||||
"SPLUNK_ES_CONTENT_UPDATE": {
|
||||
"app_number": 3449,
|
||||
"app_version": null,
|
||||
"local_path": null
|
||||
},
|
||||
"SPLUNK_MACHINE_LEARNING_TOOLKIT": {
|
||||
"app_number": 2890,
|
||||
"app_version": "5.4.1",
|
||||
"http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/splunk-machine-learning-toolkit_541.tgz"
|
||||
},
|
||||
"SPLUNK_TA_FIX_WINDOWS": {
|
||||
"app_number": 9999,
|
||||
"app_version": "1.0.0",
|
||||
"http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/Splunk_TA_fix_windows.tgz"
|
||||
},
|
||||
"SPLUNK_TA_FOR_IIS": {
|
||||
"app_number": 3185,
|
||||
"app_version": "1.2.0",
|
||||
"http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/splunk-add-on-for-microsoft-iis_120.tgz"
|
||||
},
|
||||
"SPLUNK_TA_FOR_SURICATA": {
|
||||
"app_number": 4242,
|
||||
"app_version": "2.3.4",
|
||||
"http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/ta-for-suricata_234.tgz"
|
||||
},
|
||||
"SPLUNK_TA_FOR_ZEEK": {
|
||||
"app_number": 5466,
|
||||
"app_version": "1.0.5",
|
||||
"http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/ta-for-zeek_105.tgz"
|
||||
},
|
||||
"SPLUNK_TA_MICROSOFT_CLOUD_SERVICES": {
|
||||
"app_number": 3110,
|
||||
"app_version": "5.2.1",
|
||||
"http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/splunk-add-on-for-microsoft-cloud-services_521.tgz"
|
||||
},
|
||||
"Splunk Add-on for CrowdStrike FDR": {
|
||||
"app_number": 5579,
|
||||
"app_version": "1.4.0",
|
||||
"http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/splunk-add-on-for-crowdstrike-fdr_140.tgz"
|
||||
},
|
||||
"URL_TOOLBOX": {
|
||||
"app_number": 2734,
|
||||
"app_version": "1.9.2",
|
||||
"http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/url-toolbox_192.tgz"
|
||||
},
|
||||
"Splunk_TA_okta_identity_cloud": {
|
||||
"app_number": 6553,
|
||||
"app_version": "2.1.0,",
|
||||
"http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/splunk-add-on-for-okta-identity-cloud_210.tgz"
|
||||
}
|
||||
},
|
||||
"branch": "BRANCH_DOES_NOT_EXIST_USE_CLI_ARGUMENT",
|
||||
"commit_hash": null,
|
||||
"container_tag": "latest",
|
||||
"detections_list": null,
|
||||
"folders": [
|
||||
"endpoint",
|
||||
"cloud",
|
||||
"network",
|
||||
"web",
|
||||
"application"
|
||||
],
|
||||
"interactive": false,
|
||||
"local_base_container_name": "splunk_test_%d",
|
||||
"mock": false,
|
||||
"mode": "changes",
|
||||
"no_interactive_failure": true,
|
||||
"num_containers": 10,
|
||||
"persist_security_content": false,
|
||||
"pr_number": null,
|
||||
"reuse_image": true,
|
||||
"show_splunk_app_password": false,
|
||||
"splunk_app_password": null,
|
||||
"splunk_container_apps_directory": "/opt/splunk/etc/apps",
|
||||
"splunkbase_password": null,
|
||||
"splunkbase_username": null,
|
||||
"types": [
|
||||
"Anomaly",
|
||||
"Hunting",
|
||||
"TTP"
|
||||
]
|
||||
}
|
||||
+1
-1
Submodule contentctl updated: cfd1e51e89...a169fee8d7
+1
-2
@@ -182,5 +182,4 @@ apps:
|
||||
version: 1.9.2
|
||||
description: description of app
|
||||
hardcoded_path: https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/Latest/url-toolbox_192.tgz
|
||||
githash: d6fac80e6d50ae06b40f91519a98489d4ce3a3fd
|
||||
|
||||
githash: d6fac80e6d50ae06b40f91519a98489d4ce3a3fd
|
||||
@@ -0,0 +1,38 @@
|
||||
name: PingID
|
||||
id: 17890675-61c1-40bd-a88e-6a8e9e246b43
|
||||
author: Patrick Bareiss, Splunk
|
||||
source: XmlWinEventLog:Security
|
||||
sourcetype: XmlWinEventLog
|
||||
separator: null
|
||||
supported_TA: {}
|
||||
event_names: []
|
||||
fields:
|
||||
- _time
|
||||
- actors{}.name
|
||||
- actors{}.type
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- extracted_source
|
||||
- host
|
||||
- id
|
||||
- index
|
||||
- linecount
|
||||
- punct
|
||||
- recorded
|
||||
- resources{}.ipaddress
|
||||
- resources{}.websession
|
||||
- result.message
|
||||
- result.status
|
||||
- source
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
example_log: '{"source":"PINGID","id":"b2eb1fef-651b-11ee-b38b-0ac7a554ed19","recorded":"2023-10-05T14:10:53.538Z","actors":[{"type":"user","name":"victim_user"}],"resources":[{"ipaddress":"174.235.80.142","websession":"webs_ijkF-T_bAC_G3w2TfvdpAEQeC545KFlqVFOsolCXdjo"}],"result":{"status":"SUCCESS","message":"Device
|
||||
Paired SMS \"Mobile 1\""}}'
|
||||
@@ -0,0 +1,34 @@
|
||||
name: Splunk
|
||||
id: d8a2c791-460b-4756-a8e5-ecade77b21e3
|
||||
author: Patrick Bareiss, Splunk
|
||||
source: splunkd_ui_access.log
|
||||
sourcetype: splunkd_ui_access
|
||||
separator: null
|
||||
supported_TA: {}
|
||||
event_names: []
|
||||
fields:
|
||||
- _time
|
||||
- action
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- dest
|
||||
- host
|
||||
- index
|
||||
- info
|
||||
- linecount
|
||||
- punct
|
||||
- source
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- timeendpos
|
||||
- timestamp
|
||||
- timestartpos
|
||||
- user
|
||||
example_log: 'Audit:[timestamp=01-25-2023 22:08:54.818, user=admin, action=search,
|
||||
info=granted REST: /search/jobs/rt_1674684525.24/events]'
|
||||
@@ -0,0 +1,27 @@
|
||||
name: Endpoint.Filesystem
|
||||
prefix: Filesystem
|
||||
fields:
|
||||
- action
|
||||
- dest
|
||||
- dest_bunit
|
||||
- dest_category
|
||||
- dest_priority
|
||||
- dest_requires_av
|
||||
- dest_should_timesync
|
||||
- dest_should_update
|
||||
- file_access_time
|
||||
- file_create_time
|
||||
- file_hash
|
||||
- file_modify_time
|
||||
- file_name
|
||||
- file_path
|
||||
- file_acl
|
||||
- file_size
|
||||
- process_guid
|
||||
- process_id
|
||||
- tag
|
||||
- user
|
||||
- user_bunit
|
||||
- user_category
|
||||
- user_priority
|
||||
- vendor_product
|
||||
@@ -0,0 +1,39 @@
|
||||
name: Endpoint.Processes
|
||||
prefix: Processes
|
||||
fields:
|
||||
- action
|
||||
- cpu_load_percent
|
||||
- dest
|
||||
- dest_bunit
|
||||
- dest_category
|
||||
- dest_is_expected
|
||||
- dest_priority
|
||||
- dest_requires_av
|
||||
- dest_should_timesync
|
||||
- dest_should_update
|
||||
- loaded_file
|
||||
- mem_used
|
||||
- original_file_name
|
||||
- os
|
||||
- parent_process
|
||||
- parent_process_exec
|
||||
- parent_process_id
|
||||
- parent_process_guid
|
||||
- parent_process_name
|
||||
- parent_process_path
|
||||
- process
|
||||
- process_current_directory
|
||||
- process_exec
|
||||
- process_hash
|
||||
- process_guid
|
||||
- process_id
|
||||
- process_integrity_level
|
||||
- process_name
|
||||
- process_path
|
||||
- tag
|
||||
- user
|
||||
- user_id
|
||||
- user_bunit
|
||||
- user_category
|
||||
- user_priority
|
||||
- vendor_product
|
||||
@@ -0,0 +1,27 @@
|
||||
name: Endpoint.Registry
|
||||
prefix: Registry
|
||||
fields:
|
||||
- action
|
||||
- dest
|
||||
- dest_bunit
|
||||
- dest_category
|
||||
- dest_priority
|
||||
- dest_requires_av
|
||||
- dest_should_timesync
|
||||
- dest_should_update
|
||||
- process_guid
|
||||
- process_id
|
||||
- registry_hive
|
||||
- registry_path
|
||||
- registry_key_name
|
||||
- registry_value_data
|
||||
- registry_value_name
|
||||
- registry_value_text
|
||||
- registry_value_type
|
||||
- status
|
||||
- tag
|
||||
- user
|
||||
- user_bunit
|
||||
- user_category
|
||||
- user_priority
|
||||
- vendor_product
|
||||
@@ -0,0 +1,35 @@
|
||||
name: Endpoint.Services
|
||||
prefix: Services
|
||||
fields:
|
||||
- description
|
||||
- dest
|
||||
- dest_bunit
|
||||
- dest_category
|
||||
- dest_is_expected
|
||||
- dest_priority
|
||||
- dest_requires_av
|
||||
- dest_should_timesync
|
||||
- dest_should_update
|
||||
- process_guid
|
||||
- process_id
|
||||
- service
|
||||
- service_dll
|
||||
- service_dll_path
|
||||
- service_dll_hash
|
||||
- service_dll_signature_exists
|
||||
- service_dll_signature_verified
|
||||
- service_exec
|
||||
- service_hash
|
||||
- service_id
|
||||
- service_name
|
||||
- service_path
|
||||
- service_signature_exists
|
||||
- service_signature_verified
|
||||
- start_mode
|
||||
- status
|
||||
- tag
|
||||
- user
|
||||
- user_bunit
|
||||
- user_category
|
||||
- user_priority
|
||||
- vendor_product
|
||||
@@ -0,0 +1,32 @@
|
||||
name: Network_Resolution.DNS
|
||||
prefix: DNS
|
||||
fields:
|
||||
- additional_answer_count
|
||||
- answer
|
||||
- answer_count
|
||||
- authority_answer_count
|
||||
- dest
|
||||
- dest_bunit
|
||||
- dest_category
|
||||
- dest_port
|
||||
- dest_priority
|
||||
- duration
|
||||
- message_type
|
||||
- name
|
||||
- query
|
||||
- query_count
|
||||
- query_type
|
||||
- record_type
|
||||
- reply_code
|
||||
- reply_code_id
|
||||
- response_time
|
||||
- src
|
||||
- src_bunit
|
||||
- src_category
|
||||
- src_port
|
||||
- src_priority
|
||||
- tag
|
||||
- transaction_id
|
||||
- transport
|
||||
- ttl
|
||||
- vendor_product
|
||||
@@ -0,0 +1,66 @@
|
||||
name: Network_Traffic.All_Traffic
|
||||
prefix: All_Traffic
|
||||
fields:
|
||||
- action
|
||||
- app
|
||||
- bytes
|
||||
- bytes_in
|
||||
- bytes_out
|
||||
- channel
|
||||
- dest
|
||||
- dest_bunit
|
||||
- dest_category
|
||||
- dest_interface
|
||||
- dest_ip
|
||||
- dest_mac
|
||||
- dest_port
|
||||
- dest_priority
|
||||
- dest_translated_ip
|
||||
- dest_translated_port
|
||||
- dest_zone
|
||||
- direction
|
||||
- duration
|
||||
- dvc
|
||||
- dvc_bunit
|
||||
- dvc_category
|
||||
- dvc_ip
|
||||
- dvc_mac
|
||||
- dvc_priority
|
||||
- dvc_zone
|
||||
- flow_id
|
||||
- icmp_code
|
||||
- icmp_type
|
||||
- packets
|
||||
- packets_in
|
||||
- packets_out
|
||||
- process_id
|
||||
- protocol
|
||||
- protocol_version
|
||||
- response_time
|
||||
- rule
|
||||
- session_id
|
||||
- src
|
||||
- src_bunit
|
||||
- src_category
|
||||
- src_interface
|
||||
- src_ip
|
||||
- src_mac
|
||||
- src_port
|
||||
- src_priority
|
||||
- src_translated_ip
|
||||
- src_translated_port
|
||||
- src_zone
|
||||
- ssid
|
||||
- tag
|
||||
- tcp_flag
|
||||
- transport
|
||||
- tos
|
||||
- ttl
|
||||
- user
|
||||
- user_bunit
|
||||
- user_category
|
||||
- user_priority
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
- vlan
|
||||
- wifi
|
||||
@@ -0,0 +1,41 @@
|
||||
name: Web.Web
|
||||
prefix: Web
|
||||
fields:
|
||||
- action
|
||||
- app
|
||||
- bytes
|
||||
- bytes_in
|
||||
- bytes_out
|
||||
- cached
|
||||
- category
|
||||
- cookie
|
||||
- dest
|
||||
- dest_bunit
|
||||
- dest_category
|
||||
- dest_priority
|
||||
- dest_port
|
||||
- duration
|
||||
- http_content_type
|
||||
- http_method
|
||||
- http_referrer
|
||||
- http_referrer_domain
|
||||
- http_user_agent
|
||||
- http_user_agent_length
|
||||
- response_time
|
||||
- site
|
||||
- src
|
||||
- src_bunit
|
||||
- src_category
|
||||
- src_priority
|
||||
- status
|
||||
- tag
|
||||
- uri_path
|
||||
- uri_query
|
||||
- url
|
||||
- url_domain
|
||||
- url_length
|
||||
- user
|
||||
- user_bunit
|
||||
- user_category
|
||||
- user_priority
|
||||
- vendor_product
|
||||
@@ -0,0 +1,229 @@
|
||||
name: AWS CloudTrail
|
||||
id: aa8d90bf-8ab1-4a9f-8c1b-24a67b1cd0b0
|
||||
author: Patrick Bareiss, Splunk
|
||||
source: aws_cloudtrail
|
||||
sourcetype: aws:cloudtrail
|
||||
separator: eventName
|
||||
supported_TA:
|
||||
name: Splunk Add-on for Amazon Web Services (AWS)
|
||||
version: 7.4.1
|
||||
url: https://splunkbase.splunk.com/app/1876
|
||||
event_names:
|
||||
- event_name: AWS CloudTrail
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail.yml
|
||||
- event_name: AWS CloudTrail AssumeRoleWithSAML
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_AssumeRoleWithSAML.yml
|
||||
- event_name: AWS CloudTrail ConsoleLogin
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_ConsoleLogin.yml
|
||||
- event_name: AWS CloudTrail CopyObject
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_CopyObject.yml
|
||||
- event_name: AWS CloudTrail CreateAccessKey
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_CreateAccessKey.yml
|
||||
- event_name: AWS CloudTrail CreateKey
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_CreateKey.yml
|
||||
- event_name: AWS CloudTrail CreateLoginProfile
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_CreateLoginProfile.yml
|
||||
- event_name: AWS CloudTrail CreateNetworkAclEntry
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_CreateNetworkAclEntry.yml
|
||||
- event_name: AWS CloudTrail CreatePolicyVersion
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_CreatePolicyVersion.yml
|
||||
- event_name: AWS CloudTrail CreateSnapshot
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_CreateSnapshot.yml
|
||||
- event_name: AWS CloudTrail CreateTask
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_CreateTask.yml
|
||||
- event_name: AWS CloudTrail CreateVirtualMFADevice
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_CreateVirtualMFADevice.yml
|
||||
- event_name: AWS CloudTrail DeactivateMFADevice
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_DeactivateMFADevice.yml
|
||||
- event_name: AWS CloudTrail DeleteAccountPasswordPolicy
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_DeleteAccountPasswordPolicy.yml
|
||||
- event_name: AWS CloudTrail DeleteAlarms
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_DeleteAlarms.yml
|
||||
- event_name: AWS CloudTrail DeleteDetector
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_DeleteDetector.yml
|
||||
- event_name: AWS CloudTrail DeleteGroup
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_DeleteGroup.yml
|
||||
- event_name: AWS CloudTrail DeleteIPSet
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_DeleteIPSet.yml
|
||||
- event_name: AWS CloudTrail DeleteLogGroup
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_DeleteLogGroup.yml
|
||||
- event_name: AWS CloudTrail DeleteLogStream
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_DeleteLogStream.yml
|
||||
- event_name: AWS CloudTrail DeleteLoggingConfiguration
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_DeleteLoggingConfiguration.yml
|
||||
- event_name: AWS CloudTrail DeleteNetworkAclEntry
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_DeleteNetworkAclEntry.yml
|
||||
- event_name: AWS CloudTrail DeletePolicy
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_DeletePolicy.yml
|
||||
- event_name: AWS CloudTrail DeleteRule
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_DeleteRule.yml
|
||||
- event_name: AWS CloudTrail DeleteRuleGroup
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_DeleteRuleGroup.yml
|
||||
- event_name: AWS CloudTrail DeleteSnapshot
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_DeleteSnapshot.yml
|
||||
- event_name: AWS CloudTrail DeleteTrail
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_DeleteTrail.yml
|
||||
- event_name: AWS CloudTrail DeleteVirtualMFADevice
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_DeleteVirtualMFADevice.yml
|
||||
- event_name: AWS CloudTrail DeleteWebACL
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_DeleteWebACL.yml
|
||||
- event_name: AWS CloudTrail DescribeEventAggregates
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_DescribeEventAggregates.yml
|
||||
- event_name: AWS CloudTrail DescribeImageScanFindings
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_DescribeImageScanFindings.yml
|
||||
- event_name: AWS CloudTrail DescribeSnapshotAttribute
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_DescribeSnapshotAttribute.yml
|
||||
- event_name: AWS CloudTrail GetAccountPasswordPolicy
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_GetAccountPasswordPolicy.yml
|
||||
- event_name: AWS CloudTrail GetObject
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_GetObject.yml
|
||||
- event_name: AWS CloudTrail GetPasswordData
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_GetPasswordData.yml
|
||||
- event_name: AWS CloudTrail JobCreated
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_JobCreated.yml
|
||||
- event_name: AWS CloudTrail ModifyDBInstance
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_ModifyDBInstance.yml
|
||||
- event_name: AWS CloudTrail ModifyImageAttribute
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_ModifyImageAttribute.yml
|
||||
- event_name: AWS CloudTrail ModifySnapshotAttribute
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_ModifySnapshotAttribute.yml
|
||||
- event_name: AWS CloudTrail PutBucketAcl
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_PutBucketAcl.yml
|
||||
- event_name: AWS CloudTrail PutBucketLifecycle
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_PutBucketLifecycle.yml
|
||||
- event_name: AWS CloudTrail PutBucketReplication
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_PutBucketReplication.yml
|
||||
- event_name: AWS CloudTrail PutBucketVersioning
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_PutBucketVersioning.yml
|
||||
- event_name: AWS CloudTrail PutImage
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_PutImage.yml
|
||||
- event_name: AWS CloudTrail PutKeyPolicy
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_PutKeyPolicy.yml
|
||||
- event_name: AWS CloudTrail ReplaceNetworkAclEntry
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_ReplaceNetworkAclEntry.yml
|
||||
- event_name: AWS CloudTrail SetDefaultPolicyVersion
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_SetDefaultPolicyVersion.yml
|
||||
- event_name: AWS CloudTrail StopLogging
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_StopLogging.yml
|
||||
- event_name: AWS CloudTrail UpdateAccountPasswordPolicy
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_UpdateAccountPasswordPolicy.yml
|
||||
- event_name: AWS CloudTrail UpdateLoginProfile
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_UpdateLoginProfile.yml
|
||||
- event_name: AWS CloudTrail UpdateSAMLProvider
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_UpdateSAMLProvider.yml
|
||||
- event_name: AWS CloudTrail UpdateTrail
|
||||
data_source: data_sources/cloud/event_sources/AWS_CloudTrail_UpdateTrail.yml
|
||||
fields:
|
||||
- _time
|
||||
- action
|
||||
- app
|
||||
- awsRegion
|
||||
- aws_account_id
|
||||
- change_type
|
||||
- command
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- dest
|
||||
- direction
|
||||
- dvc
|
||||
- errorCode
|
||||
- eventCategory
|
||||
- eventID
|
||||
- eventName
|
||||
- eventSource
|
||||
- eventTime
|
||||
- eventType
|
||||
- eventVersion
|
||||
- eventtype
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- managementEvent
|
||||
- msg
|
||||
- object
|
||||
- object_category
|
||||
- object_id
|
||||
- product
|
||||
- protocol
|
||||
- punct
|
||||
- readOnly
|
||||
- recipientAccountId
|
||||
- region
|
||||
- requestID
|
||||
- requestParameters.groupId
|
||||
- requestParameters.ipPermissions.items{}.fromPort
|
||||
- requestParameters.ipPermissions.items{}.ipProtocol
|
||||
- requestParameters.ipPermissions.items{}.ipRanges.items{}.cidrIp
|
||||
- requestParameters.ipPermissions.items{}.toPort
|
||||
- responseElements._return
|
||||
- responseElements.requestId
|
||||
- responseElements.securityGroupRuleSet.items{}.cidrIpv4
|
||||
- responseElements.securityGroupRuleSet.items{}.fromPort
|
||||
- responseElements.securityGroupRuleSet.items{}.groupId
|
||||
- responseElements.securityGroupRuleSet.items{}.groupOwnerId
|
||||
- responseElements.securityGroupRuleSet.items{}.ipProtocol
|
||||
- responseElements.securityGroupRuleSet.items{}.isEgress
|
||||
- responseElements.securityGroupRuleSet.items{}.securityGroupRuleId
|
||||
- responseElements.securityGroupRuleSet.items{}.toPort
|
||||
- signature
|
||||
- source
|
||||
- sourceIPAddress
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src
|
||||
- src_ip
|
||||
- src_ip_range
|
||||
- src_port_range
|
||||
- start_time
|
||||
- status
|
||||
- tag
|
||||
- tag::eventtype
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- tlsDetails.cipherSuite
|
||||
- tlsDetails.clientProvidedHostHeader
|
||||
- tlsDetails.tlsVersion
|
||||
- user
|
||||
- userAgent
|
||||
- userIdentity.accessKeyId
|
||||
- userIdentity.accountId
|
||||
- userIdentity.arn
|
||||
- userIdentity.principalId
|
||||
- userIdentity.type
|
||||
- userIdentity.userName
|
||||
- userName
|
||||
- user_access_key
|
||||
- user_agent
|
||||
- user_arn
|
||||
- user_group_id
|
||||
- user_id
|
||||
- user_name
|
||||
- user_type
|
||||
- vendor
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
- vendor_region
|
||||
example_log: '{"eventVersion": "1.09", "userIdentity": {"type": "IAMUser", "principalId":
|
||||
"AIDAAAAAAAAAAAAAAAAAA", "arn": "arn:aws:iam::111111111111:user/daftpunk_cli", "accountId":
|
||||
"111111111111", "accessKeyId": "AKIAAAAAAAAAAAAAAAAA", "userName": "daftpunk_cli"},
|
||||
"eventTime": "2024-02-21T19:19:40Z", "eventSource": "ec2.amazonaws.com", "eventName":
|
||||
"AuthorizeSecurityGroupIngress", "awsRegion": "us-west-2", "sourceIPAddress": "2.2.2.2",
|
||||
"userAgent": "aws-cli/2.13.22 Python/3.11.5 Darwin/22.5.0 source/arm64 prompt/off
|
||||
command/ec2.authorize-security-group-ingress", "requestParameters": {"groupId":
|
||||
"sg-07ffb1896dcd3713e", "ipPermissions": {"items": [{"ipProtocol": "-1", "fromPort":
|
||||
-1, "toPort": -1, "groups": {}, "ipRanges": {"items": [{"cidrIp": "0.0.0.0/0"}]},
|
||||
"ipv6Ranges": {}, "prefixListIds": {}}]}}, "responseElements": {"requestId": "4950930b-2129-423c-95b0-1b87c8fa115a",
|
||||
"_return": true, "securityGroupRuleSet": {"items": [{"groupOwnerId": "111111111111",
|
||||
"groupId": "sg-07ffb1896dcd3713e", "securityGroupRuleId": "sgr-0217c1b508cc6b76c",
|
||||
"isEgress": false, "ipProtocol": "-1", "fromPort": -1, "toPort": -1, "cidrIpv4":
|
||||
"0.0.0.0/0"}]}}, "requestID": "4950930b-2129-423c-95b0-1b87c8fa115a", "eventID":
|
||||
"bdade96f-6272-468a-b084-413b9711e92f", "readOnly": false, "eventType": "AwsApiCall",
|
||||
"managementEvent": true, "recipientAccountId": "111111111111", "eventCategory":
|
||||
"Management", "tlsDetails": {"tlsVersion": "TLSv1.3", "cipherSuite": "TLS_AES_128_GCM_SHA256",
|
||||
"clientProvidedHostHeader": "ec2.us-west-2.amazonaws.com"}}'
|
||||
@@ -0,0 +1,122 @@
|
||||
name: AWS Security Hub
|
||||
id: b02bfbf3-294f-478e-99a1-e24b8c692d7e
|
||||
author: Patrick Bareiss, Splunk
|
||||
source: aws_securityhub_finding
|
||||
sourcetype: aws:securityhub:finding
|
||||
separator: null
|
||||
supported_TA:
|
||||
name: Splunk Add-on for Amazon Web Services (AWS)
|
||||
version: 7.4.1
|
||||
url: https://splunkbase.splunk.com/app/1876
|
||||
event_names: []
|
||||
fields:
|
||||
- _time
|
||||
- AwsAccountId
|
||||
- CreatedAt
|
||||
- Description
|
||||
- FirstObservedAt
|
||||
- GeneratorId
|
||||
- Id
|
||||
- LastObservedAt
|
||||
- ProductArn
|
||||
- ProductFields.aws/guardduty/service/action/actionType
|
||||
- ProductFields.aws/guardduty/service/action/awsApiCallAction/affectedResources/AWS::S3::Bucket
|
||||
- ProductFields.aws/guardduty/service/action/awsApiCallAction/api
|
||||
- ProductFields.aws/guardduty/service/action/awsApiCallAction/callerType
|
||||
- ProductFields.aws/guardduty/service/action/awsApiCallAction/remoteIpDetails/city/cityName
|
||||
- ProductFields.aws/guardduty/service/action/awsApiCallAction/remoteIpDetails/country/countryName
|
||||
- ProductFields.aws/guardduty/service/action/awsApiCallAction/remoteIpDetails/geoLocation/lat
|
||||
- ProductFields.aws/guardduty/service/action/awsApiCallAction/remoteIpDetails/geoLocation/lon
|
||||
- ProductFields.aws/guardduty/service/action/awsApiCallAction/remoteIpDetails/ipAddressV4
|
||||
- ProductFields.aws/guardduty/service/action/awsApiCallAction/remoteIpDetails/organization/asn
|
||||
- ProductFields.aws/guardduty/service/action/awsApiCallAction/remoteIpDetails/organization/asnOrg
|
||||
- ProductFields.aws/guardduty/service/action/awsApiCallAction/remoteIpDetails/organization/isp
|
||||
- ProductFields.aws/guardduty/service/action/awsApiCallAction/remoteIpDetails/organization/org
|
||||
- ProductFields.aws/guardduty/service/action/awsApiCallAction/serviceName
|
||||
- ProductFields.aws/guardduty/service/additionalInfo/sample
|
||||
- ProductFields.aws/guardduty/service/additionalInfo/unusual/hoursOfDay.0_
|
||||
- ProductFields.aws/guardduty/service/additionalInfo/unusual/userNames.0_
|
||||
- ProductFields.aws/guardduty/service/archived
|
||||
- ProductFields.aws/guardduty/service/count
|
||||
- ProductFields.aws/guardduty/service/detectorId
|
||||
- ProductFields.aws/guardduty/service/eventFirstSeen
|
||||
- ProductFields.aws/guardduty/service/eventLastSeen
|
||||
- ProductFields.aws/guardduty/service/resourceRole
|
||||
- ProductFields.aws/guardduty/service/serviceName
|
||||
- ProductFields.aws/securityhub/CompanyName
|
||||
- ProductFields.aws/securityhub/FindingId
|
||||
- ProductFields.aws/securityhub/ProductName
|
||||
- RecordState
|
||||
- Resources{}.Details.AwsEc2Instance.IamInstanceProfileArn
|
||||
- Resources{}.Details.AwsEc2Instance.ImageId
|
||||
- Resources{}.Details.AwsEc2Instance.IpV4Addresses{}
|
||||
- Resources{}.Details.AwsEc2Instance.LaunchedAt
|
||||
- Resources{}.Details.AwsEc2Instance.SubnetId
|
||||
- Resources{}.Details.AwsEc2Instance.Type
|
||||
- Resources{}.Details.AwsEc2Instance.VpcId
|
||||
- Resources{}.Details.AwsIamAccessKey.PrincipalId
|
||||
- Resources{}.Details.AwsIamAccessKey.PrincipalName
|
||||
- Resources{}.Details.AwsIamAccessKey.PrincipalType
|
||||
- Resources{}.Details.AwsS3Bucket.CreatedAt
|
||||
- Resources{}.Details.AwsS3Bucket.OwnerId
|
||||
- Resources{}.Details.AwsS3Bucket.ServerSideEncryptionConfiguration.Rules{}.ApplyServerSideEncryptionByDefault.KMSMasterKeyID
|
||||
- Resources{}.Details.AwsS3Bucket.ServerSideEncryptionConfiguration.Rules{}.ApplyServerSideEncryptionByDefault.SSEAlgorithm
|
||||
- Resources{}.Id
|
||||
- Resources{}.Partition
|
||||
- Resources{}.Region
|
||||
- Resources{}.Tags.GeneratedFindingInstaceTag1
|
||||
- Resources{}.Tags.GeneratedFindingInstaceTag2
|
||||
- Resources{}.Tags.GeneratedFindingInstaceTag3
|
||||
- Resources{}.Tags.GeneratedFindingInstaceTag4
|
||||
- Resources{}.Tags.GeneratedFindingInstaceTag5
|
||||
- Resources{}.Tags.GeneratedFindingInstaceTag6
|
||||
- Resources{}.Tags.GeneratedFindingInstaceTag7
|
||||
- Resources{}.Tags.GeneratedFindingInstaceTag8
|
||||
- Resources{}.Tags.GeneratedFindingInstaceTag9
|
||||
- Resources{}.Tags.foo
|
||||
- Resources{}.Type
|
||||
- SchemaVersion
|
||||
- Severity.Label
|
||||
- Severity.Normalized
|
||||
- Severity.Product
|
||||
- SourceUrl
|
||||
- Title
|
||||
- Types{}
|
||||
- UpdatedAt
|
||||
- Workflow.Status
|
||||
- WorkflowState
|
||||
- accesskey_extract
|
||||
- app
|
||||
- body
|
||||
- description
|
||||
- dest
|
||||
- dest_type
|
||||
- eventtype
|
||||
- host
|
||||
- id
|
||||
- index
|
||||
- instance_extract
|
||||
- linecount
|
||||
- punct
|
||||
- s3bucket_extract
|
||||
- severity
|
||||
- severity_id
|
||||
- signature
|
||||
- signature_id
|
||||
- source
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- subject
|
||||
- tag
|
||||
- tag::eventtype
|
||||
- timestamp
|
||||
- type
|
||||
- vendor_account
|
||||
- vendor_region
|
||||
example_log: '{"ProductArn":"arn:aws:securityhub:us-east-1::product/aws/guardduty","Types":["Software
|
||||
and Configuration Checks/Exfiltration:S3.ObjectRead.Unusual"],"SourceUrl":"https://us-east-1.console.aws.amazon.com/guardduty/home?region=us-east-1#/findings?macros=current&fId=6aba6b696aea10606e8b336f68d98819","Description":"Principal
|
||||
GeneratedFindingUserName read objects from S3 bucket GeneratedFindingS3Bucket in
|
||||
an unusual way.","SchemaVersion":"2018-10-08","GeneratorId":"arn:aws:guardduty:us-east-1:802684071507:detector/48ba636359b884eb132865311fdeb317","FirstObservedAt":"2020-09-28T22:26:15.636Z","CreatedAt":"2020-09-28T22:26:15.636Z","RecordState":"ACTIVE","Title":"Unusual
|
||||
reads of objects in S3 bucket GeneratedFindingS3Bucket.","Workflow":{"Status":"NEW"},"LastObservedAt":"2020-09-28T22:26:15.636Z","Severity":{"Normalized":20,"Label":"LOW","Product":2},"UpdatedAt":"2020-09-28T22:26:15.636Z","WorkflowState":"NEW","ProductFields":{"aws/guardduty/service/archived":"false","aws/guardduty/service/action/awsApiCallAction/remoteIpDetails/organization/asnOrg":"GeneratedFindingASNOrg","aws/guardduty/service/additionalInfo/unusual/userNames.0_":"GeneratedFindingUserName","aws/guardduty/service/action/awsApiCallAction/remoteIpDetails/organization/org":"GeneratedFindingORG","aws/guardduty/service/resourceRole":"TARGET","aws/guardduty/service/action/awsApiCallAction/remoteIpDetails/organization/isp":"GeneratedFindingISP","aws/guardduty/service/action/awsApiCallAction/remoteIpDetails/geoLocation/lat":"0","aws/guardduty/service/count":"1","aws/guardduty/service/action/awsApiCallAction/remoteIpDetails/ipAddressV4":"198.51.100.0","aws/guardduty/service/additionalInfo/sample":"true","aws/guardduty/service/action/awsApiCallAction/remoteIpDetails/country/countryName":"GeneratedFindingCountryName","aws/guardduty/service/action/awsApiCallAction/callerType":"Remote
|
||||
IP","aws/guardduty/service/action/awsApiCallAction/serviceName":"GeneratedFindingAPIServiceName","aws/guardduty/service/action/awsApiCallAction/remoteIpDetails/city/cityName":"GeneratedFindingCityName","aws/guardduty/service/action/awsApiCallAction/api":"GeneratedFindingAPIName","aws/guardduty/service/serviceName":"guardduty","aws/guardduty/service/action/awsApiCallAction/remoteIpDetails/geoLocation/lon":"0","aws/guardduty/service/detectorId":"48ba636359b884eb132865311fdeb317","aws/guardduty/service/action/awsApiCallAction/remoteIpDetails/organization/asn":"-1","aws/guardduty/service/eventFirstSeen":"2020-09-28T22:26:15.636Z","aws/guardduty/service/action/awsApiCallAction/affectedResources/AWS::S3::Bucket":"GeneratedFindingS3Bucket","aws/guardduty/service/eventLastSeen":"2020-09-28T22:26:15.636Z","aws/guardduty/service/additionalInfo/unusual/hoursOfDay.0_":"1513609200000","aws/guardduty/service/action/actionType":"AWS_API_CALL","aws/securityhub/FindingId":"arn:aws:securityhub:us-east-1::product/aws/guardduty/arn:aws:guardduty:us-east-1:802684071507:detector/48ba636359b884eb132865311fdeb317/finding/6aba6b696aea10606e8b336f68d98819","aws/securityhub/ProductName":"GuardDuty","aws/securityhub/CompanyName":"Amazon"},"AwsAccountId":"802684071507","Id":"arn:aws:guardduty:us-east-1:802684071507:detector/48ba636359b884eb132865311fdeb317/finding/6aba6b696aea10606e8b336f68d98819","Resources":[{"Partition":"aws","Type":"AwsEc2Instance","Details":{"AwsEc2Instance":{"Type":"m3.xlarge","VpcId":"GeneratedFindingVPCId","ImageId":"ami-99999999","IpV4Addresses":["10.0.0.1","198.51.100.0"],"SubnetId":"GeneratedFindingSubnetId","LaunchedAt":"2016-08-02T02:05:06Z","IamInstanceProfileArn":"arn:aws:iam::802684071507:example/instance/profile"}},"Region":"us-east-1","Id":"arn:aws:ec2:us-east-1:802684071507:instance/i-99999999","Tags":{"GeneratedFindingInstaceTag7":"GeneratedFindingInstaceTagValue7","GeneratedFindingInstaceTag8":"GeneratedFindingInstaceTagValue8","GeneratedFindingInstaceTag9":"GeneratedFindingInstaceTagValue9","GeneratedFindingInstaceTag1":"GeneratedFindingInstaceValue1","GeneratedFindingInstaceTag2":"GeneratedFindingInstaceTagValue2","GeneratedFindingInstaceTag3":"GeneratedFindingInstaceTagValue3","GeneratedFindingInstaceTag4":"GeneratedFindingInstaceTagValue4","GeneratedFindingInstaceTag5":"GeneratedFindingInstaceTagValue5","GeneratedFindingInstaceTag6":"GeneratedFindingInstaceTagValue6"}},{"Partition":"aws","Type":"AwsIamAccessKey","Details":{"AwsIamAccessKey":{"PrincipalId":"GeneratedFindingPrincipalId","PrincipalName":"GeneratedFindingUserName","PrincipalType":"IAMUser"}},"Region":"us-east-1","Id":"AWS::IAM::AccessKey:GeneratedFindingAccessKeyId"},{"Partition":"aws","Type":"AwsS3Bucket","Details":{"AwsS3Bucket":{"OwnerId":"CanonicalId
|
||||
of Owner","CreatedAt":"2017-12-18T15:58:11.551Z","ServerSideEncryptionConfiguration":{"Rules":[{"ApplyServerSideEncryptionByDefault":{"SSEAlgorithm":"SSEAlgorithm","KMSMasterKeyID":"arn:aws:kms:region:123456789012:key/key-id"}}]}}},"Region":"us-east-1","Id":"arn:aws:s3:::bucketName","Tags":{"foo":"bar"}}]}'
|
||||
@@ -0,0 +1,180 @@
|
||||
name: Azure Active Directory
|
||||
id: 7c12d2b2-2679-4806-b258-c17eaffbc66d
|
||||
author: Patrick Bareiss, Splunk
|
||||
source: Azure AD
|
||||
sourcetype: azure:monitor:aad
|
||||
separator: operationName
|
||||
supported_TA:
|
||||
name: Splunk Add-on for Microsoft Cloud Services
|
||||
version: 5.2.2
|
||||
url: https://splunkbase.splunk.com/app/3110
|
||||
event_names:
|
||||
- event_name: Azure Active Directory
|
||||
data_source: data_sources/cloud/event_sources/Azure_Active_Directory.yml
|
||||
- event_name: Azure Active Directory Add app role assignment to service principal
|
||||
data_source: data_sources/cloud/event_sources/Azure_Active_Directory_Add_app_role_assignment_to_service_principal.yml
|
||||
- event_name: Azure Active Directory Add member to role
|
||||
data_source: data_sources/cloud/event_sources/Azure_Active_Directory_Add_member_to_role.yml
|
||||
- event_name: Azure Active Directory Add owner to application
|
||||
data_source: data_sources/cloud/event_sources/Azure_Active_Directory_Add_owner_to_application.yml
|
||||
- event_name: Azure Active Directory Add service principal
|
||||
data_source: data_sources/cloud/event_sources/Azure_Active_Directory_Add_service_principal.yml
|
||||
- event_name: Azure Active Directory Add unverified domain
|
||||
data_source: data_sources/cloud/event_sources/Azure_Active_Directory_Add_unverified_domain.yml
|
||||
- event_name: Azure Active Directory Consent to application
|
||||
data_source: data_sources/cloud/event_sources/Azure_Active_Directory_Consent_to_application.yml
|
||||
- event_name: Azure Active Directory Disable Strong Authentication
|
||||
data_source: data_sources/cloud/event_sources/Azure_Active_Directory_Disable_Strong_Authentication.yml
|
||||
- event_name: Azure Active Directory Enable account
|
||||
data_source: data_sources/cloud/event_sources/Azure_Active_Directory_Enable_account.yml
|
||||
- event_name: Azure Active Directory Invite external user
|
||||
data_source: data_sources/cloud/event_sources/Azure_Active_Directory_Invite_external_user.yml
|
||||
- event_name: Azure Active Directory Reset password (by admin)
|
||||
data_source: data_sources/cloud/event_sources/Azure_Active_Directory_Reset_password_(by_admin).yml
|
||||
- event_name: Azure Active Directory Set domain authentication
|
||||
data_source: data_sources/cloud/event_sources/Azure_Active_Directory_Set_domain_authentication.yml
|
||||
- event_name: Azure Active Directory Sign-in activity
|
||||
data_source: data_sources/cloud/event_sources/Azure_Active_Directory_Sign-in_activity.yml
|
||||
- event_name: Azure Active Directory Update application
|
||||
data_source: data_sources/cloud/event_sources/Azure_Active_Directory_Update_application.yml
|
||||
- event_name: Azure Active Directory Update authorization policy
|
||||
data_source: data_sources/cloud/event_sources/Azure_Active_Directory_Update_authorization_policy.yml
|
||||
- event_name: Azure Active Directory Update user
|
||||
data_source: data_sources/cloud/event_sources/Azure_Active_Directory_Update_user.yml
|
||||
- event_name: Azure Active Directory User registered security info
|
||||
data_source: data_sources/cloud/event_sources/Azure_Active_Directory_User_registered_security_info.yml
|
||||
fields:
|
||||
- _time
|
||||
- Level
|
||||
- callerIpAddress
|
||||
- category
|
||||
- correlationId
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- durationMs
|
||||
- host
|
||||
- identity
|
||||
- index
|
||||
- linecount
|
||||
- location
|
||||
- operationName
|
||||
- operationVersion
|
||||
- properties.alternateSignInName
|
||||
- properties.appDisplayName
|
||||
- properties.appId
|
||||
- properties.appServicePrincipalId
|
||||
- properties.authenticationDetails{}.RequestSequence
|
||||
- properties.authenticationDetails{}.StatusSequence
|
||||
- properties.authenticationDetails{}.authenticationMethod
|
||||
- properties.authenticationDetails{}.authenticationMethodDetail
|
||||
- properties.authenticationDetails{}.authenticationStepDateTime
|
||||
- properties.authenticationDetails{}.authenticationStepRequirement
|
||||
- properties.authenticationDetails{}.authenticationStepResultDetail
|
||||
- properties.authenticationDetails{}.succeeded
|
||||
- properties.authenticationProcessingDetails{}.key
|
||||
- properties.authenticationProcessingDetails{}.value
|
||||
- properties.authenticationProtocol
|
||||
- properties.authenticationRequirement
|
||||
- properties.autonomousSystemNumber
|
||||
- properties.clientAppUsed
|
||||
- properties.clientCredentialType
|
||||
- properties.conditionalAccessStatus
|
||||
- properties.correlationId
|
||||
- properties.createdDateTime
|
||||
- properties.crossTenantAccessType
|
||||
- properties.deviceDetail.deviceId
|
||||
- properties.deviceDetail.operatingSystem
|
||||
- properties.flaggedForReview
|
||||
- properties.homeTenantId
|
||||
- properties.id
|
||||
- properties.incomingTokenType
|
||||
- properties.ipAddress
|
||||
- properties.isInteractive
|
||||
- properties.isTenantRestricted
|
||||
- properties.location.city
|
||||
- properties.location.countryOrRegion
|
||||
- properties.location.geoCoordinates.latitude
|
||||
- properties.location.geoCoordinates.longitude
|
||||
- properties.location.state
|
||||
- properties.originalRequestId
|
||||
- properties.processingTimeInMilliseconds
|
||||
- properties.resourceDisplayName
|
||||
- properties.resourceId
|
||||
- properties.resourceServicePrincipalId
|
||||
- properties.resourceTenantId
|
||||
- properties.riskDetail
|
||||
- properties.riskLevelAggregated
|
||||
- properties.riskLevelDuringSignIn
|
||||
- properties.riskState
|
||||
- properties.rngcStatus
|
||||
- properties.servicePrincipalId
|
||||
- properties.signInIdentifier
|
||||
- properties.ssoExtensionVersion
|
||||
- properties.status.errorCode
|
||||
- properties.status.failureReason
|
||||
- properties.tokenIssuerName
|
||||
- properties.tokenIssuerType
|
||||
- properties.uniqueTokenIdentifier
|
||||
- properties.userAgent
|
||||
- properties.userDisplayName
|
||||
- properties.userId
|
||||
- properties.userPrincipalName
|
||||
- properties.userType
|
||||
- punct
|
||||
- resourceId
|
||||
- resultDescription
|
||||
- resultSignature
|
||||
- resultType
|
||||
- source
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- tenantId
|
||||
- time
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
example_log: '{"time": "2023-01-23T21:29:14.1490728Z", "resourceId": "/tenants/fc69e276-e9e8-4af9-9002-1e410d77244e/providers/Microsoft.aadiam",
|
||||
"operationName": "Sign-in activity", "operationVersion": "1.0", "category": "SignInLogs",
|
||||
"tenantId": "fc69e276-e9e8-4af9-9002-1e410d77244e", "resultType": "50126", "resultSignature":
|
||||
"None", "resultDescription": "Invalid username or password or Invalid on-premise
|
||||
username or password.", "durationMs": 0, "callerIpAddress": "35.80.10.10", "correlationId":
|
||||
"1634ad3a-1f98-4964-add5-92fc58621944", "identity": "User30", "Level": 4, "location":
|
||||
"US", "properties": {"id": "13148568-d61e-45eb-b38b-1fa63c106d00", "createdDateTime":
|
||||
"2023-01-23T21:29:14.1490728+00:00", "userDisplayName": "User30", "userPrincipalName":
|
||||
"user30@splunkresearch.com", "userId": "40b61050-e814-4ae5-8ffe-66b6f0c53998", "appId":
|
||||
"1b730954-1685-4b74-9bfd-dac224a7b894", "appDisplayName": "Azure Active Directory
|
||||
PowerShell", "ipAddress": "35.80.10.10", "status": {"errorCode": 50126, "failureReason":
|
||||
"Invalid username or password or Invalid on-premise username or password."}, "clientAppUsed":
|
||||
"Mobile Apps and Desktop clients", "userAgent": "Mozilla/5.0 (Windows NT; Windows
|
||||
NT 10.0; en-US) WindowsPowerShell/5.1.14393.5127", "deviceDetail": {"deviceId":
|
||||
"", "operatingSystem": "Windows 10"}, "location": {"city": "Boardman", "state":
|
||||
"Oregon", "countryOrRegion": "US", "geoCoordinates": {"latitude": 45.83599853515625,
|
||||
"longitude": -119.6989974975586}}, "correlationId": "1634ad3a-1f98-4964-add5-92fc58621944",
|
||||
"conditionalAccessStatus": "notApplied", "appliedConditionalAccessPolicies": [],
|
||||
"authenticationContextClassReferences": [], "originalRequestId": "13148568-d61e-45eb-b38b-1fa63c106d00",
|
||||
"isInteractive": true, "tokenIssuerName": "", "tokenIssuerType": "AzureAD", "authenticationProcessingDetails":
|
||||
[{"key": "Legacy TLS (TLS 1.0, 1.1, 3DES)", "value": "False"}, {"key": "Is CAE Token",
|
||||
"value": "False"}], "networkLocationDetails": [], "clientCredentialType": "none",
|
||||
"processingTimeInMilliseconds": 47, "riskDetail": "none", "riskLevelAggregated":
|
||||
"none", "riskLevelDuringSignIn": "none", "riskState": "none", "riskEventTypes":
|
||||
[], "riskEventTypes_v2": [], "resourceDisplayName": "Windows Azure Active Directory",
|
||||
"resourceId": "00000002-0000-0000-c000-000000000000", "resourceTenantId": "fc69e276-e9e8-4af9-9002-1e410d77244e",
|
||||
"homeTenantId": "fc69e276-e9e8-4af9-9002-1e410d77244e", "authenticationDetails":
|
||||
[{"authenticationStepDateTime": "2023-01-23T21:29:14.1490728+00:00", "authenticationMethod":
|
||||
"Password", "authenticationMethodDetail": "Password in the cloud", "succeeded":
|
||||
false, "authenticationStepResultDetail": "Invalid username or password or Invalid
|
||||
on-premise username or password.", "authenticationStepRequirement": "Primary authentication",
|
||||
"StatusSequence": 0, "RequestSequence": 1}], "authenticationRequirementPolicies":
|
||||
[], "authenticationRequirement": "singleFactorAuthentication", "alternateSignInName":
|
||||
"user30@splunkresearch.com", "signInIdentifier": "user30@splunkresearch.com", "servicePrincipalId":
|
||||
"", "userType": "Member", "flaggedForReview": false, "isTenantRestricted": false,
|
||||
"autonomousSystemNumber": 16509, "crossTenantAccessType": "none", "privateLinkDetails":
|
||||
{}, "ssoExtensionVersion": "", "uniqueTokenIdentifier": "aIUUEx7W60Wzix-mPBBtAA",
|
||||
"authenticationStrengths": [], "incomingTokenType": "none", "authenticationProtocol":
|
||||
"none", "appServicePrincipalId": null, "resourceServicePrincipalId": "4d6bd7de-c9bc-45cc-b8ec-ae315f66bf77",
|
||||
"rngcStatus": 0}}'
|
||||
@@ -0,0 +1,17 @@
|
||||
name: Azure Audit
|
||||
id: 62e2f93e-4e9c-4d38-bb2c-6d59c4565318
|
||||
author: Patrick Bareiss, Splunk
|
||||
source: mscs:azure:audit
|
||||
sourcetype: mscs:azure:audit
|
||||
separator: operationName.localizedValue
|
||||
supported_TA:
|
||||
name: Splunk Add-on for Microsoft Cloud Services
|
||||
version: 5.2.2
|
||||
url: https://splunkbase.splunk.com/app/3110
|
||||
event_names:
|
||||
- event_name: Azure Audit Create or Update an Azure Automation Runbook
|
||||
data_source: data_sources/cloud/event_sources/Azure_Audit_Create_or_Update_an_Azure_Automation_Runbook.yml
|
||||
- event_name: Azure Audit Create or Update an Azure Automation account
|
||||
data_source: data_sources/cloud/event_sources/Azure_Audit_Create_or_Update_an_Azure_Automation_account.yml
|
||||
- event_name: Azure Audit Create or Update an Azure Automation webhook
|
||||
data_source: data_sources/cloud/event_sources/Azure_Audit_Create_or_Update_an_Azure_Automation_webhook.yml
|
||||
@@ -0,0 +1,78 @@
|
||||
name: CircleCI
|
||||
id: 34ad06fc-a296-4ab5-8315-2f07714948e3
|
||||
author: Patrick Bareiss, Splunk
|
||||
source: circleci
|
||||
sourcetype: circleci
|
||||
separator: null
|
||||
supported_TA:
|
||||
name: App for CircleCI
|
||||
version: 0.1.1
|
||||
url: https://splunkbase.splunk.com/app/5162
|
||||
event_names: []
|
||||
fields:
|
||||
- _time
|
||||
- author_name
|
||||
- avatar_url
|
||||
- branch
|
||||
- build_num
|
||||
- build_time_millis
|
||||
- build_url
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- eventtype
|
||||
- fail_reason
|
||||
- host
|
||||
- index
|
||||
- job_name
|
||||
- job_time
|
||||
- linecount
|
||||
- owners{}
|
||||
- project_slug
|
||||
- punct
|
||||
- queued_time
|
||||
- reponame
|
||||
- source
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- start_time
|
||||
- status
|
||||
- stop_time
|
||||
- tag
|
||||
- tag::eventtype
|
||||
- timedout
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- username
|
||||
- vcs.commit_time
|
||||
- vcs.committer_name
|
||||
- vcs.revision
|
||||
- vcs.subject
|
||||
- vcs.tag
|
||||
- vcs.type
|
||||
- vcs.url
|
||||
- workflows.job_id
|
||||
- workflows.job_name
|
||||
- workflows.upstream_job_ids{}
|
||||
- workflows.workflow_id
|
||||
- workflows.workflow_name
|
||||
- workflows.workspace_id
|
||||
example_log: '{"job_time": "2021-09-02T08:13:34.273Z", "stop_time": "2021-09-02T08:13:34.273Z",
|
||||
"start_time": "2021-09-02T08:10:15.829Z", "queued_time": "2021-09-02T08:10:12.764Z",
|
||||
"job_name": "Unknown", "reponame": "devsecops_poc", "build_num": 94, "build_url":
|
||||
"https://circleci.com/gh/splunk/devsecops_poc/94", "branch": "main", "status": "success",
|
||||
"project_slug": "gh/splunk/devsecops_poc", "fail_reason": null, "build_time_millis":
|
||||
198444, "timedout": false, "username": "splunk", "owners": ["P4T12ICK"], "author_name":
|
||||
"P4T12ICK", "avatar_url": "", "workflows": {"job_name": "k8s-security", "job_id":
|
||||
"aa1e394f-42c8-4809-93fc-7ba9f8fc51d2", "workflow_id": "6a1bd1c8-e3c4-4d7a-b3e4-16cc726cc0ca",
|
||||
"workspace_id": "6a1bd1c8-e3c4-4d7a-b3e4-16cc726cc0ca", "upstream_job_ids": ["7d543f1d-ae02-449d-9ce3-f710e9094c47",
|
||||
"39a8bf7a-fe22-4886-8661-9f6eec43b348", "7c1adae6-feb1-409b-b17a-c9beaab63359"],
|
||||
"upstream_concurrency_map": {}, "workflow_name": "deployment"}, "vcs": {"commit_time":
|
||||
"2021-09-02T08:05:59.000Z", "type": "github", "url": "https://github.com/splunk/devsecops_poc",
|
||||
"revision": "68d5575c64352792e6e716a1e909db5f9cb3bc2a", "tag": null, "committer_name":
|
||||
"P4T12ICK", "subject": "small change"}}'
|
||||
@@ -0,0 +1,52 @@
|
||||
name: G Suite Drive
|
||||
id: 5f79120f-a235-4468-bd0d-55203758ac22
|
||||
author: Patrick Bareiss, Splunk
|
||||
source: http:gsuite
|
||||
sourcetype: gsuite:drive:json
|
||||
separator: null
|
||||
supported_TA:
|
||||
name: Splunk Add-on for Google Workspace
|
||||
version: 2.6.3
|
||||
url: https://splunkbase.splunk.com/app/5556
|
||||
event_names: []
|
||||
fields:
|
||||
- _time
|
||||
- email
|
||||
- host
|
||||
- index
|
||||
- ip_address
|
||||
- linecount
|
||||
- name
|
||||
- parameters.actor_is_collaborator_account
|
||||
- parameters.billable
|
||||
- parameters.doc_id
|
||||
- parameters.doc_title
|
||||
- parameters.doc_type
|
||||
- parameters.is_encrypted
|
||||
- parameters.new_value{}
|
||||
- parameters.old_value{}
|
||||
- parameters.old_visibility
|
||||
- parameters.originating_app_id
|
||||
- parameters.owner
|
||||
- parameters.owner_is_shared_drive
|
||||
- parameters.owner_is_team_drive
|
||||
- parameters.primary_event
|
||||
- parameters.target_user
|
||||
- parameters.visibility
|
||||
- parameters.visibility_change
|
||||
- punct
|
||||
- source
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- timestamp
|
||||
- type
|
||||
- unique_id
|
||||
example_log: '{"type": "acl_change", "name": "change_user_access", "parameters": {"primary_event":
|
||||
true, "billable": true, "visibility_change": "none", "target_user": "alberto@internal_test_email.com",
|
||||
"old_value": ["none"], "new_value": ["can_edit"], "old_visibility": "private", "doc_id":
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", "doc_type": "spreadsheet", "is_encrypted":
|
||||
false, "doc_title": "Invoice-11111 FedEx - Delivery - Dummy Detection POC", "visibility":
|
||||
"shared_internally", "originating_app_id": "000000000001", "actor_is_collaborator_account":
|
||||
false, "owner": "peter@external_test_email.com", "owner_is_shared_drive": false,
|
||||
"owner_is_team_drive": false}, "email": "peter@external_test_email.com", "unique_id":
|
||||
"123456789", "ip_address": "null", "timestamp": "2021-08-23T09:19:08.200Z"}'
|
||||
@@ -0,0 +1,108 @@
|
||||
name: G Suite Gmail
|
||||
id: 706c3978-41de-406b-b6e0-75bd01e12a5d
|
||||
author: Patrick Bareiss, Splunk
|
||||
source: http:gsuite
|
||||
sourcetype: gsuite:gmail:bigquery
|
||||
separator: null
|
||||
supported_TA:
|
||||
name: Splunk Add-on for Google Workspace
|
||||
version: 2.6.3
|
||||
url: https://splunkbase.splunk.com/app/5556
|
||||
event_names: []
|
||||
fields:
|
||||
- _time
|
||||
- action_type
|
||||
- attachment{}.file_extension_type
|
||||
- attachment{}.malware_family
|
||||
- attachment{}.sha256
|
||||
- connection_info.authenticated_domain{}.name
|
||||
- connection_info.authenticated_domain{}.type
|
||||
- connection_info.client_host_zone
|
||||
- connection_info.client_ip
|
||||
- connection_info.dkim_pass
|
||||
- connection_info.dmarc_pass
|
||||
- connection_info.dmarc_published_domain
|
||||
- connection_info.ip_geo_city
|
||||
- connection_info.ip_geo_country
|
||||
- connection_info.is_internal
|
||||
- connection_info.is_intra_domain
|
||||
- connection_info.smtp_in_connect_ip
|
||||
- connection_info.smtp_out_connect_ip
|
||||
- connection_info.smtp_out_remote_host
|
||||
- connection_info.smtp_reply_code
|
||||
- connection_info.smtp_response_reason
|
||||
- connection_info.smtp_tls_cipher
|
||||
- connection_info.smtp_tls_state
|
||||
- connection_info.smtp_tls_version
|
||||
- connection_info.smtp_user_agent_ip
|
||||
- connection_info.spf_pass
|
||||
- connection_info.tls_required_but_unavailable
|
||||
- description
|
||||
- destination{}.address
|
||||
- destination{}.rcpt_response
|
||||
- destination{}.selector
|
||||
- destination{}.service
|
||||
- destination{}.smime_decryption_success
|
||||
- destination{}.smime_extraction_success
|
||||
- destination{}.smime_parsing_success
|
||||
- destination{}.smime_signature_verification_success
|
||||
- eventtype
|
||||
- flattened_destinations
|
||||
- flattened_triggered_rule_info
|
||||
- host
|
||||
- index
|
||||
- is_policy_check_for_sender
|
||||
- is_spam
|
||||
- linecount
|
||||
- message_set{}.type
|
||||
- num_message_attachments
|
||||
- payload_size
|
||||
- punct
|
||||
- rfc2822_message_id
|
||||
- smime_content_type
|
||||
- smime_encrypt_message
|
||||
- smime_extraction_success
|
||||
- smime_packaging_success
|
||||
- smime_sign_message
|
||||
- smtp_relay_error
|
||||
- source
|
||||
- source.address
|
||||
- source.from_header_address
|
||||
- source.from_header_displayname
|
||||
- source.selector
|
||||
- source.service
|
||||
- sourcetype
|
||||
- spam_info
|
||||
- splunk_server
|
||||
- structured_policy_log_info
|
||||
- subject
|
||||
- tag
|
||||
- tag::eventtype
|
||||
- timestamp
|
||||
- upload_error_category
|
||||
example_log: '{"action_type": 10, "rfc2822_message_id": "<CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC@mail.gmail.com>",
|
||||
"subject": "New Order DHL0000001 - Dummy email for Detection Development", "payload_size":
|
||||
6733, "source": {"address": "john@external_test_email.com", "service": "gmail-for-work",
|
||||
"selector": "policy", "from_header_address": "john@external_test_email.com", "from_header_displayname":
|
||||
"john smith"}, "destination": [{"address": "peter@internal_test_email.com", "service":
|
||||
"smtp-outbound", "selector": "gmail-for-work", "smime_signature_verification_success":
|
||||
null, "smime_decryption_success": null, "smime_parsing_success": null, "smime_extraction_success":
|
||||
null, "rcpt_response": null}], "flattened_destinations": "smtp-outbound:gmail-for-work:peter@internal_test_email.com",
|
||||
"description": "", "connection_info": {"client_ip": "null", "smtp_in_connect_ip":
|
||||
null, "smtp_out_connect_ip": "null", "failed_smtp_out_connect_ip": [], "smtp_tls_state":
|
||||
1, "smtp_reply_code": 250, "tls_required_but_unavailable": false, "smtp_out_remote_host":
|
||||
"internal_test_app.com", "smtp_user_agent_ip": "null", "is_intra_domain": false,
|
||||
"dmarc_pass": null, "dmarc_published_domain": null, "client_host_zone": null, "smtp_response_reason":
|
||||
null, "ip_geo_city": null, "ip_geo_country": null, "authenticated_domain": [{"name":
|
||||
"internal_test_email.com", "type": 2}, {"name": "internal_test_email.com", "type":
|
||||
6}, {"name": "internal_test_email.com", "type": 1}], "is_internal": false, "dkim_pass":
|
||||
true, "spf_pass": true, "smtp_tls_version": "TLSv9.9", "smtp_tls_cipher": "TLS_AES"},
|
||||
"is_spam": null, "is_policy_check_for_sender": false, "num_message_attachments":
|
||||
1, "message_set": [{"type": 57}, {"type": 9}, {"type": 22}, {"type": 15}, {"type":
|
||||
48}, {"type": 27}, {"type": 10}, {"type": 50}, {"type": 51}, {"type": 46}, {"type":
|
||||
61}, {"type": 44}], "smtp_relay_error": null, "upload_error_category": null, "structured_policy_log_info":
|
||||
null, "triggered_rule_info": [], "flattened_triggered_rule_info": null, "smime_sign_message":
|
||||
null, "smime_encrypt_message": null, "smime_packaging_success": null, "smime_extraction_success":
|
||||
null, "smime_content_type": null, "link_domain": [], "attachment": [{"sha256": "1111111111111111111111111111111111111111111111111111111111111111",
|
||||
"file_extension_type": "zip", "malware_family": null}], "spam_info": null, "timestamp":
|
||||
1629378633.802384}'
|
||||
@@ -0,0 +1,205 @@
|
||||
name: GitHub
|
||||
id: 88aa4632-3c3e-43f6-a00a-998d71f558e3
|
||||
author: Patrick Bareiss, Splunk
|
||||
source: github
|
||||
sourcetype: aws:firehose:json
|
||||
separator: null
|
||||
supported_TA:
|
||||
name: Splunk Add-on for Github
|
||||
version: 2.2.1
|
||||
url: https://splunkbase.splunk.com/app/6254
|
||||
event_names: []
|
||||
fields:
|
||||
- _time
|
||||
- action
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- meta
|
||||
- punct
|
||||
- source
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- timestamp
|
||||
- workflow_run.actor.avatar_url
|
||||
- workflow_run.actor.events_url
|
||||
- workflow_run.actor.followers_url
|
||||
- workflow_run.actor.following_url
|
||||
- workflow_run.actor.gists_url
|
||||
- workflow_run.actor.gravatar_id
|
||||
- workflow_run.actor.html_url
|
||||
- workflow_run.actor.id
|
||||
- workflow_run.actor.login
|
||||
- workflow_run.actor.node_id
|
||||
- workflow_run.actor.organizations_url
|
||||
- workflow_run.actor.received_events_url
|
||||
- workflow_run.actor.repos_url
|
||||
- workflow_run.actor.site_admin
|
||||
- workflow_run.actor.starred_url
|
||||
- workflow_run.actor.subscriptions_url
|
||||
- workflow_run.actor.type
|
||||
- workflow_run.actor.url
|
||||
- workflow_run.artifacts_url
|
||||
- workflow_run.cancel_url
|
||||
- workflow_run.check_suite_id
|
||||
- workflow_run.check_suite_node_id
|
||||
- workflow_run.check_suite_url
|
||||
- workflow_run.conclusion
|
||||
- workflow_run.created_at
|
||||
- workflow_run.event
|
||||
- workflow_run.head_branch
|
||||
- workflow_run.head_commit.author.email
|
||||
- workflow_run.head_commit.author.name
|
||||
- workflow_run.head_commit.committer.email
|
||||
- workflow_run.head_commit.committer.name
|
||||
- workflow_run.head_commit.id
|
||||
- workflow_run.head_commit.message
|
||||
- workflow_run.head_commit.timestamp
|
||||
- workflow_run.head_commit.tree_id
|
||||
- workflow_run.head_repository.collaborators_url
|
||||
- workflow_run.head_repository.description
|
||||
- workflow_run.head_repository.fork
|
||||
- workflow_run.head_repository.forks_url
|
||||
- workflow_run.head_repository.full_name
|
||||
- workflow_run.head_repository.hooks_url
|
||||
- workflow_run.head_repository.html_url
|
||||
- workflow_run.head_repository.id
|
||||
- workflow_run.head_repository.keys_url
|
||||
- workflow_run.head_repository.name
|
||||
- workflow_run.head_repository.node_id
|
||||
- workflow_run.head_repository.owner.avatar_url
|
||||
- workflow_run.head_repository.owner.events_url
|
||||
- workflow_run.head_repository.owner.followers_url
|
||||
- workflow_run.head_repository.owner.following_url
|
||||
- workflow_run.head_repository.owner.gists_url
|
||||
- workflow_run.head_repository.owner.gravatar_id
|
||||
- workflow_run.head_repository.owner.html_url
|
||||
- workflow_run.head_repository.owner.id
|
||||
- workflow_run.head_repository.owner.login
|
||||
- workflow_run.head_repository.owner.node_id
|
||||
- workflow_run.head_repository.owner.organizations_url
|
||||
- workflow_run.head_repository.owner.received_events_url
|
||||
- workflow_run.head_repository.owner.repos_url
|
||||
- workflow_run.head_repository.owner.site_admin
|
||||
- workflow_run.head_repository.owner.starred_url
|
||||
- workflow_run.head_repository.owner.subscriptions_url
|
||||
- workflow_run.head_repository.owner.type
|
||||
- workflow_run.head_repository.owner.url
|
||||
- workflow_run.head_repository.private
|
||||
- workflow_run.head_repository.teams_url
|
||||
- workflow_run.head_repository.url
|
||||
- workflow_run.head_sha
|
||||
- workflow_run.html_url
|
||||
- workflow_run.id
|
||||
- workflow_run.jobs_url
|
||||
- workflow_run.logs_url
|
||||
- workflow_run.name
|
||||
- workflow_run.node_id
|
||||
- workflow_run.previous_attempt_url
|
||||
- workflow_run.pull_requests{}.base.ref
|
||||
- workflow_run.pull_requests{}.base.repo.id
|
||||
- workflow_run.pull_requests{}.base.repo.name
|
||||
- workflow_run.pull_requests{}.base.repo.url
|
||||
- workflow_run.pull_requests{}.base.sha
|
||||
- workflow_run.pull_requests{}.head.ref
|
||||
- workflow_run.pull_requests{}.head.repo.id
|
||||
- workflow_run.pull_requests{}.head.repo.name
|
||||
- workflow_run.pull_requests{}.head.repo.url
|
||||
- workflow_run.pull_requests{}.head.sha
|
||||
- workflow_run.pull_requests{}.id
|
||||
- workflow_run.pull_requests{}.number
|
||||
- workflow_run.pull_requests{}.url
|
||||
- workflow_run.repository.archive_url
|
||||
- workflow_run.repository.assignees_url
|
||||
- workflow_run.repository.blobs_url
|
||||
- workflow_run.repository.branches_url
|
||||
- workflow_run.repository.collaborators_url
|
||||
- workflow_run.repository.comments_url
|
||||
- workflow_run.repository.commits_url
|
||||
- workflow_run.repository.compare_url
|
||||
- workflow_run.repository.contents_url
|
||||
- workflow_run.repository.contributors_url
|
||||
- workflow_run.repository.deployments_url
|
||||
- workflow_run.repository.description
|
||||
- workflow_run.repository.downloads_url
|
||||
- workflow_run.repository.events_url
|
||||
- workflow_run.repository.fork
|
||||
- workflow_run.repository.forks_url
|
||||
- workflow_run.repository.full_name
|
||||
- workflow_run.repository.git_commits_url
|
||||
- workflow_run.repository.git_refs_url
|
||||
- workflow_run.repository.git_tags_url
|
||||
- workflow_run.repository.hooks_url
|
||||
- workflow_run.repository.html_url
|
||||
- workflow_run.repository.id
|
||||
- workflow_run.repository.issue_comment_url
|
||||
- workflow_run.repository.issue_events_url
|
||||
- workflow_run.repository.issues_url
|
||||
- workflow_run.repository.keys_url
|
||||
- workflow_run.repository.labels_url
|
||||
- workflow_run.repository.languages_url
|
||||
- workflow_run.repository.merges_url
|
||||
- workflow_run.repository.milestones_url
|
||||
- workflow_run.repository.name
|
||||
- workflow_run.repository.node_id
|
||||
- workflow_run.repository.notifications_url
|
||||
- workflow_run.repository.owner.avatar_url
|
||||
- workflow_run.repository.owner.events_url
|
||||
- workflow_run.repository.owner.followers_url
|
||||
- workflow_run.repository.owner.following_url
|
||||
- workflow_run.repository.owner.gists_url
|
||||
- workflow_run.repository.owner.gravatar_id
|
||||
- workflow_run.repository.owner.html_url
|
||||
- workflow_run.repository.owner.id
|
||||
- workflow_run.repository.owner.login
|
||||
- workflow_run.repository.owner.node_id
|
||||
- workflow_run.repository.owner.organizations_url
|
||||
- workflow_run.repository.owner.received_events_url
|
||||
- workflow_run.repository.owner.repos_url
|
||||
- workflow_run.repository.owner.site_admin
|
||||
- workflow_run.repository.owner.starred_url
|
||||
- workflow_run.repository.owner.subscriptions_url
|
||||
- workflow_run.repository.owner.type
|
||||
- workflow_run.repository.owner.url
|
||||
- workflow_run.repository.private
|
||||
- workflow_run.repository.pulls_url
|
||||
- workflow_run.repository.releases_url
|
||||
- workflow_run.repository.stargazers_url
|
||||
- workflow_run.repository.statuses_url
|
||||
- workflow_run.repository.subscribers_url
|
||||
- workflow_run.repository.subscription_url
|
||||
- workflow_run.repository.tags_url
|
||||
- workflow_run.repository.teams_url
|
||||
- workflow_run.repository.trees_url
|
||||
- workflow_run.repository.url
|
||||
- workflow_run.rerun_url
|
||||
- workflow_run.run_attempt
|
||||
- workflow_run.run_number
|
||||
- workflow_run.run_started_at
|
||||
- workflow_run.status
|
||||
- workflow_run.triggering_actor.avatar_url
|
||||
- workflow_run.triggering_actor.events_url
|
||||
- workflow_run.triggering_actor.followers_url
|
||||
- workflow_run.triggering_actor.following_url
|
||||
- workflow_run.triggering_actor.gists_url
|
||||
- workflow_run.triggering_actor.gravatar_id
|
||||
- workflow_run.triggering_actor.html_url
|
||||
- workflow_run.triggering_actor.id
|
||||
- workflow_run.triggering_actor.login
|
||||
- workflow_run.triggering_actor.node_id
|
||||
- workflow_run.triggering_actor.organizations_url
|
||||
- workflow_run.triggering_actor.received_events_url
|
||||
- workflow_run.triggering_actor.repos_url
|
||||
- workflow_run.triggering_actor.site_admin
|
||||
- workflow_run.triggering_actor.starred_url
|
||||
- workflow_run.triggering_actor.subscriptions_url
|
||||
- workflow_run.triggering_actor.type
|
||||
- workflow_run.triggering_actor.url
|
||||
- workflow_run.updated_at
|
||||
- workflow_run.url
|
||||
- workflow_run.workflow_id
|
||||
- workflow_run.workflow_url
|
||||
example_log: '{"action":"requested","workflow_run":{"id":2088708615,"name":"auto-update","node_id":"WFR_kwLOCa00Ec58fyoH","head_branch":"mac_os_detections","head_sha":"4049334910ea3d52a917ca35aed66d11c80ed966","run_number":9504,"event":"push","status":"queued","conclusion":null,"workflow_id":4692335,"check_suite_id":5918781611,"check_suite_node_id":"CS_kwDOCa00Ec8AAAABYMlwqw","url":"https://api.github.com/repos/splunk/security_content/actions/runs/2088708615","html_url":"https://github.com/splunk/security_content/actions/runs/2088708615","pull_requests":[{"url":"https://api.github.com/repos/splunk/security_content/pulls/2131","id":893091277,"number":2131,"head":{"ref":"mac_os_detections","sha":"4049334910ea3d52a917ca35aed66d11c80ed966","repo":{"id":162346001,"url":"https://api.github.com/repos/splunk/security_content","name":"security_content"}},"base":{"ref":"develop","sha":"a7d3d1dc57f9bf36fe22e470bcf518fcc2c89283","repo":{"id":162346001,"url":"https://api.github.com/repos/splunk/security_content","name":"security_content"}}}],"created_at":"2022-04-04T08:43:15Z","updated_at":"2022-04-04T08:43:15Z","actor":{"login":"jsmith","id":8362376,"node_id":"MDQ6VXNlcjgzNjIzNzY=","avatar_url":"https://avatars.githubusercontent.com/u/8362376?v=4","gravatar_id":"","url":"https://api.github.com/users/jsmith","html_url":"https://github.com/jsmith","followers_url":"https://api.github.com/users/jsmith/followers","following_url":"https://api.github.com/users/jsmith/following{/other_user}","gists_url":"https://api.github.com/users/jsmith/gists{/gist_id}","starred_url":"https://api.github.com/users/jsmith/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jsmith/subscriptions","organizations_url":"https://api.github.com/users/jsmith/orgs","repos_url":"https://api.github.com/users/jsmith/repos","events_url":"https://api.github.com/users/jsmith/events{/privacy}","received_events_url":"https://api.github.com/users/jsmith/received_events","type":"User","site_admin":false},"run_attempt":1,"run_started_at":"2022-04-04T08:43:15Z","triggering_actor":{"login":"jsmith","id":8362376,"node_id":"MDQ6VXNlcjgzNjIzNzY=","avatar_url":"https://avatars.githubusercontent.com/u/8362376?v=4","gravatar_id":"","url":"https://api.github.com/users/jsmith","html_url":"https://github.com/jsmith","followers_url":"https://api.github.com/users/jsmith/followers","following_url":"https://api.github.com/users/jsmith/following{/other_user}","gists_url":"https://api.github.com/users/jsmith/gists{/gist_id}","starred_url":"https://api.github.com/users/jsmith/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jsmith/subscriptions","organizations_url":"https://api.github.com/users/jsmith/orgs","repos_url":"https://api.github.com/users/jsmith/repos","events_url":"https://api.github.com/users/jsmith/events{/privacy}","received_events_url":"https://api.github.com/users/jsmith/received_events","type":"User","site_admin":false},"jobs_url":"https://api.github.com/repos/splunk/security_content/actions/runs/2088708615/jobs","logs_url":"https://api.github.com/repos/splunk/security_content/actions/runs/2088708615/logs","check_suite_url":"https://api.github.com/repos/splunk/security_content/check-suites/5918781611","artifacts_url":"https://api.github.com/repos/splunk/security_content/actions/runs/2088708615/artifacts","cancel_url":"https://api.github.com/repos/splunk/security_content/actions/runs/2088708615/cancel","rerun_url":"https://api.github.com/repos/splunk/security_content/actions/runs/2088708615/rerun","previous_attempt_url":null,"workflow_url":"https://api.github.com/repos/splunk/security_content/actions/workflows/4692335","head_commit":{"id":"4049334910ea3d52a917ca35aed66d11c80ed966","tree_id":"df4ddc1359be3b19f093b7a27dbf5708187743a0","message":"small
|
||||
change","timestamp":"2022-04-04T08:43:01Z","author":{"name":"jsmith","email":"jsmith@evilcorp.com"},"committer":{"name":"jsmith","email":"jsmith@evilcorp.com"}},"repository":{"id":162346001,"node_id":"MDEwOlJlcG9zaXRvcnkxNjIzNDYwMDE=","name":"security_content","full_name":"splunk/security_content","private":false,"owner":{"login":"splunk","id":651467,"node_id":"MDEyOk9yZ2FuaXphdGlvbjY1MTQ2Nw==","avatar_url":"https://avatars.githubusercontent.com/u/651467?v=4","gravatar_id":"","url":"https://api.github.com/users/splunk","html_url":"https://github.com/splunk","followers_url":"https://api.github.com/users/splunk/followers","following_url":"https://api.github.com/users/splunk/following{/other_user}","gists_url":"https://api.github.com/users/splunk/gists{/gist_id}","starred_url":"https://api.github.com/users/splunk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/splunk/subscriptions","organizations_url":"https://api.github.com/users/splunk/orgs","repos_url":"https://api.github.com/users/splunk/repos","events_url":"https://api.github.com/users/splunk/events{/privacy}","received_events_url":"https://api.github.com/users/splunk/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/splunk/security_content","description":"Splunk
|
||||
Security Content","fork":false,"url":"https://api.github.com/repos/splunk/security_content","forks_url":"https://api.github.com/repos/splunk/security_content/forks","keys_url":"https://api.github.com/repos/splunk/security_content/keys{/key_id}","collaborators_url":"https://api.github.com/repos/splunk/security_content/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/splunk/security_content/teams","hooks_url":"https://api.github.com/repos/splunk/security_content/hooks","issue_events_url":"https://api.github.com/repos/splunk/security_content/issues/events{/number}","events_url":"https://api.github.com/repos/splunk/security_content/events","assignees_url":"https://api.github.com/repos/splunk/security_content/assignees{/user}","branches_url":"https://api.github.com/repos/splunk/security_content/branches{/branch}","tags_url":"https://api.github.com/repos/splunk/security_content/tags","blobs_url":"https://api.github.com/repos/splunk/security_content/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/splunk/security_content/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/splunk/security_content/git/refs{/sha}","trees_url":"https://api.github.com/repos/splunk/security_content/git/trees{/sha}","statuses_url":"https://api.github.com/repos/splunk/security_content/statuses/{sha}","languages_url":"https://api.github.com/repos/splunk/security_content/languages","stargazers_url":"https://api.github.com/repos/splunk/security_content/stargazers","contributors_url":"https://api.github.com/repos/splunk/security_content/contributors","subscribers_url":"https://api.github.com/repos/splunk/security_content/subscribers","subscription_url":"https://api.github.com/repos/splunk/security_content/subscription","commits_url":"https://api.github.com/repos/splunk/security_content/commits{/sha}","git_commits_url":"https://api.github.com/repos/splunk/security_content/git/commits{/sha}","comments_url":"https://api.github.com/repos/splunk/security_content/comments{/number}","issue_comment_url":"https://api.github.com/repos/splunk/security_content/issues/comments{/number}","contents_url":"https://api.github.com/repos/splunk/security_content/contents/{+path}","compare_url":"https://api.github.com/repos/splunk/security_content/compare/{base}...{head}","merges_url":"https://api.github.com/repos/splunk/security_content/merges","archive_url":"https://api.github.com/repos/splunk/security_content/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/splunk/security_content/downloads","issues_url":"https://api.github.com/repos/splunk/security_content/issues{/number}","pulls_url":"https://api.github.com/repos/splunk/security_content/pulls{/number}","milestones_url":"https://api.github.com/repos/splunk/security_content/milestones{/number}","notifications_url":"https://api.github.com/repos/splunk/security_content/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/splunk/security_content/labels{/name}","releases_url":"https://api.github.com/repos/splunk/security_content/releases{/id}","deployments_url":"https://api.github.com/repos/splunk/security_content/deployments"},"head_repository":{"id":162346001,"node_id":"MDEwOlJlcG9zaXRvcnkxNjIzNDYwMDE=","name":"security_content","full_name":"splunk/security_content","private":false,"owner":{"login":"splunk","id":651467,"node_id":"MDEyOk9yZ2FuaXphdGlvbjY1MTQ2Nw==","avatar_url":"https://avatars.githubusercontent.com/u/651467?v=4","gravatar_id":"","url":"https://api.github.com/users/splunk","html_url":"https://github.com/splunk","followers_url":"https://api.github.com/users/splunk/followers","following_url":"https://api.github.com/users/splunk/following{/other_user}","gists_url":"https://api.github.com/users/splunk/gists{/gist_id}","starred_url":"https://api.github.com/users/splunk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/splunk/subscriptions","organizations_url":"https://api.github.com/users/splunk/orgs","repos_url":"https://api.github.com/users/splunk/repos","events_url":"https://api.github.com/users/splunk/events{/privacy}","received_events_url":"https://api.github.com/users/splunk/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/splunk/security_content","description":"Splunk
|
||||
Security Content","fork":false,"url":"https://api.github.com/repos/splunk/security_content","forks_url":"https://api.github.com/repos/splunk/security_content/forks","keys_url":"https://api.github.com/repos/splunk/security_content/keys{/key_id}","collaborators_url":"https://api.github.com/repos/splunk/security_content/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/splunk/security_content/teams","hooks_url":"https://api.github.com/repos/splunk/security_content/hooks","issue_events_url":"https://api.github.com/repos/splunk/security_content/issues/events{/num'
|
||||
@@ -0,0 +1,17 @@
|
||||
name: Google Workspace
|
||||
id: 9ef3a321-c641-4798-8a92-9c10c714a004
|
||||
author: Patrick Bareiss, Splunk
|
||||
source: gws:reports:admin
|
||||
sourcetype: gws:reports:admin
|
||||
separator: event.name
|
||||
supported_TA:
|
||||
name: Splunk Add-on for Google Workspace
|
||||
version: 2.6.3
|
||||
url: https://splunkbase.splunk.com/app/5556
|
||||
event_names:
|
||||
- event_name: Google Workspace
|
||||
data_source: data_sources/cloud/event_sources/Google_Workspace.yml
|
||||
- event_name: Google Workspace login_failure
|
||||
data_source: data_sources/cloud/event_sources/Google_Workspace_login_failure.yml
|
||||
- event_name: Google Workspace login_success
|
||||
data_source: data_sources/cloud/event_sources/Google_Workspace_login_success.yml
|
||||
@@ -0,0 +1,61 @@
|
||||
name: Kubernetes Audit
|
||||
id: 6c25181a-0c07-4aaf-90e6-77ab1f0e6699
|
||||
author: Patrick Bareiss, Splunk
|
||||
source: kubernetes
|
||||
sourcetype: _json
|
||||
separator: null
|
||||
supported_TA: {}
|
||||
event_names: []
|
||||
fields:
|
||||
- _time
|
||||
- annotations.authorization.k8s.io/decision
|
||||
- annotations.authorization.k8s.io/reason
|
||||
- apiVersion
|
||||
- auditID
|
||||
- eventtype
|
||||
- host
|
||||
- index
|
||||
- kind
|
||||
- level
|
||||
- linecount
|
||||
- objectRef.apiGroup
|
||||
- objectRef.apiVersion
|
||||
- objectRef.namespace
|
||||
- objectRef.resource
|
||||
- punct
|
||||
- requestReceivedTimestamp
|
||||
- requestURI
|
||||
- responseObject.apiVersion
|
||||
- responseObject.code
|
||||
- responseObject.details.group
|
||||
- responseObject.details.kind
|
||||
- responseObject.kind
|
||||
- responseObject.message
|
||||
- responseObject.reason
|
||||
- responseObject.status
|
||||
- responseStatus.code
|
||||
- responseStatus.details.group
|
||||
- responseStatus.details.kind
|
||||
- responseStatus.message
|
||||
- responseStatus.reason
|
||||
- responseStatus.status
|
||||
- source
|
||||
- sourceIPs{}
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- stage
|
||||
- stageTimestamp
|
||||
- tag
|
||||
- tag::eventtype
|
||||
- timestamp
|
||||
- user.groups{}
|
||||
- user.uid
|
||||
- user.username
|
||||
- userAgent
|
||||
- verb
|
||||
example_log: '{"kind":"Event","apiVersion":"audit.k8s.io/v1","level":"RequestResponse","auditID":"582c31ab-4906-49bb-9ff9-872f980ccb84","stage":"ResponseComplete","requestURI":"/apis/batch/v1/namespaces/test2/jobs?fieldManager=kubectl-create\u0026fieldValidation=Strict","verb":"create","user":{"username":"k8s-test-user","uid":"aws-iam-authenticator:591511147606:AROAYTOGP2RLFHNBOTP5J","groups":["system:authenticated"]},"sourceIPs":["176.95.188.101"],"userAgent":"kubectl/v1.27.2
|
||||
(darwin/arm64) kubernetes/7f6f68f","objectRef":{"resource":"jobs","namespace":"test2","apiGroup":"batch","apiVersion":"v1"},"responseStatus":{"metadata":{},"status":"Failure","message":"jobs.batch
|
||||
is forbidden: User \"k8s-test-user\" cannot create resource \"jobs\" in API group
|
||||
\"batch\" in the namespace \"test2\"","reason":"Forbidden","details":{"group":"batch","kind":"jobs"},"code":403},"responseObject":{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"jobs.batch
|
||||
is forbidden: User \"k8s-test-user\" cannot create resource \"jobs\" in API group
|
||||
\"batch\" in the namespace \"test2\"","reason":"Forbidden","details":{"group":"batch","kind":"jobs"},"code":403},"requestReceivedTimestamp":"2023-12-07T14:44:53.358394Z","stageTimestamp":"2023-12-07T14:44:53.375985Z","annotations":{"authorization.k8s.io/decision":"forbid","authorization.k8s.io/reason":""}}'
|
||||
@@ -0,0 +1,48 @@
|
||||
name: Kubernetes Falco
|
||||
id: 23c0eeed-840a-4711-a41b-6819c1ffbba5
|
||||
author: Patrick Bareiss, Splunk
|
||||
source: kubernetes
|
||||
sourcetype: kube:container:falco
|
||||
separator: null
|
||||
supported_TA: {}
|
||||
event_names: []
|
||||
fields:
|
||||
- _time
|
||||
- command
|
||||
- container_id
|
||||
- container_image
|
||||
- container_image_tag
|
||||
- container_name
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- evt_type
|
||||
- exe_flags
|
||||
- host
|
||||
- index
|
||||
- k8s_ns
|
||||
- k8s_pod_name
|
||||
- linecount
|
||||
- parent
|
||||
- proc_exepath
|
||||
- process
|
||||
- punct
|
||||
- source
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- terminal
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- user
|
||||
- user_loginuid
|
||||
- user_uid
|
||||
example_log: '12:18:18.691725165: Notice A shell was spawned in a container with an
|
||||
attached terminal (evt_type=execve user=root user_uid=0 user_loginuid=-1 process=bash
|
||||
proc_exepath=/usr/lib/splunk-otel-collector/agent-bundle/bin/bash parent=runc command=bash
|
||||
-il terminal=34816 exe_flags=EXE_WRITABLE container_id=7a2566e8e462 container_image=quay.io/signalfx/splunk-otel-collector
|
||||
container_image_tag=0.88.0 container_name=otel-collector k8s_ns=default k8s_pod_name=my-splunk-otel-collector-agent-9sdhr)'
|
||||
@@ -0,0 +1,123 @@
|
||||
name: O365
|
||||
id: 11c0eed5-3f3f-42e4-bf72-30f11295a686
|
||||
author: Patrick Bareiss, Splunk
|
||||
source: o365
|
||||
sourcetype: o365:management:activity
|
||||
separator: Operation
|
||||
supported_TA:
|
||||
name: Splunk Add-on for Microsoft Office 365
|
||||
version: 4.5.1
|
||||
url: https://splunkbase.splunk.com/app/4055
|
||||
event_names:
|
||||
- event_name: O365
|
||||
data_source: data_sources/cloud/event_sources/O365.yml
|
||||
- event_name: O365 Add app role assignment grant to user.
|
||||
data_source: data_sources/cloud/event_sources/O365_Add_app_role_assignment_grant_to_user..yml
|
||||
- event_name: O365 Add app role assignment to service principal.
|
||||
data_source: data_sources/cloud/event_sources/O365_Add_app_role_assignment_to_service_principal..yml
|
||||
- event_name: O365 Add member to role.
|
||||
data_source: data_sources/cloud/event_sources/O365_Add_member_to_role..yml
|
||||
- event_name: O365 Add owner to application.
|
||||
data_source: data_sources/cloud/event_sources/O365_Add_owner_to_application..yml
|
||||
- event_name: O365 Add service principal.
|
||||
data_source: data_sources/cloud/event_sources/O365_Add_service_principal..yml
|
||||
- event_name: O365 Add-MailboxPermission
|
||||
data_source: data_sources/cloud/event_sources/O365_Add-MailboxPermission.yml
|
||||
- event_name: O365 Change user license.
|
||||
data_source: data_sources/cloud/event_sources/O365_Change_user_license..yml
|
||||
- event_name: O365 Consent to application.
|
||||
data_source: data_sources/cloud/event_sources/O365_Consent_to_application..yml
|
||||
- event_name: O365 Disable Strong Authentication.
|
||||
data_source: data_sources/cloud/event_sources/O365_Disable_Strong_Authentication..yml
|
||||
- event_name: O365 MailItemsAccessed
|
||||
data_source: data_sources/cloud/event_sources/O365_MailItemsAccessed.yml
|
||||
- event_name: O365 ModifyFolderPermissions
|
||||
data_source: data_sources/cloud/event_sources/O365_ModifyFolderPermissions.yml
|
||||
- event_name: O365 Set Company Information.
|
||||
data_source: data_sources/cloud/event_sources/O365_Set_Company_Information..yml
|
||||
- event_name: O365 Set-Mailbox
|
||||
data_source: data_sources/cloud/event_sources/O365_Set-Mailbox.yml
|
||||
- event_name: O365 Update application.
|
||||
data_source: data_sources/cloud/event_sources/O365_Update_application..yml
|
||||
- event_name: O365 Update authorization policy.
|
||||
data_source: data_sources/cloud/event_sources/O365_Update_authorization_policy..yml
|
||||
- event_name: O365 Update user.
|
||||
data_source: data_sources/cloud/event_sources/O365_Update_user..yml
|
||||
- event_name: O365 UserLoggedIn
|
||||
data_source: data_sources/cloud/event_sources/O365_UserLoggedIn.yml
|
||||
- event_name: O365 UserLoginFailed
|
||||
data_source: data_sources/cloud/event_sources/O365_UserLoginFailed.yml
|
||||
fields:
|
||||
- _time
|
||||
- AppAccessContext.IssuedAtTime
|
||||
- AppAccessContext.UniqueTokenId
|
||||
- AppId
|
||||
- ClientAppId
|
||||
- ClientIP
|
||||
- CreationTime
|
||||
- ExternalAccess
|
||||
- Id
|
||||
- Name
|
||||
- ObjectId
|
||||
- Operation
|
||||
- OrganizationId
|
||||
- OrganizationName
|
||||
- OriginatingServer
|
||||
- Parameters{}.Name
|
||||
- Parameters{}.Value
|
||||
- RecordType
|
||||
- RequestId
|
||||
- ResultStatus
|
||||
- Role
|
||||
- SessionId
|
||||
- User
|
||||
- UserId
|
||||
- UserKey
|
||||
- UserType
|
||||
- Version
|
||||
- Workload
|
||||
- app
|
||||
- authentication_service
|
||||
- command
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- dest
|
||||
- dest_name
|
||||
- dvc
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- object
|
||||
- punct
|
||||
- record_type
|
||||
- signature
|
||||
- source
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src
|
||||
- src_ip
|
||||
- status
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- user
|
||||
- user_id
|
||||
- user_type
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
example_log: '{"AppAccessContext": {"IssuedAtTime": "2023-10-17T19:13:05", "UniqueTokenId":
|
||||
"g7oAmNhLoU-8qJVeWeAwAA"}, "CreationTime": "2023-10-17T19:19:59", "Id": "3d26a8cd-d8f4-42f9-1898-08dbcf460e5a",
|
||||
"Operation": "New-ManagementRoleAssignment", "OrganizationId": "aeb12f6b-1ff3-4a18-9ea2-29aa57e2ae08",
|
||||
"RecordType": 1, "ResultStatus": "True", "UserKey": "1003BFFD98415B4E", "UserType":
|
||||
2, "Version": 1, "Workload": "Exchange", "ClientIP": "71.1.1.1:61528", "ObjectId":
|
||||
"splunkresearch.onmicrosoft.com\\attack-test", "UserId": "compromisedAdmin@splunkresearch.onmicrosoft.com",
|
||||
"AppId": "fb78d390-0c51-40cd-8e17-fdbfab77341b", "ClientAppId": "", "ExternalAccess":
|
||||
false, "OrganizationName": "splunkresearch.onmicrosoft.com", "OriginatingServer":
|
||||
"BYAPR18MB2408 (15.20.6863.047)", "Parameters": [{"Name": "User", "Value": "lowpriv@splunkresearch.onmicrosoft.com"},
|
||||
{"Name": "Name", "Value": "attack-test"}, {"Name": "Role", "Value": "ApplicationImpersonation"}],
|
||||
"RequestId": "53a50583-e429-63a4-c9f7-8fbb14437e8a", "SessionId": "e2a028f1-d0e1-4ddb-a5a7-ec57343457ad"}'
|
||||
@@ -0,0 +1,92 @@
|
||||
event_name: AWS CloudTrail AssumeRoleWithSAML
|
||||
fields:
|
||||
- _time
|
||||
- action
|
||||
- app
|
||||
- awsRegion
|
||||
- change_type
|
||||
- command
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- dest
|
||||
- dvc
|
||||
- errorCode
|
||||
- eventCategory
|
||||
- eventID
|
||||
- eventName
|
||||
- eventSource
|
||||
- eventTime
|
||||
- eventType
|
||||
- eventVersion
|
||||
- eventtype
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- managementEvent
|
||||
- msg
|
||||
- object_category
|
||||
- product
|
||||
- punct
|
||||
- readOnly
|
||||
- recipientAccountId
|
||||
- region
|
||||
- requestID
|
||||
- requestParameters.durationSeconds
|
||||
- requestParameters.principalArn
|
||||
- requestParameters.roleArn
|
||||
- requestParameters.roleSessionName
|
||||
- requestParameters.sAMLAssertionID
|
||||
- resources{}.ARN
|
||||
- resources{}.accountId
|
||||
- resources{}.type
|
||||
- responseElements.assumedRoleUser.arn
|
||||
- responseElements.assumedRoleUser.assumedRoleId
|
||||
- responseElements.audience
|
||||
- responseElements.credentials.accessKeyId
|
||||
- responseElements.credentials.expiration
|
||||
- responseElements.credentials.sessionToken
|
||||
- responseElements.issuer
|
||||
- responseElements.nameQualifier
|
||||
- responseElements.subject
|
||||
- responseElements.subjectType
|
||||
- signature
|
||||
- source
|
||||
- sourceIPAddress
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src
|
||||
- src_ip
|
||||
- src_user
|
||||
- src_user_id
|
||||
- src_user_type
|
||||
- start_time
|
||||
- status
|
||||
- tag
|
||||
- tag::action
|
||||
- tag::eventtype
|
||||
- temp_access_key
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- user
|
||||
- userAgent
|
||||
- userIdentity.identityProvider
|
||||
- userIdentity.principalId
|
||||
- userIdentity.type
|
||||
- userIdentity.userName
|
||||
- user_agent
|
||||
- user_arn
|
||||
- user_id
|
||||
- user_name
|
||||
- user_role
|
||||
- user_type
|
||||
- vendor
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
- vendor_region
|
||||
example_log: '{"eventVersion": "1.08", "userIdentity": {"type": "SAMLUser", "principalId": "ZRu9MRAjiG9tvi1QBNfdI664G5A=:rodsoto@rodsoto.onmicrosoft.com", "userName": "rodsoto@rodsoto.onmicrosoft.com", "identityProvider": "ZRu9MRAjiG9tvi1QBNfdI664G5A="}, "eventTime": "2021-01-22T03:44:16Z", "eventSource": "sts.amazonaws.com", "eventName": "AssumeRoleWithSAML", "awsRegion": "us-east-1", "sourceIPAddress": "72.21.217.152", "userAgent": "AWS Signin, aws-internal/3 aws-sdk-java/1.11.898 Linux/4.9.230-0.1.ac.223.84.332.metal1.x86_64 OpenJDK_64-Bit_Server_VM/25.275-b01 java/1.8.0_275 kotlin/1.3.72 vendor/Oracle_Corporation", "requestParameters": {"sAMLAssertionID": "_d33ba0ad-0c88-4b83-80a6-27c08027d000", "roleSessionName": "rodsoto@rodsoto.onmicrosoft.com", "durationSeconds": 3600, "roleArn": "arn:aws:iam::111111111111:role/rodonmicrotestrole", "principalArn": "arn:aws:iam::111111111111:saml-provider/rodsotoonmicrosoft"}, "responseElements": {"subjectType": "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress", "issuer": "https://sts.windows.net/0e8108b1-18e9-41a4-961b-dfcddf92ef08/", "credentials": {"accessKeyId": "ASIAYTOGP2RLKJXOV7VR", "expiration": "Jan 22, 2021 3:59:16 AM", "sessionToken": "IQoJb3JpZ2luX2VjENz//////////wEaCXVzLWVhc3QtMSJGMEQCIHl/WQdLq53ULYl10fPtpeV3H7da9mOXGuIStvhdDA6kAiAdO/7rocOXAtyDV+0MJhSj/piqlqEI/BcAKm8zqBhOgiqgAwi1//////////8BEAIaDDU5MTUxMTE0NzYwNiIMAFP8GfyI/x1fKCHYKvQCznxxgKnEdcuvrr/fBLmHxEDjQ9vQxjasA8gZF8GawZ5SFH9ViKqoZh93bYkOwKqZD8cdqJIo9SYL17RGhVqxzvsjU4+QsRXTN5eGgh+LyF9EZqeCl6oCkaTJqNrXHuenzTi0yiL510LKsSckrAm8+SuwI/jQu3oE1BEcJQieAc4RjYx3II+1cUvyfRlFvR2NDfZhdWcQvAivV06KJg9c2zfCF0Agzn/YZSNvsRL5UhnKhJ2wktSvT8lR0mS3n9xR1j3iYNxVDHab180cnfkP3G6tAmxj5U29diNQrusJxKWWhr/Q9wHRdDj5dO2QUZzSymKKU/UiRJ8nyYPINaJ8XWVAPiT4QgzpMxotkvSkDLEG/brB9yEr2p7W8Y3xMGZ37qSGkuU4z9x40RU9G1XPhv27NO9aaGs/VXYTMCzWRNxnsLfNkk/DihrcaR0SclRcvs+zmfe1ZUoGnfjNYm+AIyJi4D7OrXF5/Mt46Z2y76DnULlAMJCUqYAGOpsBw4fyafV8OizX7Lebh2JRXFZsWBY1GTpyGvO5otrw++4axud44vYVi5iU5rbJxtTBm4vtJartxgXoPJFnQuat9gLrIlXhjmg+m50a5xs1Ut2UWEsWY2Duu4jA9ap7P7dYv9kIK9P2uyhsjKQhCjTpfe4I/llcupbDotYBJuvlB5n85a5kgiSriFk5zetoXQIweuYEWQZsD/AN+LE="}, "nameQualifier": "ZRu9MRAjiG9tvi1QBNfdI664G5A=", "assumedRoleUser": {"assumedRoleId": "AROAYTOGP2RLKFUVAQAIJ:rodsoto@rodsoto.onmicrosoft.com", "arn": "arn:aws:sts::111111111111:assumed-role/rodonmicrotestrole/rodsoto@rodsoto.onmicrosoft.com"}, "subject": "rodsoto@rodsoto.onmicrosoft.com", "audience": "https://signin.aws.amazon.com/saml"}, "requestID": "e19c7a7f-cd96-4642-9ee6-2360a7b01b12", "eventID": "b25b825d-9c9b-49d3-9ecd-290dbe8f2c29", "readOnly": true, "resources": [{"accountId": "111111111111", "type": "AWS::IAM::Role", "ARN": "arn:aws:iam::111111111111:role/rodonmicrotestrole"}, {"accountId": "111111111111", "type": "AWS::IAM::SAMLProvider", "ARN": "arn:aws:iam::111111111111:saml-provider/rodsotoonmicrosoft"}], "eventType": "AwsApiCall", "managementEvent": true, "eventCategory": "Management", "recipientAccountId": "111111111111"}'
|
||||
@@ -0,0 +1,80 @@
|
||||
event_name: AWS CloudTrail ConsoleLogin
|
||||
fields:
|
||||
- _time
|
||||
- action
|
||||
- additionalEventData.LoginTo
|
||||
- additionalEventData.MFAUsed
|
||||
- additionalEventData.MobileVersion
|
||||
- app
|
||||
- authentication_method
|
||||
- awsRegion
|
||||
- aws_account_id
|
||||
- command
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- desc
|
||||
- dest
|
||||
- dvc
|
||||
- errorCode
|
||||
- errorMessage
|
||||
- eventCategory
|
||||
- eventID
|
||||
- eventName
|
||||
- eventSource
|
||||
- eventTime
|
||||
- eventType
|
||||
- eventVersion
|
||||
- eventtype
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- managementEvent
|
||||
- msg
|
||||
- object_category
|
||||
- product
|
||||
- punct
|
||||
- readOnly
|
||||
- reason
|
||||
- recipientAccountId
|
||||
- region
|
||||
- requestParameters
|
||||
- responseElements.ConsoleLogin
|
||||
- result
|
||||
- signature
|
||||
- source
|
||||
- sourceIPAddress
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src
|
||||
- src_ip
|
||||
- start_time
|
||||
- status
|
||||
- tag
|
||||
- tag::action
|
||||
- tag::eventtype
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- tlsDetails.cipherSuite
|
||||
- tlsDetails.clientProvidedHostHeader
|
||||
- tlsDetails.tlsVersion
|
||||
- userAgent
|
||||
- userIdentity.accessKeyId
|
||||
- userIdentity.accountId
|
||||
- userIdentity.type
|
||||
- userIdentity.userName
|
||||
- user_access_key
|
||||
- user_agent
|
||||
- user_group_id
|
||||
- user_name
|
||||
- user_type
|
||||
- vendor
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
- vendor_region
|
||||
example_log: '{"eventVersion": "1.08", "userIdentity": {"type": "IAMUser", "accountId": "140429656527", "accessKeyId": "", "userName": "HIDDEN_DUE_TO_SECURITY_REASONS"}, "eventTime": "2022-10-19T20:33:38Z", "eventSource": "signin.amazonaws.com", "eventName": "ConsoleLogin", "awsRegion": "us-east-1", "sourceIPAddress": "142.254.89.27", "userAgent": "Go-http-client/1.1", "errorMessage": "No username found in supplied account", "requestParameters": null, "responseElements": {"ConsoleLogin": "Failure"}, "additionalEventData": {"LoginTo": "https://console.aws.amazon.com", "MobileVersion": "No", "MFAUsed": "No"}, "eventID": "9fcfb8c3-3fca-48db-85d2-7b107f9d95d0", "readOnly": false, "eventType": "AwsConsoleSignIn", "managementEvent": true, "recipientAccountId": "140429656527", "eventCategory": "Management", "tlsDetails": {"tlsVersion": "TLSv1.2", "cipherSuite": "ECDHE-RSA-AES128-GCM-SHA256", "clientProvidedHostHeader": "signin.aws.amazon.com"}}'
|
||||
@@ -0,0 +1,86 @@
|
||||
event_name: AWS CloudTrail CopyObject
|
||||
fields:
|
||||
- _time
|
||||
- additionalEventData.AuthenticationMethod
|
||||
- additionalEventData.CipherSuite
|
||||
- additionalEventData.SSEApplied
|
||||
- additionalEventData.SignatureVersion
|
||||
- additionalEventData.bytesTransferredIn
|
||||
- additionalEventData.bytesTransferredOut
|
||||
- additionalEventData.x-amz-id-2
|
||||
- app
|
||||
- awsRegion
|
||||
- aws_account_id
|
||||
- command
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- dest
|
||||
- dvc
|
||||
- errorCode
|
||||
- eventCategory
|
||||
- eventID
|
||||
- eventName
|
||||
- eventSource
|
||||
- eventTime
|
||||
- eventType
|
||||
- eventVersion
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- managementEvent
|
||||
- msg
|
||||
- object_category
|
||||
- product
|
||||
- punct
|
||||
- readOnly
|
||||
- recipientAccountId
|
||||
- region
|
||||
- requestID
|
||||
- requestParameters.Host
|
||||
- requestParameters.bucketName
|
||||
- requestParameters.key
|
||||
- requestParameters.x-amz-copy-source
|
||||
- requestParameters.x-amz-server-side-encryption
|
||||
- requestParameters.x-amz-server-side-encryption-aws-kms-key-id
|
||||
- resources{}.ARN
|
||||
- resources{}.accountId
|
||||
- resources{}.type
|
||||
- responseElements.x-amz-server-side-encryption
|
||||
- responseElements.x-amz-server-side-encryption-aws-kms-key-id
|
||||
- signature
|
||||
- source
|
||||
- sourceIPAddress
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src
|
||||
- src_ip
|
||||
- start_time
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- user
|
||||
- userAgent
|
||||
- userIdentity.accessKeyId
|
||||
- userIdentity.accountId
|
||||
- userIdentity.arn
|
||||
- userIdentity.principalId
|
||||
- userIdentity.type
|
||||
- userIdentity.userName
|
||||
- userName
|
||||
- user_access_key
|
||||
- user_agent
|
||||
- user_arn
|
||||
- user_group_id
|
||||
- user_id
|
||||
- user_name
|
||||
- user_type
|
||||
- vendor
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
- vendor_region
|
||||
example_log: '{"eventVersion": "1.08", "userIdentity": {"type": "IAMUser", "principalId": "AIDAYTOGP2RLNALZHZ6KX", "arn": "arn:aws:iam::111111111111:user/patrick_cli", "accountId": "111111111111", "accessKeyId": "AKIAYTOGP2RLJ2OYSF6E", "userName": "patrick_cli"}, "eventTime": "2021-01-11T12:40:47Z", "eventSource": "s3.amazonaws.com", "eventName": "CopyObject", "awsRegion": "us-west-2", "sourceIPAddress": "95.90.199.65", "userAgent": "[aws-cli/2.0.45 Python/3.7.4 Darwin/20.2.0 exe/x86_64 command/s3.cp]", "requestParameters": {"bucketName": "patricktestbucketencrypt", "x-amz-server-side-encryption-aws-kms-key-id": "arn:aws:kms:us-west-2:111111111111:key/f2a82583-a7d3-4c92-8787-fe2baab1cee1", "Host": "patricktestbucketencrypt.s3.us-west-2.amazonaws.com", "x-amz-server-side-encryption": "aws:kms", "x-amz-copy-source": "patricktestbucketencrypt/kms_aws_events.json", "key": "kms_aws_events_encrypted.json"}, "responseElements": {"x-amz-server-side-encryption": "aws:kms", "x-amz-server-side-encryption-aws-kms-key-id": "arn:aws:kms:us-west-2:111111111111:key/f2a82583-a7d3-4c92-8787-fe2baab1cee1"}, "additionalEventData": {"SignatureVersion": "SigV4", "CipherSuite": "ECDHE-RSA-AES128-GCM-SHA256", "bytesTransferredIn": 0.0, "SSEApplied": "SSE_KMS", "AuthenticationMethod": "AuthHeader", "x-amz-id-2": "fqzX1iZV6ImDtkFxbGvziOE6fUwryRa+PhnLckfVAkLNHdbCAHNq4l/yckUd1a2HNJPL6NAS01U=", "bytesTransferredOut": 234.0}, "requestID": "6A7359F7A9414B02", "eventID": "b20d43de-175d-4443-acd7-f5f3e587ae00", "readOnly": false, "resources": [{"type": "AWS::S3::Object", "ARN": "arn:aws:s3:::patricktestbucketencrypt/kms_aws_events_encrypted.json"}, {"accountId": "111111111111", "type": "AWS::S3::Bucket", "ARN": "arn:aws:s3:::patricktestbucketencrypt"}, {"accountId": "111111111111", "type": "AWS::S3::Bucket", "ARN": "arn:aws:s3:::patricktestbucketencrypt"}, {"type": "AWS::S3::Object", "ARN": "arn:aws:s3:::patricktestbucketencrypt/kms_aws_events.json"}], "eventType": "AwsApiCall", "managementEvent": false, "recipientAccountId": "111111111111", "eventCategory": "Data"}'
|
||||
@@ -0,0 +1,80 @@
|
||||
event_name: AWS CloudTrail CreateAccessKey
|
||||
fields:
|
||||
- _time
|
||||
- action
|
||||
- app
|
||||
- awsRegion
|
||||
- aws_account_id
|
||||
- change_type
|
||||
- command
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- dest
|
||||
- dvc
|
||||
- errorCode
|
||||
- eventCategory
|
||||
- eventID
|
||||
- eventName
|
||||
- eventSource
|
||||
- eventTime
|
||||
- eventType
|
||||
- eventVersion
|
||||
- eventtype
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- managementEvent
|
||||
- msg
|
||||
- object_category
|
||||
- product
|
||||
- punct
|
||||
- readOnly
|
||||
- recipientAccountId
|
||||
- region
|
||||
- requestID
|
||||
- requestParameters.userName
|
||||
- responseElements.accessKey.accessKeyId
|
||||
- responseElements.accessKey.createDate
|
||||
- responseElements.accessKey.status
|
||||
- responseElements.accessKey.userName
|
||||
- signature
|
||||
- source
|
||||
- sourceIPAddress
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src
|
||||
- src_ip
|
||||
- src_user_name
|
||||
- start_time
|
||||
- status
|
||||
- tag
|
||||
- tag::eventtype
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- user
|
||||
- userAgent
|
||||
- userIdentity.accessKeyId
|
||||
- userIdentity.accountId
|
||||
- userIdentity.arn
|
||||
- userIdentity.principalId
|
||||
- userIdentity.type
|
||||
- userIdentity.userName
|
||||
- userName
|
||||
- user_access_key
|
||||
- user_agent
|
||||
- user_arn
|
||||
- user_group_id
|
||||
- user_id
|
||||
- user_name
|
||||
- user_type
|
||||
- vendor
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
- vendor_region
|
||||
example_log: '{"eventVersion": "1.08", "userIdentity": {"type": "IAMUser", "principalId": "AIDAYTOGP2RLEHRX5YWNV", "arn": "arn:aws:iam::121521347698:user/bhavin_cli", "accountId": "121521347698", "accessKeyId": "AKIAYTOGP2RLLAA6NJUM", "userName": "bhavin_cli"}, "eventTime": "2021-03-02T21:18:24Z", "eventSource": "iam.amazonaws.com", "eventName": "CreateAccessKey", "awsRegion": "us-east-1", "sourceIPAddress": "12.25.72.12", "userAgent": "aws-cli/2.0.62 Python/3.9.0 Darwin/19.6.0 source/x86_64 command/iam.create-access-key", "requestParameters": {"userName": "AtomicRedTeam"}, "responseElements": {"accessKey": {"userName": "AtomicRedTeam", "accessKeyId": "AKIAYTOGP2RLOQ4ULYGT", "status": "Active", "createDate": "Mar 2, 2021 9:18:24 PM"}}, "requestID": "12c8773d-6c78-46bf-a8e4-f841adc8f70d", "eventID": "5772e8d5-cccc-470d-81ef-acacfe85a804", "readOnly": false, "eventType": "AwsApiCall", "managementEvent": true, "eventCategory": "Management", "recipientAccountId": "121521347698"}'
|
||||
@@ -0,0 +1,98 @@
|
||||
event_name: AWS CloudTrail CreateKey
|
||||
fields:
|
||||
- _time
|
||||
- app
|
||||
- awsRegion
|
||||
- aws_account_id
|
||||
- command
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- dest
|
||||
- dvc
|
||||
- errorCode
|
||||
- eventCategory
|
||||
- eventID
|
||||
- eventName
|
||||
- eventSource
|
||||
- eventTime
|
||||
- eventType
|
||||
- eventVersion
|
||||
- eventtype
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- managementEvent
|
||||
- msg
|
||||
- object_category
|
||||
- product
|
||||
- punct
|
||||
- readOnly
|
||||
- recipientAccountId
|
||||
- region
|
||||
- requestID
|
||||
- requestParameters.bypassPolicyLockoutSafetyCheck
|
||||
- requestParameters.customerMasterKeySpec
|
||||
- requestParameters.description
|
||||
- requestParameters.keyUsage
|
||||
- requestParameters.origin
|
||||
- requestParameters.policy
|
||||
- resources{}.ARN
|
||||
- resources{}.accountId
|
||||
- resources{}.type
|
||||
- responseElements.keyMetadata.aWSAccountId
|
||||
- responseElements.keyMetadata.arn
|
||||
- responseElements.keyMetadata.creationDate
|
||||
- responseElements.keyMetadata.customerMasterKeySpec
|
||||
- responseElements.keyMetadata.description
|
||||
- responseElements.keyMetadata.enabled
|
||||
- responseElements.keyMetadata.encryptionAlgorithms{}
|
||||
- responseElements.keyMetadata.keyId
|
||||
- responseElements.keyMetadata.keyManager
|
||||
- responseElements.keyMetadata.keyState
|
||||
- responseElements.keyMetadata.keyUsage
|
||||
- responseElements.keyMetadata.origin
|
||||
- signature
|
||||
- source
|
||||
- sourceIPAddress
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src
|
||||
- src_ip
|
||||
- start_time
|
||||
- tag
|
||||
- tag::eventtype
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- user
|
||||
- userAgent
|
||||
- userIdentity.accessKeyId
|
||||
- userIdentity.accountId
|
||||
- userIdentity.arn
|
||||
- userIdentity.principalId
|
||||
- userIdentity.sessionContext.attributes.creationDate
|
||||
- userIdentity.sessionContext.attributes.mfaAuthenticated
|
||||
- userIdentity.sessionContext.sessionIssuer.accountId
|
||||
- userIdentity.sessionContext.sessionIssuer.arn
|
||||
- userIdentity.sessionContext.sessionIssuer.principalId
|
||||
- userIdentity.sessionContext.sessionIssuer.type
|
||||
- userIdentity.sessionContext.sessionIssuer.userName
|
||||
- userIdentity.type
|
||||
- userName
|
||||
- user_access_key
|
||||
- user_agent
|
||||
- user_arn
|
||||
- user_group_id
|
||||
- user_id
|
||||
- user_name
|
||||
- user_type
|
||||
- vendor
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
- vendor_region
|
||||
example_log: '{"eventVersion": "1.08", "userIdentity": {"type": "AssumedRole", "principalId": "AROAIJIESMXKGCJRCTPR6:pbareiss@splunk.local", "arn": "arn:aws:sts::111111111111:assumed-role/okta_adm_role/pbareiss@splunk.local", "accountId": "111111111111", "accessKeyId": "ASIAYTOGP2RLK74OPBDR", "sessionContext": {"sessionIssuer": {"type": "Role", "principalId": "AROAIJIESMXKGCJRCTPR6", "arn": "arn:aws:iam::111111111111:role/okta_adm_role", "accountId": "111111111111", "userName": "okta_adm_role"}, "webIdFederationData": {}, "attributes": {"mfaAuthenticated": "false", "creationDate": "2021-01-11T09:03:18Z"}}}, "eventTime": "2021-01-11T09:56:31Z", "eventSource": "kms.amazonaws.com", "eventName": "CreateKey", "awsRegion": "us-west-2", "sourceIPAddress": "95.90.199.65", "userAgent": "aws-internal/3 aws-sdk-java/1.11.893 Linux/4.9.230-0.1.ac.223.84.332.metal1.x86_64 OpenJDK_64-Bit_Server_VM/25.272-b10 java/1.8.0_272 vendor/Oracle_Corporation", "requestParameters": {"origin": "AWS_KMS", "policy": "{\n \"Id\": \"key-consolepolicy-3\",\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"Enable IAM User Permissions\",\n \"Effect\": \"Allow\",\n \"Principal\": {\n \"AWS\": \"arn:aws:iam::111111111111:root\"\n },\n \"Action\": \"kms:*\",\n \"Resource\": \"*\"\n },\n {\n \"Sid\": \"Allow access for Key Administrators\",\n \"Effect\": \"Allow\",\n \"Principal\": {\n \"AWS\": \"arn:aws:iam::111111111111:user/patrick_cli\"\n },\n \"Action\": [\n \"kms:Create*\",\n \"kms:Describe*\",\n \"kms:Enable*\",\n \"kms:List*\",\n \"kms:Put*\",\n \"kms:Update*\",\n \"kms:Revoke*\",\n \"kms:Disable*\",\n \"kms:Get*\",\n \"kms:Delete*\",\n \"kms:TagResource\",\n \"kms:UntagResource\",\n \"kms:ScheduleKeyDeletion\",\n \"kms:CancelKeyDeletion\"\n ],\n \"Resource\": \"*\"\n },\n {\n \"Sid\": \"Allow use of the key\",\n \"Effect\": \"Allow\",\n \"Principal\": {\n \"AWS\": \"arn:aws:iam::111111111111:user/patrick_cli\"\n },\n \"Action\": [\n \"kms:Encrypt\",\n \"kms:Decrypt\",\n \"kms:ReEncrypt*\",\n \"kms:GenerateDataKey*\",\n \"kms:DescribeKey\"\n ],\n \"Resource\": \"*\"\n },\n {\n \"Sid\": \"Allow attachment of persistent resources\",\n \"Effect\": \"Allow\",\n \"Principal\": {\n \"AWS\": \"arn:aws:iam::111111111111:user/patrick_cli\"\n },\n \"Action\": [\n \"kms:CreateGrant\",\n \"kms:ListGrants\",\n \"kms:RevokeGrant\"\n ],\n \"Resource\": \"*\",\n \"Condition\": {\n \"Bool\": {\n \"kms:GrantIsForAWSResource\": \"true\"\n }\n }\n },\n {\n \"Sid\": \"Allow use of the key\",\n \"Effect\": \"Allow\",\n \"Principal\": {\n \"AWS\": \"*\"\n },\n \"Action\": [\n \"kms:Encrypt\"\n ],\n \"Resource\": \"*\"\n }\n ]\n}", "description": "", "customerMasterKeySpec": "SYMMETRIC_DEFAULT", "bypassPolicyLockoutSafetyCheck": false, "tags": [], "keyUsage": "ENCRYPT_DECRYPT"}, "responseElements": {"keyMetadata": {"aWSAccountId": "111111111111", "keyId": "f2a82583-a7d3-4c92-8787-fe2baab1cee1", "arn": "arn:aws:kms:us-west-2:111111111111:key/f2a82583-a7d3-4c92-8787-fe2baab1cee1", "creationDate": "Jan 11, 2021, 9:56:30 AM", "enabled": true, "description": "", "keyUsage": "ENCRYPT_DECRYPT", "keyState": "Enabled", "origin": "AWS_KMS", "keyManager": "CUSTOMER", "customerMasterKeySpec": "SYMMETRIC_DEFAULT", "encryptionAlgorithms": ["SYMMETRIC_DEFAULT"]}}, "requestID": "3356af25-a237-471f-ba5e-abb37d4a256f", "eventID": "f09518ac-5ae5-4214-80ee-4f23ccdedd4c", "readOnly": false, "resources": [{"accountId": "111111111111", "type": "AWS::KMS::Key", "ARN": "arn:aws:kms:us-west-2:111111111111:key/f2a82583-a7d3-4c92-8787-fe2baab1cee1"}], "eventType": "AwsApiCall", "managementEvent": true, "eventCategory": "Management", "recipientAccountId": "111111111111"}'
|
||||
@@ -0,0 +1,79 @@
|
||||
event_name: AWS CloudTrail CreateLoginProfile
|
||||
fields:
|
||||
- _time
|
||||
- action
|
||||
- app
|
||||
- awsRegion
|
||||
- aws_account_id
|
||||
- change_type
|
||||
- command
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- dest
|
||||
- dvc
|
||||
- errorCode
|
||||
- eventCategory
|
||||
- eventID
|
||||
- eventName
|
||||
- eventSource
|
||||
- eventTime
|
||||
- eventType
|
||||
- eventVersion
|
||||
- eventtype
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- managementEvent
|
||||
- msg
|
||||
- object_category
|
||||
- product
|
||||
- punct
|
||||
- readOnly
|
||||
- recipientAccountId
|
||||
- region
|
||||
- requestID
|
||||
- requestParameters.passwordResetRequired
|
||||
- requestParameters.userName
|
||||
- responseElements.loginProfile.createDate
|
||||
- responseElements.loginProfile.passwordResetRequired
|
||||
- responseElements.loginProfile.userName
|
||||
- signature
|
||||
- source
|
||||
- sourceIPAddress
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src
|
||||
- src_ip
|
||||
- start_time
|
||||
- status
|
||||
- tag
|
||||
- tag::eventtype
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- user
|
||||
- userAgent
|
||||
- userIdentity.accessKeyId
|
||||
- userIdentity.accountId
|
||||
- userIdentity.arn
|
||||
- userIdentity.principalId
|
||||
- userIdentity.type
|
||||
- userIdentity.userName
|
||||
- userName
|
||||
- user_access_key
|
||||
- user_agent
|
||||
- user_arn
|
||||
- user_group_id
|
||||
- user_id
|
||||
- user_name
|
||||
- user_type
|
||||
- vendor
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
- vendor_region
|
||||
example_log: '{"eventVersion": "1.08", "userIdentity": {"type": "IAMUser", "principalId": "AIDAYTOGP2RLEHRX5YWNV", "arn": "arn:aws:iam::111111111111:user/bhavin_cli", "accountId": "111111111111", "accessKeyId": "AKIAYTOGP2RLLAA6NJUM", "userName": "bhavin_cli"}, "eventTime": "2021-03-05T01:02:38Z", "eventSource": "iam.amazonaws.com", "eventName": "CreateLoginProfile", "awsRegion": "us-east-1", "sourceIPAddress": "73.15.72.101", "userAgent": "aws-cli/2.0.62 Python/3.9.2 Darwin/19.6.0 source/x86_64 command/iam.create-login-profile", "requestParameters": {"userName": "AtomicRedTeam", "passwordResetRequired": false}, "responseElements": {"loginProfile": {"userName": "AtomicRedTeam", "createDate": "Mar 5, 2021 1:02:38 AM", "passwordResetRequired": false}}, "requestID": "f1b90364-8aed-4559-96cf-f5f2009bb7cb", "eventID": "ffb76906-6dd1-4219-adfe-e26b92036a1e", "readOnly": false, "eventType": "AwsApiCall", "managementEvent": true, "eventCategory": "Management", "recipientAccountId": "111111111111"}'
|
||||
@@ -0,0 +1,95 @@
|
||||
event_name: AWS CloudTrail CreateNetworkAclEntry
|
||||
fields:
|
||||
- _time
|
||||
- action
|
||||
- app
|
||||
- awsRegion
|
||||
- aws_account_id
|
||||
- change_type
|
||||
- command
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- dest
|
||||
- direction
|
||||
- dvc
|
||||
- errorCode
|
||||
- eventCategory
|
||||
- eventID
|
||||
- eventName
|
||||
- eventSource
|
||||
- eventTime
|
||||
- eventType
|
||||
- eventVersion
|
||||
- eventtype
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- managementEvent
|
||||
- msg
|
||||
- object
|
||||
- object_category
|
||||
- object_id
|
||||
- product
|
||||
- protocol
|
||||
- protocol_code
|
||||
- punct
|
||||
- readOnly
|
||||
- recipientAccountId
|
||||
- region
|
||||
- requestID
|
||||
- requestParameters.aclProtocol
|
||||
- requestParameters.cidrBlock
|
||||
- requestParameters.egress
|
||||
- requestParameters.networkAclId
|
||||
- requestParameters.ruleAction
|
||||
- requestParameters.ruleNumber
|
||||
- responseElements._return
|
||||
- responseElements.requestId
|
||||
- rule_action
|
||||
- signature
|
||||
- source
|
||||
- sourceIPAddress
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src
|
||||
- src_ip
|
||||
- src_ip_range
|
||||
- start_time
|
||||
- status
|
||||
- tag
|
||||
- tag::eventtype
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- user
|
||||
- userAgent
|
||||
- userIdentity.accessKeyId
|
||||
- userIdentity.accountId
|
||||
- userIdentity.arn
|
||||
- userIdentity.principalId
|
||||
- userIdentity.sessionContext.attributes.creationDate
|
||||
- userIdentity.sessionContext.attributes.mfaAuthenticated
|
||||
- userIdentity.sessionContext.sessionIssuer.accountId
|
||||
- userIdentity.sessionContext.sessionIssuer.arn
|
||||
- userIdentity.sessionContext.sessionIssuer.principalId
|
||||
- userIdentity.sessionContext.sessionIssuer.type
|
||||
- userIdentity.sessionContext.sessionIssuer.userName
|
||||
- userIdentity.type
|
||||
- userName
|
||||
- user_access_key
|
||||
- user_agent
|
||||
- user_arn
|
||||
- user_group_id
|
||||
- user_id
|
||||
- user_name
|
||||
- user_type
|
||||
- vendor
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
- vendor_region
|
||||
example_log: '{"eventVersion": "1.08", "userIdentity": {"type": "AssumedRole", "principalId": "AROAIJIESMXKGCJRCTPR6:pbareiss@splunk.local", "arn": "arn:aws:sts::111111111111:assumed-role/okta_adm_role/pbareiss@splunk.local", "accountId": "111111111111", "accessKeyId": "ASIAYTOGP2RLF3F7BXZK", "sessionContext": {"sessionIssuer": {"type": "Role", "principalId": "AROAIJIESMXKGCJRCTPR6", "arn": "arn:aws:iam::111111111111:role/okta_adm_role", "accountId": "111111111111", "userName": "okta_adm_role"}, "webIdFederationData": {}, "attributes": {"mfaAuthenticated": "false", "creationDate": "2021-01-12T08:36:15Z"}}}, "eventTime": "2021-01-12T08:38:39Z", "eventSource": "ec2.amazonaws.com", "eventName": "CreateNetworkAclEntry", "awsRegion": "eu-central-1", "sourceIPAddress": "95.90.199.65", "userAgent": "console.ec2.amazonaws.com", "requestParameters": {"networkAclId": "acl-078ccebebcbabe175", "ruleNumber": 10, "egress": false, "ruleAction": "allow", "icmpTypeCode": {}, "portRange": {}, "aclProtocol": "-1", "cidrBlock": "0.0.0.0/0"}, "responseElements": {"requestId": "d29c9c32-3a72-48d3-b612-6ba795e9ec64", "_return": true}, "requestID": "d29c9c32-3a72-48d3-b612-6ba795e9ec64", "eventID": "6d1ce00e-4099-463c-8a4d-2af2fb2178ba", "readOnly": false, "eventType": "AwsApiCall", "managementEvent": true, "eventCategory": "Management", "recipientAccountId": "111111111111"}'
|
||||
@@ -0,0 +1,80 @@
|
||||
event_name: AWS CloudTrail CreatePolicyVersion
|
||||
fields:
|
||||
- _time
|
||||
- action
|
||||
- app
|
||||
- awsRegion
|
||||
- aws_account_id
|
||||
- change_type
|
||||
- command
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- dest
|
||||
- dvc
|
||||
- errorCode
|
||||
- eventCategory
|
||||
- eventID
|
||||
- eventName
|
||||
- eventSource
|
||||
- eventTime
|
||||
- eventType
|
||||
- eventVersion
|
||||
- eventtype
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- managementEvent
|
||||
- msg
|
||||
- object_category
|
||||
- product
|
||||
- punct
|
||||
- readOnly
|
||||
- recipientAccountId
|
||||
- region
|
||||
- requestID
|
||||
- requestParameters.policyArn
|
||||
- requestParameters.policyDocument
|
||||
- requestParameters.setAsDefault
|
||||
- responseElements.policyVersion.createDate
|
||||
- responseElements.policyVersion.isDefaultVersion
|
||||
- responseElements.policyVersion.versionId
|
||||
- signature
|
||||
- source
|
||||
- sourceIPAddress
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src
|
||||
- src_ip
|
||||
- start_time
|
||||
- status
|
||||
- tag
|
||||
- tag::eventtype
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- user
|
||||
- userAgent
|
||||
- userIdentity.accessKeyId
|
||||
- userIdentity.accountId
|
||||
- userIdentity.arn
|
||||
- userIdentity.principalId
|
||||
- userIdentity.type
|
||||
- userIdentity.userName
|
||||
- userName
|
||||
- user_access_key
|
||||
- user_agent
|
||||
- user_arn
|
||||
- user_group_id
|
||||
- user_id
|
||||
- user_name
|
||||
- user_type
|
||||
- vendor
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
- vendor_region
|
||||
example_log: '{"eventVersion": "1.08", "userIdentity": {"type": "IAMUser", "principalId": "AIDAYTOGP2RLNMCDVJZAY", "arn": "arn:aws:iam::111111111111:user/rhino_escalate", "accountId": "111111111111", "accessKeyId": "AKIAYTOGP2RLHSQZPZFZ", "userName": "rhino_escalate"}, "eventTime": "2021-02-23T00:02:30Z", "eventSource": "iam.amazonaws.com", "eventName": "CreatePolicyVersion", "awsRegion": "us-east-1", "sourceIPAddress": "73.15.72.101", "userAgent": "aws-cli/2.0.62 Python/3.9.0 Darwin/19.6.0 source/x86_64 command/iam.create-policy-version", "requestParameters": {"policyArn": "arn:aws:iam::111111111111:policy/rhino_escalate", "policyDocument": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"AllowEverything\",\n \"Effect\": \"Allow\",\n \"Action\": \"iam:*\",\n \"Resource\": \"*\"\n }\n ]\n }", "setAsDefault": true}, "responseElements": {"policyVersion": {"versionId": "v2", "isDefaultVersion": true, "createDate": "Feb 23, 2021 12:02:30 AM"}}, "requestID": "fa42b4b2-f34a-4673-8f9f-b25cf1f5005a", "eventID": "33149175-90fd-4cff-a43b-408e4f848c1c", "readOnly": false, "eventType": "AwsApiCall", "managementEvent": true, "eventCategory": "Management", "recipientAccountId": "111111111111"}'
|
||||
@@ -0,0 +1,89 @@
|
||||
event_name: AWS CloudTrail CreateSnapshot
|
||||
fields:
|
||||
- _time
|
||||
- app
|
||||
- awsRegion
|
||||
- aws_account_id
|
||||
- change_type
|
||||
- command
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- dest
|
||||
- dvc
|
||||
- errorCode
|
||||
- eventCategory
|
||||
- eventID
|
||||
- eventName
|
||||
- eventSource
|
||||
- eventTime
|
||||
- eventType
|
||||
- eventVersion
|
||||
- eventtype
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- managementEvent
|
||||
- msg
|
||||
- object_category
|
||||
- product
|
||||
- punct
|
||||
- readOnly
|
||||
- recipientAccountId
|
||||
- region
|
||||
- requestID
|
||||
- requestParameters.tagSpecificationSet.items{}.resourceType
|
||||
- requestParameters.tagSpecificationSet.items{}.tags{}.key
|
||||
- requestParameters.tagSpecificationSet.items{}.tags{}.value
|
||||
- requestParameters.volumeId
|
||||
- responseElements.encrypted
|
||||
- responseElements.ownerId
|
||||
- responseElements.requestId
|
||||
- responseElements.snapshotId
|
||||
- responseElements.startTime
|
||||
- responseElements.status
|
||||
- responseElements.tagSet.items{}.key
|
||||
- responseElements.tagSet.items{}.value
|
||||
- responseElements.volumeId
|
||||
- responseElements.volumeSize
|
||||
- signature
|
||||
- source
|
||||
- sourceIPAddress
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src
|
||||
- src_ip
|
||||
- start_time
|
||||
- tag
|
||||
- tag::eventtype
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- tlsDetails.cipherSuite
|
||||
- tlsDetails.clientProvidedHostHeader
|
||||
- tlsDetails.tlsVersion
|
||||
- user
|
||||
- userAgent
|
||||
- userIdentity.accessKeyId
|
||||
- userIdentity.accountId
|
||||
- userIdentity.arn
|
||||
- userIdentity.principalId
|
||||
- userIdentity.type
|
||||
- userIdentity.userName
|
||||
- userName
|
||||
- user_access_key
|
||||
- user_agent
|
||||
- user_arn
|
||||
- user_group_id
|
||||
- user_id
|
||||
- user_name
|
||||
- user_type
|
||||
- vendor
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
- vendor_region
|
||||
example_log: '{"eventVersion": "1.08", "userIdentity": {"type": "IAMUser", "principalId": "AIDAYTOGP2RLCNEAQXWZV", "arn": "arn:aws:iam::111111111111:user/bhavin_console", "accountId": "111111111111", "accessKeyId": "AKIAYTOGP2RLF5EAXXXX", "userName": "bhavin_console"}, "eventTime": "2023-03-20T22:31:18Z", "eventSource": "ec2.amazonaws.com", "eventName": "CreateSnapshot", "awsRegion": "us-west-2", "sourceIPAddress": "72.135.1.1", "userAgent": "APN/1.0 HashiCorp/1.0 Terraform/1.1.2 (+https://www.terraform.io) terraform-provider-aws/3.76.1 (+https://registry.terraform.io/providers/hashicorp/aws) aws-sdk-go/1.44.157 (go1.19.3; darwin; amd64) stratus-red-team_46665bb8-dc15-4aba-a5ad-a362772b3f0d HashiCorp-terraform-exec/0.17.3", "requestParameters": {"volumeId": "vol-0363e53e12f67c9b7", "tagSpecificationSet": {"items": [{"resourceType": "snapshot", "tags": [{"key": "StratusRedTeam", "value": "true"}]}]}}, "responseElements": {"requestId": "fefed928-d461-45f0-802f-a99d94c833a8", "snapshotId": "snap-02effb3bb62786b18", "volumeId": "vol-0363e53e12f67c9b7", "status": "pending", "startTime": 1679351478226, "ownerId": "111111111111", "volumeSize": "1", "encrypted": false, "tagSet": {"items": [{"key": "StratusRedTeam", "value": "true"}]}}, "requestID": "fefed928-d461-45f0-802f-a99d94c833a8", "eventID": "2d52d141-d1e6-4d1f-a380-1461c1bf9f83", "readOnly": false, "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "111111111111", "eventCategory": "Management", "tlsDetails": {"tlsVersion": "TLSv1.2", "cipherSuite": "ECDHE-RSA-AES128-GCM-SHA256", "clientProvidedHostHeader": "ec2.us-west-2.amazonaws.com"}}'
|
||||
@@ -0,0 +1,88 @@
|
||||
event_name: AWS CloudTrail CreateTask
|
||||
fields:
|
||||
- _time
|
||||
- app
|
||||
- awsRegion
|
||||
- aws_account_id
|
||||
- command
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- dest
|
||||
- dvc
|
||||
- errorCode
|
||||
- eventCategory
|
||||
- eventID
|
||||
- eventName
|
||||
- eventSource
|
||||
- eventTime
|
||||
- eventType
|
||||
- eventVersion
|
||||
- eventtype
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- managementEvent
|
||||
- msg
|
||||
- object_category
|
||||
- product
|
||||
- punct
|
||||
- readOnly
|
||||
- recipientAccountId
|
||||
- region
|
||||
- requestID
|
||||
- requestParameters.cloudWatchLogGroupArn
|
||||
- requestParameters.destinationLocationArn
|
||||
- requestParameters.options.logLevel
|
||||
- requestParameters.options.verifyMode
|
||||
- requestParameters.schedule.scheduleExpression
|
||||
- requestParameters.sourceLocationArn
|
||||
- responseElements.taskArn
|
||||
- sessionCredentialFromConsole
|
||||
- signature
|
||||
- source
|
||||
- sourceIPAddress
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src
|
||||
- src_ip
|
||||
- start_time
|
||||
- tag
|
||||
- tag::eventtype
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- tlsDetails.cipherSuite
|
||||
- tlsDetails.clientProvidedHostHeader
|
||||
- tlsDetails.tlsVersion
|
||||
- user
|
||||
- userAgent
|
||||
- userIdentity.accessKeyId
|
||||
- userIdentity.accountId
|
||||
- userIdentity.arn
|
||||
- userIdentity.principalId
|
||||
- userIdentity.sessionContext.attributes.creationDate
|
||||
- userIdentity.sessionContext.attributes.mfaAuthenticated
|
||||
- userIdentity.sessionContext.sessionIssuer.accountId
|
||||
- userIdentity.sessionContext.sessionIssuer.arn
|
||||
- userIdentity.sessionContext.sessionIssuer.principalId
|
||||
- userIdentity.sessionContext.sessionIssuer.type
|
||||
- userIdentity.sessionContext.sessionIssuer.userName
|
||||
- userIdentity.type
|
||||
- userName
|
||||
- user_access_key
|
||||
- user_agent
|
||||
- user_arn
|
||||
- user_group_id
|
||||
- user_id
|
||||
- user_name
|
||||
- user_type
|
||||
- vendor
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
- vendor_region
|
||||
example_log: '{"eventVersion": "1.08", "userIdentity": {"type": "AssumedRole", "principalId": "AROAYTOGP2RLDF6WQQQQQ:abc@acme.com", "arn": "arn:aws:sts::111111111111:assumed-role/AWSReservedSSO_SPLKAdministratorAccess_d9ce1347d0a6dd3f/abc@acme.com", "accountId": "111111111111", "accessKeyId": "ASIAYTOGP2RLOB2GM111", "sessionContext": {"sessionIssuer": {"type": "Role", "principalId": "AROAYTOGP2RLDF6WQQQQQ", "arn": "arn:aws:iam::111111111111:role/aws-reserved/sso.amazonaws.com/us-west-2/AWSReservedSSO_SPLKAdministratorAccess_d9ce1347d0a6dd3f", "accountId": "111111111111", "userName": "AWSReservedSSO_SPLKAdministratorAccess_d9ce1347d0a6dd3f"}, "webIdFederationData": {}, "attributes": {"creationDate": "2023-03-14T21:53:15Z", "mfaAuthenticated": "false"}}}, "eventTime": "2023-03-14T22:05:36Z", "eventSource": "datasync.amazonaws.com", "eventName": "CreateTask", "awsRegion": "us-west-2", "sourceIPAddress": "1.1.1.1", "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36", "requestParameters": {"sourceLocationArn": "arn:aws:datasync:us-west-2:111111111111:location/loc-0921d426f7955d416", "destinationLocationArn": "arn:aws:datasync:us-west-1:111111111111:location/loc-0b94cf657c358ef06", "cloudWatchLogGroupArn": "arn:aws:logs:us-west-2:111111111111:log-group:/aws/datasync", "options": {"verifyMode": "ONLY_FILES_TRANSFERRED", "logLevel": "BASIC"}, "excludes": [], "schedule": {"scheduleExpression": "cron(6 * * * ? *)"}, "tags": [], "includes": []}, "responseElements": {"taskArn": "arn:aws:datasync:us-west-2:111111111111:task/task-0c77dc0d4b0792ce6"}, "requestID": "de5f4282-aa2b-49b8-8d1b-c3bdb11e2fba", "eventID": "def4cd05-f845-4aec-bc96-07d6ce420d16", "readOnly": false, "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "111111111111", "eventCategory": "Management", "tlsDetails": {"tlsVersion": "TLSv1.2", "cipherSuite": "ECDHE-RSA-AES128-GCM-SHA256", "clientProvidedHostHeader": "datasync.us-west-2.amazonaws.com"}, "sessionCredentialFromConsole": "true"}'
|
||||
@@ -0,0 +1,78 @@
|
||||
event_name: AWS CloudTrail CreateVirtualMFADevice
|
||||
fields:
|
||||
- _time
|
||||
- action
|
||||
- app
|
||||
- awsRegion
|
||||
- aws_account_id
|
||||
- change_type
|
||||
- command
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- dest
|
||||
- dvc
|
||||
- errorCode
|
||||
- eventCategory
|
||||
- eventID
|
||||
- eventName
|
||||
- eventSource
|
||||
- eventTime
|
||||
- eventType
|
||||
- eventVersion
|
||||
- eventtype
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- managementEvent
|
||||
- msg
|
||||
- object_category
|
||||
- product
|
||||
- punct
|
||||
- readOnly
|
||||
- recipientAccountId
|
||||
- region
|
||||
- requestID
|
||||
- requestParameters.path
|
||||
- requestParameters.virtualMFADeviceName
|
||||
- responseElements.virtualMFADevice.serialNumber
|
||||
- sessionCredentialFromConsole
|
||||
- signature
|
||||
- source
|
||||
- sourceIPAddress
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src
|
||||
- src_ip
|
||||
- start_time
|
||||
- status
|
||||
- tag
|
||||
- tag::eventtype
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- user
|
||||
- userAgent
|
||||
- userIdentity.accessKeyId
|
||||
- userIdentity.accountId
|
||||
- userIdentity.arn
|
||||
- userIdentity.principalId
|
||||
- userIdentity.sessionContext.attributes.creationDate
|
||||
- userIdentity.sessionContext.attributes.mfaAuthenticated
|
||||
- userIdentity.type
|
||||
- userName
|
||||
- user_access_key
|
||||
- user_agent
|
||||
- user_arn
|
||||
- user_group_id
|
||||
- user_id
|
||||
- user_type
|
||||
- vendor
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
- vendor_region
|
||||
example_log: '{"eventVersion": "1.08", "userIdentity": {"type": "Root", "principalId": "140429656527", "arn": "arn:aws:iam::140429656527:root", "accountId": "140429656527", "accessKeyId": "ASIASBMSCQHH2YXNXJBU", "sessionContext": {"sessionIssuer": {}, "webIdFederationData": {}, "attributes": {"creationDate": "2023-01-30T22:59:36Z", "mfaAuthenticated": "false"}}}, "eventTime": "2023-01-30T23:02:23Z", "eventSource": "iam.amazonaws.com", "eventName": "CreateVirtualMFADevice", "awsRegion": "us-east-1", "sourceIPAddress": "23.93.193.6", "userAgent": "AWS Internal", "requestParameters": {"path": "/", "virtualMFADeviceName": "strt_mfa_2"}, "responseElements": {"virtualMFADevice": {"serialNumber": "arn:aws:iam::140429656527:mfa/strt_mfa_2"}}, "requestID": "2fbe2074-55f8-4ec6-ad32-0b250803cf46", "eventID": "7e1c493d-c3c3-4f4a-ae4f-8cdd38970027", "readOnly": false, "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "140429656527", "eventCategory": "Management", "sessionCredentialFromConsole": "true"}'
|
||||
@@ -0,0 +1,78 @@
|
||||
event_name: AWS CloudTrail DeactivateMFADevice
|
||||
fields:
|
||||
- _time
|
||||
- action
|
||||
- app
|
||||
- awsRegion
|
||||
- aws_account_id
|
||||
- change_type
|
||||
- command
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- dest
|
||||
- dvc
|
||||
- errorCode
|
||||
- eventCategory
|
||||
- eventID
|
||||
- eventName
|
||||
- eventSource
|
||||
- eventTime
|
||||
- eventType
|
||||
- eventVersion
|
||||
- eventtype
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- managementEvent
|
||||
- msg
|
||||
- object_category
|
||||
- product
|
||||
- punct
|
||||
- readOnly
|
||||
- recipientAccountId
|
||||
- region
|
||||
- requestID
|
||||
- requestParameters.serialNumber
|
||||
- requestParameters.userName
|
||||
- responseElements
|
||||
- signature
|
||||
- source
|
||||
- sourceIPAddress
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src
|
||||
- src_ip
|
||||
- start_time
|
||||
- status
|
||||
- tag
|
||||
- tag::eventtype
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- user
|
||||
- userAgent
|
||||
- userIdentity.accessKeyId
|
||||
- userIdentity.accountId
|
||||
- userIdentity.arn
|
||||
- userIdentity.principalId
|
||||
- userIdentity.sessionContext.attributes.creationDate
|
||||
- userIdentity.sessionContext.attributes.mfaAuthenticated
|
||||
- userIdentity.type
|
||||
- userName
|
||||
- user_access_key
|
||||
- user_agent
|
||||
- user_arn
|
||||
- user_group_id
|
||||
- user_id
|
||||
- user_name
|
||||
- user_type
|
||||
- vendor
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
- vendor_region
|
||||
example_log: '{"eventVersion": "1.08", "userIdentity": {"type": "Root", "principalId": "111111111111", "arn": "arn:aws:iam::111111111111:root", "accountId": "111111111111", "accessKeyId": "ASIASBMSCQHHWAIHMHUX", "sessionContext": {"sessionIssuer": {}, "webIdFederationData": {}, "attributes": {"creationDate": "2022-10-04T16:13:23Z", "mfaAuthenticated": "true"}}}, "eventTime": "2022-10-04T16:13:45Z", "eventSource": "iam.amazonaws.com", "eventName": "DeactivateMFADevice", "awsRegion": "us-east-1", "sourceIPAddress": "142.254.89.27", "userAgent": "Coral/Netty4", "requestParameters": {"userName": "AWS ROOT USER", "serialNumber": "arn:aws:iam::111111111111:mfa/root-account-mfa-device"}, "responseElements": null, "requestID": "d27cfb15-34b4-4c16-82bc-a55d15b4e47d", "eventID": "bfe9fd91-0b4d-470a-9c03-77839151806d", "readOnly": false, "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "111111111111", "eventCategory": "Management"}'
|
||||
@@ -0,0 +1,79 @@
|
||||
event_name: AWS CloudTrail DeleteAccountPasswordPolicy
|
||||
fields:
|
||||
- _time
|
||||
- action
|
||||
- app
|
||||
- awsRegion
|
||||
- aws_account_id
|
||||
- change_type
|
||||
- command
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- desc
|
||||
- dest
|
||||
- dvc
|
||||
- errorCode
|
||||
- eventCategory
|
||||
- eventID
|
||||
- eventName
|
||||
- eventSource
|
||||
- eventTime
|
||||
- eventType
|
||||
- eventVersion
|
||||
- eventtype
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- managementEvent
|
||||
- msg
|
||||
- object_category
|
||||
- product
|
||||
- punct
|
||||
- readOnly
|
||||
- recipientAccountId
|
||||
- region
|
||||
- requestID
|
||||
- requestParameters
|
||||
- responseElements
|
||||
- sessionCredentialFromConsole
|
||||
- signature
|
||||
- source
|
||||
- sourceIPAddress
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src
|
||||
- src_ip
|
||||
- start_time
|
||||
- status
|
||||
- tag
|
||||
- tag::eventtype
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- user
|
||||
- userAgent
|
||||
- userIdentity.accessKeyId
|
||||
- userIdentity.accountId
|
||||
- userIdentity.arn
|
||||
- userIdentity.principalId
|
||||
- userIdentity.sessionContext.attributes.creationDate
|
||||
- userIdentity.sessionContext.attributes.mfaAuthenticated
|
||||
- userIdentity.type
|
||||
- userName
|
||||
- user_access_key
|
||||
- user_agent
|
||||
- user_arn
|
||||
- user_group_id
|
||||
- user_id
|
||||
- user_name
|
||||
- user_type
|
||||
- vendor
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
- vendor_region
|
||||
example_log: '{"eventVersion": "1.08", "userIdentity": {"type": "Root", "principalId": "111111111111", "arn": "arn:aws:iam::111111111111:root", "accountId": "111111111111", "accessKeyId": "ASIASBMSCQHHWMDJXSE6", "sessionContext": {"sessionIssuer": {}, "webIdFederationData": {}, "attributes": {"creationDate": "2023-01-26T18:44:21Z", "mfaAuthenticated": "false"}}}, "eventTime": "2023-01-26T21:23:22Z", "eventSource": "iam.amazonaws.com", "eventName": "DeleteAccountPasswordPolicy", "awsRegion": "us-east-1", "sourceIPAddress": "23.93.193.7", "userAgent": "AWS Internal", "requestParameters": null, "responseElements": null, "requestID": "e3616938-1aac-4abd-9ea3-3b0367b85082", "eventID": "bbd8cb02-22ba-4d1b-b23d-b82975463376", "readOnly": false, "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "111111111111", "eventCategory": "Management", "sessionCredentialFromConsole": "true"}'
|
||||
@@ -0,0 +1,75 @@
|
||||
event_name: AWS CloudTrail DeleteDetector
|
||||
fields:
|
||||
- _time
|
||||
- app
|
||||
- awsRegion
|
||||
- aws_account_id
|
||||
- command
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- dest
|
||||
- dvc
|
||||
- errorCode
|
||||
- eventCategory
|
||||
- eventID
|
||||
- eventName
|
||||
- eventSource
|
||||
- eventTime
|
||||
- eventType
|
||||
- eventVersion
|
||||
- eventtype
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- managementEvent
|
||||
- msg
|
||||
- object_category
|
||||
- product
|
||||
- punct
|
||||
- readOnly
|
||||
- recipientAccountId
|
||||
- region
|
||||
- requestID
|
||||
- requestParameters.detectorId
|
||||
- responseElements.__type
|
||||
- responseElements.message
|
||||
- result_id
|
||||
- signature
|
||||
- source
|
||||
- sourceIPAddress
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src
|
||||
- src_ip
|
||||
- start_time
|
||||
- tag
|
||||
- tag::eventtype
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- user
|
||||
- userAgent
|
||||
- userIdentity.accessKeyId
|
||||
- userIdentity.accountId
|
||||
- userIdentity.arn
|
||||
- userIdentity.principalId
|
||||
- userIdentity.type
|
||||
- userIdentity.userName
|
||||
- userName
|
||||
- user_access_key
|
||||
- user_agent
|
||||
- user_arn
|
||||
- user_group_id
|
||||
- user_id
|
||||
- user_name
|
||||
- user_type
|
||||
- vendor
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
- vendor_region
|
||||
example_log: '{"eventVersion": "1.08", "userIdentity": {"type": "IAMUser", "principalId": "AIDAYTOGP2RLI4PXTGCEU", "arn": "arn:aws:iam::111111111111:user/gowthamaraj_cli", "accountId": "111111111111", "accessKeyId": "AKIAYTOGP2RLFLKADUVG", "userName": "gowthamaraj_cli"}, "eventTime": "2022-07-21T20:27:54Z", "eventSource": "guardduty.amazonaws.com", "eventName": "DeleteDetector", "awsRegion": "us-west-2", "sourceIPAddress": "67.171.71.185", "userAgent": "aws-cli/2.7.3 Python/3.9.13 Darwin/21.5.0 source/x86_64 prompt/off command/guardduty.delete-detector", "errorCode": "BadRequestException", "requestParameters": {"detectorId": "123"}, "responseElements": {"message": "The request is rejected because the parameter detectorId has an invalid value.", "__type": "InvalidInputException"}, "requestID": "1e832076-d7a8-432b-b0df-54ba62f6b62c", "eventID": "c1367a2f-8910-4e64-9256-a854d2e9f37d", "readOnly": false, "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "111111111111", "eventCategory": "Management"}'
|
||||
@@ -0,0 +1,80 @@
|
||||
event_name: AWS CloudTrail DeleteGroup
|
||||
fields:
|
||||
- _time
|
||||
- action
|
||||
- app
|
||||
- awsRegion
|
||||
- aws_account_id
|
||||
- change_type
|
||||
- command
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- dest
|
||||
- dvc
|
||||
- errorCode
|
||||
- errorMessage
|
||||
- eventCategory
|
||||
- eventID
|
||||
- eventName
|
||||
- eventSource
|
||||
- eventTime
|
||||
- eventType
|
||||
- eventVersion
|
||||
- eventtype
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- managementEvent
|
||||
- msg
|
||||
- object_category
|
||||
- product
|
||||
- punct
|
||||
- readOnly
|
||||
- reason
|
||||
- recipientAccountId
|
||||
- region
|
||||
- requestID
|
||||
- requestParameters.groupName
|
||||
- responseElements
|
||||
- result
|
||||
- result_id
|
||||
- signature
|
||||
- source
|
||||
- sourceIPAddress
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src
|
||||
- src_ip
|
||||
- start_time
|
||||
- status
|
||||
- tag
|
||||
- tag::eventtype
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- user
|
||||
- userAgent
|
||||
- userIdentity.accessKeyId
|
||||
- userIdentity.accountId
|
||||
- userIdentity.arn
|
||||
- userIdentity.principalId
|
||||
- userIdentity.type
|
||||
- userIdentity.userName
|
||||
- userName
|
||||
- user_access_key
|
||||
- user_agent
|
||||
- user_arn
|
||||
- user_group_id
|
||||
- user_id
|
||||
- user_name
|
||||
- user_type
|
||||
- vendor
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
- vendor_region
|
||||
example_log: '{"eventVersion": "1.08", "userIdentity": {"type": "IAMUser", "principalId": "AIDAYTOGP2RLEHRX5YWNV", "arn": "arn:aws:iam::121522247101:user/bhavin_cli", "accountId": "121522247101", "accessKeyId": "AKIAYTOGP2RLLAA6NJUM", "userName": "bhavin_cli"}, "eventTime": "2021-04-07T00:17:50Z", "eventSource": "iam.amazonaws.com", "eventName": "DeleteGroup", "awsRegion": "us-east-1", "sourceIPAddress": "12.12.12.20", "userAgent": "aws-cli/2.0.62 Python/3.9.2 Darwin/19.6.0 source/x86_64 command/iam.delete-group", "errorCode": "NoSuchEntityException", "errorMessage": "The group with name AtomicRedTeam_Victim cannot be found.", "requestParameters": {"groupName": "AtomicRedTeam_Victim"}, "responseElements": null, "requestID": "15684d3b-a8c5-4334-a996-16619e901c17", "eventID": "ab65dca3-3d28-41f4-9f99-443606cc49fe", "readOnly": false, "eventType": "AwsApiCall", "managementEvent": true, "eventCategory": "Management", "recipientAccountId": "121522247101"}'
|
||||
@@ -0,0 +1,76 @@
|
||||
event_name: AWS CloudTrail DeleteIPSet
|
||||
fields:
|
||||
- _time
|
||||
- app
|
||||
- awsRegion
|
||||
- aws_account_id
|
||||
- command
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- dest
|
||||
- dvc
|
||||
- errorCode
|
||||
- eventCategory
|
||||
- eventID
|
||||
- eventName
|
||||
- eventSource
|
||||
- eventTime
|
||||
- eventType
|
||||
- eventVersion
|
||||
- eventtype
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- managementEvent
|
||||
- msg
|
||||
- object_category
|
||||
- product
|
||||
- punct
|
||||
- readOnly
|
||||
- recipientAccountId
|
||||
- region
|
||||
- requestID
|
||||
- requestParameters.detectorId
|
||||
- requestParameters.ipSetId
|
||||
- responseElements.__type
|
||||
- responseElements.message
|
||||
- result_id
|
||||
- signature
|
||||
- source
|
||||
- sourceIPAddress
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src
|
||||
- src_ip
|
||||
- start_time
|
||||
- tag
|
||||
- tag::eventtype
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- user
|
||||
- userAgent
|
||||
- userIdentity.accessKeyId
|
||||
- userIdentity.accountId
|
||||
- userIdentity.arn
|
||||
- userIdentity.principalId
|
||||
- userIdentity.type
|
||||
- userIdentity.userName
|
||||
- userName
|
||||
- user_access_key
|
||||
- user_agent
|
||||
- user_arn
|
||||
- user_group_id
|
||||
- user_id
|
||||
- user_name
|
||||
- user_type
|
||||
- vendor
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
- vendor_region
|
||||
example_log: '{"eventVersion": "1.08", "userIdentity": {"type": "IAMUser", "principalId": "AIDAYTOGP2RLEHRX5YWNV", "arn": "arn:aws:iam::111111111111:user/bhavin_cli", "accountId": "111111111111", "accessKeyId": "AKIAYTOGP2RLKQ3U2PDY", "userName": "bhavin_cli"}, "eventTime": "2022-07-26T23:14:57Z", "eventSource": "guardduty.amazonaws.com", "eventName": "DeleteIPSet", "awsRegion": "us-west-2", "sourceIPAddress": "142.254.89.27", "userAgent": "aws-cli/2.0.62 Python/3.9.2 Darwin/21.5.0 source/x86_64 command/guardduty.delete-ip-set", "errorCode": "BadRequestException", "requestParameters": {"detectorId": "11111", "ipSetId": "1111"}, "responseElements": {"message": "The request is rejected because the parameter detectorId has an invalid value.", "__type": "InvalidInputException"}, "requestID": "70d36916-4ce7-4b6e-9226-9da47d58d554", "eventID": "884dc529-d98f-4529-bfa1-8cdd6c06d02f", "readOnly": false, "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "111111111111", "eventCategory": "Management"}'
|
||||
@@ -0,0 +1,77 @@
|
||||
event_name: AWS CloudTrail DeleteLogGroup
|
||||
fields:
|
||||
- _time
|
||||
- apiVersion
|
||||
- app
|
||||
- awsRegion
|
||||
- aws_account_id
|
||||
- command
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- dest
|
||||
- dvc
|
||||
- errorCode
|
||||
- eventCategory
|
||||
- eventID
|
||||
- eventName
|
||||
- eventSource
|
||||
- eventTime
|
||||
- eventType
|
||||
- eventVersion
|
||||
- eventtype
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- managementEvent
|
||||
- msg
|
||||
- object_category
|
||||
- product
|
||||
- punct
|
||||
- readOnly
|
||||
- recipientAccountId
|
||||
- region
|
||||
- requestID
|
||||
- requestParameters.logGroupName
|
||||
- responseElements
|
||||
- signature
|
||||
- source
|
||||
- sourceIPAddress
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src
|
||||
- src_ip
|
||||
- start_time
|
||||
- tag
|
||||
- tag::eventtype
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- tlsDetails.cipherSuite
|
||||
- tlsDetails.clientProvidedHostHeader
|
||||
- tlsDetails.tlsVersion
|
||||
- user
|
||||
- userAgent
|
||||
- userIdentity.accessKeyId
|
||||
- userIdentity.accountId
|
||||
- userIdentity.arn
|
||||
- userIdentity.principalId
|
||||
- userIdentity.type
|
||||
- userIdentity.userName
|
||||
- userName
|
||||
- user_access_key
|
||||
- user_agent
|
||||
- user_arn
|
||||
- user_group_id
|
||||
- user_id
|
||||
- user_name
|
||||
- user_type
|
||||
- vendor
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
- vendor_region
|
||||
example_log: '{"eventVersion": "1.08", "userIdentity": {"type": "IAMUser", "principalId": "AIDAYTOGP2RLI4PXTGCEU", "arn": "arn:aws:iam::111111111111:user/gowthamaraj_cli", "accountId": "111111111111", "accessKeyId": "AKIAYTOGP2RLFLKADUVG", "userName": "gowthamaraj_cli"}, "eventTime": "2022-07-19T08:58:48Z", "eventSource": "logs.amazonaws.com", "eventName": "DeleteLogGroup", "awsRegion": "us-west-2", "sourceIPAddress": "67.171.71.185", "userAgent": "aws-cli/2.7.3 Python/3.9.13 Darwin/21.5.0 source/x86_64 prompt/off command/logs.delete-log-group", "requestParameters": {"logGroupName": "test-logs"}, "responseElements": null, "requestID": "76089b03-d749-4f83-bc0e-b857c83bba5f", "eventID": "5aba96c4-e7f9-4e4f-b5e6-49694162195d", "readOnly": false, "eventType": "AwsApiCall", "apiVersion": "20140328", "managementEvent": true, "recipientAccountId": "111111111111", "eventCategory": "Management", "tlsDetails": {"tlsVersion": "TLSv1.2", "cipherSuite": "ECDHE-RSA-AES128-GCM-SHA256", "clientProvidedHostHeader": "logs.us-west-2.amazonaws.com"}}'
|
||||
@@ -0,0 +1,78 @@
|
||||
event_name: AWS CloudTrail DeleteLogStream
|
||||
fields:
|
||||
- _time
|
||||
- apiVersion
|
||||
- app
|
||||
- awsRegion
|
||||
- aws_account_id
|
||||
- command
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- dest
|
||||
- dvc
|
||||
- errorCode
|
||||
- eventCategory
|
||||
- eventID
|
||||
- eventName
|
||||
- eventSource
|
||||
- eventTime
|
||||
- eventType
|
||||
- eventVersion
|
||||
- eventtype
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- managementEvent
|
||||
- msg
|
||||
- object_category
|
||||
- product
|
||||
- punct
|
||||
- readOnly
|
||||
- recipientAccountId
|
||||
- region
|
||||
- requestID
|
||||
- requestParameters.logGroupName
|
||||
- requestParameters.logStreamName
|
||||
- responseElements
|
||||
- signature
|
||||
- source
|
||||
- sourceIPAddress
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src
|
||||
- src_ip
|
||||
- start_time
|
||||
- tag
|
||||
- tag::eventtype
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- tlsDetails.cipherSuite
|
||||
- tlsDetails.clientProvidedHostHeader
|
||||
- tlsDetails.tlsVersion
|
||||
- user
|
||||
- userAgent
|
||||
- userIdentity.accessKeyId
|
||||
- userIdentity.accountId
|
||||
- userIdentity.arn
|
||||
- userIdentity.principalId
|
||||
- userIdentity.type
|
||||
- userIdentity.userName
|
||||
- userName
|
||||
- user_access_key
|
||||
- user_agent
|
||||
- user_arn
|
||||
- user_group_id
|
||||
- user_id
|
||||
- user_name
|
||||
- user_type
|
||||
- vendor
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
- vendor_region
|
||||
example_log: '{"eventVersion": "1.08", "userIdentity": {"type": "IAMUser", "principalId": "AIDAYTOGP2RLI4PXTGCEU", "arn": "arn:aws:iam::111111111111:user/gowthamaraj_cli", "accountId": "111111111111", "accessKeyId": "AKIAYTOGP2RLFLKADUVG", "userName": "gowthamaraj_cli"}, "eventTime": "2022-07-20T21:09:51Z", "eventSource": "logs.amazonaws.com", "eventName": "DeleteLogStream", "awsRegion": "us-west-2", "sourceIPAddress": "67.171.71.185", "userAgent": "aws-cli/2.7.3 Python/3.9.13 Darwin/21.5.0 source/x86_64 prompt/off command/logs.delete-log-stream", "requestParameters": {"logGroupName": "test-logs", "logStreamName": "20150601"}, "responseElements": null, "requestID": "2d7e859e-d697-426f-8b56-c4c11c4055f3", "eventID": "561c3f4e-17ca-4438-b15d-29903baf7b13", "readOnly": false, "eventType": "AwsApiCall", "apiVersion": "20140328", "managementEvent": true, "recipientAccountId": "111111111111", "eventCategory": "Management", "tlsDetails": {"tlsVersion": "TLSv1.2", "cipherSuite": "ECDHE-RSA-AES128-GCM-SHA256", "clientProvidedHostHeader": "logs.us-west-2.amazonaws.com"}}'
|
||||
@@ -0,0 +1,85 @@
|
||||
event_name: AWS CloudTrail DeleteNetworkAclEntry
|
||||
fields:
|
||||
- _time
|
||||
- action
|
||||
- app
|
||||
- awsRegion
|
||||
- aws_account_id
|
||||
- change_type
|
||||
- command
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- direction
|
||||
- dvc
|
||||
- errorCode
|
||||
- eventCategory
|
||||
- eventID
|
||||
- eventName
|
||||
- eventSource
|
||||
- eventTime
|
||||
- eventType
|
||||
- eventVersion
|
||||
- eventtype
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- managementEvent
|
||||
- msg
|
||||
- object_category
|
||||
- product
|
||||
- punct
|
||||
- readOnly
|
||||
- recipientAccountId
|
||||
- region
|
||||
- requestID
|
||||
- requestParameters.egress
|
||||
- requestParameters.networkAclId
|
||||
- requestParameters.ruleNumber
|
||||
- responseElements._return
|
||||
- responseElements.requestId
|
||||
- signature
|
||||
- source
|
||||
- sourceIPAddress
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src
|
||||
- src_ip
|
||||
- start_time
|
||||
- status
|
||||
- tag
|
||||
- tag::eventtype
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- user
|
||||
- userAgent
|
||||
- userIdentity.accessKeyId
|
||||
- userIdentity.accountId
|
||||
- userIdentity.arn
|
||||
- userIdentity.principalId
|
||||
- userIdentity.sessionContext.attributes.creationDate
|
||||
- userIdentity.sessionContext.attributes.mfaAuthenticated
|
||||
- userIdentity.sessionContext.sessionIssuer.accountId
|
||||
- userIdentity.sessionContext.sessionIssuer.arn
|
||||
- userIdentity.sessionContext.sessionIssuer.principalId
|
||||
- userIdentity.sessionContext.sessionIssuer.type
|
||||
- userIdentity.sessionContext.sessionIssuer.userName
|
||||
- userIdentity.type
|
||||
- userName
|
||||
- user_access_key
|
||||
- user_agent
|
||||
- user_arn
|
||||
- user_group_id
|
||||
- user_id
|
||||
- user_name
|
||||
- user_type
|
||||
- vendor
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
- vendor_region
|
||||
example_log: '{"eventVersion": "1.08", "userIdentity": {"type": "AssumedRole", "principalId": "AROAIJIESMXKGCJRCTPR6:pbareiss@splunk.local", "arn": "arn:aws:sts::111111111111:assumed-role/okta_adm_role/pbareiss@splunk.local", "accountId": "111111111111", "accessKeyId": "ASIAYTOGP2RLF3F7BXZK", "sessionContext": {"sessionIssuer": {"type": "Role", "principalId": "AROAIJIESMXKGCJRCTPR6", "arn": "arn:aws:iam::111111111111:role/okta_adm_role", "accountId": "111111111111", "userName": "okta_adm_role"}, "webIdFederationData": {}, "attributes": {"mfaAuthenticated": "false", "creationDate": "2021-01-12T08:36:15Z"}}}, "eventTime": "2021-01-12T09:26:26Z", "eventSource": "ec2.amazonaws.com", "eventName": "DeleteNetworkAclEntry", "awsRegion": "eu-central-1", "sourceIPAddress": "95.90.199.65", "userAgent": "console.ec2.amazonaws.com", "requestParameters": {"networkAclId": "acl-078ccebebcbabe175", "ruleNumber": 40, "egress": false}, "responseElements": {"requestId": "607474bb-836b-46be-be4a-351ebbef67d6", "_return": true}, "requestID": "607474bb-836b-46be-be4a-351ebbef67d6", "eventID": "b9e05770-e9b0-4ba1-91e8-6537097e06e7", "readOnly": false, "eventType": "AwsApiCall", "managementEvent": true, "eventCategory": "Management", "recipientAccountId": "111111111111"}'
|
||||
@@ -0,0 +1,80 @@
|
||||
event_name: AWS CloudTrail DeletePolicy
|
||||
fields:
|
||||
- _time
|
||||
- action
|
||||
- app
|
||||
- awsRegion
|
||||
- aws_account_id
|
||||
- change_type
|
||||
- command
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- dest
|
||||
- dvc
|
||||
- errorCode
|
||||
- errorMessage
|
||||
- eventCategory
|
||||
- eventID
|
||||
- eventName
|
||||
- eventSource
|
||||
- eventTime
|
||||
- eventType
|
||||
- eventVersion
|
||||
- eventtype
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- managementEvent
|
||||
- msg
|
||||
- object_category
|
||||
- product
|
||||
- punct
|
||||
- readOnly
|
||||
- reason
|
||||
- recipientAccountId
|
||||
- region
|
||||
- requestID
|
||||
- requestParameters.policyArn
|
||||
- responseElements
|
||||
- result
|
||||
- result_id
|
||||
- signature
|
||||
- source
|
||||
- sourceIPAddress
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src
|
||||
- src_ip
|
||||
- start_time
|
||||
- status
|
||||
- tag
|
||||
- tag::eventtype
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- user
|
||||
- userAgent
|
||||
- userIdentity.accessKeyId
|
||||
- userIdentity.accountId
|
||||
- userIdentity.arn
|
||||
- userIdentity.principalId
|
||||
- userIdentity.type
|
||||
- userIdentity.userName
|
||||
- userName
|
||||
- user_access_key
|
||||
- user_agent
|
||||
- user_arn
|
||||
- user_group_id
|
||||
- user_id
|
||||
- user_name
|
||||
- user_type
|
||||
- vendor
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
- vendor_region
|
||||
example_log: '{"eventVersion": "1.08", "userIdentity": {"type": "IAMUser", "principalId": "AIDAYTOGP2RLEHRX5YWNV", "arn": "arn:aws:iam::151521547504:user/bhavin_cli", "accountId": "151521547504", "accessKeyId": "AKIAYTOGP2RLLAA6NJUM", "userName": "bhavin_cli"}, "eventTime": "2021-04-02T18:01:00Z", "eventSource": "iam.amazonaws.com", "eventName": "DeletePolicy", "awsRegion": "us-east-1", "sourceIPAddress": "61.25.42.212", "userAgent": "aws-cli/2.0.62 Python/3.9.2 Darwin/19.6.0 source/x86_64 command/iam.delete-policy", "errorCode": "NoSuchEntityException", "errorMessage": "Policy arn:aws:iam::151521547504:policy/AtomicRedTeam was not found.", "requestParameters": {"policyArn": "arn:aws:iam::151521547504:policy/AtomicRedTeam"}, "responseElements": null, "requestID": "90cbe52f-e744-4bba-9f5c-1843c9ca1855", "eventID": "abd071bf-0a38-4fab-af4a-5eee55f0935e", "readOnly": false, "eventType": "AwsApiCall", "managementEvent": true, "eventCategory": "Management", "recipientAccountId": "151521547504"}'
|
||||
@@ -0,0 +1,78 @@
|
||||
event_name: AWS CloudTrail DeleteRule
|
||||
fields:
|
||||
- _time
|
||||
- apiVersion
|
||||
- app
|
||||
- awsRegion
|
||||
- aws_account_id
|
||||
- command
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- dest
|
||||
- dvc
|
||||
- errorCode
|
||||
- eventCategory
|
||||
- eventID
|
||||
- eventName
|
||||
- eventSource
|
||||
- eventTime
|
||||
- eventType
|
||||
- eventVersion
|
||||
- eventtype
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- managementEvent
|
||||
- msg
|
||||
- object_category
|
||||
- product
|
||||
- punct
|
||||
- readOnly
|
||||
- recipientAccountId
|
||||
- region
|
||||
- requestID
|
||||
- requestParameters.changeToken
|
||||
- requestParameters.ruleId
|
||||
- responseElements.changeToken
|
||||
- signature
|
||||
- source
|
||||
- sourceIPAddress
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src
|
||||
- src_ip
|
||||
- start_time
|
||||
- tag
|
||||
- tag::eventtype
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- tlsDetails.cipherSuite
|
||||
- tlsDetails.clientProvidedHostHeader
|
||||
- tlsDetails.tlsVersion
|
||||
- user
|
||||
- userAgent
|
||||
- userIdentity.accessKeyId
|
||||
- userIdentity.accountId
|
||||
- userIdentity.arn
|
||||
- userIdentity.principalId
|
||||
- userIdentity.type
|
||||
- userIdentity.userName
|
||||
- userName
|
||||
- user_access_key
|
||||
- user_agent
|
||||
- user_arn
|
||||
- user_group_id
|
||||
- user_id
|
||||
- user_name
|
||||
- user_type
|
||||
- vendor
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
- vendor_region
|
||||
example_log: '{"eventVersion": "1.08", "userIdentity": {"type": "IAMUser", "principalId": "AIDAYTOGP2RLI4PXTGCEU", "arn": "arn:aws:iam::111111111111:user/gowthamaraj_cli", "accountId": "111111111111", "accessKeyId": "AKIAYTOGP2RLFLKADUVG", "userName": "gowthamaraj_cli"}, "eventTime": "2022-07-20T21:40:42Z", "eventSource": "waf.amazonaws.com", "eventName": "DeleteRule", "awsRegion": "us-east-1", "sourceIPAddress": "67.171.71.185", "userAgent": "aws-cli/2.7.3 Python/3.9.13 Darwin/21.5.0 source/x86_64 prompt/off command/waf.delete-rule", "requestParameters": {"changeToken": "c5daf4cb-68e1-425f-b52d-49a32a7f187f", "ruleId": "5a9b1c4a-a999-4bb2-9f51-555f086ff34f"}, "responseElements": {"changeToken": "c5daf4cb-68e1-425f-b52d-49a32a7f187f"}, "requestID": "2089be3e-28ea-4349-b505-db72c81c272a", "eventID": "0f815483-f6bb-42d9-b870-0dcc64ddc9a4", "readOnly": false, "eventType": "AwsApiCall", "apiVersion": "2015-08-24", "managementEvent": true, "recipientAccountId": "111111111111", "eventCategory": "Management", "tlsDetails": {"tlsVersion": "TLSv1.2", "cipherSuite": "ECDHE-RSA-AES128-GCM-SHA256", "clientProvidedHostHeader": "waf.amazonaws.com"}}'
|
||||
@@ -0,0 +1,76 @@
|
||||
event_name: AWS CloudTrail DeleteTrail
|
||||
fields:
|
||||
- _time
|
||||
- app
|
||||
- awsRegion
|
||||
- aws_account_id
|
||||
- command
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- dest
|
||||
- dvc
|
||||
- errorCode
|
||||
- eventCategory
|
||||
- eventID
|
||||
- eventName
|
||||
- eventSource
|
||||
- eventTime
|
||||
- eventType
|
||||
- eventVersion
|
||||
- eventtype
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- managementEvent
|
||||
- msg
|
||||
- object_category
|
||||
- product
|
||||
- punct
|
||||
- readOnly
|
||||
- recipientAccountId
|
||||
- region
|
||||
- requestID
|
||||
- requestParameters.name
|
||||
- responseElements
|
||||
- signature
|
||||
- source
|
||||
- sourceIPAddress
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src
|
||||
- src_ip
|
||||
- start_time
|
||||
- tag
|
||||
- tag::eventtype
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- tlsDetails.cipherSuite
|
||||
- tlsDetails.clientProvidedHostHeader
|
||||
- tlsDetails.tlsVersion
|
||||
- user
|
||||
- userAgent
|
||||
- userIdentity.accessKeyId
|
||||
- userIdentity.accountId
|
||||
- userIdentity.arn
|
||||
- userIdentity.principalId
|
||||
- userIdentity.type
|
||||
- userIdentity.userName
|
||||
- userName
|
||||
- user_access_key
|
||||
- user_agent
|
||||
- user_arn
|
||||
- user_group_id
|
||||
- user_id
|
||||
- user_name
|
||||
- user_type
|
||||
- vendor
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
- vendor_region
|
||||
example_log: '{"eventVersion": "1.08", "userIdentity": {"type": "IAMUser", "principalId": "AIDAYTOGP2RLEHRX5YWNV", "arn": "arn:aws:iam::111111111111:user/bhavin_cli", "accountId": "111111111111", "accessKeyId": "AKIAYTOGP2RLKQ3U2PDY", "userName": "bhavin_cli"}, "eventTime": "2022-07-13T19:03:51Z", "eventSource": "cloudtrail.amazonaws.com", "eventName": "DeleteTrail", "awsRegion": "us-west-2", "sourceIPAddress": "192.184.242.57", "userAgent": "aws-cli/2.0.62 Python/3.9.2 Darwin/21.5.0 source/x86_64 command/cloudtrail.delete-trail", "requestParameters": {"name": "redatomictesttrail"}, "responseElements": null, "requestID": "2ba0af54-1451-4a2c-846e-18436bcee01e", "eventID": "1c53bcce-650d-486a-b3f6-f64fd853e509", "readOnly": false, "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "111111111111", "eventCategory": "Management", "tlsDetails": {"tlsVersion": "TLSv1.2", "cipherSuite": "ECDHE-RSA-AES128-GCM-SHA256", "clientProvidedHostHeader": "cloudtrail.us-west-2.amazonaws.com"}}'
|
||||
@@ -0,0 +1,78 @@
|
||||
event_name: AWS CloudTrail DeleteVirtualMFADevice
|
||||
fields:
|
||||
- _time
|
||||
- action
|
||||
- app
|
||||
- awsRegion
|
||||
- aws_account_id
|
||||
- change_type
|
||||
- command
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- dest
|
||||
- dvc
|
||||
- errorCode
|
||||
- eventCategory
|
||||
- eventID
|
||||
- eventName
|
||||
- eventSource
|
||||
- eventTime
|
||||
- eventType
|
||||
- eventVersion
|
||||
- eventtype
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- managementEvent
|
||||
- msg
|
||||
- object_category
|
||||
- product
|
||||
- punct
|
||||
- readOnly
|
||||
- recipientAccountId
|
||||
- region
|
||||
- requestID
|
||||
- requestParameters.serialNumber
|
||||
- responseElements
|
||||
- sessionCredentialFromConsole
|
||||
- signature
|
||||
- source
|
||||
- sourceIPAddress
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src
|
||||
- src_ip
|
||||
- start_time
|
||||
- status
|
||||
- tag
|
||||
- tag::eventtype
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- user
|
||||
- userAgent
|
||||
- userIdentity.accessKeyId
|
||||
- userIdentity.accountId
|
||||
- userIdentity.arn
|
||||
- userIdentity.principalId
|
||||
- userIdentity.sessionContext.attributes.creationDate
|
||||
- userIdentity.sessionContext.attributes.mfaAuthenticated
|
||||
- userIdentity.type
|
||||
- userName
|
||||
- user_access_key
|
||||
- user_agent
|
||||
- user_arn
|
||||
- user_group_id
|
||||
- user_id
|
||||
- user_name
|
||||
- user_type
|
||||
- vendor
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
- vendor_region
|
||||
example_log: '{"eventVersion": "1.08", "userIdentity": {"type": "Root", "principalId": "111111111111", "arn": "arn:aws:iam::111111111111:root", "accountId": "111111111111", "accessKeyId": "ASIASBMSCQHHWAIHMHUX", "sessionContext": {"sessionIssuer": {}, "webIdFederationData": {}, "attributes": {"creationDate": "2022-10-04T16:13:23Z", "mfaAuthenticated": "true"}}}, "eventTime": "2022-10-04T16:13:46Z", "eventSource": "iam.amazonaws.com", "eventName": "DeleteVirtualMFADevice", "awsRegion": "us-east-1", "sourceIPAddress": "AWS Internal", "userAgent": "AWS Internal", "requestParameters": {"serialNumber": "arn:aws:iam::111111111111:mfa/root-account-mfa-device"}, "responseElements": null, "requestID": "5f192b01-d59d-4cee-8880-cc5cc6fd9b43", "eventID": "01f0258f-b83f-4c0f-8fd3-380473840db8", "readOnly": false, "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "111111111111", "eventCategory": "Management", "sessionCredentialFromConsole": "true"}'
|
||||
@@ -0,0 +1,78 @@
|
||||
event_name: AWS CloudTrail DeleteWebACL
|
||||
fields:
|
||||
- _time
|
||||
- apiVersion
|
||||
- app
|
||||
- awsRegion
|
||||
- aws_account_id
|
||||
- command
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- dest
|
||||
- dvc
|
||||
- errorCode
|
||||
- eventCategory
|
||||
- eventID
|
||||
- eventName
|
||||
- eventSource
|
||||
- eventTime
|
||||
- eventType
|
||||
- eventVersion
|
||||
- eventtype
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- managementEvent
|
||||
- msg
|
||||
- object_category
|
||||
- product
|
||||
- punct
|
||||
- readOnly
|
||||
- recipientAccountId
|
||||
- region
|
||||
- requestID
|
||||
- requestParameters.changeToken
|
||||
- requestParameters.webACLId
|
||||
- responseElements.changeToken
|
||||
- signature
|
||||
- source
|
||||
- sourceIPAddress
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src
|
||||
- src_ip
|
||||
- start_time
|
||||
- tag
|
||||
- tag::eventtype
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- tlsDetails.cipherSuite
|
||||
- tlsDetails.clientProvidedHostHeader
|
||||
- tlsDetails.tlsVersion
|
||||
- user
|
||||
- userAgent
|
||||
- userIdentity.accessKeyId
|
||||
- userIdentity.accountId
|
||||
- userIdentity.arn
|
||||
- userIdentity.principalId
|
||||
- userIdentity.type
|
||||
- userIdentity.userName
|
||||
- userName
|
||||
- user_access_key
|
||||
- user_agent
|
||||
- user_arn
|
||||
- user_group_id
|
||||
- user_id
|
||||
- user_name
|
||||
- user_type
|
||||
- vendor
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
- vendor_region
|
||||
example_log: '{"eventVersion": "1.08", "userIdentity": {"type": "IAMUser", "principalId": "AIDAYTOGP2RLI4PXTGCEU", "arn": "arn:aws:iam::111111111111:user/gowthamaraj_cli", "accountId": "111111111111", "accessKeyId": "AKIAYTOGP2RLFLKADUVG", "userName": "gowthamaraj_cli"}, "eventTime": "2022-07-20T21:32:54Z", "eventSource": "waf.amazonaws.com", "eventName": "DeleteWebACL", "awsRegion": "us-east-1", "sourceIPAddress": "67.171.71.185", "userAgent": "aws-cli/2.7.3 Python/3.9.13 Darwin/21.5.0 source/x86_64 prompt/off command/waf.delete-web-acl", "requestParameters": {"changeToken": "11eb19d6-d960-4398-8761-6a8fbf8fc425", "webACLId": "6a9771ff-7d94-4fec-a049-e42da0bc7347"}, "responseElements": {"changeToken": "11eb19d6-d960-4398-8761-6a8fbf8fc425"}, "requestID": "55fd5189-5f86-4052-8e8e-993faf1753e8", "eventID": "c8fd51ac-676d-4d5d-aa5a-7e642cf5bb97", "readOnly": false, "eventType": "AwsApiCall", "apiVersion": "2015-08-24", "managementEvent": true, "recipientAccountId": "111111111111", "eventCategory": "Management", "tlsDetails": {"tlsVersion": "TLSv1.2", "cipherSuite": "ECDHE-RSA-AES128-GCM-SHA256", "clientProvidedHostHeader": "waf.amazonaws.com"}}'
|
||||
@@ -0,0 +1,74 @@
|
||||
event_name: AWS CloudTrail DescribeEventAggregates
|
||||
fields:
|
||||
- _time
|
||||
- app
|
||||
- awsRegion
|
||||
- aws_account_id
|
||||
- command
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- dest
|
||||
- dvc
|
||||
- errorCode
|
||||
- eventCategory
|
||||
- eventID
|
||||
- eventName
|
||||
- eventSource
|
||||
- eventTime
|
||||
- eventType
|
||||
- eventVersion
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- managementEvent
|
||||
- msg
|
||||
- object_category
|
||||
- product
|
||||
- punct
|
||||
- readOnly
|
||||
- recipientAccountId
|
||||
- region
|
||||
- requestID
|
||||
- requestParameters.aggregateField
|
||||
- requestParameters.filter.eventStatusCodes{}
|
||||
- requestParameters.filter.startTimes{}.from
|
||||
- responseElements
|
||||
- sessionCredentialFromConsole
|
||||
- signature
|
||||
- source
|
||||
- sourceIPAddress
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src
|
||||
- src_ip
|
||||
- start_time
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- user
|
||||
- userAgent
|
||||
- userIdentity.accessKeyId
|
||||
- userIdentity.accountId
|
||||
- userIdentity.arn
|
||||
- userIdentity.principalId
|
||||
- userIdentity.sessionContext.attributes.creationDate
|
||||
- userIdentity.sessionContext.attributes.mfaAuthenticated
|
||||
- userIdentity.type
|
||||
- userName
|
||||
- user_access_key
|
||||
- user_agent
|
||||
- user_arn
|
||||
- user_group_id
|
||||
- user_id
|
||||
- user_name
|
||||
- user_type
|
||||
- vendor
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
- vendor_region
|
||||
example_log: '{"eventVersion": "1.08", "userIdentity": {"type": "Root", "principalId": "140429656527", "arn": "arn:aws:iam::140429656527:root", "accountId": "140429656527", "accessKeyId": "ASIASBMSCQHHQQ6LB24V", "sessionContext": {"sessionIssuer": {}, "webIdFederationData": {}, "attributes": {"creationDate": "2023-01-31T21:58:17Z", "mfaAuthenticated": "true"}}}, "eventTime": "2023-02-01T02:52:34Z", "eventSource": "health.amazonaws.com", "eventName": "DescribeEventAggregates", "awsRegion": "us-east-1", "sourceIPAddress": "54.188.0.152", "userAgent": "AWS Internal", "requestParameters": {"aggregateField": "eventTypeCategory", "filter": {"eventStatusCodes": ["open", "upcoming"], "startTimes": [{"from": "Jan 25, 2023 2:54:32 AM"}]}}, "responseElements": null, "requestID": "d6adf050-1d7a-4c25-9d48-0319e33f6f9a", "eventID": "201cee69-61ab-4ffb-80b7-bd31e81e0d82", "readOnly": true, "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "140429656527", "eventCategory": "Management", "sessionCredentialFromConsole": "true"}'
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,77 @@
|
||||
event_name: AWS CloudTrail GetAccountPasswordPolicy
|
||||
fields:
|
||||
- _time
|
||||
- action
|
||||
- app
|
||||
- awsRegion
|
||||
- aws_account_id
|
||||
- change_type
|
||||
- command
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- desc
|
||||
- dest
|
||||
- dvc
|
||||
- errorCode
|
||||
- eventCategory
|
||||
- eventID
|
||||
- eventName
|
||||
- eventSource
|
||||
- eventTime
|
||||
- eventType
|
||||
- eventVersion
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- managementEvent
|
||||
- msg
|
||||
- object_category
|
||||
- product
|
||||
- punct
|
||||
- readOnly
|
||||
- recipientAccountId
|
||||
- region
|
||||
- requestID
|
||||
- requestParameters
|
||||
- responseElements
|
||||
- signature
|
||||
- source
|
||||
- sourceIPAddress
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src
|
||||
- src_ip
|
||||
- start_time
|
||||
- status
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- tlsDetails.cipherSuite
|
||||
- tlsDetails.clientProvidedHostHeader
|
||||
- tlsDetails.tlsVersion
|
||||
- user
|
||||
- userAgent
|
||||
- userIdentity.accessKeyId
|
||||
- userIdentity.accountId
|
||||
- userIdentity.arn
|
||||
- userIdentity.principalId
|
||||
- userIdentity.type
|
||||
- userIdentity.userName
|
||||
- userName
|
||||
- user_access_key
|
||||
- user_agent
|
||||
- user_arn
|
||||
- user_group_id
|
||||
- user_id
|
||||
- user_name
|
||||
- user_type
|
||||
- vendor
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
- vendor_region
|
||||
example_log: '{"eventVersion": "1.08", "userIdentity": {"type": "IAMUser", "principalId": "AIDASBMSCQHHTH5NDF4GD", "arn": "arn:aws:iam::111111111111:user/strt_fonder", "accountId": "111111111111", "accessKeyId": "AKIASBMSCQHH5A5NJDM5", "userName": "strt_fonder"}, "eventTime": "2023-01-26T22:39:06Z", "eventSource": "iam.amazonaws.com", "eventName": "GetAccountPasswordPolicy", "awsRegion": "us-east-1", "sourceIPAddress": "23.93.193.7", "userAgent": "aws-cli/2.7.25 Python/3.10.6 Darwin/21.6.0 source/x86_64 prompt/off command/iam.get-account-password-policy", "requestParameters": null, "responseElements": null, "requestID": "098fd0dd-e42e-4249-91fb-9637925bf2fe", "eventID": "5eb0fb9b-18ff-4be9-b90d-107a290e1d5c", "readOnly": true, "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "111111111111", "eventCategory": "Management", "tlsDetails": {"tlsVersion": "TLSv1.2", "cipherSuite": "ECDHE-RSA-AES128-GCM-SHA256", "clientProvidedHostHeader": "iam.amazonaws.com"}}'
|
||||
@@ -0,0 +1,85 @@
|
||||
event_name: AWS CloudTrail GetObject
|
||||
fields:
|
||||
- _time
|
||||
- additionalEventData.AuthenticationMethod
|
||||
- additionalEventData.CipherSuite
|
||||
- additionalEventData.SignatureVersion
|
||||
- additionalEventData.bytesTransferredIn
|
||||
- additionalEventData.bytesTransferredOut
|
||||
- additionalEventData.x-amz-id-2
|
||||
- app
|
||||
- awsRegion
|
||||
- aws_account_id
|
||||
- command
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- dest
|
||||
- dvc
|
||||
- errorCode
|
||||
- eventCategory
|
||||
- eventID
|
||||
- eventName
|
||||
- eventSource
|
||||
- eventTime
|
||||
- eventType
|
||||
- eventVersion
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- managementEvent
|
||||
- msg
|
||||
- object_category
|
||||
- product
|
||||
- punct
|
||||
- readOnly
|
||||
- recipientAccountId
|
||||
- region
|
||||
- requestID
|
||||
- requestParameters.Host
|
||||
- requestParameters.bucketName
|
||||
- requestParameters.key
|
||||
- requestParameters.x-amz-request-payer
|
||||
- resources{}.ARN
|
||||
- resources{}.accountId
|
||||
- resources{}.type
|
||||
- responseElements
|
||||
- signature
|
||||
- source
|
||||
- sourceIPAddress
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src
|
||||
- src_ip
|
||||
- start_time
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- tlsDetails.cipherSuite
|
||||
- tlsDetails.clientProvidedHostHeader
|
||||
- tlsDetails.tlsVersion
|
||||
- user
|
||||
- userAgent
|
||||
- userIdentity.accessKeyId
|
||||
- userIdentity.accountId
|
||||
- userIdentity.arn
|
||||
- userIdentity.principalId
|
||||
- userIdentity.type
|
||||
- userIdentity.userName
|
||||
- userName
|
||||
- user_access_key
|
||||
- user_agent
|
||||
- user_arn
|
||||
- user_group_id
|
||||
- user_id
|
||||
- user_name
|
||||
- user_type
|
||||
- vendor
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
- vendor_region
|
||||
example_log: '{"eventVersion": "1.08", "userIdentity": {"type": "IAMUser", "principalId": "AIDAYTOGP2RLCNEAQXWZV", "arn": "arn:aws:iam::111111111111:user/console", "accountId": "111111111111", "accessKeyId": "AKIAYTOGP2RLF5EAXXXX", "userName": "console"}, "eventTime": "2023-04-11T01:18:47Z", "eventSource": "s3.amazonaws.com", "eventName": "GetObject", "awsRegion": "us-west-2", "sourceIPAddress": "12.26.0.38", "userAgent": "[aws-cli/2.11.2 Python/3.11.2 Darwin/22.3.0 exe/x86_64 prompt/off command/s3.cp]", "requestParameters": {"bucketName": "security-content", "Host": "security-content.s3.us-west-2.amazonaws.com", "x-amz-request-payer": "requester", "key": "stories/windows_discovery_techniques.yml"}, "responseElements": null, "additionalEventData": {"SignatureVersion": "SigV4", "CipherSuite": "ECDHE-RSA-AES128-GCM-SHA256", "bytesTransferredIn": 0, "AuthenticationMethod": "AuthHeader", "x-amz-id-2": "dcha0yrujT+O4FHsYxHx48KxMk4+wtO7MaNRwFOFs46R1PynKWcCsbLScYEFytN+Vt35hyq1cek=", "bytesTransferredOut": 1136}, "requestID": "GVSEBM08Z93FB3BT", "eventID": "2b7231c2-892d-464e-8880-1e4f81ae7eb2", "readOnly": true, "resources": [{"type": "AWS::S3::Object", "ARN": "arn:aws:s3:::security-content/stories/windows_discovery_techniques.yml"}, {"accountId": "111111111111", "type": "AWS::S3::Bucket", "ARN": "arn:aws:s3:::security-content"}], "eventType": "AwsApiCall", "managementEvent": false, "recipientAccountId": "111111111111", "eventCategory": "Data", "tlsDetails": {"tlsVersion": "TLSv1.2", "cipherSuite": "ECDHE-RSA-AES128-GCM-SHA256", "clientProvidedHostHeader": "security-content.s3.us-west-2.amazonaws.com"}}'
|
||||
@@ -0,0 +1,87 @@
|
||||
event_name: AWS CloudTrail GetPasswordData
|
||||
fields:
|
||||
- _time
|
||||
- app
|
||||
- awsRegion
|
||||
- aws_account_id
|
||||
- change_type
|
||||
- command
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- dest
|
||||
- dvc
|
||||
- errorCode
|
||||
- errorMessage
|
||||
- eventCategory
|
||||
- eventID
|
||||
- eventName
|
||||
- eventSource
|
||||
- eventTime
|
||||
- eventType
|
||||
- eventVersion
|
||||
- eventtype
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- managementEvent
|
||||
- msg
|
||||
- object_category
|
||||
- product
|
||||
- punct
|
||||
- readOnly
|
||||
- reason
|
||||
- recipientAccountId
|
||||
- region
|
||||
- requestID
|
||||
- requestParameters.instanceId
|
||||
- responseElements
|
||||
- result
|
||||
- result_id
|
||||
- signature
|
||||
- source
|
||||
- sourceIPAddress
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src
|
||||
- src_ip
|
||||
- start_time
|
||||
- tag
|
||||
- tag::eventtype
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- tlsDetails.cipherSuite
|
||||
- tlsDetails.clientProvidedHostHeader
|
||||
- tlsDetails.tlsVersion
|
||||
- user
|
||||
- userAgent
|
||||
- userIdentity.accessKeyId
|
||||
- userIdentity.accountId
|
||||
- userIdentity.arn
|
||||
- userIdentity.principalId
|
||||
- userIdentity.sessionContext.attributes.creationDate
|
||||
- userIdentity.sessionContext.attributes.mfaAuthenticated
|
||||
- userIdentity.sessionContext.sessionIssuer.accountId
|
||||
- userIdentity.sessionContext.sessionIssuer.arn
|
||||
- userIdentity.sessionContext.sessionIssuer.principalId
|
||||
- userIdentity.sessionContext.sessionIssuer.type
|
||||
- userIdentity.sessionContext.sessionIssuer.userName
|
||||
- userIdentity.type
|
||||
- userName
|
||||
- user_access_key
|
||||
- user_agent
|
||||
- user_arn
|
||||
- user_group_id
|
||||
- user_id
|
||||
- user_name
|
||||
- user_type
|
||||
- vendor
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
- vendor_region
|
||||
example_log: '{"eventVersion": "1.08", "userIdentity": {"type": "AssumedRole", "principalId": "AROAYTOGP2RLP5AASA6I5:aws-go-sdk-1660169051746043000", "arn": "arn:aws:sts::111111111111:assumed-role/sample-role-used-by-stratus-for-ec2-password-data/aws-go-sdk-1660169051746043000", "accountId": "111111111111", "accessKeyId": "ASIAYTOGP2RLLY5RQXEF", "sessionContext": {"sessionIssuer": {"type": "Role", "principalId": "AROAYTOGP2RLP5AASA6I5", "arn": "arn:aws:iam::111111111111:role/sample-role-used-by-stratus-for-ec2-password-data", "accountId": "111111111111", "userName": "sample-role-used-by-stratus-for-ec2-password-data"}, "webIdFederationData": {}, "attributes": {"creationDate": "2022-08-10T22:04:12Z", "mfaAuthenticated": "false"}}}, "eventTime": "2022-08-10T22:04:13Z", "eventSource": "ec2.amazonaws.com", "eventName": "GetPasswordData", "awsRegion": "us-west-2", "sourceIPAddress": "142.254.89.27", "userAgent": "stratus-red-team_e3e4b259-63a4-4d89-acd5-a7286a279bb8", "errorCode": "Client.UnauthorizedOperation", "errorMessage": "You are not authorized to perform this operation. Encoded authorization failure message: OwnXKlWs2vtfsyXhkYTFO35PfDwIeH4oGadP2dmbdguXBDpSfP-65XwZU4JdWht_u8p9BlgIZ0QOYIzmm5-ApXc7HsgOynmQvF4vFNUxxiuY0w-VRNBiuPmphwnJqYln8pTJogn0DfcleY5TIuDEFwmGvZHnGMmK1kXJ1VcUiQvbK_vuDpSqIDFz-jqcnOTjzsC4DXlTZkHLL1HEeNVIjI9HCEWYG4CuG9Ti8BQ0AnGVkU8oqvtS6iyVlnPI9oId5_AWpfmE1ijhNKbgFH77DjRn6QyR5rGkGYYFpvaIyMvX33Vti4RzfAyJdpuzMgp6tV-q_Rbh0ikwBJvUtiiGfmqzdQynfRNDQmXJ3ruifOjGmUz34M90SGFJKi5CVHGThtO3UWj9EqYXpKdu_JgTYEqxWvRBopB--V7tOap8XKuz7W3rWyHN2clHA0yooLZ3DV34LWgzzDp9Iv66829HSTwGz7h2P0sGdCNuV_FCxwQzWYa8f6_h1By90MvWUvmEDLSzOfA_PF6BcqCmV8XBiPUvCMPebDSGmPwSa371J5Yn2xEiuQadfuNYRLZnd2i1V_NF9ax67BdZ", "requestParameters": {"instanceId": "i-7sap2krlslv6adrs"}, "responseElements": null, "requestID": "87368810-7b30-4ff9-b097-702778a53f22", "eventID": "0cdd3757-296a-4454-9619-d0f8be335081", "readOnly": true, "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "111111111111", "eventCategory": "Management", "tlsDetails": {"tlsVersion": "TLSv1.2", "cipherSuite": "ECDHE-RSA-AES128-GCM-SHA256", "clientProvidedHostHeader": "ec2.us-west-2.amazonaws.com"}}'
|
||||
@@ -0,0 +1,63 @@
|
||||
event_name: AWS CloudTrail JobCreated
|
||||
fields:
|
||||
- _time
|
||||
- app
|
||||
- awsRegion
|
||||
- aws_account_id
|
||||
- command
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- desc
|
||||
- dest
|
||||
- dvc
|
||||
- errorCode
|
||||
- eventCategory
|
||||
- eventID
|
||||
- eventName
|
||||
- eventSource
|
||||
- eventTime
|
||||
- eventType
|
||||
- eventVersion
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- managementEvent
|
||||
- msg
|
||||
- object_category
|
||||
- product
|
||||
- punct
|
||||
- readOnly
|
||||
- recipientAccountId
|
||||
- region
|
||||
- requestParameters
|
||||
- responseElements
|
||||
- serviceEventDetails.jobArn
|
||||
- serviceEventDetails.jobEventId
|
||||
- serviceEventDetails.jobId
|
||||
- serviceEventDetails.status
|
||||
- signature
|
||||
- source
|
||||
- sourceIPAddress
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src
|
||||
- src_ip
|
||||
- start_time
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- userAgent
|
||||
- userIdentity.accountId
|
||||
- userIdentity.invokedBy
|
||||
- user_agent
|
||||
- user_group_id
|
||||
- vendor
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
- vendor_region
|
||||
example_log: '{"eventVersion": "1.08", "userIdentity": {"accountId": "111111111111", "invokedBy": "s3.amazonaws.com"}, "eventTime": "2023-04-24T23:51:17Z", "eventSource": "s3.amazonaws.com", "eventName": "JobCreated", "awsRegion": "us-west-2", "sourceIPAddress": "s3.amazonaws.com", "userAgent": "s3.amazonaws.com", "requestParameters": null, "responseElements": null, "eventID": "894153ad-ed86-4719-bb66-6c52ef7dc767", "readOnly": false, "eventType": "AwsServiceEvent", "managementEvent": true, "recipientAccountId": "111111111111", "serviceEventDetails": {"jobId": "bb54efd8-937d-4f0c-967d-aa8443998dac", "jobArn": "arn:aws:s3:us-west-2:111111111111:job/bb54efd8-937d-4f0c-967d-aa8443998dac", "status": "New", "jobEventId": "4e70d2f1053c07a79d9be9a14e486020", "failureCodes": [], "statusChangeReason": []}, "eventCategory": "Management"}'
|
||||
@@ -0,0 +1,135 @@
|
||||
event_name: AWS CloudTrail ModifyDBInstance
|
||||
fields:
|
||||
- _time
|
||||
- app
|
||||
- awsRegion
|
||||
- aws_account_id
|
||||
- command
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- dest
|
||||
- dvc
|
||||
- errorCode
|
||||
- eventCategory
|
||||
- eventID
|
||||
- eventName
|
||||
- eventSource
|
||||
- eventTime
|
||||
- eventType
|
||||
- eventVersion
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- managementEvent
|
||||
- msg
|
||||
- object_category
|
||||
- product
|
||||
- punct
|
||||
- readOnly
|
||||
- recipientAccountId
|
||||
- region
|
||||
- requestID
|
||||
- requestParameters.allowMajorVersionUpgrade
|
||||
- requestParameters.applyImmediately
|
||||
- requestParameters.dBInstanceIdentifier
|
||||
- requestParameters.deletionProtection
|
||||
- requestParameters.masterUserPassword
|
||||
- responseElements.allocatedStorage
|
||||
- responseElements.autoMinorVersionUpgrade
|
||||
- responseElements.availabilityZone
|
||||
- responseElements.backupRetentionPeriod
|
||||
- responseElements.backupTarget
|
||||
- responseElements.cACertificateIdentifier
|
||||
- responseElements.copyTagsToSnapshot
|
||||
- responseElements.customerOwnedIpEnabled
|
||||
- responseElements.dBInstanceArn
|
||||
- responseElements.dBInstanceClass
|
||||
- responseElements.dBInstanceIdentifier
|
||||
- responseElements.dBInstanceStatus
|
||||
- responseElements.dBParameterGroups{}.dBParameterGroupName
|
||||
- responseElements.dBParameterGroups{}.parameterApplyStatus
|
||||
- responseElements.dBSubnetGroup.dBSubnetGroupDescription
|
||||
- responseElements.dBSubnetGroup.dBSubnetGroupName
|
||||
- responseElements.dBSubnetGroup.subnetGroupStatus
|
||||
- responseElements.dBSubnetGroup.subnets{}.subnetAvailabilityZone.name
|
||||
- responseElements.dBSubnetGroup.subnets{}.subnetIdentifier
|
||||
- responseElements.dBSubnetGroup.subnets{}.subnetStatus
|
||||
- responseElements.dBSubnetGroup.vpcId
|
||||
- responseElements.dbInstancePort
|
||||
- responseElements.dbiResourceId
|
||||
- responseElements.deletionProtection
|
||||
- responseElements.endpoint.address
|
||||
- responseElements.endpoint.hostedZoneId
|
||||
- responseElements.endpoint.port
|
||||
- responseElements.engine
|
||||
- responseElements.engineVersion
|
||||
- responseElements.enhancedMonitoringResourceArn
|
||||
- responseElements.httpEndpointEnabled
|
||||
- responseElements.iAMDatabaseAuthenticationEnabled
|
||||
- responseElements.instanceCreateTime
|
||||
- responseElements.kmsKeyId
|
||||
- responseElements.latestRestorableTime
|
||||
- responseElements.licenseModel
|
||||
- responseElements.masterUsername
|
||||
- responseElements.monitoringInterval
|
||||
- responseElements.monitoringRoleArn
|
||||
- responseElements.multiAZ
|
||||
- responseElements.networkType
|
||||
- responseElements.optionGroupMemberships{}.optionGroupName
|
||||
- responseElements.optionGroupMemberships{}.status
|
||||
- responseElements.pendingModifiedValues.masterUserPassword
|
||||
- responseElements.performanceInsightsEnabled
|
||||
- responseElements.performanceInsightsKMSKeyId
|
||||
- responseElements.performanceInsightsRetentionPeriod
|
||||
- responseElements.preferredBackupWindow
|
||||
- responseElements.preferredMaintenanceWindow
|
||||
- responseElements.publiclyAccessible
|
||||
- responseElements.storageEncrypted
|
||||
- responseElements.storageThroughput
|
||||
- responseElements.storageType
|
||||
- responseElements.vpcSecurityGroups{}.status
|
||||
- responseElements.vpcSecurityGroups{}.vpcSecurityGroupId
|
||||
- sessionCredentialFromConsole
|
||||
- signature
|
||||
- source
|
||||
- sourceIPAddress
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src
|
||||
- src_ip
|
||||
- start_time
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- user
|
||||
- userAgent
|
||||
- userIdentity.accessKeyId
|
||||
- userIdentity.accountId
|
||||
- userIdentity.arn
|
||||
- userIdentity.principalId
|
||||
- userIdentity.sessionContext.attributes.creationDate
|
||||
- userIdentity.sessionContext.attributes.mfaAuthenticated
|
||||
- userIdentity.sessionContext.sessionIssuer.accountId
|
||||
- userIdentity.sessionContext.sessionIssuer.arn
|
||||
- userIdentity.sessionContext.sessionIssuer.principalId
|
||||
- userIdentity.sessionContext.sessionIssuer.type
|
||||
- userIdentity.sessionContext.sessionIssuer.userName
|
||||
- userIdentity.type
|
||||
- userName
|
||||
- user_access_key
|
||||
- user_agent
|
||||
- user_arn
|
||||
- user_group_id
|
||||
- user_id
|
||||
- user_name
|
||||
- user_type
|
||||
- vendor
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
- vendor_region
|
||||
example_log: '{"eventVersion": "1.08", "userIdentity": {"type": "AssumedRole", "principalId": "AROAYTOGP2RLDF6WP4HD6:gowthamarajr@splunk.com", "arn": "arn:aws:sts::111111111111:assumed-role/AWSReservedSSO_SPLKAdministratorAccess_d9ce1347d0a6dd3f/gowthamarajr@splunk.com", "accountId": "111111111111", "accessKeyId": "ASIAYTOGP2RLAKJDBQGB", "sessionContext": {"sessionIssuer": {"type": "Role", "principalId": "AROAYTOGP2RLDF6WP4HD6", "arn": "arn:aws:iam::111111111111:role/aws-reserved/sso.amazonaws.com/us-west-2/AWSReservedSSO_SPLKAdministratorAccess_d9ce1347d0a6dd3f", "accountId": "111111111111", "userName": "AWSReservedSSO_SPLKAdministratorAccess_d9ce1347d0a6dd3f"}, "webIdFederationData": {}, "attributes": {"creationDate": "2022-08-05T08:47:55Z", "mfaAuthenticated": "false"}}}, "eventTime": "2022-08-05T09:19:15Z", "eventSource": "rds.amazonaws.com", "eventName": "ModifyDBInstance", "awsRegion": "us-west-2", "sourceIPAddress": "AWS Internal", "userAgent": "AWS Internal", "requestParameters": {"dBInstanceIdentifier": "database-1", "applyImmediately": true, "masterUserPassword": "****", "allowMajorVersionUpgrade": false, "deletionProtection": true}, "responseElements": {"dBInstanceIdentifier": "database-1", "dBInstanceClass": "db.m6g.large", "engine": "postgres", "dBInstanceStatus": "available", "masterUsername": "postgres", "endpoint": {"address": "database-1.ce6wk5bvtc0t.us-west-2.rds.amazonaws.com", "port": 5432, "hostedZoneId": "Z1PVIF0B656C1W"}, "allocatedStorage": 5, "instanceCreateTime": "Aug 5, 2022 9:02:51 AM", "preferredBackupWindow": "06:35-07:05", "backupRetentionPeriod": 7, "dBSecurityGroups": [], "vpcSecurityGroups": [{"vpcSecurityGroupId": "sg-46cfd020", "status": "active"}], "dBParameterGroups": [{"dBParameterGroupName": "default.postgres14", "parameterApplyStatus": "in-sync"}], "availabilityZone": "us-west-2a", "dBSubnetGroup": {"dBSubnetGroupName": "default", "dBSubnetGroupDescription": "default", "vpcId": "vpc-5f02343b", "subnetGroupStatus": "Complete", "subnets": [{"subnetIdentifier": "subnet-43225f35", "subnetAvailabilityZone": {"name": "us-west-2b"}, "subnetOutpost": {}, "subnetStatus": "Active"}, {"subnetIdentifier": "subnet-e55d7881", "subnetAvailabilityZone": {"name": "us-west-2a"}, "subnetOutpost": {}, "subnetStatus": "Active"}, {"subnetIdentifier": "subnet-0beddb972f034bdaa", "subnetAvailabilityZone": {"name": "us-west-2c"}, "subnetOutpost": {}, "subnetStatus": "Active"}, {"subnetIdentifier": "subnet-2d70cd75", "subnetAvailabilityZone": {"name": "us-west-2c"}, "subnetOutpost": {}, "subnetStatus": "Active"}]}, "preferredMaintenanceWindow": "sat:11:44-sat:12:14", "pendingModifiedValues": {"masterUserPassword": "****"}, "latestRestorableTime": "Aug 5, 2022 9:12:31 AM", "multiAZ": false, "engineVersion": "14.2", "autoMinorVersionUpgrade": true, "readReplicaDBInstanceIdentifiers": [], "licenseModel": "postgresql-license", "storageThroughput": 0, "optionGroupMemberships": [{"optionGroupName": "default:postgres-14", "status": "in-sync"}], "publiclyAccessible": false, "storageType": "standard", "dbInstancePort": 0, "storageEncrypted": true, "kmsKeyId": "arn:aws:kms:us-west-2:111111111111:key/318bcd5d-c453-489d-b63a-07753eab0623", "dbiResourceId": "db-IX2K4LYFLBVZDHBYNPEAVFHFQM", "cACertificateIdentifier": "rds-ca-2019", "domainMemberships": [], "copyTagsToSnapshot": true, "monitoringInterval": 60, "enhancedMonitoringResourceArn": "arn:aws:logs:us-west-2:111111111111:log-group:RDSOSMetrics:log-stream:db-IX2K4LYFLBVZDHBYNPEAVFHFQM", "monitoringRoleArn": "arn:aws:iam::111111111111:role/rds-monitoring-role", "dBInstanceArn": "arn:aws:rds:us-west-2:111111111111:db:database-1", "iAMDatabaseAuthenticationEnabled": false, "performanceInsightsEnabled": true, "performanceInsightsKMSKeyId": "arn:aws:kms:us-west-2:111111111111:key/318bcd5d-c453-489d-b63a-07753eab0623", "performanceInsightsRetentionPeriod": 7, "deletionProtection": true, "associatedRoles": [], "httpEndpointEnabled": false, "tagList": [], "customerOwnedIpEnabled": false, "networkType": "IPV4", "backupTarget": "region"}, "requestID": "59e6b621-2f12-415b-bde4-21fa2dc7c113", "eventID": "46351ca1-760e-4eef-b3ff-19723e13fbf8", "readOnly": false, "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "111111111111", "eventCategory": "Management", "sessionCredentialFromConsole": "true"}'
|
||||
@@ -0,0 +1,81 @@
|
||||
event_name: AWS CloudTrail ModifyImageAttribute
|
||||
fields:
|
||||
- _time
|
||||
- app
|
||||
- awsRegion
|
||||
- aws_account_id
|
||||
- change_type
|
||||
- command
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- dest
|
||||
- dvc
|
||||
- errorCode
|
||||
- eventCategory
|
||||
- eventID
|
||||
- eventName
|
||||
- eventSource
|
||||
- eventTime
|
||||
- eventType
|
||||
- eventVersion
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- managementEvent
|
||||
- msg
|
||||
- object_category
|
||||
- product
|
||||
- punct
|
||||
- readOnly
|
||||
- recipientAccountId
|
||||
- region
|
||||
- requestID
|
||||
- requestParameters.attributeType
|
||||
- requestParameters.imageId
|
||||
- requestParameters.launchPermission.add.items{}.userId
|
||||
- responseElements._return
|
||||
- responseElements.requestId
|
||||
- sessionCredentialFromConsole
|
||||
- signature
|
||||
- source
|
||||
- sourceIPAddress
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src
|
||||
- src_ip
|
||||
- start_time
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- user
|
||||
- userAgent
|
||||
- userIdentity.accessKeyId
|
||||
- userIdentity.accountId
|
||||
- userIdentity.arn
|
||||
- userIdentity.principalId
|
||||
- userIdentity.sessionContext.attributes.creationDate
|
||||
- userIdentity.sessionContext.attributes.mfaAuthenticated
|
||||
- userIdentity.sessionContext.sessionIssuer.accountId
|
||||
- userIdentity.sessionContext.sessionIssuer.arn
|
||||
- userIdentity.sessionContext.sessionIssuer.principalId
|
||||
- userIdentity.sessionContext.sessionIssuer.type
|
||||
- userIdentity.sessionContext.sessionIssuer.userName
|
||||
- userIdentity.type
|
||||
- userName
|
||||
- user_access_key
|
||||
- user_agent
|
||||
- user_arn
|
||||
- user_group_id
|
||||
- user_id
|
||||
- user_name
|
||||
- user_type
|
||||
- vendor
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
- vendor_region
|
||||
example_log: '{"eventVersion": "1.08", "userIdentity": {"type": "AssumedRole", "principalId": "AROAYTOGP2RLDF6WP4HD6:bonobo@bo.com", "arn": "arn:aws:sts::111111111111:assumed-role/AWSReservedSSO_SPLKAdministratorAccess_d9ce1347d0a6dd3f/bonobo@bo.com", "accountId": "111111111111", "accessKeyId": "ASIAYTOGP2RLBHIEEEPN", "sessionContext": {"sessionIssuer": {"type": "Role", "principalId": "AROAYTOGP2RLDF6WP4HD6", "arn": "arn:aws:iam::111111111111:role/aws-reserved/sso.amazonaws.com/us-west-2/AWSReservedSSO_SPLKAdministratorAccess_d9ce1347d0a6dd3f", "accountId": "111111111111", "userName": "AWSReservedSSO_SPLKAdministratorAccess_d9ce1347d0a6dd3f"}, "webIdFederationData": {}, "attributes": {"creationDate": "2023-03-23T19:27:44Z", "mfaAuthenticated": "false"}}}, "eventTime": "2023-03-23T21:47:28Z", "eventSource": "ec2.amazonaws.com", "eventName": "ModifyImageAttribute", "awsRegion": "us-west-2", "sourceIPAddress": "72.135.245.10", "userAgent": "AWS Internal", "requestParameters": {"imageId": "ami-06dac31db29508566", "launchPermission": {"add": {"items": [{"userId": "140429656527"}]}}, "attributeType": "launchPermission"}, "responseElements": {"requestId": "84c431ce-6268-4218-aaf8-b4cdc1cd4055", "_return": true}, "requestID": "84c431ce-6268-4218-aaf8-b4cdc1cd4055", "eventID": "957e1b12-ea17-4006-aefd-20677ace72b8", "readOnly": false, "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "111111111111", "eventCategory": "Management", "sessionCredentialFromConsole": "true"}'
|
||||
@@ -0,0 +1,77 @@
|
||||
event_name: AWS CloudTrail ModifySnapshotAttribute
|
||||
fields:
|
||||
- _time
|
||||
- app
|
||||
- awsRegion
|
||||
- aws_account_id
|
||||
- change_type
|
||||
- command
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- dest
|
||||
- dvc
|
||||
- errorCode
|
||||
- eventCategory
|
||||
- eventID
|
||||
- eventName
|
||||
- eventSource
|
||||
- eventTime
|
||||
- eventType
|
||||
- eventVersion
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- managementEvent
|
||||
- msg
|
||||
- object_category
|
||||
- product
|
||||
- punct
|
||||
- readOnly
|
||||
- recipientAccountId
|
||||
- region
|
||||
- requestID
|
||||
- requestParameters.attributeType
|
||||
- requestParameters.createVolumePermission.add.items{}.userId
|
||||
- requestParameters.snapshotId
|
||||
- responseElements._return
|
||||
- responseElements.requestId
|
||||
- signature
|
||||
- source
|
||||
- sourceIPAddress
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src
|
||||
- src_ip
|
||||
- start_time
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- tlsDetails.cipherSuite
|
||||
- tlsDetails.clientProvidedHostHeader
|
||||
- tlsDetails.tlsVersion
|
||||
- user
|
||||
- userAgent
|
||||
- userIdentity.accessKeyId
|
||||
- userIdentity.accountId
|
||||
- userIdentity.arn
|
||||
- userIdentity.principalId
|
||||
- userIdentity.type
|
||||
- userIdentity.userName
|
||||
- userName
|
||||
- user_access_key
|
||||
- user_agent
|
||||
- user_arn
|
||||
- user_group_id
|
||||
- user_id
|
||||
- user_name
|
||||
- user_type
|
||||
- vendor
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
- vendor_region
|
||||
example_log: '{"eventVersion": "1.08", "userIdentity": {"type": "IAMUser", "principalId": "AIDAYTOGP2RLCNEAQXWZV", "arn": "arn:aws:iam::111111111111:user/bhavin_console", "accountId": "111111111111", "accessKeyId": "AKIAYTOGP2RLF5EAXXXX", "userName": "bhavin_console"}, "eventTime": "2023-03-20T22:31:36Z", "eventSource": "ec2.amazonaws.com", "eventName": "ModifySnapshotAttribute", "awsRegion": "us-west-2", "sourceIPAddress": "72.135.1.1", "userAgent": "stratus-red-team_46665bb8-dc15-4aba-a5ad-a362772b3f0d", "requestParameters": {"snapshotId": "snap-02effb3bb62786b18", "createVolumePermission": {"add": {"items": [{"userId": "012345678912"}]}}, "attributeType": "CREATE_VOLUME_PERMISSION"}, "responseElements": {"requestId": "f58433e6-a7f4-4e63-9cba-7ecc60ab74b2", "_return": true}, "requestID": "f58433e6-a7f4-4e63-9cba-7ecc60ab74b2", "eventID": "62e027d3-7191-48f4-b5fe-4b66c58b3008", "readOnly": false, "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "111111111111", "eventCategory": "Management", "tlsDetails": {"tlsVersion": "TLSv1.2", "cipherSuite": "ECDHE-RSA-AES128-GCM-SHA256", "clientProvidedHostHeader": "ec2.us-west-2.amazonaws.com"}}'
|
||||
@@ -0,0 +1,90 @@
|
||||
event_name: AWS CloudTrail PutBucketAcl
|
||||
fields:
|
||||
- _time
|
||||
- action
|
||||
- additionalEventData.AuthenticationMethod
|
||||
- additionalEventData.CipherSuite
|
||||
- additionalEventData.SignatureVersion
|
||||
- additionalEventData.bytesTransferredIn
|
||||
- additionalEventData.bytesTransferredOut
|
||||
- additionalEventData.x-amz-id-2
|
||||
- app
|
||||
- awsRegion
|
||||
- aws_account_id
|
||||
- change_type
|
||||
- command
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- dest
|
||||
- dvc
|
||||
- errorCode
|
||||
- eventCategory
|
||||
- eventID
|
||||
- eventName
|
||||
- eventSource
|
||||
- eventTime
|
||||
- eventType
|
||||
- eventVersion
|
||||
- eventtype
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- managementEvent
|
||||
- msg
|
||||
- object
|
||||
- object_category
|
||||
- object_id
|
||||
- product
|
||||
- punct
|
||||
- readOnly
|
||||
- recipientAccountId
|
||||
- region
|
||||
- requestID
|
||||
- requestParameters.Host
|
||||
- requestParameters.accessControlList.x-amz-grant-write-acp
|
||||
- requestParameters.acl
|
||||
- requestParameters.bucketName
|
||||
- resources{}.ARN
|
||||
- resources{}.accountId
|
||||
- resources{}.type
|
||||
- responseElements
|
||||
- signature
|
||||
- source
|
||||
- sourceIPAddress
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src
|
||||
- src_ip
|
||||
- src_user
|
||||
- start_time
|
||||
- status
|
||||
- tag
|
||||
- tag::eventtype
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- user
|
||||
- userAgent
|
||||
- userIdentity.accessKeyId
|
||||
- userIdentity.accountId
|
||||
- userIdentity.arn
|
||||
- userIdentity.principalId
|
||||
- userIdentity.type
|
||||
- userIdentity.userName
|
||||
- userName
|
||||
- user_access_key
|
||||
- user_agent
|
||||
- user_arn
|
||||
- user_group_id
|
||||
- user_id
|
||||
- user_name
|
||||
- vendor
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
- vendor_region
|
||||
example_log: '{"eventVersion": "1.08", "userIdentity": {"type": "IAMUser", "principalId": "AIDAYTOGP2RLNALZHZ6KX", "arn": "arn:aws:iam::111111111111:user/patrick_cli", "accountId": "111111111111", "accessKeyId": "AKIAYTOGP2RLJ2OYSF6E", "userName": "patrick_cli"}, "eventTime": "2021-01-12T14:03:17Z", "eventSource": "s3.amazonaws.com", "eventName": "PutBucketAcl", "awsRegion": "eu-central-1", "sourceIPAddress": "95.90.199.65", "userAgent": "[aws-cli/2.0.45 Python/3.7.4 Darwin/20.2.0 exe/x86_64 command/s3api.put-bucket-acl]", "requestParameters": {"bucketName": "patricktestbucket19", "Host": "patricktestbucket19.s3.eu-central-1.amazonaws.com", "acl": "", "accessControlList": {"x-amz-grant-write-acp": "uri=http://acs.amazonaws.com/groups/global/AuthenticatedUsers"}}, "responseElements": null, "additionalEventData": {"SignatureVersion": "SigV4", "CipherSuite": "ECDHE-RSA-AES128-GCM-SHA256", "bytesTransferredIn": 0, "AuthenticationMethod": "AuthHeader", "x-amz-id-2": "qb+xR18y4+4serdq8conds+tNROklOFRYciGHof4z1pcnTnT9SCrx6iYHuupPNaiMnZ9kdB43yE=", "bytesTransferredOut": 0}, "requestID": "23FAB394417ECFCD", "eventID": "9feee3c9-711f-4f7d-af4c-992907a2a521", "readOnly": false, "resources": [{"accountId": "111111111111", "type": "AWS::S3::Bucket", "ARN": "arn:aws:s3:::patricktestbucket19"}], "eventType": "AwsApiCall", "managementEvent": true, "eventCategory": "Management", "recipientAccountId": "111111111111"}'
|
||||
@@ -0,0 +1,91 @@
|
||||
event_name: AWS CloudTrail PutBucketLifecycle
|
||||
fields:
|
||||
- _time
|
||||
- additionalEventData.AuthenticationMethod
|
||||
- additionalEventData.CipherSuite
|
||||
- additionalEventData.SignatureVersion
|
||||
- additionalEventData.bytesTransferredIn
|
||||
- additionalEventData.bytesTransferredOut
|
||||
- additionalEventData.x-amz-id-2
|
||||
- app
|
||||
- awsRegion
|
||||
- aws_account_id
|
||||
- command
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- dest
|
||||
- dvc
|
||||
- errorCode
|
||||
- eventCategory
|
||||
- eventID
|
||||
- eventName
|
||||
- eventSource
|
||||
- eventTime
|
||||
- eventType
|
||||
- eventVersion
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- managementEvent
|
||||
- msg
|
||||
- object
|
||||
- object_category
|
||||
- object_id
|
||||
- product
|
||||
- punct
|
||||
- readOnly
|
||||
- recipientAccountId
|
||||
- region
|
||||
- requestID
|
||||
- requestParameters.Host
|
||||
- requestParameters.LifecycleConfiguration.Rule.Expiration.Days
|
||||
- requestParameters.LifecycleConfiguration.Rule.Filter.Prefix
|
||||
- requestParameters.LifecycleConfiguration.Rule.ID
|
||||
- requestParameters.LifecycleConfiguration.Rule.Status
|
||||
- requestParameters.LifecycleConfiguration.xmlns
|
||||
- requestParameters.bucketName
|
||||
- requestParameters.lifecycle
|
||||
- resources{}.ARN
|
||||
- resources{}.accountId
|
||||
- resources{}.type
|
||||
- responseElements
|
||||
- signature
|
||||
- source
|
||||
- sourceIPAddress
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src
|
||||
- src_ip
|
||||
- start_time
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- tlsDetails.cipherSuite
|
||||
- tlsDetails.clientProvidedHostHeader
|
||||
- tlsDetails.tlsVersion
|
||||
- user
|
||||
- userAgent
|
||||
- userIdentity.accessKeyId
|
||||
- userIdentity.accountId
|
||||
- userIdentity.arn
|
||||
- userIdentity.principalId
|
||||
- userIdentity.type
|
||||
- userIdentity.userName
|
||||
- userName
|
||||
- user_access_key
|
||||
- user_agent
|
||||
- user_arn
|
||||
- user_group_id
|
||||
- user_id
|
||||
- user_name
|
||||
- user_type
|
||||
- vendor
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
- vendor_region
|
||||
example_log: '{"eventVersion": "1.08", "userIdentity": {"type": "IAMUser", "principalId": "AIDAYTOGP2RLEHRX5YWNV", "arn": "arn:aws:iam::111111111111:user/bhavin_cli", "accountId": "111111111111", "accessKeyId": "AKIAYTOGP2RLKQ3U2PDY", "userName": "bhavin_cli"}, "eventTime": "2022-07-13T21:58:27Z", "eventSource": "s3.amazonaws.com", "eventName": "PutBucketLifecycle", "awsRegion": "us-west-2", "sourceIPAddress": "192.184.242.57", "userAgent": "[stratus-red-team_d73089cf-1905-430c-b6d3-4dc4d669190f]", "requestParameters": {"lifecycle": "", "bucketName": "my-cloudtrail-bucket-alfsujjpnbpguqrh", "LifecycleConfiguration": {"xmlns": "http://s3.amazonaws.com/doc/2006-03-01/", "Rule": {"Status": "Enabled", "Filter": {"Prefix": "*"}, "Expiration": {"Days": 1}, "ID": "nuke-cloudtrail-logs-after-1-day"}}, "Host": "my-cloudtrail-bucket-alfsujjpnbpguqrh.s3.us-west-2.amazonaws.com"}, "responseElements": null, "additionalEventData": {"SignatureVersion": "SigV4", "CipherSuite": "ECDHE-RSA-AES128-GCM-SHA256", "bytesTransferredIn": 249, "AuthenticationMethod": "AuthHeader", "x-amz-id-2": "TVXZE5kOVTMLqYlmKK+j/5g6flwkiFXFfw8PyNivFO4/9YXnDsyzFlGEzAy2rukTTiukLdEwtuM=", "bytesTransferredOut": 0}, "requestID": "1P8X27T2BCMY93Y9", "eventID": "25d92cd1-f366-4b11-b408-967a17ce70f3", "readOnly": false, "resources": [{"accountId": "111111111111", "type": "AWS::S3::Bucket", "ARN": "arn:aws:s3:::my-cloudtrail-bucket-alfsujjpnbpguqrh"}], "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "111111111111", "eventCategory": "Management", "tlsDetails": {"tlsVersion": "TLSv1.2", "cipherSuite": "ECDHE-RSA-AES128-GCM-SHA256", "clientProvidedHostHeader": "my-cloudtrail-bucket-alfsujjpnbpguqrh.s3.us-west-2.amazonaws.com"}}'
|
||||
@@ -0,0 +1,104 @@
|
||||
event_name: AWS CloudTrail PutBucketReplication
|
||||
fields:
|
||||
- _time
|
||||
- additionalEventData.AuthenticationMethod
|
||||
- additionalEventData.CipherSuite
|
||||
- additionalEventData.SignatureVersion
|
||||
- additionalEventData.bytesTransferredIn
|
||||
- additionalEventData.bytesTransferredOut
|
||||
- additionalEventData.x-amz-id-2
|
||||
- app
|
||||
- awsRegion
|
||||
- aws_account_id
|
||||
- command
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- dest
|
||||
- dvc
|
||||
- errorCode
|
||||
- eventCategory
|
||||
- eventID
|
||||
- eventName
|
||||
- eventSource
|
||||
- eventTime
|
||||
- eventType
|
||||
- eventVersion
|
||||
- eventtype
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- managementEvent
|
||||
- msg
|
||||
- object
|
||||
- object_category
|
||||
- object_id
|
||||
- product
|
||||
- punct
|
||||
- readOnly
|
||||
- recipientAccountId
|
||||
- region
|
||||
- requestID
|
||||
- requestParameters.Host
|
||||
- requestParameters.ReplicationConfiguration.Role
|
||||
- requestParameters.ReplicationConfiguration.Rule.DeleteMarkerReplication.Status
|
||||
- requestParameters.ReplicationConfiguration.Rule.Destination.Bucket
|
||||
- requestParameters.ReplicationConfiguration.Rule.Filter
|
||||
- requestParameters.ReplicationConfiguration.Rule.ID
|
||||
- requestParameters.ReplicationConfiguration.Rule.Priority
|
||||
- requestParameters.ReplicationConfiguration.Rule.Status
|
||||
- requestParameters.ReplicationConfiguration.xmlns
|
||||
- requestParameters.bucketName
|
||||
- requestParameters.replication
|
||||
- resources{}.ARN
|
||||
- resources{}.accountId
|
||||
- resources{}.type
|
||||
- responseElements
|
||||
- signature
|
||||
- source
|
||||
- sourceIPAddress
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src
|
||||
- src_ip
|
||||
- start_time
|
||||
- tag
|
||||
- tag::eventtype
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- tlsDetails.cipherSuite
|
||||
- tlsDetails.clientProvidedHostHeader
|
||||
- tlsDetails.tlsVersion
|
||||
- user
|
||||
- userAgent
|
||||
- userIdentity.accessKeyId
|
||||
- userIdentity.accountId
|
||||
- userIdentity.arn
|
||||
- userIdentity.principalId
|
||||
- userIdentity.sessionContext.attributes.creationDate
|
||||
- userIdentity.sessionContext.attributes.mfaAuthenticated
|
||||
- userIdentity.sessionContext.sessionIssuer.accountId
|
||||
- userIdentity.sessionContext.sessionIssuer.arn
|
||||
- userIdentity.sessionContext.sessionIssuer.principalId
|
||||
- userIdentity.sessionContext.sessionIssuer.type
|
||||
- userIdentity.sessionContext.sessionIssuer.userName
|
||||
- userIdentity.type
|
||||
- userName
|
||||
- user_access_key
|
||||
- user_agent
|
||||
- user_arn
|
||||
- user_group_id
|
||||
- user_id
|
||||
- user_name
|
||||
- user_type
|
||||
- vendor
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
- vendor_region
|
||||
- vpcEndpointId
|
||||
example_log: '{"eventVersion": "1.08", "userIdentity": {"type": "AssumedRole", "principalId": "AROAYTOGP2RLDF6WP4H11:bpatel@splunk.com", "arn": "arn:aws:sts::111111111111:assumed-role/AWSReservedSSO_SPLKAdministratorAccess_d9ce1347d0a6dd3f/bpatel@splunk.com", "accountId": "111111111111", "accessKeyId": "ASIAYTOGP2RLJOVYQHW2", "sessionContext": {"sessionIssuer": {"type": "Role", "principalId": "AROAYTOGP2RLDF6WP4H11", "arn": "arn:aws:iam::111111111111:role/aws-reserved/sso.amazonaws.com/us-west-2/AWSReservedSSO_SPLKAdministratorAccess_d9ce1347d0a6dd3f", "accountId": "111111111111", "userName": "AWSReservedSSO_SPLKAdministratorAccess_d9ce1347d0a6dd3f"}, "webIdFederationData": {}, "attributes": {"creationDate": "2023-04-24T23:45:42Z", "mfaAuthenticated": "false"}}}, "eventTime": "2023-04-24T23:49:33Z", "eventSource": "s3.amazonaws.com", "eventName": "PutBucketReplication", "awsRegion": "us-west-2", "sourceIPAddress": "23.93.193.6", "userAgent": "[S3Console/0.4, aws-internal/3 aws-sdk-java/1.11.1030 Linux/5.4.238-155.347.amzn2int.x86_64 OpenJDK_64-Bit_Server_VM/25.362-b10 java/1.8.0_362 vendor/Oracle_Corporation cfg/retry-mode/standard]", "requestParameters": {"replication": "", "bucketName": "git-wild-hunt-results", "Host": "s3.us-west-2.amazonaws.com", "ReplicationConfiguration": {"Role": "arn:aws:iam::111111111111:role/attack_range_bpatel", "xmlns": "http://s3.amazonaws.com/doc/2006-03-01/", "Rule": {"Status": "Enabled", "Destination": {"Bucket": "arn:aws:s3:::badpublicbuckettest"}, "Filter": "", "Priority": 0, "ID": "replication_x_test", "DeleteMarkerReplication": {"Status": "Disabled"}}}}, "responseElements": null, "additionalEventData": {"SignatureVersion": "SigV4", "CipherSuite": "ECDHE-RSA-AES128-GCM-SHA256", "bytesTransferredIn": 416, "AuthenticationMethod": "AuthHeader", "x-amz-id-2": "8UoliFe/sG2/v8qB2g763/g0Fy+kfaUqtKrzLHEILnHUisC3rL1dQfJ3NSIYcA/kzpIHQ955pGo=", "bytesTransferredOut": 0}, "requestID": "14SAVMJNEJMTZN91", "eventID": "fbe079d1-bc6b-4ee0-8893-d2b412c5550f", "readOnly": false, "resources": [{"accountId": "111111111111", "type": "AWS::S3::Bucket", "ARN": "arn:aws:s3:::git-wild-hunt-results"}], "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "111111111111", "vpcEndpointId": "vpce-a0d039c9", "eventCategory": "Management", "tlsDetails": {"tlsVersion": "TLSv1.2", "cipherSuite": "ECDHE-RSA-AES128-GCM-SHA256", "clientProvidedHostHeader": "s3.us-west-2.amazonaws.com"}}'
|
||||
@@ -0,0 +1,95 @@
|
||||
event_name: AWS CloudTrail PutBucketVersioning
|
||||
fields:
|
||||
- _time
|
||||
- additionalEventData.AuthenticationMethod
|
||||
- additionalEventData.CipherSuite
|
||||
- additionalEventData.SignatureVersion
|
||||
- additionalEventData.bytesTransferredIn
|
||||
- additionalEventData.bytesTransferredOut
|
||||
- additionalEventData.x-amz-id-2
|
||||
- app
|
||||
- awsRegion
|
||||
- aws_account_id
|
||||
- command
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- dest
|
||||
- dvc
|
||||
- errorCode
|
||||
- eventCategory
|
||||
- eventID
|
||||
- eventName
|
||||
- eventSource
|
||||
- eventTime
|
||||
- eventType
|
||||
- eventVersion
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- managementEvent
|
||||
- msg
|
||||
- object
|
||||
- object_category
|
||||
- object_id
|
||||
- product
|
||||
- punct
|
||||
- readOnly
|
||||
- recipientAccountId
|
||||
- region
|
||||
- requestID
|
||||
- requestParameters.Host
|
||||
- requestParameters.VersioningConfiguration.Status
|
||||
- requestParameters.VersioningConfiguration.xmlns
|
||||
- requestParameters.bucketName
|
||||
- requestParameters.versioning
|
||||
- resources{}.ARN
|
||||
- resources{}.accountId
|
||||
- resources{}.type
|
||||
- responseElements
|
||||
- signature
|
||||
- source
|
||||
- sourceIPAddress
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src
|
||||
- src_ip
|
||||
- start_time
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- tlsDetails.cipherSuite
|
||||
- tlsDetails.clientProvidedHostHeader
|
||||
- tlsDetails.tlsVersion
|
||||
- user
|
||||
- userAgent
|
||||
- userIdentity.accessKeyId
|
||||
- userIdentity.accountId
|
||||
- userIdentity.arn
|
||||
- userIdentity.principalId
|
||||
- userIdentity.sessionContext.attributes.creationDate
|
||||
- userIdentity.sessionContext.attributes.mfaAuthenticated
|
||||
- userIdentity.sessionContext.sessionIssuer.accountId
|
||||
- userIdentity.sessionContext.sessionIssuer.arn
|
||||
- userIdentity.sessionContext.sessionIssuer.principalId
|
||||
- userIdentity.sessionContext.sessionIssuer.type
|
||||
- userIdentity.sessionContext.sessionIssuer.userName
|
||||
- userIdentity.type
|
||||
- userName
|
||||
- user_access_key
|
||||
- user_agent
|
||||
- user_arn
|
||||
- user_group_id
|
||||
- user_id
|
||||
- user_name
|
||||
- user_type
|
||||
- vendor
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
- vendor_region
|
||||
- vpcEndpointId
|
||||
example_log: '{"eventVersion": "1.08", "userIdentity": {"type": "AssumedRole", "principalId": "AROAYTOGP2RLDF6WP4HD6:daftpunk@splunk.com", "arn": "arn:aws:sts::111111111111:assumed-role/AWSReservedSSO_SPLKAdministratorAccess_d9ce1347d0a6dd3f/daftpunk@splunk.com", "accountId": "111111111111", "accessKeyId": "ASIAYTOGP2RLAQ5VXXXX", "sessionContext": {"sessionIssuer": {"type": "Role", "principalId": "AROAYTOGP2RLDF6WP4HD6", "arn": "arn:aws:iam::111111111111:role/aws-reserved/sso.amazonaws.com/us-west-2/AWSReservedSSO_SPLKAdministratorAccess_d9ce1347d0a6dd3f", "accountId": "111111111111", "userName": "AWSReservedSSO_SPLKAdministratorAccess_d9ce1347d0a6dd3f"}, "webIdFederationData": {}, "attributes": {"creationDate": "2022-08-04T15:18:37Z", "mfaAuthenticated": "false"}}}, "eventTime": "2022-08-04T15:19:25Z", "eventSource": "s3.amazonaws.com", "eventName": "PutBucketVersioning", "awsRegion": "us-west-2", "sourceIPAddress": "73.57.168.38", "userAgent": "[S3Console/0.4, aws-internal/3 aws-sdk-java/1.11.1030 Linux/5.4.196-119.356.amzn2int.x86_64 OpenJDK_64-Bit_Server_VM/25.302-b08 java/1.8.0_302 vendor/Oracle_Corporation cfg/retry-mode/standard]", "requestParameters": {"bucketName": "git-wild-hunt-results", "Host": "s3.us-west-2.amazonaws.com", "versioning": "", "VersioningConfiguration": {"Status": "Suspended", "xmlns": "http://s3.amazonaws.com/doc/2006-03-01/"}}, "responseElements": null, "additionalEventData": {"SignatureVersion": "SigV4", "CipherSuite": "ECDHE-RSA-AES128-GCM-SHA256", "bytesTransferredIn": 125, "AuthenticationMethod": "AuthHeader", "x-amz-id-2": "F3tJSu/C2DMkRNLldcWTRzApxQa6v197ImcuQDA++vaeaLj9UvcIkEFgDIrMYUdXLI4t+Uih5hk=", "bytesTransferredOut": 0}, "requestID": "5KXZDSNDYXWC8Q4M", "eventID": "42d7a97e-9d35-4c8e-8d0a-4a82d91aab55", "readOnly": false, "resources": [{"accountId": "111111111111", "type": "AWS::S3::Bucket", "ARN": "arn:aws:s3:::git-wild-hunt-results"}], "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "111111111111", "vpcEndpointId": "vpce-a0d039c9", "eventCategory": "Management", "tlsDetails": {"tlsVersion": "TLSv1.2", "cipherSuite": "ECDHE-RSA-AES128-GCM-SHA256", "clientProvidedHostHeader": "s3.us-west-2.amazonaws.com"}}'
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,85 @@
|
||||
event_name: AWS CloudTrail PutKeyPolicy
|
||||
fields:
|
||||
- _time
|
||||
- app
|
||||
- awsRegion
|
||||
- aws_account_id
|
||||
- command
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- dest
|
||||
- dvc
|
||||
- errorCode
|
||||
- eventCategory
|
||||
- eventID
|
||||
- eventName
|
||||
- eventSource
|
||||
- eventTime
|
||||
- eventType
|
||||
- eventVersion
|
||||
- eventtype
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- managementEvent
|
||||
- msg
|
||||
- object_category
|
||||
- product
|
||||
- punct
|
||||
- readOnly
|
||||
- recipientAccountId
|
||||
- region
|
||||
- requestID
|
||||
- requestParameters.bypassPolicyLockoutSafetyCheck
|
||||
- requestParameters.keyId
|
||||
- requestParameters.policy
|
||||
- requestParameters.policyName
|
||||
- resources{}.ARN
|
||||
- resources{}.accountId
|
||||
- resources{}.type
|
||||
- responseElements
|
||||
- signature
|
||||
- source
|
||||
- sourceIPAddress
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src
|
||||
- src_ip
|
||||
- start_time
|
||||
- tag
|
||||
- tag::eventtype
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- user
|
||||
- userAgent
|
||||
- userIdentity.accessKeyId
|
||||
- userIdentity.accountId
|
||||
- userIdentity.arn
|
||||
- userIdentity.principalId
|
||||
- userIdentity.sessionContext.attributes.creationDate
|
||||
- userIdentity.sessionContext.attributes.mfaAuthenticated
|
||||
- userIdentity.sessionContext.sessionIssuer.accountId
|
||||
- userIdentity.sessionContext.sessionIssuer.arn
|
||||
- userIdentity.sessionContext.sessionIssuer.principalId
|
||||
- userIdentity.sessionContext.sessionIssuer.type
|
||||
- userIdentity.sessionContext.sessionIssuer.userName
|
||||
- userIdentity.type
|
||||
- userName
|
||||
- user_access_key
|
||||
- user_agent
|
||||
- user_arn
|
||||
- user_group_id
|
||||
- user_id
|
||||
- user_name
|
||||
- user_type
|
||||
- vendor
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
- vendor_region
|
||||
example_log: '{"eventVersion": "1.08", "userIdentity": {"type": "AssumedRole", "principalId": "AROAIJIESMXKGCJRCTPR6:pbareiss@splunk.local", "arn": "arn:aws:sts::111111111111:assumed-role/okta_adm_role/pbareiss@splunk.local", "accountId": "111111111111", "accessKeyId": "ASIAYTOGP2RLK74OPBDR", "sessionContext": {"sessionIssuer": {"type": "Role", "principalId": "AROAIJIESMXKGCJRCTPR6", "arn": "arn:aws:iam::111111111111:role/okta_adm_role", "accountId": "111111111111", "userName": "okta_adm_role"}, "webIdFederationData": {}, "attributes": {"mfaAuthenticated": "false", "creationDate": "2021-01-11T09:03:18Z"}}}, "eventTime": "2021-01-11T11:04:39Z", "eventSource": "kms.amazonaws.com", "eventName": "PutKeyPolicy", "awsRegion": "us-west-2", "sourceIPAddress": "95.90.199.65", "userAgent": "aws-internal/3 aws-sdk-java/1.11.893 Linux/4.9.230-0.1.ac.223.84.332.metal1.x86_64 OpenJDK_64-Bit_Server_VM/25.272-b10 java/1.8.0_272 vendor/Oracle_Corporation", "requestParameters": {"keyId": "f2a82583-a7d3-4c92-8787-fe2baab1cee1", "policyName": "default", "policy": "{\n \"Version\": \"2012-10-17\",\n \"Id\": \"key-consolepolicy-3\",\n \"Statement\": [\n {\n \"Sid\": \"Enable IAM User Permissions\",\n \"Effect\": \"Allow\",\n \"Principal\": {\n \"AWS\": \"arn:aws:iam::111111111111:root\"\n },\n \"Action\": \"kms:*\",\n \"Resource\": \"*\"\n },\n {\n \"Sid\": \"Allow access for Key Administrators\",\n \"Effect\": \"Allow\",\n \"Principal\": {\n \"AWS\": \"arn:aws:iam::111111111111:user/patrick_cli\"\n },\n \"Action\": [\n \"kms:Create*\",\n \"kms:Describe*\",\n \"kms:Enable*\",\n \"kms:List*\",\n \"kms:Put*\",\n \"kms:Update*\",\n \"kms:Revoke*\",\n \"kms:Disable*\",\n \"kms:Get*\",\n \"kms:Delete*\",\n \"kms:TagResource\",\n \"kms:UntagResource\",\n \"kms:ScheduleKeyDeletion\",\n \"kms:CancelKeyDeletion\"\n ],\n \"Resource\": \"*\"\n },\n {\n \"Sid\": \"Allow use of the key\",\n \"Effect\": \"Allow\",\n \"Principal\": {\n \"AWS\": \"arn:aws:iam::111111111111:user/patrick_cli\"\n },\n \"Action\": [\n \"kms:Encrypt\",\n \"kms:Decrypt\",\n \"kms:ReEncrypt*\",\n \"kms:GenerateDataKey*\",\n \"kms:DescribeKey\"\n ],\n \"Resource\": \"*\"\n },\n {\n \"Sid\": \"Allow attachment of persistent resources\",\n \"Effect\": \"Allow\",\n \"Principal\": {\n \"AWS\": \"arn:aws:iam::111111111111:user/patrick_cli\"\n },\n \"Action\": [\n \"kms:CreateGrant\",\n \"kms:ListGrants\",\n \"kms:RevokeGrant\"\n ],\n \"Resource\": \"*\",\n \"Condition\": {\n \"Bool\": {\n \"kms:GrantIsForAWSResource\": \"true\"\n }\n }\n },\n {\n \"Sid\": \"Allow use of the key\",\n \"Effect\": \"Allow\",\n \"Principal\": {\n \"AWS\": \"*\"\n },\n \"Action\": [\n \"kms:Encrypt\"\n ],\n \"Resource\": \"*\"\n }\n ]\n}", "bypassPolicyLockoutSafetyCheck": false}, "responseElements": null, "requestID": "c7836c7a-ca95-47aa-a3fb-a7db0d66fec8", "eventID": "612f17e3-2317-4dd9-8aa3-393bc8a7961b", "readOnly": false, "resources": [{"accountId": "111111111111", "type": "AWS::KMS::Key", "ARN": "arn:aws:kms:us-west-2:111111111111:key/f2a82583-a7d3-4c92-8787-fe2baab1cee1"}], "eventType": "AwsApiCall", "managementEvent": true, "eventCategory": "Management", "recipientAccountId": "111111111111"}'
|
||||
@@ -0,0 +1,92 @@
|
||||
event_name: AWS CloudTrail ReplaceNetworkAclEntry
|
||||
fields:
|
||||
- _time
|
||||
- action
|
||||
- app
|
||||
- awsRegion
|
||||
- aws_account_id
|
||||
- change_type
|
||||
- command
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- direction
|
||||
- dvc
|
||||
- errorCode
|
||||
- eventCategory
|
||||
- eventID
|
||||
- eventName
|
||||
- eventSource
|
||||
- eventTime
|
||||
- eventType
|
||||
- eventVersion
|
||||
- eventtype
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- managementEvent
|
||||
- msg
|
||||
- object_category
|
||||
- product
|
||||
- protocol
|
||||
- protocol_code
|
||||
- punct
|
||||
- readOnly
|
||||
- recipientAccountId
|
||||
- region
|
||||
- requestID
|
||||
- requestParameters.aclProtocol
|
||||
- requestParameters.cidrBlock
|
||||
- requestParameters.egress
|
||||
- requestParameters.networkAclId
|
||||
- requestParameters.ruleAction
|
||||
- requestParameters.ruleNumber
|
||||
- responseElements._return
|
||||
- responseElements.requestId
|
||||
- rule_action
|
||||
- signature
|
||||
- source
|
||||
- sourceIPAddress
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src
|
||||
- src_ip
|
||||
- src_ip_range
|
||||
- start_time
|
||||
- status
|
||||
- tag
|
||||
- tag::eventtype
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- user
|
||||
- userAgent
|
||||
- userIdentity.accessKeyId
|
||||
- userIdentity.accountId
|
||||
- userIdentity.arn
|
||||
- userIdentity.principalId
|
||||
- userIdentity.sessionContext.attributes.creationDate
|
||||
- userIdentity.sessionContext.attributes.mfaAuthenticated
|
||||
- userIdentity.sessionContext.sessionIssuer.accountId
|
||||
- userIdentity.sessionContext.sessionIssuer.arn
|
||||
- userIdentity.sessionContext.sessionIssuer.principalId
|
||||
- userIdentity.sessionContext.sessionIssuer.type
|
||||
- userIdentity.sessionContext.sessionIssuer.userName
|
||||
- userIdentity.type
|
||||
- userName
|
||||
- user_access_key
|
||||
- user_agent
|
||||
- user_arn
|
||||
- user_group_id
|
||||
- user_id
|
||||
- user_name
|
||||
- user_type
|
||||
- vendor
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
- vendor_region
|
||||
example_log: '{"eventVersion": "1.08", "userIdentity": {"type": "AssumedRole", "principalId": "AROAIJIESMXKGCJRCTPR6:pbareiss@splunk.local", "arn": "arn:aws:sts::111111111111:assumed-role/okta_adm_role/pbareiss@splunk.local", "accountId": "111111111111", "accessKeyId": "ASIAYTOGP2RLF3F7BXZK", "sessionContext": {"sessionIssuer": {"type": "Role", "principalId": "AROAIJIESMXKGCJRCTPR6", "arn": "arn:aws:iam::111111111111:role/okta_adm_role", "accountId": "111111111111", "userName": "okta_adm_role"}, "webIdFederationData": {}, "attributes": {"mfaAuthenticated": "false", "creationDate": "2021-01-12T08:36:15Z"}}}, "eventTime": "2021-01-12T08:49:49Z", "eventSource": "ec2.amazonaws.com", "eventName": "ReplaceNetworkAclEntry", "awsRegion": "eu-central-1", "sourceIPAddress": "95.90.199.65", "userAgent": "console.ec2.amazonaws.com", "requestParameters": {"networkAclId": "acl-078ccebebcbabe175", "ruleNumber": 20, "egress": false, "ruleAction": "allow", "icmpTypeCode": {}, "portRange": {}, "aclProtocol": "-1", "cidrBlock": "0.0.0.0/0"}, "responseElements": {"requestId": "97b40da9-9291-4a92-8e9e-892b6887ffc9", "_return": true}, "requestID": "97b40da9-9291-4a92-8e9e-892b6887ffc9", "eventID": "46fe04b8-d007-4933-8bb8-c8b65c1121fa", "readOnly": false, "eventType": "AwsApiCall", "managementEvent": true, "eventCategory": "Management", "recipientAccountId": "111111111111"}'
|
||||
@@ -0,0 +1,77 @@
|
||||
event_name: AWS CloudTrail SetDefaultPolicyVersion
|
||||
fields:
|
||||
- _time
|
||||
- action
|
||||
- app
|
||||
- awsRegion
|
||||
- aws_account_id
|
||||
- change_type
|
||||
- command
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- dest
|
||||
- dvc
|
||||
- errorCode
|
||||
- eventCategory
|
||||
- eventID
|
||||
- eventName
|
||||
- eventSource
|
||||
- eventTime
|
||||
- eventType
|
||||
- eventVersion
|
||||
- eventtype
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- managementEvent
|
||||
- msg
|
||||
- object_category
|
||||
- product
|
||||
- punct
|
||||
- readOnly
|
||||
- recipientAccountId
|
||||
- region
|
||||
- requestID
|
||||
- requestParameters.policyArn
|
||||
- requestParameters.versionId
|
||||
- responseElements
|
||||
- signature
|
||||
- source
|
||||
- sourceIPAddress
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src
|
||||
- src_ip
|
||||
- start_time
|
||||
- status
|
||||
- tag
|
||||
- tag::eventtype
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- user
|
||||
- userAgent
|
||||
- userIdentity.accessKeyId
|
||||
- userIdentity.accountId
|
||||
- userIdentity.arn
|
||||
- userIdentity.principalId
|
||||
- userIdentity.type
|
||||
- userIdentity.userName
|
||||
- userName
|
||||
- user_access_key
|
||||
- user_agent
|
||||
- user_arn
|
||||
- user_group_id
|
||||
- user_id
|
||||
- user_name
|
||||
- user_type
|
||||
- vendor
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
- vendor_region
|
||||
example_log: '{"eventVersion": "1.08", "userIdentity": {"type": "IAMUser", "principalId": "AIDAYTOGP2RLESDK2NOSX", "arn": "arn:aws:iam::111111111111:user/AtomicRedTeam", "accountId": "111111111111", "accessKeyId": "AKIAYTOGP2RLKMZDMPVA", "userName": "AtomicRedTeam"}, "eventTime": "2021-03-02T21:05:49Z", "eventSource": "iam.amazonaws.com", "eventName": "SetDefaultPolicyVersion", "awsRegion": "us-east-1", "sourceIPAddress": "73.15.72.101", "userAgent": "aws-cli/2.0.62 Python/3.9.0 Darwin/19.6.0 source/x86_64 command/iam.set-default-policy-version", "requestParameters": {"policyArn": "arn:aws:iam::111111111111:policy/VulnerablePolicy", "versionId": "v1"}, "responseElements": null, "requestID": "3bdf8738-2eab-4ae8-a858-2e2a4ccfc66b", "eventID": "742f6e55-4bc7-49e2-965f-56ffbc46a980", "readOnly": false, "eventType": "AwsApiCall", "managementEvent": true, "eventCategory": "Management", "recipientAccountId": "111111111111"}'
|
||||
@@ -0,0 +1,73 @@
|
||||
event_name: AWS CloudTrail StopLogging
|
||||
fields:
|
||||
- _time
|
||||
- app
|
||||
- awsRegion
|
||||
- aws_account_id
|
||||
- command
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- dest
|
||||
- dvc
|
||||
- errorCode
|
||||
- eventCategory
|
||||
- eventID
|
||||
- eventName
|
||||
- eventSource
|
||||
- eventTime
|
||||
- eventType
|
||||
- eventVersion
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- managementEvent
|
||||
- msg
|
||||
- object_category
|
||||
- product
|
||||
- punct
|
||||
- readOnly
|
||||
- recipientAccountId
|
||||
- region
|
||||
- requestID
|
||||
- requestParameters.name
|
||||
- responseElements
|
||||
- signature
|
||||
- source
|
||||
- sourceIPAddress
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src
|
||||
- src_ip
|
||||
- start_time
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- tlsDetails.cipherSuite
|
||||
- tlsDetails.clientProvidedHostHeader
|
||||
- tlsDetails.tlsVersion
|
||||
- user
|
||||
- userAgent
|
||||
- userIdentity.accessKeyId
|
||||
- userIdentity.accountId
|
||||
- userIdentity.arn
|
||||
- userIdentity.principalId
|
||||
- userIdentity.type
|
||||
- userIdentity.userName
|
||||
- userName
|
||||
- user_access_key
|
||||
- user_agent
|
||||
- user_arn
|
||||
- user_group_id
|
||||
- user_id
|
||||
- user_name
|
||||
- user_type
|
||||
- vendor
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
- vendor_region
|
||||
example_log: '{"eventVersion": "1.08", "userIdentity": {"type": "IAMUser", "principalId": "AIDAYTOGP2RLEHRX5YWNV", "arn": "arn:aws:iam::111111111111:user/bhavin_cli", "accountId": "111111111111", "accessKeyId": "AKIAYTOGP2RLKQ3U2PDY", "userName": "bhavin_cli"}, "eventTime": "2022-06-30T21:26:49Z", "eventSource": "cloudtrail.amazonaws.com", "eventName": "StopLogging", "awsRegion": "us-west-2", "sourceIPAddress": "72.193.184.209", "userAgent": "stratus-red-team_a6a8f8f2-d560-4062-bd0d-c232130cfcc5", "requestParameters": {"name": "my-cloudtrail-trail"}, "responseElements": null, "requestID": "d8b79caa-08d2-4f7e-b93a-73bb7b85f260", "eventID": "9f8d2b82-6e9d-45b8-9055-78d8c00ca416", "readOnly": false, "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "111111111111", "eventCategory": "Management", "tlsDetails": {"tlsVersion": "TLSv1.2", "cipherSuite": "ECDHE-RSA-AES128-GCM-SHA256", "clientProvidedHostHeader": "cloudtrail.us-west-2.amazonaws.com"}}'
|
||||
@@ -0,0 +1,84 @@
|
||||
event_name: AWS CloudTrail UpdateAccountPasswordPolicy
|
||||
fields:
|
||||
- _time
|
||||
- action
|
||||
- app
|
||||
- awsRegion
|
||||
- aws_account_id
|
||||
- change_type
|
||||
- command
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- dest
|
||||
- dvc
|
||||
- errorCode
|
||||
- eventCategory
|
||||
- eventID
|
||||
- eventName
|
||||
- eventSource
|
||||
- eventTime
|
||||
- eventType
|
||||
- eventVersion
|
||||
- eventtype
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- managementEvent
|
||||
- msg
|
||||
- object_category
|
||||
- product
|
||||
- punct
|
||||
- readOnly
|
||||
- recipientAccountId
|
||||
- region
|
||||
- requestID
|
||||
- requestParameters.allowUsersToChangePassword
|
||||
- requestParameters.hardExpiry
|
||||
- requestParameters.minimumPasswordLength
|
||||
- requestParameters.requireLowercaseCharacters
|
||||
- requestParameters.requireNumbers
|
||||
- requestParameters.requireSymbols
|
||||
- requestParameters.requireUppercaseCharacters
|
||||
- responseElements
|
||||
- sessionCredentialFromConsole
|
||||
- signature
|
||||
- source
|
||||
- sourceIPAddress
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src
|
||||
- src_ip
|
||||
- start_time
|
||||
- status
|
||||
- tag
|
||||
- tag::eventtype
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- user
|
||||
- userAgent
|
||||
- userIdentity.accessKeyId
|
||||
- userIdentity.accountId
|
||||
- userIdentity.arn
|
||||
- userIdentity.principalId
|
||||
- userIdentity.sessionContext.attributes.creationDate
|
||||
- userIdentity.sessionContext.attributes.mfaAuthenticated
|
||||
- userIdentity.type
|
||||
- userName
|
||||
- user_access_key
|
||||
- user_agent
|
||||
- user_arn
|
||||
- user_group_id
|
||||
- user_id
|
||||
- user_name
|
||||
- user_type
|
||||
- vendor
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
- vendor_region
|
||||
example_log: '{"eventVersion": "1.08", "userIdentity": {"type": "Root", "principalId": "111111111111", "arn": "arn:aws:iam::111111111111:root", "accountId": "111111111111", "accessKeyId": "ASIASBMSCQHHZZ4THONS", "sessionContext": {"sessionIssuer": {}, "webIdFederationData": {}, "attributes": {"creationDate": "2023-01-26T22:10:41Z", "mfaAuthenticated": "false"}}}, "eventTime": "2023-01-26T22:38:59Z", "eventSource": "iam.amazonaws.com", "eventName": "UpdateAccountPasswordPolicy", "awsRegion": "us-east-1", "sourceIPAddress": "23.93.193.7", "userAgent": "AWS Internal", "requestParameters": {"minimumPasswordLength": 6, "requireSymbols": true, "requireNumbers": false, "requireUppercaseCharacters": false, "requireLowercaseCharacters": false, "allowUsersToChangePassword": false, "hardExpiry": false}, "responseElements": null, "requestID": "7685efa9-5c56-451a-bd25-3db520108589", "eventID": "ccc1d5c2-dd72-4798-8023-ed5a4205f2d5", "readOnly": false, "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "111111111111", "eventCategory": "Management", "sessionCredentialFromConsole": "true"}'
|
||||
@@ -0,0 +1,76 @@
|
||||
event_name: AWS CloudTrail UpdateLoginProfile
|
||||
fields:
|
||||
- _time
|
||||
- action
|
||||
- app
|
||||
- awsRegion
|
||||
- aws_account_id
|
||||
- change_type
|
||||
- command
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- dest
|
||||
- dvc
|
||||
- errorCode
|
||||
- eventCategory
|
||||
- eventID
|
||||
- eventName
|
||||
- eventSource
|
||||
- eventTime
|
||||
- eventType
|
||||
- eventVersion
|
||||
- eventtype
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- managementEvent
|
||||
- msg
|
||||
- object_category
|
||||
- product
|
||||
- punct
|
||||
- readOnly
|
||||
- recipientAccountId
|
||||
- region
|
||||
- requestID
|
||||
- requestParameters.userName
|
||||
- responseElements
|
||||
- signature
|
||||
- source
|
||||
- sourceIPAddress
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src
|
||||
- src_ip
|
||||
- start_time
|
||||
- status
|
||||
- tag
|
||||
- tag::eventtype
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- user
|
||||
- userAgent
|
||||
- userIdentity.accessKeyId
|
||||
- userIdentity.accountId
|
||||
- userIdentity.arn
|
||||
- userIdentity.principalId
|
||||
- userIdentity.type
|
||||
- userIdentity.userName
|
||||
- userName
|
||||
- user_access_key
|
||||
- user_agent
|
||||
- user_arn
|
||||
- user_group_id
|
||||
- user_id
|
||||
- user_name
|
||||
- user_type
|
||||
- vendor
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
- vendor_region
|
||||
example_log: '{"eventVersion": "1.08", "userIdentity": {"type": "IAMUser", "principalId": "AIDAYTOGP2RLEHRX5YWNV", "arn": "arn:aws:iam::111111111111:user/bhavin_cli", "accountId": "111111111111", "accessKeyId": "AKIAYTOGP2RLLAA6NJUM", "userName": "bhavin_cli"}, "eventTime": "2021-03-05T01:02:59Z", "eventSource": "iam.amazonaws.com", "eventName": "UpdateLoginProfile", "awsRegion": "us-east-1", "sourceIPAddress": "73.15.72.101", "userAgent": "aws-cli/2.0.62 Python/3.9.2 Darwin/19.6.0 source/x86_64 command/iam.update-login-profile", "requestParameters": {"userName": "AtomicRedTeam"}, "responseElements": null, "requestID": "08f38478-1749-4fb5-b07c-469d3448777a", "eventID": "033580e7-bbba-4b70-be63-7eeddb04b842", "readOnly": false, "eventType": "AwsApiCall", "managementEvent": true, "eventCategory": "Management", "recipientAccountId": "111111111111"}'
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,81 @@
|
||||
event_name: AWS CloudTrail UpdateTrail
|
||||
fields:
|
||||
- _time
|
||||
- app
|
||||
- awsRegion
|
||||
- aws_account_id
|
||||
- command
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- dest
|
||||
- dvc
|
||||
- errorCode
|
||||
- eventCategory
|
||||
- eventID
|
||||
- eventName
|
||||
- eventSource
|
||||
- eventTime
|
||||
- eventType
|
||||
- eventVersion
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- managementEvent
|
||||
- msg
|
||||
- object_category
|
||||
- product
|
||||
- punct
|
||||
- readOnly
|
||||
- recipientAccountId
|
||||
- region
|
||||
- requestID
|
||||
- requestParameters.includeGlobalServiceEvents
|
||||
- requestParameters.isMultiRegionTrail
|
||||
- requestParameters.name
|
||||
- responseElements.includeGlobalServiceEvents
|
||||
- responseElements.isMultiRegionTrail
|
||||
- responseElements.isOrganizationTrail
|
||||
- responseElements.logFileValidationEnabled
|
||||
- responseElements.name
|
||||
- responseElements.s3BucketName
|
||||
- responseElements.trailARN
|
||||
- signature
|
||||
- source
|
||||
- sourceIPAddress
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src
|
||||
- src_ip
|
||||
- start_time
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- tlsDetails.cipherSuite
|
||||
- tlsDetails.clientProvidedHostHeader
|
||||
- tlsDetails.tlsVersion
|
||||
- user
|
||||
- userAgent
|
||||
- userIdentity.accessKeyId
|
||||
- userIdentity.accountId
|
||||
- userIdentity.arn
|
||||
- userIdentity.principalId
|
||||
- userIdentity.type
|
||||
- userIdentity.userName
|
||||
- userName
|
||||
- user_access_key
|
||||
- user_agent
|
||||
- user_arn
|
||||
- user_group_id
|
||||
- user_id
|
||||
- user_name
|
||||
- user_type
|
||||
- vendor
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
- vendor_region
|
||||
example_log: '{"eventVersion": "1.08", "userIdentity": {"type": "IAMUser", "principalId": "AIDAYTOGP2RLI4PXTGCEU", "arn": "arn:aws:iam::111111111111:user/gowthamaraj_cli", "accountId": "111111111111", "accessKeyId": "AKIAYTOGP2RLFLKADUVG", "userName": "gowthamaraj_cli"}, "eventTime": "2022-07-19T08:42:26Z", "eventSource": "cloudtrail.amazonaws.com", "eventName": "UpdateTrail", "awsRegion": "us-west-2", "sourceIPAddress": "67.171.71.185", "userAgent": "aws-cli/2.7.3 Python/3.9.13 Darwin/21.5.0 source/x86_64 prompt/off command/cloudtrail.update-trail", "requestParameters": {"name": "Regulatory", "includeGlobalServiceEvents": true, "isMultiRegionTrail": true}, "responseElements": {"name": "Regulatory", "s3BucketName": "s3-for-cloudtrail-logs111", "includeGlobalServiceEvents": true, "isMultiRegionTrail": true, "trailARN": "arn:aws:cloudtrail:us-west-2:111111111111:trail/Regulatory", "logFileValidationEnabled": false, "isOrganizationTrail": false}, "requestID": "0da61466-5bba-43f9-b7e1-27437de120b2", "eventID": "ce02af60-f29e-4bc2-8b29-31c12f408fed", "readOnly": false, "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "111111111111", "eventCategory": "Management", "tlsDetails": {"tlsVersion": "TLSv1.2", "cipherSuite": "ECDHE-RSA-AES128-GCM-SHA256", "clientProvidedHostHeader": "cloudtrail.us-west-2.amazonaws.com"}}'
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
event_name: Azure Active Directory Add app role assignment to service principal
|
||||
fields:
|
||||
- _time
|
||||
- Level
|
||||
- additional_details
|
||||
- additional_details_name
|
||||
- additional_details_value
|
||||
- category
|
||||
- command
|
||||
- correlationId
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- dest
|
||||
- dest_type
|
||||
- durationMs
|
||||
- dvc
|
||||
- eventtype
|
||||
- host
|
||||
- id
|
||||
- identity
|
||||
- index
|
||||
- linecount
|
||||
- object_attrs
|
||||
- object_id
|
||||
- operationName
|
||||
- operationVersion
|
||||
- path_from_resourceId
|
||||
- properties.activityDateTime
|
||||
- properties.activityDisplayName
|
||||
- properties.additionalDetails{}.key
|
||||
- properties.additionalDetails{}.value
|
||||
- properties.category
|
||||
- properties.correlationId
|
||||
- properties.id
|
||||
- properties.initiatedBy.app.appId
|
||||
- properties.initiatedBy.app.displayName
|
||||
- properties.initiatedBy.app.servicePrincipalId
|
||||
- properties.initiatedBy.app.servicePrincipalName
|
||||
- properties.loggedByService
|
||||
- properties.operationType
|
||||
- properties.result
|
||||
- properties.resultReason
|
||||
- properties.targetResources{}.displayName
|
||||
- properties.targetResources{}.id
|
||||
- properties.targetResources{}.modifiedProperties{}.displayName
|
||||
- properties.targetResources{}.modifiedProperties{}.newValue
|
||||
- properties.targetResources{}.modifiedProperties{}.oldValue
|
||||
- properties.targetResources{}.type
|
||||
- properties.userAgent
|
||||
- punct
|
||||
- resourceId
|
||||
- result
|
||||
- resultSignature
|
||||
- result_id
|
||||
- signature
|
||||
- source
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- src_user_type
|
||||
- status
|
||||
- tag
|
||||
- tag::eventtype
|
||||
- tenantId
|
||||
- time
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
- user_agent
|
||||
- user_type
|
||||
- vendor_account
|
||||
- vendor_product
|
||||
example_log: '{"time": "2024-02-08T21:49:53.7643129Z", "resourceId": "/tenants/75243ab2-44f8-435c-a7a6-b479385df6d4/providers/Microsoft.aadiam", "operationName": "Add app role assignment to service principal", "operationVersion": "1.0", "category": "AuditLogs", "tenantId": "75243ab2-44f8-435c-a7a6-b479385df6d4", "resultSignature": "None", "durationMs": 0, "correlationId": "ed53faec-49b5-444f-b6af-b928558ca433", "identity": "LegacyTestOAuthApp", "Level": 4, "properties": {"id": "Directory_ed53faec-49b5-444f-b6af-b928558ca433_XH34Q_29215277", "category": "ApplicationManagement", "correlationId": "ed53faec-49b5-444f-b6af-b928558ca433", "result": "success", "resultReason": "", "activityDisplayName": "Add app role assignment to service principal", "activityDateTime": "2024-02-08T21:49:53.7643129+00:00", "loggedByService": "Core Directory", "operationType": "Assign", "userAgent": null, "initiatedBy": {"app": {"appId": null, "displayName": "LegacyTestOAuthApp", "servicePrincipalId": "fc8c8125-bc0c-499d-8344-e53c6e3caa81", "servicePrincipalName": null}}, "targetResources": [{"id": "8429eb5c-faeb-4ade-8eac-acc003790769", "displayName": "Office 365 Exchange Online", "type": "ServicePrincipal", "modifiedProperties": [{"displayName": "AppRole.Id", "oldValue": null, "newValue": "\"dc890d15-9560-4a4c-9b7f-a736ec74ec40\""}, {"displayName": "AppRole.Value", "oldValue": null, "newValue": "\"full_access_as_app\""}, {"displayName": "AppRole.DisplayName", "oldValue": null, "newValue": "\"Use Exchange Web Services with full access to all mailboxes\""}, {"displayName": "AppRoleAssignment.CreatedDateTime", "oldValue": null, "newValue": "\"2024-02-08T21:49:53.6813076Z\""}, {"displayName": "AppRoleAssignment.LastModifiedDateTime", "oldValue": null, "newValue": "\"2024-02-08T21:49:53.6813076Z\""}, {"displayName": "ServicePrincipal.ObjectID", "oldValue": null, "newValue": "\"2e5c2fd0-cca4-452c-9891-a07c0dafd964\""}, {"displayName": "ServicePrincipal.DisplayName", "oldValue": null, "newValue": "\"STRT_Oauth\""}, {"displayName": "ServicePrincipal.AppId", "oldValue": null, "newValue": "\"5f91ce94-4cc5-4ebe-aeb6-f074e57201bb\""}, {"displayName": "ServicePrincipal.Name", "oldValue": null, "newValue": "\"5f91ce94-4cc5-4ebe-aeb6-f074e57201bb\""}, {"displayName": "TargetId.ServicePrincipalNames", "oldValue": null, "newValue": "\"https://outlook.office.com;Microsoft.Exchange;00000002-0000-0ff1-ce00-000000000000;00000002-0000-0ff1-ce00-000000000000/*.outlook.com;00000002-0000-0ff1-ce00-000000000000/outlook.com;00000002-0000-0ff1-ce00-000000000000/mail.office365.com;00000002-0000-0ff1-ce00-000000000000/outlook.office365.com;https://webmail.apps.mil/;https://ps.protection.outlook.com/;https://outlook-dod.office365.us/;https://outlook.com/;https://outlook.office365.com/;https://outlook.office.com/;https://outlook.office365.com:443/;https://outlook-sdf.office365.com/;https://outlook-sdf.office.com/;https://outlook.office365.us/;https://autodiscover-s.office365.us/;https://ps.compliance.protection.outlook.com;https://manage.protection.apps.mil;https://outlook-tdf.office.com/;https://outlook-tdf-2.office.com/;https://ps.outlook.com\""}], "administrativeUnits": []}, {"id": "2e5c2fd0-cca4-452c-9891-a07c0dafd964", "displayName": "5f91ce94-4cc5-4ebe-aeb6-f074e57201bb", "type": "ServicePrincipal", "modifiedProperties": [], "administrativeUnits": []}], "additionalDetails": [{"key": "User-Agent", "value": "Mozilla/5.0 (Macintosh; Darwin 23.3.0 Darwin Kernel Version 23.3.0: Wed Dec 20 21:28:58 PST 2023; root:xnu-10002.81.5~7/RELEASE_X86_64; en-US) PowerShell/7.3.4"}, {"key": "AppId", "value": "00000002-0000-0ff1-ce00-000000000000"}]}}'
|
||||
@@ -0,0 +1,53 @@
|
||||
event_name: Azure Active Directory Add member to role
|
||||
fields:
|
||||
- _time
|
||||
- Level
|
||||
- callerIpAddress
|
||||
- category
|
||||
- correlationId
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- durationMs
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- operationName
|
||||
- operationVersion
|
||||
- properties.activityDateTime
|
||||
- properties.activityDisplayName
|
||||
- properties.category
|
||||
- properties.correlationId
|
||||
- properties.id
|
||||
- properties.initiatedBy.user.displayName
|
||||
- properties.initiatedBy.user.id
|
||||
- properties.initiatedBy.user.ipAddress
|
||||
- properties.initiatedBy.user.userPrincipalName
|
||||
- properties.loggedByService
|
||||
- properties.operationType
|
||||
- properties.result
|
||||
- properties.resultReason
|
||||
- properties.targetResources{}.displayName
|
||||
- properties.targetResources{}.id
|
||||
- properties.targetResources{}.modifiedProperties{}.displayName
|
||||
- properties.targetResources{}.modifiedProperties{}.newValue
|
||||
- properties.targetResources{}.modifiedProperties{}.oldValue
|
||||
- properties.targetResources{}.type
|
||||
- properties.targetResources{}.userPrincipalName
|
||||
- properties.userAgent
|
||||
- punct
|
||||
- resourceId
|
||||
- resultSignature
|
||||
- source
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- tenantId
|
||||
- time
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
example_log: '{"time": "2023-04-28T16:39:51.9312625Z", "resourceId": "/tenants/fc69e276-e9e8-4af9-9002-1e410d77244e/providers/Microsoft.aadiam", "operationName": "Add member to role", "operationVersion": "1.0", "category": "AuditLogs", "tenantId": "fc69e276-e9e8-4af9-9002-1e410d77244e", "resultSignature": "None", "durationMs": 0, "callerIpAddress": "52.177.250.168", "correlationId": "b425f2d7-2245-4952-b599-61dff8054f2b", "Level": 4, "properties": {"id": "Directory_b425f2d7-2245-4952-b599-61dff8054f2b_FLAW0_72812697", "category": "RoleManagement", "correlationId": "b425f2d7-2245-4952-b599-61dff8054f2b", "result": "success", "resultReason": "", "activityDisplayName": "Add member to role", "activityDateTime": "2023-04-28T16:39:51.9312625+00:00", "loggedByService": "Core Directory", "operationType": "Assign", "userAgent": null, "initiatedBy": {"user": {"id": "3bd47e42-37c9-442f-a2b4-f04de61ef0ce", "displayName": null, "userPrincipalName": "strt_admin@splunkresearch.com", "ipAddress": "52.177.250.168", "roles": []}}, "targetResources": [{"id": "0d664d57-a3ee-4049-8642-280a5c7243ef", "displayName": null, "type": "User", "userPrincipalName": "User1@splunkresearch.com", "modifiedProperties": [{"displayName": "Role.ObjectID", "oldValue": null, "newValue": "\"38bf5baf-7ec7-4bc2-8920-6d4044da12c2\""}, {"displayName": "Role.DisplayName", "oldValue": null, "newValue": "\"Privileged Role Administrator\""}, {"displayName": "Role.TemplateId", "oldValue": null, "newValue": "\"9b895d92-2cd3-44c7-9d02-a6ac2d5ea5c3\""}, {"displayName": "Role.WellKnownObjectName", "oldValue": null, "newValue": "\"ApplicationAdministrators\""}], "administrativeUnits": []}, {"id": "38bf5baf-7ec7-4bc2-8920-6d4044da12c2", "displayName": null, "type": "Role", "modifiedProperties": [], "administrativeUnits": []}], "additionalDetails": []}}'
|
||||
@@ -0,0 +1,58 @@
|
||||
event_name: Azure Active Directory Add owner to application
|
||||
fields:
|
||||
- _time
|
||||
- Level
|
||||
- callerIpAddress
|
||||
- category
|
||||
- correlationId
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- durationMs
|
||||
- eventtype
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- operationName
|
||||
- operationVersion
|
||||
- properties.activityDateTime
|
||||
- properties.activityDisplayName
|
||||
- properties.additionalDetails{}.key
|
||||
- properties.additionalDetails{}.value
|
||||
- properties.category
|
||||
- properties.correlationId
|
||||
- properties.id
|
||||
- properties.initiatedBy.user.displayName
|
||||
- properties.initiatedBy.user.id
|
||||
- properties.initiatedBy.user.ipAddress
|
||||
- properties.initiatedBy.user.userPrincipalName
|
||||
- properties.loggedByService
|
||||
- properties.operationType
|
||||
- properties.result
|
||||
- properties.resultReason
|
||||
- properties.targetResources{}.displayName
|
||||
- properties.targetResources{}.id
|
||||
- properties.targetResources{}.modifiedProperties{}.displayName
|
||||
- properties.targetResources{}.modifiedProperties{}.newValue
|
||||
- properties.targetResources{}.modifiedProperties{}.oldValue
|
||||
- properties.targetResources{}.type
|
||||
- properties.targetResources{}.userPrincipalName
|
||||
- properties.userAgent
|
||||
- punct
|
||||
- resourceId
|
||||
- resultSignature
|
||||
- source
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- tag
|
||||
- tag::eventtype
|
||||
- tenantId
|
||||
- time
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
example_log: '{"time": "2023-06-20T15:54:13.2420879Z", "resourceId": "/tenants/fc69e276-e9e8-4af9-9002-1e410d77244e/providers/Microsoft.aadiam", "operationName": "Add owner to application", "operationVersion": "1.0", "category": "AuditLogs", "tenantId": "fc69e276-e9e8-4af9-9002-1e410d77244e", "resultSignature": "None", "durationMs": 0, "callerIpAddress": "20.190.135.43", "correlationId": "231de5d4-2156-433a-8163-48956bdaa040", "Level": 4, "properties": {"id": "Directory_231de5d4-2156-433a-8163-48956bdaa040_C21RW_365283677", "category": "ApplicationManagement", "correlationId": "231de5d4-2156-433a-8163-48956bdaa040", "result": "success", "resultReason": "", "activityDisplayName": "Add owner to application", "activityDateTime": "2023-06-20T15:54:13.2420879+00:00", "loggedByService": "Core Directory", "operationType": "Assign", "userAgent": null, "initiatedBy": {"user": {"id": "4d3f1865-b395-4430-91dc-1b9dd337712e", "displayName": null, "userPrincipalName": "globaladmin@splunkresearch.com", "ipAddress": "20.190.135.43", "roles": []}}, "targetResources": [{"id": "dd92f1af-43d7-47d9-b93c-a78c6b635180", "displayName": null, "type": "User", "userPrincipalName": "Abigail.Clark@splunkresearch.com", "modifiedProperties": [{"displayName": "Application.ObjectID", "oldValue": null, "newValue": "\"bb2479d8-5e89-4480-bb7e-3178d5a5d469\""}, {"displayName": "Application.DisplayName", "oldValue": null, "newValue": "\"CloudForge\""}, {"displayName": "Application.AppId", "oldValue": null, "newValue": "\"f0748f3d-45f2-4e2e-a4e1-f2e2b5271bdf\""}], "administrativeUnits": []}, {"id": "bb2479d8-5e89-4480-bb7e-3178d5a5d469", "displayName": null, "type": "Application", "modifiedProperties": [], "administrativeUnits": []}], "additionalDetails": [{"key": "User-Agent", "value": "Mozilla/5.0 (Macintosh; Darwin 22.4.0 Darwin Kernel Version 22.4.0: Mon Mar 6 21:00:17 PST 2023; root:xnu-8796.101.5~3/RELEASE_X86_64; en-US) PowerShell/7.3.4"}]}}'
|
||||
@@ -0,0 +1,53 @@
|
||||
event_name: Azure Active Directory Add service principal
|
||||
fields:
|
||||
- _time
|
||||
- Level
|
||||
- category
|
||||
- correlationId
|
||||
- date_hour
|
||||
- date_mday
|
||||
- date_minute
|
||||
- date_month
|
||||
- date_second
|
||||
- date_wday
|
||||
- date_year
|
||||
- date_zone
|
||||
- durationMs
|
||||
- host
|
||||
- index
|
||||
- linecount
|
||||
- operationName
|
||||
- operationVersion
|
||||
- properties.activityDateTime
|
||||
- properties.activityDisplayName
|
||||
- properties.additionalDetails{}.key
|
||||
- properties.additionalDetails{}.value
|
||||
- properties.category
|
||||
- properties.correlationId
|
||||
- properties.id
|
||||
- properties.initiatedBy.user.displayName
|
||||
- properties.initiatedBy.user.id
|
||||
- properties.initiatedBy.user.ipAddress
|
||||
- properties.initiatedBy.user.userPrincipalName
|
||||
- properties.loggedByService
|
||||
- properties.operationType
|
||||
- properties.result
|
||||
- properties.resultReason
|
||||
- properties.targetResources{}.displayName
|
||||
- properties.targetResources{}.id
|
||||
- properties.targetResources{}.modifiedProperties{}.displayName
|
||||
- properties.targetResources{}.modifiedProperties{}.newValue
|
||||
- properties.targetResources{}.modifiedProperties{}.oldValue
|
||||
- properties.targetResources{}.type
|
||||
- properties.userAgent
|
||||
- punct
|
||||
- resourceId
|
||||
- resultSignature
|
||||
- source
|
||||
- sourcetype
|
||||
- splunk_server
|
||||
- tenantId
|
||||
- time
|
||||
- timeendpos
|
||||
- timestartpos
|
||||
example_log: '{"time": "2024-02-07T22:31:14.4970418Z", "resourceId": "/tenants/a417c578-c7ee-480d-a225-d48057e74df5/providers/Microsoft.aadiam", "operationName": "Add service principal", "operationVersion": "1.0", "category": "AuditLogs", "tenantId": "a417c578-c7ee-480d-a225-d48057e74df5", "resultSignature": "None", "durationMs": 0, "correlationId": "ea473f15-64b3-435a-a885-6ee3908919e2", "Level": 4, "properties": {"id": "Directory_ea473f15-64b3-435a-a885-6ee3908919e2_GSOLK_21152854", "category": "ApplicationManagement", "correlationId": "ea473f15-64b3-435a-a885-6ee3908919e2", "result": "success", "resultReason": "", "activityDisplayName": "Add service principal", "activityDateTime": "2024-02-07T22:31:14.4970418+00:00", "loggedByService": "Core Directory", "operationType": "Add", "userAgent": null, "initiatedBy": {"user": {"id": "e4c722ac-3b83-478d-8f52-c388885dc30f", "displayName": null, "userPrincipalName": "Herman@phantomengineering.onmicrosoft.com", "ipAddress": "", "roles": []}}, "targetResources": [{"id": "2dedf863-ac93-4f45-87b3-e32f48145380", "displayName": "Malicious11", "type": "ServicePrincipal", "modifiedProperties": [{"displayName": "AccountEnabled", "oldValue": "[]", "newValue": "[true]"}, {"displayName": "AppPrincipalId", "oldValue": "[]", "newValue": "[\"e06366ca-8489-4748-b6a2-d7e4332f45c1\"]"}, {"displayName": "DisplayName", "oldValue": "[]", "newValue": "[\"Malicious11\"]"}, {"displayName": "ServicePrincipalName", "oldValue": "[]", "newValue": "[\"e06366ca-8489-4748-b6a2-d7e4332f45c1\"]"}, {"displayName": "Credential", "oldValue": "[]", "newValue": "[{\"CredentialType\":2,\"KeyStoreId\":\"291154f0-a9f5-45bb-87be-9c8ee5b6d62c\",\"KeyGroupId\":\"291154f0-a9f5-45bb-87be-9c8ee5b6d62c\"}]"}, {"displayName": "Included Updated Properties", "oldValue": null, "newValue": "\"AccountEnabled, AppPrincipalId, DisplayName, ServicePrincipalName, Credential\""}, {"displayName": "TargetId.ServicePrincipalNames", "oldValue": null, "newValue": "\"e06366ca-8489-4748-b6a2-d7e4332f45c1\""}], "administrativeUnits": []}], "additionalDetails": [{"key": "User-Agent", "value": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36"}, {"key": "AppId", "value": "e06366ca-8489-4748-b6a2-d7e4332f45c1"}]}}'
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user