9
9
10
10
# need to set this ENV var due to a OSX High Sierra forking bug
11
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'
12
+ os .environ [" OBJC_DISABLE_INITIALIZE_FORK_SAFETY" ] = " YES"
13
13
14
14
15
15
def init (args ):
16
16
config_path = args .config
17
- print ("""
17
+ print (
18
+ """
18
19
__
19
20
.d$$b
20
21
.' TO$;\\
@@ -44,110 +45,146 @@ def init(args):
44
45
45
46
By: Splunk Threat Research Team [STRT] - research@splunk.com
46
47
47
- """ )
48
+ """
49
+ )
48
50
49
51
# parse config
50
52
config = ConfigHandler .read_config (config_path )
51
53
ConfigHandler .validate_config (config )
52
54
53
- if config ['general' ]['cloud_provider' ] == 'aws' :
54
- config .pop ('azure' )
55
- config .pop ('local' )
55
+ if config ["general" ]["cloud_provider" ] == "aws" :
56
+ config .pop ("azure" )
56
57
controller = AwsController (config )
57
- elif config ['general' ]['cloud_provider' ] == 'azure' :
58
- config .pop ('aws' )
59
- config .pop ('local' )
58
+ elif config ["general" ]["cloud_provider" ] == "azure" :
59
+ config .pop ("aws" )
60
60
controller = AzureController (config )
61
- elif config ['general' ]['cloud_provider' ] == 'local' :
62
- from modules .vagrant_controller import VagrantController
63
- config .pop ('azure' )
64
- config .pop ('aws' )
65
- controller = VagrantController (config )
66
-
61
+
67
62
return controller
68
63
69
64
70
65
def simulate (args ):
71
66
controller = init (args )
72
67
controller .simulate (args .engine , args .target , args .technique , args .playbook )
73
68
69
+
74
70
def dump (args ):
75
71
controller = init (args )
76
72
controller .dump (args .file_name , args .search , args .earliest , args .latest )
77
73
74
+
78
75
def replay (args ):
79
76
controller = init (args )
80
77
controller .replay (args .file_name , args .index , args .sourcetype , args .source )
81
78
79
+
82
80
def build (args ):
83
81
controller = init (args )
84
82
controller .build ()
85
83
84
+
86
85
def destroy (args ):
87
86
controller = init (args )
88
87
controller .destroy ()
89
88
89
+
90
90
def stop (args ):
91
91
controller = init (args )
92
- instance_ids = [id .strip () for id in args .instance_ids .split (',' )] if args .instance_ids else None
92
+ instance_ids = (
93
+ [id .strip () for id in args .instance_ids .split ("," )]
94
+ if args .instance_ids
95
+ else None
96
+ )
93
97
controller .stop (instance_ids )
94
-
98
+
99
+
95
100
def resume (args ):
96
101
controller = init (args )
97
- instance_ids = [id .strip () for id in args .instance_ids .split (',' )] if args .instance_ids else None
102
+ instance_ids = (
103
+ [id .strip () for id in args .instance_ids .split ("," )]
104
+ if args .instance_ids
105
+ else None
106
+ )
98
107
controller .resume (instance_ids )
99
108
100
- def packer (args ):
101
- controller = init (args )
102
- controller .packer (args .image_name )
103
109
104
110
def configure (args ):
105
111
configuration .new (args .config )
106
112
113
+
107
114
def show (args ):
108
115
controller = init (args )
109
116
controller .show ()
110
117
118
+
111
119
def create_remote_backend (args ):
112
120
controller = init (args )
113
121
controller .create_remote_backend (args .backend_name )
114
122
123
+
115
124
def delete_remote_backend (args ):
116
125
controller = init (args )
117
126
controller .delete_remote_backend (args .backend_name )
118
127
128
+
119
129
def init_remote_backend (args ):
120
130
controller = init (args )
121
131
controller .init_remote_backend (args .backend_name )
122
132
133
+
123
134
def main (args ):
124
135
"""
125
136
main function parses the arguments passed to the script and calls the respctive method.
126
137
127
138
:param args: Arguments passed by the user on command line while calling the script.
128
- :return: returns the output of the function called.
139
+ :return: returns the output of the function called.
129
140
"""
130
141
# grab arguments
131
142
parser = argparse .ArgumentParser (
132
- description = "Use `attack_range.py action -h` to get help with any Attack Range action" )
133
- parser .add_argument ("-c" , "--config" , required = False , default = "attack_range.yml" ,
134
- help = "path to the configuration file of the attack range" )
143
+ description = "Use `attack_range.py action -h` to get help with any Attack Range action"
144
+ )
145
+ parser .add_argument (
146
+ "-c" ,
147
+ "--config" ,
148
+ required = False ,
149
+ default = "attack_range.yml" ,
150
+ help = "path to the configuration file of the attack range" ,
151
+ )
135
152
parser .set_defaults (func = lambda _ : parser .print_help ())
136
153
137
154
actions_parser = parser .add_subparsers (title = "attack Range actions" , dest = "action" )
138
- configure_parser = actions_parser .add_parser ("configure" , help = "configure a new attack range" )
139
- build_parser = actions_parser .add_parser ("build" , help = "builds attack range instances" )
140
- simulate_parser = actions_parser .add_parser ("simulate" , help = "simulates attack techniques" )
141
- destroy_parser = actions_parser .add_parser ("destroy" , help = "destroy attack range instances" )
155
+ configure_parser = actions_parser .add_parser (
156
+ "configure" , help = "configure a new attack range"
157
+ )
158
+ build_parser = actions_parser .add_parser (
159
+ "build" , help = "builds attack range instances"
160
+ )
161
+ simulate_parser = actions_parser .add_parser (
162
+ "simulate" , help = "simulates attack techniques"
163
+ )
164
+ destroy_parser = actions_parser .add_parser (
165
+ "destroy" , help = "destroy attack range instances"
166
+ )
142
167
stop_parser = actions_parser .add_parser ("stop" , help = "stops attack range instances" )
143
- resume_parser = actions_parser .add_parser ("resume" , help = "resumes previously stopped attack range instances" )
168
+ resume_parser = actions_parser .add_parser (
169
+ "resume" , help = "resumes previously stopped attack range instances"
170
+ )
144
171
packer_parser = actions_parser .add_parser ("packer" , help = "create golden images" )
145
172
show_parser = actions_parser .add_parser ("show" , help = "list machines" )
146
- dump_parser = actions_parser .add_parser ("dump" , help = "dump locally logs from attack range instances" )
147
- replay_parser = actions_parser .add_parser ("replay" , help = "replay dumps into the splunk server" )
148
- create_remote_backend_parser = actions_parser .add_parser ("create_remote_backend" , help = "Create a Remote Backend" )
149
- delete_remote_backend_parser = actions_parser .add_parser ("delete_remote_backend" , help = "Delete a Remote Backend" )
150
- init_remote_backend_parser = actions_parser .add_parser ("init_remote_backend" , help = "Init a Remote Backend" )
173
+ dump_parser = actions_parser .add_parser (
174
+ "dump" , help = "dump locally logs from attack range instances"
175
+ )
176
+ replay_parser = actions_parser .add_parser (
177
+ "replay" , help = "replay dumps into the splunk server"
178
+ )
179
+ create_remote_backend_parser = actions_parser .add_parser (
180
+ "create_remote_backend" , help = "Create a Remote Backend"
181
+ )
182
+ delete_remote_backend_parser = actions_parser .add_parser (
183
+ "delete_remote_backend" , help = "Delete a Remote Backend"
184
+ )
185
+ init_remote_backend_parser = actions_parser .add_parser (
186
+ "init_remote_backend" , help = "Init a Remote Backend"
187
+ )
151
188
152
189
# Build arguments
153
190
build_parser .set_defaults (func = build )
@@ -157,73 +194,117 @@ def main(args):
157
194
158
195
# Stop arguments
159
196
stop_parser .set_defaults (func = stop )
160
- stop_parser .add_argument ("--instance_ids" , required = False , type = str , help = "comma-separated list of instance IDs to stop" )
197
+ stop_parser .add_argument (
198
+ "--instance_ids" ,
199
+ required = False ,
200
+ type = str ,
201
+ help = "comma-separated list of instance IDs to stop" ,
202
+ )
161
203
162
204
# Resume arguments
163
205
resume_parser .set_defaults (func = resume )
164
- resume_parser .add_argument ("--instance_ids" , required = False , type = str , help = "comma-separated list of instance IDs to resume" )
165
-
166
- # Packer agruments
167
- packer_parser . add_argument ( "-in" , "--image_name" , required = True , type = str ,
168
- help = "provide image name such as splunk, linux, windows-2016, windows-2019, nginx, windows-10, windows-11" )
169
- packer_parser . set_defaults ( func = packer )
206
+ resume_parser .add_argument (
207
+ "--instance_ids" ,
208
+ required = False ,
209
+ type = str ,
210
+ help = "comma-separated list of instance IDs to resume" ,
211
+ )
170
212
171
213
# Configure arguments
172
- configure_parser .add_argument ("-c" , "--config" , required = False , type = str , default = 'attack_range.yml' ,
173
- help = "provide path to write configuration to" )
214
+ configure_parser .add_argument (
215
+ "-c" ,
216
+ "--config" ,
217
+ required = False ,
218
+ type = str ,
219
+ default = "attack_range.yml" ,
220
+ help = "provide path to write configuration to" ,
221
+ )
174
222
configure_parser .set_defaults (func = configure )
175
223
176
224
# Simulation arguments
177
- simulate_parser .add_argument ("-e" , "--engine" , required = False , default = "ART" ,
178
- help = "simulation engine to use. Available options are: PurpleSharp and ART (default)" )
179
- simulate_parser .add_argument ("-t" , "--target" , required = True ,
180
- help = "target for attack simulation. Use the name of the aws EC2 name" )
181
- simulate_parser .add_argument ("-te" , "--technique" , required = False , type = str , default = "" ,
182
- help = "comma delimited list of MITRE ATT&CK technique ID to simulate in the "
183
- "attack_range, example: T1117, T1118" )
184
- simulate_parser .add_argument ("-p" , "--playbook" , required = False , type = str , default = "" ,
185
- help = "file path for a simulation playbook" )
225
+ simulate_parser .add_argument (
226
+ "-e" ,
227
+ "--engine" ,
228
+ required = False ,
229
+ default = "ART" ,
230
+ help = "simulation engine to use. Available options are: PurpleSharp and ART (default)" ,
231
+ )
232
+ simulate_parser .add_argument (
233
+ "-t" ,
234
+ "--target" ,
235
+ required = True ,
236
+ help = "target for attack simulation. Use the name of the aws EC2 name" ,
237
+ )
238
+ simulate_parser .add_argument (
239
+ "-te" ,
240
+ "--technique" ,
241
+ required = False ,
242
+ type = str ,
243
+ default = "" ,
244
+ help = "comma delimited list of MITRE ATT&CK technique ID to simulate in the "
245
+ "attack_range, example: T1117, T1118" ,
246
+ )
247
+ simulate_parser .add_argument (
248
+ "-p" ,
249
+ "--playbook" ,
250
+ required = False ,
251
+ type = str ,
252
+ default = "" ,
253
+ help = "file path for a simulation playbook" ,
254
+ )
186
255
187
256
simulate_parser .set_defaults (func = simulate )
188
257
189
258
# Dump Arguments
190
- dump_parser .add_argument ("-fn" , "--file_name" , required = True ,
191
- help = "file name of the attack_data" )
192
- dump_parser .add_argument ("--search" , required = True ,
193
- help = "splunk search to export" )
194
- dump_parser .add_argument ("--earliest" , required = True ,
195
- help = "earliest time of the splunk search" )
196
- dump_parser .add_argument ("--latest" , required = False , default = "now" ,
197
- help = "latest time of the splunk search" )
259
+ dump_parser .add_argument (
260
+ "-fn" , "--file_name" , required = True , help = "file name of the attack_data"
261
+ )
262
+ dump_parser .add_argument ("--search" , required = True , help = "splunk search to export" )
263
+ dump_parser .add_argument (
264
+ "--earliest" , required = True , help = "earliest time of the splunk search"
265
+ )
266
+ dump_parser .add_argument (
267
+ "--latest" ,
268
+ required = False ,
269
+ default = "now" ,
270
+ help = "latest time of the splunk search" ,
271
+ )
198
272
dump_parser .set_defaults (func = dump )
199
273
200
274
# Replay Arguments
201
- replay_parser .add_argument ("-fn" , "--file_name" , required = True ,
202
- help = "file name of the attack_data" )
203
- replay_parser .add_argument ("--source" , required = True ,
204
- help = "source of replayed data" )
205
- replay_parser .add_argument ("--sourcetype" , required = True ,
206
- help = "sourcetype of replayed data" )
207
- replay_parser .add_argument ("--index" , required = False , default = "test" ,
208
- help = "index of replayed data" )
275
+ replay_parser .add_argument (
276
+ "-fn" , "--file_name" , required = True , help = "file name of the attack_data"
277
+ )
278
+ replay_parser .add_argument (
279
+ "--source" , required = True , help = "source of replayed data"
280
+ )
281
+ replay_parser .add_argument (
282
+ "--sourcetype" , required = True , help = "sourcetype of replayed data"
283
+ )
284
+ replay_parser .add_argument (
285
+ "--index" , required = False , default = "test" , help = "index of replayed data"
286
+ )
209
287
replay_parser .set_defaults (func = replay )
210
288
211
289
# Show arguments
212
290
show_parser .set_defaults (func = show , machines = True )
213
291
214
292
# Create Remote Backend
215
- create_remote_backend_parser .add_argument ("-bn" , "--backend_name" , required = True ,
216
- help = "name of the remote backend" )
293
+ create_remote_backend_parser .add_argument (
294
+ "-bn" , "--backend_name" , required = True , help = "name of the remote backend"
295
+ )
217
296
create_remote_backend_parser .set_defaults (func = create_remote_backend )
218
297
219
298
# Delete Remote Backend
220
- delete_remote_backend_parser .add_argument ("-bn" , "--backend_name" , required = True ,
221
- help = "name of the remote backend" )
299
+ delete_remote_backend_parser .add_argument (
300
+ "-bn" , "--backend_name" , required = True , help = "name of the remote backend"
301
+ )
222
302
delete_remote_backend_parser .set_defaults (func = delete_remote_backend )
223
-
303
+
224
304
# Init Remote Backend
225
- init_remote_backend_parser .add_argument ("-bn" , "--backend_name" , required = True ,
226
- help = "name of the remote backend" )
305
+ init_remote_backend_parser .add_argument (
306
+ "-bn" , "--backend_name" , required = True , help = "name of the remote backend"
307
+ )
227
308
init_remote_backend_parser .set_defaults (func = init_remote_backend )
228
309
229
310
# # parse them
0 commit comments