secator 0.16.3__py3-none-any.whl → 0.16.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of secator might be problematic. Click here for more details.

secator/celery.py CHANGED
@@ -214,11 +214,21 @@ def run_command(self, results, name, targets, opts={}):
214
214
  update_state(self, task)
215
215
  update_state(self, task, force=True)
216
216
 
217
+ if CONFIG.addons.mongodb.enabled:
218
+ return [r._uuid for r in task.results]
217
219
  return task.results
218
220
 
219
221
 
220
222
  @app.task
221
223
  def forward_results(results):
224
+ """Forward results to the next task (bridge task).
225
+
226
+ Args:
227
+ results (list): Results to forward.
228
+
229
+ Returns:
230
+ list: List of uuids.
231
+ """
222
232
  if isinstance(results, list):
223
233
  for ix, item in enumerate(results):
224
234
  if isinstance(item, dict) and 'results' in item:
@@ -227,10 +237,16 @@ def forward_results(results):
227
237
  results = results['results']
228
238
 
229
239
  if IN_CELERY_WORKER_PROCESS:
230
- console.print(Info(message=f'Forwarding {len(results)} results'))
240
+ console.print(Info(message=f'Deduplicating {len(results)} results'))
231
241
 
232
242
  results = flatten(results)
233
- results = deduplicate(results, attr='_uuid')
243
+ if IN_CELERY_WORKER_PROCESS and CONFIG.addons.mongodb.enabled:
244
+ console.print(Info(message=f'Extracting uuids from {len(results)} results'))
245
+ uuids = [r._uuid for r in results if hasattr(r, '_uuid')]
246
+ uuids.extend([r for r in results if isinstance(r, str)])
247
+ results = list(set(uuids))
248
+ else:
249
+ results = deduplicate(results, attr='_uuid')
234
250
 
235
251
  if IN_CELERY_WORKER_PROCESS:
236
252
  console.print(Info(message=f'Forwarded {len(results)} flattened and deduplicated results'))
@@ -254,9 +270,16 @@ def mark_runner_started(results, runner, enable_hooks=True):
254
270
  console.print(Info(message=f'Runner {runner.unique_name} has started, running mark_started'))
255
271
  debug(f'Runner {runner.unique_name} has started, running mark_started', sub='celery')
256
272
  if results:
257
- runner.results = forward_results(results)
273
+ results = forward_results(results)
258
274
  runner.enable_hooks = enable_hooks
275
+ if IN_CELERY_WORKER_PROCESS and CONFIG.addons.mongodb.enabled:
276
+ from secator.hooks.mongodb import get_results
277
+ results = get_results(results)
278
+ for item in results:
279
+ runner.add_result(item, print=False)
259
280
  runner.mark_started()
281
+ if IN_CELERY_WORKER_PROCESS and CONFIG.addons.mongodb.enabled:
282
+ return [r._uuid for r in runner.results]
260
283
  return runner.results
261
284
 
262
285
 
@@ -277,9 +300,14 @@ def mark_runner_completed(results, runner, enable_hooks=True):
277
300
  debug(f'Runner {runner.unique_name} has finished, running mark_completed', sub='celery')
278
301
  results = forward_results(results)
279
302
  runner.enable_hooks = enable_hooks
303
+ if IN_CELERY_WORKER_PROCESS and CONFIG.addons.mongodb.enabled:
304
+ from secator.hooks.mongodb import get_results
305
+ results = get_results(results)
280
306
  for item in results:
281
307
  runner.add_result(item, print=False)
282
308
  runner.mark_completed()
309
+ if IN_CELERY_WORKER_PROCESS and CONFIG.addons.mongodb.enabled:
310
+ return [r._uuid for r in runner.results]
283
311
  return runner.results
284
312
 
285
313
 
secator/hooks/gcs.py CHANGED
@@ -11,7 +11,7 @@ from secator.utils import debug
11
11
 
12
12
  GCS_BUCKET_NAME = CONFIG.addons.gcs.bucket_name
13
13
  ITEMS_TO_SEND = {
14
- 'url': ['screenshot_path']
14
+ 'url': ['screenshot_path', 'stored_response_path']
15
15
  }
