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:
Gowthamaraj Rajendran
2024-05-22 16:47:39 +00:00
1891 changed files with 18259 additions and 225171 deletions
+1
View File
@@ -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.
-97
View File
@@ -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 -2
View File
@@ -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
+38
View File
@@ -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\""}}'
+34
View File
@@ -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]'
+27
View File
@@ -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
+39
View File
@@ -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
+27
View File
@@ -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
+35
View File
@@ -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
+32
View File
@@ -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
+66
View File
@@ -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
+41
View File
@@ -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
+229
View File
@@ -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"}}'
+122
View File
@@ -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}}'
+17
View File
@@ -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
+78
View File
@@ -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"}}'
+52
View File
@@ -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"}'
+108
View File
@@ -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}'
+205
View File
@@ -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'
+17
View File
@@ -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
+61
View File
@@ -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":""}}'
+48
View File
@@ -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)'
+123
View File
@@ -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"}}'
@@ -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