secator 0.10.1a12__tar.gz → 0.11.0__tar.gz
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-0.10.1a12 → secator-0.11.0}/.docker/Dockerfile.alpine +1 -1
- {secator-0.10.1a12 → secator-0.11.0}/.docker/Dockerfile.arch +1 -1
- {secator-0.10.1a12 → secator-0.11.0}/.docker/Dockerfile.debian +1 -1
- {secator-0.10.1a12 → secator-0.11.0}/.docker/Dockerfile.kali +1 -1
- {secator-0.10.1a12 → secator-0.11.0}/.docker/Dockerfile.osx +1 -1
- {secator-0.10.1a12 → secator-0.11.0}/.docker/Dockerfile.ubuntu +1 -1
- {secator-0.10.1a12 → secator-0.11.0}/CHANGELOG.md +29 -0
- {secator-0.10.1a12 → secator-0.11.0}/PKG-INFO +1 -1
- {secator-0.10.1a12 → secator-0.11.0}/pyproject.toml +1 -1
- {secator-0.10.1a12 → secator-0.11.0}/scripts/stories/STORY.md +1 -1
- {secator-0.10.1a12 → secator-0.11.0}/secator/celery.py +10 -5
- {secator-0.10.1a12 → secator-0.11.0}/secator/celery_signals.py +2 -11
- {secator-0.10.1a12 → secator-0.11.0}/secator/cli.py +153 -46
- secator-0.11.0/secator/configs/workflows/url_params_fuzz.yaml +23 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/configs/workflows/wordpress.yaml +4 -1
- {secator-0.10.1a12 → secator-0.11.0}/secator/decorators.py +10 -5
- {secator-0.10.1a12 → secator-0.11.0}/secator/definitions.py +3 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/installer.py +46 -32
- {secator-0.10.1a12 → secator-0.11.0}/secator/output_types/__init__.py +2 -1
- secator-0.11.0/secator/output_types/certificate.py +78 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/output_types/user_account.py +1 -1
- {secator-0.10.1a12 → secator-0.11.0}/secator/rich.py +1 -1
- {secator-0.10.1a12 → secator-0.11.0}/secator/runners/_base.py +14 -6
- {secator-0.10.1a12 → secator-0.11.0}/secator/runners/_helpers.py +4 -3
- {secator-0.10.1a12 → secator-0.11.0}/secator/runners/command.py +81 -21
- {secator-0.10.1a12 → secator-0.11.0}/secator/runners/scan.py +5 -3
- {secator-0.10.1a12 → secator-0.11.0}/secator/runners/workflow.py +22 -4
- {secator-0.10.1a12 → secator-0.11.0}/secator/tasks/_categories.py +6 -1
- secator-0.11.0/secator/tasks/arjun.py +82 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/tasks/ffuf.py +2 -1
- secator-0.11.0/secator/tasks/gitleaks.py +76 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/tasks/mapcidr.py +1 -1
- {secator-0.10.1a12 → secator-0.11.0}/secator/tasks/naabu.py +7 -1
- {secator-0.10.1a12 → secator-0.11.0}/secator/tasks/nmap.py +29 -29
- {secator-0.10.1a12 → secator-0.11.0}/secator/tasks/subfinder.py +1 -1
- secator-0.11.0/secator/tasks/testssl.py +274 -0
- secator-0.11.0/secator/tasks/trivy.py +95 -0
- secator-0.11.0/secator/tasks/wafw00f.py +83 -0
- secator-0.11.0/secator/tasks/wpprobe.py +94 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/template.py +49 -67
- {secator-0.10.1a12 → secator-0.11.0}/secator/utils.py +13 -5
- {secator-0.10.1a12 → secator-0.11.0}/secator/utils_test.py +26 -8
- secator-0.11.0/tests/integration/inputs.py +48 -0
- {secator-0.10.1a12 → secator-0.11.0}/tests/integration/outputs.py +33 -2
- secator-0.11.0/tests/integration/setup.sh +15 -0
- secator-0.11.0/tests/integration/teardown.sh +14 -0
- secator-0.10.1a12/tests/integration/test_tasks_categories.py → secator-0.11.0/tests/integration/test_helpers.py +1 -1
- {secator-0.10.1a12 → secator-0.11.0}/tests/integration/test_tasks.py +3 -0
- {secator-0.10.1a12 → secator-0.11.0}/tests/integration/test_worker.py +4 -4
- {secator-0.10.1a12 → secator-0.11.0}/tests/integration/test_workflows.py +1 -1
- {secator-0.10.1a12 → secator-0.11.0}/tests/performance/loadtester.py +1 -1
- secator-0.10.1a12/tests/unit/test_tasks.py → secator-0.11.0/tests/unit/test_command.py +14 -49
- secator-0.11.0/tests/unit/test_tasks.py +51 -0
- {secator-0.10.1a12 → secator-0.11.0}/tests/unit/test_template.py +27 -9
- secator-0.10.1a12/tests/integration/inputs.py +0 -43
- secator-0.10.1a12/tests/integration/setup.sh +0 -5
- secator-0.10.1a12/tests/integration/teardown.sh +0 -4
- {secator-0.10.1a12 → secator-0.11.0}/.docker/build_all.sh +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/.dockerignore +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/.flake8 +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/.gitignore +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/CONTRIBUTING.md +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/Dockerfile +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/LICENSE +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/README.md +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/SECURITY.md +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/cloudbuild.yaml +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/helm/.helmignore +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/helm/Chart.yaml +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/helm/templates/redis-service.yaml +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/helm/templates/redis.yaml +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/helm/templates/secator-manager.yaml +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/helm/templates/secator-worker.yaml +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/helm/values.yaml +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/scripts/download_cves.sh +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/scripts/install.sh +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/scripts/install_asciinema.sh +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/scripts/install_go.sh +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/scripts/install_ruby.sh +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/scripts/msf/exploit_cve.rc +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/scripts/msf/ftp_anonymous.rc +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/scripts/msf/ftp_version.rc +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/scripts/msf/ftp_vsftpd_234_backdoor.rc +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/scripts/msf/redis.rc +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/scripts/stories/aliases.sh +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/scripts/stories/demo.sh +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/scripts/stories/fmt.sh +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/scripts/stories/input.sh +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/scripts/stories/pipe.sh +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/scripts/stories/short_demo.sh +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/.gitignore +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/__init__.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/celery_utils.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/config.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/configs/__init__.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/configs/profiles/__init__.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/configs/profiles/aggressive.yaml +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/configs/profiles/default.yaml +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/configs/profiles/stealth.yaml +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/configs/scans/__init__.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/configs/scans/domain.yaml +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/configs/scans/host.yaml +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/configs/scans/network.yaml +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/configs/scans/subdomain.yaml +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/configs/scans/url.yaml +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/configs/workflows/__init__.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/configs/workflows/cidr_recon.yaml +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/configs/workflows/code_scan.yaml +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/configs/workflows/host_recon.yaml +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/configs/workflows/subdomain_recon.yaml +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/configs/workflows/url_bypass.yaml +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/configs/workflows/url_crawl.yaml +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/configs/workflows/url_dirsearch.yaml +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/configs/workflows/url_fuzz.yaml +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/configs/workflows/url_nuclei.yaml +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/configs/workflows/url_vuln.yaml +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/configs/workflows/user_hunt.yaml +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/exporters/__init__.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/exporters/_base.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/exporters/console.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/exporters/csv.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/exporters/gdrive.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/exporters/json.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/exporters/table.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/exporters/txt.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/hooks/__init__.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/hooks/gcs.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/hooks/mongodb.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/output_types/_base.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/output_types/error.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/output_types/exploit.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/output_types/info.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/output_types/ip.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/output_types/port.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/output_types/progress.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/output_types/record.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/output_types/stat.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/output_types/state.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/output_types/subdomain.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/output_types/tag.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/output_types/target.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/output_types/url.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/output_types/vulnerability.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/output_types/warning.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/report.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/runners/__init__.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/runners/celery.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/runners/task.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/scans/__init__.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/serializers/__init__.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/serializers/dataclass.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/serializers/json.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/serializers/regex.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/tasks/__init__.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/tasks/bbot.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/tasks/bup.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/tasks/cariddi.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/tasks/dalfox.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/tasks/dirsearch.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/tasks/dnsx.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/tasks/dnsxbrute.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/tasks/feroxbuster.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/tasks/fping.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/tasks/gau.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/tasks/gf.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/tasks/gospider.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/tasks/grype.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/tasks/h8mail.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/tasks/httpx.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/tasks/katana.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/tasks/maigret.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/tasks/msfconsole.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/tasks/nuclei.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/tasks/searchsploit.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/tasks/wpscan.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/thread.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/secator/workflows/__init__.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/tests/__init__.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/tests/fixtures/h8mail_breach.txt +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/tests/fixtures/ls.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/tests/fixtures/msfconsole_input.rc +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/tests/fixtures/nmap_output.xml +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/tests/integration/__init__.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/tests/integration/test_addons.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/tests/integration/test_celery.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/tests/integration/test_scans.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/tests/integration/wordlist.txt +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/tests/integration/wordlist_dns.txt +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/tests/integration/wordpress_toolbox/Dockerfile +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/tests/integration/wordpress_toolbox/Makefile +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/tests/performance/__init__.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/tests/performance/test_worker.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/tests/unit/__init__.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/tests/unit/test_celery.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/tests/unit/test_cli.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/tests/unit/test_config.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/tests/unit/test_offline.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/tests/unit/test_runners.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/tests/unit/test_scans.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/tests/unit/test_serializers.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/tests/unit/test_tasks_categories.py +0 -0
- {secator-0.10.1a12 → secator-0.11.0}/tests/unit/test_utils.py +0 -0
|
@@ -32,5 +32,5 @@ RUN pipx install . && \
|
|
|
32
32
|
secator install addons redis && \
|
|
33
33
|
secator install addons dev
|
|
34
34
|
RUN secator config set security.force_source_install true
|
|
35
|
-
RUN secator install tools --cleanup
|
|
35
|
+
RUN secator install tools --cleanup --fail-fast
|
|
36
36
|
ENTRYPOINT ["secator"]
|
|
@@ -33,5 +33,5 @@ RUN pipx install . && \
|
|
|
33
33
|
secator install addons redis && \
|
|
34
34
|
secator install addons dev
|
|
35
35
|
RUN secator config set security.force_source_install true
|
|
36
|
-
RUN secator install tools --cleanup
|
|
36
|
+
RUN secator install tools --cleanup --fail-fast
|
|
37
37
|
ENTRYPOINT ["secator"]
|
|
@@ -36,5 +36,5 @@ RUN pipx install . && \
|
|
|
36
36
|
secator install addons redis && \
|
|
37
37
|
secator install addons dev
|
|
38
38
|
RUN secator config set security.force_source_install true
|
|
39
|
-
RUN secator install tools --cleanup
|
|
39
|
+
RUN secator install tools --cleanup --fail-fast
|
|
40
40
|
ENTRYPOINT ["secator"]
|
|
@@ -33,5 +33,5 @@ RUN pipx install . && \
|
|
|
33
33
|
secator install addons redis && \
|
|
34
34
|
secator install addons dev
|
|
35
35
|
RUN secator config set security.force_source_install true
|
|
36
|
-
RUN secator install tools --cleanup
|
|
36
|
+
RUN secator install tools --cleanup --fail-fast
|
|
37
37
|
ENTRYPOINT ["secator"]
|
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.11.0](https://github.com/freelabz/secator/compare/v0.10.0...v0.11.0) (2025-04-22)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* **celery:** simplify task runner logic ([#574](https://github.com/freelabz/secator/issues/574)) ([9eb057c](https://github.com/freelabz/secator/commit/9eb057cee0afcba93e2f5d7d1d9a4807c1ecb1fc))
|
|
9
|
+
* **output_types:** add Certificate output type ([#459](https://github.com/freelabz/secator/issues/459)) ([179f915](https://github.com/freelabz/secator/commit/179f9154d9886245c16b9c38365365b08ee4afb9))
|
|
10
|
+
* restore nmap defaults, del port_scan, mod host_recon ([#581](https://github.com/freelabz/secator/issues/581)) ([e0c7c58](https://github.com/freelabz/secator/commit/e0c7c58c11b462ac161263e2550064387b5c0ff5))
|
|
11
|
+
* **runner:** core improvements ([#582](https://github.com/freelabz/secator/issues/582)) ([11f2dd3](https://github.com/freelabz/secator/commit/11f2dd3cbcf16139e3495b9cb54da6fdff0d95e6))
|
|
12
|
+
* **task:** arjun integration ([#504](https://github.com/freelabz/secator/issues/504)) ([be7f80c](https://github.com/freelabz/secator/commit/be7f80cee0a9251cca6b5e55f4293e8881516f7a))
|
|
13
|
+
* **tasks:** add wpprobe ([#557](https://github.com/freelabz/secator/issues/557)) ([d413097](https://github.com/freelabz/secator/commit/d4130971ac0b7fc9f6e357d3e0f17fc6d6d60004))
|
|
14
|
+
* **tasks:** gitleaks integration ([#441](https://github.com/freelabz/secator/issues/441)) ([e6d5830](https://github.com/freelabz/secator/commit/e6d58308a64dc018c1706854795eac2c6d88adc4))
|
|
15
|
+
* **tasks:** trivy integration ([#460](https://github.com/freelabz/secator/issues/460)) ([f7169cf](https://github.com/freelabz/secator/commit/f7169cfdb32697b25c59f1106b8da80eb6540ab2))
|
|
16
|
+
* **tasks:** wafw00f integration ([#471](https://github.com/freelabz/secator/issues/471)) ([b9b80b0](https://github.com/freelabz/secator/commit/b9b80b06449f863b117350e4be3acb9f14a59ca8))
|
|
17
|
+
* **task:** testssl.sh integration ([#484](https://github.com/freelabz/secator/issues/484)) ([7c65d60](https://github.com/freelabz/secator/commit/7c65d605eedc0f63ace2724fff5b584314065ccb))
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Bug Fixes
|
|
21
|
+
|
|
22
|
+
* add debug of tasks unit tests, internal tasks not added to cmd, add display flag for options ([#587](https://github.com/freelabz/secator/issues/587)) ([3980234](https://github.com/freelabz/secator/commit/3980234d968a893940736daa2bb347951190bce1))
|
|
23
|
+
* add default user agent and remove ffuf recursion ([#586](https://github.com/freelabz/secator/issues/586)) ([332d1bd](https://github.com/freelabz/secator/commit/332d1bd4a63f8338bc9425ccd92d5188fc6e983e))
|
|
24
|
+
* **celery:** kill worker in solo mode ([#568](https://github.com/freelabz/secator/issues/568)) ([c2fd107](https://github.com/freelabz/secator/commit/c2fd107ea1c4248c3eba518dfdc6d777eff8ef15))
|
|
25
|
+
* help shorthand flag -h ([#591](https://github.com/freelabz/secator/issues/591)) ([ea3a4ce](https://github.com/freelabz/secator/commit/ea3a4ceb4c8dec14caf2fdde7e6ad39b03695cfd))
|
|
26
|
+
* installer and x-platform issues ([#590](https://github.com/freelabz/secator/issues/590)) ([8ce1e1e](https://github.com/freelabz/secator/commit/8ce1e1eaf2e80249060035ffe27fef330c54f366))
|
|
27
|
+
* **installer:** support single binary download ([#588](https://github.com/freelabz/secator/issues/588)) ([bc799b9](https://github.com/freelabz/secator/commit/bc799b9da4e34b8974d92790ac185db4f5884472))
|
|
28
|
+
* thread is_started ([9b6c6bb](https://github.com/freelabz/secator/commit/9b6c6bb244a3434db3d398160918bc807288a9ad))
|
|
29
|
+
* wordlist not loaded when local path is provided ([#572](https://github.com/freelabz/secator/issues/572)) ([ef071a9](https://github.com/freelabz/secator/commit/ef071a9aa430220b5cfe0dcb5db271512339a140))
|
|
30
|
+
* wpscan ignore main redirect and ssl ignore ([#577](https://github.com/freelabz/secator/issues/577)) ([35c445d](https://github.com/freelabz/secator/commit/35c445dc9a669c8f73764b712c13e983d7598f90))
|
|
31
|
+
|
|
3
32
|
## [0.10.0](https://github.com/freelabz/secator/compare/v0.9.4...v0.10.0) (2025-03-04)
|
|
4
33
|
|
|
5
34
|
|
|
@@ -62,7 +62,7 @@ secator z default mydomain.com --worker
|
|
|
62
62
|
from secator.runners import Workflow
|
|
63
63
|
from secator.template import TemplateLoader
|
|
64
64
|
|
|
65
|
-
config = TemplateLoader(name='
|
|
65
|
+
config = TemplateLoader(name='workflow/host_recon')
|
|
66
66
|
hooks = {
|
|
67
67
|
Task: {
|
|
68
68
|
'on_item': {
|
|
@@ -223,10 +223,11 @@ def forward_results(results):
|
|
|
223
223
|
|
|
224
224
|
|
|
225
225
|
@app.task
|
|
226
|
-
def mark_runner_started(runner, enable_hooks=True):
|
|
226
|
+
def mark_runner_started(results, runner, enable_hooks=True):
|
|
227
227
|
"""Mark a runner as started and run on_start hooks.
|
|
228
228
|
|
|
229
229
|
Args:
|
|
230
|
+
results (List): Previous results.
|
|
230
231
|
runner (Runner): Secator runner instance.
|
|
231
232
|
enable_hooks (bool): Enable hooks.
|
|
232
233
|
|
|
@@ -234,9 +235,12 @@ def mark_runner_started(runner, enable_hooks=True):
|
|
|
234
235
|
list: Runner results
|
|
235
236
|
"""
|
|
236
237
|
debug(f'Runner {runner.unique_name} has started, running mark_started', sub='celery')
|
|
238
|
+
if results:
|
|
239
|
+
runner.results = forward_results(results)
|
|
237
240
|
runner.enable_hooks = enable_hooks
|
|
238
|
-
runner.
|
|
239
|
-
|
|
241
|
+
if not runner.dry_run:
|
|
242
|
+
runner.mark_started()
|
|
243
|
+
return runner.results
|
|
240
244
|
|
|
241
245
|
|
|
242
246
|
@app.task
|
|
@@ -254,8 +258,9 @@ def mark_runner_completed(results, runner, enable_hooks=True):
|
|
|
254
258
|
debug(f'Runner {runner.unique_name} has finished, running mark_completed', sub='celery')
|
|
255
259
|
results = forward_results(results)
|
|
256
260
|
runner.enable_hooks = enable_hooks
|
|
257
|
-
|
|
258
|
-
|
|
261
|
+
if not runner.dry_run:
|
|
262
|
+
[runner.add_result(item) for item in results]
|
|
263
|
+
runner.mark_completed()
|
|
259
264
|
return runner.results
|
|
260
265
|
|
|
261
266
|
|
|
@@ -65,16 +65,6 @@ def setup_idle_timer(timeout):
|
|
|
65
65
|
timer.start()
|
|
66
66
|
|
|
67
67
|
|
|
68
|
-
def maybe_override_logging():
|
|
69
|
-
def decorator(func):
|
|
70
|
-
if CONFIG.celery.override_default_logging:
|
|
71
|
-
return signals.setup_logging.connect(func)
|
|
72
|
-
else:
|
|
73
|
-
return func
|
|
74
|
-
return decorator
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
@maybe_override_logging()
|
|
78
68
|
def setup_logging(*args, **kwargs):
|
|
79
69
|
"""Override celery's logging setup to prevent it from altering our settings.
|
|
80
70
|
github.com/celery/celery/issues/1867
|
|
@@ -134,8 +124,9 @@ def worker_shutdown_handler(**kwargs):
|
|
|
134
124
|
|
|
135
125
|
|
|
136
126
|
def setup_handlers():
|
|
127
|
+
if CONFIG.celery.override_default_logging:
|
|
128
|
+
signals.setup_logging.connect(setup_logging)
|
|
137
129
|
signals.celeryd_after_setup.connect(capture_worker_name)
|
|
138
|
-
signals.setup_logging.connect(setup_logging)
|
|
139
130
|
signals.task_prerun.connect(task_prerun_handler)
|
|
140
131
|
signals.task_postrun.connect(task_postrun_handler)
|
|
141
132
|
signals.task_revoked.connect(task_revoked_handler)
|
|
@@ -18,14 +18,14 @@ from rich.table import Table
|
|
|
18
18
|
|
|
19
19
|
from secator.config import CONFIG, ROOT_FOLDER, Config, default_config, config_path
|
|
20
20
|
from secator.decorators import OrderedGroup, register_runner
|
|
21
|
-
from secator.definitions import ADDONS_ENABLED, ASCII, DEV_PACKAGE,
|
|
21
|
+
from secator.definitions import ADDONS_ENABLED, ASCII, DEV_PACKAGE, VERSION, STATE_COLORS
|
|
22
22
|
from secator.installer import ToolInstaller, fmt_health_table_row, get_health_table, get_version_info, get_distro_config
|
|
23
23
|
from secator.output_types import FINDING_TYPES, Info, Warning, Error
|
|
24
24
|
from secator.report import Report
|
|
25
25
|
from secator.rich import console
|
|
26
26
|
from secator.runners import Command, Runner
|
|
27
27
|
from secator.serializers.dataclass import loads_dataclass
|
|
28
|
-
from secator.template import TemplateLoader
|
|
28
|
+
from secator.template import TEMPLATES, TemplateLoader
|
|
29
29
|
from secator.utils import (
|
|
30
30
|
debug, detect_host, discover_tasks, flatten, print_version, get_file_date,
|
|
31
31
|
sort_files_by_date, get_file_timestamp, list_reports, get_info_from_report_path, human_to_timedelta
|
|
@@ -34,17 +34,18 @@ from secator.utils import (
|
|
|
34
34
|
click.rich_click.USE_RICH_MARKUP = True
|
|
35
35
|
|
|
36
36
|
ALL_TASKS = discover_tasks()
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
ALL_SCANS = ALL_CONFIGS.scan
|
|
37
|
+
ALL_WORKFLOWS = [t for t in TEMPLATES if t.type == 'workflow']
|
|
38
|
+
ALL_SCANS = [t for t in TEMPLATES if t.type == 'scan']
|
|
40
39
|
FINDING_TYPES_LOWER = [c.__name__.lower() for c in FINDING_TYPES]
|
|
40
|
+
CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help'])
|
|
41
41
|
|
|
42
42
|
|
|
43
43
|
#-----#
|
|
44
44
|
# CLI #
|
|
45
45
|
#-----#
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
|
|
48
|
+
@click.group(cls=OrderedGroup, invoke_without_command=True, context_settings=CONTEXT_SETTINGS)
|
|
48
49
|
@click.option('--version', '-version', is_flag=True, default=False)
|
|
49
50
|
@click.pass_context
|
|
50
51
|
def cli(ctx, version):
|
|
@@ -119,11 +120,12 @@ for config in sorted(ALL_SCANS, key=lambda x: x['name']):
|
|
|
119
120
|
@click.option('-Q', '--queue', type=str, default='', help='Listen to a specific queue.')
|
|
120
121
|
@click.option('-P', '--pool', type=str, default='eventlet', help='Pool implementation.')
|
|
121
122
|
@click.option('--quiet', is_flag=True, help='Quiet mode.')
|
|
123
|
+
@click.option('--loglevel', type=str, default='INFO', help='Log level.')
|
|
122
124
|
@click.option('--check', is_flag=True, help='Check if Celery worker is alive.')
|
|
123
125
|
@click.option('--dev', is_flag=True, help='Start a worker in dev mode (celery multi).')
|
|
124
126
|
@click.option('--stop', is_flag=True, help='Stop a worker in dev mode (celery multi).')
|
|
125
127
|
@click.option('--show', is_flag=True, help='Show command (celery multi).')
|
|
126
|
-
def worker(hostname, concurrency, reload, queue, pool, quiet, check, dev, stop, show):
|
|
128
|
+
def worker(hostname, concurrency, reload, queue, pool, quiet, loglevel, check, dev, stop, show):
|
|
127
129
|
"""Run a worker."""
|
|
128
130
|
|
|
129
131
|
# Check Celery addon is installed
|
|
@@ -169,6 +171,7 @@ def worker(hostname, concurrency, reload, queue, pool, quiet, check, dev, stop,
|
|
|
169
171
|
|
|
170
172
|
cmd += f' -P {pool}' if pool else ''
|
|
171
173
|
cmd += f' -c {concurrency}' if concurrency else ''
|
|
174
|
+
cmd += f' -l {loglevel}' if loglevel else ''
|
|
172
175
|
|
|
173
176
|
if reload:
|
|
174
177
|
patterns = "celery.py;tasks/*.py;runners/*.py;serializers/*.py;output_types/*.py;hooks/*.py;exporters/*.py"
|
|
@@ -862,7 +865,7 @@ def health(json, debug, strict):
|
|
|
862
865
|
error = False
|
|
863
866
|
for tool, info in status['tools'].items():
|
|
864
867
|
if not info['installed']:
|
|
865
|
-
console.print(Error(message=f'{tool} not installed
|
|
868
|
+
console.print(Error(message=f'{tool} is not installed.'))
|
|
866
869
|
error = True
|
|
867
870
|
if error:
|
|
868
871
|
sys.exit(1)
|
|
@@ -878,21 +881,21 @@ def run_install(title=None, cmd=None, packages=None, next_steps=None):
|
|
|
878
881
|
if CONFIG.offline_mode:
|
|
879
882
|
console.print(Error(message='Cannot run this command in offline mode.'))
|
|
880
883
|
return
|
|
881
|
-
with console.status(f'[bold yellow] Installing {title}...'):
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
884
|
+
# with console.status(f'[bold yellow] Installing {title}...'):
|
|
885
|
+
if cmd:
|
|
886
|
+
from secator.installer import SourceInstaller
|
|
887
|
+
status = SourceInstaller.install(cmd)
|
|
888
|
+
elif packages:
|
|
889
|
+
from secator.installer import PackageInstaller
|
|
890
|
+
status = PackageInstaller.install(packages)
|
|
891
|
+
return_code = 1
|
|
892
|
+
if status.is_ok():
|
|
893
|
+
return_code = 0
|
|
894
|
+
if next_steps:
|
|
895
|
+
console.print('[bold gold3]:wrench: Next steps:[/]')
|
|
896
|
+
for ix, step in enumerate(next_steps):
|
|
897
|
+
console.print(f' :keycap_{ix}: {step}')
|
|
898
|
+
sys.exit(return_code)
|
|
896
899
|
|
|
897
900
|
|
|
898
901
|
@cli.group()
|
|
@@ -1051,8 +1054,9 @@ def install_ruby():
|
|
|
1051
1054
|
|
|
1052
1055
|
@install.command('tools')
|
|
1053
1056
|
@click.argument('cmds', required=False)
|
|
1054
|
-
@click.option('--cleanup', is_flag=True, default=False)
|
|
1055
|
-
|
|
1057
|
+
@click.option('--cleanup', is_flag=True, default=False, help='Clean up tools after installation.')
|
|
1058
|
+
@click.option('--fail-fast', is_flag=True, default=False, help='Fail fast if any tool fails to install.')
|
|
1059
|
+
def install_tools(cmds, cleanup, fail_fast):
|
|
1056
1060
|
"""Install supported tools."""
|
|
1057
1061
|
if CONFIG.offline_mode:
|
|
1058
1062
|
console.print(Error(message='Cannot run this command in offline mode.'))
|
|
@@ -1069,10 +1073,12 @@ def install_tools(cmds, cleanup):
|
|
|
1069
1073
|
console.print(Error(message=f'No tools found for {cmd_str}.'))
|
|
1070
1074
|
return
|
|
1071
1075
|
for ix, cls in enumerate(tools):
|
|
1072
|
-
with console.status(f'[bold yellow][{ix + 1}/{len(tools)}] Installing {cls.__name__} ...'):
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
+
# with console.status(f'[bold yellow][{ix + 1}/{len(tools)}] Installing {cls.__name__} ...'):
|
|
1077
|
+
status = ToolInstaller.install(cls)
|
|
1078
|
+
if not status.is_ok():
|
|
1079
|
+
return_code = 1
|
|
1080
|
+
if fail_fast:
|
|
1081
|
+
sys.exit(return_code)
|
|
1076
1082
|
console.print()
|
|
1077
1083
|
if cleanup:
|
|
1078
1084
|
distro = get_distro_config()
|
|
@@ -1132,14 +1138,13 @@ def update(all):
|
|
|
1132
1138
|
return_code = 0
|
|
1133
1139
|
for cls in ALL_TASKS:
|
|
1134
1140
|
cmd = cls.cmd.split(' ')[0]
|
|
1135
|
-
version_flag = cls.
|
|
1136
|
-
version_flag = None if cls.version_flag == OPT_NOT_SUPPORTED else version_flag
|
|
1141
|
+
version_flag = cls.get_version_flag()
|
|
1137
1142
|
info = get_version_info(cmd, version_flag, cls.install_github_handle)
|
|
1138
1143
|
if not info['installed'] or info['status'] == 'outdated' or not info['latest_version']:
|
|
1139
|
-
with console.status(f'[bold yellow]Installing {cls.__name__} ...'):
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1144
|
+
# with console.status(f'[bold yellow]Installing {cls.__name__} ...'):
|
|
1145
|
+
status = ToolInstaller.install(cls)
|
|
1146
|
+
if not status.is_ok():
|
|
1147
|
+
return_code = 1
|
|
1143
1148
|
sys.exit(return_code)
|
|
1144
1149
|
|
|
1145
1150
|
#-------#
|
|
@@ -1250,24 +1255,35 @@ def test():
|
|
|
1250
1255
|
pass
|
|
1251
1256
|
|
|
1252
1257
|
|
|
1253
|
-
def run_test(cmd, name):
|
|
1258
|
+
def run_test(cmd, name=None, exit=True, verbose=False):
|
|
1254
1259
|
"""Run a test and return the result.
|
|
1255
1260
|
|
|
1256
1261
|
Args:
|
|
1257
|
-
cmd: Command to run.
|
|
1258
|
-
name: Name of the test.
|
|
1262
|
+
cmd (str): Command to run.
|
|
1263
|
+
name (str, optional): Name of the test.
|
|
1264
|
+
exit (bool, optional): Exit after running the test with the return code.
|
|
1265
|
+
verbose (bool, optional): Print verbose output.
|
|
1266
|
+
|
|
1267
|
+
Returns:
|
|
1268
|
+
Return code of the test.
|
|
1259
1269
|
"""
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1270
|
+
cmd_name = name + ' tests' if name else 'tests'
|
|
1271
|
+
result = Command.execute(cmd, name=cmd_name, cwd=ROOT_FOLDER, quiet=not verbose)
|
|
1272
|
+
if name:
|
|
1273
|
+
if result.return_code == 0:
|
|
1274
|
+
console.print(f':tada: {name.capitalize()} tests passed !', style='bold green')
|
|
1275
|
+
else:
|
|
1276
|
+
console.print(f':x: {name.capitalize()} tests failed !', style='bold red')
|
|
1277
|
+
if exit:
|
|
1278
|
+
sys.exit(result.return_code)
|
|
1279
|
+
return result.return_code
|
|
1264
1280
|
|
|
1265
1281
|
|
|
1266
1282
|
@test.command()
|
|
1267
1283
|
def lint():
|
|
1268
1284
|
"""Run lint tests."""
|
|
1269
1285
|
cmd = f'{sys.executable} -m flake8 secator/'
|
|
1270
|
-
run_test(cmd, 'lint')
|
|
1286
|
+
run_test(cmd, 'lint', verbose=True)
|
|
1271
1287
|
|
|
1272
1288
|
|
|
1273
1289
|
@test.command()
|
|
@@ -1285,13 +1301,21 @@ def unit(tasks, workflows, scans, test):
|
|
|
1285
1301
|
os.environ['SECATOR_HTTP_STORE_RESPONSES'] = '0'
|
|
1286
1302
|
os.environ['SECATOR_RUNNERS_SKIP_CVE_SEARCH'] = '1'
|
|
1287
1303
|
|
|
1304
|
+
if not test:
|
|
1305
|
+
if tasks:
|
|
1306
|
+
test = 'test_tasks'
|
|
1307
|
+
elif workflows:
|
|
1308
|
+
test = 'test_workflows'
|
|
1309
|
+
elif scans:
|
|
1310
|
+
test = 'test_scans'
|
|
1311
|
+
|
|
1288
1312
|
import shutil
|
|
1289
1313
|
shutil.rmtree('/tmp/.secator', ignore_errors=True)
|
|
1290
1314
|
cmd = f'{sys.executable} -m coverage run --omit="*test*" --data-file=.coverage.unit -m pytest -s -v tests/unit'
|
|
1291
1315
|
if test:
|
|
1292
1316
|
test_str = ' or '.join(test.split(','))
|
|
1293
1317
|
cmd += f' -k "{test_str}"'
|
|
1294
|
-
run_test(cmd, 'unit')
|
|
1318
|
+
run_test(cmd, 'unit', verbose=True)
|
|
1295
1319
|
|
|
1296
1320
|
|
|
1297
1321
|
@test.command()
|
|
@@ -1307,6 +1331,14 @@ def integration(tasks, workflows, scans, test):
|
|
|
1307
1331
|
os.environ['SECATOR_DIRS_DATA'] = '/tmp/.secator'
|
|
1308
1332
|
os.environ['SECATOR_RUNNERS_SKIP_CVE_SEARCH'] = '1'
|
|
1309
1333
|
|
|
1334
|
+
if not test:
|
|
1335
|
+
if tasks:
|
|
1336
|
+
test = 'test_tasks'
|
|
1337
|
+
elif workflows:
|
|
1338
|
+
test = 'test_workflows'
|
|
1339
|
+
elif scans:
|
|
1340
|
+
test = 'test_scans'
|
|
1341
|
+
|
|
1310
1342
|
import shutil
|
|
1311
1343
|
shutil.rmtree('/tmp/.secator', ignore_errors=True)
|
|
1312
1344
|
|
|
@@ -1314,7 +1346,7 @@ def integration(tasks, workflows, scans, test):
|
|
|
1314
1346
|
if test:
|
|
1315
1347
|
test_str = ' or '.join(test.split(','))
|
|
1316
1348
|
cmd += f' -k "{test_str}"'
|
|
1317
|
-
run_test(cmd, 'integration')
|
|
1349
|
+
run_test(cmd, 'integration', verbose=True)
|
|
1318
1350
|
|
|
1319
1351
|
|
|
1320
1352
|
@test.command()
|
|
@@ -1337,7 +1369,82 @@ def performance(tasks, workflows, scans, test):
|
|
|
1337
1369
|
if test:
|
|
1338
1370
|
test_str = ' or '.join(test.split(','))
|
|
1339
1371
|
cmd += f' -k "{test_str}"'
|
|
1340
|
-
run_test(cmd, 'performance')
|
|
1372
|
+
run_test(cmd, 'performance', verbose=True)
|
|
1373
|
+
|
|
1374
|
+
|
|
1375
|
+
@test.command()
|
|
1376
|
+
@click.argument('name', type=str)
|
|
1377
|
+
@click.option('--verbose', '-v', is_flag=True, default=False, help='Print verbose output')
|
|
1378
|
+
def task(name, verbose):
|
|
1379
|
+
"""Test task."""
|
|
1380
|
+
task = [task for task in ALL_TASKS if task.__name__ == name]
|
|
1381
|
+
warnings = []
|
|
1382
|
+
exit_code = 0
|
|
1383
|
+
|
|
1384
|
+
# Check if task is correctly registered
|
|
1385
|
+
check_error(task, 'Check task is registered', 'Task is not registered. Make sure there is no syntax errors in the task class definition.', warnings) # noqa: E501
|
|
1386
|
+
task = task[0]
|
|
1387
|
+
task_name = task.__name__
|
|
1388
|
+
|
|
1389
|
+
# Run install
|
|
1390
|
+
console.print(f'\n[bold gold3]:wrench: Running install tests for task {name} ...[/]') if verbose else None
|
|
1391
|
+
cmd = f'secator install tools {task_name}'
|
|
1392
|
+
ret_code = Command.execute(cmd, name='install', quiet=not verbose, cwd=ROOT_FOLDER)
|
|
1393
|
+
version_info = task.get_version_info()
|
|
1394
|
+
check_error(version_info['installed'], 'Check task is installed', 'Failed to install command. Fix your installation command.', warnings) # noqa: E501
|
|
1395
|
+
check_error(any(cmd for cmd in [task.install_cmd, task.install_github_handle]), 'Check task installation command is defined', 'Task has no installation command. Please define a `install_cmd` or `install_github_handle` class attribute.', warnings) # noqa: E501
|
|
1396
|
+
check_error(version_info['version'], 'Check task version can be fetched', 'Failed to detect version info. Fix your `version_flag` class attribute.', warnings) # noqa: E501
|
|
1397
|
+
|
|
1398
|
+
# Run task-specific tests
|
|
1399
|
+
console.print(f'\n[bold gold3]:wrench: Running task-specific tests for {name} ...[/]') if verbose else None
|
|
1400
|
+
check_error(task.__doc__, 'Check task description is set (cls.__doc__)', 'Task has no description (class docstring).', warnings) # noqa: E501
|
|
1401
|
+
check_error(task.cmd, 'Check task command is set (cls.cmd)', 'Task has no cmd attribute.', warnings)
|
|
1402
|
+
check_error(task.input_type, 'Check task input type is set (cls.input_type)', 'Task has no input_type attribute.', warnings) # noqa: E501
|
|
1403
|
+
check_error(task.output_types, 'Check task output types is set (cls.output_types)', 'Task has no output_types attribute.', warnings) # noqa: E501
|
|
1404
|
+
|
|
1405
|
+
# Print all warnings
|
|
1406
|
+
exit_code = 1 if len(warnings) > 0 else 0
|
|
1407
|
+
if exit_code == 1:
|
|
1408
|
+
console.print()
|
|
1409
|
+
console.print("[bold red]Issues:[/]")
|
|
1410
|
+
for warning in warnings:
|
|
1411
|
+
console.print(warning)
|
|
1412
|
+
console.print()
|
|
1413
|
+
console.print(Info(message=f'Skipping unit and integration tests for {name} due to previous errors.'))
|
|
1414
|
+
console.print(Error(message=f'Task {name} tests failed. Please fix the issues above before making a PR.'))
|
|
1415
|
+
sys.exit(exit_code)
|
|
1416
|
+
|
|
1417
|
+
# Run unit tests
|
|
1418
|
+
console.print(f'\n[bold gold3]:wrench: Running unit tests for {name} ...[/]') if verbose else None
|
|
1419
|
+
cmd = f'secator test unit --tasks {name}'
|
|
1420
|
+
ret_code = run_test(cmd, exit=False, verbose=verbose)
|
|
1421
|
+
check_error(ret_code == 0, 'Check unit tests pass', 'Unit tests failed.', warnings)
|
|
1422
|
+
|
|
1423
|
+
# Run integration tests
|
|
1424
|
+
console.print(f'\n[bold gold3]:wrench: Running integration tests for {name} ...[/]') if verbose else None
|
|
1425
|
+
cmd = f'secator test integration --tasks {name}'
|
|
1426
|
+
ret_code = run_test(cmd, exit=False, verbose=verbose)
|
|
1427
|
+
check_error(ret_code == 0, 'Check integration tests pass', 'Integration tests failed.', warnings)
|
|
1428
|
+
|
|
1429
|
+
# Exit with exit code
|
|
1430
|
+
exit_code = 1 if len(warnings) > 0 else 0
|
|
1431
|
+
if exit_code == 0:
|
|
1432
|
+
console.print(f':tada: Task {name} tests passed ! You are free to make a PR.', style='bold green')
|
|
1433
|
+
else:
|
|
1434
|
+
console.print(Error(message=f'Task {name} tests failed. Please fix the issues above before making a PR.'))
|
|
1435
|
+
|
|
1436
|
+
sys.exit(exit_code)
|
|
1437
|
+
|
|
1438
|
+
|
|
1439
|
+
def check_error(condition, message, error, warnings=[]):
|
|
1440
|
+
console.print(f'[bold magenta]:zap: {message} ...[/]', end='')
|
|
1441
|
+
if not condition:
|
|
1442
|
+
warning = Warning(message=error)
|
|
1443
|
+
warnings.append(warning)
|
|
1444
|
+
console.print(' [bold red]FAILED[/]', style='dim')
|
|
1445
|
+
else:
|
|
1446
|
+
console.print(' [bold green]OK[/]', style='dim')
|
|
1447
|
+
return True
|
|
1341
1448
|
|
|
1342
1449
|
|
|
1343
1450
|
@test.command()
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
type: workflow
|
|
2
|
+
name: url_params_fuzz
|
|
3
|
+
alias: url_params_fuzz
|
|
4
|
+
description: Extract parameters from an URL and fuzz them
|
|
5
|
+
tags: [http, fuzz]
|
|
6
|
+
input_types:
|
|
7
|
+
- url
|
|
8
|
+
tasks:
|
|
9
|
+
arjun:
|
|
10
|
+
description: Extract parameters from URLs
|
|
11
|
+
ffuf:
|
|
12
|
+
description: Fuzz URL params
|
|
13
|
+
wordlist: https://raw.githubusercontent.com/danielmiessler/SecLists/refs/heads/master/Discovery/Web-Content/burp-parameter-names.txt
|
|
14
|
+
targets_:
|
|
15
|
+
- type: url
|
|
16
|
+
field: url
|
|
17
|
+
condition: item._source.startswith('arjun')
|
|
18
|
+
httpx:
|
|
19
|
+
description: Probe fuzzed URLs
|
|
20
|
+
targets_:
|
|
21
|
+
- type: url
|
|
22
|
+
field: url
|
|
23
|
+
condition: item._source.startswith('ffuf')
|
|
@@ -19,16 +19,17 @@ RUNNER_OPTS = {
|
|
|
19
19
|
'print_stat': {'is_flag': True, 'short': 'stat', 'default': False, 'help': 'Print runtime statistics'},
|
|
20
20
|
'print_format': {'default': '', 'short': 'fmt', 'help': 'Output formatting string'},
|
|
21
21
|
'enable_profiler': {'is_flag': True, 'short': 'prof', 'default': False, 'help': 'Enable runner profiling'},
|
|
22
|
-
'show': {'is_flag': True, 'default': False, 'help': 'Show command that will be run (tasks only)'},
|
|
23
|
-
'no_process': {'is_flag': True, 'default': False, 'help': 'Disable secator processing'},
|
|
22
|
+
'show': {'is_flag': True, 'short': 'sh', 'default': False, 'help': 'Show command that will be run (tasks only)'},
|
|
23
|
+
'no_process': {'is_flag': True, 'short': 'nps', 'default': False, 'help': 'Disable secator processing'},
|
|
24
24
|
# 'filter': {'default': '', 'short': 'f', 'help': 'Results filter', 'short': 'of'}, # TODO add this
|
|
25
|
-
'quiet': {'is_flag': True, 'default': False, 'help': 'Enable quiet mode'},
|
|
25
|
+
'quiet': {'is_flag': True, 'short': 'q', 'default': False, 'help': 'Enable quiet mode'},
|
|
26
|
+
'dry_run': {'is_flag': True, 'short': 'dr', 'default': False, 'help': 'Enable dry run'},
|
|
26
27
|
}
|
|
27
28
|
|
|
28
29
|
RUNNER_GLOBAL_OPTS = {
|
|
29
30
|
'sync': {'is_flag': True, 'help': 'Run tasks synchronously (automatic if no worker is alive)'},
|
|
30
31
|
'worker': {'is_flag': True, 'default': False, 'help': 'Run tasks in worker'},
|
|
31
|
-
'no_poll': {'is_flag': True, 'default': False, 'help': 'Do not live poll for tasks results when running in worker'},
|
|
32
|
+
'no_poll': {'is_flag': True, 'short': 'np', 'default': False, 'help': 'Do not live poll for tasks results when running in worker'}, # noqa: E501
|
|
32
33
|
'proxy': {'type': str, 'help': 'HTTP proxy'},
|
|
33
34
|
'driver': {'type': str, 'help': 'Export real-time results. E.g: "mongodb"'}
|
|
34
35
|
# 'debug': {'type': int, 'default': 0, 'help': 'Debug mode'},
|
|
@@ -224,12 +225,16 @@ def decorate_command_options(opts):
|
|
|
224
225
|
for opt_name, opt_conf in reversed_opts.items():
|
|
225
226
|
conf = opt_conf.copy()
|
|
226
227
|
short_opt = conf.pop('short', None)
|
|
227
|
-
conf.pop('internal',
|
|
228
|
+
internal = conf.pop('internal', False)
|
|
229
|
+
display = conf.pop('display', True)
|
|
230
|
+
if internal and not display:
|
|
231
|
+
continue
|
|
228
232
|
conf.pop('prefix', None)
|
|
229
233
|
conf.pop('shlex', None)
|
|
230
234
|
conf.pop('meta', None)
|
|
231
235
|
conf.pop('supported', None)
|
|
232
236
|
conf.pop('process', None)
|
|
237
|
+
conf.pop('requires_sudo', None)
|
|
233
238
|
reverse = conf.pop('reverse', False)
|
|
234
239
|
long = f'--{opt_name}'
|
|
235
240
|
short = f'-{short_opt}' if short_opt else f'-{opt_name}'
|
|
@@ -107,6 +107,9 @@ TAGS = 'tags'
|
|
|
107
107
|
WEBSERVER = 'webserver'
|
|
108
108
|
WORDLIST = 'wordlist'
|
|
109
109
|
WORDS = 'words'
|
|
110
|
+
CERTIFICATE_STATUS_UNKNOWN = 'Unknown'
|
|
111
|
+
CERTIFICATE_STATUS_TRUSTED = 'Trusted'
|
|
112
|
+
CERTIFICATE_STATUS_REVOKED = 'Revoked'
|
|
110
113
|
|
|
111
114
|
|
|
112
115
|
def is_importable(module_to_import):
|