16
16
 
17
17
 
@@ -42,10 +42,12 @@ def upload_blob(bucket_name, source_file_name, destination_blob_name):
42
42
  storage_client = storage.Client()
43
43
  bucket = storage_client.bucket(bucket_name)
44
44
  blob = bucket.blob(destination_blob_name)
45
- blob.upload_from_filename(source_file_name)
45
+ with open(source_file_name, 'rb') as f:
46
+ f.seek(0)
47
+ blob.upload_from_file(f)
46
48
  end_time = time()
47
49
  elapsed = end_time - start_time
48
- debug(f'in {elapsed:.4f}s', obj={'blob': 'CREATED', 'blob_name': destination_blob_name, 'bucket': bucket_name}, obj_after=False, sub='hooks.gcs', verbose=True) # noqa: E501
50
+ debug(f'in {elapsed:.4f}s', obj={'blob': 'UPLOADED', 'blob_name': destination_blob_name, 'bucket': bucket_name}, obj_after=False, sub='hooks.gcs', verbose=True) # noqa: E501
49
51
 
50
52
 
51
53
  HOOKS = {
secator/hooks/mongodb.py CHANGED
@@ -30,7 +30,8 @@ def get_mongodb_client():
30
30
  _mongodb_client = pymongo.MongoClient(
31
31
  escape_mongodb_url(MONGODB_URL),
32
32
  maxPoolSize=MONGODB_MAX_POOL_SIZE,
33
- serverSelectionTimeoutMS=MONGODB_CONNECT_TIMEOUT
33
+ serverSelectionTimeoutMS=MONGODB_CONNECT_TIMEOUT,
34
+ connect=False
34
35
  )
35
36
  return _mongodb_client
36
37
 
@@ -46,6 +47,28 @@ def get_runner_dbg(runner):
46
47
  }
47
48
 
48
49
 
50
+ def get_results(uuids):
51
+ """Get results from MongoDB based on a list of uuids.
52
+
53
+ Args:
54
+ uuids (list[str | Output]): List of uuids, but can also be a mix of uuids and output types.
55
+
56
+ Returns:
57
+ Generator of findings.
58
+ """
59
+ client = get_mongodb_client()
60
+ db = client.main
61
+ del_uuids = []
62
+ for r in uuids:
63
+ if isinstance(r, tuple(OUTPUT_TYPES)):
64
+ yield r
65
+ del_uuids.append(r)
66
+ uuids = [ObjectId(u) for u in uuids if u not in del_uuids and ObjectId.is_valid(u)]
67
+ for r in db.findings.find({'_id': {'$in': uuids}}):
68
+ finding = load_finding(r)
69
+ yield finding
70
+
71
+
49
72
  def update_runner(self):
50
73
  client = get_mongodb_client()
51
74
  db = client.main
@@ -135,19 +158,23 @@ def load_findings(objs):
135
158
 
136
159
 
137
160
  @shared_task
138
- def tag_duplicates(ws_id: str = None):
161
+ def tag_duplicates(ws_id: str = None, full_scan: bool = False):
139
162
  """Tag duplicates in workspace.
140
163
 
141
164
  Args:
142
165
  ws_id (str): Workspace id.
166
+ full_scan (bool): If True, scan all findings, otherwise only untagged findings.
143
167
  """
144
168
  debug(f'running duplicate check on workspace {ws_id}', sub='hooks.mongodb')
145
169
  client = get_mongodb_client()
146
170
  db = client.main
147
171
  workspace_query = list(
148
172
  db.findings.find({'_context.workspace_id': str(ws_id), '_tagged': True}).sort('_timestamp', -1))
173
+ untagged_query = {'_context.workspace_id': str(ws_id)}
174
+ if not full_scan:
175
+ untagged_query['_tagged'] = {'$ne': True}
149
176
  untagged_query = list(
150
- db.findings.find({'_context.workspace_id': str(ws_id), '_tagged': {'$ne': True}}).sort('_timestamp', -1))
177
+ db.findings.find(untagged_query).sort('_timestamp', -1))
151
178
  if not untagged_query:
152
179
  debug('no untagged findings. Skipping.', id=ws_id, sub='hooks.mongodb')
