secator 0.13.0__py3-none-any.whl → 0.14.0__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/cli.py +32 -8
- secator/configs/profiles/aggressive.yaml +6 -5
- secator/configs/profiles/default.yaml +6 -7
- secator/configs/profiles/insane.yaml +8 -0
- secator/configs/profiles/paranoid.yaml +8 -0
- secator/configs/profiles/polite.yaml +8 -0
- secator/configs/profiles/sneaky.yaml +8 -0
- secator/configs/profiles/tor.yaml +5 -0
- secator/decorators.py +1 -0
- secator/report.py +2 -2
- secator/runners/_base.py +30 -0
- secator/runners/scan.py +1 -0
- secator/runners/task.py +1 -0
- secator/template.py +1 -1
- {secator-0.13.0.dist-info → secator-0.14.0.dist-info}/METADATA +1 -1
- {secator-0.13.0.dist-info → secator-0.14.0.dist-info}/RECORD +19 -16
- secator/configs/profiles/stealth.yaml +0 -7
- secator/configs/workflows/port_scan.yaml +0 -39
- {secator-0.13.0.dist-info → secator-0.14.0.dist-info}/WHEEL +0 -0
- {secator-0.13.0.dist-info → secator-0.14.0.dist-info}/entry_points.txt +0 -0
- {secator-0.13.0.dist-info → secator-0.14.0.dist-info}/licenses/LICENSE +0 -0
secator/cli.py
CHANGED
|
@@ -36,6 +36,7 @@ click.rich_click.USE_RICH_MARKUP = True
|
|
|
36
36
|
ALL_TASKS = discover_tasks()
|
|
37
37
|
ALL_WORKFLOWS = [t for t in TEMPLATES if t.type == 'workflow']
|
|
38
38
|
ALL_SCANS = [t for t in TEMPLATES if t.type == 'scan']
|
|
39
|
+
ALL_PROFILES = [t for t in TEMPLATES if t.type == 'profile']
|
|
39
40
|
FINDING_TYPES_LOWER = [c.__name__.lower() for c in FINDING_TYPES]
|
|
40
41
|
CONTEXT_SETTINGS = dict(help_option_names=['-h', '-help', '--help'])
|
|
41
42
|
|
|
@@ -125,6 +126,25 @@ for config in sorted(ALL_SCANS, key=lambda x: x['name']):
|
|
|
125
126
|
register_runner(scan, config)
|
|
126
127
|
|
|
127
128
|
|
|
129
|
+
@cli.group(aliases=['p'])
|
|
130
|
+
@click.pass_context
|
|
131
|
+
def profile(ctx):
|
|
132
|
+
"""Show profiles"""
|
|
133
|
+
pass
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
@profile.command('list')
|
|
137
|
+
def profile_list():
|
|
138
|
+
table = Table()
|
|
139
|
+
table.add_column("Profile name", style="bold gold3")
|
|
140
|
+
table.add_column("Description", overflow='fold')
|
|
141
|
+
table.add_column("Options", overflow='fold')
|
|
142
|
+
for profile in ALL_PROFILES:
|
|
143
|
+
opts_str = ','.join(f'{k}={v}' for k, v in profile.opts.items())
|
|
144
|
+
table.add_row(profile.name, profile.description, opts_str)
|
|
145
|
+
console.print(table)
|
|
146
|
+
|
|
147
|
+
|
|
128
148
|
#--------#
|
|
129
149
|
# WORKER #
|
|
130
150
|
#--------#
|
|
@@ -685,7 +705,7 @@ def report_show(report_query, output, runner_type, time_delta, type, query, work
|
|
|
685
705
|
all_results.extend(runner.results)
|
|
686
706
|
continue
|
|
687
707
|
report = Report(runner, title=f"Consolidated report - {current}", exporters=exporters)
|
|
688
|
-
report.build(extractors=extractors if not unified else [])
|
|
708
|
+
report.build(extractors=extractors if not unified else [], dedupe=unified)
|
|
689
709
|
file_date = get_file_date(path)
|
|
690
710
|
runner_name = data['info']['name']
|
|
691
711
|
console.print(
|
|
@@ -1423,6 +1443,16 @@ def task(name, verbose, check):
|
|
|
1423
1443
|
task = task[0]
|
|
1424
1444
|
task_name = task.__name__
|
|
1425
1445
|
|
|
1446
|
+
# Check task command is set
|
|
1447
|
+
check_test(
|
|
1448
|
+
task.cmd,
|
|
1449
|
+
'Check task command is set (cls.cmd)',
|
|
1450
|
+
'Task has no cmd attribute.',
|
|
1451
|
+
errors
|
|
1452
|
+
)
|
|
1453
|
+
if errors:
|
|
1454
|
+
sys.exit(0)
|
|
1455
|
+
|
|
1426
1456
|
# Run install
|
|
1427
1457
|
cmd = f'secator install tools {task_name}'
|
|
1428
1458
|
ret_code = Command.execute(cmd, name='install', quiet=not verbose, cwd=ROOT_FOLDER)
|
|
@@ -1437,7 +1467,7 @@ def task(name, verbose, check):
|
|
|
1437
1467
|
errors
|
|
1438
1468
|
)
|
|
1439
1469
|
check_test(
|
|
1440
|
-
any(cmd for cmd in [task.install_cmd, task.install_github_handle]),
|
|
1470
|
+
any(cmd for cmd in [task.install_pre, task.install_cmd, task.install_github_handle]),
|
|
1441
1471
|
'Check task installation command is defined',
|
|
1442
1472
|
'Task has no installation command. Please define one or more of the following class attributes: `install_pre`, `install_cmd`, `install_post`, `install_github_handle`.', # noqa: E501
|
|
1443
1473
|
errors
|
|
@@ -1471,12 +1501,6 @@ def task(name, verbose, check):
|
|
|
1471
1501
|
'Task has no description (class docstring).',
|
|
1472
1502
|
errors
|
|
1473
1503
|
)
|
|
1474
|
-
check_test(
|
|
1475
|
-
task.cmd,
|
|
1476
|
-
'Check task command is set (cls.cmd)',
|
|
1477
|
-
'Task has no cmd attribute.',
|
|
1478
|
-
errors
|
|
1479
|
-
)
|
|
1480
1504
|
check_test(
|
|
1481
1505
|
task.input_type,
|
|
1482
1506
|
'Check task input type is set (cls.input_type)',
|
secator/decorators.py
CHANGED
|
@@ -13,6 +13,7 @@ from secator.utils import (deduplicate, expand_input, get_command_category)
|
|
|
13
13
|
|
|
14
14
|
RUNNER_OPTS = {
|
|
15
15
|
'output': {'type': str, 'default': None, 'help': 'Output options (-o table,json,csv,gdrive)', 'short': 'o'},
|
|
16
|
+
'profiles': {'type': str, 'default': 'default', 'help': 'Profiles', 'short': 'pf'},
|
|
16
17
|
'workspace': {'type': str, 'default': 'default', 'help': 'Workspace', 'short': 'ws'},
|
|
17
18
|
'print_json': {'is_flag': True, 'short': 'json', 'default': False, 'help': 'Print items as JSON lines'},
|
|
18
19
|
'print_raw': {'is_flag': True, 'short': 'raw', 'default': False, 'help': 'Print items in raw format'},
|
secator/report.py
CHANGED
|
@@ -55,7 +55,7 @@ class Report:
|
|
|
55
55
|
f'{str(e)}[/]\n[dim]{traceback_as_string(e)}[/]',
|
|
56
56
|
)
|
|
57
57
|
|
|
58
|
-
def build(self, extractors=[], dedupe=
|
|
58
|
+
def build(self, extractors=[], dedupe=CONFIG.runners.remove_duplicates):
|
|
59
59
|
# Trim options
|
|
60
60
|
from secator.decorators import DEFAULT_CLI_OPTIONS
|
|
61
61
|
opts = merge_opts(self.runner.config.options, self.runner.run_opts)
|
|
@@ -97,7 +97,7 @@ class Report:
|
|
|
97
97
|
if items:
|
|
98
98
|
if sort_by and all(sort_by):
|
|
99
99
|
items = sorted(items, key=operator.attrgetter(*sort_by))
|
|
100
|
-
if dedupe
|
|
100
|
+
if dedupe:
|
|
101
101
|
items = remove_duplicates(items)
|
|
102
102
|
# items = [item for item in items if not item._duplicate and item not in dedupe_from]
|
|
103
103
|
for extractor in extractors:
|
secator/runners/_base.py
CHANGED
|
@@ -138,6 +138,10 @@ class Runner:
|
|
|
138
138
|
self.debug('Run opts', obj={k: v for k, v in self.run_opts.items() if v is not None}, sub='init')
|
|
139
139
|
self.debug('Print opts', obj={k: v for k, v in self.print_opts.items() if v is not None}, sub='init')
|
|
140
140
|
|
|
141
|
+
# Load profiles
|
|
142
|
+
profiles_str = run_opts.get('profiles', [])
|
|
143
|
+
self.load_profiles(profiles_str)
|
|
144
|
+
|
|
141
145
|
# Determine exporters
|
|
142
146
|
exporters_str = self.run_opts.get('output') or self.default_exporters
|
|
143
147
|
self.exporters = self.resolve_exporters(exporters_str)
|
|
@@ -953,6 +957,32 @@ class Runner:
|
|
|
953
957
|
]
|
|
954
958
|
return [cls for cls in classes if cls]
|
|
955
959
|
|
|
960
|
+
def load_profiles(self, profiles):
|
|
961
|
+
"""Load profiles and update run options.
|
|
962
|
+
|
|
963
|
+
Args:
|
|
964
|
+
profiles (list[str]): List of profile names to resolve.
|
|
965
|
+
|
|
966
|
+
Returns:
|
|
967
|
+
list: List of profiles.
|
|
968
|
+
"""
|
|
969
|
+
from secator.cli import ALL_PROFILES
|
|
970
|
+
if isinstance(profiles, str):
|
|
971
|
+
profiles = profiles.split(',')
|
|
972
|
+
templates = []
|
|
973
|
+
for pname in profiles:
|
|
974
|
+
matches = [p for p in ALL_PROFILES if p.name == pname]
|
|
975
|
+
if not matches:
|
|
976
|
+
self._print(Warning(message=f'Profile "{pname}" was not found'), rich=True)
|
|
977
|
+
else:
|
|
978
|
+
templates.append(matches[0])
|
|
979
|
+
opts = {}
|
|
980
|
+
for profile in templates:
|
|
981
|
+
self._print(Info(message=f'Loaded profile {profile.name} ({profile.description})'), rich=True)
|
|
982
|
+
opts.update(profile.opts)
|
|
983
|
+
opts = {k: v for k, v in opts.items() if k not in self.run_opts}
|
|
984
|
+
self.run_opts.update(opts)
|
|
985
|
+
|
|
956
986
|
@classmethod
|
|
957
987
|
def get_func_path(cls, func):
|
|
958
988
|
"""Get the full symbolic path of a function or method, including staticmethods, using function and method
|
secator/runners/scan.py
CHANGED
|
@@ -33,6 +33,7 @@ class Scan(Runner):
|
|
|
33
33
|
sigs = []
|
|
34
34
|
for name, workflow_opts in self.config.workflows.items():
|
|
35
35
|
run_opts = self.run_opts.copy()
|
|
36
|
+
run_opts.pop('profiles', None)
|
|
36
37
|
run_opts['no_poll'] = True
|
|
37
38
|
run_opts['caller'] = 'Scan'
|
|
38
39
|
opts = merge_opts(scan_opts, workflow_opts, run_opts)
|
secator/runners/task.py
CHANGED
secator/template.py
CHANGED
|
@@ -64,7 +64,7 @@ class TemplateLoader(DotMap):
|
|
|
64
64
|
_path = config.pop('_path', None)
|
|
65
65
|
if _path:
|
|
66
66
|
console.print(f'[italic green]{_path}[/]\n')
|
|
67
|
-
yaml_str = yaml.dump(config, indent=4)
|
|
67
|
+
yaml_str = yaml.dump(config, indent=4, sort_keys=False)
|
|
68
68
|
from rich.syntax import Syntax
|
|
69
69
|
yaml_highlight = Syntax(yaml_str, 'yaml', line_numbers=True)
|
|
70
70
|
console.print(yaml_highlight)
|
|
@@ -3,22 +3,26 @@ secator/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
3
3
|
secator/celery.py,sha256=Xg8e0zpQu4_-jlsZeC65NZtkopHGsGIyQ3SiW5fyH4E,9771
|
|
4
4
|
secator/celery_signals.py,sha256=hG62Gr34xKJYZTgZFn_wZcsAlMgKuTazQhx55FC5cDA,4259
|
|
5
5
|
secator/celery_utils.py,sha256=_wcUC42VPUotPhh9YYqbuq0dkARI8_RoCklDlhQL9Jg,8903
|
|
6
|
-
secator/cli.py,sha256=
|
|
6
|
+
secator/cli.py,sha256=76DSAyg0wZ4AraKwiEr7beoPNvQZjPgtz4IMEEP8UPs,51465
|
|
7
7
|
secator/config.py,sha256=t3RJhfVKIoEcfDWBsYlFzz29BM3dsvJtGFzwTYL0Cfc,19727
|
|
8
|
-
secator/decorators.py,sha256=
|
|
8
|
+
secator/decorators.py,sha256=tTDXNNkEQrOF4jx1UgiOD_pxMnk0LX0R41ALALOx3jk,14668
|
|
9
9
|
secator/definitions.py,sha256=qE_ZjzGcfrdASL7wjrc_0zoszUovL00KP--kGjDr93w,2986
|
|
10
10
|
secator/installer.py,sha256=UBlQdcTvYXjmCiTui_fk9DOOxJ4Vs8i70m0ZCVFV78Q,19633
|
|
11
|
-
secator/report.py,sha256=
|
|
11
|
+
secator/report.py,sha256=eWD8KgkXXZY_2cpu3xJY-ZuIkU60_UB62C79S69nDJM,3617
|
|
12
12
|
secator/rich.py,sha256=0P6TECNePsfivc5h1JsJoAqKmpFnME5m8k29ZJjvbwM,3277
|
|
13
|
-
secator/template.py,sha256=
|
|
13
|
+
secator/template.py,sha256=o2igSFcNRWqptg8Rg00m8tvMmVAvbpnnvooWynk1LVI,4567
|
|
14
14
|
secator/thread.py,sha256=rgRgEtcMgs2wyfLWVlCTUCLWeg6jsMo5iKpyyrON5rY,655
|
|
15
15
|
secator/utils.py,sha256=kaBqWgBmUZohlvn6nFY805tG26viIu_LdJysNfZWMY4,22055
|
|
16
16
|
secator/utils_test.py,sha256=jiCvgL4JMhIC1-ZGe6j9umNRZreSDp6nlkMgEJhf5ho,7996
|
|
17
17
|
secator/configs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
18
|
secator/configs/profiles/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
19
|
-
secator/configs/profiles/aggressive.yaml,sha256=
|
|
20
|
-
secator/configs/profiles/default.yaml,sha256=
|
|
21
|
-
secator/configs/profiles/
|
|
19
|
+
secator/configs/profiles/aggressive.yaml,sha256=CXsCD76zrS93Iy47H-SUeEm3Ofl58H12dOr6rhm5sUg,159
|
|
20
|
+
secator/configs/profiles/default.yaml,sha256=QCGvqNyRdFjFjGKXLuz9xc9bvKhgG87HfR3flfaaoFs,130
|
|
21
|
+
secator/configs/profiles/insane.yaml,sha256=t3Z0fSy-tJkasMoPPViqxicTo0So5gnF3kfCBWIsR6Q,152
|
|
22
|
+
secator/configs/profiles/paranoid.yaml,sha256=P3jONEyS9qIU5OPhBpEmlzc1AMJVC6ncIBR3GwJIr8Q,128
|
|
23
|
+
secator/configs/profiles/polite.yaml,sha256=yZ2rtUMpSf-xMD7ZBFd6QS7XfYPEOSZ0Sn65lVF9M54,138
|
|
24
|
+
secator/configs/profiles/sneaky.yaml,sha256=TOouDi-JQ3ZGZW9t7xbax-UvB-r2IsTr9sONwSRGo88,147
|
|
25
|
+
secator/configs/profiles/tor.yaml,sha256=bHkn10KrJ5ct57od0Y8kaH-0IWB8aZWfmKQ68FZzct4,91
|
|
22
26
|
secator/configs/scans/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
23
27
|
secator/configs/scans/domain.yaml,sha256=Dkm5dU2NdUTInkWD5cmVczvhUH0soaKPtoESeg8BVsQ,265
|
|
24
28
|
secator/configs/scans/host.yaml,sha256=tobz6yGeYlVnGwLVI9RLJT6MDLnGmQVVj8EOwAdksfw,189
|
|
@@ -29,7 +33,6 @@ secator/configs/workflows/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJW
|
|
|
29
33
|
secator/configs/workflows/cidr_recon.yaml,sha256=ytmirZxtJ8lKnzdo83mwTHOhy1OpnltuN3HFkk6XwzI,557
|
|
30
34
|
secator/configs/workflows/code_scan.yaml,sha256=3H8H55NVskiDbBwNueVF8FUYkquEQn2C6evnid9zhB4,207
|
|
31
35
|
secator/configs/workflows/host_recon.yaml,sha256=6RcH4RwCmTgesWVu8NrVIgW2ifNC4kSKgiRkNwZECdg,1173
|
|
32
|
-
secator/configs/workflows/port_scan.yaml,sha256=J6-MPpPPfwFAIKf21gXMLu1wkprvZNAfDA_U90eXKJk,951
|
|
33
36
|
secator/configs/workflows/subdomain_recon.yaml,sha256=GFhAyatzWRVx3a2kphNWNoTB13wY3GZTSZ2tusFgo8E,722
|
|
34
37
|
secator/configs/workflows/url_bypass.yaml,sha256=_uBzDhevJ2DOD9UkE25n7ZrmnjjfdU3lV3mnUudgdU0,180
|
|
35
38
|
secator/configs/workflows/url_crawl.yaml,sha256=h74dvDBNLuY1EHc9FMby3ydr34VH1qFJHQKUaIIYpcw,573
|
|
@@ -71,12 +74,12 @@ secator/output_types/user_account.py,sha256=EvF3Ebg9eXS_-iDguU1dSHZ9wAsJimEJznDv
|
|
|
71
74
|
secator/output_types/vulnerability.py,sha256=nF7OT9zGez8sZvLrkhjBOORjVi8hCqfCYUFq3eZ_ywo,2870
|
|
72
75
|
secator/output_types/warning.py,sha256=47GtmG083GqGPb_R5JDFmARJ9Mqrme58UxwJhgdGPuI,853
|
|
73
76
|
secator/runners/__init__.py,sha256=EBbOk37vkBy9p8Hhrbi-2VtM_rTwQ3b-0ggTyiD22cE,290
|
|
74
|
-
secator/runners/_base.py,sha256=
|
|
77
|
+
secator/runners/_base.py,sha256=XeH48AJvBKn3Z5qxbBmnL81jASWvIihBxPojw9Tyk-U,32629
|
|
75
78
|
secator/runners/_helpers.py,sha256=FoawlexiNl1-QMBfwBx0p4Hi7rGZxHe_RAMahqZuJ0Y,2883
|
|
76
79
|
secator/runners/celery.py,sha256=bqvDTTdoHiGRCt0FRvlgFHQ_nsjKMP5P0PzGbwfCj_0,425
|
|
77
80
|
secator/runners/command.py,sha256=aAM_VZB9ZDtSYhg52PUlBJIkiqUcNb895Xuef6lIkF8,26900
|
|
78
|
-
secator/runners/scan.py,sha256=
|
|
79
|
-
secator/runners/task.py,sha256=
|
|
81
|
+
secator/runners/scan.py,sha256=jDPT9lnb2bGShvTClQ9u9SVRcHzZnXU1v308H7Fc-RE,1656
|
|
82
|
+
secator/runners/task.py,sha256=3wudRz8TdvkonnllaeLYLFztNlyXrMQ3E31t5lCRPkk,2066
|
|
80
83
|
secator/runners/workflow.py,sha256=sO3B9GcndQLgGPnDz-A6XKnBmYO_ABAU_UXpW-q1K1A,3890
|
|
81
84
|
secator/scans/__init__.py,sha256=s4Ojsk5CWwyWqHu_A4zaXUL5Hm5L5nCmCHZn7wdD3Io,623
|
|
82
85
|
secator/serializers/__init__.py,sha256=OP5cmFl77ovgSCW_IDcZ21St2mUt5UK4QHfrsK2KvH8,248
|
|
@@ -118,8 +121,8 @@ secator/tasks/wafw00f.py,sha256=XeYl6ppS_YA-SmhBNdNcFmgUWYmiCnzU7TTLfxUTcRo,2747
|
|
|
118
121
|
secator/tasks/wpprobe.py,sha256=Dx-HcGYjWyyeIsHwkstlcxPKJ5GR6jP9TMTHeV6SXPo,4025
|
|
119
122
|
secator/tasks/wpscan.py,sha256=QrEO6ZrkmC3TDtD91Aeqip8qrcsrK7filHKpRdcteJU,5755
|
|
120
123
|
secator/workflows/__init__.py,sha256=R_TTyjg9f2Ph2_LYiF0lL07IjTrfRE_zqJzy-N7_WCk,675
|
|
121
|
-
secator-0.
|
|
122
|
-
secator-0.
|
|
123
|
-
secator-0.
|
|
124
|
-
secator-0.
|
|
125
|
-
secator-0.
|
|
124
|
+
secator-0.14.0.dist-info/METADATA,sha256=_jYPgntzztbYS1ucHWOSSIq9d6J1MfEAikWHGr3DGpg,14724
|
|
125
|
+
secator-0.14.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
126
|
+
secator-0.14.0.dist-info/entry_points.txt,sha256=lPgsqqUXWgiuGSfKy-se5gHdQlAXIwS_A46NYq7Acic,44
|
|
127
|
+
secator-0.14.0.dist-info/licenses/LICENSE,sha256=19W5Jsy4WTctNkqmZIqLRV1gTDOp01S3LDj9iSgWaJ0,2867
|
|
128
|
+
secator-0.14.0.dist-info/RECORD,,
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
type: workflow
|
|
2
|
-
name: port_scan
|
|
3
|
-
alias: pscan
|
|
4
|
-
description: Port scan
|
|
5
|
-
tags: [recon, network, http, vuln]
|
|
6
|
-
input_types:
|
|
7
|
-
- host
|
|
8
|
-
- cidr_range
|
|
9
|
-
tasks:
|
|
10
|
-
naabu:
|
|
11
|
-
description: Find open ports
|
|
12
|
-
skip_host_discovery: True
|
|
13
|
-
ports: "-" # scan all ports
|
|
14
|
-
nmap:
|
|
15
|
-
description: Search for vulnerabilities on open ports
|
|
16
|
-
skip_host_discovery: True
|
|
17
|
-
version_detection: True
|
|
18
|
-
targets_: port.host
|
|
19
|
-
ports_: port.port
|
|
20
|
-
_group:
|
|
21
|
-
searchsploit:
|
|
22
|
-
description: Search for related exploits
|
|
23
|
-
targets_:
|
|
24
|
-
- type: port
|
|
25
|
-
field: '{host}~{service_name}'
|
|
26
|
-
condition: item._source.startswith('nmap') and len(item.service_name.split('/')) > 1
|
|
27
|
-
httpx:
|
|
28
|
-
description: Probe HTTP services on open ports
|
|
29
|
-
targets_:
|
|
30
|
-
- type: port
|
|
31
|
-
field: '{host}:{port}'
|
|
32
|
-
condition: item._source.startswith('nmap')
|
|
33
|
-
results:
|
|
34
|
-
- type: port
|
|
35
|
-
|
|
36
|
-
- type: url
|
|
37
|
-
condition: item.status_code != 0
|
|
38
|
-
|
|
39
|
-
- type: vulnerability
|
|
File without changes
|
|
File without changes
|
|
File without changes
|