1
- from argparse import ArgumentParser
2
- from netaddr import IPNetwork , IPRange , IPGlob
3
- from Interlace .lib .core .output import OutputHelper , Level
4
1
import os .path
5
- from os import access , W_OK
6
2
import sys
7
- from re import compile
8
- from random import sample , choice
3
+ from argparse import ArgumentParser
9
4
from math import ceil
5
+ from random import sample , choice
6
+
7
+ from netaddr import IPNetwork , IPRange , IPGlob
8
+
9
+ from Interlace .lib .threader import Task
10
10
11
11
12
12
class InputHelper (object ):
@@ -78,134 +78,148 @@ def _get_cidr_to_ips(cidr_range):
78
78
return ips
79
79
80
80
@staticmethod
81
- def _replace_variable_for_commands (commands , variable , replacements ):
82
- tmp_commands = set ()
81
+ def _process_port (port_type ):
82
+ if "," in port_type :
83
+ return port_type .split ("," )
84
+ elif "-" in port_type :
85
+ tmp = port_type .split ("-" )
86
+ begin_range = int (tmp [0 ])
87
+ end_range = int (tmp [1 ])
88
+ if begin_range >= end_range :
89
+ raise Exception ("Invalid range provided" )
90
+ return list (range (begin_range , end_range + 1 ))
91
+ return [port_type ]
83
92
84
- test = list ()
85
-
86
- for replacement in replacements :
87
- for command in commands :
88
- test .append (str (command ).replace (variable , str (replacement )))
89
-
90
- tmp_commands .update (test )
91
- return tmp_commands
92
-
93
93
@staticmethod
94
- def _replace_variable_array (commands , variable , replacement ):
95
- tmp_commands = set ()
96
- counter = 0
94
+ def _pre_process_commands (command_list , task_name , is_global_task = True ):
95
+ """
96
+ :param command_list:
97
+ :param task_name: all tasks have 'scope' and all scopes have unique names, global scope defaults ''
98
+ :param is_global_task: when True, signifies that all global tasks are meant to be run concurrently
99
+ :return: list of possibly re-adjusted commands
100
+ """
101
+ task_block = []
102
+ sibling = None
103
+ global_task = None
104
+ for command in command_list :
105
+ command = str (command ).strip ()
106
+ if not command :
107
+ continue
108
+ # the start or end of a command block
109
+ if command .startswith ('_block:' ) and command .endswith ('_' ):
110
+ new_task_name = command .split ('_block:' )[1 ][:- 1 ].strip ()
111
+ # if this is the end of a block, then we're done
112
+ if task_name == new_task_name :
113
+ return task_block
114
+ # otherwise pre-process all the commands in this new `new_task_name` block
115
+ for task in InputHelper ._pre_process_commands (command_list , new_task_name , False ):
116
+ task_block .append (task )
117
+ sibling = task
118
+ continue
119
+ else :
120
+ # if a blocker is encountered, all commands following the blocker must wait until the last
121
+ # command in the block is executed. All block commands are synchronous
122
+ if command == '_blocker_' :
123
+ global_task = sibling
124
+ continue
125
+ task = Task (command )
126
+ # if we're in the global scope and there was a previous _blocker_ encountered, we wait for the last
127
+ # child of the block
128
+ if is_global_task and global_task :
129
+ task .wait_for (global_task .get_lock ())
130
+ # all but the first command in a block scope wait for its predecessor
131
+ elif sibling and not is_global_task :
132
+ task .wait_for (sibling .get_lock ())
133
+ task_block .append (task )
134
+ sibling = task
135
+ return task_block
97
136
98
- test = list ()
137
+ @staticmethod
138
+ def _pre_process_hosts (host_ranges , destination_set , arguments ):
139
+ for host in host_ranges :
140
+ host = host .replace (" " , "" )
141
+ for ips in host .split ("," ):
142
+ # check if it is a domain name
143
+ if ips .split ("." )[- 1 ][0 ].isalpha ():
144
+ destination_set .add (ips )
145
+ continue
146
+ # checking for CIDR
147
+ if not arguments .nocidr and "/" in ips :
148
+ destination_set .update (InputHelper ._get_cidr_to_ips (ips ))
149
+ # checking for IPs in a range
150
+ elif "-" in ips :
151
+ destination_set .update (InputHelper ._get_ips_from_range (ips ))
152
+ # checking for glob ranges
153
+ elif "*" in ips :
154
+ destination_set .update (InputHelper ._get_ips_from_glob (ips ))
155
+ else :
156
+ destination_set .add (ips )
99
157
100
- if not variable in sample (commands , 1 )[0 ]:
101
- return commands
158
+ @staticmethod
159
+ def _replace_variable_with_commands (commands , variable , replacements ):
160
+ def add_task (t , item_list ):
161
+ if t not in set (item_list ):
162
+ item_list .append (t )
102
163
164
+ tasks = []
103
165
for command in commands :
104
- test .append (str (command ).replace (variable , str (replacement [counter ])))
105
- counter += 1
166
+ for replacement in replacements :
167
+ if command .name ().find (variable ) != - 1 :
168
+ new_task = command .clone ()
169
+ new_task .replace (variable , replacement )
170
+ add_task (new_task , tasks )
171
+ else :
172
+ add_task (command , tasks )
173
+ return tasks
106
174
107
- tmp_commands .update (test )
108
- return tmp_commands
175
+ @staticmethod
176
+ def _replace_variable_array (commands , variable , replacement ):
177
+ if variable not in sample (commands , 1 )[0 ]:
178
+ return
109
179
180
+ for counter , command in enumerate (commands ):
181
+ command .replace (variable , str (replacement [counter ]))
110
182
111
183
@staticmethod
112
184
def process_commands (arguments ):
113
- commands = set ()
185
+ commands = list ()
114
186
ranges = set ()
115
187
targets = set ()
116
188
exclusions_ranges = set ()
117
189
exclusions = set ()
118
- final_commands = set ()
119
- output = OutputHelper (arguments )
120
190
121
191
# removing the trailing slash if any
122
- if arguments .output :
123
- if arguments .output [- 1 ] == "/" :
124
- arguments .output = arguments .output [:- 1 ]
192
+ if arguments .output and arguments .output [- 1 ] == "/" :
193
+ arguments .output = arguments .output [:- 1 ]
125
194
126
195
if arguments .port :
127
- if "," in arguments .port :
128
- ports = arguments .port .split ("," )
129
- elif "-" in arguments .port :
130
- tmp_ports = arguments .port .split ("-" )
131
- if int (tmp_ports [0 ]) >= int (tmp_ports [1 ]):
132
- raise Exception ("Invalid range provided" )
133
- ports = list (range (int (tmp_ports [0 ]), int (tmp_ports [1 ]) + 1 ))
134
- else :
135
- ports = [arguments .port ]
196
+ ports = InputHelper ._process_port (arguments .port )
136
197
137
198
if arguments .realport :
138
- if "," in arguments .realport :
139
- real_ports = arguments .realport .split ("," )
140
- elif "-" in arguments .realport :
141
- tmp_ports = arguments .realport .split ("-" )
142
- if int (tmp_ports [0 ]) >= int (tmp_ports [1 ]):
143
- raise Exception ("Invalid range provided" )
144
- real_ports = list (range (int (tmp_ports [0 ]), int (tmp_ports [1 ]) + 1 ))
145
- else :
146
- real_ports = [arguments .realport ]
199
+ real_ports = InputHelper ._process_port (arguments .realport )
147
200
148
201
# process targets first
149
202
if arguments .target :
150
203
ranges .add (arguments .target )
151
204
else :
152
- targetFile = arguments .target_list
205
+ target_file = arguments .target_list
153
206
if not sys .stdin .isatty ():
154
- targetFile = sys .stdin
155
- for target in targetFile :
156
- if target .strip ():
157
- ranges .add (target .strip ())
207
+ target_file = sys .stdin
208
+ ranges .update ([target .strip () for target in target_file if target .strip ()])
158
209
159
210
# process exclusions first
160
211
if arguments .exclusions :
161
212
exclusions_ranges .add (arguments .exclusions )
162
213
else :
163
214
if arguments .exclusions_list :
164
215
for exclusion in arguments .exclusions_list :
165
- exclusions_ranges .add (target .strip ())
166
-
167
- # removing elements that may have spaces (helpful for easily processing comma notation)
168
- for target in ranges :
169
- target = target .replace (" " , "" )
170
-
171
- for ips in target .split ("," ):
172
-
173
- # check if it is a domain name
174
- if ips .split ("." )[- 1 ][0 ].isalpha ():
175
- targets .add (ips )
176
- continue
177
- # checking for CIDR
178
- if not arguments .nocidr and "/" in ips :
179
- targets .update (InputHelper ._get_cidr_to_ips (ips ))
180
- # checking for IPs in a range
181
- elif "-" in ips :
182
- targets .update (InputHelper ._get_ips_from_range (ips ))
183
- # checking for glob ranges
184
- elif "*" in ips :
185
- targets .update (InputHelper ._get_ips_from_glob (ips ))
186
- else :
187
- targets .add (ips )
216
+ exclusion = exclusion .strip ()
217
+ if exclusion :
218
+ exclusions .add (exclusion )
188
219
189
220
# removing elements that may have spaces (helpful for easily processing comma notation)
190
- for exclusion in exclusions_ranges :
191
- exclusion = exclusion .replace (" " , "" )
192
-
193
- for ips in exclusion .split ("," ):
194
- # check if it is a domain name
195
- if ips .split ("." )[- 1 ][0 ].isalpha ():
196
- targets .add (ips )
197
- continue
198
- # checking for CIDR
199
- if not arguments .nocidr and "/" in ips :
200
- exclusions .update (InputHelper ._get_cidr_to_ips (ips ))
201
- # checking for IPs in a range
202
- elif "-" in ips :
203
- exclusions .update (InputHelper ._get_ips_from_range (ips ))
204
- # checking for glob ranges
205
- elif "*" in ips :
206
- exclusions .update (InputHelper ._get_ips_from_glob (ips ))
207
- else :
208
- exclusions .add (ips )
221
+ InputHelper ._pre_process_hosts (ranges , targets , arguments )
222
+ InputHelper ._pre_process_hosts (exclusions_ranges , exclusions , arguments )
209
223
210
224
# difference operation
211
225
targets -= exclusions
@@ -218,46 +232,40 @@ def process_commands(arguments):
218
232
random_file = choice (files )
219
233
220
234
if arguments .command :
221
- commands .add (arguments .command .rstrip ('\n ' ))
235
+ commands .append (arguments .command .rstrip ('\n ' ))
222
236
else :
223
- for command in arguments .command_list :
224
- commands .add (command .rstrip ('\n ' ))
237
+ commands = InputHelper ._pre_process_commands (arguments .command_list , '' )
225
238
226
- final_commands = InputHelper ._replace_variable_for_commands (commands , "_target_" , targets )
227
- final_commands = InputHelper ._replace_variable_for_commands ( final_commands , "_host_" , targets )
239
+ commands = InputHelper ._replace_variable_with_commands (commands , "_target_" , targets )
240
+ commands = InputHelper ._replace_variable_with_commands ( commands , "_host_" , targets )
228
241
229
242
if arguments .port :
230
- final_commands = InputHelper ._replace_variable_for_commands ( final_commands , "_port_" , ports )
243
+ commands = InputHelper ._replace_variable_with_commands ( commands , "_port_" , ports )
231
244
232
245
if arguments .realport :
233
- final_commands = InputHelper ._replace_variable_for_commands ( final_commands , "_realport_" , real_ports )
246
+ commands = InputHelper ._replace_variable_with_commands ( commands , "_realport_" , real_ports )
234
247
235
248
if arguments .random :
236
- final_commands = InputHelper ._replace_variable_for_commands ( final_commands , "_random_" , [random_file ])
249
+ commands = InputHelper ._replace_variable_with_commands ( commands , "_random_" , [random_file ])
237
250
238
251
if arguments .output :
239
- final_commands = InputHelper ._replace_variable_for_commands ( final_commands , "_output_" , [arguments .output ])
252
+ commands = InputHelper ._replace_variable_with_commands ( commands , "_output_" , [arguments .output ])
240
253
241
254
if arguments .proto :
242
255
if "," in arguments .proto :
243
256
protocols = arguments .proto .split ("," )
244
257
else :
245
258
protocols = arguments .proto
246
- final_commands = InputHelper ._replace_variable_for_commands ( final_commands , "_proto_" , protocols )
247
-
259
+ commands = InputHelper ._replace_variable_with_commands ( commands , "_proto_" , protocols )
260
+
248
261
# process proxies
249
262
if arguments .proxy_list :
250
- proxy_list = list ()
251
- for proxy in arguments .proxy_list :
252
- if proxy .strip ():
253
- proxy_list .append (proxy .strip ())
254
-
255
- if len (proxy_list ) < len (final_commands ):
256
- proxy_list = ceil (len (final_commands ) / len (proxy_list )) * proxy_list
257
-
258
- final_commands = InputHelper ._replace_variable_array (final_commands , "_proxy_" , proxy_list )
263
+ proxy_list = [proxy for proxy in arguments .proxy_list if proxy .strip ()]
264
+ if len (proxy_list ) < len (commands ):
265
+ proxy_list = ceil (len (commands ) / len (proxy_list )) * proxy_list
259
266
260
- return final_commands
267
+ InputHelper ._replace_variable_array (commands , "_proxy_" , proxy_list )
268
+ return commands
261
269
262
270
263
271
class InputParser (object ):
0 commit comments