153
180
  return
secator/runners/_base.py CHANGED
@@ -178,6 +178,10 @@ class Runner:
178
178
 
179
179
  # Add prior results to runner results
180
180
  self.debug(f'adding {len(results)} prior results to runner', sub='init')
181
+ if CONFIG.addons.mongodb.enabled:
182
+ self.debug('adding prior results from MongoDB', sub='init')
183
+ from secator.hooks.mongodb import get_results
184
+ results = get_results(results)
181
185
  for result in results:
182
186
  self.add_result(result, print=False, output=False, hooks=False, queue=not self.has_parent)
183
187
 
@@ -189,8 +193,8 @@ class Runner:
189
193
  for target in targets:
190
194
  self.add_result(target, print=False, output=False)
191
195
 
192
- # Run extractors on results and targets
193
- self._run_extractors(results + targets)
196
+ # Run extractors on results
197
+ self._run_extractors()
194
198
  self.debug(f'inputs ({len(self.inputs)})', obj=self.inputs, sub='init')
195
199
  self.debug(f'run opts ({len(self.resolved_opts)})', obj=self.resolved_opts, sub='init')
196
200
  self.debug(f'print opts ({len(self.resolved_print_opts)})', obj=self.resolved_print_opts, sub='init')
@@ -430,12 +434,12 @@ class Runner:
430
434
  if error:
431
435
  self.add_result(error)
432
436
 
433
- def _run_extractors(self, results):
437
+ def _run_extractors(self):
434
438
  """Run extractors on results and targets."""
435
439
  self.debug('running extractors', sub='init')
436
440
  ctx = {'opts': DotMap(self.run_opts), 'targets': self.inputs, 'ancestor_id': self.ancestor_id}
