Skip to content

Commit 5c07389

Browse files
committed
total_replay_tool
1 parent ff5b252 commit 5c07389

File tree

11 files changed

+2027
-3
lines changed

11 files changed

+2027
-3
lines changed

bin/replay.py

Lines changed: 71 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from urllib3 import disable_warnings
1111
import yaml
1212
from pathlib import Path
13-
13+
from urllib.parse import urlparse, urlunparse, unquote
1414

1515
def load_environment_variables():
1616
"""Load required environment variables for Splunk connection."""
@@ -114,6 +114,70 @@ def send_data_to_splunk(file_path, splunk_host, hec_token, event_host_uuid,
114114
except Exception as e:
115115
print(f":x: Error sending {file_path} to Splunk HEC: {e}")
116116

117+
def parse_old_attack_yml_data_file(yml_file_path,
118+
index_override,
119+
source_override,
120+
sourcetype_override,
121+
host_uuid):
122+
### handling possible empty inputs
123+
print("Processing old attack data yml file")
124+
if source_override == "" or sourcetype_override == "" or index_override == "":
125+
return None, [], {}
126+
127+
try:
128+
with open(yml_file_path, 'r') as file:
129+
data = yaml.safe_load(file)
130+
131+
# Extract required fields
132+
file_id = host_uuid
133+
d = data.get('dataset')
134+
### if the instance is list
135+
if isinstance(d, list):
136+
dataset_val = d[0]
137+
if isinstance(d, str):
138+
dataset_val = d
139+
140+
name_value = os.path.basename(dataset_val).split(".")[0]
141+
p = urlparse(dataset_val)
142+
if not p.scheme or not p.netloc:
143+
raise ValueError(f"Unsupported GitHub URL format: {dataset_val}")
144+
145+
m, path_value = str(p.path).split("master")
146+
### generate our own datasets data
147+
### "datasets": [
148+
### {
149+
### "name": "windows-sysmon_creddump",
150+
### "path": "/datasets/attack_techniques/T1003.001/atomic_red_team/windows-sysmon_creddump.log",
151+
### "sourcetype": "XmlWinEventLog",
152+
### "source": "XmlWinEventLog:Microsoft-Windows-Sysmon/Operational"
153+
### }
154+
### ]
155+
# Extract required fields
156+
157+
datasets = [
158+
{
159+
"name": name_value,
160+
"path": path_value,
161+
"sourcetype":sourcetype_override,
162+
"source":source_override
163+
}
164+
]
165+
#print(datasets)
166+
# Extract default metadata from YAML file
167+
default_index = index_override
168+
default_source = source_override
169+
default_sourcetype = sourcetype_override
170+
171+
# Return tuple of (id, datasets_list, default_metadata)
172+
return file_id, datasets, {
173+
'index': default_index,
174+
'source': default_source,
175+
'sourcetype': default_sourcetype
176+
}
177+
178+
except Exception as e:
179+
print(f"Error parsing {yml_file_path}: {e}")
180+
return None, [], {}
117181

118182
def main():
119183
parser = argparse.ArgumentParser(
@@ -205,8 +269,12 @@ def main():
205269
file_id, datasets, defaults = parse_data_yml(yml_file)
206270

207271
if not file_id or not datasets:
208-
print(f"Skipping {yml_file} - no valid data found")
209-
continue
272+
273+
file_id, datasets, defaults = parse_old_attack_yml_data_file(yml_file, args.index_override, args.source_override, args.sourcetype_override, args.host_uuid)
274+
275+
if not file_id or not datasets:
276+
print(f"Skipping {yml_file} - no valid data found")
277+
continue
210278

211279
# Use the id from YAML file as host field (unless user provided one)
212280
event_host_uuid = args.host_uuid or file_id

total_replay/assets/banner.png

107 KB
Loading

total_replay/assets/usage.png

417 KB
Loading
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
settings:
2+
security_content_detection_path: ~/path/to/your/security_content/detections
3+
attack_range_dir_path: ~/path/to/your/attack_range
4+
attack_data_dir_path: ~/path/to/your/attack_data
5+
attack_range_py_name: attack_range.py
6+
output_dir_name : output
7+
cache_replay_yaml_name : cache_replay_data.yml
8+
replayed_yaml_cache_dir_name: replayed_yaml_cache
9+
python_interpreter_name: python3
10+
attack_range_version_on: False
11+
attack_data_version_on: True
12+
debug_print: True

total_replay/poetry.lock

Lines changed: 740 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

total_replay/pyproject.toml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
[project]
2+
name = "total-replay"
3+
version = "0.1.0"
4+
description = "Attack Data Replay Amplifier"
5+
authors = [
6+
{name = "Teoderick Contreras",email = "[email protected]"}
7+
]
8+
license = {text = "Apache License"}
9+
requires-python = ">=3.13"
10+
dependencies = [
11+
"rich (>=14.2.0,<15.0.0)",
12+
"typer (>=0.20.0,<0.21.0)",
13+
"pyyaml (>=6.0.3,<7.0.0)",
14+
"requests (>=2.32.5,<3.0.0)",
15+
"urllib3 (>=2.5.0,<3.0.0)",
16+
"pandas (>=2.3.3,<3.0.0)",
17+
"colorama (>=0.4.6,<0.5.0)",
18+
"ansible-runner (>=2.4.2,<3.0.0)"
19+
]
20+
21+
22+
[build-system]
23+
requires = ["poetry-core>=2.0.0,<3.0.0"]
24+
build-backend = "poetry.core.masonry.api"

total_replay/readme.md

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# TOTAL-REPLAY
2+
3+
![TOTAL-REPLAY](assets/banner.png)
4+
5+
## Description
6+
7+
This lightweight tool helps you make the most of Splunk’s [Security Content](https://github.com/splunk/security_content) metadata, such as detection names, analytic stories, and more, by replaying relevant test event logs or attack data from either the [Splunk Attack Data](https://github.com/splunk/attack_data) or [Splunk Attack Range](https://github.com/splunk/attack_range) projects.
8+
9+
## Installation
10+
11+
### MAC/LINUX
12+
#### TOTAL-REPLAY IN SPLUNK ATTACK-DATA REPO
13+
1. Clone the Splunk Security Content github repo. We recommend to follow this steps [Security Content Getting Started](https://github.com/splunk/security_content).
14+
15+
2. Install Poetry (if not already installed)
16+
```
17+
curl -sSL https://install.python-poetry.org/ | python3 -
18+
```
19+
3. Navigate to your project directory
20+
```
21+
cd /path/to/your/total-replay-project
22+
```
23+
4. Create a virtual environment and activate it
24+
```
25+
poetry shell
26+
```
27+
5. Install project dependencies
28+
29+
6. In total_replay->configuration->config.yml, add the folder path of the Splunk Attack Data repo and the detection folder path in Splunk Security Content.
30+
31+
```
32+
settings:
33+
security_content_detection_path: ~/path/to/your/security_content/detections
34+
attack_data_dir_path: ~/path/to/your/attack_data
35+
```
36+
7. make sure you setup the required environment variables for splunk server connection
37+
38+
| Environment Variables. | Description |
39+
|----------------------------|-------------------------|
40+
| **SPLUNK_HOST** | SPLUNK HOST IP ADDRESS |
41+
| **SPLUNK_HEC_TOKEN** | SPLUNK SERVER HEC TOKEN |
42+
43+
you can use the `export` commandline function for adding these environment variables
44+
45+
```
46+
export SPLUNK_HOST= <IP_ADDRESS>
47+
export SPLUNK_HEC_TOKEN= <SPLUNK_HEC_TOKEN>
48+
```
49+
50+
### Windows
51+
We recommend using the Windows Subsystem for Linux (WSL). You can find a tutorial [here](https://learn.microsoft.com/en-us/windows/wsl/install). After installing WSL, you can follow the steps described in the Linux section.
52+
53+
54+
## Usage
55+
56+
![TOTAL-REPLAY-USAGE](assets/usage.png)
57+
58+
### Features
59+
60+
A. This tool accepts the following types of metadata as input:
61+
62+
- **Splunk detection names**
63+
- **MITRE ATT&CK tactic and technique IDs**
64+
- **Splunk detection GUIDs**
65+
- **Analytic stories**
66+
67+
It then uses these inputs to identify and replay the attack data associated with them.
68+
69+
B. Or for automation purposes, you can use a simple .txt file like:
70+
71+
```
72+
wsreset_uac_bypass.yml
73+
wscript_or_cscript_suspicious_child_process.yml
74+
windows_user_deletion_via_net.yml
75+
Windows User Disabled Via Net
76+
Windows Chromium Browser No Security Sandbox Process
77+
004e32e2-146d-11ec-a83f-acde48001122
78+
01d29b48-ff6f-11eb-b81e-acde48001123
79+
#T1014
80+
T1589.001
81+
Amos Stealer
82+
PromptLock
83+
f64579c0-203f-11ec-abcc-acde48001122
84+
004e32e2-146d-11ec-a83f-acde48001122
85+
```
86+
87+
that contains all the Security Content metadata you want to replay and then choose if you want to replay them all

total_replay/test/test_names.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
wsreset_uac_bypass.yml
2+
wscript_or_cscript_suspicious_child_process.yml
3+
windows_user_deletion_via_net.yml
4+
Windows User Disabled Via Net
5+
Windows Chromium Browser No Security Sandbox Process
6+
004e32e2-146d-11ec-a83f-acde48001122
7+
01d29b48-ff6f-11eb-b81e-acde48001123
8+
#T1014
9+
T1589.001
10+
Amos Stealer
11+
PromptLock
12+
f64579c0-203f-11ec-abcc-acde48001122
13+
004e32e2-146d-11ec-a83f-acde48001122

0 commit comments

Comments
 (0)