437
441
  inputs, run_opts, errors = run_extractors(
438
- results,
442
+ self.results,
439
443
  self.run_opts,
440
444
  self.inputs,
441
445
  ctx=ctx,
@@ -96,6 +96,20 @@ class HttpFuzzer(Command):
96
96
  meta_opts = {k: OPTS[k] for k in OPTS_HTTP_FUZZERS}
97
97
  input_types = [URL]
98
98
  output_types = [Url]
99
+ profile = lambda opts: HttpFuzzer.dynamic_profile(opts) # noqa: E731
100
+
101
+ @staticmethod
102
+ def dynamic_profile(opts):
103
+ wordlist = HttpFuzzer._get_opt_value(
104
+ opts,
105
+ 'wordlist',
106
+ opts_conf=dict(HttpFuzzer.opts, **HttpFuzzer.meta_opts),
107
+ opt_aliases=opts.get('aliases', []),
108
+ preprocess=True,
109
+ process=True,
110
+ )
111
+ wordlist_size_mb = os.path.getsize(wordlist) / (1024 * 1024)
112
+ return 'cpu' if wordlist_size_mb > 5 else 'io'
99
113
 
100
114
 
101
115
  #----------------#
secator/tasks/dalfox.py CHANGED
@@ -25,6 +25,7 @@ class dalfox(VulnHttp):
25
25
  output_types = [Vulnerability, Url]
26
26
  tags = ['url', 'fuzz']
27
27
  input_flag = 'url'
28
+ input_chunk_size = 20
28
29
  file_flag = 'file'
29
30
  # input_chunk_size = 1
30
31
  json_flag = '--format jsonl'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: secator
3
- Version: 0.16.3
3
+ Version: 0.16.5
4
4
  Summary: The pentester's swiss knife.
5
5
  Project-URL: Homepage, https://github.com/freelabz/secator
6
6
  Project-URL: Issues, https://github.com/freelabz/secator/issues
@@ -1,6 +1,6 @@
1
1
  secator/.gitignore,sha256=da8MUc3hdb6Mo0WjZu2upn5uZMbXcBGvhdhTQ1L89HI,3093
2
2
  secator/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- secator/celery.py,sha256=Uu9bslbxyi6bQnlRfXOQkyZ62BlwZ_xKWiyYwtRhzII,10553
3
+ secator/celery.py,sha256=FAahY_kfjxc3tD2R42kNre_eb-QeSvArKyGpthXeWDg,11626
4
4
  secator/celery_signals.py,sha256=R4ZNBPKSxUvesGCvZ7MXoRkWNOTMS5hraZzjLh5sQ0o,4191
5
5
  secator/celery_utils.py,sha256=vhL5ZxXDn3ODvyVxMijKyUTJ1dOisMDjF_PhFUyOVSA,9451
6
6
  secator/cli.py,sha256=lzgttr8-Hib1X6bGi8PCOfX90incum7ZFR5x46cDZ34,60887
@@ -57,8 +57,8 @@ secator/exporters/json.py,sha256=1ZtDf8RksPO_V0zIvnwDUxMUb630DCElAMM8_RQvyAo,474
57
57
  secator/exporters/table.py,sha256=zYNmwNGEyB6dTJ1ATVkrv-AOuPjrW6tvk1_4naLQo8Q,1114
58
58
  secator/exporters/txt.py,sha256=t_FykaJOxs4UUlqiH4k6HCccEqYqc8e3iNZndL_CKPg,739
59
59
  secator/hooks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
60
- secator/hooks/gcs.py,sha256=MIhntyWYz9BZdTXhWl5JznaczSq1_7fl3TVqPufuTSo,1490
61
- secator/hooks/mongodb.py,sha256=QbW412E1oK_WHwClWtaZI4quH4ak6S-aT3D4JWSmeKw,7635
60
+ secator/hooks/gcs.py,sha256=v8Q1-ky9e4xaLgyTJaeWWpiVhu0SzWbXLIEHYV9f5h8,1550
61
+ secator/hooks/mongodb.py,sha256=x6gLPdvMOBz0ViWbfaM9Xkv1plLYvXjKWpd83b0VUFU,8393
62
62
  secator/output_types/__init__.py,sha256=CJcYy2_Ek-opKiBz4wFlDHQBTm3t0JVwZ4w_2Jxoeuw,1291
63
63
  secator/output_types/_base.py,sha256=9iBqPdtlfJBldBiuC729KamHHGbKhwo69P-2UNwz-3Q,2874
64
64
  secator/output_types/certificate.py,sha256=IXW3GN0JRmuDgoedr8NV8ccuRQOuoInNZWnAKL8zeqY,3040
@@ -79,7 +79,7 @@ secator/output_types/user_account.py,sha256=EvF3Ebg9eXS_-iDguU1dSHZ9wAsJimEJznDv
79
79
  secator/output_types/vulnerability.py,sha256=eWJDFCYf3sP5-hPKQT-4Kd5id9bJzTW2u-O_d_4P6EA,2849
80
80
  secator/output_types/warning.py,sha256=iy949Aj5OXJLWif7HFB5EvjcYrgKHAzIP9ffyLTV7LA,830
81
81
  secator/runners/__init__.py,sha256=EBbOk37vkBy9p8Hhrbi-2VtM_rTwQ3b-0ggTyiD22cE,290
82
- secator/runners/_base.py,sha256=Utxw3iLBsugIy7Nt3rUAy0dueezM-uil_lfSAqDgvGE,40514
82
+ secator/runners/_base.py,sha256=IkAQfPzz_kou5Pa82y-2Wmtp_lIudKMc9ix8_NP4370,40663
83
83
  secator/runners/_helpers.py,sha256=TeebZnpo4cp-9tpgPlDoFm_gmr00_CERAC1aOYhTzA4,6281
84
84
  secator/runners/celery.py,sha256=bqvDTTdoHiGRCt0FRvlgFHQ_nsjKMP5P0PzGbwfCj_0,425
85
85
  secator/runners/command.py,sha256=5fmwmqkUkomceLUSp2rtJvn_ydE2gI95rqS4WKWciYI,30200
@@ -92,12 +92,12 @@ secator/serializers/dataclass.py,sha256=Fo2ZVsVjSF0KMq81JT8mGZxsKsxyueShlDsh9Pgw
92
92
  secator/serializers/json.py,sha256=UJwAymRzjF-yBKOgz1MTOyBhQcdQg7fOKRXgmHIu8fo,411
93
93
  secator/serializers/regex.py,sha256=fh-fE0RGvKSGKByFtwmKsWriRpZR9PXZQsY9JybHBWI,489
94
94
  secator/tasks/__init__.py,sha256=Op0O0Aa8c124AfDG-cEB9VLRsXZ1wXTpVrT3g-wxMNg,184
95
- secator/tasks/_categories.py,sha256=yns_5PBKStp6TJEeaYB6yFUjkFMmLh7LEuxcNcADNro,14962
95
+ secator/tasks/_categories.py,sha256=ZmUNzeFIZ9-_er9sLJw66PTYIL5nO799JQU3EoW-6nE,15394
96
96
  secator/tasks/arjun.py,sha256=WdRZtTCd2Ejbv5HlLS_FoWVKgGpMsR6RCDekV2kR788,3061
97
97
  secator/tasks/bbot.py,sha256=moIkwd52jCKaeg1v6Nv4Gfmd4GPObo9c9nwOzQvf-2M,9236
98
98
  secator/tasks/bup.py,sha256=9IXsCqMdhOeZcCsQB2L4IJ3Kzm2oQKDE7mflGljm0lM,3867
99
99
  secator/tasks/cariddi.py,sha256=iT-2Aryw2PPrzPedc-N_E--DxKFz_gSrcJj4z5PGQf8,4142
100
- secator/tasks/dalfox.py,sha256=Z_1xu_3piw08L7z33gT00omW7JD3Ojnc0fHkFqoutyA,2470
100
+ secator/tasks/dalfox.py,sha256=DWz0VWBH5SU_AyHU36YC88vAEyJ1hXkKKKNXgQvwlrU,2493
101
101
  secator/tasks/dirsearch.py,sha256=_6xPZYpNsbwR4d9NFQw3NXxQKn5zyfO1lyrWzl5p7NY,2469
102
102
  secator/tasks/dnsx.py,sha256=2qNC-wSjS33geuHMOwuBapLwKEvWTlDgnmvM67ZSJVA,4220
103
103
  secator/tasks/feroxbuster.py,sha256=dz_DGw_CbVGw9AeFjtrAEQwoxDgKzYC-KT9VLwE5UlE,3022
@@ -125,8 +125,8 @@ secator/tasks/wafw00f.py,sha256=9CnV9F7ZrykO27F3PAb5HtwULDMYEKGSTbz-jh0kc2g,3189
125
125
  secator/tasks/wpprobe.py,sha256=1QPJ-7JvhL7LFvjUTAmqpH2Krp-Qmi079lonso16YPQ,3229
126
126
  secator/tasks/wpscan.py,sha256=dBkbG9EODHDUBAA8uNVULX4SdVgTCAi_F1T1oCfRbsI,5852
127
127
  secator/workflows/__init__.py,sha256=XOviyjSylZ4cuVmmQ76yuqZRdmvOEghqAnuw_4cLmfk,702
128
- secator-0.16.3.dist-info/METADATA,sha256=q9d__g8tXAFEQ47__NmReJX3nfvXdG9TkPA1QlKo2sg,17253
129
- secator-0.16.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
130
- secator-0.16.3.dist-info/entry_points.txt,sha256=lPgsqqUXWgiuGSfKy-se5gHdQlAXIwS_A46NYq7Acic,44
131
- secator-0.16.3.dist-info/licenses/LICENSE,sha256=19W5Jsy4WTctNkqmZIqLRV1gTDOp01S3LDj9iSgWaJ0,2867
132
- secator-0.16.3.dist-info/RECORD,,
128
+ secator-0.16.5.dist-info/METADATA,sha256=Bob8xdFbxnKib4O7WIiG9VAtq9efZ9JLzwpPQIcXhAw,17253
129
+ secator-0.16.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
130
+ secator-0.16.5.dist-info/entry_points.txt,sha256=lPgsqqUXWgiuGSfKy-se5gHdQlAXIwS_A46NYq7Acic,44
131
+ secator-0.16.5.dist-info/licenses/LICENSE,sha256=19W5Jsy4WTctNkqmZIqLRV1gTDOp01S3LDj9iSgWaJ0,2867
132
+ secator-0.16.5.dist-info/RECORD,,